CAN BUS Acknowledgment error - c

I am using STM32F429 CAN bus Program with TJA1041A as CAN
Transreciver.The Problem is the messages are not getting acknowledged and herewith I
am attaching the code for further reference.I am using PCAN View to see
the messages.I kindly request to check the code and tell me if there are any faults.
Code:-
int main(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);
// SystemInit();
GPIO_InitTypeDef GPIO_InitDef;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitDef.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13;
GPIO_InitDef.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitDef.GPIO_OType = GPIO_OType_PP;
GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitDef.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOB, &GPIO_InitDef);
/* Connect CAN pins to AF */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_CAN2); // CAN2_RX
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_CAN2); // CAN2_TX
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO_InitDef.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
GPIO_InitDef.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitDef.GPIO_OType = GPIO_OType_PP;
GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitDef.GPIO_Speed = GPIO_Speed_100MHz;
/* Connect PD5 and PD7 pins for CAN Transreceiver to enable and
stanby */
GPIO_Init(GPIOD, &GPIO_InitDef);
GPIO_SetBits(GPIOD, GPIO_Pin_5|GPIO_Pin_7);
RCC_ClocksTypeDef RCC_Clocks;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
RCC_GetClocksFreq(&RCC_Clocks);
CAN_DeInit(CAN2);
CAN_StructInit(&CAN_InitStructure);
/* CAN cell init */
CAN_InitStructure.CAN_TTCM = DISABLE;
CAN_InitStructure.CAN_ABOM = DISABLE;
CAN_InitStructure.CAN_AWUM = DISABLE;
CAN_InitStructure.CAN_NART = DISABLE;
CAN_InitStructure.CAN_RFLM = DISABLE;
CAN_InitStructure.CAN_TXFP = DISABLE;
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal ;
/* quanta 1+14+6 = 21, 21 * 4 = 84, 42000000 / 84 = 5000000 */
/* CAN Baudrate = 500Kbps (CAN clocked at 42 MHz) Prescale = 4 */
/* Requires a clock with integer division into APB clock */
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; // 1+6+7 = 14, 1+14+6 = 21,
1+15+5 = 21
CAN_InitStructure.CAN_BS1 = CAN_BS1_14tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_6tq;
CAN_InitStructure.CAN_Prescaler = 4; // quanta by baudrate - 125kbps
CAN_Init(CAN2, &CAN_InitStructure);
/* CAN filter init */
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; //
IdMask or IdList
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit; // 16
or 32
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000; // Everything,
otherwise 11-bit in top bits
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0; // Rx
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
//CAN_FilterInitStructure.CAN_FilterNumber = 0; // CAN1 [ 0..13]
// CAN_FilterInit(&CAN_FilterInitStructure);
CAN_FilterInitStructure.CAN_FilterNumber = 14; // CAN2 [14..27]
CAN_FilterInit(&CAN_FilterInitStructure);
CAN_ITConfig(CAN2, CAN_IT_FMP0, ENABLE);
CanTxMsg TxMessage;
// transmit */
TxMessage.StdId = 0x321;
TxMessage.ExtId = 0x00;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 8;
TxMessage.Data[0] = 0x02;
TxMessage.Data[1] = 0x11;
TxMessage.Data[2] = 0x11;
TxMessage.Data[3] = 0x11;
while(1)
{
uint32_t i;
int j = 0;
uint8_t TransmitMailbox = 0;
TxMessage.Data[4] = (j >> 0) & 0xFF; // Cycling
TxMessage.Data[5] = (j >> 8) & 0xFF;
TxMessage.Data[6] = (j >> 16) & 0xFF;
TxMessage.Data[7] = (j >> 24) & 0xFF;
j++;
TransmitMailbox = CAN_Transmit(CAN2, &TxMessage);
i = 0;
while((CAN_TransmitStatus(CAN2, TransmitMailbox) != CANTXOK) && (i
!= 0xFFFF)) // Wait on Transmit
{
i++;
CAN2RX();// Pump RX
}
}
}

This is the default behavior of any CAN bus. You need at least two CAN controllers on the bus to establish communication. If there is just one node, you will get nothing but error frames.
For debugging purposes, all CAN controllers have a "loop back" debug feature which allows them to acknowledge and listen to their own frames. You must enable this if you are alone on the bus.
Alternatively, if you have two CAN controllers in the same MCU, you can enable both of them and wire them together.

Probably you should enable the transeiver : It should have some voltage in input (Vbat = 12V) and Vi/o and also you need to enable the EN Pin.

Related

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?

I can't see any signal on the CAN_TX line

