5.2 bxCAN Guide

This chapter describes the file composition and the 33 public functions of the bxCAN driver in the N32G41x standard peripheral library: CAN reset and initialization, filter configuration, operating mode control, message transmit and receive, error management and status query, and interrupt and flag management. Two examples, CAN_LoopBack and CAN_Tx_Rx, demonstrate message transfer in loopback mode and normal mode. Read the register bit definitions, operating modes, filter mechanism and bit timing together with the “Controller area network (CAN)” chapter of the user manual, and take the errata sheet as the authority on known chip issues.

5.2.1 Related files

Relative path Purpose
firmware/n32g41x_std_periph_driver/inc/n32g41x_can.h Defines the CAN_InitType, CAN_FilterInitType, CanTxMessage and CanRxMessage structures and the operating-mode, bit-timing, filter, mailbox and flag macros, and declares 33 public functions in the eight sections reset and initialization, configuration, operating mode control, transmit, receive, error management, status query, and interrupt and flag management
firmware/n32g41x_std_periph_driver/src/n32g41x_can.c Implements those 33 functions: register reset and bit timing, filter and operating-mode configuration, mailbox message transmit and receive, error counters and status query, and interrupt and flag access
projects/n32g41x_EVAL/examples/bxCAN/ bxCAN example root directory, containing 2 examples: CAN_LoopBack and CAN_Tx_Rx
projects/n32g41x_EVAL/examples/bxCAN/CAN_LoopBack/ Composition of this example project: MDK-ARM/, EWARM/, inc/, src/, readme.txt
projects/n32g41x_EVAL/bsp/ Board support directory referenced by both example projects: evaluation-board resource definitions and common millisecond delay and log-printing implementations

5.2.2 API reference

Search API33 functions

The following 33 public functions are listed in the declaration order of n32g41x_can.h in 8 groups; each entry gives a summary and the original comment above the function in n32g41x_can.c.

Reset and initialization

CAN_DeInit, CAN_Init, CAN_InitStruct, CAN_InitFilter, CAN_SoftwareReset

Configuration

CAN_DebugFreeze, CAN_EnTTComMode

Operating mode control

CAN_OperatingModeReq, CAN_EnterSleep, CAN_WakeUp

Transmit

CAN_TransmitMessage, CAN_TransmitSTS, CAN_CancelTransmitMessage

Receive

CAN_ReceiveMessage, CAN_ReleaseFIFO, CAN_PendingMessage

Error management

CAN_GetLastErrCode, CAN_GetReceiveErrCounter, CAN_GetLSBTransmitErrCounter

Status query

CAN_GetTransmitFailStatus, CAN_GetArbitrationLostStatus, CAN_GetFlagLowestPriority, CAN_GetTransmitMailboxEmptyFlag, CAN_GetReceiveSignal, CAN_GetLastSamplePoint, CAN_GetReceiveMode, CAN_GetTransmitMode, CAN_GetMailboxCode

Interrupt and flag management

CAN_INTConfig, CAN_GetFlagSTS, CAN_ClearFlag, CAN_GetIntStatus, CAN_ClearINTPendingBit

void CAN_DeInit(const CAN_Module *CANx)Deinitializes the CAN peripheral registers to their default reset values.
Source comment
name    CAN_DeInit
fun     Deinitializes the CAN peripheral registers to their default reset values.
param   CANx:
             - CAN
return  none
uint8_t CAN_Init(CAN_Module *CANx, const CAN_InitType *CAN_InitParam)Initializes the CAN peripheral according to the specified parameters in the CAN_InitType structure.
Source comment
name   CAN_Init
fun    Initializes the CAN peripheral according to the specified
       parameters in the CAN_InitType structure.
param  CANx:
            - CAN
param  CAN_InitParam (The input parameters must be the following values) :
            - BaudRatePrescaler
                - It ranges from 1 to 1024.
            - OperatingMode
                - CAN_Normal_Mode
                - CAN_LoopBack_Mode
                - CAN_Silent_Mode
                - CAN_Silent_LoopBack_Mode
            - RSJW
                - CAN_RSJW_1tq
                - CAN_RSJW_2tq
                - CAN_RSJW_3tq
                - CAN_RSJW_4tq
            - TBS1
                - CAN_TBS1_1tq
                - CAN_TBS1_2tq
                - CAN_TBS1_3tq
                - CAN_TBS1_4tq
                - CAN_TBS1_5tq
                - CAN_TBS1_6tq
                - CAN_TBS1_7tq
                - CAN_TBS1_8tq
                - CAN_TBS1_9tq
                - CAN_TBS1_10tq
                - CAN_TBS1_11tq
                - CAN_TBS1_12tq
                - CAN_TBS1_13tq
                - CAN_TBS1_14tq
                - CAN_TBS1_15tq
                - CAN_TBS1_16tq
            - TBS2
                - CAN_TBS2_1tq
                - CAN_TBS2_2tq
                - CAN_TBS2_3tq
                - CAN_TBS2_4tq
                - CAN_TBS2_5tq
                - CAN_TBS2_6tq
                - CAN_TBS2_7tq
                - CAN_TBS2_8tq
            - TTCM
                - DISABLE
                - ENABLE
            - ABOM
                - DISABLE
                - ENABLE
            - AWKUM
                - DISABLE
                - ENABLE
            - NART
                - DISABLE
                - ENABLE
            - RFLM
                - DISABLE
                - ENABLE
            - TXFP
                - DISABLE
                - ENABLE
