Using CubeMX, TrueStudio, an STM32F767ZI, and HAL, I am developing software to access a USB Flash drive using FatFS though the USB host port.
The board has a host and device USB connector attached to the MCU.
Within CubeMX, I configured FreeRTOS, USB Host MSC, and FatFS.
This works, I can see these different states when plugging and unplugging the flash drive:
--- Plugging in USB flash drive ---
HOST_USER_CONNECTION
HOST_USER_CONNECTION
HOST_DEV_ATTACHED
phost->device.speed: 1
HOST_ENUMERATION
HOST_SET_CONFIGURATION
HOST_SET_WAKEUP_FEATURE
HOST_CHECK_CLASS
USBH_MSC_InterfaceInit
HOST_CLASS_REQUEST
USBH_MSC_ClassRequest
HOST_CLASS
USBH_MSC_Process
processId: 3, Appli_state 1
USBH_MSC_GetLUNInfo
info.capacity.block_nbr : 623395
info.capacity.block_size: 512
capacity : 3116 MB
HOST_USER_CLASS_ACTIVE
FATFS_LinkDriver Failed
USBDISKPath:
processId: 2, Appli_state 2
USBH_MSC_GetLUNInfo
info.capacity.block_nbr : 62333951
info.capacity.block_size: 512
capacity : 31166 MB
--- Unplugging USB flash drive ---
HOST_USER_DISCONNECTION
HOST_DEV_DISCONNECTED
USBH_MSC_InterfaceDeInit
processId: 5, Appli_state 3
USBH_MSC_GetLUNInfo
info.capacity.block_nbr : 62333951
info.capacity.block_size: 512
capacity : 31166 MB
So, after MX_USB_HOST_Init(); was called in freertos.c all the above happened.
FATFS_LinkDriver() is called from MX_FATFS_Init().
But the functions in usbh_diskio.c are not called, so something went wrong there.
The pieces of code I'm looking at are these:
freertos.c, where MX_USB_HOST_Init() is called, after this the MSC is registered.
/* StartDefaultTask function */
void StartDefaultTask(void const * argument)
{
/* init code for FATFS */
MX_FATFS_Init();
/* init code for LWIP */
MX_LWIP_Init();
/* init code for USB_HOST */
MX_USB_HOST_Init();
/* init code for USB_DEVICE */
MX_USB_DEVICE_Init();
/* init code for LIBJPEG */
MX_LIBJPEG_Init();
/* USER CODE BEGIN StartDefaultTask */
MSC_LUNTypeDef info;
uint8_t lun = 0;
uint16_t val = 0;
/* Infinite loop */
for(;;)
{
/* USB Host Background task */
// USBH_Process(&hUsbHostFS);
val++;
if (val >= 1000)
{
if (processIdOld != processId)
{
printf("processId: %d, Appli_state %d\n", processId, Appli_state);
processIdOld = processId;
USBH_MSC_GetLUNInfo(&hUSB_Host, lun, &info);
uint32_t cap = info.capacity.block_nbr / 2000;
printf("info.capacity.block_nbr : %ld\n", info.capacity.block_nbr);
printf("info.capacity.block_size: %d\n", info.capacity.block_size);
printf("capacity : %d MB\n", cap);
}
// printf("1");
// fflush(stdout);
// HAL_GPIO_TogglePin(PIO10_LED_RS_ERR_GPIO_Port, PIO10_LED_RS_ERR_Pin);
val = 0;
}
osDelay(1);
}
/* USER CODE END StartDefaultTask */
}
usb_host.c, where USB is initialized, and I can see USBH_UserProcess is called when I plug/unplug the USB flash drive.
void MX_USB_HOST_Init(void)
{
/* USER CODE BEGIN USB_HOST_Init_PreTreatment */
/* USER CODE END USB_HOST_Init_PreTreatment */
/* Init host Library, add supported class and start the library. */
USBH_Init(&hUsbHostFS, USBH_UserProcess, HOST_FS);
USBH_RegisterClass(&hUsbHostFS, USBH_AUDIO_CLASS);
USBH_RegisterClass(&hUsbHostFS, USBH_CDC_CLASS);
USBH_RegisterClass(&hUsbHostFS, USBH_MSC_CLASS);
USBH_RegisterClass(&hUsbHostFS, USBH_HID_CLASS);
USBH_RegisterClass(&hUsbHostFS, USBH_MTP_CLASS);
USBH_Start(&hUsbHostFS);
/* USER CODE BEGIN USB_HOST_Init_PostTreatment */
/* USER CODE END USB_HOST_Init_PostTreatment */
}
/*
* user callback definition
*/
static void USBH_UserProcess (USBH_HandleTypeDef *phost, uint8_t id)
{
/* USER CODE BEGIN CALL_BACK_1 */
switch(id)
{
case HOST_USER_SELECT_CONFIGURATION:
printf("HOST_USER_SELECT_CONFIGURATION\n");
break;
case HOST_USER_DISCONNECTION:
printf("HOST_USER_DISCONNECTION\n");
Appli_state = APPLICATION_DISCONNECT;
break;
case HOST_USER_CLASS_ACTIVE:
printf("HOST_USER_CLASS_ACTIVE\n");
Appli_state = APPLICATION_READY;
break;
case HOST_USER_CONNECTION:
printf("HOST_USER_CONNECTION\n");
Appli_state = APPLICATION_START;
break;
default:
break;
}
/* USER CODE END CALL_BACK_1 */
}
The above part works fine, sofar.
Except the linking of the usbh driver.
Has anybody used this or know good working examples?
Related
I am using ESP8266 with STM32F103. The ESP receives the AT-command correctly and executes it, and I can receive the echo characters, but when it comes to the ESP response I can't receive anything.
Here is a pic to demonstrate the issue:
https://drive.google.com/file/d/19Of8ENNDDB0YAV5H5HuamcWF_OwV8JSj/view?usp=sharing
For instance: I send ATE0 to stop the echo, the ESP executes the command and there is no echo anymore, but I can't receive "OK" or "WIFI CONNECTED" or any other response.
I have tried putty and it worked without any problems in sending or receiving, so the ESP is fine.
I am using 115200 Baud rate, and this is my code:
main:
void main(void)
{
/* Init RCC */
RCC_voidInitSysClock();
/* Enable Clock For GPIOA & UART1 */
RCC_voidEnableClock(RCC_APB2,GPIOA_BUS);
RCC_voidEnableClock(RCC_APB2,14);
/* Set TX and Rx Directions */
MGPIO_voidSetPinDirection(GPIOA, PIN9 ,OUTPUT_SPEED_2MHZ_AFPP); /* TX */
MGPIO_voidSetPinDirection(GPIOA, PIN10 ,INPUT_FLOATING); /* RX */
/* Set Direction For Pin 0 To power Led */
MGPIO_voidSetPinDirection(GPIOA, PIN0 ,OUTPUT_SPEED_10MHZ_PP);
/* Enable UART1 Interrupt */
MNVIC_voidEnableInterrupt(USART1_ID);
/* Init UART1 */
MUART_voidInit();
/* Init ESP */
HESP_voidInit();
/* Connect To WIFI Network */
HESP_voidConnecttoWifi("Androidap","111112222");
//HESP_voidConnectToServerTCP("162.253.155.226","80");
//HESP_u8ReceiveResponse("Abdullaharm.freevar.com/status.txt","47");
while(1)
{
}
}
Implementation of ESP_init and connect to WIFI functions:
void HESP_voidInit(void)
{
//MUART_voidTransmitSynch("AT\r\n");
/* Stop Echo */
MUART_voidTransmitSynch("ATE0\r\n");
/* Set Station Mode */
MUART_voidTransmitSynch("AT+CWMODE=1\r\n");
MSYSTICK_voidSetBusyWait(1000);//microseconds
}
void HESP_voidConnecttoWifi(uint8* Copy_u8SSID , uint8* Copy_u8Pass)
{
/* Connect to WIFI network */
MUART_voidTransmitSynch("AT+CWJAP_CUR=\"");
MUART_voidTransmitSynch(Copy_u8SSID);
MUART_voidTransmitSynch("\",\"");
MUART_voidTransmitSynch(Copy_u8Pass);
MUART_voidTransmitSynch("\"\r\n");
}
Implementaion of UART_TransmitSynch:
void MUART_voidTransmitSynch(uint8 arr[])
{
uint8 i=0;
while(arr[i] != '\0')
{
UART1 -> DR = arr[i];
/* wait till transmission is complete */
while (!(UART1->SR & (1<<6)));
i++;
MSYSTICK_voidSetBusyWait(2000); //microseconds
}
}
I am using interrupt to receive from the ESP and this is the code inside ISR:
void USART1_IRQHandler(void)
{
if(GET_BIT(UART1 -> SR , 5))
{
static uint8 Data_Counter=0;
if(UART1 -> DR !='\0')
{
Data_Received_int[Data_Counter]=UART1 -> DR;
Data_Counter++;
}
else
{
Data_Counter=0;
}
CLR_BIT(UART1 -> SR , 5);
}
//UART_CallBackPtr();
}
Good day
The goal:
I am trying to configure FreeRTOS and LwIP so that I can set up MQTT.
I am using a STM32-NucleoF429ZI development board
What I have done:
I am using CubeMX to generate project files and I am using Visual Studio and VisualGDB for compiling and debugging.
I have set up FreeRTOS for the dev board using CMSIS_V2 and Heap_4.
I have set up LwIP with: Static IP and MEM_SIZE of 1024*10
I have kept all standard pinout (i.e. I have note cleared pinouts) of nucleo board
Ive set up an "Ethernet" thread and I am blinking and LED on the ethernet thread and the default thread.
Other than that no other setting has been changed. I did not set the MPU because as far as I can tell, this MCU does not have it.
The problem:
If I comment out the line MX_LWIP_Init();, (which cubeMX puts into the default thread), then the board runs fine and both LED's on both threads blink forever as far as I have tested. However, as soon as I leave MX_LWIP_Init();, FreeRTOS gets stuck as shown in the picture.
This occurs anywhere from 30 seconds to many minutes after powering the board
Please excuse the picture, but it shows where exactly the program is when I pause it. If I resume the debugger and pause it again, it always pauses in the same place.
I have tried moving MX_LWIP_Init(); into main.c with the other init functions and also into the ethernet thread where it should belong. All produce the same error at some point.
I can ping the board once I add MX_LWIP_Init();
freertos.c
/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name : freertos.c
* Description : Code for freertos applications
******************************************************************************
* #attention
*
* Copyright (c) 2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "config.h"
#include "EthernetLwIP_thread.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
/* USER CODE END Variables */
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
.name = "defaultTask",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
/* USER CODE END FunctionPrototypes */
void StartDefaultTask(void *argument);
extern void MX_LWIP_Init(void);
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
/**
* #brief FreeRTOS initialization
* #param None
* #retval None
*/
void MX_FREERTOS_Init(void) {
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */
/* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
/* USER CODE END RTOS_QUEUES */
/* Create the thread(s) */
/* creation of defaultTask */
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
/* USER CODE BEGIN RTOS_THREADS */
if (EthernetModule_Init() == Result_Successful)
{
logger("template module successfully initialized!!!");
}
/* USER CODE END RTOS_THREADS */
/* USER CODE BEGIN RTOS_EVENTS */
/* add events, ... */
/* USER CODE END RTOS_EVENTS */
}
/* USER CODE BEGIN Header_StartDefaultTask */
/**
* #brief Function implementing the defaultTask thread.
* #param argument: Not used
* #retval None
*/
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
/* init code for LWIP */
//MX_LWIP_Init();
/* USER CODE BEGIN StartDefaultTask */
// Task timing
TickType_t xLastWakeTime;
xLastWakeTime = xTaskGetTickCount();
const TickType_t xDelay_Ticks = 1000; // Current RTOS clock config has 1 tick equal 1ms. Thus 20 ticks sets a frequency of 50Hz
/* Infinite loop */
while (1)
{
vTaskDelayUntil(&xLastWakeTime, xDelay_Ticks); // waits until a certain number of ticks have passed before it starts this task again in a timely manner
HAL_GPIO_TogglePin(LED_BLUE_PORT, LED_BLUE_PIN);
//HAL_GPIO_TogglePin(LED_RED_PORT, LED_RED_PIN);
//HAL_GPIO_TogglePin(LED_GREEN_PORT, LED_GREEN_PIN);
}
/* USER CODE END StartDefaultTask */
}
/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
/* USER CODE END Application */
Ethernet src file
/* Ethernet_thread.c */
// Includes: ----------------------------------------------------------
#include "EthernetLwIP_thread.h"
#include "config.h"
// Instantiations: ----------------------------------------------------
// Thread declaration: ------------------------------------------------
osThreadId_t EthernetModule_ThreadId;
const osThreadAttr_t EthernetModule_Attributes = {
.name = "EthernetModule",
.priority = (osPriority_t) osPriorityHigh,
.stack_size = 1024 * 4 // This needs to be optimized at a later stage
};
void EthernetModule_Thread(void *argument);
// Functions: --------------------------------------------------------
// Initializing functions: ---------------------------------------------------------------------
MResult EthernetModule_HardwareInit()
{
return Result_Successful;
}
MResult EthernetModule_Init() {
MX_LWIP_Init();
if (EthernetModule_HardwareInit() == Result_Error)
return Result_Error;
EthernetModule_ThreadId = osThreadNew(EthernetModule_Thread, NULL, &EthernetModule_Attributes);
if (EthernetModule_ThreadId == NULL)
return Result_Error;
return Result_Successful;
}
// Thread: ---------------------------------------------------------------------------------------
void EthernetModule_Thread(void *argument)
{
// Task timing
TickType_t xLastWakeTime;
xLastWakeTime = xTaskGetTickCount();
const TickType_t xDelay_Ticks = 500;
while (1)
{
vTaskDelayUntil(&xLastWakeTime, xDelay_Ticks);
HAL_GPIO_TogglePin(LED_GREEN_PORT, LED_GREEN_PIN);
}
}
I am not sure the cause of this problem, but I have changed from FreeRTOS CMSIS_V2 to CMSIS_V1 and it resolved the issue. I dont know if there is a configuration in CMSIS_V2 that was wrong, or if there is an actual bug, but CMSIS_V1 and LwIP works great now.
The size of my buffer is 4096 and I want to fill the buffer with the adc values that are read.
#define ADC_BUF_LEN 4096
uint16_t adc_buf[ADC_BUF_LEN];
I am using this function to start the reading process of the ADC using DMA
HAL_ADC_Start_DMA(&hadc2, (uint32_t*)adc_buf, ADC_BUF_LEN);
Here are my configurations for the ADC
hadc2.Instance = ADC2;
hadc2.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV6;
hadc2.Init.Resolution = ADC_RESOLUTION_12B;
hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc2.Init.ContinuousConvMode = ENABLE;
hadc2.Init.DiscontinuousConvMode = DISABLE;
hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc2.Init.NbrOfConversion = 1;
hadc2.Init.DMAContinuousRequests = ENABLE;
hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
if (HAL_ADC_Init(&hadc2) != HAL_OK)
{
Error_Handler();
}
This my DMA configuration
/**
* Enable DMA controller clock
*/
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA2_CLK_ENABLE();
/* DMA interrupt init */
/* DMA2_Stream2_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
}
These are my interrupt functions. I set a toggle breakpoint on the first interrupt and when I debug, the LED does not turn on which suggests that the DMA isn't working?
/* USER CODE BEGIN 4 */
//Called when first half of buffer is filled
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc) {
//HAL_ADC_GetValue(&hadc2);
HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, GPIO_PIN_SET);
}
//Called when buffer is completely filled
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){
HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, GPIO_PIN_RESET);
}
I set the prescaled to be divided by 6 if this information helps.
Please give me some advice!
Thank you in advance.
I want to use both CAN1 and CAN2 for my application with 500kbps and 125kbps speeds respectively. I have initialized both of them as per my requirements using HAL. Where in Tx is implemented in polling and Rx in interrupts. CAN1 Tx and Rx working perfect. Coming to CAN2 Tx is working and Rx is not working. Interrupt itself is not firing up for CAN2 Rx (HAL_CAN_RxFifo0MsgPendingCallback is not being called). I've read in datasheet that SRAM sharing process is happening between 2 CANs. I'm unable to comprehend that. Is that an issue?
I'm attaching the code also. Please check and help!
Little overview - all MCU clocks running at - 16 MHz using internal HSI, No filter in CAN configs
################ MAIN FILE ####################
/* Private variables ---------------------------------------------------------*/
CAN_HandleTypeDef hcan1;
CAN_HandleTypeDef hcan2;
/* USER CODE BEGIN PV */
CAN_TxHeaderTypeDef txheader;
uint8_t txdata[8];
CAN_RxHeaderTypeDef RxHeader;
uint8_t RxData[8];
CAN_TxHeaderTypeDef txheader1;
uint8_t txdata1[8];
CAN_RxHeaderTypeDef RxHeader1;
uint8_t RxData1[8];
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_CAN1_Init(void);
static void MX_CAN2_Init(void);
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t fill = 0;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_CAN1_Init();
MX_CAN2_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
txheader.DLC = 8;
txheader.ExtId = 0x11111111;
txheader.IDE = CAN_ID_EXT;
txheader.RTR = CAN_RTR_DATA;
for(uint8_t i = 0; i<8;i++)
{
txdata[i] = i;
}
// txdata[0] = fill;
HAL_Delay(250);
HAL_CAN_AddTxMessage(&hcan1,&txheader,txdata, (uint32_t *)CAN_TX_MAILBOX0);
HAL_Delay(250);
HAL_CAN_AddTxMessage(&hcan2,&txheader,txdata, (uint32_t *)CAN_TX_MAILBOX0);
}
/* USER CODE END 3 */
}
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_SCALE3);
/** 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_NONE;
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_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
/**
* #brief CAN1 Initialization Function
* #param None
* #retval None
*/
static void MX_CAN1_Init(void)
{
/* USER CODE BEGIN CAN1_Init 0 */
CAN_FilterTypeDef sFilterConfig;
/* USER CODE END CAN1_Init 0 */
/* USER CODE BEGIN CAN1_Init 1 */
/* USER CODE END CAN1_Init 1 */
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 2;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_13TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = DISABLE;
hcan1.Init.AutoWakeUp = DISABLE;
hcan1.Init.AutoRetransmission = DISABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN1_Init 2 */
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
{
/* Filter configuration Error */
Error_Handler();
}
HAL_CAN_Start(&hcan1);
/*##-4- Activate CAN RX notification #######################################*/
if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
{
/* Notification Error */
Error_Handler();
}
/* USER CODE END CAN1_Init 2 */
}
/**
* #brief CAN1 Initialization Function
* #param None
* #retval None
*/
static void MX_CAN2_Init(void)
{
/* USER CODE BEGIN CAN1_Init 0 */
CAN_FilterTypeDef sFilterConfig;
/* USER CODE END CAN1_Init 0 */
/* USER CODE BEGIN CAN1_Init 1 */
/* USER CODE END CAN1_Init 1 */
hcan2.Instance = CAN2;
hcan2.Init.Prescaler = 8;
hcan2.Init.Mode = CAN_MODE_NORMAL;
hcan2.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan2.Init.TimeSeg1 = CAN_BS1_13TQ;
hcan2.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan2.Init.TimeTriggeredMode = DISABLE;
hcan2.Init.AutoBusOff = DISABLE;
hcan2.Init.AutoWakeUp = DISABLE;
hcan2.Init.AutoRetransmission = DISABLE;
hcan2.Init.ReceiveFifoLocked = DISABLE;
hcan2.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN1_Init 2 */
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
if (HAL_CAN_ConfigFilter(&hcan2, &sFilterConfig) != HAL_OK)
{
/* Filter configuration Error */
Error_Handler();
}
HAL_CAN_Start(&hcan2);
/*##-4- Activate CAN RX notification #######################################*/
if (HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
{
/* Notification Error */
Error_Handler();
}
/* USER CODE END CAN1_Init 2 */
}
/**
* #brief GPIO Initialization Function
* #param None
* #retval None
*/
static void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
}
/* USER CODE BEGIN 4 */
/**
* #brief Rx Fifo 0 message pending callback
* #param hcan: pointer to a CAN_HandleTypeDef structure that contains
* the configuration information for the specified CAN.
* #retval None
*/
uint8_t cflag;
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
/* Get RX message */
if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
{
/* Reception Error */
Error_Handler();
}
/* Display LEDx */
if ((RxHeader.StdId == 0x321) && (RxHeader.IDE == CAN_ID_STD) && (RxHeader.DLC == 2))
{
}
/* Display LEDx */
if ((RxHeader.ExtId == 0x11111111) && (RxHeader.IDE == CAN_ID_EXT) && (RxHeader.DLC == 8))
{
cflag = 1;
}
else
cflag = 0;
}
/* USER CODE END 4 */
##################### MSP FILE ######################
/**
* Initializes the Global MSP.
*/
void HAL_MspInit(void)
{
/* USER CODE BEGIN MspInit 0 */
/* USER CODE END MspInit 0 */
__HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_RCC_PWR_CLK_ENABLE();
/* System interrupt init*/
/* USER CODE BEGIN MspInit 1 */
/* USER CODE END MspInit 1 */
}
static uint32_t HAL_RCC_CAN1_CLK_ENABLED=0;
/**
* #brief CAN MSP Initialization
* This function configures the hardware resources used in this example
* #param hcan: CAN handle pointer
* #retval None
*/
void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hcan->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspInit 0 */
/* USER CODE END CAN1_MspInit 0 */
/* Peripheral clock enable */
HAL_RCC_CAN1_CLK_ENABLED++;
if(HAL_RCC_CAN1_CLK_ENABLED==1){
__HAL_RCC_CAN1_CLK_ENABLE();
}
__HAL_RCC_GPIOA_CLK_ENABLE();
/**CAN1 GPIO Configuration
PA11 ------> CAN1_RX
PA12 ------> CAN1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
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(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN CAN1_MspInit 1 */
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
/* USER CODE END CAN1_MspInit 1 */
}
else if(hcan->Instance==CAN2)
{
/* USER CODE BEGIN CAN2_MspInit 0 */
/* USER CODE END CAN2_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_CAN2_CLK_ENABLE();
HAL_RCC_CAN1_CLK_ENABLED++;
if(HAL_RCC_CAN1_CLK_ENABLED==1){
__HAL_RCC_CAN1_CLK_ENABLE();
}
__HAL_RCC_GPIOB_CLK_ENABLE();
/**CAN2 GPIO Configuration
PB12 ------> CAN2_RX
PB13 ------> CAN2_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13;
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_CAN2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* CAN2 interrupt Init */
HAL_NVIC_SetPriority(CAN2_RX0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn);
/* USER CODE BEGIN CAN2_MspInit 1 */
/* USER CODE END CAN2_MspInit 1 */
}
}
/**
* #brief CAN MSP De-Initialization
* This function freeze the hardware resources used in this example
* #param hcan: CAN handle pointer
* #retval None
*/
void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
{
if(hcan->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspDeInit 0 */
/* USER CODE END CAN1_MspDeInit 0 */
/* Peripheral clock disable */
HAL_RCC_CAN1_CLK_ENABLED--;
if(HAL_RCC_CAN1_CLK_ENABLED==0){
__HAL_RCC_CAN1_CLK_DISABLE();
}
/**CAN1 GPIO Configuration
PA11 ------> CAN1_RX
PA12 ------> CAN1_TX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
/* USER CODE BEGIN CAN1_MspDeInit 1 */
/* USER CODE END CAN1_MspDeInit 1 */
}
else if(hcan->Instance==CAN2)
{
/* USER CODE BEGIN CAN2_MspDeInit 0 */
/* USER CODE END CAN2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_CAN2_CLK_DISABLE();
HAL_RCC_CAN1_CLK_ENABLED--;
if(HAL_RCC_CAN1_CLK_ENABLED==0){
__HAL_RCC_CAN1_CLK_DISABLE();
}
/**CAN2 GPIO Configuration
PB12 ------> CAN2_RX
PB13 ------> CAN2_TX
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_12|GPIO_PIN_13);
/* CAN2 interrupt DeInit */
HAL_NVIC_DisableIRQ(CAN2_RX0_IRQn);
/* USER CODE BEGIN CAN2_MspDeInit 1 */
/* USER CODE END CAN2_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
######################### IT FILE #############################
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx_it.h"
/* External variables --------------------------------------------------------*/
extern CAN_HandleTypeDef hcan2;
/**
* #brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
/******************************************************************************/
/* STM32F4xx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */
/* For the available peripheral interrupt handler names, */
/* please refer to the startup file (startup_stm32f4xx.s). */
/******************************************************************************/
/**
* #brief This function handles CAN2 RX0 interrupt.
*/
void CAN2_RX0_IRQHandler(void)
{
/* USER CODE BEGIN CAN2_RX0_IRQn 0 */
/* USER CODE END CAN2_RX0_IRQn 0 */
HAL_CAN_IRQHandler(&hcan2);
/* USER CODE BEGIN CAN2_RX0_IRQn 1 */
/* USER CODE END CAN2_RX0_IRQn 1 */
}
/* USER CODE BEGIN 1 */
/**
* #brief This function handles CAN1 RX0 interrupt request.
* #param None
* #retval None
*/
extern CAN_HandleTypeDef hcan1;
void CAN1_RX0_IRQHandler(void)
{
HAL_CAN_IRQHandler(&hcan1);
}
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
I solved my problem. Got help from ST community. Please refer to the link below.
https://community.st.com/s/feed/0D53W00000RQCwgSAH?t=1608012202888
Problem was filter configuration for CAN1 and CAN2. There are 28 filter banks (0-27) split between CAN1 and CAN2. First half (0-13) for CAN1 and the rest for CAN2. So just make some changes in the code posted above -
CAN 1:
sFilterConfig.FilterBank = 0;
:
sFilterConfig.SlaveStartFilterBank = 14;
CAN2:
sFilterConfig.FilterBank = 14; // previously 0
:
sFilterConfig.SlaveStartFilterBank = 14; // previously 27
Thanks to Lundin for suggesting sync point. Use this website for CAN Bit time calculations for various chips -
http://www.bittiming.can-wiki.info/
I am trying to read informations from a external sensor by USART, using a Nucleo stm32wb board. The sensor is using a 9600 baud rate and I know that it is fonctionnal. My pin connections are also good.
Furthermore, I can see on my logic analyzer that data are always sent.
The problem is that I always got a receive timeout no matter what timeout using.
Here is my code :
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
HW_RTC_Init();
/* USER CODE BEGIN 2 */
int incomingBytes[100];
uint8_t d = 'a';
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_UART_Receive(&huart1, &d, 1, 1000);
if(d == 0x42){
incomingBytes[0] = d;
for(int i = 1;i<31;i++){
HAL_UART_Receive(&huart1, &d, 1, 1000);
incomingBytes[i] = d;
}
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* #brief USART1 Initialization Function
* #param None
* #retval None
*/
static void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
Any idea of what I could forgot?