I try to use the CAN bus on an STM32F303 discovery board, and I am using the PD0→RX and PD1→TX pins.
I want to try to send a message and analyse on the oscilloscope. So my configuration is seen below in the code blocks.
When I analyse with the oscilloscope which pins are PD0 and PD1, I can't see anything on the oscilloscope.
Where is my fault?
This is my code:
#include <stm32f30x.h>
#include <stm32f30x_i2c.h>
#include <stm32f30x_rcc.h>
#include <stm32f30x_syscfg.h>
#include <stm32f30x_exti.h>
// #include <stm32f30x_misc.h>
#include "main.h"
#include <stdio.h>
#include "common.h"
#include "io_periph_defs.h"
#include "stm32f30x.h"
#include <stdio.h>
#include "conf.h"
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CanTxMsg TxMessage;
CanRxMsg RxMessage;
void Init_TxMes(CanTxMsg *TxMessage)
{
/* Transmit INITIALIZATION*/
TxMessage->IDE = CAN_ID_STD;
TxMessage->DLC = 2;
TxMessage->StdId = 0x321;
TxMessage->RTR = CAN_RTR_DATA;
}
void Init_RxMes(CanRxMsg *RxMessage)
{
uint8_t i = 0;
RxMessage->StdId = 0;
RxMessage->IDE = CAN_ID_STD;
RxMessage->DLC = 0;
RxMessage->FMI = 0;
for (i = 0; i < 8; i++)
{
RxMessage->Data[i] = 0;
}
}
void CAN_setup(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); //Enable the clock for CAN
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
/* Configure CAN1 RX pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Configure CAN1 TX pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_9);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_9);
/* Enable the CAN global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = CAN1_SCE_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX1_IRQn;
NVIC_Init(&NVIC_InitStructure);
CAN_DeInit(CAN1);
/* Configure CAN1 **************************************************/
/* Struct init*/
CAN_StructInit(&CAN_InitStructure);
/* CAN cell init */
CAN_InitStructure.CAN_TTCM = DISABLE;
CAN_InitStructure.CAN_ABOM = DISABLE;
CAN_InitStructure.CAN_AWUM = DISABLE;
CAN_InitStructure.CAN_NART = DISABLE;
CAN_InitStructure.CAN_RFLM = DISABLE;
CAN_InitStructure.CAN_TXFP = DISABLE;
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
/* CAN Baudrate = 125kbps (CAN clocked at 36 MHz) */
CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
CAN_InitStructure.CAN_Prescaler = 16;
CAN_Init(CAN1, &CAN_InitStructure);
/* CAN filter init */
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
}
int main(void)
{
int i;
uint8_t TransmitMailbox = 0;
CAN_setup(); // Set up CAN interface
Init_TxMes(&TxMessage);
init_pin(GPIOA, GPIO_Pin_8, GPIO_Mode_OUT, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_UP);
while (1)
{
TxMessage.Data[0] = 0xAA;
GPIO_SetBits(GPIOA, GPIO_Pin_8); // Transmit data
TransmitMailbox = CAN_Transmit(CAN1, &TxMessage);
i = 0;
while ((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK))
; // I put a breakpoint here to check
// and found the message is pending.
GPIO_ResetBits(GPIOA, GPIO_Pin_8); // Transmit data
//i++;
}
}
I think there is the problem, but how can I solve it?
Stacking in loop.
while ((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK)

stm32f4 discovery CAN transmit

This is my program for CAN transmit. I just want to see through the
oscilloscope wether something is being sent or not. I am using stm32f407
and attolic true studio for it, but i am unable to see any signal on my
tx pin. Kindly tell me where is my mistake. Do i need to connect the transciever externally and also how can i access CAN_H and CAN_L pins.
#include "stm32f4xx.h"
int main(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_ClocksTypeDef RCC_Clocks;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CanTxMsg TxMessage;
RCC_GetClocksFreq(&RCC_Clocks);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);`
GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
CAN_DeInit(CAN1);
CAN_StructInit(&CAN_InitStructure);
CAN_InitStructure.CAN_TTCM = DISABLE;
CAN_InitStructure.CAN_ABOM = DISABLE;
CAN_InitStructure.CAN_AWUM = DISABLE;
CAN_InitStructure.CAN_NART = DISABLE;
CAN_InitStructure.CAN_RFLM = DISABLE;
CAN_InitStructure.CAN_TXFP = DISABLE;
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_7tq;
CAN_InitStructure.CAN_Prescaler = 4;
CAN_Init(CAN1, &CAN_InitStructure);
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
// transmit */
TxMessage.StdId= 0x123;
TxMessage.ExtId= 0x00;
TxMessage.RTR= CAN_RTR_DATA;
TxMessage.IDE= CAN_ID_STD;
TxMessage.DLC= 4;
TxMessage.Data[0]= 0x02;
TxMessage.Data[1]= 0x11;
TxMessage.Data[2]=0x11;
TxMessage.Data[3]=0x11;
while(1)
{
volatile uint_t i;
unit8_t TransmitMailbox= 0;
//sprintf(TxMessage.Data, "Imran\n");
TransmitMailbox= CAN_Transmit(CAN1,&TxMessage);
i=0;
while((CAN_TransmitStatus(CAN1,TransmitMailbox) !=CANTXOK)&& (i !=0xFFFFFF))
{
i++;
}
}
}
Try to turn on the Automatic Wake Up by changing to the following line:
CAN_InitStructure.CAN_AWUM = ENABLE;
The stm32f407 has only the CAN Controller without the internal transciever, so you need to connect it externaly. Also you have to connect another device into your CAN Bus to see something (remember about the terminators).
Please explain what do you mean by saying that:
how can i access CAN_H and CAN_L pins
PS. You should not put each functionality into one routine because it is unreadable.

STM32F4 ADC DMA config not working

I'm trying to get ADC with DMA working on my STM32F411RE nucleo board.
the signal is connected to the PC0 pin (ADC channel 10, DMA2), but whenever I check, the uhADC1ConvertedValue is 0. Am I missing something? Is my config wrong?
__IO uint32_t uhADC1ConvertedValue;
unsigned int getADCVal(){
return uhADC1ConvertedValue;
}
void ADC2_Init(){
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
uhADC1ConvertedValue = 1;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&uhADC1ConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
DMA_Cmd(DMA2_Stream0, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOC, &GPIO_InitStructure);
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_3Cycles);
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
ADC_EOCOnEachRegularChannelCmd(ADC1, ENABLE);
}
int main(void)
{
int rev = 0;
uC_Init();
rev = getADCVal(); //enc28j60getrev();
simple_server();
return rev;
}
I can't really tell what was wrong with my previous code (probably the part where i didn't start the timer that would start the ADC), but here is a working one (this code keeps ADC doing conversions continously (well, started by a timer) and loads the measured value into a variable):
volatile uint32_t uhADC1ConvertedValue;
uint32_t getADCVal(){
return uhADC1ConvertedValue;
}
void adc_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOC, &GPIO_InitStructure);
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
//konfiguracja ADC
ADC1->CR2 = ADC_CR2_ADON | //włącz ADC
ADC_CR2_EXTEN_0 | //wyzwalanie przetwornika zboczem opadającym i narastającym
ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_0 | //wyzwalanie przetwornika kanałem 4 timera 4
ADC_CR2_DDS | //kontynuuj przesył DMA po ostatnim przesyle (konieczne dla circular mode)
ADC_CR2_DMA; //włącz DMA dla ADC
//włączenie skanowania i przerwania dla zakonczonej konwersji
ADC1->CR1 = ADC_CR1_SCAN; //| ADC_CR1_EOCIE;
//Ustawienie czasu konwersji na 3 + 12 cykli zegara ADC, zegar ADC == 42MHz częstotliwosć próbkowania ~1Ms
ADC1->SMPR1 = 0;//ADC_SMPR1_SMP11_1 | ADC_SMPR1_SMP12_1;
//Ustawienie ilosci kanałów do skanowania
ADC1->SQR1 = (1)<<20;
//Ustawienie kanałów 11 i 12 do skanowania
ADC1->SQR3 = 10<<5;
//Konfiguracja DMA dla przetwornika ADC1
DMA2_Stream0->NDTR = 1; //ilosc bajtów do przesłania
DMA2_Stream0->PAR = (uint32_t)&ADC1->DR;
DMA2_Stream0->M0AR = (uint32_t)&uhADC1ConvertedValue;
DMA2_Stream0->CR = DMA_SxCR_PL_1 | //priority high
DMA_SxCR_MSIZE_0 | //memory size 16bit
DMA_SxCR_PSIZE_0 | //pheriperial size 16bit
DMA_SxCR_MINC | //inkrementuj wskaźnik po stronie pamięci
DMA_SxCR_CIRC | //zapętlenie bufora pamięci
DMA_SxCR_EN; //włączenie kontrolera DMA
//konfiguracja timera dla przetwornika
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
TIM4->CR1 = 0; //resetowanie rejestru konfiguracji
TIM4->PSC = 0; //prescaller na 0
TIM4->ARR = 167; //reload register na 83
TIM4->CCR4 = 167; //rejesrt compare dla wyzwalania przetwornika
TIM4->CCMR2 |= TIM_CCMR2_OC4M_0 | TIM_CCMR2_OC4M_1; //przełączanie wyjcia przy compare
TIM4->CCER |= TIM_CCER_CC4E; //włączenie wyjcia 4
//konfiguracja NVIC
NVIC_EnableIRQ(ADC_IRQn); //przerwanie od zakonczenia konwersji ADC
//uruchom przetwornik
ADC1->CR2 |= ADC_CR2_ADON;
//uruchom timer
TIM4->CR1 = TIM_CR1_CEN;
}
int main(void)
{
uint32_t rev;
int bb= 0;
uC_Init();
//ADC2_Init();
adc_init();
rev = uhADC1ConvertedValue;
rev = uhADC1ConvertedValue;
rev = uhADC1ConvertedValue;
for (bb=0; bb< 100000; bb++) // tu dociera i sie wywala
{;;}
rev = uhADC1ConvertedValue;
rev = uhADC1ConvertedValue;
rev = uhADC1ConvertedValue;
rev = uhADC1ConvertedValue;
// rev = 20;
/**/
simple_server(); //petla nieskonczona
return rev;
}

STM32F4Discovery: Receiving CAN message

I am lost on how to receive CAN message on STM32F4Discovery. I have it in Silent_Loopback mode, meaning all sent messages should arrive in CAN controller itself. I get Transmit_OK status when I send the message, however, nothing appears in the FIFO mailbox. I have skipped CAN filter configuration in order to receive all messages and not to filter any of them out. What am I doing wrong?
/* Includes */
#include "stm32f4xx.h"
#include "stm32f4_discovery.h"
void Delay(__IO uint32_t nCount) {
while(nCount--) {
}
}
void RCC_Configuration(void) {
/* ENABLE CLOCKS */
/* GPIOB clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
/* USART3 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
/* CAN1 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
/* CAN2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);
}
void GPIO_Configuration(void) {
GPIO_InitTypeDef GPIO_InitStructureUSART;
GPIO_InitTypeDef GPIO_InitStructureCAN_RX;
GPIO_InitTypeDef GPIO_InitStructureCAN_TX;
/* GPIO USART Configuration */
GPIO_InitStructureUSART.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStructureUSART.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructureUSART.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructureUSART.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructureUSART.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructureUSART);
/* Connect USART to AF */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3); //USART_TX = PB10
GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3); //USART_RX = PB11
/* GPIO CAN_RX Configuration */
GPIO_InitStructureCAN_RX.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructureCAN_RX.GPIO_Mode = GPIO_Mode_AF;
//GPIO_InitStructureCAN_TX.GPIO_OType = GPIO_OType_PP;
//GPIO_InitStructureCAN_TX.GPIO_PuPd = GPIO_PuPd_NOPULL;
//GPIO_InitStructureCAN_TX.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructureCAN_RX);
/* GPIO CAN_TX Configuration */
GPIO_InitStructureCAN_TX.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructureCAN_TX.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructureCAN_TX.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructureCAN_TX.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructureCAN_TX.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructureCAN_TX);
/* Connect CAN_RX & CAN_TX to AF9 */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_CAN2); //CAN_RX = PB12
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_CAN2); //CAN_TX = PB13
}
void USART_Configuration(void) {
USART_InitTypeDef USART_InitStructure;
/* USART3 configuration */
/* 256000 baud, window 8 data bits, one stop bit, no parity, no hardware flow control, rx/tx enabled */
USART_InitStructure.USART_BaudRate = 256000;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART3, &USART_InitStructure);
USART_Cmd(USART3, ENABLE);
}
void CAN_Configuration(void) {
CAN_InitTypeDef CAN_InitStructure;
/* CAN2 reset */
CAN_DeInit(CAN2);
/* CAN2 configuration */
CAN_InitStructure.CAN_TTCM = DISABLE; // Time-triggered communication mode = DISABLED
CAN_InitStructure.CAN_ABOM = DISABLE; // Automatic bus-off management mode = DISABLED
CAN_InitStructure.CAN_AWUM = DISABLE; // Automatic wake-up mode = DISABLED
CAN_InitStructure.CAN_NART = DISABLE; // Non-automatic retransmission mode = DISABLED
CAN_InitStructure.CAN_RFLM = DISABLE; // Receive FIFO locked mode = DISABLED
CAN_InitStructure.CAN_TXFP = DISABLE; // Transmit FIFO priority = DISABLED
CAN_InitStructure.CAN_Mode = CAN_Mode_Silent_LoopBack; // Normal CAN mode
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; // Synchronization jump width = 1
CAN_InitStructure.CAN_BS1 = CAN_BS1_14tq; //14
CAN_InitStructure.CAN_BS2 = CAN_BS2_6tq; //6
CAN_InitStructure.CAN_Prescaler = 4; // Baudrate 500 kbps
//CAN_InitStructure.CAN_Prescaler = 16; // Baudrate 125 kbps
if (CAN_Init(CAN2, &CAN_InitStructure)) { // Initialize CAN
STM_EVAL_LEDInit(LED6); // Initialize and
STM_EVAL_LEDOn(LED6); // Turn ON blue LED if CAN initialization is successful
}
}
void CAN_FilterConfiguration(void) {
CAN_FilterInitTypeDef CAN_FilterInitStructure;
/* CAN2 filter configuration */
CAN_FilterInitStructure.CAN_FilterNumber = 0; // Filter number = 0 (0<=x<=13)
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; // Filter mode = identifier mask based filtering
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0300 << 5; //0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x03FF << 5;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0; // FIFO = 0
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
}
void CAN_TxMessage(void) {
CanTxMsg TxMessage;
/* CAN message to send */
TxMessage.StdId = 0x321;
TxMessage.ExtId = 0x01;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 8;
TxMessage.Data[0] = 0x04;
TxMessage.Data[1] = 0x01;
TxMessage.Data[2] = 0x00;
TxMessage.Data[3] = 0x00;
TxMessage.Data[4] = 0x00;
TxMessage.Data[5] = 0x00;
TxMessage.Data[6] = 0x00;
TxMessage.Data[7] = 0x00;
//while (1) {
CAN_TransmitStatus(CAN2, 0);
CAN_Transmit(CAN2, &TxMessage);
if(CAN_TransmitStatus(CAN2, 0)){
STM_EVAL_LEDInit(LED4); // Initialize and
STM_EVAL_LEDOn(LED4); // turn ON green LED if transmit was successful
}
//}
}
void CAN_OBDII_RequestCurrentData(int PIDNumber) {
CanTxMsg TxMessage;
TxMessage.StdId = 0x7DF; // PID request identifier
TxMessage.ExtId = 0x7DF;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 8;
TxMessage.Data[0] = 0x02; // Number of additional bytes = 2
TxMessage.Data[1] = 0x01; // Show current data = 1
TxMessage.Data[2] = PIDNumber; // PID code number
TxMessage.Data[3] = 0x00;
TxMessage.Data[4] = 0x00;
TxMessage.Data[5] = 0x00;
TxMessage.Data[6] = 0x00;
TxMessage.Data[7] = 0x00;
CAN_Transmit(CAN2, &TxMessage); // Transmit OBDII PID request via CAN2/mailbox0
}
void CAN_RxMessage(void) {
CanRxMsg RxMessage;
int d0=0;
while(1) {
CAN_Receive(CAN2,CAN_FIFO0,&RxMessage);
d0 = RxMessage.Data[0];
d0 = RxMessage.Data[1];
d0 = RxMessage.Data[2];
d0 = RxMessage.Data[3];
d0 = RxMessage.Data[4];
d0 = RxMessage.Data[5];
d0 = RxMessage.Data[6];
d0 = RxMessage.Data[7];
}
}
int main(void)
{
/* Initialize Clocks */
RCC_Configuration();
/* Initialize GPIO */
GPIO_Configuration();
/* Initialize USART */
USART_Configuration();
/* Initialize CAN */
CAN_Configuration();
/* Initialize CAN Reception Filter */
//CAN_FilterConfiguration();
/* Transfer CAN message */
CAN_TxMessage();
/* Receive CAN message */
CAN_RxMessage();
You have to configure filter to accept all messages (if you don't have any filter, no message will be accepted). But in your example you use CAN2, so FilterNumber must be 14 or higher.
#define CAN_FIFO_ID 0
#define CAN_FIFO CAN_FIFO0
#define CAN_FIFO_IN CAN_IT_FMP0
/**
* #brief Default filter - accept all to CAN_FIFO
*/
void CAN_SetFilter()
{
/* Default filter - accept all to CAN_FIFO*/
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CAN_FilterInitStructure.CAN_FilterNumber = 14; // 0..13 for CAN1, 14..27 for CAN2
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO_ID;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
}
The number of filters assigned to CAN1 and CAN2 is defined in the CAN_FMR register which by default is set to 14 which is the start of the CAN2 filters.
This can be set to 28 which would mean no filters to CAN2 and all 28 to CAN1 or if set to 0 all 28 filters are assigned to CAN2.
Normally (if you have a valid Filter Number) in mask mode any mask = zero will let everything through.

Resources