return InitStatus :
            - CAN_InitSTS_Failed
            - CAN_InitSTS_Success
void CAN_InitStruct(CAN_InitType *CAN_InitParam)Fills each CAN_InitType member with its default value.
Source comment
name   CAN_InitStruct
fun    Fills each CAN_InitType member with its default value.
param  CAN_InitParam (The input parameters must be the following values) :
            - BaudRatePrescaler
                - It ranges from 1 to 1024.
            - OperatingMode
                - CAN_Normal_Mode
                - CAN_LoopBack_Mode
                - CAN_Silent_Mode
                - CAN_Silent_LoopBack_Mode
            - RSJW
                - CAN_RSJW_1tq
                - CAN_RSJW_2tq
                - CAN_RSJW_3tq
                - CAN_RSJW_4tq
            - TBS1
                - CAN_TBS1_1tq
                - CAN_TBS1_2tq
                - CAN_TBS1_3tq
                - CAN_TBS1_4tq
                - CAN_TBS1_5tq
                - CAN_TBS1_6tq
                - CAN_TBS1_7tq
                - CAN_TBS1_8tq
                - CAN_TBS1_9tq
                - CAN_TBS1_10tq
                - CAN_TBS1_11tq
                - CAN_TBS1_12tq
                - CAN_TBS1_13tq
                - CAN_TBS1_14tq
                - CAN_TBS1_15tq
                - CAN_TBS1_16tq
            - TBS2
                - CAN_TBS2_1tq
                - CAN_TBS2_2tq
                - CAN_TBS2_3tq
                - CAN_TBS2_4tq
                - CAN_TBS2_5tq
                - CAN_TBS2_6tq
                - CAN_TBS2_7tq
                - CAN_TBS2_8tq
            - TTCM
                - DISABLE
                - ENABLE
            - ABOM
                - DISABLE
                - ENABLE
            - AWKUM
                - DISABLE
                - ENABLE
            - NART
                - DISABLE
                - ENABLE
            - RFLM
                - DISABLE
                - ENABLE
            - TXFP
                - DISABLE
                - ENABLE
return none
void CAN_InitFilter(const CAN_FilterInitType *CAN_InitFilterStruct)Initializes the CAN peripheral according to the specified parameters in the CAN_FilterInitType structure.
Source comment
name   CAN_InitFilter
fun    Initializes the CAN peripheral according to the specified
       parameters in the CAN_FilterInitType structure.
param  CAN_InitFilterStruct (The input parameters must be the following values) :
            - Filter_HighId
                - It ranges from 0x0000 to 0xFFFF
            - Filter_LowId
                - It ranges from 0x0000 to 0xFFFF
            - FilterMask_HighId
                - It ranges from 0x0000 to 0xFFFF
            - FilterMask_LowId
                - It ranges from 0x0000 to 0xFFFF
            - Filter_FIFOAssignment
                - CAN_Filter_FIFO0
                - CAN_Filter_FIFO1
            - Filter_Num
                - It ranges from 0 to 13
            - Filter_Mode
                - CAN_Filter_IdMaskMode
                - CAN_Filter_IdListMode
            - Filter_Scale
                - CAN_Filter_16bitScale
                - CAN_Filter_32bitScale
            - Filter_Act
                - ENABLE
                - DISABLE
return none
void CAN_SoftwareReset(CAN_Module *CANx)Enable software reset.
Source comment
name   CAN_SoftwareReset
fun    Enable software reset.
param  CANx:
               - CAN
return none
void CAN_DebugFreeze(CAN_Module *CANx, FunctionalState Cmd)Enables the DBG Freeze for CAN.
Source comment
name   CAN_DebugFreeze
fun    Enables the DBG Freeze for CAN.
param  CANx:
            - CAN
param  Cmd (The input parameters must be the following values):
            - DISABLE
            - ENABLE
return none
void CAN_EnTTComMode(CAN_Module *CANx, FunctionalState Cmd)Enables the CAN Time stamp sent.
Source comment
name   CAN_EnTTComMode
fun    Enables the CAN Time stamp sent.
param  CANx:
            - CAN
param  Cmd (The input parameters must be the following values):
            - DISABLE
            - ENABLE
note   when enabled, Time stamp (MTIM[15:0]) value is sent in the last
       two data bytes of the 8-byte message: MTIM[7:0] in data byte 6
       and MTIM[15:8] in data byte 7
note   DLC must be programmed as 8 in order Time Stamp (2 bytes) to be
       sent over the CAN bus.
return none
uint8_t CAN_OperatingModeReq(CAN_Module *CANx, uint8_t CAN_OperatingMode)Select the CAN Operation mode.
Source comment
name   CAN_OperatingModeReq
fun    Select the CAN Operation mode.
param  CANx:
            - CAN
param  CAN_OperatingMode (The input parameters must be the following values) :
               - CAN_Operating_InitMode
               - CAN_Operating_NormalMode
               - CAN_Operating_SleepMode
return status :
               - CAN_ModeSTS_Failed    CAN failed entering the specific mode
               - CAN_ModeSTS_Success   CAN Succeed entering the specific mode
uint8_t CAN_EnterSleep(CAN_Module *CANx)Enters sleep mode.
Source comment
name   CAN_EnterSleep
fun    Enters sleep mode.
param  CANx:
            - CAN
return sleepstatus:
            - CAN_SLEEP_Ok
            - CAN_SLEEP_Failed
