Loading...
 

SW4STM32 and SW4Linux fully supports the STM32MP1 asymmetric multicore Cortex/A7+M4 MPUs

   With System Workbench for Linux, Embedded Linux on the STM32MP1 family of MPUs from ST was never as simple to build and maintain, even for newcomers in the Linux world. And, if you install System Workbench for Linux in System Workbench for STM32 you can seamlessly develop and debug asymmetric applications running partly on Linux, partly on the Cortex-M4.
You can get more information from the ac6-tools website and download (registration required) various documents highlighting:

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?