0
votes

I am trying to start learning programming and I am trying to get this code to work: https://github.com/espruino/Espruino/blob/master/targetlibs/stm32f4/lib/stm32f4xx_can.c I am using Atollic TruStudio Lite.

I did the basic LED blinking code with Discovery, but other than that. I have no clue how to do this.

I don't get how am i supposed to simulate CAN message (and other things) via STM32.

I am a total beginner, so please, don't rip my throat out.

Thanks

1
Maybe a packed struct? Is there nothing useful in the included .h files?Martin James

1 Answers

1
votes

Here's an example of a CAN loopback you can try. It's a CAN loopback test. It's in the stm32f4 examples that you can download from the STM website. This is for an STM32439 eval board but it should work on a discovery. (Both are STM32F4 chips).

#define USE_CAN1
/* Uncomment the line below if you will use the CAN 2 peripheral */
/* #define USE_CAN2 */

#ifdef  USE_CAN1
  #define CANx              CAN1
  #define CAN_CLK           RCC_APB1Periph_CAN1      

#else /* USE_CAN2 */
  #define CANx              CAN2
  #define CAN_CLK           (RCC_APB1Periph_CAN1 | RCC_APB1Periph_CAN2)   
#endif  /* USE_CAN1 */

typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;

__IO uint32_t ret = 0; /* for return of the interrupt handling */
volatile TestStatus TestRx;

TestStatus CAN_Polling(void);

int main(void) {
    /*!< At this stage the microcontroller clock setting is already configured, 
       this is done through SystemInit() function which is called from startup
       files (startup_stm32f40_41xxx.s/startup_stm32f427_437xx.s/startup_stm32f429_439xx.s)
       before to branch to application main. 
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f4xx.c file
     */   

    /* CANx Periph clock enable */
    RCC_APB1PeriphClockCmd(CAN_CLK, ENABLE);

    /* Initialize LEDs mounted on EVAL board */
    STM_EVAL_LEDInit(LED1);
    STM_EVAL_LEDInit(LED2);

    /* CAN transmit at 125Kb/s and receive by polling in loopback mode */
    TestRx = CAN_Polling();

    if (TestRx !=  FAILED) { /* OK */
        /* Turn on LED1 */
        STM_EVAL_LEDOn(LED1);
    } else { /* KO */
        /* Turn on LED2 */
        STM_EVAL_LEDOn(LED2);
    }

    /* Infinite loop */
    while (1) { }
}

/**
 * @brief  Configures the CAN, transmit and receive by polling
 * @param  None
 * @retval PASSED if the reception is well done, FAILED in other case
 */
TestStatus CAN_Polling(void) {
    CAN_InitTypeDef        CAN_InitStructure;
    CAN_FilterInitTypeDef  CAN_FilterInitStructure;
    CanTxMsg TxMessage;
    CanRxMsg RxMessage;
    uint32_t uwCounter = 0;
    uint8_t TransmitMailbox = 0;

    /* CAN register init */
    CAN_DeInit(CANx);

    /* 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_LoopBack;
    CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;

    /* CAN Baudrate = 175kbps (CAN clocked at 42 MHz) */
    CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
    CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
    CAN_InitStructure.CAN_Prescaler = 16;
    CAN_Init(CANx, &CAN_InitStructure);

    /* CAN filter init */
#ifdef  USE_CAN1
    CAN_FilterInitStructure.CAN_FilterNumber = 0;
#else /* USE_CAN2 */
    CAN_FilterInitStructure.CAN_FilterNumber = 14;
#endif  /* USE_CAN1 */
    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);

    /* transmit */
    TxMessage.StdId = 0x11;
    TxMessage.RTR = CAN_RTR_DATA;
    TxMessage.IDE = CAN_ID_STD;
    TxMessage.DLC = 2;
    TxMessage.Data[0] = 0xCA;
    TxMessage.Data[1] = 0xFE;

    TransmitMailbox = CAN_Transmit(CANx, &TxMessage);
    uwCounter = 0;
    while((CAN_TransmitStatus(CANx, TransmitMailbox)  !=  CANTXOK) && (uwCounter  !=  0xFFFF)) {
        uwCounter++;
    }

    uwCounter = 0;
    while((CAN_MessagePending(CANx, CAN_FIFO0) < 1) && (uwCounter  !=  0xFFFF)) {
        uwCounter++;
    }

    /* receive */
    RxMessage.StdId = 0x00;
    RxMessage.IDE = CAN_ID_STD;
    RxMessage.DLC = 0;
    RxMessage.Data[0] = 0x00;
    RxMessage.Data[1] = 0x00;
    CAN_Receive(CANx, CAN_FIFO0, &RxMessage);

    if (RxMessage.StdId != 0x11) {
        return FAILED;  
    }

    if (RxMessage.IDE != CAN_ID_STD) {
        return FAILED;
    }

    if (RxMessage.DLC != 2) {
        return FAILED;  
    }

    if ((RxMessage.Data[0]<<8|RxMessage.Data[1]) != 0xCAFE) {
        return FAILED;
    }

    return PASSED; /* Test Passed */
}