uint8_t CAN_WakeUp(CAN_Module *CANx)Wakes the CAN up.
Source comment
name   CAN_WakeUp
fun    Wakes the CAN up.
param  CANx:
            - CAN
return CAN_Status:
            - CAN_WKU_Ok
            - CAN_WKU_Failed
uint8_t CAN_TransmitMessage(CAN_Module *CANx, CanTxMessage *TxMessage)initialize the transmission of a message.
Source comment
name   CAN_TransmitMessage
fun    initialize the transmission of a message.
param  CANx:
            - CAN
param  TxMessage  (The input parameters must be the following values):
            - StdId
                - It ranges from 0 to 0x7FF
            - ExtId
                - It ranges from 0 to 0x1FFFFFFF
            - IDE
                - CAN_Standard_Id
                - CAN_Extended_Id
            - RTR
                - CAN_RTRQ_Data
                - CAN_RTRQ_Remote
            - DLC
                - It ranges from 0 to 8
            - Data[0-7]
                - It ranges from 0 to 0xFF
return  transmit_mailbox (The input parameters must be the following values) :
            - CAN_TXMAILBOX_0
            - CAN_TXMAILBOX_1
            - CAN_TXMAILBOX_2
            - CAN_TxSTS_NoMailBox
uint8_t CAN_TransmitSTS(const CAN_Module *CANx, uint8_t TransmitMailbox)Checks the transmission of a message.
Source comment
name   CAN_TransmitSTS
fun    Checks the transmission of a message.
param  CANx:
            - CAN
param  TransmitMailbox (The input parameters must be the following values) :
            - CAN_TXMAILBOX_0
            - CAN_TXMAILBOX_1
            - CAN_TXMAILBOX_2
return state :
            - CAN_TxSTS_Failed
            - CAN_TxSTS_Ok
            - CAN_TxSTS_Pending
void CAN_CancelTransmitMessage(CAN_Module *CANx, uint8_t Mailbox)Cancels a transmit request.
Source comment
name   CAN_CancelTransmitMessage
brief  Cancels a transmit request.
param  CANx:
            - CAN
param  Mailbox (The input parameters must be the following values) :
            - CAN_TXMAILBOX_0
            - CAN_TXMAILBOX_1
            - CAN_TXMAILBOX_2
return none

Use note: The source comment provides a brief field but no fun field, so this summary is taken from brief; the implementation writes CAN_TSTS_ABRQM0, CAN_TSTS_ABRQM1 or CAN_TSTS_ABRQM2 to CANx->TSTS according to Mailbox, that is, it sets the abort request bit of the selected transmit mailbox, and does nothing for any other value of Mailbox.

void CAN_ReceiveMessage(CAN_Module *CANx, uint8_t FIFONum, CanRxMessage *RxMessage)Receives a message.
Source comment
name   CAN_ReceiveMessage
fun    Receives a message.
param  CANx:
            - CAN
param  FIFONum (The input parameters must be the following values) :
            - CAN_FIFO0
            - CAN_FIFO1
param  RxMessage (The input parameters must be the following values) :
            - StdId
                - It ranges from 0 to 0x7FF
            - ExtId
                - It ranges from 0 to 0x1FFFFFFF
            - IDE
                - CAN_Standard_Id
                - CAN_Extended_Id
            - RTR
                - CAN_RTRQ_Data
                - CAN_RTRQ_Remote
            - DLC
                - It ranges from 0 to 8
            - Data[0-7]
                - It ranges from 0 to 0xFF
            - FMI
                - It ranges from 0 to 0xFF
return none
void CAN_ReleaseFIFO(CAN_Module *CANx, uint8_t FIFONum)Releases the specified DATAFIFO.
Source comment
name   CAN_ReleaseFIFO
fun    Releases the specified DATAFIFO.
param  CANx:
            - CAN
param  FIFONum (The input parameters must be the following values) :
            - CAN_FIFO0
            - CAN_FIFO1
return none
uint8_t CAN_PendingMessage(const CAN_Module *CANx, uint8_t FIFONum)Returns the number of pending messages.
Source comment
name   CAN_PendingMessage
fun    Returns the number of pending messages.
param  CANx :
            - CAN
param  FIFONum (The input parameters must be the following values) :
            - CAN_FIFO0
            - CAN_FIFO1
return message_pending :
            - CAN_FIFOX_PENDING_0
            - CAN_FIFOX_PENDING_1
            - CAN_FIFOX_PENDING_2
            - CAN_FIFOX_PENDING_3
uint8_t CAN_GetLastErrCode(const CAN_Module *CANx)Returns the CANx’s last error code (LEC).
Source comment
name   CAN_GetLastErrCode
fun    Returns the CANx's last error code (LEC).
param  CANx:
            - CAN
return errorcode :
            - CAN_ERRORCODE_NoErr            No Error
            - CAN_ERRORCODE_StuffErr         Stuff Error
            - CAN_ERRORCODE_FormErr          Form Error
            - CAN_ERRORCODE_ACKErr           Acknowledgment Error
            - CAN_ERRORCODE_BitRecessiveErr  Bit Recessive Error
            - CAN_ERRORCODE_BitDominantErr   Bit Dominant Error
            - CAN_ERRORCODE_CRCErr           CRC Error
            - CAN_ERRORCODE_SoftwareSetErr   Software Set Error
uint8_t CAN_GetReceiveErrCounter(const CAN_Module *CANx)Returns the CANx Receive Error Counter (REC).
Source comment
name   CAN_GetReceiveErrCounter
fun    Returns the CANx Receive Error Counter (REC).
param  CANx:
            - CAN
