Loading...
 

Zephyr project on STM32

   Zephyr Workbench, a VSCode extension to manage Zephyr on STM32.
It enables users to easily create, develop, and debug Zephyr applications.
Main features:
  • Install host dependencies.
  • Import toolchain and SDK.
  • Create, configure, build and manage apps.
  • Debug STM32.
You can directly download it from the VSCode marketplace
For more details, visit the Zephyr Workbench

System Workbench for STM32


STM32F103 + CAN -> microcontroller does not release the frame from FIFO banks

Hi everyone,

I have a problem with implementation CAN protocol on STM32F103C8.

I have a blue pill board connected through PA11 (CAN Rx) and PA12 (CAN Tx) to CJMCU-1051 transceiver ( relation between connection: CRX -> PA11, CTX -> PA12).
The CANL and CANH signals from the transceiver are connected to the CAN bus on which there are already two nodes and they communicate with each other with baudrate = 500kBps (4 frames run on the network):
CAN BUS
So network is working.

And now my code.
Clocks are configuring to max speed - 72MHz (of course PCLK1, according to RM , is sets to 36MHz).

void RCC_Conf(void)

{
// RCC setting reset
RCC_DeInit();

// Turn on HSE
RCC_HSEConfig(RCC_HSE_ON);

// Wait up to HSE will be ready
HSEStartUpStatus = RCC_WaitForHSEStartUp();

if(HSEStartUpStatus == SUCCESS)
{
/*
* the introduction of delays is (waitstate) for higher clock rates
* is due to the maximum frequency with which it is performed
* communication with Flash memory can be 24 MHz
*/
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

// wait for flash memory
FLASH_SetLatency(FLASH_Latency_2);

// HCLK = SYSCLK
RCC_HCLKConfig(RCC_SYSCLK_Div1);

// PCLK2 = HCLK
RCC_PCLK2Config(RCC_HCLK_Div1);

// PCLK1 = HCLK/2
RCC_PCLK1Config(RCC_HCLK_Div2);

// PLLCLK = 8MHz * 9 = 72 MHz
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

// Turn on PLL
RCC_PLLCmd(ENABLE);

// Wait up to PLL will be ready
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

// Select PLL as source of clock
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

// Wait up to PLL will be the source of clock
while(RCC_GetSYSCLKSource() != 0x08);

// Turn on Włączenie clock signal supervision system
//RCC_ClockSecuritySystemCmd(ENABLE);
}

}


Configuration of SysTick

void SysTick_Conf (void)

{
SysTick_Config(F_PCLK2/8/1000);
SysTick->CTRL &= ~SysTick_CTRL_CLKSOURCE_Msk;

}


And finally CAN configuration:

void CAN_Config(void)

{
GPIO_InitTypeDef GPIO_InitStructure;
uint8_t ststus = 10;

/* Configure CAN1 IOs **********************************************/
/* GPIOA and AFIO clocks enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);

/* Configure CAN1 RX pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure)

/* Configure CAN1 TX pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

/* Configure CAN1 and CAN2 **************************************************/
/* CAN1 and Periph clocks enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

/* CAN1 and CAN2 register init */
CAN_DeInit(CAN1);
// CAN_DeInit(CAN2);

/* Struct init*/
CAN_StructInit(&CAN_InitStructure);

/* CAN1 and CAN2 cell init */
CAN_InitStructure.CAN_TTCM = DISABLE;
CAN_InitStructure.CAN_ABOM = DISABLE;
CAN_InitStructure.CAN_AWUM = ENABLE;//DISABLE;
CAN_InitStructure.CAN_NART = DISABLE;
CAN_InitStructure.CAN_RFLM = DISABLE;
CAN_InitStructure.CAN_TXFP = ENABLE;
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
CAN_InitStructure.CAN_SJW = CAN_SJW_4tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_8tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;

/* 500KBps */
CAN_InitStructure.CAN_Prescaler =12;


/*Initializes the CAN1 and CAN2 */
ststus = CAN_Init(CAN1, &CAN_InitStructure);
// CAN_Init(CAN2, &CAN_InitStructure);

/* CAN1 filter init */
CAN_FilterInitStructure.CAN_FilterNumber = 1;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x1;
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);

TxMessage.StdId = 0x10;
TxMessage.ExtId = 0x00;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 4;

}


As answer from function: ststus = CAN_Init(CAN1, &CAN_InitStructure); I got value equal to 1, so CAN protocol is correctly implemented and it is in normal mode. This situation is confirmed by values of registers:
CAN MCR MSR

In main program loop I want to send a frame every 1s, the source_time variable is a variable incremented in the SysTick interrupt and I want to send it by the bus

while (1)

{
if(flag_)
{
TxMessage.Data0 = (uint8_t)(source_time >> 24);
TxMessage.Data1 = (uint8_t)(source_time >> 16);
TxMessage.Data2 = (uint8_t)(source_time >> 8);
TxMessage.Data3 = (uint8_t)source_time;

temp1 = CAN_Transmit(CAN1, &TxMessage);

temp2 = CAN_GetLastErrorCode(CAN1);

TransmitStatus0 = CAN_TransmitStatus(CAN1,0);
TransmitStatus1 = CAN_TransmitStatus(CAN1,1);
TransmitStatus2 = CAN_TransmitStatus(CAN1,2);
flag_ = 0;
}

}


The result is that transmission status is set to pending (the value is returned by the CAN_TransmitStatus function) for all FIFO banks, what is confirmed by registers:
TXRQ

After connection oscilloscope between microcontroller and transceiver I can notice that transceiver allow for transferring CRX frames (PA11 pin), o that I conclude that transceiver works properly:
Rx Tx

Summing up, maybe someone has an idea why STM does not send a frame to the transceiver but is in pending mode all the time?