STM32F1xx CAN2 receive interrupt not being called - c

I've successfully established CAN communication with CAN1 of two STM32F105vC(s)(Which has two CANs), and I can send and receive CAN frames.
But when I change my code to use CAN2, it works, I mean it acknowledges the received CAN frames but the receive interrupt is not being called at all.
I thought it's filter configuration, I changed the BankNumber multipletimes (tried 0, 1, 14, 20), no luck.
Here is my configurations:
Initilizing:
init_HAL_CAN(CAN2);
if(HAL_CAN_Receive_IT(canHandle, CAN_FIFO0) != HAL_OK)
{
/* Reception Error */
Error_Handler();
}
Receive callback:
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* CanHandle)
{
LED_DBG_TOGGLE();
// other
// stuff
// here
//...
/* Receive */
if(HAL_CAN_Receive_IT(CanHandle, CAN_FIFO0) != HAL_OK)
{
/* Reception Error */
Error_Handler();
}
}
Init function:
void init_HAL_CAN(CAN_TypeDef* _CANInstance)
{
CAN_FilterConfTypeDef sFilterConfig;
static CanTxMsgTypeDef TxMessage;
static CanRxMsgTypeDef RxMessage;
/*##-1- Configure the CAN peripheral #######################################*/
canHandle->Instance = _CANInstance;
canHandle->pTxMsg = &TxMessage;
canHandle->pRxMsg = &RxMessage;
canHandle->Init.TTCM = DISABLE; //Non time trigger communication mode //
canHandle->Init.ABOM = DISABLE; //The software automatically Bus-off management //
canHandle->Init.AWUM = DISABLE; //Sleep mode wake by software (clear CAN-> MCR SLEEP) (automatic wake-up mode)//
canHandle->Init.NART = DISABLE; //Disable automatic transfer message (non-automatic retransmission mode)//
canHandle->Init.RFLM = DISABLE; //The message is not locked, the new cover the old //
canHandle->Init.TXFP = DISABLE; // Priority is determined by the message identifier //
canHandle->Init.Mode = CAN_MODE_NORMAL;
canHandle->Init.SJW = CAN_SJW_1TQ;
canHandle->Init.BS1 = CAN_BS1_2TQ;
canHandle->Init.BS2 = CAN_BS2_1TQ;
canHandle->Init.Prescaler = 7;
if(HAL_CAN_Init(canHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
return false;
}
/*##-2- Configure the CAN Filter ###########################################*/
CAN_FilterConfTypeDef sFilterConfig;
sFilterConfig.FilterNumber = 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 = 0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.BankNumber = 20;
if (HAL_CAN_ConfigFilter(canHandle, &sFilterConfig) != HAL_OK)
{
/* Filter configuration Error */
Error_Handler();
return false;
}
}
IRQHandler (placed in stm32f1xx_it.c):
void CAN2_RX0_IRQHandler(void)
{
HAL_CAN_IRQHandler(canHandle);
}
MspInit function (placed in stm32f1xx_hal_msp.c) :
void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan)
{
GPIO_InitTypeDef GPIO_InitStruct;
/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* CAN1 Periph clock enable */
CANx1_CLK_ENABLE(); // Need to enable CAN1 clock too.
CANx2_CLK_ENABLE();
/* Enable GPIO clock ****************************************/
CANx2_GPIO_CLK_ENABLE();
/* CAN2 needs no remapping *******/
/*##-2- Configure peripheral GPIO ##########################################*/
/* CAN1 TX GPIO pin configuration */
GPIO_InitStruct.Pin = CANx2_TX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(CANx2_TX_GPIO_PORT, &GPIO_InitStruct);
/* CAN1 RX GPIO pin configuration */
GPIO_InitStruct.Pin = CANx2_RX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(CANx2_RX_GPIO_PORT, &GPIO_InitStruct);
/*##-3- Configure the NVIC #################################################*/
/* NVIC configuration for CAN2 Reception complete interrupt */
HAL_NVIC_SetPriority(CAN2_RX0_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn);
}
I should mention again, that following codes works perfectly with CAN1 (of course with changing CAN2 to CAN1, etc).
And it's clear that the CAN controller is working because the other board that is transmitting CAN frames, receives the acknowledges (and does not get any transmitting error or timeout), the only problem here is Receive Interrupts, why?

