STM32 wakeup from CAN bus - c

I am trying to wake up the CPU from the CAN bus but it fails. Data from the bus processor receive but does not wake it up, for example, an interrupt from GPIO wakes it up and then it responds to the last 3 data from CAN Bus
CPU STM32F103C6
HAL_SuspendTick();
HAL_TIM_Base_Stop(&htim1);
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
HAL_TIM_Base_Start(&htim1);
HAL_ResumeTick();
tick_sleep = HAL_GetTick();
HAL Config interrupt
CAN Bus config
void MX_CAN_Init(void)
{
/* USER CODE BEGIN CAN_Init 0 */
/* USER CODE END CAN_Init 0 */
/* USER CODE BEGIN CAN_Init 1 */
/* USER CODE END CAN_Init 1 */
hcan.Instance = CAN1;
hcan.Init.Prescaler = 6;
hcan.Init.Mode = CAN_MODE_NORMAL;
hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan.Init.TimeSeg1 = CAN_BS1_2TQ;
hcan.Init.TimeSeg2 = CAN_BS2_1TQ;
hcan.Init.TimeTriggeredMode = DISABLE;
hcan.Init.AutoBusOff = ENABLE;
hcan.Init.AutoWakeUp = ENABLE;
hcan.Init.AutoRetransmission = ENABLE;
hcan.Init.ReceiveFifoLocked = DISABLE;
hcan.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN_Init 2 */
HAL_CAN_Start(&hcan);
CAN_FilterTypeDef sFilterConfig;
sFilterConfig.FilterIdHigh = 0xFFFF;
sFilterConfig.FilterIdLow = 0xFFFF;
sFilterConfig.FilterMaskIdHigh = 0;
sFilterConfig.FilterMaskIdLow = 0;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 0;
HAL_CAN_ConfigFilter(&hcan,&sFilterConfig);
/* USER CODE END CAN_Init 2 */
}

I forgot to run interrupts from CAN
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_CAN_Init();
MX_I2C1_Init();
MX_TIM3_Init();
MX_USART2_UART_Init();
MX_TIM1_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4);
HAL_TIM_Base_Start_IT(&htim1);
HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING); // CAN interrupts start

Related

ADC in low power run mode measure same numbers

I have stm32L053R8 nucleo64 board. I'm trying to get adc measure in low power run mode. It's not working correctly in Lprun mode but when I try in run mode it's working. In Lprun mode I only get 2 values. Half of the resolution and full of the resolution(12bit -> 2047 & 4095). Can you guys help me to figure out where am I doing wrong?
I tried to figure out why this happens and configured LFMEN, VREFEN, ULP bits but didn't worked.
ADC_HandleTypeDef hadc;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC_Init(void);
uint16_t adcVal = 0;
int main(void) {
HAL_Init();
MX_GPIO_Init();
MX_ADC_Init();
/*
// Bit 25 LFMEN: Low Frequency Mode enabled
ADC->CCR |= (1UL << 25);
// Bit 22 VREFEN: VREFINT enable
ADC->CCR |= (1UL << 22);
// Bit 9 ULP: Vrefint is ON in low power mode
PWR->CR &= ~(1UL << 9U);
*/
HAL_PWREx_EnableLowPowerRunMode();
while (1) {
HAL_Delay(500);
HAL_ADC_Start(&hadc);
HAL_ADC_PollForConversion(&hadc, 100);
adcVal = HAL_ADC_GetValue(&hadc);
HAL_ADC_Stop(&hadc);
}
}
/* #brief System Clock Configuration
* #retval None
*/
void SystemClock_Config(void) {
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/* Configure the main internal regulator output voltage */
__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_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = 0;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_2;
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_MSI;
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 ADC Initialization Function
* #param None
* #retval None
*/
static void MX_ADC_Init(void) {
/* USER CODE BEGIN ADC_Init 0 */
/* USER CODE END ADC_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC_Init 1 */
/* USER CODE END ADC_Init 1 */
/* Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) */
hadc.Instance = ADC1;
hadc.Init.OversamplingMode = DISABLE;
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ContinuousConvMode = DISABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.DMAContinuousRequests = DISABLE;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerFrequencyMode = ENABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
if (HAL_ADC_Init(&hadc) != HAL_OK) {
Error_Handler();
}
/* Configure for the selected ADC regular channel to be converted. */
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
Error_Handler();
}
}

