Thanks in advance for your time and support

PS: I have not come to implement the hadler part since just putting the callbakc crashes. The debugger says it receives an “unexpected exception” and goes into an infinite loop.
SimpleCan.h
Code: Select all
#ifndef __CAN__H
#define __CAN__H
#include "Arduino.h"
#include "stm32f4xx_hal_can.h"
// Value needed for prescaler. depends
// on CLK configuration
enum CanSpeed
{
Kbit500 = 5,
Kbit250 = 10,
Kbit125 = 20,
Kbit100 = 25,
Kbit50 = 50,
Kbit20 = 125
};
enum CanMode
{
NormalCAN = CAN_MODE_NORMAL,
SilentCAN = CAN_MODE_SILENT,
LoopBackCan = CAN_MODE_LOOPBACK,
SilentLoopBackCAN = CAN_MODE_SILENT_LOOPBACK
};
typedef struct{
uint8_t dlc;
uint32_t msgID;
bool isRTR;
bool isStandard;
uint8_t data[8];
}CanMessage;
CanMessage createMessage(void);
/**
CAN wrapper for STM32F405RGT6 board.
*/
class SimpleCan
{
public:
/*
class RxHandler
{
public:
RxHandler(uint16_t dataLength, void(*callback)(CAN_RxHeaderTypeDef rxHeader, uint8_t *rxData));
~RxHandler();
void notify(CAN_HandleTypeDef *hcan1);
private:
CAN_RxHeaderTypeDef _rxHeader;
uint8_t *_rxData;
void(*_callback)(CAN_RxHeaderTypeDef, uint8_t *);
};
*/
SimpleCan();
HAL_StatusTypeDef init(CanSpeed speed, CanMode mode);
HAL_StatusTypeDef configFilter(CAN_FilterTypeDef *filterDef);
HAL_StatusTypeDef configSnniferFilter();
HAL_StatusTypeDef activateNotification(/*RxHandler *rxHandler*/);
HAL_StatusTypeDef deactivateNotification();
HAL_StatusTypeDef begin();
HAL_StatusTypeDef stop();
HAL_StatusTypeDef send(CanMessage message);
//private: interrupt handler needs access to it
CAN_HandleTypeDef hcan;
//static RxHandler *_rxHandler;
};
#endif
Code: Select all
#include <SimpleCan.h>
#include <Arduino.h>
extern "C" HAL_StatusTypeDef HAL_CAN_Start(CAN_HandleTypeDef *);
extern "C" HAL_StatusTypeDef HAL_CAN_Stop (CAN_HandleTypeDef *);
extern "C" HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef *);
extern "C" HAL_StatusTypeDef HAL_CAN_ActivateNotification(CAN_HandleTypeDef *, uint32_t );
extern "C" void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *);
void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan1)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hcan1->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspInit 0 */
/* USER CODE END CAN1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_CAN1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**CAN1 GPIO Configuration
PB8 ------> CAN1_RX
PB9 ------> CAN1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* CAN1 interrupt Init */
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
/* USER CODE BEGIN CAN1_MspInit 1 */
/* USER CODE END CAN1_MspInit 1 */
}
}
CanMessage createMessage(){
CanMessage message;
message.dlc = 8;
message.msgID = 200;
message.isRTR = false;
message.isStandard = true;
uint8_t messageLoadBuffer[8] ={0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x23};
memcpy(message.data, messageLoadBuffer, 8);
return message;
}
SimpleCan::SimpleCan(){
return;
}
HAL_StatusTypeDef SimpleCan::init(CanSpeed speed, CanMode mode){
hcan.Instance = CAN1;
hcan.Init.Prescaler = speed;
hcan.Init.Mode = mode;
hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan.Init.TimeSeg1 = CAN_BS1_8TQ;
hcan.Init.TimeSeg2 = CAN_BS2_1TQ;
hcan.Init.TimeTriggeredMode = DISABLE;
hcan.Init.AutoBusOff = DISABLE;
hcan.Init.AutoWakeUp = DISABLE;
hcan.Init.AutoRetransmission = DISABLE;
hcan.Init.ReceiveFifoLocked = DISABLE;
hcan.Init.TransmitFifoPriority = DISABLE;
return HAL_CAN_Init(&hcan);
}
HAL_StatusTypeDef SimpleCan::begin(){
return HAL_CAN_Start(&hcan);
}
HAL_StatusTypeDef SimpleCan::stop(){
return HAL_CAN_Stop(&hcan);
}
HAL_StatusTypeDef SimpleCan::configFilter(CAN_FilterTypeDef *filterDef){
// Default filter - accept all to CAN_FIFO*
CAN_FilterTypeDef sFilterConfig;
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterIdHigh = 0x00005;
sFilterConfig.FilterBank = 0x0000;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x00 ; // HE TOCADO ESTO !!!!!!!
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
return HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
}
HAL_StatusTypeDef SimpleCan::configSnniferFilter(){
// Default filter - accept all to CAN_FIFO*
CAN_FilterTypeDef sFilterConfig;
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterIdHigh = 0x00005;
sFilterConfig.FilterBank = 0x0000;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x200 << 5; //11-bit ID, in top bits
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
return HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
}
HAL_StatusTypeDef SimpleCan::send(CanMessage message){
uint32_t TxMailbox;
CAN_TxHeaderTypeDef pHeader;
pHeader.DLC= message.dlc;
message.isStandard ? pHeader.IDE=CAN_ID_STD : pHeader.IDE=CAN_ID_EXT;
message.isRTR ? pHeader.RTR=CAN_RTR_REMOTE : pHeader.RTR=CAN_RTR_DATA;
message.isStandard ? pHeader.StdId=0x200 : pHeader.ExtId=0x200;
return HAL_CAN_AddTxMessage(&hcan, &pHeader, (uint8_t*)message.data, &TxMailbox);
}
HAL_StatusTypeDef SimpleCan::activateNotification( /*RxHandler *rxHandler*/)
{/*
if (_rxHandler != NULL)
{
return HAL_ERROR;
}
_rxHandler = rxHandler;
*/
return HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
}
HAL_StatusTypeDef SimpleCan::deactivateNotification(){
// _rxHandler = NULL;
return HAL_CAN_DeactivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
}
// RxHandler Implementation
/*
SimpleCan::RxHandler::RxHandler(uint16_t dataLength, void (*callback)(CAN_RxHeaderTypeDef, uint8_t *))
{
_rxData = new byte[dataLength];
_callback = callback;
}
SimpleCan::RxHandler::~RxHandler()
{
delete[] _rxData;
}
void SimpleCan::RxHandler::notify(CAN_HandleTypeDef *hcan1)
{
if (SimpleCan::_rxHandler == NULL)
{
return;
}
SimpleCan::_rxHandler->notify(hcan1);
}
*/
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
digitalToggle(PC13);
/*
if (SimpleCan::_rxHandler == NULL)
{
return;
}
SimpleCan:_rxHandler->notify(hcan1);
*/
}
Code: Select all
#include <Arduino.h>
#include "stm32f4xx_hal_can.h"
#include <SimpleCan.h>
// This SystemClock_Config is copy&paste from CubeIDE
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
// Configure the main internal regulator output voltage
//
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
// Initializes the RCC Oscillators according to the specified parameters
// in the RCC_OscInitTypeDef structure.
//
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 100;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
// Initializes the CPU, AHB and APB buses clocks
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
{
Error_Handler();
}
}
/*
static void handleCanMessage(CAN_RxHeaderTypeDef rxHeader, uint8_t *rxData)
{
digitalToggle(PC13);
}
SimpleCan::RxHandler can1RxHandler(8, handleCanMessage);
*/
SimpleCan can;
void setup() {
Serial1.begin(115200);
pinMode(PC13,OUTPUT);
can.init(Kbit250,LoopBackCAN);
can.configSnniferFilter();
can.activateNotification( /*&can1RxHandler*/);
can.begin();
}
void loop() {
Serial1.println("Hola Can !!!");
//digitalToggle(PC13);
CanMessage msg = createMessage();
can.send(msg);
delay(10);
}
Code: Select all
[env:genericSTM32F405RG]
platform = ststm32
board = genericSTM32F405RG
board_build.f_cpu = 100000000L
framework = arduino
debug_tool = stlink
upload_protocol = stlink
build_flags =
-D HSE_VALUE=8000000
-D HAVE_HWSERIAL1
-D PIN_WIRE_SDA=PB11
-D PIN_WIRE_SCL=PB10
-D PIN_SPI_MOSI=PA7
-D PIN_SPI_MISO=PA6
-D PIN_SPI_SCK=PA5
-D PIN_SPI_SS=PA4
-D HAL_CAN_MODULE_ENABLED
monitor_speed = 115200
lib_deps =
askuric/Simple FOC@^2.0.2
Wire
SPI