AnsweredAssumed Answered

Hal_Can transmits the same frame multiple times.

Question asked by Vegard Havellen on Jul 25, 2017

Hi.

 

I am woring on a program that sends packages over can regularly on a STM32f446ze. The program gets values from another chip over uart, does some signal processing and sends the values over Can. My problem is that when the calculation is done and the program is to send the values, it sends the same values multiple times, making it not send all the values. I have implemented a circular buffer to store the values to be sent, and when the program gets a HAL_CAN_TxCpltCallback it sends the next value in the buffer. This does not work, since it aends the same value multiple times. 

 

My device is connected to a network with another device that acknowledges the frames, so it is not the automatic retransmission that is the problem. 

 

 

/*Variables for CAN*/
uint8_t canValue = 1, WorkingPhase = 1;
uint8_t canFIFO[CAN_BUFF_LENGTH][8];
uint8_t canFIIndx = 0, canFOIndx = 0, packetsLeft = 0;

[...]

void
HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan){
packetsLeft--;
sendData();
}

[...]

void sendData(void){

  /* Set the data to be transmitted */
if (packetsLeft){
 
  canFOIndx++;
  if (canFOIndx > CAN_BUFF_LENGTH){
   canFOIndx = 0;
  }
  for(int i = 0; i<8;i++){
   CanHandle.pTxMsg->Data[i] = canFIFO[canFOIndx][i];
  }
 
  CanHandle.pTxMsg->StdId = canFIFO[canFOIndx][1];
 
  if(HAL_CAN_Transmit_IT(&CanHandle) != HAL_OK){
   Error_Handler();
  }
}
}
[...]

void fillBuffer(void){
for(int i = 0; i<11;i++){
  canFIIndx++;
  packetsLeft++;
  if (canFIIndx > CAN_BUFF_LENGTH){
   canFIIndx = 0;
  }
 
  canFIFO[canFIIndx][0] = (uint8_t) (WorkingPhase << 4) + i;    //Phase and harmonic number
  canFIFO[canFIIndx][1] = (uint8_t) harVal[i] >> 24;       //Sending the value of the harmonic
  canFIFO[canFIIndx][2] = (uint8_t) harVal[i] >> 16;
  canFIFO[canFIIndx][3] = (uint8_t) harVal[i] >> 8;
  canFIFO[canFIIndx][4] = (uint8_t) harVal[i];
  canFIFO[canFIIndx][5] = (uint8_t) harIndx[i] >> 8;       //Sending the index of the harmonic
  canFIFO[canFIIndx][6] = (uint8_t) harIndx[i];
  canFIFO[canFIIndx][7] = (uint8_t) i;                            //padding signal
 
}
if (packetsLeft == 11){
  sendData();
}
}

Can anyone point me in the right direction and explain me why it sends the same frame multiple times?

 

 

Here is my can.c file:

/* Includes ------------------------------------------------------------------*/
#include "can.h"
#include "gpio.h"

CAN_HandleTypeDef    CanHandle;

/* CAN1 init function */
void MX_CAN1_Init(void)
{
  CAN_FilterConfTypeDef  sFilterConfig;
  static CanTxMsgTypeDef        TxMessage;
  static CanRxMsgTypeDef        RxMessage;

  /*##-1- Configure the CAN peripheral #######################################*/
  CanHandle.Instance = CAN1;
  CanHandle.pTxMsg = &TxMessage;
  CanHandle.pRxMsg = &RxMessage;

  CanHandle.Init.TTCM = DISABLE;
  CanHandle.Init.ABOM = DISABLE;
  CanHandle.Init.AWUM = DISABLE;
  CanHandle.Init.NART = ENABLE;
  CanHandle.Init.RFLM = DISABLE;
  CanHandle.Init.TXFP = DISABLE;
  CanHandle.Init.Mode = CAN_MODE_NORMAL;

/*Can rate of 250K, S5 in CAN device*/
  CanHandle.Init.SJW = CAN_SJW_1TQ;
  CanHandle.Init.BS1 = CAN_BS1_12TQ;
  CanHandle.Init.BS2 = CAN_BS2_7TQ;
  CanHandle.Init.Prescaler = 9;

  if(HAL_CAN_Init(&CanHandle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }

  /*##-2- Configure the CAN Filter ###########################################*/
  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 = 14;

  if(HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig) != HAL_OK)
  {
    /* Filter configuration Error */
    Error_Handler();
  }

  /*##-3- Configure Transmission process #####################################*/
  CanHandle.pTxMsg->StdId = 0x321;
  CanHandle.pTxMsg->ExtId = 0x01;
  CanHandle.pTxMsg->RTR = CAN_RTR_DATA;
  CanHandle.pTxMsg->IDE = CAN_ID_STD;
  CanHandle.pTxMsg->DLC = 2;
}

void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct;
  if(canHandle->Instance==CAN1)
  {

    /* 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);

    /* CAN1 interrupt Init */
    HAL_NVIC_SetPriority(CAN1_TX_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(CAN1_TX_IRQn);
    HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
    HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
    HAL_NVIC_SetPriority(CAN1_SCE_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn);
  }
}

void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
{

  if(canHandle->Instance==CAN1)
  {

    /* 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);

    /* CAN1 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);
  }
}

Outcomes