TIMER triggered DMA - AD conversion, STM32F4 works only ones

I am implementing an a/d conversion with DMA transfer fired by a timer on a nucleo-STM32F401RE board.
Both TIMER2, the one used for the time base, and ADC with DMA looking at the debug are fine.
But when I use the timer to start the AD conversion it works only once, and then the timer go on, but don't starts the ADC.
I cannot find if there is some flag to clear or set.
Here the code:
TIMER 2 (changed sMasterConfig.MasterOutputTrigger from TIM_TRGO_RESET to TIM_TRGO_UPDATE, else ADC never starts):
void MX_TIM2_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 100;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 100;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; //TIM_TRGO_RESET
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
sConfigOC.OCMode = TIM_OCMODE_TIMING;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
ADC (if I set DMA continuos request at the end of one burst starts immediatly another and ignore the timer):
void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
hadc1.Init.Resolution = ADC_RESOLUTION_8B;
hadc1.Init.ScanConvMode = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T2_TRGO;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
}
MAIN and CallBack:
#define DEBUG 1
#define UART_RX_BUF_SIZE 1
#define UART_TIMEOUT 0X00000FFF
#define ADC_BUF_SIZE 10
volatile uint8_t UART_rx_buf[UART_RX_BUF_SIZE] = {0};
volatile uint8_t UART_rx_pending = 0;
const volatile char UART_tx_start[1] = "U";
volatile uint8_t UART_timeout = 0;
volatile uint16_t ADC_buf[ADC_BUF_SIZE] = {0};
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_USART2_UART_Init();
MX_ADC1_Init();
MX_TIM2_Init();
#ifdef DEBUG
DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM2_STOP;
#endif
/*INITIALIZATION: SEND A CHARACTER AND WAIT FOR A RESPONSE*/
HAL_Delay(10);
UART_timeout = HAL_UART_Transmit(&huart2, (uint8_t*)UART_tx_start, (uint16_t)1, (uint32_t)UART_TIMEOUT);
UART_timeout = HAL_UART_Receive(&huart2, (uint8_t*)UART_rx_buf, (uint16_t)UART_RX_BUF_SIZE, (uint32_t)UART_TIMEOUT);
if(UART_timeout == HAL_TIMEOUT) UART_config_timeout();
/*START CONFIGURATION*/
TIMER_CONFIG(UART_rx_buf[0]); //SET TIMER PRSC AND ARR
HAL_UART_Receive_IT(&huart2, (uint8_t*)UART_rx_buf, (uint16_t)UART_RX_BUF_SIZE); //UART RX INTERUPT ENABLE
TIM2 -> EGR |= 0x00000001; //RESET TIMER
HAL_TIM_Base_Start(&htim2); //START TIMER
HAL_ADC_Start_DMA(&hadc1, (uint32_t*) ADC_buf, ADC_BUF_SIZE); //START ADC-DMA REQUEAST
while (1)
{
if(UART_rx_pending == 1) {
UART_rx_pending = 0;
/*MANAGE RX DATA*/
HAL_UART_Receive_IT(&huart2, (uint8_t*)UART_rx_buf, (uint16_t)UART_RX_BUF_SIZE);
}
}
}
=============================================================================================
void HAL_UART_RxCpltCallback (UART_HandleTypeDef* huart) {UART_rx_pending = 1;}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {}
The first part of the main perform a short data transfer with the pc to set the ARR and PSC of TIMER2, in debug their values are fixed, and EGR is masked in order to reset the timer with the new values of ARR and PSC.
There is something that I miss?

while(1) loop in main() stops execute with ADC DMA Access with STM32F072CBT6