return counter_value:
            - It ranges from 0 to 255
note   In case of an error during reception, this counter is incremented
       by 1 or by 8 depending on the error condition as defined by the CAN
       standard. After every successful reception, the counter is
       decremented by 1 or reset to 120 if its value was higher than 127.
       When the counter value exceeds 127, the CAN controller enters the
       error passive state.
uint8_t CAN_GetLSBTransmitErrCounter(const CAN_Module *CANx)Returns the LSB of the 9-bit CANx Transmit Error Counter(TEC).
Source comment
name   CAN_GetLSBTransmitErrCounter
fun    Returns the LSB of the 9-bit CANx Transmit Error Counter(TEC).
param  CANx:
            - CAN
return counter_value:
            - It ranges from 0 to 255
FlagStatus CAN_GetTransmitFailStatus(const CAN_Module *CANx, uint8_t mailbox_queue)Get the transmit failure status of the given transmit mailbox.
Source comment
name   CAN_GetTransmitFailStatus
fun    Get the transmit failure status of the given transmit mailbox.
param  CANx:
               - CAN
param  mailbox_queue:
               - CAN_TXMAILBOX_0
               - CAN_TXMAILBOX_1
               - CAN_TXMAILBOX_2
return FlagStatus:
               - SET
               - RESET
FlagStatus CAN_GetArbitrationLostStatus(const CAN_Module *CANx, uint8_t mailbox_queue)Get the status of arbitration lost.
Source comment
name   CAN_GetArbitrationLostStatus
fun    Get the status of arbitration lost.
param  CANx:
               - CAN
param  mailbox_queue:
               - CAN_TXMAILBOX_0
               - CAN_TXMAILBOX_1
               - CAN_TXMAILBOX_2
return FlagStatus:
               - SET
               - RESET
FlagStatus CAN_GetFlagLowestPriority(const CAN_Module *CANx, uint8_t mailbox_queue)Get the flag of lowest priority.
Source comment
name   CAN_GetFlagLowestPriority
fun    Get the flag of lowest priority.
param  CANx:
               - CAN
param  mailbox_queue:
               - CAN_TXMAILBOX_0
               - CAN_TXMAILBOX_1
               - CAN_TXMAILBOX_2
return FlagStatus:
               - SET
               - RESET
FlagStatus CAN_GetTransmitMailboxEmptyFlag(const CAN_Module *CANx, uint8_t mailbox_queue)Get the flag of Transmit mailbox empty.
Source comment
name   CAN_GetTransmitMailboxEmptyFlag
fun    Get the flag of Transmit mailbox empty.
param  CANx:
               - CAN
param  mailbox_queue:
               - CAN_TXMAILBOX_0
               - CAN_TXMAILBOX_1
               - CAN_TXMAILBOX_2
return FlagStatus:
               - SET
               - RESET
FlagStatus CAN_GetReceiveSignal(const CAN_Module *CANx)Returns the CANx’s receive signal value (RXS).
Source comment
name   CAN_GetReceiveSignal
fun    Returns the CANx's receive signal value (RXS).
param  CANx:
            - CAN
return FlagStatus:
            - SET
            - RESET
FlagStatus CAN_GetLastSamplePoint(const CAN_Module *CANx)Returns the CANx’s Last sample point (LSMP).
Source comment
name   CAN_GetLastSamplePoint
fun    Returns the CANx's Last sample point (LSMP).
param  CANx:
            - CAN
return FlagStatus:
            - SET
            - RESET
FlagStatus CAN_GetReceiveMode(const CAN_Module *CANx)Returns the CANx’s receive mode (RXMD).
Source comment
name   CAN_GetReceiveMode
fun    Returns the CANx's receive mode (RXMD).
param  CANx:
            - CAN
return FlagStatus:
            - SET
            - RESET
FlagStatus CAN_GetTransmitMode(const CAN_Module *CANx)Returns the CANx’s transmit mode (TXMD).
Source comment
name   CAN_GetTransmitMode
fun    Returns the CANx's transmit mode (TXMD).
param  CANx:
            - CAN
return FlagStatus:
            - SET
            - RESET
uint8_t CAN_GetMailboxCode(const CAN_Module *CANx)Returns the CANx’s mailbox code (CODE[1:0]).
Source comment
name   CAN_GetMailboxCode
fun    Returns the CANx's mailbox code (CODE[1:0]).
param  CANx:
            - CAN
return  mailbox_queue :
            - CAN_TXMAILBOX_0
            - CAN_TXMAILBOX_1
            - CAN_TXMAILBOX_2
            - CAN_TxSTS_NoMailBox
void CAN_INTConfig(CAN_Module *CANx, uint32_t CAN_INT, FunctionalState Cmd)Enables or disables the specified CANx interrupts according to Cmd.
Source comment
name   CAN_INTConfig
fun    Enables or disables the specified CANx interrupts according
       to Cmd.
param  CANx:
               - CAN
param  CAN_INT (The input parameters must be the following values) :
               - CAN_INT_TME,
               - CAN_INT_FMP0,
               - CAN_INT_FF0,
               - CAN_INT_FOV0,
               - CAN_INT_FMP1,
               - CAN_INT_FF1,
               - CAN_INT_FOV1,
               - CAN_INT_EWG,
               - CAN_INT_EPV,
               - CAN_INT_BOF,
               - CAN_INT_LEC,
               - CAN_INT_ERR,
               - CAN_INT_WKU,
               - CAN_INT_SLK.