I had similar issue and what help was reference manual:
CAN2SB[5:0]: CAN2 start bank
These bits are set and cleared by software. They define the start bank for the CAN2
interface (Slave) in the range 0 to 27.
Note: When CAN2SB[5:0] = 28d, all the filters to CAN1 can be used.
When CAN2SB[5:0] is set to 0, no filters are assigned to CAN1
sFilterConfig.BankNumber = 20;
Please change
sFilterConfig.BankNumber = 20;
to
sFilterConfig.BankNumber = 0x2d;

You must perform settings of all filters through hcan1. Even for Can2.
In connectivity line
devices, the registers from offset 0x200 to 31C are present only in CAN1.
...and on offset 0x200 begins filter settings...

Related

STM32H743 nucleo board, using the 3 ADCs at once (1 ADC at a time) on polling mode; doesn´t work

I am working on a project where a STM32H743 nucleo board and use of 16 ADC inputs are involved.
Obviously, these analog inputs are used once a time; read the value via polling mechanism and configure the next input... configure the ADC channel, start the ADC, read the value via polling and configure the next input... 16 times each 1 ms, as a Real-Time behaviour.
The problem I found is that I can´t start any of the 3 ADCs, it stuck at this line at
stm32h7xx_hal_adc.h (I think that I configure the clocks or another sort of things incorrectly) :
while(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_RDY) == 0UL)
This line is in the function:
HAL_StatusTypeDef ADC_Enable(ADC_HandleTypeDef *hadc)
That is being called by:
HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef *hadc)
Thanks in advance for the help, the source code is provided below.
The source code files are:
MAIN.C
#include "main.h"
#include "hwdrvlib.h"
#include "test.h"
volatile unsigned int systick_count = 0;
static volatile int systick_active = 1;
/**
* #brief The application entry point.
* #retval int
*/
int main(void)
{
#ifdef CPU_CACHE
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
#endif
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config(); //Located on hwdrvlid.h y hwdrvlib.c
/* SysTick is 0 at start */
tick = (uint8_t)0;
/* Initialize */
ADC_Init(); /* Initialize ADC peripherals and GPIO ADC inputs as analog */
//Located on hwdrvlid.h y hwdrvlib.c
/* Sample Time: 0.001 */
while (...) { /* Some comparison deleted for readability */
RT_Task(); //Located on Function file
} //End of while
}
hwdrvlib.c (The file that contains configuration functions)
ADC_HandleTypeDef hadc1 __attribute__((section(".ramd2")));
ADC_HandleTypeDef hadc2 __attribute__((section(".ramd2")));
ADC_HandleTypeDef hadc3 __attribute__((section(".ramd2")));
void ADC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* ADC Clock Enable */
__HAL_RCC_ADC12_CLK_ENABLE();
__HAL_RCC_ADC3_CLK_ENABLE();
/* ADC Periph interface clock configuration */
__HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP);//or PLL2
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/* ADCs GPIO as analog input */
/* System ADC Input number 1 PF9 */
/*##-2- Configure peripheral GPIO ##########################################*/
/* ADC Channel GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
/* Initialization of 16 analog inputs, hidden for readability */
/* System ADC Input number 16 PA3 */
/*##-2- Configure peripheral GPIO ##########################################*/
/* ADC Channel GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* ADC1 Config */
hadc1.Instance = ADC1;
if (HAL_ADC_DeInit(&hadc1) != HAL_OK) {
/* ADC1 de-initialization Error */
Error_Handler();
}
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc1.Init.Resolution = ADC_RESOLUTION_16B;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.NbrOfConversion = 1; /* Vector Support */
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.NbrOfDiscConversion = 1;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
hadc1.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc1) != HAL_OK) {
Error_Handler();
}
/* The same for ADC2 and ADC3 using hadc2 and hadc3 */
}
void ADC_Input_Select(ADC_HandleTypeDef *hadc,uint32_t Channel)
{
static ADC_ChannelConfTypeDef sConfig = { 0 };
/* Configure Regular Channel */
sConfig.Channel = Channel;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_387CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(hadc, &sConfig) != HAL_OK) {
Error_Handler();
}
}
/**
* #brief System Clock Configuration
* #retval None
*
*
*
* Configure 480 MHz CPU Clock, 240 MHz APB1 and APB2 Clock
* flash latency 4
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = { 0 };
RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 };
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 };
/** Supply configuration update enable
*/
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
/* The voltage scaling allows optimizing the power consumption when the device is
clocked below the maximum system frequency, to update the voltage scaling value
regarding system frequency refer to product datasheet. */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {
}
__HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {
}
__HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_HSI);//HSE
/* a 480 MHz config */
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {
}
/** Initializes the CPU, AHB and APB busses clocks
*/
#ifdef USB_VCP_SETUP
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 |
RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_DIV1;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 60;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLQ = 2;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
#else
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_DIV1;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 60;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLQ = 2;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
#endif
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
Error_Handler();
}
/* End of old 480 MHz config */
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
|RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) {
Error_Handler();
}
/* USB CLK Initialization if needed */
#ifdef USB_VCP_SETUP
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB;
PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;//PLL
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {
Error_Handler();
}
/** Enable USB Voltage detector
*/
HAL_PWREx_EnableUSBVoltageDetector();
#endif
}
FUNCTION FILE
(The function that contains the function to be executed, in order to read analog input data)
void RT_Task(void)
{
/* ADC3-IN2 PF9 */
ADC_Input_Select(&hadc3,ADC_CHANNEL_2);
HAL_ADC_Start(&hadc3); /* Execution stucks here :( */
if (HAL_ADC_PollForConversion(&hadc3,1000) != HAL_OK ) {
/* ADC conversion fails */
//Escribir aqui la salida de error
} else {
test2_B.VectorConcatenate[1] = HAL_ADC_GetValue(&hadc3) + 0;
}
/* More ADC reading hidden for readability */
}
Solution for this problem, remember that you can face this with any microcontroller:
I found the failure, it is something that I never imagine before.
The initialization function takes more time that the SysTick IRQ needs to trigger the first IRQ (the Real-Time task is called from the SysTick IRQ), and due to ADC peripherals are not initialized... its functions could not be executed properly.
I added an uint8 variable to detect if the initialization function ends at RT Task call start code. Also I need to enable ADC_ConfigureBoostMode(&hadc1); for each used ADC.
int main(void)
{
Init_finished = (uint8_t)0;
#ifdef CPU_CACHE
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
#endif
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* SysTick is 0 at start */
tick = (uint8_t)0;
/* Initialize model */
test_initialize(1);
Init_finished = (uint8_t)255;
and use these
ADC_ConfigureBoostMode(&hadc1); /* and for hadc2 and hadc3 */

STM32L0 LoRaWAN Discovery Board: Trigger RTC Alarm Every 250 Milliseconds

Ultimately, what I would like to do is to trigger an alarm to wake up the STM32L0 every 250 milliseconds, do some functionality, and then go back into sleep mode. What I am attempting to do now with this code as a proof of concept for the RTC Alarm. It is to trigger the alarm every second. This is confirmed by the wake_up_flag=1 in the alarm callback. I am using a custom printf function and a function to show RTC time and the value of the wake up flag, which I excluded to focus on the code related to my problem.
The problem is the RTC seems to be working and keeping track of time, but the alarm callback never triggers and I do not have any idea why. I produced most of this code with STM32CubeIDE and to the best of my knowledge, enabled everything I needed to. I am new to STM32CubeIDE and any help would be greatly appreciated. Thank you in advanced.
Main Loop:
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_SPI1_Init();
MX_USART2_UART_Init();
MX_RTC_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
RTC_TimeShow();
my_printf("WAKE UP FLAG %d\n" ,wake_up_flag);
if(wake_up_flag == 1){
wake_up_flag = 0;
my_printf("WOKE UP");
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_Delay(1000);
}
/* USER CODE END 3 */
}
Alarm Callback:
void HAL_RTC_AlarmEventCallback(RTC_HandleTypeDef *hrtc){
wake_up_flag = 1;
}
RTC Initialization:
static void MX_RTC_Init(void)
{
/* Enable the RTC Alarm Interrupt */
/* USER CODE BEGIN RTC_Init 0 */
/* USER CODE END RTC_Init 0 */
RTC_TimeTypeDef sTime = {0};
RTC_DateTypeDef sDate = {0};
RTC_AlarmTypeDef sAlarm = {0};
/* USER CODE BEGIN RTC_Init 1 */
/* USER CODE END RTC_Init 1 */
/** Initialize RTC Only
*/
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127;
hrtc.Init.SynchPrediv = 255;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
if (HAL_RTC_Init(&hrtc) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN Check_RTC_BKUP */
/* USER CODE END Check_RTC_BKUP */
/** Initialize RTC and set the Time and Date
*/
sTime.Hours = 0x0;
sTime.Minutes = 0x0;
sTime.Seconds = 0x0;
sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sTime.StoreOperation = RTC_STOREOPERATION_RESET;
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
sDate.WeekDay = RTC_WEEKDAY_MONDAY;
sDate.Month = RTC_MONTH_JANUARY;
sDate.Date = 0x1;
sDate.Year = 0x0;
if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
/** Enable the Alarm A
*/
sAlarm.AlarmTime.Hours = 0x0;
sAlarm.AlarmTime.Minutes = 0x0;
sAlarm.AlarmTime.Seconds = 0x0;
sAlarm.AlarmTime.SubSeconds = 0x0;
sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
sAlarm.AlarmMask = RTC_ALARMMASK_ALL;
sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_NONE;
sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
sAlarm.AlarmDateWeekDay = 0x1;
sAlarm.Alarm = RTC_ALARM_A;
if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
}
GPIO Configuration:
/**
* #brief GPIO Initialization Function
* #param None
* #retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, PA15_RESERVED_Pin|PA12_RESERVED_Pin|PA1_RESERVED_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, PC1_RESERVED_Pin|PC0_RESERVED_Pin|PC2_RESERVED_Pin, GPIO_PIN_RESET);
/*Configure GPIO pins : PA15_RESERVED_Pin PA12_RESERVED_Pin PA1_RESERVED_Pin */
GPIO_InitStruct.Pin = PA15_RESERVED_Pin|PA12_RESERVED_Pin|PA1_RESERVED_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : PB4_RESERVED_Pin PB1_RESERVED_Pin PB0_RESERVED_Pin */
GPIO_InitStruct.Pin = PB4_RESERVED_Pin|PB1_RESERVED_Pin|PB0_RESERVED_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pin : PC13_RESERVED_Pin */
GPIO_InitStruct.Pin = PC13_RESERVED_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(PC13_RESERVED_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : PC1_RESERVED_Pin PC0_RESERVED_Pin PC2_RESERVED_Pin */
GPIO_InitStruct.Pin = PC1_RESERVED_Pin|PC0_RESERVED_Pin|PC2_RESERVED_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI0_1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);
HAL_NVIC_SetPriority(EXTI4_15_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
}
I ended up needing to modify the RTC.h and RTC.c file with another RTC type like as follows:
In RTC.h, I modified and added another Alarm match for 250 milliseconds as below.
enum AlarmMatch: uint8_t {
MATCH_250MS = 7, //Every 256 milliseconds
MATCH_ANY = 0, // Every Second
MATCH_SS = 1, // Every Minute
MATCH_MMSS = 2, // Every Hour
MATCH_HHMMSS = 3, // Every Day
MATCH_DHHMMSS = 4, // Every Month
MATCH_MMDDHHMMSS = 5, // Every Year
MATCH_YYMMDDHHMMSS = 6, // Once, on a specific date and a specific time
};
In RTC.c , in the void RTCClass::AdvanceAlarm() function, I added the following to the alarm switch. The second parameter was based on seconds. The key was that the third parameter is based on the 32.768KHz crystal (32,768 oscillations per second), so if you want 250 ms, that is 1/4 of 32,768 which is 8192.
switch (_alarm_match) {
case MATCH_250MS:
_alarm_calendar.year = calendar.year;
_alarm_calendar.month = calendar.month;
_alarm_calendar.day = calendar.day;
_alarm_calendar.hours = calendar.hours;
_alarm_calendar.minutes = calendar.minutes;
_alarm_calendar.seconds = calendar.seconds;
stm32l0_rtc_calendar_offset(&_alarm_calendar, 0, 8192, &_alarm_calendar);
break;

STM32: Receiving SPI data with DMA - always wrong number of bytes in Rx buffer

With an STM32F764 I want to receive 33 bytes from 11 daisy-chained 24 bit ADCs via SPI in read-only mode. The received data looks okay but there are 37 to 39 bytes in the buffer. Also with other byte numbers I receive 4 to 6 bytes more than expected.
Does anyone have an idea why that happens?
HAL_SPI_Receive_DMA is called by a GPIO interrupt from an external ADC when the 33 bytes are ready.
After finishing the DMA the buffer content is processed in Sampling().
Is the external GPIO interrupt handler the correct place for calling HAL_SPI_Receive_DMA?
/*SPI init for external ADCs (only Rx)*/
uint8_t SPI3_Init_ADC(void)
{
hspi3.Instance = SPI3;
hspi3.Init.Mode = SPI_MODE_MASTER;
hspi3.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
hspi3.Init.DataSize = SPI_DATASIZE_8BIT;
hspi3.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi3.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi3.Init.NSS = SPI_NSS_SOFT;
hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; /*SPI3_CLK = 12.5 MHz*/
hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi3.Init.TIMode = SPI_TIMODE_DISABLE;
hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi3.Init.CRCPolynomial = 7;
hspi3.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi3.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if (HAL_SPI_Init(&hspi3) != HAL_OK)
return ERR;
return OK;
}
/*SPI MSP and DMA Initialization*/
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/*SPI3: ADCs*/
if(hspi->Instance==SPI3)
{
__HAL_RCC_SPI3_CLK_ENABLE(); /* Peripheral clock enable */
__HAL_RCC_GPIOB_CLK_ENABLE();
/*PB3 --> SPI3_SCK*/
/*PB4 --> SPI3_MISO*/
GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*DMA 1 / channel 0 / stream 0 transfers data from external ADC to sample registers*/
__HAL_RCC_DMA1_CLK_ENABLE(); /*DMA clock*/
hdma_spi3_rx.Init.Channel = DMA_CHANNEL_0;
hdma_spi3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; /*from SPI to memory*/
hdma_spi3_rx.Init.PeriphInc = DMA_PINC_DISABLE; /*no increment on SPI side*/
hdma_spi3_rx.Init.MemInc = DMA_MINC_ENABLE; /*increment sample memory address*/
hdma_spi3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi3_rx.Init.Mode = DMA_NORMAL;
hdma_spi3_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
hdma_spi3_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma_spi3_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
hdma_spi3_rx.Init.MemBurst = DMA_PBURST_SINGLE;
hdma_spi3_rx.Init.PeriphBurst = DMA_PBURST_SINGLE;
hdma_spi3_rx.Instance = DMA1_Stream0;
HAL_DMA_Init(&hdma_spi3_rx);
HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0); /*highest priority for DMA interrupt*/
HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn); /*enable DMA interrupt*/
__HAL_LINKDMA(hspi, hdmarx, hdma_spi3_rx); /*link DMA1 to SPI3*/
}
/*INTERRUPT HANDLERS*/
/*Data ready interrupt (/ADC_/DRDY) of external ADCs*/
void EXTI9_5_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7); /*clear interrupt*/
HAL_SPI_Receive_DMA(&hspi3, SplRxBuff, 33); /*get 33 bytes ADC data*/
}
/*DMA1 stream0 global interrupt (Rx of external ADCs complete)*/
void SPI_DMA_Rx_IRQHandler(void)
{
HAL_DMA_IRQHandler(&hdma_spi3_rx);
Sampling();
}
Screenshot:
The red part is excess data. The ADC delivers actual data here from its unused 12th channel.
I bet as you do not protect the start transmition function call with any synchronisation mechanism (flag, semaphore etc) your interrupt is triggered before other transmit is done. Also the mystery function sampling in the DMA handler may does something strange.