I'm using DMA to Access the Data from my ADC. The value at the ADC changes permantenly.
I read I can use DMA so I can use the value of the ADC everytime and everywhere I want to.
Problem is that my Main while() Loop is not or just once execute. The DMA Interupt calls.
HAL_ADC_Start_DMA(&hadc, (uint32_t*) &buffer, 1);
Here is the Code for Start the DMA for the ADC. Mode is Circular.
Here is the Init:
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSI14
|RCC_OSCILLATORTYPE_HSI48;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
RCC_OscInitStruct.HSI14State = RCC_HSI14_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.HSI14CalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI48;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_USART2
|RCC_PERIPHCLK_I2C1;
PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_HSI;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/**
* #brief ADC Initialization Function
* #param None
* #retval None
*/
static void MX_ADC_Init(void)
{
/* USER CODE BEGIN ADC_Init 0 */
/* USER CODE END ADC_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC_Init 1 */
/* USER CODE END ADC_Init 1 */
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
hadc.Init.ContinuousConvMode = ENABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.DMAContinuousRequests = ENABLE;
hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC_Init 2 */
/* USER CODE END ADC_Init 2 */
}
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
The ADC reads a analog volage from I/O.
My while(1) Loop currently just contains blinking led code.
Check the following:
Inside Hal_MSP file use DMA_CIRCULAR
create the buffer like this -> __IO uint16_t buffer[1]
then use it like this -> HAL_ADC_Start_DMA(&hadc, (uint32_t*) &buffer, 1);
Its better to start DMA at the end of ADC init. You can place above line inside the USER CODE BEGIN ADC_Init 2 comment braces.
The ADC size is 12 bit of this controller so circular DMA will automatically overwrite after every conversion.

STM32L0 ADC Problem converting multiple channels using DMA

I'm trying to convert 3 ADC channels using DMA. But the variables don't seem to change when I watch them in the debugger. I know the conversion complete callback is executed because I breakpointed it. So this suggests that the DMA transfer is not executing and the buffer is not being filled. I'm using stm32cube to initialize my project. I've trimmed the generated code. Thanks.
ADC_HandleTypeDef hadc;
DMA_HandleTypeDef hdma_adc;
uint32_t uwADC8ConvertedValue = 0;
uint32_t uwADC10ConvertedValue = 0;
uint32_t uwADC11ConvertedValue = 0;
uint32_t adcBuffer[3];
/* USER CODE BEGIN 0 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *AdcHandle) {
uwADC8ConvertedValue = adcBuffer[0];
uwADC10ConvertedValue = adcBuffer[1];
uwADC11ConvertedValue = adcBuffer[2];
}
/* USER CODE END 0 */
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_RTC_Init();
MX_ADC_Init();
MX_USART2_UART_Init();
MX_USART5_UART_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim2);
HAL_ADC_Start_IT(&hadc);
HAL_ADC_Start_DMA(&hadc, adcBuffer, 3);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
HAL_UART_Transmit(&huart2, TxBuffer, 15, 5000);
GPIO_PinState userPBstate = OFF;
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_TogglePin(MODEM_PW_GPIO_Port, MODEM_PW_Pin);
HAL_GPIO_TogglePin(CAM1_LD_GPIO_Port, CAM1_LD_Pin);
HAL_GPIO_TogglePin(CAM1_PW_GPIO_Port, CAM1_PW_Pin);
HAL_Delay(100);
userPBstate = HAL_GPIO_ReadPin(USER_PB_GPIO_Port, USER_PB_Pin);
if (userPBstate == ON) {
HAL_UART_Transmit(&huart2, (uint8_t *)"User button pressed!\n\r", 22, 5000);
}
else {
HAL_UART_Transmit(&huart2, (uint8_t *)"User button NOT pressed!\n\r", 26, 5000);
}
}
/* USER CODE END 3 */
}
/* ADC init function */
static void MX_ADC_Init(void)
{
ADC_ChannelConfTypeDef sConfig;
/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc.Instance = ADC1;
hadc.Init.OversamplingMode = DISABLE;
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.SamplingTime = ADC_SAMPLETIME_160CYCLES_5;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ContinuousConvMode = ENABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.DMAContinuousRequests = ENABLE;
hadc.Init.EOCSelection = ADC_EOC_SEQ_CONV;
hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerFrequencyMode = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_8;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_10;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_11;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/**
* Enable DMA controller clock
*/
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
User custom code:
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim2);
HAL_ADC_Start_IT(&hadc);
HAL_ADC_Start_DMA(&hadc, adcBuffer, 3);
/* USER CODE END 2 */
should be:
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim2);
HAL_ADC_Start_DMA(&hadc, adcBuffer, 3);
/* USER CODE END 2 */
If you want to use DMA mode, then do not use interrupt mode.