param  Cmd :
               - DISABLE
               - ENABLE
return none
FlagStatus CAN_GetFlagSTS(const CAN_Module *CANx, uint32_t CAN_FLAG)Checks whether the specified CAN flag is set or not.
Source comment
name   CAN_GetFlagSTS
fun    Checks whether the specified CAN flag is set or not.
param  CANx:
                - CAN
param  CAN_FLAG (The input parameters must be the following values) :
                - CAN_FLAG_EWGFL
                - CAN_FLAG_EPVFL
                - CAN_FLAG_BOFFL
                - CAN_FLAG_LEC
                - CAN_FLAG_RQCPM0
                - CAN_FLAG_RQCPM1
                - CAN_FLAG_RQCPM2
                - CAN_FLAG_FFMP1
                - CAN_FLAG_FFULL1
                - CAN_FLAG_FFOVR1
                - CAN_FLAG_FFMP0
                - CAN_FLAG_FFULL0
                - CAN_FLAG_FFOVR0
                - CAN_FLAG_WKU
                - CAN_FLAG_SLAK
return  FlagStatus:
                - SET
                - RESET
void CAN_ClearFlag(CAN_Module *CANx, uint32_t CAN_FLAG)Clears the CAN’s flag status.
Source comment
name   CAN_ClearFlag
fun    Clears the CAN's flag status.
param  CANx:
                  - CAN
param  CAN_FLAG (The input parameters must be the following values) :
                  - CAN_FLAG_RQCPM0
                  - CAN_FLAG_RQCPM1
                  - CAN_FLAG_RQCPM2
                  - CAN_FLAG_FFULL1
                  - CAN_FLAG_FFOVR1
                  - CAN_FLAG_FFULL0
                  - CAN_FLAG_FFOVR0
                  - CAN_FLAG_WKU
                  - CAN_FLAG_SLAK
                  - CAN_FLAG_LEC
return none
INTStatus CAN_GetIntStatus(const CAN_Module *CANx, uint32_t CAN_INT)Checks whether the specified CANx interrupt has occurred or not.
Source comment
name   CAN_GetIntStatus
fun    Checks whether the specified CANx interrupt has occurred or not.
param  CANx:
                    -  CAN
param  CAN_INT (The input parameters must be the following values) :
                    -  CAN_INT_TME
                    -  CAN_INT_FMP0
                    -  CAN_INT_FF0
                    -  CAN_INT_FOV0
                    -  CAN_INT_FMP1
                    -  CAN_INT_FF1
                    -  CAN_INT_FOV1
                    -  CAN_INT_WKU
                    -  CAN_INT_SLK
                    -  CAN_INT_EWG
                    -  CAN_INT_EPV
                    -  CAN_INT_BOF
                    -  CAN_INT_LEC
                    -  CAN_INT_ERR
return INTStatus :
                    - SET
                    - RESET
void CAN_ClearINTPendingBit(CAN_Module *CANx, uint32_t CAN_INT)Clears the CANx’s interrupt status.
Source comment
name   CAN_ClearINTPendingBit
fun    Clears the CANx's interrupt status.
param  CANx:
                -  CAN
param  CAN_INT (The input parameters must be the following values) :
                -  CAN_INT_TME
                -  CAN_INT_FF0
                -  CAN_INT_FOV0
                -  CAN_INT_FF1
                -  CAN_INT_FOV1
                -  CAN_INT_WKU
                -  CAN_INT_SLK
                -  CAN_INT_EWG
                -  CAN_INT_EPV
                -  CAN_INT_BOF
                -  CAN_INT_LEC
                -  CAN_INT_ERR
return none

5.2.3 Demo descriptions

This section describes the 2 bxCAN examples: CAN_LoopBack loops each transmitted message back for internal reception in loopback mode, and CAN_Tx_Rx sends and receives messages through an external transceiver and bus in normal mode.

5.2.3.1 CAN_LoopBack Loopback transfer

Example directory: projects/n32g41x_EVAL/examples/bxCAN/CAN_LoopBack/

Enable the CAN and GPIO clocks→configure PA11 and PA12 for CAN alternate function→initialize CAN and the receive filter in loopback mode→transmit one message and wait for the looped-back reception→verify the received message, delay, and transmit again

