5.28 USART Guide

This chapter covers the files of the USART driver in the N32H49x standard peripheral library, its 46 public functions, and 16 examples such as 485, LIN, and IrDA. Read it together with the “USART” chapter of the user manual for the mechanisms of register bit definitions, fractional baud-rate calculation, FIFO and thresholds, multiprocessor communication, synchronous mode, single-wire half-duplex, smart card, IrDA, hardware flow control, and receiver timeout.

5.28.1 Related files

Relative path Purpose
firmware/n32h49x_std_periph_driver/inc/n32h49x_usart.h Defines the USART_InitType and USART_ClockInitType structures and the macros for word length, stop bits, parity, mode, hardware flow control, oversampling, clock, interrupts, DMA, wake-up, LIN, IrDA, smart card, half-duplex, flags, and FIFO depth, and declares the 46 public functions
firmware/n32h49x_std_periph_driver/src/n32h49x_usart.c Implements the 46 functions: reset and initialization, data transmit and receive, flag and interrupt status access, DMA, multiprocessor, LIN, synchronous, half-duplex, smart card, IrDA, driver enable, and FIFO configuration
projects/n32h49x_EVAL/examples/USART/ USART example root, containing 16 examples: 485_Master, 485_Slave, DMA_Interrupt, DMA_Polling, FIFO_Interrupt, HalfDuplex, HardwareFlowCtrl, Interrupt, Transmit_Receive, LIN_Master, LIN_Slave, MultiProcessor, Polling, Printf, SmartCard, Synchronous
projects/n32h49x_EVAL/examples/USART/Polling/ Project layout of that example: MDK-ARM/, EWARM/, inc/, src/, readme.txt
projects/n32h49x_EVAL/bsp/ Board support files used by some demos of this module: evaluation board definitions, millisecond and microsecond delays, and UART print remapping

5.28.2 API reference

Search API46 functions

The 46 public functions below follow the declaration order of n32h49x_usart.h and fall into 8 groups; each entry gives a summary and the original comment directly above the function in n32h49x_usart.c.

Reset and initialization

USART_DeInit, USART_Init, USART_StructInit, USART_ClockInit, USART_ClockStructInit, USART_Enable

Interrupts, DMA, and multiprocessor communication

USART_ConfigInt, USART_EnableDMA, USART_SetAddr, USART_ConfigWakeUpMode, USART_EnableRcvWakeUp

LIN and data transfer

USART_ConfigLINBreakDetectLength, USART_EnableLIN, USART_SendData, USART_ReceiveData, USART_SendBreak

Smart card, IrDA, and half-duplex

USART_SetGuardTime, USART_SetPrescaler, USART_EnableSmartCard, USART_SetSmartCardNACK, USART_EnableHalfDuplex, USART_ConfigIrDAMode, USART_EnableIrDA

Flags and interrupt status

USART_GetFlagStatus, USART_ClrFlag, USART_ClrRTOFlag, USART_GetIntStatus

Driver enable, pin swap, and idle frame control

USART_IdleFrameSet, USART_PinSwapSet, USART_CfgDriverAssertTime, USART_CfgDriverdeassertTime, USART_DriverPolaritySet, USART_DriverModeSet

Error discard and receiver timeout

USART_FEFDiscardSet, USART_NEFDiscardSet, USART_PEFDiscardSet, USART_RTOSet

FIFO and timeout width

USART_GetTxFIFO_Num, USART_GetRxFIFO_Num, USART_CfgRxFIFOThreshold, USART_CfgTxFIFOThreshold, USART_ClrFIFO, USART_FIFOModeSet, USART_IdleFrameWidthSet, USART_CfgRTOWidth, USART_FirstByteDelayFixSet

void USART_DeInit(USART_Module* USARTx)Deinitializes the USARTx peripheral registers to their default reset values.
Source comment
name    USART_DeInit
fun     Deinitializes the USARTx peripheral registers to their default reset values.
param   U(S)ARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
return  none
void USART_Init(USART_Module* USARTx, USART_InitType* USART_InitStruct)Initializes the USARTx peripheral according to USART_InitStruct.
Source comment
name    USART_Init
fun     Initializes the USARTx peripheral according to USART_InitStruct.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param   USART_InitStruct (The input parameters must be the following values):
          - buad_rate :
            - (((buad_rate) > 0) && ((buad_rate) < 0x00E4E1C0))
          - WordLength
            - USART_WL_8B
            - USART_WL_9B
          - StopBits
            - USART_STPB_1
            - USART_STPB_0_5
            - USART_STPB_2
            - USART_STPB_1_5
          - Parity
            - USART_PE_NO
            - USART_PE_EVEN
            - USART_PE_ODD
          - Mode
            - USART_MODE_RX
            - USART_MODE_TX
          - HardwareFlowControl
            - USART_HFCTRL_NONE
            - USART_HFCTRL_RTS
            - USART_HFCTRL_CTS
            - USART_HFCTRL_RTS_CTS
          - OverSampling
            - USART_8OVER
            - USART_16OVER
return  none
void USART_StructInit(USART_InitType* USART_InitStruct)Fills each USART_InitStruct member with its default value.
Source comment
name    USART_StructInit.
fun     Fills each USART_InitStruct member with its default value.
param   USART_InitStruct (The input parameters must be the following values):
          - BaudRate
          - WordLength
          - StopBits
          - Parity
          - Mode
          - OverSampling
return  none
void USART_ClockInit(USART_Module* USARTx, USART_ClockInitType* USART_ClockInitStruct)Initializes the USARTx peripheral Clock according to the specified parameters in the USART_ClockInitStruct.
Source comment
name    USART_ClockInit
fun     Initializes the USARTx peripheral Clock according to the specified parameters in the USART_ClockInitStruct.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
param   USART_ClockInitStruct (The input parameters must be the following values):
          - Clock :
            - USART_CLK_DISABLE
            - USART_CLK_ENABLE
          - USART_Clock_Polarity
            - USART_CLKPOL_LOW
            - USART_CLKPOL_HIGH
          - USART_Clock_Phase
            - USART_CLKPHA_1EDGE
            - USART_CLKPHA_2EDGE
          - USART_Last_Bit
            - USART_CLKLB_DISABLE
            - USART_CLKLB_ENABLE
return  none
note    The Smart Card and Synchronous modes are not available for UART5/UART6/UART7/UART8.
void USART_ClockStructInit(USART_ClockInitType* USART_ClockInitStruct)Fills each USART_ClockInitStruct member with its default value.
Source comment
name    USART_ClockStructInit
fun     Fills each USART_ClockInitStruct member with its default value.
param   USART_ClockInitStruct (The input parameters must be the following values):
          - Clock
          - USART_Clock_Polarity
          - USART_Clock_Phase
          - USART_Last_Bit
return  none
void USART_Enable(USART_Module* USARTx, FunctionalState Cmd)Enables or disables the specified USART peripheral.
Source comment
name    USART_Enable
fun     Enables or disables the specified USART peripheral.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param   Cmd (The input parameters must be the following values):
          - ENABLE
          - DISABLE
return  none
void USART_ConfigInt(USART_Module* USARTx, uint32_t USART_INT, FunctionalState Cmd)Enables or disables the specified USART interrupts.
Source comment
name    USART_ConfigInt
fun     Enables or disables the specified USART interrupts.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param   USART_INT (The input parameters must be the following values):
          - USART_INT_PEF   Parity Error interrupt
          - USART_INT_TXC   Transmission complete interrupt
          - USART_INT_TXDE  Transmit Data Register empty interrupt
          - USART_INT_RXDNE Receive Data register not empty interrupt
          - USART_INT_IDLEF Idle line detection interrupt
          - USART_INT_RTOE  Receiver timeout interrupt
          - USART_INT_LINBD LIN Break detection interrupt
          - USART_INT_ERRF  Error interrupt(Frame error, noise error, overrun error)
          - USART_INT_CTSF  CTS change interrupt
          - USART_INT_TXFTE  TXFIFO threshold interrupt enable
          - USART_INT_RXFTE  RXFIFO threshold interrupt enable
          - USART_INT_RXFEE  RXFIFO empty interrupt enable
          - USART_INT_TXFEE  TXFIFO empty interrupt enable
          - USART_INT_RXFFE  RXFIFO full interrupt enable
          - USART_INT_TXFFE  TXFIFO full interrupt enable
param   Cmd (The input parameters must be the following values):
          - ENABLE
          - DISABLE
return  none
void USART_EnableDMA(USART_Module* USARTx, uint32_t USART_DMAReq, FunctionalState Cmd)Enables or disables the USART’s DMA interface.
Source comment
name    USART_EnableDMA
fun     Enables or disables the USART's DMA interface.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param   USART_DMAReq (The input parameters must be the following values):
          - USART_DMAREQ_TX USART DMA transmit request
          - USART_DMAREQ_RX USART DMA receive request
param   Cmd (The input parameters must be the following values):
          - ENABLE
          - DISABLE
return  none
void USART_SetAddr(USART_Module* USARTx, uint8_t USART_Addr)Sets the address of the USART node.
Source comment
name    USART_SetAddr
fun     Sets the address of the USART node.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param   USART_Addr (The input parameters must be the following values):
          - (((USART_Addr)>=0x00)&&((USART_Addr)<0x10))
return  none
void USART_ConfigWakeUpMode(USART_Module* USARTx, uint32_t USART_WakeUpMode)Selects the USART WakeUp method.
Source comment
name    USART_ConfigWakeUpMode
fun     Selects the USART WakeUp method.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param   USART_WakeUpMode (The input parameters must be the following values):
          - USART_WUM_IDLELINE WakeUp by an idle line detection
          - USART_WUM_ADDRMASK WakeUp by an address mark
return  none
void USART_EnableRcvWakeUp(USART_Module* USARTx, FunctionalState Cmd)Determines if the USART is in mute mode or not.
Source comment
name    USART_EnableRcvWakeUp
fun     Determines if the USART is in mute mode or not.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param   Cmd (The input parameters must be the following values):
          - ENABLE
          - DISABLE
return  none
void USART_ConfigLINBreakDetectLength(USART_Module* USARTx, uint32_t USART_LINBreakDetectLength)Sets the USART LIN Break detection length.
Source comment
name    USART_ConfigLINBreakDetectLength
fun     Sets the USART LIN Break detection length.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param   USART_LINBreakDetectLength (The input parameters must be the following values):
          - USART_LINBDL_10B 10-bit break detection
          - USART_LINBDL_11B 11-bit break detection
return  none
void USART_EnableLIN(USART_Module* USARTx, FunctionalState Cmd)Enables or disables the USART’s LIN mode.
Source comment
name    USART_EnableLIN
fun     Enables or disables the USART's LIN mode.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param   Cmd (The input parameters must be the following values):
          - ENABLE
          - DISABLE
return  none
void USART_SendData(USART_Module* USARTx, uint32_t Data)Transmits single data through the USARTx peripheral.
Source comment
name    USART_SendData
fun     Transmits single data through the USARTx peripheral.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param   Data :
          - the data to transmit
return  none
uint32_t USART_ReceiveData(USART_Module* USARTx)Returns the most recent received data by the USARTx peripheral.
Source comment
name    USART_ReceiveData
fun     Returns the most recent received data by the USARTx peripheral.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
return  none
void USART_SendBreak(USART_Module* USARTx)Transmits break characters.
Source comment
name    USART_SendBreak
fun     Transmits break characters.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
return  none
void USART_SetGuardTime(USART_Module* USARTx, uint8_t USART_GuardTime)Sets the specifies USART guard time.
Source comment
name    USART_SetGuardTime
fun     Sets the specifies USART guard time.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
param   USART_GuardTime:
          - specifies the guard time
return  none
void USART_SetPrescaler(USART_Module* USARTx, uint8_t USART_Prescaler)Sets the system clock prescaler.
Source comment
name    USART_SetPrescaler
fun     Sets the system clock prescaler.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param   USART_Prescaler:
          - specifies the prescaler clock
return  none
void USART_EnableSmartCard(USART_Module* USARTx, FunctionalState Cmd)Enables or disables the USART’s Smart Card mode.
Source comment
name    USART_EnableSmartCard
fun     Enables or disables the USART's Smart Card mode.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
param   Cmd (The input parameters must be the following values):
          - ENABLE
          - DISABLE
return  none
void USART_SetSmartCardNACK(USART_Module* USARTx, FunctionalState Cmd)Enables or disables NACK transmission.
Source comment
name    USART_SetSmartCardNACK
fun     Enables or disables NACK transmission.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
param   Cmd (The input parameters must be the following values):
          - ENABLE
          - DISABLE
return  none
void USART_EnableHalfDuplex(USART_Module* USARTx, FunctionalState Cmd)Enables or disables the USART’s Half Duplex communication.
Source comment
name    USART_EnableHalfDuplex
fun     Enables or disables the USART's Half Duplex communication.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param   Cmd (The input parameters must be the following values):
          - ENABLE
          - DISABLE
return  none
void USART_ConfigIrDAMode(USART_Module* USARTx, uint32_t USART_IrDAMode)Configures the USART’s IrDA interface.
Source comment
name    USART_ConfigIrDAMode
fun     Configures the USART's IrDA interface.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param   USART_IrDAMode (The input parameters must be the following values):
          - USART_IRDAMODE_LOWPPWER
          - USART_IRDAMODE_NORMAL
return  none
void USART_EnableIrDA(USART_Module* USARTx, FunctionalState Cmd)Enables or disables the USART’s IrDA interface.
Source comment
name    USART_EnableIrDA
fun     Enables or disables the USART's IrDA interface.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param   Cmd (The input parameters must be the following values):
          - ENABLE
          - DISABLE
return  none
FlagStatus USART_GetFlagStatus(USART_Module* USARTx, uint32_t USART_FLAG)Checks whether the specified USART flag is set or not.
Source comment
name    USART_GetFlagStatus
fun     Checks whether the specified USART flag is set or not.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param   USART_FLAG (The input   parameters must be the following values):
          - USART_FLAG_FELOSE   Received Data FE Error Discard Flag
          - USART_FLAG_NELOSE   Received Data NE Error Discard Flag
          - USART_FLAG_PELOSE   Received Data PE Error Discard Flag
          - USART_FLAG_RTO      recevier timeout Flag
          - USART_FLAG_FEF      Framing error Flag
          - USART_FLAG_NEF      Noise error flag Flag
          - USART_FLAG_OREF     Overrun error
          - USART_FLAG_PEF      Parity error
          - USART_FLAG_LINBD    LIN break detection flag
          - USART_FLAG_CTSF     CTS Change flag
          - USART_FLAG_RXDNE    Receive data register not empty flag
          - USART_FLAG_TXC      Transmission Complete flag
          - USART_FLAG_TXDE     Transmit data register empty flag
          - USART_FLAG_IDLEF    Idle Line detection flag
          - USART_FLAG_TXFT     TX FIFO threshold flag
          - USART_FLAG_RXFT     RX FIFO threshold flag
          - USART_FLAG_RXFE     RX FIFO empty flag
          - USART_FLAG_TXFE     TX FIFO empty flag
          - USART_FLAG_RXFF     RX FIFO full flag
          - USART_FLAG_TXFF     TX FIFO full flag
return  USART_FLAG
          - SET
          - RESET
void USART_ClrFlag(USART_Module* USARTx, uint32_t USART_FLAG)Clears the USARTx’s pending flags.
Source comment
name    USART_ClrFlag
fun     Clears the USARTx's pending flags.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param   USART_FLAG (The input   parameters must be the following values):
          - USART_FLAG_FELOSE   Received Data FE Error Discard Flag
          - USART_FLAG_NELOSE   Received Data NE Error Discard Flag
          - USART_FLAG_PELOSE   Received Data PE Error Discard Flag
          - USART_FLAG_LINBD    LIN break detection flag
          - USART_FLAG_CTSF     CTS Change flag
          - USART_FLAG_RXDNE    Receive data register not empty flag
          - USART_FLAG_TXC      Transmission Complete flag
return  none
note
          - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun
            error) and IDLE (Idle line detected) flags are cleared by software
            sequence: a read operation to USART_STS register (USART_GetFlagStatus())
            followed by a read operation to USART_DAT register (USART_ReceiveData()).
          - RXNE flag can be also cleared by a read to the USART_DAT register
            (USART_ReceiveData()).
          - TC flag can be also cleared by software sequence: a read operation to
            USART_SR register (USART_GetFlagStatus()) followed by a write operation
            to USART_DAT register (USART_SendData()).
          - TXE flag is cleared only by a write to the USART_DAT register
            (USART_SendData()).
          - RTO flag is cleared only by a write 1 to the USART_CTRL2.RTOCF bit.
            (USART_ClrRTOFlag()).