stm32f4 CAN receiver_IT issue

Next in my little project(stm32f407vg) is to receive can messages from another hardware(PIC 18L25K80)
I currently have working an UART to my computer so I can easily debug the chip via UART.
The problem is that I receive the message, the interruption gets triggered but what I read from rxMessage is non sense.
Test Procedure:
Simulating the emitter I use Microchip CAN BUS Analayzer, here is the screenshot of the window:
And here is what I see in the UART:
And this is what I see if I debug (I'm using Coocox 1.7.8):
Why the values of rxMessage doesn't change neither inside the HAL driver or in my code (can.c).
Thanks.
---------------------------- main.c-------------------------
#include "globals.h"
#include "stm32f4xx_hal.h"
#include "syscfg.h"
#include "can.h"
#include "usart.h"
#include "gpio.h"
#include "kernel.h"
#include <stdio.h>
int main(void){
SysIniCfg();
while (1){
kernelMotor();
usartMotor();
canMotor();
HAL_GPIO_TogglePin(LED_G_GPIO_Port,LED_G_Pin);
}
}
------------------------- end main.c -----------------------
---------------------------- syscfg.c-------------------------
#include "syscfg.h"
#include "syscfg.h"
#include "can.h"
#include "usart.h"
#include "gpio.h"
#include "kernel.h"
/*
* System Init configuration
*/
void SysIniCfg(){
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_CAN1_Init();
MX_USART1_UART_Init();
/* Initialize interrupts */
MX_NVIC_Init();
kernelInit();
}
------------------------- end syscfg.c -----------------------
---------------------------- can.h-------------------------
#include "stm32f4xx_hal.h"
#include "globals.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* USER CODE BEGIN Private defines */
typedef struct
{
CAN_HandleTypeDef Handle;
HAL_CAN_StateTypeDef *pState;
uint32_t *pErrorCode;
} t_can_control;
typedef enum{
CM_STOPPED = 0,
CM_INIT = 1,
CM_IDLE = 10,
CM_ERROR = 255
}uint8_t_canStates;
uint8_t_canStates canMotorStates;
extern CAN_HandleTypeDef hcan1;
t_can_control can_ctrl;
CanTxMsgTypeDef sTxMsg;
CanRxMsgTypeDef sRxMsg;
/* USER CODE END Private defines */
/* USER CODE BEGIN Prototypes */
extern void Error_Handler(void);
void MX_CAN1_Init(void);
------------------------- end can.h -----------------------
---------------------------- can.c-------------------------
#include "can.h"
#include "usart.h"
#include "gpio.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
CAN_HandleTypeDef hcan1;
/* CAN1 init function */
void MX_CAN1_Init(void)
{
CAN_FilterConfTypeDef sFilterConfig;
canMotorStates = CM_STOPPED;
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 20;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SJW = CAN_SJW_1TQ;
hcan1.Init.BS1 = CAN_BS1_13TQ;
hcan1.Init.BS2 = CAN_BS2_2TQ;
hcan1.Init.TTCM = DISABLE;
hcan1.Init.ABOM = DISABLE;
hcan1.Init.AWUM = DISABLE;
hcan1.Init.NART = DISABLE;
hcan1.Init.RFLM = DISABLE;
hcan1.Init.TXFP = DISABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK){
Error_Handler();
}
sFilterConfig.FilterNumber = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = 0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.BankNumber = 14;
if(HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK){
Error_Handler();
}
}
void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(canHandle->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspInit 0 */
/* USER CODE END CAN1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_CAN1_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 */
canMotorStates = CM_INIT;
/* USER CODE END CAN1_MspInit 1 */
}
}
void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
{
if(canHandle->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspDeInit 0 */
/* USER CODE END CAN1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_CAN1_CLK_DISABLE();
/**CAN1 GPIO Configuration
PA11 ------> CAN1_RX
PA12 ------> CAN1_TX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
/* Peripheral interrupt Deinit*/
HAL_NVIC_DisableIRQ(CAN1_TX_IRQn);
HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn);
HAL_NVIC_DisableIRQ(CAN1_RX1_IRQn);
HAL_NVIC_DisableIRQ(CAN1_SCE_IRQn);
}
/* USER CODE BEGIN CAN1_MspDeInit 1 */
canMotorStates = CM_STOPPED;
/* USER CODE END CAN1_MspDeInit 1 */
}
/**
* #brief Sends order for reading and reads an amount of data in no-blocking mode with Interrupt.
* #param u8can: Number of CAN instance
* #param u16std_id: CAN standard identifier
* #param pstate: Pointer to CAN state
* #param pu32error: Pointer to CAN error code
* #retval HAL status
*/
HAL_StatusTypeDef CAN_Read_wInt(uint8_t u8can, uint16_t u16std_id, HAL_CAN_StateTypeDef *pstate, uint32_t *pu32error){
HAL_StatusTypeDef status = HAL_OK;
if ((*pu32error) == HAL_CAN_ERROR_NONE)
{
/* Set Rx Message structure */
sRxMsg.StdId = (uint32_t)u16std_id;
sRxMsg.IDE = CAN_ID_STD;
sRxMsg.RTR = CAN_RTR_DATA;
sRxMsg.DLC = (uint8_t)8;
sRxMsg.FIFONumber = CAN_FIFO0;
sRxMsg.FMI = 1;
/* Put structure in the handle */
can_ctrl.Handle.pRxMsg = &sRxMsg;
/* Order to transmit in non-blocking mode */
status = HAL_CAN_Receive_IT(&hcan1, CAN_FIFO0);
if (status == HAL_OK)
{
/* Link external pointers to CAN local pointer */
can_ctrl.pState = pstate;
can_ctrl.pErrorCode = pu32error;
/* Update CAN State */
*(can_ctrl.pState) = HAL_CAN_STATE_BUSY_RX;
}
}
else
{
status = HAL_BUSY;
}
return status;
}
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* CanHandle)
{
HAL_GPIO_TogglePin(LED_Y_GPIO_Port,LED_Y_Pin);
char canOutBuffer[100];
sprintf(canOutBuffer,"-- %d : %d --", CanHandle->pRxMsg->StdId,CanHandle->pRxMsg->Data[0]);
usartPutString(canOutBuffer);
if(HAL_CAN_Receive_IT(CanHandle, CAN_FIFO0) != HAL_OK){
Error_Handler();
}
}
------------------------- end can.c -----------------------
---------------------------- main.c-------------------------
------------------------- end main.c -----------------------
I found what I was missing, in the definition of the can handle was specified the tx and rx message, so I suppose that the HAL drivers didn't do the initialization of this structures
void MX_CAN1_Init(void) {
CAN_FilterConfTypeDef sFilterConfig;
static CanTxMsgTypeDef TxMessage;
static CanRxMsgTypeDef RxMessage;
canMotorStates = CM_STOPPED;
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 20;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SJW = CAN_SJW_1TQ;
hcan1.Init.BS1 = CAN_BS1_13TQ;
hcan1.Init.BS2 = CAN_BS2_2TQ;
hcan1.Init.TTCM = DISABLE;
hcan1.Init.ABOM = DISABLE;
hcan1.Init.AWUM = DISABLE;
hcan1.Init.NART = DISABLE;
hcan1.Init.RFLM = DISABLE;
hcan1.Init.TXFP = DISABLE;
hcan1.pRxMsg = &RxMessage;
hcan1.pTxMsg = &TxMessage;
if (HAL_CAN_Init(&hcan1) != HAL_OK)
{
Error_Handler();
}
sFilterConfig.FilterNumber = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = 0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.BankNumber = 14;
if(HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
{
/* Filter configuration Error */
Error_Handler();
}
}

Resources