Item Source analysis
Function In loopback test mode, transmits one standard data frame;
the message loops back internally to the receive FIFO, and after the identifier and the 8 data bytes are compared successfully the next frame is transmitted, repeating indefinitely.
Source files src/main.c: main and the message field assignments;
src/can_config.c: CAN_CONFIG, CAN_NVIC_Configuration, CAN_GPIO_Configuration and Check_CanRecData;
inc/can_config.h: pin and filter macros, the Check_CanRecData declaration and the extern variables;
inc/main.h: includes the driver and configuration headers;
src/n32g41x_it.c, inc/n32g41x_it.h: interrupt service functions such as CAN_IRQHandler;
readme.txt: function, environment and usage notes;
MDK-ARM/, EWARM/: Keil and IAR projects.
Key configuration Pins: RX is PA11 and TX is PA12, both on GPIO_AF1, switched by the N32G412 and N32G415 macros;
RX is GPIO_MODE_INPUT, GPIO_PULL_UP and GPIO_DS_HIGH, TX is GPIO_MODE_AF_PP and GPIO_DS_HIGH;
Mode: OperatingMode is CAN_LoopBack_Mode and TXFP is ENABLE, while TTCM, ABOM, AWKUM, NART and RFLM are DISABLE;
Baud rate: 500 Kbps, APB1 48 MHz with prescaler 6 under N32G415 and 40 MHz with prescaler 5 otherwise;
Filter: bank 0 in 32-bit mask mode assigned to CAN_FIFO0, admitting only identifier 0x400;
Interrupt: FIFO0 pending, preemption and subpriority 0x0;
Clock: HSI+PLL, 80 MHz for N32G412 and 96 MHz for N32G415.
Program and data path main first calls CAN_CONFIG to initialize the clock, GPIO, NVIC, CAN and the filter, then fills CAN_TxMessage;
in the while loop it first calls CAN_TransmitMessage to request transmission, then repeatedly calls Check_CanRecData in the Rx_Flag is DISABLE loop to compare the message;
the FIFO0 pending interrupt triggers CAN_IRQHandler, where CAN_ReceiveMessage reads the message;
after a successful check the loop delays and clears Rx_Flag for the next round.
Main APIs CAN_InitStruct, CAN_Init, CAN_InitFilter, CAN_TransmitMessage, CAN_ReceiveMessage, CAN_INTConfig
Verification After download and reset, a CAN analyser shows a message with identifier 0x400 and data 0x00 to 0x07 being transmitted repeatedly;
in loopback mode no external transceiver is needed, and the return value of Check_CanRecData can also be observed for a non-zero result.
Use note In loopback mode TX is fed back internally to RX, so no external CAN transceiver or bus is needed;
the development environment is KEIL MDK-ARM 5.34 or IAR EWARM 8.50.1, on the N32G41x_STB V1.0 evaluation board.
Core-code walkthrough and porting

The example first completes clock, pin and CAN initialization, then the main loop transmits a message and verifies the looped-back message with the help of an interrupt.

Data path: main -> CAN_CONFIG enables the clocks and configures GPIO, NVIC, CAN and the filter -> CAN_TransmitMessage requests transmission -> the looped-back reception triggers CAN_IRQHandler -> CAN_ReceiveMessage reads FIFO0 -> Check_CanRecData compares -> after a delay Rx_Flag is cleared

1. Start from default values and reset CAN. CAN_CONFIG first enables the CAN clock, then configures the interrupt and the pins, and then CAN_DeInit resets the registers and CAN_InitStruct fills them with default values.

src/can_config.csrc/can_config.c · CAN_CONFIG
    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_CAN, ENABLE);

    CAN_NVIC_Configuration();
    CAN_GPIO_Configuration();

    CAN_DeInit(CAN);
    CAN_InitStruct(&CAN_InitStructure);

When porting to another board, only CAN_GPIO_Configuration and the pin macros in can_config.h need to change.

2. Bit timing gives 500 Kbps per model. N32G415 uses APB1 at 48 MHz with a prescaler of 6, and the other models use APB1 at 40 MHz with a prescaler of 5, with the same segment parameters.

src/can_config.csrc/can_config.c · CAN_CONFIG
#ifdef N32G415
    /* Baud rate = APB1CLK / (BaudRatePrescaler * (TBS1 + TBS2 + 1))
       APB1CLK = 48MHz, 48000000 / (6 * (11 + 4 + 1)) = 500000 = 500Kbps */
    CAN_InitStructure.RSJW              = CAN_RSJW_4tq;
    CAN_InitStructure.TBS1              = CAN_TBS1_11tq;
    CAN_InitStructure.TBS2              = CAN_TBS2_4tq;
    CAN_InitStructure.BaudRatePrescaler = 6;
#else
    /* Baud rate = APB1CLK / (BaudRatePrescaler * (TBS1 + TBS2 + 1))
       APB1CLK = 40MHz, 40000000 / (5 * (11 + 4 + 1)) = 500000 = 500Kbps */
    CAN_InitStructure.RSJW              = CAN_RSJW_4tq;
    CAN_InitStructure.TBS1              = CAN_TBS1_11tq;
    CAN_InitStructure.TBS2              = CAN_TBS2_4tq;
    CAN_InitStructure.BaudRatePrescaler = 5;
#endif

When switching model or converting another baud rate, change BaudRatePrescaler, TBS1, TBS2 and RSJW together.

3. Filter 0 admits only identifier 0x400. The filter is configured as 32-bit mask mode and assigned to FIFO0, and both the match values and the masks come from macros in inc/can_config.h, comparing only the bits that must match.

src/can_config.csrc/can_config.c · CAN_CONFIG
    CAN_FilterInitStructure.Filter_Num            = 0;
    CAN_FilterInitStructure.Filter_Mode           = CAN_Filter_IdMaskMode;
    CAN_FilterInitStructure.Filter_Scale          = CAN_Filter_32bitScale;
    CAN_FilterInitStructure.Filter_HighId         = CAN_STD_ID_LIST_32BIT_H(0x00000400);
    CAN_FilterInitStructure.Filter_LowId          = CAN_STD_ID_LIST_32BIT_L(0x00000400);
    CAN_FilterInitStructure.FilterMask_HighId     = CAN_STD_ID_LIST_32BIT_H(0x00000200);
    CAN_FilterInitStructure.FilterMask_LowId      = CAN_STD_ID_LIST_32BIT_L(0x00000200);
    CAN_FilterInitStructure.Filter_FIFOAssignment = CAN_FIFO0;
    CAN_FilterInitStructure.Filter_Act            = ENABLE;
    CAN_InitFilter(&CAN_FilterInitStructure);