void USART_ClrRTOFlag(USART_Module* USARTx)Clears the USARTx’s RTO pending flag.
Source comment
name    USART_ClrRTOFlag
fun     Clears the USARTx's RTO pending flag.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
return  none
INTStatus USART_GetIntStatus(USART_Module* USARTx, uint32_t USART_INT)Checks whether the specified USART interrupt has set or not.
Source comment
name    USART_GetIntStatus
fun     Checks whether the specified USART interrupt has set or not.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param   USART_INT (The input parameters must be the following values):
          - USART_INT_PEF   Parity Error interrupt
          - USART_INT_TXC   Transmission complete interrupt
          - USART_INT_TXDE  Transmit Data Register empty interrupt
          - USART_INT_RXDNE Receive Data register not empty interrupt
          - USART_INT_IDLEF Idle line detection interrupt
          - USART_INT_RTOE  Receiver timeout interrupt
          - USART_INT_LINBD LIN Break detection interrupt
          - USART_INT_ERRF  Error interrupt(Frame error, noise error, overrun error)
          - USART_INT_CTSF  CTS change interrupt
          - USART_INT_TXFTE  TXFIFO threshold interrupt enable
          - USART_INT_RXFTE  RXFIFO threshold interrupt enable
          - USART_INT_RXFEE  RXFIFO empty interrupt enable
          - USART_INT_TXFEE  TXFIFO empty interrupt enable
          - USART_INT_RXFFE  RXFIFO full interrupt enable
          - USART_INT_TXFFE  TXFIFO full interrupt enable
return  bitstatus
          - SET
          - RESET
void USART_IdleFrameSet(USART_Module* USARTx,FunctionalState Cmd)Idle frame controllable enable or disable.
Source comment
name    USART_IdleFrameSet
fun     Idle frame controllable enable or disable.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param  Cmd:(The input parameters must be the following values)
          - ENABLE
          - DISABLE
return  none
void USART_PinSwapSet(USART_Module* USARTx,FunctionalState Cmd)Swap TX/RX pins enable or disable.
Source comment
name    USART_PinSwapSet
fun     Swap TX/RX pins enable or disable.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART9
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param  Cmd:(The input parameters must be the following values)
          - ENABLE
          - DISABLE
return  none

Use note: The instance list in the source comment writes USART9 twice and omits USART4; the instances actually supported follow the header declaration and the user manual.

void USART_CfgDriverAssertTime(USART_Module* USARTx,uint32_t Time)Set Driver Enable assertion time.
Source comment
name    USART_CfgDriverAssertTime
fun     Set Driver Enable assertion time.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param  Time:(The input parameters must be the following values)
          - 0x01 ~ 0x1F
return  none
void USART_CfgDriverdeassertTime(USART_Module* USARTx,uint32_t Time)Set Driver Enable deassertion time.
Source comment
name    USART_CfgDriverdeassertTime
fun     Set Driver Enable deassertion time.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param  Time:(The input parameters must be the following values)
          - 0x01 ~ 0x1F
return  none
void USART_DriverPolaritySet(USART_Module* USARTx,FunctionalState Cmd)Driver enable polarity selection.
Source comment
name    USART_DriverPolaritySet
fun     Driver enable polarity selection.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param  Cmd:(The input parameters must be the following values)
          - ENABLE
          - DISABLE
return  none
void USART_DriverModeSet(USART_Module* USARTx,FunctionalState Cmd)Driver enable mode selection.
Source comment
name    USART_DriverModeSet
fun     Driver enable mode selection.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param  Cmd:(The input parameters must be the following values)
          - ENABLE
          - DISABLE
return  none
void USART_FEFDiscardSet(USART_Module* USARTx,FunctionalState Cmd)FEF Data Discard enable or disable.
Source comment
name    USART_FEFDiscardSet
fun     FEF Data Discard enable or disable.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param  Cmd:(The input parameters must be the following values)
          - ENABLE
          - DISABLE
return  none
void USART_NEFDiscardSet(USART_Module* USARTx,FunctionalState Cmd)NEF Data Discard enable or disable.
Source comment
name    USART_NEFDiscardSet
fun     NEF Data Discard enable or disable.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param  Cmd:(The input parameters must be the following values)
          - ENABLE
          - DISABLE
return  none
void USART_PEFDiscardSet(USART_Module* USARTx,FunctionalState Cmd)PEF Data Discard enable or disable.
Source comment
name    USART_PEFDiscardSet
fun     PEF Data Discard enable or disable.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param  Cmd:(The input parameters must be the following values)
          - ENABLE
          - DISABLE
return  none
void USART_RTOSet(USART_Module* USARTx,FunctionalState Cmd)Receiver timeout enable or disable.
Source comment
name    USART_RTOSet
fun     Receiver timeout enable or disable.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param  Cmd:(The input parameters must be the following values)
          - ENABLE
          - DISABLE
return  none
uint32_t USART_GetTxFIFO_Num(USART_Module* USARTx)number of TXFIFO valid data.
Source comment
name    USART_GetTxFIFO_Num
fun     number of  TXFIFO valid data.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
return  0x00~0x08
uint32_t USART_GetRxFIFO_Num(USART_Module* USARTx)number of RXFIFO valid data.
Source comment
name    USART_GetRxFIFO_Num
fun     number of  RXFIFO valid data.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
return  0x00~0x08
void USART_CfgRxFIFOThreshold(USART_Module* USARTx,uint32_t threshold)RXFIFO threshold configuration.
Source comment
name    USART_CfgRxFIFOThreshold
fun     RXFIFO threshold configuration.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param   threshold (The input parameters must be the following values):
          - USART_FIFO_DEEP1
          - USART_FIFO_DEEP2
          - USART_FIFO_DEEP4
          - USART_FIFO_DEEP6
          - USART_FIFO_DEEP7
          - USART_FIFO_DEEP8
return  none
void USART_CfgTxFIFOThreshold(USART_Module* USARTx,uint32_t threshold)TXFIFO threshold configuration.
Source comment
name    USART_CfgTxFIFOThreshold
fun     TXFIFO threshold configuration.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param   threshold (The input parameters must be the following values):
          - USART_FIFO_DEEP1
          - USART_FIFO_DEEP2
          - USART_FIFO_DEEP4
          - USART_FIFO_DEEP6
          - USART_FIFO_DEEP7
          - USART_FIFO_DEEP8
return  none
void USART_ClrFIFO(USART_Module* USARTx)FIFO clear.
Source comment
name    USART_ClrFIFO
fun     FIFO clear.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
return  none
void USART_FIFOModeSet(USART_Module* USARTx,FunctionalState Cmd)FIFO mode enable or disable.
Source comment
name    USART_FIFOModeSet
fun     FIFO mode enable or disable.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param  Cmd:(The input parameters must be the following values)
          - ENABLE
          - DISABLE
return  none
void USART_IdleFrameWidthSet(USART_Module* USARTx,uint32_t Width)configure Idle frame width.
Source comment
name    USART_CfgIdleFrameWidth
fun     configure Idle frame width.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param  Width:(The input parameters must be the following values)
          - 0x0000 ~ 0xFFFF
return  none

Use note: The function name in the source comment is USART_CfgIdleFrameWidth, which differs from the USART_IdleFrameWidthSet declared in the header; this is a driver comment typo, and the actual function is the one denoted by the function name.

void USART_CfgRTOWidth(USART_Module* USARTx,uint32_t Width)configure receive timeout width.
Source comment
name    USART_CfgRTOWidth
fun     configure receive timeout width.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param  Width:(The input parameters must be the following values)
          - 0x00000000 ~ 0x0FFFFFFF
return  none
void USART_FirstByteDelayFixSet(USART_Module* USARTx,FunctionalState Cmd)First byte delay fixed enable or disable.
Source comment
name    USART_FirstByteDelayFixSet
fun     First byte delay fixed enable or disable.
param   USARTx (The input parameters must be the following values):
          - USART1
          - USART2
          - USART3
          - USART4
          - USART9
          - UART5
          - UART6
          - UART7
          - UART8
          - UART10
param  Cmd:(The input parameters must be the following values)
          - ENABLE
          - DISABLE
return  none

5.28.3 Demo descriptions

This section covers the 16 USART examples: Polling, Interrupt, DMA_Polling, and DMA_Interrupt complete two-node transmit and receive with polling, interrupts, and DMA respectively; HardwareFlowCtrl and HalfDuplex demonstrate hardware flow control and single-wire half-duplex; 485_Master and 485_Slave demonstrate RS-485 transmit and receive; LIN_Master and LIN_Slave demonstrate LIN frame transmit and receive; Synchronous demonstrates synchronous mode and SPI communication; SmartCard demonstrates the smart card protocol and ATR parsing; Transmit_Receive demonstrates IrDA transmit and receive; MultiProcessor demonstrates multiprocessor address wake-up; FIFO_Interrupt demonstrates FIFO threshold interrupt reception; Printf redirects printf to the UART.

5.28.3.1 485/485_Master RS-485 master transmit and receive

Example directory: projects/n32h49x_EVAL/examples/USART/485/485_Master/

Initialize the UART, the 485 transceiver pins, and the interrupt→Send a fixed text over the 485 bus to the slave→Wait for the slave to return data of the same length→Compare the transmit and receive buffers→Print the test result over the UART

Item Source analysis
Function Two evaluation boards perform half-duplex transmit and receive over an RS-485 bus;
the master sends a fixed text to the slave through USARTz (UART5) and then receives and compares the same text returned by the slave.
Source files src/main.c: log initialization, clock and GPIO configuration, USART parameter configuration, 485 driver enable control, and data comparison;
inc/main.h: the USARTz instance, pins, alternate-function numbers, and interrupt macros;
src/n32h49x_it.c: the USARTz_IRQHandler transmit/receive interrupt and error-flag clearing;
readme.txt: function, environment, pin connection, and test steps.
The pin macros come from bsp/, and log_info comes from bsp/src/log.c.
Key configuration USARTz is UART5, with Rx on PA5 (GPIO_AF21), Tx on PA4 (GPIO_AF20), and DE on PA3 (GPIO_AF19), all configured as alternate-function push-pull with pull-up.
Baud rate 115200, 8-bit word length, 1 stop bit, no parity, no hardware flow control, both directions enabled.
DE assertion time 1 and deassertion time 0, polarity DISABLE, driver enable mode ENABLE;
NVIC group 2, UART5 subpriority 1.
Program and data path main first calls log_init, configures the clocks, NVIC, and GPIO, initializes USARTz to 115200, 8 bits, 1 stop bit, and no parity, configures the 485 driver, and enables the transmit/receive interrupt and USART.
It then busy-waits until RxCounter2 reaches the receive length, calls Buffercmp to compare the transmit and receive buffers, and prints OK or Fail according to the result.
Main APIs USART_StructInit, USART_Init, USART_CfgDriverAssertTime, USART_CfgDriverdeassertTime, USART_DriverPolaritySet, USART_DriverModeSet, USART_ConfigInt, USART_Enable, USART_ReceiveData, USART_SendData
Verification Power the slave first, then the master, and reset to run;
the master UART prints N32H49x 485 Master test START, and after the slave returns, prints N32H49x 485 Master test OK when the data matches.
Use note Disconnect the MCU_TX and MCU_RX jumpers of the NS-LINK on the board first;
power the Slave first and the Master after;
the J33, J34, and J35 jumpers must be connected.
The example is based on N32H497ZGL7_EVB V1.0, with a toolchain of KEIL MDK-ARM V5.34 or IAR EWARM 8.50.1.
Core-code walkthrough and porting

The example uses USARTz (UART5) with a 485 transceiver to complete one interrupt-driven transmit/receive cycle with driver enable control between two evaluation boards.

Data path: USARTz transmits TxBuffer2 → 485 transceiver → the slave USARTz receives → USARTz_IRQHandler writes byte by byte into RxBuffer2 → the slave returns the data → the master Buffercmp compares the transmit and receive buffers → log_info prints the result

1. Define the instance, pins, and alternate-function numbers used by the 485 with macros. inc/main.h points USARTz to UART5 and gives the Rx, Tx, and DE pins with their alternate-function numbers; all later configuration accesses them through this macro set.

inc/main.hinc/main.h
#define USARTz                  UART5
#define USARTz_CLK              RCC_APB1_PERIPHEN_UART5
#define USARTz_GPIO             GPIOA
#define USARTz_GPIO_CLK         RCC_AHB_PERIPHEN_GPIOA
#define USARTz_RxPin            GPIO_PIN_5
#define USARTz_TxPin            GPIO_PIN_4
#define USARTz_DEPin            GPIO_PIN_3
#define USARTz_Rx_GPIO_AF       GPIO_AF21
#define USARTz_Tx_GPIO_AF       GPIO_AF20
#define USARTz_DE_GPIO_AF       GPIO_AF19

When changing the instance or pins, only this macro set needs to be modified.

2. Configure the 485 transceiver driver enable. After DE mode is enabled, USART automatically drives the DE pin high when transmitting; the assertion time is set to 1 and the deassertion time to 0, with active-low polarity.

src/main.csrc/main.c · main
    USART_CfgDriverAssertTime(USARTz,1);
    USART_CfgDriverdeassertTime(USARTz,0);
    USART_DriverPolaritySet(USARTz,DISABLE);
    USART_DriverModeSet(USARTz,ENABLE);

DEAT cannot be 0 after DEM is enabled, so the minimum value 1 is used here.

3. Enable the transmit/receive interrupt and start USART. The master enables both the transmit and receive interrupts, and USART_Enable sets UEN to start transmit and receive.

src/main.csrc/main.c · main
    USART_ConfigInt(USARTz, USART_INT_TXDE,ENABLE);
    USART_ConfigInt(USARTz, USART_INT_RXDNE,ENABLE);

    /* Enable the USARTz */
    USART_Enable(USARTz, ENABLE);

4. Move the transmit/receive data in the interrupt. The receive interrupt writes data into RxBuffer2 and disables itself once full; the transmit interrupt writes out TxBuffer2 byte by byte.

