- /****************************************************************************
- * [url=home.php?mod=space&uid=288409]@file[/url] main.c
- * [url=home.php?mod=space&uid=895143]@version[/url] V3.00
- * $Revision: 4 $
- * $Date: 15/02/06 10:22a $
- * @brief
- * Transmit and receive data in UART RS485 mode.
- * This sample code needs to work with UART_RS485_Master.
- * @note
- * Copyright (C) 2011 Nuvoton Technology Corp. All rights reserved.
- *
- ******************************************************************************/
- #include <stdio.h>
- #include "M058S.h"
- #define PLL_CLOCK 50000000
- #define RXBUFSIZE 128
- #define IS_USE_RS485NMM 1 //1:Select NMM_Mode , 0:Select AAD_Mode
- #define MATCH_ADDRSS 0xC0
- /*---------------------------------------------------------------------------------------------------------*/
- /* Define functions prototype */
- /*---------------------------------------------------------------------------------------------------------*/
- extern char GetChar(void);
- int32_t main(void);
- void RS485_HANDLE(void);
- void RS485_9bitModeSlave(void);
- volatile int32_t r_pointer = 0;
- uint8_t g_u8RecData[RXBUFSIZE] = {0};
- /*---------------------------------------------------------------------------------------------------------*/
- /* ISR to handle UART Channel 0 interrupt event */
- /*---------------------------------------------------------------------------------------------------------*/
- void UART0_IRQHandler(void)
- {
- RS485_HANDLE();
- }
- /*---------------------------------------------------------------------------------------------------------*/
- /* RS485 Callback function */
- /*---------------------------------------------------------------------------------------------------------*/
- void RS485_HANDLE()
- {
- volatile uint32_t addr = 0;
- volatile uint32_t u32IntSts = UART0->ISR;
- /* RLS INT & RDA INT */ //For RS485 Detect Address
- if((u32IntSts & UART_ISR_RLS_INT_Msk) && (u32IntSts & UART_ISR_RDA_INT_Msk))
- {
- if(UART0->FSR & UART_FSR_RS485_ADD_DETF_Msk) /* ADD_IF, RS485 mode */
- {
- addr = UART0->RBR;
- UART_RS485_CLEAR_ADDR_FLAG(UART0); /* clear ADD_IF flag */
- #if (IS_USE_RS485NMM ==1) //RS485_NMM
- /* if address match, enable RX to receive data, otherwise to disable RX */
- /* In NMM mode, user can decide multi-address filter */
- /* In AAD mode, only one address can set */
- if(addr == MATCH_ADDRSS)
- {
- UART0->FCR &= ~ UART_FCR_RX_DIS_Msk; /* Enable RS485 RX */
- }
- else
- {
- UART0->FCR |= UART_FCR_RX_DIS_Msk; /* Disable RS485 RX */
- UART0->FCR |= UART_FCR_RFR_Msk; /* Clear data from RX FIFO */
- }
- #endif
- }
- }
- else if((u32IntSts & UART_ISR_RDA_INT_Msk) || (u32IntSts & UART_ISR_TOUT_INT_Msk)) /* Rx Ready or Time-out INT*/
- {
- /* Handle received data */
- g_u8RecData[r_pointer++] = UART0->RBR;
- }
- else if(u32IntSts & UART_ISR_BUF_ERR_INT_Msk) /* Buffer Error INT */
- {
- printf("\nBuffer Error...\n");
- UART_ClearIntFlag(UART0, UART_ISR_BUF_ERR_INT_Msk);
- }
- }
- /*---------------------------------------------------------------------------------------------------------*/
- /* RS485 Receive Test (IS_USE_RS485NMM: 0:AAD 1:NMM) */
- /*---------------------------------------------------------------------------------------------------------*/
- void RS485_9bitModeSlave()
- {
- uint32_t i;
- printf("\n");
- printf("+-------------------------------------------------------------+\n");
- printf("| Pin Configure |\n");
- printf("+-------------------------------------------------------------+\n");
- printf("| _______ _______ |\n");
- printf("| | | | | |\n");
- printf("| |Master |--- TXD(P3.1) <====> RXD(P3.0) ---| Slave | |\n");
- printf("| | |--- RTS(P0.3) <====> RTS(P0.3) ---| | |\n");
- printf("| |_______| |_______| |\n");
- printf("| |\n");
- printf("+-------------------------------------------------------------+\n");
- printf("| Please enable semihosted to show messages on debug session.|\n");
- printf("| Keil users must define DEBUG_ENABLE_SEMIHOST in both C/C++ |\n");
- printf("| and Asm preprocessor symbols. |\n");
- printf("| IAR users must define DEBUG_ENABLE_SEMIHOST in both C/C++ |\n");
- printf("| Compiler and Assembler preprocessor symbols. |\n");
- printf("+-------------------------------------------------------------+\n");
- printf("| RS485 Function Test (9-bit Slave) |\n");
- printf("+-------------------------------------------------------------+\n");
- /*
- The sample code is used to test RS485 9-bit mode and needs
- two Module test board to complete the test.
- Master:
- 1.Set AUD mode and HW will control RTS pin. LEV_RTS is set to '0'.
- 2.Master will send four different address with 10 bytes data to test Slave.
- 3.Address bytes : the parity bit should be '1'. (Set UA_LCR = 0x2B)
- 4.Data bytes : the parity bit should be '0'. (Set UA_LCR = 0x3B)
- 5.RTS pin is low in idle state. When master is sending,
- RTS pin will be pull high.
- Slave:
- 1.Set AAD and AUD mode firstly. LEV_RTS is set to '0'.
- 2.The received byte, parity bit is '1' , is considered "ADDRESS".
- 3.The received byte, parity bit is '0' , is considered "DATA". (Default)
- 4.AAD: The slave will ignore any data until ADDRESS match ADDR_MATCH value.
- When RLS and RDA interrupt is happened,it means the ADDRESS is received.
- Check if RS485_ADD_DETF is set and read UA_RBR to clear ADDRESS stored in rx_fifo.
- NMM: The slave will ignore data byte until disable RX_DIS.
- When RLS and RDA interrupt is happened,it means the ADDRESS is received.
- Check the ADDRESS is match or not by user in UART_IRQHandler.
- If the ADDRESS is match,clear RX_DIS bit to receive data byte.
- If the ADDRESS is not match,set RX_DIS bit to avoid data byte stored in FIFO.
- */
- /* Set Data Format, Only need parity enable whenever parity ODD/EVEN */
- UART_SetLine_Config(UART0, 0, UART_WORD_LEN_8, UART_PARITY_EVEN, UART_STOP_BIT_1);
- /* Set RTS pin active level as high level active */
- UART0->MCR &= ~UART_MCR_LEV_RTS_Msk;
- UART0->MCR |= UART_RTS_IS_HIGH_LEV_ACTIVE;
- #if(IS_USE_RS485NMM == 1)
- printf("\n");
- printf("+-------------------------------------------------------------+\n");
- printf("| Normal Multidrop Operation Mode |\n");
- printf("+-------------------------------------------------------------+\n");
- printf("| The function is used to test 9-bit slave mode. |\n");
- printf("| Only Address %x data can receive |\n", MATCH_ADDRSS);
- printf("+-------------------------------------------------------------+\n");
- /* Set RX_DIS enable before set RS485-NMM mode */
- UART0->FCR |= UART_FCR_RX_DIS_Msk;
- /* Set RS485-NMM Mode */
- UART_SelectRS485Mode(UART0, UART_ALT_CSR_RS485_NMM_Msk | UART_ALT_CSR_RS485_AUD_Msk, 0);
- /* Set RS485 address detection enable */
- UART0->ALT_CSR |= UART_ALT_CSR_RS485_ADD_EN_Msk;
- #else
- printf("+-------------------------------------------------------------+\n");
- printf("| The function is used to test 9-bit slave mode. |\n");
- printf("| Auto Address Match Operation Mode |\n");
- printf("+-------------------------------------------------------------+\n");
- printf("|Only Address %x, data can receive |\n", MATCH_ADDRSS);
- printf("+-------------------------------------------------------------+\n");
- /* Set RS485-AAD Mode and address match is 0xC0 */
- UART_SelectRS485Mode(UART0, UART_ALT_CSR_RS485_AAD_Msk | UART_ALT_CSR_RS485_AUD_Msk, MATCH_ADDRSS);
- /* Set RS485 address detection enable */
- UART0->ALT_CSR |= UART_ALT_CSR_RS485_ADD_EN_Msk;
- #endif
- /* Enable RDA\RLS\Time-out Interrupt */
- UART_EnableInt(UART0, (UART_IER_RDA_IEN_Msk | UART_IER_RLS_IEN_Msk | UART_IER_RTO_IEN_Msk));
- r_pointer = 0;
- /* Check Rx empty, otherwise read Rx */
- printf("Starting to recevice %d bytes data...\n", RXBUFSIZE);
- while(r_pointer < RXBUFSIZE);
- /* Compare Data */
- for(i = 0; i < RXBUFSIZE; i++)
- {
- if(g_u8RecData[i] != (i & 0xFF))
- {
- printf("Compare Data Failed\n");
- while(1);
- }
- }
- printf("\n Receive OK & Check OK\n");
- /* Flush Rx FIFO */
- UART0->FCR |= UART_FCR_RFR_Msk;
- /* Disable RDA\RLS\Time-out Interrupt */
- UART_DisableInt(UART0, (UART_IER_RDA_IEN_Msk | UART_IER_RLS_IEN_Msk | UART_IER_RTO_IEN_Msk));
- printf("\nEnd test\n");
- }
- void SYS_Init(void)
- {
- /*---------------------------------------------------------------------------------------------------------*/
- /* Init System Clock */
- /*---------------------------------------------------------------------------------------------------------*/
- /* Enable Internal RC 22.1184MHz clock */
- CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);
- /* Waiting for Internal RC clock ready */
- CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);
- /* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
- CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));
- /* Enable external XTAL 12MHz clock */
- CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);
- /* Waiting for external XTAL clock ready */
- CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);
- /* Set core clock as PLL_CLOCK from PLL */
- CLK_SetCoreClock(PLL_CLOCK);
- /* Enable UART module clock */
- CLK_EnableModuleClock(UART0_MODULE);
- /* Select UART module clock source */
- CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));
- /*---------------------------------------------------------------------------------------------------------*/
- /* Init I/O Multi-function */
- /*---------------------------------------------------------------------------------------------------------*/
- /* Set P3 multi-function pins for UART0 RXD and TXD */
- SYS->P3_MFP &= ~(SYS_MFP_P30_Msk | SYS_MFP_P31_Msk);
- SYS->P3_MFP |= (SYS_MFP_P30_RXD | SYS_MFP_P31_TXD);
- /* Set P0 multi-function pins for UART RTS */
- SYS->P0_MFP = SYS->P0_MFP & (~SYS_MFP_P03_Msk) | SYS_MFP_P03_RTS;
- }
- void UART0_Init()
- {
- /*---------------------------------------------------------------------------------------------------------*/
- /* Init UART */
- /*---------------------------------------------------------------------------------------------------------*/
- /* Reset UART0 */
- SYS_ResetModule(UART0_RST);
- /* Configure UART0 and set UART0 Baudrate */
- UART_Open(UART0, 115200);
- }
- /*---------------------------------------------------------------------------------------------------------*/
- /* MAIN function */
- /*---------------------------------------------------------------------------------------------------------*/
- int32_t main(void)
- {
- /* Unlock protected registers */
- SYS_UnlockReg();
- /* Init System, peripheral clock and multi-function I/O */
- SYS_Init();
- /* Lock protected registers */
- SYS_LockReg();
- /* Init UART0 for testing */
- UART0_Init();
- /*---------------------------------------------------------------------------------------------------------*/
- /* SAMPLE CODE */
- /*---------------------------------------------------------------------------------------------------------*/
- printf("\n\nCPU [url=home.php?mod=space&uid=72445]@[/url] %dHz\n", SystemCoreClock);
- printf("\n\nUART Sample Program\n");
- /* UART RS485 sample slave function */
- RS485_9bitModeSlave();
- while(1);
- }
|