To receive other identifiers, change Filter_HighId, Filter_LowId and the matching mask values together.

4. The interrupt fetches the message and the main loop verifies before retransmitting. The FIFO0 pending interrupt reads the message into CAN_RxMessage, and the main loop waits on the flag after transmitting and compares the message with Check_CanRecData.

src/n32g41x_it.csrc/n32g41x_it.c · CAN_IRQHandler
void CAN_IRQHandler(void)
{
    /* Receives a message */
    CAN_ReceiveMessage(CAN, CAN_FIFO0, &CAN_RxMessage);
}
src/main.csrc/main.c · main
    while(1)
    {
        /* Transmit */
        CAN_TransmitMessage(CAN, &CAN_TxMessage);
        while(Rx_Flag == DISABLE)
        {
            Rx_Flag = Check_CanRecData(&CAN_RxMessage, 0x0400, 0x00, CAN_Standard_Id, CAN_RTRQ_Data, 8,
                         0x00, 0x01, 0x02, 0x03,
                         0x04, 0x05, 0x06, 0x07, 0);
        }

        /* Delay */
        wait_slak = 0xFFFF;
        while(wait_slak > 0)
        {
            wait_slak--;
        }
        Rx_Flag = DISABLE;
    }

When the expected message changes, change the Check_CanRecData arguments and the CAN_TxMessage field assignments in main together.

Corresponding source files: src/main.c, src/can_config.c, src/n32g41x_it.c, inc/can_config.h

5.2.3.2 CAN_Tx_Rx Normal-mode transfer

Example directory: projects/n32g41x_EVAL/examples/bxCAN/CAN_Tx_Rx/

Enable the CAN and GPIO clocks→configure PA11 and PA12 for CAN alternate function→initialize CAN and the receive filter in normal mode→transmit one message after start-up→after a message from the bus an interrupt sets the flag and one more message is transmitted

Item Source analysis
Function In normal mode, transmits one standard data frame after start-up and then waits for messages on the bus;
after one message is received an interrupt sets a flag and the main loop transmits one more frame, repeating indefinitely.
Source files src/main.c: main and the message field assignments;
src/can_config.c: CAN_CONFIG, CAN_NVIC_Configuration, CAN_GPIO_Configuration and Check_CanRecData;
inc/can_config.h: pin and filter macros, the Check_CanRecData declaration and the extern variables;
inc/main.h: includes the driver and configuration headers;
src/n32g41x_it.c, inc/n32g41x_it.h: interrupt service functions such as CAN_IRQHandler;
readme.txt: function, environment and usage notes;
MDK-ARM/, EWARM/: Keil and IAR projects.
Key configuration Pins: RX is PA11 and TX is PA12, both on GPIO_AF1, switched by the N32G412 and N32G415 macros;
RX is GPIO_MODE_INPUT, GPIO_PULL_UP and GPIO_DS_HIGH, TX is GPIO_MODE_AF_PP and GPIO_DS_HIGH;
Mode: OperatingMode is CAN_Normal_Mode and TXFP is ENABLE, while TTCM, ABOM, AWKUM, NART and RFLM are DISABLE;
Baud rate: 500 Kbps, APB1 48 MHz with prescaler 6 under N32G415 and 40 MHz with prescaler 5 otherwise;
Filter: bank 0 in 32-bit mask mode assigned to CAN_FIFO0, admitting only identifier 0x400;
Interrupt: FIFO0 pending, preemption and subpriority 0x0;
Clock: HSI+PLL, 80 MHz for N32G412 and 96 MHz for N32G415.
Program and data path main first calls CAN_CONFIG to initialize the peripheral, then fills CAN_TxMessage;
in the while loop it first calls CAN_TransmitMessage to request transmission, then polls Rx_Flag;
the FIFO0 pending interrupt triggers CAN_IRQHandler, where CAN_ReceiveMessage reads the message and sets Rx_Flag to ENABLE;
the main loop clears Rx_Flag and transmits again.
Main APIs CAN_InitStruct, CAN_Init, CAN_InitFilter, CAN_TransmitMessage, CAN_ReceiveMessage, CAN_INTConfig
Verification An external CAN transceiver and CAN bus are required;
other nodes on the bus see a message with identifier 0x400 and data 0x00 to 0x07, and this node transmits one more frame after each received message.
Use note Normal mode needs an external CAN transceiver and a connection to the CAN bus;
the development environment is KEIL MDK-ARM 5.34 or IAR EWARM 8.50.1, on the N32G41x_STB V1.0 evaluation board.
Core-code walkthrough and porting

The example first completes clock, pin and CAN initialization, then the main loop triggers the next transmission from each received message.

Data path: main -> CAN_CONFIG enables the clocks and configures GPIO, NVIC, CAN and the filter -> CAN_TransmitMessage transmits the first frame -> a reception from the bus triggers CAN_IRQHandler -> CAN_ReceiveMessage reads FIFO0 and sets Rx_Flag -> the main loop clears the flag and transmits again

1. Start from default values and reset CAN. CAN_CONFIG first enables the CAN clock, then configures the interrupt and the pins, and then CAN_DeInit resets the registers and CAN_InitStruct fills them with default values.

src/can_config.csrc/can_config.c · CAN_CONFIG
    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_CAN, ENABLE);

    CAN_NVIC_Configuration();
    CAN_GPIO_Configuration();

    CAN_DeInit(CAN);
    CAN_InitStruct(&CAN_InitStructure);

When porting to another board, only CAN_GPIO_Configuration and the pin macros in can_config.h need to change.