STM32F4 as I2C Slave. Why "void I2C1_ER_IRQHandler(void)" is executed after "HAL_I2C_Slave_Transmit_DMA"?

I am using I2C bus as SLAVE mode in a STM32F411RE. The master is an arduino board.
The configuration is working well because I see thougth master serial (arduino) and STstudio (STM32F411) that all the frames are OK and thrue oscilloscope.
I noticed that I2C1_ER_IRQHandler function is triggered every time the slave finishes its TX transmission (Master receive that transmision and finishes with NACK and STOP BIT). In the next link:
https://drive.google.com/file/d/1-W5Z2nsvLNj6PE1TT9eDCDdYvFpnis8g/view?usp=sharing
https://drive.google.com/file/d/14JkeAw2If3v0A71V9-KQasH9rK3PRm3H/view?usp=sharing
https://drive.google.com/file/d/1Te2F8aNnvkqUSnfRK5UOO-qKabLXXv1D/view?usp=sharing
you can download pictures, you can see the SDA signal and GPIO PIN 2 which toggles within I2C1_ER_IRQHandler function. ¿could be related to the Slave (stm32) is receiving NACK at the end of thanssmission? see pictures
The SLAVE main function and calls are as follows:
#define BUFFERSIZE_RX 0x03 // Master sends 3 bytes
#define BUFFERSIZE_TX 0x04 //Master is waiting for 4 bytes
uint8_t aRxBuffer[BUFFERSIZE_RX];
uint8_t aTxBuffer[BUFFERSIZE_TX];
int main(void)
{
…uC INITIALIZATION
if(HAL_I2C_Slave_Receive_DMA(&hi2c1, (uint8_t *)aRxBuffer, BUFFERSIZE_RX) != HAL_OK)
{
Error_Handler();
}
while (1)
{}
}
void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c)
{
if(HAL_I2C_GetState(&hi2c1) == HAL_I2C_STATE_READY)
{
if(HAL_I2C_Slave_Receive_DMA(&hi2c1, (uint8_t *)aRxBuffer, BUFFERSIZE_RX) != HAL_OK)
{
Error_Handler();
}
}
}
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
{
if(HAL_I2C_GetState(&hi2c1) == HAL_I2C_STATE_READY)
{
if(HAL_I2C_Slave_Transmit_DMA(&hi2c1, (uint8_t*)aTxBuffer, BUFFERSIZE_TX)!= HAL_OK)
{
Error_Handler();
}
}
}
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET);
}
void I2C1_ER_IRQHandler(void)
{
HAL_I2C_ER_IRQHandler(&hi2c1);
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_2);
}
I2C and DMA configuration is as the STM32Cube_FW_F4_V1.24.0 examples, but if you need them I can send them as well.
The Arduino Master only sends the following functions:
void loop()
{
Wire.beginTransmission(address);
Wire.write((uint8_t)M_TX_1);
Wire.write((uint8_t)M_TX_2);
Wire.write((uint8_t)M_TX_3);
Wire.endTransmission();
delay(1);
Wire.requestFrom(address, (uint8_t)4);
M_RX_1 = Wire.read();
M_RX_2 = Wire.read();
M_RX_3 = Wire.read();
M_RX_4 = Wire.read();
… Serial prints and so on…
}
I have tested I2C in interruption mode and the same thing happens… communications works but always the I2C1_ER_IRQHandler is called.
I am completely lost, any help or comment are really appreciate!!!
Sorry for the long post.
P.D. HAL_I2C_ErrorCallback never called, so i suppose that it is OK.
Best regards.
Alejandro
PD2: SPI GPIO and DMA configuration:
static void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000;
//hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_16_9; // Modificacion
hi2c1.Init.OwnAddress1 = SLAVEADDRESS << 1; // Modificacion
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
//hi2c1.Init.OwnAddress2 = 0x06; // Modificacion
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
}
static void MX_DMA_Init(void)
{
__HAL_RCC_DMA1_CLK_ENABLE();
HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 2);
HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
}
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hi2c->Instance==I2C1)
{
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
__HAL_RCC_I2C1_CLK_ENABLE();
hdma_i2c1_rx.Instance = DMA1_Stream0;
hdma_i2c1_rx.Init.Channel = DMA_CHANNEL_1;
hdma_i2c1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_i2c1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_i2c1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_i2c1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_i2c1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_i2c1_rx.Init.Mode = DMA_NORMAL;
hdma_i2c1_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_i2c1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma_i2c1_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_i2c1_rx.Init.MemBurst = DMA_MBURST_INC4;
hdma_i2c1_rx.Init.PeriphBurst = DMA_PBURST_INC4;
if (HAL_DMA_Init(&hdma_i2c1_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(hi2c,hdmarx,hdma_i2c1_rx);
hdma_i2c1_tx.Instance = DMA1_Stream1;
hdma_i2c1_tx.Init.Channel = DMA_CHANNEL_0;
hdma_i2c1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_i2c1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_i2c1_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_i2c1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_i2c1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_i2c1_tx.Init.Mode = DMA_NORMAL;
hdma_i2c1_tx.Init.Priority = DMA_PRIORITY_HIGH;
hdma_i2c1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma_i2c1_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_i2c1_tx.Init.MemBurst = DMA_MBURST_INC4;
hdma_i2c1_tx.Init.PeriphBurst = DMA_PBURST_INC4;
if (HAL_DMA_Init(&hdma_i2c1_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(hi2c,hdmatx,hdma_i2c1_tx);
HAL_NVIC_SetPriority(I2C1_EV_IRQn, 0, 3);
HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);
HAL_NVIC_SetPriority(I2C1_ER_IRQn, 0, 2);
HAL_NVIC_EnableIRQ(I2C1_ER_IRQn);
}
}
To start with, Is it possible that this is an event IRQ (EV) to indicate a slave has finished transferring data and is not an error IRQ? You may have configured this to show that the slave is done with data transfer on the bus.
If that is not the case, definitely take a little better look at the I2C standard of communication. In your case, a NACK just indicates the stop of the transfer all together from the master, or it could mean that the transfer failed, but if you say all frames are successful, then it is definitely the end of transfer condition.
That being said, it is important to know how this was all configured. I would check the initialization sequence of the I2C on the F4 and make sure that it is in compliance with what is expected from the Arduino. It should be something like this.
Setup the associated clocks with I2C and GPIOs
Map the GPIOs
Enable the Interrupt services needed through the Nested Vectored Interrupt Controller (NVIC)
Set the settings of the I2C to the desired framing
Enable the I2C peripheral and interrupts
These steps will allow you to make sure you are covering your ground here.
Now you also must make sure you have the right features enabled if you are using DMA with I2C as well. The F4 does some packet error checking after the end of each message. Do you have the PEC enabled? If so, make sure there is not something causing this to get the IRQ interrupt to fire.
You also have event flags to read from in a debugger to see what error specifically triggered the I2C IRQ error line. According to the STMF4 reference manual, the event flags to generate an interrupt are:
0: Error interrupt disabled
1: Error interrupt enabled
This interrupt is generated when:
– BERR = 1
– ARLO = 1
– AF = 1
– OVR = 1
– PECERR = 1
– TIMEOUT = 1
– SMBALERT = 1
Although, you mentioned that the Error Callback function was not active, so these might not be present.
Finally, just to be safe, ensure the IRQ line isn't being used elsewhere in software. it could just be that the line is controlled by something else and being pulled high, causing the IRQ handler function to be called. This is unlikely if the code you posted is the only thing running, but it is worth a thought.

STM32F0 SPI receive interrupt not firing

I have a simple project, created using CubeMX for the peripheral initialisation.
SPI is in slave mode, and appears to be initialised correctly, but when I clock 8 bits of data, the interrupt doesn't get called.
Here's the code
/* SPI1 init function */
static void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_SLAVE;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 7;
hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hspi->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspInit 0 */
/* USER CODE END SPI1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
/**SPI1 GPIO Configuration
PA5 ------> SPI1_SCK
PA6 ------> SPI1_MISO
PA7 ------> SPI1_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Peripheral interrupt init */
HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SPI1_IRQn);
/* USER CODE BEGIN SPI1_MspInit 1 */
/* USER CODE END SPI1_MspInit 1 */
}
}
void SPI1_IRQHandler(void)
{
/* USER CODE BEGIN SPI1_IRQn 0 */
/* USER CODE END SPI1_IRQn 0 */
HAL_SPI_IRQHandler(&hspi1);
/* USER CODE BEGIN SPI1_IRQn 1 */
spi_interrupt();
/* USER CODE END SPI1_IRQn 1 */
}
The spi_interrupt() is my specific code for the interrupt actions, and a breakpoint in there never fires.
I've got a scope on the CLKIN pin, and its definitely got the 8 clocks.
ST's HAL library won't enable the actual peripheral interrupts in the initialization function.
For almost all of the peripherals an additional function has to be called which always has the following name structure HAL_<peripheral>_<action>_IT so in case of SPI RX it is called HAL_SPI_Receive_IT.
This enables actually the SPI RX interrupt by setting the correct bit with a macro called: __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR)).
Note that if the number of expected bytes (this value is passed in the HAL_SPI_Receive_IT by the user) is reached then the HAL_SPI_IRQHandler will disable the SPI RX interrupt again, thus a repeated HAL_SPI_Receive_IT call is needed in case of a new reception.

Resources