src/n32h49x_it.csrc/n32h49x_it.c · USARTz_IRQHandler
void USARTz_IRQHandler(void)
{
    if ((USART_GetFlagStatus(USARTz, USART_FLAG_RXDNE) != RESET)  && (USART_GetIntStatus(USARTz, USART_INT_RXDNE) != RESET))
    {
        /* Read one byte from the receive data register */
        RxBuffer2[RxCounter2++] = USART_ReceiveData(USARTz);

        if (RxCounter2 == NbrOfDataToRead1)
        {
            /* Disable the USARTz Receive interrupt */
            USART_ConfigInt(USARTz, USART_INT_RXDNE,DISABLE);
        }
    }

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

5.28.3.2 485/485_Slave RS-485 slave transmit and receive

Example directory: projects/n32h49x_EVAL/examples/USART/485/485_Slave/

Initialize the UART, the 485 transceiver, and the interrupt→Enable only the receive interrupt to receive the master data→Compare the received data with the local template once full→Enable the transmit interrupt to return the same text to the master→Print the comparison result over the UART

Item Source analysis
Function Two evaluation boards perform half-duplex transmit and receive over an RS-485 bus;
the slave receives the fixed text sent by the master through USARTz (UART5) and compares it, then returns the same text to the master.
Source files src/main.c: log initialization, clock and GPIO configuration, USART parameter configuration, 485 driver enable control, and enabling the transmit/receive interrupts in turn;
inc/main.h: the USARTz instance, pins, alternate-function numbers, and interrupt macros;
src/n32h49x_it.c: the USARTz_IRQHandler transmit/receive interrupt and error-flag clearing;
readme.txt: function, environment, pin connection, and test steps.
The pin macros come from bsp/, and log_info comes from bsp/src/log.c.
Key configuration USARTz is UART5, with Rx on PA5 (GPIO_AF21), Tx on PA4 (GPIO_AF20), and DE on PA3 (GPIO_AF19), all configured as alternate-function push-pull with pull-up.
Baud rate 115200, 8-bit word length, 1 stop bit, no parity, no hardware flow control, both directions enabled.
DE assertion time 1 and deassertion time 0, polarity DISABLE, driver enable mode ENABLE;
NVIC group 2, UART5 subpriority 1.
Program and data path main first calls log_init, configures the clocks, NVIC, and GPIO, initializes USARTz to 115200, 8 bits, 1 stop bit, and no parity, configures the 485 driver, enables only the receive interrupt, and then starts USART.
After RxBuffer2 is filled it calls Buffercmp to compare the transmit and receive buffers and prints OK or Fail, then enables the transmit interrupt to return the same text to the master.
Main APIs USART_StructInit, USART_Init, USART_CfgDriverAssertTime, USART_CfgDriverdeassertTime, USART_DriverPolaritySet, USART_DriverModeSet, USART_ConfigInt, USART_Enable, USART_ReceiveData, USART_SendData
Verification Power the slave first, then the master, and reset to run;
the slave UART prints N32H487ZEL7_EVB 485 Slave test START, and prints N32H487ZEL7_EVB 485 Slave test OK after it matches the master.
Use note Disconnect the MCU_TX and MCU_RX jumpers of the NS-LINK on the board first;
power the Slave first and the Master after;
the J33, J34, and J35 jumpers must be connected.
The example is based on N32H497ZGL7_EVB V1.0, with a toolchain of KEIL MDK-ARM V5.34 or IAR EWARM 8.50.1.
Core-code walkthrough and porting

The example lets the slave first enable only the receive interrupt to receive the master data, and enable the transmit interrupt to return the data after the comparison matches.

Data path: master USARTz transmits → 485 bus → slave USARTz receives → USARTz_IRQHandler writes into RxBuffer2 → Buffercmp compares → transmit interrupt enabled → USARTz_IRQHandler returns TxBuffer2 → log_info prints the result

1. Define the instance, pins, and alternate-function numbers used by the 485 with macros. inc/main.h points USARTz to UART5 and gives the Rx, Tx, and DE pins with their alternate-function numbers.

inc/main.hinc/main.h
#define USARTz                  UART5
#define USARTz_CLK              RCC_APB1_PERIPHEN_UART5
#define USARTz_GPIO             GPIOA
#define USARTz_GPIO_CLK         RCC_AHB_PERIPHEN_GPIOA
#define USARTz_RxPin            GPIO_PIN_5
#define USARTz_TxPin            GPIO_PIN_4
#define USARTz_DEPin            GPIO_PIN_3
#define USARTz_Rx_GPIO_AF       GPIO_AF21
#define USARTz_Tx_GPIO_AF       GPIO_AF20
#define USARTz_DE_GPIO_AF       GPIO_AF19

2. First enable only the receive interrupt and start USART. The slave enters the receive state first and waits for the master to send the data.

src/main.csrc/main.c · main
    /* Enable USARTz Receive and Transmit interrupts */
    USART_ConfigInt(USARTz, USART_INT_RXDNE,ENABLE);

    /* Enable the USARTz */
    USART_Enable(USARTz, ENABLE);

3. Enable the transmit interrupt to return the data after the comparison. Once full, compare the transmit and receive buffers and print the result, then enable the transmit interrupt to send the same text back to the master.

src/main.csrc/main.c · main
    TransferStatus2 = Buffercmp(TxBuffer2, RxBuffer2, TxBufferSize2);
    /* TransferStatus = PASSED, if the data transmitted and received  are the same */
    /* TransferStatus = FAILED, if the data transmitted and received are different */
    if(TransferStatus2 == PASSED)
    {
        log_info(" N32H487ZEL7_EVB 485 Slave test OK \r\n");
    }
    else
    {
        log_info(" N32H487ZEL7_EVB 485 Slave test Fail \r\n");
    }
    
    /* Enable USARTz Receive and Transmit interrupts */
    USART_ConfigInt(USARTz, USART_INT_TXDE,ENABLE);

4. Move the transmit/receive data in the interrupt. The receive interrupt writes data into RxBuffer2 and disables itself once full; the transmit interrupt writes out TxBuffer2 byte by byte.

src/n32h49x_it.csrc/n32h49x_it.c · USARTz_IRQHandler
void USARTz_IRQHandler(void)
{
    if ((USART_GetFlagStatus(USARTz, USART_FLAG_RXDNE) != RESET)  && (USART_GetIntStatus(USARTz, USART_INT_RXDNE) != RESET))
    {
        /* Read one byte from the receive data register */
        RxBuffer2[RxCounter2++] = USART_ReceiveData(USARTz);

        if (RxCounter2 == NbrOfDataToRead1)
        {
            /* Disable the USARTz Receive interrupt */
            USART_ConfigInt(USARTz, USART_INT_RXDNE,DISABLE);
        }
    }

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

5.28.3.3 DMA_Interrupt DMA interrupt transmit and receive

Example directory: projects/n32h49x_EVAL/examples/USART/DMA_Interrupt/

Initialize the two UARTs, DMA, and the interrupt→DMA moves the transmit buffers to the two transmit data registers→Polling receives one channel and the interrupt receives the other→Wait for both DMA transfers to complete→Compare the two sets of transmit and receive data

Item Source analysis
Function USARTy (USART3) and USARTz (UART5) are interconnected;
DMA completes both transmit directions, polling and interrupts complete the two receive directions, and the two sets of transceived data are finally compared.
Source files src/main.c: clock, GPIO, NVIC, DMA, and USART configuration, the two transmit/receive flows, and data comparison;
inc/main.h: the two instances, pins, alternate-function numbers, DMA channels, flags, and remap macros;
src/n32h49x_it.c: the UART5_IRQHandler receive interrupt and error-flag clearing;
readme.txt: function, environment, pin connection, and test steps.
Key configuration USARTy is USART3 (Tx PA9/GPIO_AF17, Rx PA15/GPIO_AF18), USARTz is UART5 (Tx PA2/GPIO_AF20, Rx PA3/GPIO_AF21), both alternate-function push-pull with pull-up.
Baud rate 115200, 8-bit word length, 1 stop bit, no parity;
USARTy uses DMA1_CH1 (DMA_FLAG_TC1) for Tx and USARTz uses DMA1_CH3 (DMA_FLAG_TC3) for Tx, both memory-to-peripheral.
NVIC group 2, UART5 preemption and subpriority both 0, only the USARTz receive interrupt enabled.
Program and data path main configures the clocks, NVIC, GPIO, DMA, and the two USARTs in turn, enables the two DMA transmit/receive requests and the USARTz receive interrupt, then opens the two transmit DMA channels and the USARTs.
It then polls until TxBuffer2 is received into RxBuffer1, waits for both DMA transfers to complete, and finally compares the two transmit/receive buffers with Buffercmp.
Main APIs USART_Init, USART_EnableDMA, USART_ConfigInt, USART_Enable, USART_ReceiveData, USART_GetFlagStatus, DMA_Init, DMA_RequestRemap, DMA_EnableChannel, DMA_GetFlagStatus
Verification Connect USART3_Tx (PA9) to UART5_Rx (PA3) and USART3_Rx (PA15) to UART5_Tx (PA2), and reset to run;
check TransferStatus1 and TransferStatus2 in turn;
both PASSED means both sets of data match.
Use note Disconnect the MCU_TX and MCU_RX jumpers of the NS-LINK on the board first;
the transmit side is handled by DMA, and one receive channel uses an interrupt and the other polling.
The example is based on N32H497ZGL7_EVB V1.0, with a toolchain of KEIL MDK-ARM V5.34 or IAR EWARM 8.50.1.
Core-code walkthrough and porting

The example uses DMA for both transmit directions and uses polling and interrupts for the two receive directions, then compares the two sets of data.

Data path: TxBuffer1 and TxBuffer2 → DMA moves them to the two transmit data registers → the peer receives (USARTy polling writes RxBuffer1, USARTz interrupt writes RxBuffer2) → Buffercmp compares → TransferStatus1 and TransferStatus2

1. Define the two instances, pins, and DMA channels with macros. inc/main.h uses _USART3_UART5_ to select USART3 and UART5 and gives each one its pins, alternate-function numbers, and transmit DMA channel, flag, and remap.

inc/main.hinc/main.h
#ifdef _USART3_UART5_
#define USARTy                  USART3
#define USARTy_CLK              RCC_APB1_PERIPHEN_USART3
#define USARTy_GPIO             GPIOA
#define USARTy_GPIO_CLK         RCC_AHB_PERIPHEN_GPIOA
#define USARTy_RxPin            GPIO_PIN_15
#define USARTy_TxPin            GPIO_PIN_9
#define USARTy_Rx_GPIO_AF       GPIO_AF18
#define USARTy_Tx_GPIO_AF       GPIO_AF17
#define USARTy_DAT_Base         (USART3_BASE + 0x10)
#define USARTy_Tx_DMA_Channel   DMA1_CH1
#define USARTy_Tx_DMA_FLAG      DMA_FLAG_TC1
#define USARTy_Tx_DMA_REMAP     DMA_REMAP_USART3_TX

#define USARTz                  UART5
#define USARTz_CLK              RCC_APB1_PERIPHEN_UART5
#define USARTz_GPIO             GPIOA
#define USARTz_GPIO_CLK         RCC_AHB_PERIPHEN_GPIOA
#define USARTz_RxPin            GPIO_PIN_3
#define USARTz_TxPin            GPIO_PIN_2
#define USARTz_Rx_GPIO_AF       GPIO_AF21
#define USARTz_Tx_GPIO_AF       GPIO_AF20
#define USARTz_DAT_Base         (UART5_BASE + 0x10)
#define USARTz_Tx_DMA_Channel   DMA1_CH3
#define USARTz_Tx_DMA_FLAG      DMA_FLAG_TC3
#define USARTz_Tx_DMA_REMAP     DMA_REMAP_UART5_TX
#define USARTz_IRQn             UART5_IRQn
#endif

2. Configure the two transmit DMA channels. DMA_Configuration points the memory side at the transmit buffer and the peripheral side at the data register, sets the direction to memory-to-peripheral, and opens the corresponding request remap.

src/main.csrc/main.c · DMA_Configuration
    /* USARTy_Tx_DMA_Channel (triggered by USARTy Tx event) Config */
    DMA_DeInit(USARTy_Tx_DMA_Channel);
    DMA_StructInit(&DMA_InitStructure);
    DMA_InitStructure.PeriphAddr     = USARTy_DAT_Base;
    DMA_InitStructure.MemAddr        = (uint32_t)TxBuffer1;
    DMA_InitStructure.Direction      = DMA_DIR_PERIPH_DST;
    DMA_InitStructure.BufSize        = TxBufferSize1;
    DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_DISABLE;
    DMA_InitStructure.MemoryInc      = DMA_MEM_INC_ENABLE;
    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_WIDTH_BYTE;
    DMA_InitStructure.MemDataSize    = DMA_MEM_DATA_WIDTH_BYTE;
    DMA_InitStructure.CircularMode   = DMA_MODE_NORMAL;
    DMA_InitStructure.Priority       = DMA_PRIORITY_VERY_HIGH;
    DMA_InitStructure.Mem2Mem        = DMA_M2M_DISABLE;
    DMA_Init(USARTy_Tx_DMA_Channel, &DMA_InitStructure);
    DMA_RequestRemap(USARTy_Tx_DMA_REMAP,USARTy_Tx_DMA_Channel,ENABLE);

    /* USARTz_Tx_DMA_Channel (triggered by USARTz Tx event) Config */
    DMA_DeInit(USARTz_Tx_DMA_Channel);
    DMA_InitStructure.PeriphAddr = USARTz_DAT_Base;
    DMA_InitStructure.MemAddr    = (uint32_t)TxBuffer2;
    DMA_InitStructure.Direction  = DMA_DIR_PERIPH_DST;
    DMA_InitStructure.BufSize    = TxBufferSize2;
    DMA_Init(USARTz_Tx_DMA_Channel, &DMA_InitStructure);
    DMA_RequestRemap(USARTz_Tx_DMA_REMAP,USARTz_Tx_DMA_Channel,ENABLE);

3. Enable the DMA requests and hand the transmit side to DMA. It first opens the two DMA transmit/receive requests and the USARTz receive interrupt, then enables the two transmit DMA channels and starts the USARTs.

src/main.csrc/main.c · main
    /* Enable USARTy DMA Rx and TX request */
    USART_EnableDMA(USARTy, USART_DMAREQ_RX | USART_DMAREQ_TX,ENABLE);
    /* Enable USARTz DMA Rx and TX request */
    USART_EnableDMA(USARTz, USART_DMAREQ_RX | USART_DMAREQ_TX,ENABLE);

    /* Enable the USARTz Receive Interrupt */
    USART_ConfigInt(USARTz, USART_INT_RXDNE,ENABLE);

    /* Enable USARTy TX DMA Channel */
    DMA_EnableChannel(USARTy_Tx_DMA_Channel,ENABLE);
    /* Enable USARTz TX DMA Channel */
    DMA_EnableChannel(USARTz_Tx_DMA_Channel,ENABLE);

    /* Enable the USARTy and USARTz */
    USART_Enable(USARTy, ENABLE);
    USART_Enable(USARTz, ENABLE);

4. Receive the other channel in the interrupt. UART5_IRQHandler writes into RxBuffer2 when USARTz receives a byte and disables the receive interrupt once full.

src/n32h49x_it.csrc/n32h49x_it.c · UART5_IRQHandler
void UART5_IRQHandler(void)
{
    if ((USART_GetFlagStatus(UART5, USART_FLAG_RXDNE) != RESET) && (USART_GetIntStatus(UART5, USART_INT_RXDNE) != RESET))
    {
        /* Read one byte from the receive data register */
        RxBuffer2[RxCounter++] = USART_ReceiveData(UART5);

        if (RxCounter == NbrOfDataToRead)
        {
            /* Disable the USART2 Receive interrupt */
            USART_ConfigInt(UART5, USART_INT_RXDNE,DISABLE);
        }
    }

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

5.28.3.4 DMA_Polling DMA polling transmit and receive

Example directory: projects/n32h49x_EVAL/examples/USART/DMA_Polling/

Initialize the two UARTs and the four DMA channels→DMA completes both transmit and both receive directions→Poll each of the four DMA transfer-complete flags→Compare the two sets of transmit and receive data

Item Source analysis
Function USARTy (USART3) and USARTz (UART5) are interconnected;
both transmit and receive are completed entirely by DMA in polling mode, and the two sets of transceived data are compared at the end.
Source files src/main.c: clock, GPIO, DMA, and USART configuration, enabling the four DMA channels, and data comparison;
inc/main.h: the two instances, pins, alternate-function numbers, transmit/receive DMA channels, flags, and remap macros;
src/n32h49x_it.c: the interrupt handlers (not used by this example);
readme.txt: function, environment, pin connection, and test steps.
Key configuration USARTy is USART3 (Tx PA9/GPIO_AF17, Rx PA15/GPIO_AF18), USARTz is UART5 (Tx PA2/GPIO_AF20, Rx PA3/GPIO_AF21), alternate-function push-pull with pull-up.
Baud rate 115200, 8-bit word length, 1 stop bit, no parity;
USARTy uses DMA1_CH4/CH5 for Tx/Rx and USARTz uses DMA1_CH7/CH6 for Tx/Rx, transmit memory-to-peripheral and receive peripheral-to-memory.
Program and data path main configures the clocks, GPIO, DMA, and the two USARTs in turn, enables the two DMA transmit/receive requests and the four DMA channels, then starts the two USARTs.
It then polls the four DMA transfer-complete flags one by one, and finally compares the two transmit/receive buffers with Buffercmp and writes TransferStatus1 and TransferStatus2.
Main APIs USART_Init, USART_EnableDMA, USART_Enable, DMA_Init, DMA_RequestRemap, DMA_EnableChannel, DMA_GetFlagStatus
Verification Connect USART3_Tx (PA9) to UART5_Rx (PA3) and USART3_Rx (PA15) to UART5_Tx (PA2), and reset to run;
check TransferStatus1 and TransferStatus2 in turn;
both PASSED means both sets of data match.
Use note Disconnect the MCU_TX and MCU_RX jumpers of the NS-LINK on the board first;
both transmit and receive are handled by DMA;
only polling is used, and no peripheral interrupt is generated.
The example is based on N32H497ZGL7_EVB V1.0, with a toolchain of KEIL MDK-ARM V5.34 or IAR EWARM 8.50.1.
Core-code walkthrough and porting

The example hands both transmit/receive directions to DMA, confirms the four DMA transfers one by one by polling, and then compares the two sets of data.

Data path: TxBuffer1 and TxBuffer2 → the two transmit DMA channels → the peer’s two receive DMA channels → RxBuffer1 and RxBuffer2 → Buffercmp compares → TransferStatus1 and TransferStatus2

1. Define the two instances, pins, and transmit/receive DMA channels with macros. inc/main.h uses _USART3_UART5_ to select USART3 and UART5 and gives each one a transmit and a receive DMA channel with their complete flags.

inc/main.hinc/main.h
#ifdef _USART3_UART5_
#define USARTy                  USART3
#define USARTy_CLK              RCC_APB1_PERIPHEN_USART3
#define USARTy_GPIO             GPIOA
#define USARTy_GPIO_CLK         RCC_AHB_PERIPHEN_GPIOA
#define USARTy_RxPin            GPIO_PIN_15
#define USARTy_TxPin            GPIO_PIN_9
#define USARTy_Rx_GPIO_AF       GPIO_AF18
#define USARTy_Tx_GPIO_AF       GPIO_AF17
#define USARTy_DAT_Base         (USART3_BASE + 0x10)
#define USARTy_Tx_DMA_Channel   DMA1_CH4
#define USARTy_Tx_DMA_FLAG      DMA_FLAG_TC4
#define USARTy_Rx_DMA_Channel   DMA1_CH5
#define USARTy_Rx_DMA_FLAG      DMA_FLAG_TC5
#define USARTy_Tx_DMA_REMAP     DMA_REMAP_USART3_TX
#define USARTy_Rx_DMA_REMAP     DMA_REMAP_USART3_RX

#define USARTz                  UART5
#define USARTz_CLK              RCC_APB1_PERIPHEN_UART5
#define USARTz_GPIO             GPIOA
#define USARTz_GPIO_CLK         RCC_AHB_PERIPHEN_GPIOA
#define USARTz_RxPin            GPIO_PIN_3
#define USARTz_TxPin            GPIO_PIN_2
#define USARTz_Rx_GPIO_AF       GPIO_AF21
#define USARTz_Tx_GPIO_AF       GPIO_AF20
#define USARTz_DAT_Base         (UART5_BASE + 0x10)
#define USARTz_Tx_DMA_Channel   DMA1_CH7
#define USARTz_Tx_DMA_FLAG      DMA_FLAG_TC7
#define USARTz_Rx_DMA_Channel   DMA1_CH6
#define USARTz_Rx_DMA_FLAG      DMA_FLAG_TC6
#define USARTz_Tx_DMA_REMAP     DMA_REMAP_UART5_TX
#define USARTz_Rx_DMA_REMAP     DMA_REMAP_UART5_RX
#endif

2. Configure the four DMA channels. In DMA_Configuration the transmit direction is memory-to-peripheral and the receive direction is peripheral-to-memory, and each channel opens the corresponding request remap.

src/main.csrc/main.c · DMA_Configuration
    /* USARTy_Tx_DMA_Channel (triggered by USARTy Tx event) Config */
    DMA_DeInit(USARTy_Tx_DMA_Channel);
    DMA_StructInit(&DMA_InitStructure);
    DMA_InitStructure.PeriphAddr     = USARTy_DAT_Base;
    DMA_InitStructure.MemAddr        = (uint32_t)TxBuffer1;
    DMA_InitStructure.Direction      = DMA_DIR_PERIPH_DST;
    DMA_InitStructure.BufSize        = TxBufferSize1;
    DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_DISABLE;
    DMA_InitStructure.MemoryInc      = DMA_MEM_INC_ENABLE;
    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_WIDTH_BYTE;
    DMA_InitStructure.MemDataSize    = DMA_MEM_DATA_WIDTH_BYTE;
    DMA_InitStructure.CircularMode   = DMA_MODE_NORMAL;
    DMA_InitStructure.Priority       = DMA_PRIORITY_VERY_HIGH;
    DMA_InitStructure.Mem2Mem        = DMA_M2M_DISABLE;
    DMA_Init(USARTy_Tx_DMA_Channel, &DMA_InitStructure);
    DMA_RequestRemap(USARTy_Tx_DMA_REMAP,USARTy_Tx_DMA_Channel,ENABLE);
    
    /* USARTy RX DMA1 Channel (triggered by USARTy Rx event) Config */
    DMA_DeInit(USARTy_Rx_DMA_Channel);
    DMA_InitStructure.PeriphAddr = USARTy_DAT_Base;
    DMA_InitStructure.MemAddr    = (uint32_t)RxBuffer1;
    DMA_InitStructure.Direction  = DMA_DIR_PERIPH_SRC;
    DMA_InitStructure.BufSize    = TxBufferSize2;
    DMA_Init(USARTy_Rx_DMA_Channel, &DMA_InitStructure);
    DMA_RequestRemap(USARTy_Rx_DMA_REMAP,USARTy_Rx_DMA_Channel,ENABLE);

    /* USARTz_Tx_DMA_Channel (triggered by USARTz Tx event) Config */
    DMA_DeInit(USARTz_Tx_DMA_Channel);
    DMA_InitStructure.PeriphAddr = USARTz_DAT_Base;
    DMA_InitStructure.MemAddr    = (uint32_t)TxBuffer2;
    DMA_InitStructure.Direction  = DMA_DIR_PERIPH_DST;
    DMA_InitStructure.BufSize    = TxBufferSize2;
    DMA_Init(USARTz_Tx_DMA_Channel, &DMA_InitStructure);
    DMA_RequestRemap(USARTz_Tx_DMA_REMAP,USARTz_Tx_DMA_Channel,ENABLE);
    
    /* USARTz RX DMA1 Channel (triggered by USARTz Rx event) Config */
    DMA_DeInit(USARTz_Rx_DMA_Channel);
    DMA_InitStructure.PeriphAddr = USARTz_DAT_Base;
    DMA_InitStructure.MemAddr    = (uint32_t)RxBuffer2;
    DMA_InitStructure.Direction  = DMA_DIR_PERIPH_SRC;
    DMA_InitStructure.BufSize    = TxBufferSize1;
    DMA_Init(USARTz_Rx_DMA_Channel, &DMA_InitStructure);
    DMA_RequestRemap(USARTz_Rx_DMA_REMAP,USARTz_Rx_DMA_Channel,ENABLE);

3. Enable the DMA requests and the four channels. Both USARTs open the DMA transmit/receive requests, all four channels are enabled together, and then the two USARTs are started.

src/main.csrc/main.c · main
    /* Enable USARTy DMA Rx and TX request */
    USART_EnableDMA(USARTy, USART_DMAREQ_RX | USART_DMAREQ_TX,ENABLE);
    /* Enable USARTz DMA Rx and TX request */
    USART_EnableDMA(USARTz, USART_DMAREQ_RX | USART_DMAREQ_TX,ENABLE);

    /* Enable USARTy TX DMA Channel */
    DMA_EnableChannel(USARTy_Tx_DMA_Channel,ENABLE);
    /* Enable USARTy RX DMA Channel */
    DMA_EnableChannel(USARTy_Rx_DMA_Channel,ENABLE);
    
    /* Enable USARTz TX DMA Channel */
    DMA_EnableChannel(USARTz_Tx_DMA_Channel,ENABLE);
    /* Enable USARTz RX DMA Channel */
    DMA_EnableChannel(USARTz_Rx_DMA_Channel,ENABLE);

    /* Enable the USARTy and USARTz */
    USART_Enable(USARTy, ENABLE);
    USART_Enable(USARTz, ENABLE);

4. Poll whether the four DMA channels have completed. It waits for the complete flags of the four channels in turn and then compares the two sets of data.

src/main.csrc/main.c · main
    /* Wait until USARTy TX DMA Channel  Transfer Complete */
    while (DMA_GetFlagStatus(USARTy_Tx_DMA_FLAG,DMA1) == RESET)
    {
    }
    /* Wait until USARTy RX DMA Channel Transfer Complete */
    while (DMA_GetFlagStatus(USARTy_Rx_DMA_FLAG,DMA1) == RESET)
    {
    }
    
    /* Wait until USARTz TX DMA Channel Transfer Complete */
    while (DMA_GetFlagStatus(USARTz_Tx_DMA_FLAG,DMA1) == RESET)
    {
    }
    /* Wait until USARTz RX DMA Channel Transfer Complete */
    while (DMA_GetFlagStatus(USARTz_Rx_DMA_FLAG,DMA1) == RESET)
    {
    }

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

5.28.3.5 FIFO_Interrupt FIFO interrupt transmit and receive

Example directory: projects/n32h49x_EVAL/examples/USART/FIFO_Interrupt/

Initialize the two UARTs and enable FIFO mode→Set the receive FIFO threshold and enable the receive threshold interrupt→Both directions each send 16 bytes→The interrupt reads out by FIFO depth and compares the transmit and receive data

Item Source analysis
Function USARTy (USART3) and USARTz (UART5) are interconnected, FIFO mode is enabled and the receive threshold is set to 8;
both sides each send 16 bytes, and the receiver reads the whole FIFO segment at once in the interrupt and then compares it.
Source files src/main.c: clock, GPIO, USART and NVIC configuration, FIFO threshold and mode configuration, data transmission and comparison;
inc/main.h: the two instances, pins, alternate-function numbers, and interrupt vector macros;
src/n32h49x_it.c: the USART3 and UART5 interrupt handlers that read in batches by FIFO depth;
readme.txt: function, environment, pin connection, and test steps.
Key configuration USARTy is USART3 (Tx PA9/GPIO_AF17, Rx PA15/GPIO_AF18), USARTz is UART5 (Tx PA2/GPIO_AF20, Rx PA3/GPIO_AF21), alternate-function push-pull with pull-up.
Baud rate 9600, 8-bit word length, 1 stop bit, no parity;
both set USART_FIFO_DEEP8 as the receive threshold and enable the USART_INT_RXFTE interrupt, NVIC group 2, USART3 subpriority 0, UART5 subpriority 1.
Program and data path main configures the clocks, NVIC, GPIO, and the two USARTs, sets the receive FIFO threshold, enables FIFO mode, enables the receive threshold interrupt, and then sends the two 16-byte blocks byte by byte.
When transmission passes the middle it first waits for the peer to have received data, and finally waits until the transmit/receive counters reach 16, then compares the two buffers with Buffercmp and writes TransferStatus1 and TransferStatus2.
Main APIs USART_Init, USART_CfgRxFIFOThreshold, USART_FIFOModeSet, USART_ConfigInt, USART_Enable, USART_SendData, USART_GetRxFIFO_Num, USART_ReceiveData
Verification Connect USART3_Tx (PA9) to UART5_Rx (PA3) and USART3_Rx (PA15) to UART5_Tx (PA2), and reset to run;
check TransferStatus1 and TransferStatus2 in turn;
both PASSED means both sets of data match.
Use note Disconnect the MCU_TX and MCU_RX jumpers of the NS-LINK on the board first;
when the receive threshold interrupt fires, loop over the depth returned by USART_GetRxFIFO_Num to avoid FIFO overflow;
after the whole segment is read, still check and clear the overflow, noise, parity, and framing error flags.
The example is based on N32H497ZGL7_STB V1.0, with a toolchain of KEIL MDK-ARM V5.34.0.0 or IAR EWARM 8.50.1.
Core-code walkthrough and porting

The example uses the receive threshold interrupt together with the FIFO to read out a whole segment at once and reduce the number of interrupts.

Data path: TxBuffer1 and TxBuffer2 → the two transmit directions → the peer FIFO → the RXFTE interrupt reads out by FIFO depth → RxBuffer1 and RxBuffer2 → Buffercmp compares

1. Enable FIFO mode and set the receive threshold and interrupt. Both USARTs first set an 8-level receive threshold and enable FIFO mode, then enable the receive threshold interrupt, and finally start together.

src/main.csrc/main.c · main
    /* Set the RXFIFO threshold */
    USART_CfgRxFIFOThreshold(USARTy,USART_FIFO_DEEP8);
    USART_CfgRxFIFOThreshold(USARTz,USART_FIFO_DEEP8);
    
    /* Enable the FIFO mode */
    USART_FIFOModeSet(USARTy,ENABLE);
    USART_FIFOModeSet(USARTz,ENABLE);
    
    /* Enable USARTy Receive and Transmit interrupts */
    USART_ConfigInt(USARTy, USART_INT_RXFTE,ENABLE);
    
    /* Enable USARTz Receive and Transmit interrupts */
    USART_ConfigInt(USARTz, USART_INT_RXFTE,ENABLE);

    /* Enable the USARTy and USARTz */
    USART_Enable(USARTy, ENABLE);
    USART_Enable(USARTz, ENABLE);

2. Send the two 16-byte blocks byte by byte. In the middle, at the 8th byte it first waits for the peer to have received data, to avoid FIFO overflow and data loss.

src/main.csrc/main.c · main
    for(TxCounter1=0;TxCounter1<Buffer_Num;TxCounter1++)
    {
        /* wait USARTz Receive Completion Data,Otherwise it will lead to data loss */
        if(TxCounter1 == 8)
        {
            while(RxBuffer2[TxCounter1-1] == 0);
        }
        /* Write one byte to the transmit data register */
        USART_SendData(USARTy, TxBuffer1[TxCounter1]);
    }
    
    for(TxCounter2=0;TxCounter2<Buffer_Num;TxCounter2++)
    {
        /* wait USARTy Receive Completion Data,Otherwise it will lead to data loss */
        if(TxCounter2 == 8)
        {
            while(RxBuffer1[TxCounter2-1] == 0);
        }
        /* Write one byte to the transmit data register */
        USART_SendData(USARTz, TxBuffer2[TxCounter2]);
    }

3. Read out in batches by FIFO depth in the interrupt. When the receive threshold interrupt fires it first reads the number of bytes in the FIFO, then reads that many in a loop.

src/n32h49x_it.csrc/n32h49x_it.c · USARTy_IRQHandler
void USARTy_IRQHandler(void)
{
    uint32_t i,j;
    if ((USART_GetFlagStatus(USARTy, USART_FLAG_RXFT) != RESET) && (USART_GetIntStatus(USARTy, USART_INT_RXFTE) != RESET))
    {
        j = USART_GetRxFIFO_Num(USARTy);

        for(i=0;i<j;i++)
        {
            /* Read one byte from the receive data register */
            RxBuffer1[RxCounter1++] = USART_ReceiveData(USARTy);
        }
    }

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

5.28.3.6 HalfDuplex half-duplex transmit and receive

Example directory: projects/n32h49x_EVAL/examples/USART/HalfDuplex/

Initialize the two UARTs and enable half-duplex mode→On the single-wire link USART3 transmits and UART5 receives→In reverse UART5 transmits and USART3 receives→Compare the two sets of transmit and receive data

Item Source analysis
Function USARTy (USART3) and USARTz (UART5) are each interconnected by a single Tx wire;
half-duplex mode is enabled and they transmit and receive time-division, then the two sets of data are compared.
Source files src/main.c: clock, GPIO, USART configuration, half-duplex enable, time-division transmit and receive, and data comparison;
inc/main.h: the two instances, pins, alternate-function numbers, and the test-status enumeration;
readme.txt: function, environment, pin connection, and test steps.
Key configuration USARTy is USART3 (Tx PA9/GPIO_AF17), USARTz is UART5 (Tx PA7/GPIO_AF20), alternate-function push-pull with pull-up;
only one Tx wire is connected, and the pin serves as both the transmit and receive end in half-duplex.
Baud rate 9600, 8-bit word length, 1 stop bit, no parity;
both call USART_EnableHalfDuplex to enable half-duplex.
Program and data path main configures the clocks, GPIO, and the two USARTs, starts both and enables half-duplex, and first sends byte by byte from USART3 to UART5 into RxBuffer2.
Then UART5 sends byte by byte to USART3 into RxBuffer1, confirming each byte with the transmit/receive flags, and finally compares the two buffers with Buffercmp.
Main APIs USART_Init, USART_Enable, USART_EnableHalfDuplex, USART_SendData, USART_ReceiveData, USART_GetFlagStatus
Verification Connect USART3_Tx (PA9) to UART5_Tx (PA7), and reset to run;
check TransferStatus1 and TransferStatus2 in turn;
both PASSED means both sets of data match.
Use note Disconnect the MCU_TX and MCU_RX jumpers of the NS-LINK on the board first;
half-duplex uses only one data line, so transmit and receive must be time-division and bidirectional transfer must not be started at the same time.
The example is based on N32H497ZGL7_STB V1.0, with a toolchain of KEIL MDK-ARM V5.34.0.0 or IAR EWARM 8.50.1.
Core-code walkthrough and porting

The example sets each USART to a single Tx wire, enables half-duplex and then transmits and receives time-division, confirming byte by byte.

Data path: TxBuffer1 → USART3 single-wire transmit → UART5 → RxBuffer2; TxBuffer2 → UART5 single-wire transmit → USART3 → RxBuffer1 → Buffercmp compares

1. Initialize both USARTs and enable half-duplex. The parameters of the two USARTs are the same, and after being started both enable half-duplex mode.

src/main.csrc/main.c · main
    /* Configure USARTy and USARTz */
    USART_Init(USARTy, &USART_InitStructure);
    USART_Init(USARTz, &USART_InitStructure);
    
    /* Enable the USARTy and USARTz */
    USART_Enable(USARTy, ENABLE);
    USART_Enable(USARTz, ENABLE);
    
    /* Enable USARTy Half Duplex Mode*/
    USART_EnableHalfDuplex(USARTy,ENABLE);
    /* Enable USARTz Half Duplex Mode*/
    USART_EnableHalfDuplex(USARTz,ENABLE);

2. USART3 transmits and UART5 receives. It first waits for the transmit register to empty before writing, then waits for the peer to receive and read the data; before reading it checks the overflow flag.

src/main.csrc/main.c · main
    while (NbrOfDataToRead2--)
    {
        /* Wait until end of transmit */
        while (USART_GetFlagStatus(USARTy, USART_FLAG_TXDE) == RESET)
        {
        }
        /* Write one byte in the USARTy Transmit Data Register */
        USART_SendData(USARTy, TxBuffer1[TxCounter1++]);

        /* Wait the byte is entirely received by USARTz */
        while (USART_GetFlagStatus(USARTz, USART_FLAG_RXDNE) == RESET)
        {
            /* Overflow data loss */
            if(USART_GetFlagStatus(USARTz, USART_FLAG_OREF) != RESET)
            {
                USARTz->DAT;
            }
        }
        /* Store the received byte in the RxBuffer2 */
        RxBuffer2[RxCounter2++] = USART_ReceiveData(USARTz);
    }

3. UART5 transmits and USART3 receives. The reverse process is symmetric with the previous block, and transmit/receive completion is again confirmed by flags.

src/main.csrc/main.c · main
    while (NbrOfDataToRead1--)
    {
        /* Wait until end of transmit */
        while (USART_GetFlagStatus(USARTz, USART_FLAG_TXDE) == RESET)
        {
        }
        /* Write one byte in the USARTz Transmit Data Register */
        USART_SendData(USARTz, TxBuffer2[TxCounter2++]);

        /* Wait the byte is entirely received by USARTy */
        while (USART_GetFlagStatus(USARTy, USART_FLAG_RXDNE) == RESET)
        {
            /* Overflow data loss */
            if(USART_GetFlagStatus(USARTy, USART_FLAG_OREF) != RESET)
            {
                USARTy->DAT;
            }
        }
        /* Store the received byte in the RxBuffer1 */
        RxBuffer1[RxCounter1++] = USART_ReceiveData(USARTy);
    }

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

5.28.3.7 HardwareFlowCtrl hardware flow control transmit and receive

Example directory: projects/n32h49x_EVAL/examples/USART/HardwareFlowCtrl/

Initialize the two UARTs and enable RTS/CTS hardware flow control→USART1 transmits through CTS and USART2 receives through RTS→In reverse USART2 transmits and USART1 receives→Compare the two sets of transmit and receive data

Item Source analysis
Function USARTy (USART1) and USARTz (USART2) are interconnected with four wires;
RTS/CTS hardware flow control is enabled and they transmit and receive bidirectionally, then the two sets of data are compared.
Source files src/main.c: clock, GPIO, USART configuration, flow-control parameters, bidirectional transmit and receive, and data comparison;
inc/main.h: the two instances, data and flow-control pins, alternate-function numbers, and the test-status enumeration;
readme.txt: function, environment, four-wire connection, and test steps.
Key configuration USARTy is USART1 (Tx PA9, Rx PA10, RTS PA12, CTS PA11, GPIO_AF5), USARTz is USART2 (Tx PA2, Rx PA3, RTS PA1, CTS PA0).
Baud rate 115200, 8-bit word length, 1 stop bit, no parity;
HardwareFlowControl enables both USART_HFCTRL_CTS and USART_HFCTRL_RTS, RTS is configured as push-pull output and CTS as input with pull-up.
Program and data path main configures the clocks, GPIO, and the two USARTs and starts them, and first USART1 sends byte by byte while USART2 receives into RxBuffer2.
Then USART2 sends byte by byte while USART1 receives into RxBuffer1, synchronizing with the transmit-empty and receive-not-empty flags, and finally compares the two buffers with Buffercmp.
Main APIs USART_Init, USART_Enable, USART_SendData, USART_ReceiveData, USART_GetFlagStatus
Verification Cross-connect PA9/PA3, PA10/PA2, PA11/PA1, and PA12/PA0 (Tx to Rx, CTS to RTS), and reset to run;
check TransferStatus1 and TransferStatus2 in turn;
both PASSED means both sets of data match.
Use note Disconnect the MCU_TX and MCU_RX jumpers of the NS-LINK on the board first;
the transmit side enables CTS and the receive side enables RTS, and the flow-control pins of both ends must be cross-connected to take effect.
The example is based on N32H497ZGL7_STB V1.0, with a toolchain of KEIL MDK-ARM V5.34.0.0 or IAR EWARM 8.50.1.
Core-code walkthrough and porting

The example uses the four RTS/CTS wires to connect the two UARTs, and the hardware flow-control signals regulate the pace during bidirectional transmit and receive.

Data path: TxBuffer1 → USART1 (CTS flow control) → USART2 (RTS flow control) → RxBuffer2; TxBuffer2 → USART2 → USART1 → RxBuffer1 → Buffercmp compares

1. Enable both CTS and RTS in the initialization parameters. The two USARTs share one parameter set, and the flow-control field opens both the transmit and receive sides.

src/main.csrc/main.c · main
    USART_InitStructure.BaudRate            = 115200;
    USART_InitStructure.WordLength          = USART_WL_8B;
    USART_InitStructure.StopBits            = USART_STPB_1;
    USART_InitStructure.Parity              = USART_PE_NO;
    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_CTS | USART_HFCTRL_RTS;
    USART_InitStructure.OverSampling        = USART_16OVER;
    USART_InitStructure.Mode                = USART_MODE_RX | USART_MODE_TX;

    /* Configure USARTy and USARTz */
    USART_Init(USARTy, &USART_InitStructure);
    USART_Init(USARTz, &USART_InitStructure);

    /* Enable the USARTy and USARTz */
    USART_Enable(USARTy, ENABLE);
    USART_Enable(USARTz, ENABLE);

2. Configure RTS as push-pull output and CTS as input with pull-up. One flow-control signal is driven outward and the other is sampled inward, so the directions must not be swapped.

src/main.csrc/main.c · GPIO_Configuration
    /* Configure USARTy RTS as alternate function push-pull */
    GPIO_InitStructure.Pin            = USARTy_RTSPin;
    GPIO_InitStructure.GPIO_Alternate = USARTy_RTS_GPIO_AF;
    GPIO_InitPeripheral(USARTy_GPIO, &GPIO_InitStructure);

    /* Configure USARTz Tx as alternate function push-pull */
    GPIO_InitStructure.Pin            = USARTz_TxPin;
    GPIO_InitStructure.GPIO_Alternate = USARTz_Tx_GPIO_AF;
    GPIO_InitPeripheral(USARTz_GPIO, &GPIO_InitStructure);

    /* Configure USARTz RTS as alternate function push-pull */
    GPIO_InitStructure.Pin            = USARTz_RTSPin;
    GPIO_InitStructure.GPIO_Alternate = USARTz_RTS_GPIO_AF;
    GPIO_InitPeripheral(USARTz_GPIO, &GPIO_InitStructure);

    /* Configure USARTy Rx as alternate function input and pull-up */
    GPIO_InitStructure.Pin            = USARTy_RxPin;
    GPIO_InitStructure.GPIO_Pull      = GPIO_PULL_UP;
    GPIO_InitStructure.GPIO_Alternate = USARTy_Rx_GPIO_AF;
    GPIO_InitPeripheral(USARTy_GPIO, &GPIO_InitStructure);

    /* Configure USARTz Rx as alternate function input and pull-up */
    GPIO_InitStructure.Pin            = USARTz_RxPin;
    GPIO_InitStructure.GPIO_Alternate = USARTz_Rx_GPIO_AF;
    GPIO_InitPeripheral(USARTz_GPIO, &GPIO_InitStructure);
    
    /* Configure USARTy CTS as alternate function input and pull-up */
    GPIO_InitStructure.Pin            = USARTy_CTSPin;
    GPIO_InitStructure.GPIO_Mode      = GPIO_MODE_INPUT;
    GPIO_InitStructure.GPIO_Pull      = GPIO_PULL_UP;
    GPIO_InitStructure.GPIO_Alternate = USARTy_CTS_GPIO_AF;
    GPIO_InitPeripheral(USARTy_GPIO, &GPIO_InitStructure);

    /* Configure USARTz CTS as alternate function input and pull-up */
    GPIO_InitStructure.Pin            = USARTz_CTSPin;
    GPIO_InitStructure.GPIO_Alternate = USARTz_CTS_GPIO_AF;
    GPIO_InitPeripheral(USARTz_GPIO, &GPIO_InitStructure);    

3. Transmit and receive bidirectionally byte by byte with synchronization. Each byte first waits for the transmit register to empty and then waits for the peer to receive and read it; the reverse process is symmetric.

src/main.csrc/main.c · main
    while (NbrOfDataToRead2--)
    {
        /* Send one byte from USARTy to USARTz */
        USART_SendData(USARTy, TxBuffer1[TxCounter1++]);
        /* Loop until USARTy DAT register is empty */
        while (USART_GetFlagStatus(USARTy, USART_FLAG_TXDE) == RESET)
        {
        }

        /* Loop until the USARTz Receive Data Register is not empty */
        while (USART_GetFlagStatus(USARTz, USART_FLAG_RXDNE) == RESET)
        {
            /* Overflow data loss */
            if(USART_GetFlagStatus(USARTz, USART_FLAG_OREF) != RESET)
            {
                USARTz->DAT;
            }
        }
        /* Store the received byte in RxBuffer */
        RxBuffer2[RxCounter2++] = USART_ReceiveData(USARTz);
    }

    while (NbrOfDataToRead1--)
    {
        /* Send one byte from USARTy to USARTz */
        USART_SendData(USARTz, TxBuffer2[TxCounter2++]);
        /* Loop until USARTz DAT register is empty */
        while (USART_GetFlagStatus(USARTz, USART_FLAG_TXDE) == RESET)
        {
        }

        /* Loop until the USARTz Receive Data Register is not empty */
        while (USART_GetFlagStatus(USARTy, USART_FLAG_RXDNE) == RESET)
        {
            /* Overflow data loss */
            if(USART_GetFlagStatus(USARTy, USART_FLAG_OREF) != RESET)
            {
                USARTy->DAT;
            }
        }
        /* Store the received byte in RxBuffer */
        RxBuffer1[RxCounter1++] = USART_ReceiveData(USARTy);
    }

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

5.28.3.8 Interrupt interrupt transmit and receive

Example directory: projects/n32h49x_EVAL/examples/USART/Interrupt/

Initialize the two UARTs and enable the transmit/receive interrupts→The interrupt transmits and receives byte by byte→Once a direction is full, that direction’s interrupt is disabled→Compare the two sets of transmit and receive data

Item Source analysis
Function USARTy (USART3) and USARTz (UART5) are interconnected;
transmit and receive are entirely interrupt-driven, and after one direction reaches the nominal length its interrupt is disabled, then the two sets of data are compared.
Source files src/main.c: clock, GPIO, USART and NVIC configuration, interrupt enable, and data comparison;
inc/main.h: the two instances, pins, alternate-function numbers, and interrupt vector macros;
src/n32h49x_it.c: the USART3 and UART5 interrupt handlers that disable their own interrupt once full;
readme.txt: function, environment, pin connection, and test steps.
Key configuration USARTy is USART3 (Tx PA9/GPIO_AF17, Rx PA15/GPIO_AF18), USARTz is UART5 (Tx PA2/GPIO_AF20, Rx PA3/GPIO_AF21), alternate-function push-pull with pull-up.
Baud rate 115200, 8-bit word length, 1 stop bit, no parity;
both enable the USART_INT_RXDNE and USART_INT_TXDE interrupts, NVIC group 2, USART3 subpriority 0, UART5 subpriority 1.
Program and data path main configures the clocks, NVIC, GPIO, and the two USARTs, enables the transmit/receive interrupts and starts both, then waits for the two directions’ receive counters to reach the nominal length.
When a direction is full the interrupt disables its own interrupt to avoid repeated triggering, and the main loop finally compares the two buffers with Buffercmp and writes TransferStatus1 and TransferStatus2.
Main APIs USART_Init, USART_ConfigInt, USART_Enable, USART_SendData, USART_ReceiveData, USART_GetFlagStatus, USART_GetIntStatus
Verification Connect USART3_Tx (PA9) to UART5_Rx (PA3) and USART3_Rx (PA15) to UART5_Tx (PA2), and reset to run;
check TransferStatus1 and TransferStatus2 in turn;
both PASSED means both sets of data match.
Use note Disconnect the MCU_TX and MCU_RX jumpers of the NS-LINK on the board first;
both transmit and receive are done in the interrupt, and each direction’s interrupt must be disabled once full so the condition does not stay true and re-enter continuously;
the receive branch must likewise check and clear the overflow, noise, parity, and framing error flags.
The example is based on N32H497ZGL7_STB V1.0, with a toolchain of KEIL MDK-ARM V5.34.0.0 or IAR EWARM 8.50.1.
Core-code walkthrough and porting

The example puts both transmit and receive into the interrupt, disables each direction’s interrupt when full, and the main loop only compares the results.

Data path: TxBuffer1 and TxBuffer2 → the interrupt transmits byte by byte → the peer interrupt receives byte by byte → RxBuffer1 and RxBuffer2 → Buffercmp compares

1. Enable both USARTs’ transmit/receive interrupts and start them. The receive-not-empty and transmit-empty sources each open one interrupt, both are opened, and then the UARTs are started.

src/main.csrc/main.c · main
    /* Enable USARTy Receive and Transmit interrupts */
    USART_ConfigInt(USARTy, USART_INT_RXDNE,ENABLE);
    USART_ConfigInt(USARTy, USART_INT_TXDE,ENABLE);
    
    /* Enable USARTz Receive and Transmit interrupts */
    USART_ConfigInt(USARTz, USART_INT_RXDNE,ENABLE);
    USART_ConfigInt(USARTz, USART_INT_TXDE,ENABLE);

    /* Enable the USARTy and USARTz */
    USART_Enable(USARTy, ENABLE);
    USART_Enable(USARTz, ENABLE);

2. Transmit and receive in the interrupt and disable that direction when full. It first checks the flags and the interrupt enable bits, and disables the corresponding interrupt once receive or transmit reaches the nominal length.

src/n32h49x_it.csrc/n32h49x_it.c · USARTy_IRQHandler
void USARTy_IRQHandler(void)
{
    if ((USART_GetFlagStatus(USARTy, USART_FLAG_RXDNE) != RESET) && (USART_GetIntStatus(USARTy, USART_INT_RXDNE) != RESET))
    {
        /* Read one byte from the receive data register */
        RxBuffer1[RxCounter1++] = USART_ReceiveData(USARTy);

        if (RxCounter1 == NbrOfDataToRead1)
        {
            /* Disable the USARTy Receive interrupt */
            USART_ConfigInt(USARTy, USART_INT_RXDNE,DISABLE);
        }
    }

    if ((USART_GetFlagStatus(USARTy, USART_FLAG_TXDE) != RESET) && (USART_GetIntStatus(USARTy, USART_INT_TXDE) != RESET))
    {
        /* Write one byte to the transmit data register */
        USART_SendData(USARTy, TxBuffer1[TxCounter1++]);

        if (TxCounter1 == NbrOfDataToTransfer1)
        {
            /* Disable the USARTy Transmit interrupt */
            USART_ConfigInt(USARTy, USART_INT_TXDE,DISABLE);
        }
    }

3. The main loop compares the result after receiving is complete. Each direction waits until its receive counter reaches the nominal length and then compares the transmit and receive buffers.

src/main.csrc/main.c · main
    /* Wait until end of transmission from USARTy to USARTz */
    while (RxCounter2 < RxBufferSize2)
    {
    }

    /* Wait until end of transmission from USARTz to USARTy */
    while (RxCounter1 < RxBufferSize1)
    {
    }

    /* Check the received data with the send ones */
    TransferStatus1 = Buffercmp(TxBuffer1, RxBuffer2, TxBufferSize1);

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

5.28.3.9 Transmit_Receive IrDA transmit and receive

Example directory: projects/n32h49x_EVAL/examples/USART/IrDA_Tx&Rx/Transmit_Receive/

Initialize the two UARTs and enable low-power IrDA mode→A timer outputs a 38kHz carrier driving the infrared emitter→USART3 transmits over infrared and UART5 receives in the interrupt→Compare the transmit and receive data

Item Source analysis
Function USARTy (USART3) transmits and USARTz (UART5) receives in serial IrDA low-power mode;
the two ends complete infrared-decoded communication through an infrared emitter and receiver and then compare the data.
Source files src/main.c: clock, GPIO, USART and NVIC configuration, IrDA mode and prescaler settings, transmission and comparison;
inc/main.h: the two instances, pins, alternate-function numbers, and interrupt vector macros;
src/bsp_Tim_38K.c and inc/bsp_Tim_38K.h: output a 38kHz carrier;
src/n32h49x_it.c: the UART5 receive interrupt handler;
readme.txt: function, environment, pin connection, and notes.
Key configuration USARTy is USART3 (Tx PA4/GPIO_AF17), USARTz is UART5 (Rx PG3/GPIO_AF21), and PA8 additionally outputs a 38kHz carrier.
Baud rate 1200, 8-bit word length, 1 stop bit, no parity;
both prescalers are set to 0x01, the IrDA mode is USART_IRDAMODE_NORMAL, and the APB1 clock is lowered to match the low baud rate.
Program and data path main configures the clocks, NVIC, GPIO, and the 38kHz carrier, configures USART3 for transmit and UART5 for receive, sets the prescaler and IrDA mode, and then enables them.
USART3 sends the whole string byte by byte, UART5 receives byte by byte into RxBuffer1 in the interrupt, and the main loop waits until full and then compares with Buffercmp and writes TransferStatus.
Main APIs USART_Init, USART_SetPrescaler, USART_ConfigIrDAMode, USART_EnableIrDA, USART_ConfigInt, USART_Enable, USART_SendData
Verification Connect the infrared emitter and receiver on the board, and reset to run;
check TransferStatus;
PASSED means the received data matches the transmitted data.
Use note Connect jumpers J87 and J89 first;
low-power IrDA needs a 38kHz carrier, and the APB clock must be lowered to produce the low-speed clock for 1200 baud;
The example is based on the full-featured board N32H497ZGL7_EVB V1.0, with a toolchain of KEIL MDK-ARM V5.34.0.0 or IAR EWARM 8.50.1.
Core-code walkthrough and porting

The example uses one UART to transmit and one UART to receive, together with a 38kHz carrier, to complete low-power IrDA infrared communication.

Data path: TxBuffer1 → USART3 (IrDA transmit) → infrared emitter → infrared receiver → UART5 (IrDA receive) → RxBuffer1 → Buffercmp compares

1. Configure one UART for transmit and one for receive. The two share the same parameters, only the operating mode is set to transmit and receive respectively, and the UART5 receive interrupt is opened.

src/main.csrc/main.c · main
    USART_InitStructure.BaudRate            = 1200;
    USART_InitStructure.WordLength          = USART_WL_8B;
    USART_InitStructure.StopBits            = USART_STPB_1;
    USART_InitStructure.Parity              = USART_PE_NO;
    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
    USART_InitStructure.OverSampling        = USART_16OVER;
    USART_InitStructure.Mode                = USART_MODE_TX;
    /* Configure USARTy and USARTz */
    USART_Init(USARTy, &USART_InitStructure);
    USART_InitStructure.Mode                = USART_MODE_RX;
    USART_Init(USARTz, &USART_InitStructure);
    /* Enable USARTz Receive interrupts */
    USART_ConfigInt(USARTz, USART_INT_RXDNE,ENABLE);

2. Set the prescaler and IrDA mode and enable. Low-power IrDA needs the prescaler to lower the clock to a suitable frequency, and both are enabled together after the mode is set.

src/main.csrc/main.c · main
    /* Set the USARTy prescaler */
    USART_SetPrescaler(USARTy, 0x01);//>219
    USART_SetPrescaler(USARTz, 0x01);
    /* Configure the USARTy IrDA mode */
    USART_ConfigIrDAMode(USARTy, USART_IRDAMODE_NORMAL);
    USART_ConfigIrDAMode(USARTz, USART_IRDAMODE_NORMAL);

    /* Enable the USARTy IrDA mode */
    USART_EnableIrDA(USARTy,ENABLE);
    USART_EnableIrDA(USARTz,ENABLE);
    
    /* Enable the USARTy and USARTz */
    USART_Enable(USARTy,ENABLE);
    USART_Enable(USARTz,ENABLE);

3. Transmit byte by byte and wait for reception to complete. The transmit side waits for the transmit register to empty after each byte, and the main loop then waits until the receive counter is full.

src/main.csrc/main.c · main
    while (TxCounter < TxBufferSize1)
    {
        /* Send one byte from Board1_USARTy to Board2_USARTz */
        USART_SendData(USARTy, TxBuffer1[TxCounter++]);
        /* Loop until Board1_USARTy DAT register is empty */
        while (USART_GetFlagStatus(USARTy, USART_FLAG_TXDE) == RESET)
        {
        }
    }
    while (RxCounter < TxBufferSize1)
    {
    }

Corresponding source files: src/main.c, inc/main.h, src/bsp_Tim_38K.c, src/n32h49x_it.c

5.28.3.10 LIN_Master LIN master

Example directory: projects/n32h49x_EVAL/examples/USART/LIN/LIN_Master/

Initialize the UART5 LIN mode and set the break detection length→The master node polls and sends the 0x3C master request frame→It sends the 0x3D slave response frame header and waits for the slave reply→Verify and print the 8-byte reply data

Item Source analysis
Function USARTx (UART5) works in LIN master node mode, polls to send the master request frame (0x3C) and the slave response frame header (0x3D), and prints after receiving the slave’s 8-byte reply.
Source files src/main.c: clock, NVIC, GPIO, and LIN mode initialization, and the main loop that polls the test flow;
src/lin_master.c: frame-header checksum calculation, byte transmit and receive, and the request-frame and response-frame flows;
inc/lin_master.h and inc/main.h: message structures, function declarations, and instance macros;
readme.txt: function, environment, dual-board connection, and test steps.
Key configuration USARTx is UART5 (Tx PG2/GPIO_AF20, Rx PG3/GPIO_AF21), alternate-function push-pull with pull-up;
the print port is PA9/PA10 at baud rate 115200.
LIN baud rate 9600, 8-bit word length, 1 stop bit, no parity, the break detection length is set to USART_LINBDL_10B and LIN mode is enabled.
Program and data path main configures the clocks, NVIC, GPIO, and UART5, sets the break detection length, enables LIN mode and the UART, and then enters the dead loop.
TestMasterReqFrame sends the 0x3C request frame with 8 bytes of 0x0F, TestSlaveResFrame sends the 0x3D frame header, and WaitFrameRes verifies the slave reply and copies the data back and prints it.
Main APIs USART_Init, USART_ConfigLINBreakDetectLength, USART_EnableLIN, USART_Enable, USART_SendBreak, USART_SendData, USART_GetFlagStatus
Verification Flash LIN_Master and LIN_Slave on two boards, reset the slave first and then the master, connect PG2 with PA5 and PG3 with PA4 and share ground as the readme says;
on the print port, watch the master send the request frame and the response frame header in turn and print the 8-byte data returned by the slave.
Use note The two boards must share ground, and the master Tx goes to the slave Rx and the master Rx to the slave Tx;
a LIN frame starts from the sync break generated by USART_SendBreak;
the master node provides the frame header and the slave node only returns data.
The example is based on the full-featured board N32H497ZGL7_EVB V1.0, with a toolchain of KEIL MDK-ARM V5.34 or IAR EWARM 8.50.1.
Core-code walkthrough and porting

The master node sends the frame header and polls for the slave reply, and the frame-header and data checksums are both computed in software per the LIN rules.

Data path: request frame (0x3C, 8 bytes 0x0F) → LIN bus → the slave; response frame header (0x3D) → the slave replies 8 bytes → checksum and comparison → print

1. Set the break detection length and enable LIN mode. The parameters are configured for 9600 baud; the break detection length is set first, then LIN mode and the UART are enabled.

src/main.csrc/main.c · main
    USART_InitStructure.BaudRate            = 9600;
    USART_InitStructure.WordLength          = USART_WL_8B;
    USART_InitStructure.StopBits            = USART_STPB_1;
    USART_InitStructure.Parity              = USART_PE_NO;
    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
    USART_InitStructure.Mode                = USART_MODE_RX | USART_MODE_TX;
    /* Configure USARTx */
    USART_Init(USARTx, &USART_InitStructure);
    /* Enable the USARTx LIN mode*/
    USART_ConfigLINBreakDetectLength(USARTx,USART_LINBDL_10B);
    USART_EnableLIN(USARTx,ENABLE);
    /* Enable the USARTx */
    USART_Enable(USARTx,ENABLE);

2. Send the break and then the frame content byte by byte. Every LIN frame first generates the sync header by sending a break, then writes each byte after the send completes.

src/lin_master.csrc/lin_master.c · MasterSendBytes
void MasterSendBytes(uint8_t *pBuf, uint8_t Len)
{
    USART_SendBreak(USARTx);
    while(Len--)
    {
        while(USART_GetFlagStatus(USARTx, USART_FLAG_TXC) == RESET);
        USART_SendData(USARTx, *pBuf++);
    }
    while(USART_GetFlagStatus(USARTx, USART_FLAG_TXC ) == RESET);
}

3. The main loop compares the request and response frames. It sends the 0x3C request frame, then after a short interval sends the 0x3D frame header, and retries up to four times waiting for the slave reply.

src/lin_master.csrc/lin_master.c · TestLinMaster
void TestLinMaster(void)
{
    int i = 0, count = 0;
    uint8_t recv_data[8];
    TestMasterReqFrame();
    systick_delay_ms(20);
    while(count < 4)
    {
        Memset(recv_data, 0, 8);
        TestSlaveResFrame();
        if(WaitFrameRes(recv_data, 8) == SUCCESS)
        {
            log_info("recv_data:\r\n");
            for(i = 0; i < 8; i++)
            {
                log_info("recv_data[%d] = 0x%x\r\n", i, recv_data[i]);
            }
            break;
        }
        else
        {
            log_info("slave no response!!\r\n");
            count++;
        }
    }
}

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

5.28.3.11 LIN_Slave LIN slave

Example directory: projects/n32h49x_EVAL/examples/USART/LIN/LIN_Slave/

Initialize the UART5 LIN mode and distinguish the receive and transmit IDs→The interrupt receives the master request frame using the break and state machine→The application layer fills in the 8-byte response data→The slave sends the response data back to the master

Item Source analysis
Function USARTx (UART5) works in LIN slave node mode, parsing the master frame header in the interrupt with a state machine, and after receiving the request frame the application layer fills in the data and sends an 8-byte response to the master.
Source files src/main.c: clock, NVIC, GPIO, LIN and interrupt configuration, and the main loop that handles received messages;
src/lin_slave.c: break and state-machine reception, checksum calculation, response data framing and return;
inc/lin_slave.h and inc/main.h: the state enumeration, message structures, and instance macros;
readme.txt: function, environment, dual-board connection, and test steps.
Key configuration USARTx is UART5 (Tx PA4/GPIO_AF20, Rx PA5/GPIO_AF21), alternate-function push-pull with pull-up;
the print port is PA9/PA10 at baud rate 115200.
LIN baud rate 9600, 8-bit word length, 1 stop bit, no parity, break detection length USART_LINBDL_10B, and the USART_INT_RXDNE and USART_INT_LINBD interrupts are enabled.
Program and data path main configures the clocks, NVIC, GPIO, and UART5, enables LIN mode and the transmit/receive and break interrupts and starts, then marks the receive and transmit IDs as the slave receive frame and slave response frame respectively.
In the interrupt the LIN state machine passes through sync, ID, data, and checksum in turn and sets GotMsgFlag once full;
the main loop uses it to call BOOT_ExecutiveCommand to hand the 8-byte response data to the return function.
Main APIs USART_Init, USART_ConfigLINBreakDetectLength, USART_EnableLIN, USART_ConfigInt, USART_Enable, USART_ClrFlag, USART_SendData, USART_ReceiveData
Verification Flash LIN_Master and LIN_Slave on two boards, reset the slave first and then the master, connect PG2 with PA5 and PG3 with PA4 and share ground as the readme says;
on the slave side the parsing process and the filled-in data are printed, and the master side prints the 8-byte response received.
Use note The two boards must share ground, and the master Tx goes to the slave Rx and the master Rx to the slave Tx;
the slave must clear the LINBD flag and read a register once to clear the framing error in the break interrupt, otherwise the state machine does not re-enter sync;
the same ID should be configured for only one direction, receive or transmit.
The example is based on the full-featured board N32H497ZGL7_EVB V1.0, with a toolchain of KEIL MDK-ARM V5.34 or IAR EWARM 8.50.1.
Core-code walkthrough and porting

The slave node does not receive data in the main loop; instead the break interrupt starts the state machine, and once full it is handed to the application layer for framing and return.

Data path: master frame header → LINBD and receive interrupt → LIN_EX_RxAsync state machine → LINRxDataBuffer → GotMsgFlag → BOOT_ExecutiveCommand → LIN_SetResp → LIN_SendBytes

1. Enable LIN mode and the receive and break interrupts. The parameters are configured for 9600 baud, the break detection length is set to 10 bits, and the UART is started after the interrupts are enabled.

src/main.csrc/main.c · main
    USART_InitStructure.BaudRate            = 9600;
    USART_InitStructure.WordLength          = USART_WL_8B;
    USART_InitStructure.StopBits            = USART_STPB_1;
    USART_InitStructure.Parity              = USART_PE_NO;
    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
    USART_InitStructure.Mode                = USART_MODE_RX | USART_MODE_TX;
    /* Configure USARTx */
    USART_Init(USARTx, &USART_InitStructure);
    /* Enable the USARTx LIN mode*/
    USART_ConfigLINBreakDetectLength(USARTx,USART_LINBDL_10B);
    USART_EnableLIN(USARTx,ENABLE);
    
    /* Enable USARTx Receive and Transmit interrupts */
    USART_ConfigInt(USARTx, USART_INT_RXDNE,ENABLE);
    USART_ConfigInt(USARTx, USART_INT_LINBD,ENABLE);

2. The break interrupt starts sync and the receive interrupt pushes data. When a LIN break is detected it clears the flag and moves the state machine into sync, and thereafter every received byte is fed into the state machine.

src/lin_slave.csrc/lin_slave.c · LIN_IRQHandler
void LIN_IRQHandler(void)
{
    if(USART_GetFlagStatus(USARTx, USART_FLAG_LINBD) == SET)
    {
        USART_ClrFlag(USARTx, USART_FLAG_LINBD);//Clear the LIN interval field detection flag bit
        //Read the status register and data register and clear the FE flag
        USARTx->STS;
        USARTx->DAT;
        LinRxState = SYNCH;
        return;
    }
    
    if (USART_GetFlagStatus(USARTx, USART_FLAG_RXDNE)  == SET)
    {
        USART_ClrFlag(USARTx, USART_FLAG_RXDNE); //Clear the receive interrupt flag bit
        if(USART_GetFlagStatus(USARTx, USART_FLAG_FEF) == RESET)
        {
            LIN_EX_RxAsync((uint8_t)USART_ReceiveData(USARTx));
        }
    }

3. The state machine parses the frame header in the sync and ID steps. The sync byte must be 0x55; once the ID passes the parity bits, the receive/transmit direction of that ID decides whether to take data or return data.

src/lin_slave.csrc/lin_slave.c · LIN_EX_RxAsync
void LIN_EX_RxAsync(uint8_t data)
{
    switch(LinRxState)
    {
    case IDLE:
        break;
    case SYNCH:
        if(data == 0x55)
        {
            LINRxDataBuffer[LINRxDataIndex].Sync = 0x55;
            LinRxState = ID_LEN;
        }
        else
        {
            LinRxState = IDLE;
        }
        break;
    case ID_LEN:
        if(GET_PID(data) == data)
        {
            LINRxDataBuffer[LINRxDataIndex].PID = data;
            LINRxDataBuffer[LINRxDataIndex].DataLen = 0;
            if(IDType[data & 0x3F] == ID_TYPE_SR)
            {
                LinRxState = DATA_GET;
            }
            else
            {
                //Receives the frame header sent by the host and sends data in slave mode
                if(((LINTxMsg.PID & 0x3F) == (data & 0x3F)) && (LINTxMsg.DataLen > 0))
                {
                    LIN_SendBytes(LINTxMsg.Data, LINTxMsg.DataLen + 1);
                    LINTxMsg.DataLen = 0;
                }
                LinRxState = IDLE;
            }
        }
        else
        {
            LinRxState = IDLE;
        }
        break;

4. The main loop hands the received frame to the application layer to fill in and return. The state machine sets a flag once the whole frame is received, and the main loop uses it to run the application logic and clear the flag.

src/main.csrc/main.c · main
    while (1)
    {
        if(GotMsgFlag)
        {
            BOOT_ExecutiveCommand(pLINMsg->Data, LIN_RespData);
            GotMsgFlag = 0;
        }
    }

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

5.28.3.12 MultiProcessor multiprocessor mode

Example directory: projects/n32h49x_EVAL/examples/USART/MultiProcessor/

Initialize the two UARTs and set each node’s own address→The slave receives silently while the master keeps sending 0x33→A key puts the slave into mute mode→The master sends an address frame to wake the slave and resume reception

Item Source analysis
Function USARTy (USART3) keeps sending 0x33 to USARTz (UART5), and the slave toggles LED1 as soon as it receives it;
a key, through an external interrupt, puts the slave into mute, and then the master sends address 0x102 to wake it.
Source files src/main.c: clock, GPIO, USART configuration, address and wake-up mode settings, polling transmit and receive, and LED toggling;
src/bsp_led.c, src/bsp_key.c, and their headers: onboard LED and key initialization;
src/n32h49x_it.c: the EXTI15_10 interrupt handler that switches between mute and wake-up;
readme.txt: function, environment, pin connection, and test steps.
Key configuration USARTy is USART3 (Tx PA9/GPIO_AF17, Rx PA15/GPIO_AF18), USARTz is UART5 (Tx PA2/GPIO_AF20, Rx PA3/GPIO_AF21);
LED1 uses PA8, and the key uses PC13 with an external interrupt enabled.
Baud rate 115200, 9-bit word length, 1 stop bit, no parity;
the two addresses are set to 0x1 and 0x2, and the wake-up mode is USART_WUM_ADDRMASK.
Program and data path main configures the clocks, GPIO, LED, and key, initializes both USARTs and starts them, sets the address and wake-up mode, and then enters the dead loop.
In the loop the master keeps sending 0x33 and the slave toggles LED1 when it receives it;
in the key interrupt the slave is first put into mute and then the master sends address 0x102 to wake it.
Main APIs USART_Init, USART_Enable, USART_SetAddr, USART_ConfigWakeUpMode, USART_EnableRcvWakeUp, USART_SendData, USART_ReceiveData, USART_GetFlagStatus
Verification Connect USART3_Tx (PA9) to UART5_Rx (PA3) and USART3_Rx (PA15) to UART5_Tx (PA2), and reset to run;
observe LED1 blinking continuously;
press the key once to stop the blinking and press it again to resume.
Use note Disconnect the MCU_TX and MCU_RX jumpers of the NS-LINK on the board first;
after the slave enters mute it no longer receives ordinary data, and only an address frame matching its own address can wake it;
multiprocessor mode requires a 9-bit word length, with the 9th bit distinguishing address frames from data frames.
The example is based on the full-featured board N32H497ZGL7_EVB V1.0, with a toolchain of KEIL MDK-ARM V5.34.0.0 or IAR EWARM 8.50.1.
Core-code walkthrough and porting

Multiprocessor mode uses a 9-bit word length to distinguish addresses from data, and the slave is woken by an address frame after being muted.

Data path: master 0x33 → the slave checks it and toggles LED1; key EXTI → the slave enables mute → the master sends address 0x102 → the slave wakes

1. Set the two addresses and the slave wake-up mode. Both use a 9-bit word length, each sets its own address, and the slave chooses address-mask wake-up.

src/main.csrc/main.c · main
    USART_InitStructure.BaudRate            = 115200;
    USART_InitStructure.WordLength          = USART_WL_9B;
    USART_InitStructure.StopBits            = USART_STPB_1;
    USART_InitStructure.Parity              = USART_PE_NO;
    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
    USART_InitStructure.OverSampling        = USART_16OVER;
    USART_InitStructure.Mode                = USART_MODE_RX | USART_MODE_TX;

    /* Configure USARTy and USARTz */
    USART_Init(USARTy, &USART_InitStructure);
    USART_Init(USARTz, &USART_InitStructure);

    /* Enable the USARTy and USARTz */
    USART_Enable(USARTy, ENABLE);
    USART_Enable(USARTz, ENABLE);
    
    /* Set the USARTy and USARTz Address */
    USART_SetAddr(USARTy, 0x1);
    USART_SetAddr(USARTz, 0x2);

    /* Select the USARTz WakeUp Method */
    USART_ConfigWakeUpMode(USARTz, USART_WUM_ADDRMASK);

2. Poll transmit and receive and toggle the LED on received data. The master keeps sending 0x33, and the slave lights and then extinguishes LED1 when it receives the same data, forming a blink.

src/main.csrc/main.c · main
    while (1)
    {
        /* Send one byte from USARTy to USARTz */
        USART_SendData(USARTy, 0x33);

        /* Wait while USARTy TXE = 0 */
        while (USART_GetFlagStatus(USARTy, USART_FLAG_TXDE) == RESET)
        {
        }

        if (USART_GetFlagStatus(USARTz, USART_FLAG_RXDNE) != RESET)
        {
            /* Overflow data loss */
            if(USART_GetFlagStatus(USARTz, USART_FLAG_OREF) != RESET)
            {
                USARTz->DAT;
            }
            if (USART_ReceiveData(USARTz) == 0x33)
            {
                LED1_RED_ON;
                Delay(0x1FFFFF);
                LED1_RED_OFF;
                Delay(0x1FFFFF);
            }
        }
    }

3. In the key interrupt, mute first and then send the address to wake. The interrupt is split into two steps by a flag: first put the slave into mute, then after a delay the master sends an address frame to wake it.

src/n32h49x_it.csrc/n32h49x_it.c · EXTI15_10_IRQHandler
void EXTI15_10_IRQHandler(void)
{
    Delay(0x2FFFFF);
    if (ControlFlag == 2)
    {
        ControlFlag = 0;
    }

    if (ControlFlag == 0)
    {
        /* Flush DAT register and clear the USARTz RXNE flag */
        USART_ReceiveData(USARTz);
        /* Enable the USARTz mute mode*/
        USART_EnableRcvWakeUp(USARTz,ENABLE);

        ControlFlag = 1;
    }
    else if (ControlFlag == 1)
    {
        /* Send the address mark (0x102) to wakeup USARTz */
        USART_SendData(USARTy, 0x102);
        /* Wait while USARTy TXE = 0 */
        while (USART_GetFlagStatus(USARTy, USART_FLAG_TXDE) == RESET)
        {
        }

        ControlFlag = 2;
    }

    /* Clear Key Button EXTI Line Pending Bit */
    EXTI_ClrITPendBit(KEY_INPUT_EXTI_LINE);
}

Corresponding source files: src/main.c, src/n32h49x_it.c, src/bsp_led.c, src/bsp_key.c

5.28.3.13 Polling polling transmit and receive

Example directory: projects/n32h49x_EVAL/examples/USART/Polling/

Initialize the two UARTs→USART3 polls to transmit and UART5 polls to receive→In reverse UART5 polls to transmit and USART3 receives→Compare the transmit and receive data in each of the two directions

Item Source analysis
Function USARTy (USART3) and USARTz (UART5) are interconnected;
transmit and receive are entirely flag-polled, and each of the two directions compares its data once.
Source files src/main.c: clock, GPIO, USART configuration, flag-polled transmit and receive, and two data comparisons;
inc/main.h: the two instances, pins, alternate-function numbers, and the test-status enumeration;
readme.txt: function, environment, pin connection, and test steps.
Key configuration USARTy is USART3 (Tx PA9/GPIO_AF17, Rx PA15/GPIO_AF18), USARTz is UART5 (Tx PA2/GPIO_AF20, Rx PA3/GPIO_AF21), alternate-function push-pull with pull-up.
Baud rate 115200, 8-bit word length, 1 stop bit, no parity;
no interrupt and no DMA, both directions synchronize with USART_FLAG_TXDE and USART_FLAG_RXDNE.
Program and data path main configures the clocks, GPIO, and the two USARTs and starts them, and first USART3 sends byte by byte to UART5 into RxBuffer1, writing the comparison result to TransferStatus.
It then clears the transmit/receive counters and sets the status to failed, UART5 sends byte by byte to USART3 into RxBuffer2, and the comparison result is written to the same TransferStatus again.
Main APIs USART_Init, USART_Enable, USART_SendData, USART_ReceiveData, USART_GetFlagStatus
Verification Connect USART3_Tx (PA9) to UART5_Rx (PA3) and USART3_Rx (PA15) to UART5_Tx (PA2), and reset to run;
check TransferStatus twice (once per direction);
PASSED means that direction’s data matches.
Use note Disconnect the MCU_TX and MCU_RX jumpers of the NS-LINK on the board first;
the comparison results of the two directions share the same TransferStatus, so it must be checked separately between the two directions;
otherwise only the last result is visible.
The example is based on N32H497ZGL7_STB V1.0, with a toolchain of KEIL MDK-ARM V5.34.0.0 or IAR EWARM 8.50.1.
Core-code walkthrough and porting

The example uses the most basic flag polling to complete bidirectional transmit and receive; each byte waits for the transmit register to empty, and each byte waits for the receive register not to be empty.

Data path: TxBuffer1 → USART3 → UART5 → RxBuffer1 → Buffercmp compares; TxBuffer2 → UART5 → USART3 → RxBuffer2 → Buffercmp compares

1. Initialize both USARTs and start them. The parameters are configured for 115200 baud, the two USARTs share one structure, and they are started together after configuration.

src/main.csrc/main.c · main
    USART_InitStructure.BaudRate            = 115200;
    USART_InitStructure.WordLength          = USART_WL_8B;
    USART_InitStructure.StopBits            = USART_STPB_1;
    USART_InitStructure.Parity              = USART_PE_NO;
    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
    USART_InitStructure.OverSampling        = USART_16OVER;
    USART_InitStructure.Mode                = USART_MODE_RX | USART_MODE_TX;

    /* Configure USARTy and USARTz */
    USART_Init(USARTy, &USART_InitStructure);
    USART_Init(USARTz, &USART_InitStructure);

    /* Enable the USARTy and USARTz */
    USART_Enable(USARTy, ENABLE);
    USART_Enable(USARTz, ENABLE);

2. USART3 transmits and UART5 receives, then compare. After one byte it waits for the transmit to empty and then waits for the peer to receive and read it; a final comparison gives the result.

src/main.csrc/main.c · main
    while (TxCounter < TxBufferSize1)
    {
        /* Send one byte from USARTy to USARTz */
        USART_SendData(USARTy, TxBuffer1[TxCounter++]);
        /* Loop until USARTy DAT register is empty */
        while (USART_GetFlagStatus(USARTy, USART_FLAG_TXDE) == RESET)
        {
        }

        /* Loop until the USARTz Receive Data Register is not empty */
        while (USART_GetFlagStatus(USARTz, USART_FLAG_RXDNE) == RESET)
        {
            /* Overflow data loss */
            if(USART_GetFlagStatus(USARTz, USART_FLAG_OREF) != RESET)
            {
                USARTz->DAT;
            }
        }
        /* Store the received byte in RxBuffer */
        RxBuffer1[RxCounter++] = USART_ReceiveData(USARTz);
    }

    /* Check the received data with the send ones */
    /* TransferStatus = PASSED, if the data transmitted from USARTy and
       received by USARTz are the same */
    /* TransferStatus = FAILED, if the data transmitted from USARTy and
       received by USARTz are different */
    TransferStatus = Buffercmp(TxBuffer1, RxBuffer1, TxBufferSize1);

3. Clear the counters and status before the reverse transmit/receive. The counters and status must be reset; the reverse flow is fully symmetric with the forward flow, and the comparison result reuses the same variable.

src/main.csrc/main.c · main
    TxCounter = 0;
    RxCounter = 0;
    TransferStatus = FAILED;
    while (TxCounter < TxBufferSize1)
    {
        /* Send one byte from USARTz to USARTy */
        USART_SendData(USARTz, TxBuffer2[TxCounter++]);
        /* Loop until USARTz DAT register is empty */
        while (USART_GetFlagStatus(USARTz, USART_FLAG_TXDE) == RESET)
        {
        }

        /* Loop until the USARTy Receive Data Register is not empty */
        while (USART_GetFlagStatus(USARTy, USART_FLAG_RXDNE) == RESET)
        {
            /* Overflow data loss */
            if(USART_GetFlagStatus(USARTy, USART_FLAG_OREF) != RESET)
            {
                USARTy->DAT;
            }
        }
        /* Store the received byte in RxBuffer */
        RxBuffer2[RxCounter++] = USART_ReceiveData(USARTy);
    }

    /* Check the received data with the send ones */
    /* TransferStatus = PASSED, if the data transmitted from USARTz and
       received by USARTy are the same */
    /* TransferStatus = FAILED, if the data transmitted from USARTz and
       received by USARTy are different */
    TransferStatus = Buffercmp(TxBuffer2, RxBuffer2, TxBufferSize2);

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

5.28.3.14 Printf UART printing

Example directory: projects/n32h49x_EVAL/examples/USART/Printf/

Initialize USART3 and configure the transmit pin→Retarget the C library printf to the UART→Print a line of prompt to the PC terminal after reset→Idle in the main loop

Item Source analysis
Function Retarget the C library printf to USARTx (USART3), print a line of prompt to the PC terminal after startup, and demonstrate UART print output.
Source files src/main.c: clock, GPIO, USART configuration, and the fputc retarget implementation and print call;
inc/main.h: the instance, transmit pin, and alternate-function number macros;
readme.txt: function, environment, pin connection, and test steps.
Key configuration USARTx is USART3 (Tx PA9/GPIO_AF17), alternate-function push-pull with pull-up.
Baud rate 115200, 8-bit word length, 1 stop bit, no parity;
only the transmit pin is used, and the retarget function waits for the transmit-complete flag before sending each byte.
Program and data path main configures the clocks, GPIO, and USART3 and enables it, then calls printf to output a line of prompt.
Each printed character enters fputc, which waits for USART_FLAG_TXC to be set and then writes the character to the data register;
after returning, the main loop idles.
Main APIs USART_Init, USART_Enable, USART_SendData, USART_GetFlagStatus
Verification Connect USART3_Tx (PA9) to a PC serial port or serial tool with 115200 baud and reset to run;
when USART Printf Example: retarget the C library printf function to the USART appears on the terminal, the printing has succeeded.
Use note Disconnect the MCU_TX and MCU_RX jumpers of the NS-LINK on the board first;
the retarget relies on the C library hook fputc;
to switch to another UART, only the instance macro needs to change with the pins configured accordingly.
The example is based on N32H497ZGL7_STB V1.0, with a toolchain of KEIL MDK-ARM V5.34 or IAR EWARM 8.50.1.
Core-code walkthrough and porting

The example uses the C library retarget hook to connect standard output to the UART, after which printf can be used directly.

Data path: printf → C library → fputc → wait for USART_FLAG_TXC → USART_SendData → USART3 → PC terminal

1. Configure the transmit pin as alternate-function push-pull. Only one transmit line is needed, configured as alternate-function push-pull with pull-up.

src/main.csrc/main.c · GPIO_Configuration
    GPIO_InitType GPIO_InitStructure;

    /* Initialize GPIO_InitStructure */
    GPIO_InitStruct(&GPIO_InitStructure);
    
    /* Configure USARTy Tx as alternate function push-pull */
    GPIO_InitStructure.Pin            = USARTx_TxPin;
    GPIO_InitStructure.GPIO_Mode      = GPIO_MODE_AF_PP;
    GPIO_InitStructure.GPIO_Alternate = USARTx_Tx_GPIO_AF;
    GPIO_InitStructure.GPIO_Pull      = GPIO_PULL_UP;
    GPIO_InitPeripheral(USARTx_GPIO, &GPIO_InitStructure);

2. Initialize the UART and output with printf. The parameters are configured for 115200 baud, and after enabling, printf is called directly to output the prompt string.

src/main.csrc/main.c · main
    USART_InitStructure.BaudRate            = 115200;
    USART_InitStructure.WordLength          = USART_WL_8B;
    USART_InitStructure.StopBits            = USART_STPB_1;
    USART_InitStructure.Parity              = USART_PE_NO;
    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
    USART_InitStructure.OverSampling        = USART_16OVER;
    USART_InitStructure.Mode                = USART_MODE_RX | USART_MODE_TX;

    /* Configure USARTx */
    USART_Init(USARTx, &USART_InitStructure);

    /* Enable the USARTx */
    USART_Enable(USARTx, ENABLE);

    /* Output a message on Hyperterminal using printf function */
    printf("USART Printf Example: retarget the C library printf function to the USART\r\n");

3. Complete the retarget with fputc. The C library calls fputc once for every output character, and here it writes the character to the data register after transmit completes.

src/main.csrc/main.c · fputc
int fputc(int ch, FILE* f)
{
    /* Loop until the end of transmission */
    while (USART_GetFlagStatus(USARTx, USART_FLAG_TXC) == RESET)
    {
    }
    USART_SendData(USARTx, (uint8_t)ch);

    return (ch);
}

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

5.28.3.15 SmartCard smart card communication

Example directory: projects/n32h49x_EVAL/examples/USART/SmartCard/

Reset the smart card and enter the T0 activation flow→Send the get-random-number command and receive the response→Perform PPS and re-handshake→Judge by the status word and print the random number

Item Source analysis
Function SC_USART (USART3) works in smart card interface mode;
after reset and T0 protocol activation it sends a get-random-number command to the smart card, then judges by the status word whether the command completed normally and prints the random number.
Source files src/main.c: system initialization, the smart card test flow and warm reset, and the status-word judgement and printing;
src/smartcard.c: smart card interface initialization, APDU commands, PPS configuration, byte transmit/receive, and DMA configuration;
inc/smartcard.h: the instance, pins, DMA, and protocol constants;
src/delay.c, src/n32h49x_it.c: delay and interrupt service;
readme.txt: function, environment, pin connection, and test steps.
Key configuration SC_USART is USART3 (I/O PB8/GPIO_AF17, CK PC12/GPIO_AF6), reset uses PB9, and the print port is USART1 (PA9, 115200).
Clock prescaler 40 (smart card operating clock 2.5 MHz), guard time 16, 1.5 stop bits, even parity, 9-bit word length;
DMA uses DMA1_CH7 for transmit and DMA1_CH6 for receive.
Program and data path main performs system initialization first, then enters Test_PSAM to configure the clock prescaler, guard time, and stop bits, enables the parity-error and framing-error interrupts, and then enables the smart card interface.
After T0 activation it sends the SC_GET_A2R command to get a random number, branches on the returned status word SW1/SW2 to print the result, and finally does one warm reset and de-initialization.
Main APIs USART_Init, USART_SetPrescaler, USART_SetGuardTime, USART_ClockInit, USART_ConfigInt, USART_SetSmartCardNACK, USART_EnableSmartCard, USART_SendData
Verification Per the readme, connect USART3_Tx (PB8) to the smart card I/O, USART3_CK (PC12) to CLK, and PB9 to RST, and wire up 3V3 and GND;
reset to run, and view the smart card command status word and random-number data on the 115200 print port.
Use note Connect the smart card clock, reset, power, and ground first;
the baud rate depends on the clock prescaler and the guard time, so fix the operating clock before computing it;
run NACK transmission and the application PPS command by command as the card supports, and do not cut power during re-handshake.
The example is based on the full-feature board N32H497ZGL7_EVB V1.0, with a toolchain of KEIL MDK-ARM V5.34 or IAR EWARM 8.50.1.
Core-code walkthrough and porting

The example handshakes with the smart card using the ISO7816 T0 protocol, and both reading and writing are done with byte-level transmit/receive plus a state machine.

Data path: SC_Init → reset and T0 activation → APDU command (get random number) → smart card response data and status word → judgement and printing → warm reset and de-initialization

1. Set the prescaler, guard time, and card clock. The prescaler determines the smart card operating clock, the guard time determines the minimum gap between two characters, and the card clock is initialized separately.

src/smartcard.csrc/smartcard.c
    /* SC_USART Clock set to 3MHz (PCLK1 = 120 MHZ / 40) */
    USART_SetPrescaler(SC_USART, SC_InitCfg->Clk_Div >> 1);
    /* USART Guard Time set to 16 Bit */
    USART_SetGuardTime(SC_USART, SC_InitCfg->GT);
src/smartcard.csrc/smartcard.c
    USART_ClockInitStructure.Clock      = USART_CLK_ENABLE;
    USART_ClockInitStructure.Polarity   = USART_CLKPOL_LOW;
    USART_ClockInitStructure.Phase      = USART_CLKPHA_1EDGE;
    USART_ClockInitStructure.LastBit    = USART_CLKLB_ENABLE;
    USART_ClockInit(SC_USART, &USART_ClockInitStructure);

2. Initialize the interface, enable the error interrupts, and select the NACK behavior. 9-bit word length with even parity, one interrupt each for parity error and framing error, and finally the configuration decides whether to send NACK and enables the smart card interface.

src/smartcard.csrc/smartcard.c
    USART_Init(SC_USART, &USART_InitStructure);
    /* Enable the SC_USART Parity Error Interrupt */
    USART_ConfigInt(SC_USART, USART_INT_PEF,ENABLE);
    /* Enable the SC_USART Framing Error Interrupt */
    USART_ConfigInt(SC_USART, USART_INT_ERRF,ENABLE);
    /* Enable SC_USART */
    USART_Enable(SC_USART,ENABLE);
    /* Enable the NACK Transmission */
    if(SC_InitCfg->NackEn == 0)
    {
        USART_SetSmartCardNACK(SC_USART,DISABLE);
    }
    else if(SC_InitCfg->NackEn == 1)
    {
        USART_SetSmartCardNACK(SC_USART,ENABLE);
    }
    else
    {
        log_info("\r\n NACK Enable value is error !!! \r\n");
    }
    /* Enable the Smartcard Interface */
    USART_EnableSmartCard(SC_USART,ENABLE);

3. Test flow: activate, get the random number, and judge by the status word. After the configuration parameters, the state machine is driven in a loop until the card is active, then the get-random-number command is sent and the result judged by SW1/SW2.

src/main.csrc/main.c · Test_PSAM
    log_info("USARTx Smart_Card Test Start\r\n");
    SC_InitCfg.Clk_Div   = 40;    //SC_USART Clock set to (PCLK1 = SC_USART MHZ / Clk_Div) MHz
    SC_InitCfg.GT        = 16;
    SC_InitCfg.StopBits  = 3;
    SC_InitCfg.Parity    = 1;
    SC_InitCfg.NackEn    = 0;    // 0 - Disable NACK, 1 - Enable NACK
    SCState = SC_POWER_ON;
    SC_APDU_Init(&SC_ADPU, 0x00, SC_GET_A2R, 0x00, 0x00, 0x00, NULL, 0);
    while(SCState != SC_ACTIVE_ON_T0)
    {
        SC_Handler(&SCState, &SC_ADPU, &SC_Responce, &SC_InitCfg);
    }
    /* Apply the Procedure Type Selection (PPS) */
    SC_PPSConfig();
    SC_APDU_Init(&SC_ADPU, 0x00, 0x84, 0x00, 0x00, 0x00, NULL, 8);
    SC_Handler(&SCState, &SC_ADPU, &SC_Responce, &SC_InitCfg);
    for(i = 0; i < SC_ADPU.Body.LE; i++)
    {
        log_info("\r\n SC_Responce.Data[%d] = 0x%02x \r\n", i, SC_Responce.Data[i]);
    }
    printf("\r\n SC_Responce.SW1 = 0x%02x \r\n", SC_Responce.SW1);
    printf("\r\n SC_Responce.SW2 = 0x%02x \r\n", SC_Responce.SW2);
    if((SC_Responce.SW1 == 0x90) && (SC_Responce.SW2 == 0x00))
    {

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

5.28.3.16 Synchronous synchronous mode transmit and receive

Example directory: projects/n32h49x_EVAL/examples/USART/Synchronous/

Configure USART1 in synchronous mode and SPI1 in slave mode→USART1 transmits and SPI1 receives→In reverse SPI1 transmits and USART1 receives→Compare the two sets of transmit and receive data

Item Source analysis
Function USARTy (USART1) works in synchronous mode and outputs CK, interconnected three-wire with the slave-mode SPIy (SPI1), and the two sets of data are compared after bidirectional transmit and receive.
Source files src/main.c: clock, GPIO, synchronous clock, USART and SPI configuration, bidirectional transmit/receive, and data comparison;
inc/main.h: the USART and SPI instances, data pins, CK, and alternate-function number macros;
readme.txt: function, environment, three-wire connection, and test steps.
Key configuration USARTy is USART1 (Tx PA9, Rx PA10, CK PA8, alternate function GPIO_AF5), SPIy is SPI1 (SCK PA5, MISO PA6, MOSI PA7, alternate function GPIO_AF1).
USART baud rate 115200, 8-bit word length, 1 stop bit, no parity, CK polarity low, sampled on the second edge, with a pulse on the last bit;
SPI is slave mode, 8-bit, CPOL low, CPHA second edge, software NSS, LSB first.
Program and data path main configures the clocks, GPIO, synchronous clock, USART, and SPI and enables them;
first USART1 transmits and SPI1 receives into RxBuffer2.
Then SPI1 transmits and USART1 receives into RxBuffer1, synchronized during each by the transmit-complete and receive-not-empty flags, and finally Buffercmp compares the two buffers.
Main APIs USART_Init, USART_ClockInit, USART_Enable, USART_SendData, USART_ReceiveData, USART_GetFlagStatus, SPI_I2S_ReceiveData
Verification Connect USART1_Tx (PA9) to SPI1_MOSI (PA7), USART1_Rx (PA10) to SPI1_MISO (PA6), and USART1_Clk (PA8) to SPI1_SCK (PA5);
remove the UART print jumper and reset to run, then check TransferStatus1 and TransferStatus2 in turn;
both being PASSED means the transmit and receive match.
Use note Disconnect the MCU_TX and MCU_RX jumpers of the NS-LINK on the board first and remove the UART print jumper;
USART synchronous mode is clocked by CK, so the peer must be configured in slave mode with matching clock polarity and phase;
as the side providing the clock, USART must send a dummy byte to generate the clock before it can read data back during reverse reception.
The example is based on N32H497ZGL7_STB V1.0, with a toolchain of KEIL MDK-ARM V5.34.0.0 or IAR EWARM 8.50.1.
Core-code walkthrough and porting

USART synchronous mode outputs a clock on CK and forms a three-wire bus with the slave-mode SPI, with both ends aligned byte by byte through flags.

Data path: TxBuffer1 → USART1 (synchronous) → SPI1 → RxBuffer2; TxBuffer2 → SPI1 → USART1 → RxBuffer1 → Buffercmp compares

1. Enable the synchronous clock and set the polarity and phase. The clock is output only during transmission, and the sampling phase and last-bit pulse must correspond to the peer SPI.

src/main.csrc/main.c · main
    USART_ClockInitStructure.Clock    = USART_CLK_ENABLE;
    USART_ClockInitStructure.Polarity = USART_CLKPOL_LOW;
    USART_ClockInitStructure.Phase    = USART_CLKPHA_2EDGE;
    USART_ClockInitStructure.LastBit  = USART_CLKLB_ENABLE;
    USART_ClockInit(USARTy, &USART_ClockInitStructure);

2. Configure the USART parameters and enable it. The parameters are configured for 115200 baud, and USART1 is enabled after configuration is complete.

src/main.csrc/main.c · main
    USART_InitStructure.BaudRate            = 115200;
    USART_InitStructure.WordLength          = USART_WL_8B;
    USART_InitStructure.StopBits            = USART_STPB_1;
    USART_InitStructure.Parity              = USART_PE_NO;
    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
    USART_InitStructure.OverSampling        = USART_16OVER;
    USART_InitStructure.Mode                = USART_MODE_RX | USART_MODE_TX;

    /* Configure USARTy */
    USART_Init(USARTy, &USART_InitStructure);

    /* Enable the USARTy */
    USART_Enable(USARTy, ENABLE);

3. USART1 transmits and SPI1 receives. Each byte waits for transmit to complete, then waits for the SPI receive register not to be empty and reads the data.

src/main.csrc/main.c · main
    while(NbrOfDataToRead2--)
    {
        /* Write one byte in the USARTy Transmit Data Register */
        USART_SendData(USARTy, TxBuffer1[TxCounter1++]);
        /* Wait until end of transmit */
        while (USART_GetFlagStatus(USARTy, USART_FLAG_TXC) == RESET)
        {
        }

        /* Wait the byte is entirely received by SPIy */
        while (SPI_I2S_GetStatus(SPIy, SPI_I2S_RNE_FLAG) == RESET)
        {
        }
        /* Store the received byte in the RxBuffer2 */
        RxBuffer2[RxCounter2++] = SPI_I2S_ReceiveData(SPIy);
    }

4. SPI1 transmits and USART1 receives. USART is the side providing the clock, so during reception it must send a dummy byte to generate the clock, then wait for the receive register not to be empty and read the data back.

src/main.csrc/main.c · main
    while (NbrOfDataToRead1--)
    {
        /* Wait until end of transmit */
        while (SPI_I2S_GetStatus(SPIy, SPI_I2S_TE_FLAG) == RESET)
        {
        }
        /* Write one byte in the SPIy Transmit Data Register */
        SPI_I2S_TransmitData(SPIy, TxBuffer2[TxCounter2++]);

        /* Send a Dummy byte to generate clock to slave */
        USART_SendData(USARTy, DYMMY_BYTE);
        /* Wait until end of transmit */
        while (USART_GetFlagStatus(USARTy, USART_FLAG_TXC) == RESET)
        {
        }
        /* Wait the byte is entirely received by USARTy */
        while (USART_GetFlagStatus(USARTy, USART_FLAG_RXDNE) == RESET)
        {
            /* Overflow data loss */
            if(USART_GetFlagStatus(USARTy, USART_FLAG_OREF) != RESET)
            {
                USARTy->DAT;
            }
        }
        /* Store the received byte in the RxBuffer1 */
        RxBuffer1[RxCounter1++] = USART_ReceiveData(USARTy);
    }

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

5.28.4 Notes and troubleshooting

Scenario Check & action Source
Communication mode mutual exclusion Before enabling a mode, the mutually exclusive bits must be cleared: synchronous mode requires clearing LINMEN, SCMEN, HDMEN, and IRDAMEN;
single-wire half-duplex requires clearing CLKEN, LINMEN, SCMEN, and IRDAMEN;
IrDA requires clearing CLKEN, STPB[1:0], LINMEN, HDMEN, and SCMEN;
LIN requires clearing STPB[1:0], CLKEN, SCMEN, HDMEN, and IRDAMEN;
smart card requires clearing LINMEN, HDMEN, and IRDAMEN.
User manual
Control bits not writable after enable TEDEN, IFCEN, SWAP, OSPM, DEAT, DEDT, DEP, and DEM in USART_CTRL1 can only be written while USART is disabled (UEN=0);
these settings must be completed before enabling USART.
User manual
Oversampling bit value in specific modes In LIN, IrDA, and smart card modes, USART_CTRL1.OSPM must remain 0. User manual
Baud-rate register write condition USART_BRCF cannot be written when USART_CTRL1.UEN=1;
do not change the baud-rate register value during communication;
after a new value is written the baud-rate counter is replaced immediately.
User manual
Modifying the word length during transfer USART_CTRL1.WL cannot be modified during data transfer (transmission or reception). User manual
Disabling the transmitter or receiver during transfer Clearing USART_CTRL1.TXEN during data transfer stops the baud-rate counter and corrupts the data being transmitted;
clearing USART_CTRL1.RXEN during reception loses the current received data.
User manual
Synchronous clock configuration timing CLKPOL, CLKPHA, and LBCLK in synchronous mode can only be configured when both the transmitter and the receiver are disabled;
synchronous data cannot be received while no data is being transmitted.
User manual
Receiver timeout recount After a receiver timeout, USART_STS.RTOF must be cleared (by writing USART_CTRL2.RTOCF), otherwise the timeout counting does not restart;
after clearing, counting does not begin again until the next data is received.
User manual
Data error discard and FIFO configuration Data error discard (PEFLOSE/FEFLOSE/NEFLOSE) is valid only for received data in FIFO mode;
when FIFO is enabled the thresholds TXFTCFG/RXFTCFG must not be configured as 2'b00;
USART_FIFO.CLR is a pulse bit and is automatically cleared to zero by hardware after writing 1.
User manual
Modes not supported by some instances UART5, UART6, UART7, and UART8 do not support synchronous mode or smart card mode;
CLKEN, CLKPHA, CLKPOL, and LBCLK have no effect on them, and SCMEN and SCNACK are forced to 0 for these instances.
User manual
Driver enable timing After USART_CTRL1.DEM is enabled, DEAT cannot be configured as 0 (the minimum is 1);
DEAT and DEDT must be written while UEN=0.
User manual
Writing data while CTS is invalid When nCTS is invalid (high), data written to the data register is retained and transmission begins only after nCTS becomes valid;
if nCTS is pulled high during transmission, transmission stops after the current data is transferred.
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.