2. Operating mode is normal transfer with 500 Kbps. OperatingMode is CAN_Normal_Mode and the bit timing is still split per model.

src/can_config.csrc/can_config.c · CAN_CONFIG
    /* CAN cell init */
    CAN_InitStructure.TTCM          = DISABLE;
    CAN_InitStructure.ABOM          = DISABLE;
    CAN_InitStructure.AWKUM         = DISABLE;
    CAN_InitStructure.NART          = DISABLE;
    CAN_InitStructure.RFLM          = DISABLE;
    CAN_InitStructure.TXFP          = ENABLE;
    CAN_InitStructure.OperatingMode = CAN_Normal_Mode;

#ifdef N32G415
    /* Baud rate = APB1CLK / (BaudRatePrescaler * (TBS1 + TBS2 + 1))
       APB1CLK = 48MHz, 48000000 / (6 * (11 + 4 + 1)) = 500000 = 500Kbps */
    CAN_InitStructure.RSJW              = CAN_RSJW_4tq;
    CAN_InitStructure.TBS1              = CAN_TBS1_11tq;
    CAN_InitStructure.TBS2              = CAN_TBS2_4tq;
    CAN_InitStructure.BaudRatePrescaler = 6;
#else
    /* Baud rate = APB1CLK / (BaudRatePrescaler * (TBS1 + TBS2 + 1))
       APB1CLK = 40MHz, 40000000 / (5 * (11 + 4 + 1)) = 500000 = 500Kbps */
    CAN_InitStructure.RSJW              = CAN_RSJW_4tq;
    CAN_InitStructure.TBS1              = CAN_TBS1_11tq;
    CAN_InitStructure.TBS2              = CAN_TBS2_4tq;
    CAN_InitStructure.BaudRatePrescaler = 5;
#endif

To use another mode change OperatingMode, and to convert the baud rate change BaudRatePrescaler, TBS1, TBS2 and RSJW together.

3. The main loop transmits and then waits on the flag. Each round transmits one frame and then blocks in the empty Rx_Flag is DISABLE loop until the interrupt sets the flag, after which the flag is cleared and the next round begins.

src/main.csrc/main.c · main
    while(1)
    {
        CAN_TransmitMessage(CAN, &CAN_TxMessage);
        while(Rx_Flag == DISABLE)
        {

        }
        Rx_Flag = DISABLE;
    }

To replace the polling with an event-driven design, organise the next transmission directly inside CAN_IRQHandler.

4. The interrupt sets a software flag after receiving a message. CAN_IRQHandler reads the message from FIFO0 and sets Rx_Flag to ENABLE, which is what makes the main loop continue transmitting.

src/n32g41x_it.csrc/n32g41x_it.c · CAN_IRQHandler
void CAN_IRQHandler(void)
{
    /* Receives a message */
    CAN_ReceiveMessage(CAN, CAN_FIFO0, &CAN_RxMessage);

    /* flag set */
    Rx_Flag = ENABLE;
}

Corresponding source files: src/main.c, src/can_config.c, src/n32g41x_it.c, inc/can_config.h

5.2.4 Notes and troubleshooting

Scenario Check & action Source
Width of one access to a CAN register The CAN peripheral registers must be accessed as words (32 bits), never as half-words or bytes;
when driving the registers directly, read and write them at their word width.
User manual
Changing bit timing outside initialization mode CAN_BTIM can only be modified while the CAN cell is in initialization mode, and the bit timing cannot be changed after leaving that mode;
set the baud rate and sampling point once during initialization.
User manual
Configuring or modifying a receive filter Before changing the filter values and settings, clear the corresponding CAN_FMC.FAC bit or set CAN_FMC.FINITM to 1;
CAN_FMC.FINITM set to 1 disables reception, and unused filter banks should stay deactivated.
User manual
Writing transmit mailbox data Software may modify the transmit mailbox registers only while CAN_TSTS.TMEM is 1 (mailbox empty);
after the mailbox TXRQ is set the mailbox enters the pending state and its registers are write-protected.
User manual
Aborting a transmit request Setting CAN_TSTS.ABRQM can abort a transmit request: when the mailbox is in the ready or pending state it aborts immediately;
when the mailbox is transmitting, a failed transmission is aborted after it becomes ready and the transmit-OK flag is cleared, while a successful transmission empties the mailbox and the hardware sets the transmit-OK flag.
User manual
Entering initialization mode or starting from reset After reset CAN is in sleep mode;
to enter initialization mode from sleep, set CAN_MCTRL.INIRQ and clear CAN_MCTRL.SLPRQ at the same time, then wait for CAN_MSTS.INIAK to be set.
User manual
Recovery after bus-off When the transmit error counter exceeds 255 the bus-off flag is set;
recovery requires 128 contiguous 11-bit recessive sequences on the CANRX pin, and initialization mode does not monitor CANRX, so recovery cannot complete there and the cell must leave initialization mode first.
User manual

The N32G412 and N32G415 series errata sheet V1.0.0 (2026.6.30) lists a single row for revision A chips with an empty errata link column, and gives no CAN-related entries. All the conclusions above are taken from the “Controller area network (CAN)” chapter of the user manual.

Nations Technologies DevKit Docs

Datasheets, SDK, driver APIs and demo guides for Nations Technologies MCU development kits, organized by chip series.

© 2026 Nations Technologies Inc. All rights reserved.粤ICP备11069485号This site uses cookie-free anonymous analytics.