These are the examples provided for [[/users/frank26080115/libraries/LPC1700CMSIS_Lib/]] Note, the entire "program" is not compilable!

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers rs485_master.c Source File

rs485_master.c

Go to the documentation of this file.
00001 /***********************************************************************//**
00002  * @file        rs485_master.c
00003  * @purpose     This example used to test RS485 functionality on UART1 of
00004  *              LPC1768.In this case, RS485 function on UART1 acts as Master
00005  *              on RS485 bus.
00006  * @version     2.0
00007  * @date        21. May. 2010
00008  * @author      NXP MCU SW Application Team
00009  *---------------------------------------------------------------------
00010  * Software that is described herein is for illustrative purposes only
00011  * which provides customers with programming information regarding the
00012  * products. This software is supplied "AS IS" without any warranties.
00013  * NXP Semiconductors assumes no responsibility or liability for the
00014  * use of the software, conveys no license or title under any patent,
00015  * copyright, or mask work right to the product. NXP Semiconductors
00016  * reserves the right to make changes in the software without
00017  * notification. NXP Semiconductors also make no representation or
00018  * warranty that such application will be suitable for the specified
00019  * use without further testing or modification.
00020  **********************************************************************/
00021 #include "lpc17xx_uart.h"
00022 #include "lpc17xx_libcfg.h"
00023 #include "lpc17xx_pinsel.h"
00024 
00025 /* Example group ----------------------------------------------------------- */
00026 /** @defgroup UART_RS485_Master RS485_Master
00027  * @ingroup UART_Examples
00028  * @{
00029  */
00030 
00031 /************************** PRIVATE DEFINITIONS *************************/
00032 // Slave Address
00033 #define SLAVE_ADDR_A 'A'
00034 #define SLAVE_ADDR_B 'B'
00035 
00036 /* buffer size definition */
00037 #define UART_RING_BUFSIZE 256
00038 
00039 /* Buf mask */
00040 #define __BUF_MASK (UART_RING_BUFSIZE-1)
00041 /* Check buf is full or not */
00042 #define __BUF_IS_FULL(head, tail) ((tail&__BUF_MASK)==((head+1)&__BUF_MASK))
00043 /* Check buf will be full in next receiving or not */
00044 #define __BUF_WILL_FULL(head, tail) ((tail&__BUF_MASK)==((head+2)&__BUF_MASK))
00045 /* Check buf is empty */
00046 #define __BUF_IS_EMPTY(head, tail) ((head&__BUF_MASK)==(tail&__BUF_MASK))
00047 /* Reset buf */
00048 #define __BUF_RESET(bufidx) (bufidx=0)
00049 #define __BUF_INCR(bufidx)  (bufidx=(bufidx+1)&__BUF_MASK)
00050 
00051 /************************** PRIVATE VARIABLES *************************/
00052 uint8_t menu1[] = "Hello NXP Semiconductors \n\r";
00053 uint8_t menu2[] = "RS485 demo in Master mode \n\r";
00054 uint8_t send_menu[] = "Sending... \n\r";
00055 uint8_t recv_menu[] = "Receive: ";
00056 uint8_t p_err_menu[] = "Parity error \n\r";
00057 uint8_t f_err_menu[] = "Frame error \n\r";
00058 uint8_t nextline[] = "\n\r";
00059 
00060 uint8_t slaveA_msg[] = "Msg A: Hello NXP";
00061 uint8_t slaveB_msg[] = "Msg B: Hello NXP";
00062 uint8_t terminator = 13;
00063 
00064 /************************** PRIVATE TYPES *************************/
00065 /** @brief UART Ring buffer structure */
00066 typedef struct
00067 {
00068     __IO uint32_t tx_head;                /*!< UART Tx ring buffer head index */
00069     __IO uint32_t tx_tail;                /*!< UART Tx ring buffer tail index */
00070     __IO uint32_t rx_head;                /*!< UART Rx ring buffer head index */
00071     __IO uint32_t rx_tail;                /*!< UART Rx ring buffer tail index */
00072     __IO uint8_t  tx[UART_RING_BUFSIZE];  /*!< UART Tx data ring buffer */
00073     __IO uint8_t  rx[UART_RING_BUFSIZE];  /*!< UART Rx data ring buffer */
00074 } UART_RING_BUFFER_T;
00075 
00076 /************************** PRIVATE VARIABLES *************************/
00077 // UART Ring buffer
00078 UART_RING_BUFFER_T rb;
00079 
00080 /************************** PRIVATE FUNCTIONS *************************/
00081 void UART1_IRQHandler(void);
00082 void UART_IntReceive(void);
00083 void UART_IntErr(uint8_t bLSErrType);
00084 
00085 uint32_t UARTReceive(LPC_UART_TypeDef *UARTPort, uint8_t *rxbuf, uint8_t buflen);
00086 void print_menu(void);
00087 
00088 
00089 
00090 /*----------------- INTERRUPT SERVICE ROUTINES --------------------------*/
00091 /*********************************************************************//**
00092  * @brief       UART1 interrupt handler sub-routine
00093  * @param[in]   None
00094  * @return      None
00095  **********************************************************************/
00096 void UART1_IRQHandler(void)
00097 {
00098     uint32_t intsrc, tmp, tmp1;
00099 
00100     /* Determine the interrupt source */
00101     intsrc = UART_GetIntId(LPC_UART0);
00102     tmp = intsrc & UART_IIR_INTID_MASK;
00103 
00104     // Receive Line Status
00105     if (tmp == UART_IIR_INTID_RLS){
00106         // Check line status
00107         tmp1 = UART_GetLineStatus(LPC_UART0);
00108         // Mask out the Receive Ready and Transmit Holding empty status
00109         tmp1 &= (UART_LSR_OE | UART_LSR_PE | UART_LSR_FE \
00110                 | UART_LSR_BI | UART_LSR_RXFE);
00111         // If any error exist
00112         if (tmp1) {
00113             UART_IntErr(tmp1);
00114         }
00115     }
00116 
00117     // Receive Data Available or Character time-out
00118     if ((tmp == UART_IIR_INTID_RDA) || (tmp == UART_IIR_INTID_CTI)){
00119         UART_IntReceive();
00120     }
00121 
00122 }
00123 
00124 /********************************************************************//**
00125  * @brief       UART receive function (ring buffer used)
00126  * @param[in]   None
00127  * @return      None
00128  *********************************************************************/
00129 void UART_IntReceive(void)
00130 {
00131     uint8_t tmpc;
00132     uint32_t rLen;
00133 
00134     while(1){
00135         // Call UART read function in UART driver
00136         rLen = UART_Receive((LPC_UART_TypeDef *)LPC_UART1, &tmpc, 1, NONE_BLOCKING);
00137         // If data received
00138         if (rLen){
00139             /* Check if buffer is more space
00140              * If no more space, remaining character will be trimmed out
00141              */
00142             if (!__BUF_IS_FULL(rb.rx_head,rb.rx_tail)){
00143                 rb.rx[rb.rx_head] = tmpc;
00144                 __BUF_INCR(rb.rx_head);
00145             }
00146         }
00147         // no more data
00148         else {
00149             break;
00150         }
00151     }
00152 }
00153 
00154 
00155 /*********************************************************************//**
00156  * @brief       UART Line Status Error
00157  * @param[in]   bLSErrType  UART Line Status Error Type
00158  * @return      None
00159  **********************************************************************/
00160 void UART_IntErr(uint8_t bLSErrType)
00161 {
00162     if (bLSErrType & UART_LSR_PE){
00163         UART_Send(LPC_UART0, p_err_menu, sizeof(p_err_menu), BLOCKING);
00164     }
00165 
00166     if (bLSErrType & UART_LSR_FE){
00167         UART_Send(LPC_UART0, f_err_menu, sizeof(f_err_menu), BLOCKING);
00168     }
00169 }
00170 
00171 /*-------------------------PRIVATE FUNCTIONS------------------------------*/
00172 /*********************************************************************//**
00173  * @brief       UART read function for interrupt mode (using ring buffers)
00174  * @param[in]   UARTPort    Selected UART peripheral used to send data,
00175  *              should be UART0
00176  * @param[out]  rxbuf Pointer to Received buffer
00177  * @param[in]   buflen Length of Received buffer
00178  * @return      Number of bytes actually read from the ring buffer
00179  **********************************************************************/
00180 uint32_t UARTReceive(LPC_UART_TypeDef *UARTPort, uint8_t *rxbuf, uint8_t buflen)
00181 {
00182     uint8_t *data = (uint8_t *) rxbuf;
00183     uint32_t bytes = 0;
00184 
00185     /* Temporarily lock out UART receive interrupts during this
00186        read so the UART receive interrupt won't cause problems
00187        with the index values */
00188     UART_IntConfig(UARTPort, UART_INTCFG_RBR, DISABLE);
00189 
00190     /* Loop until receive buffer ring is empty or
00191         until max_bytes expires */
00192     while ((buflen > 0) && (!(__BUF_IS_EMPTY(rb.rx_head, rb.rx_tail))))
00193     {
00194         /* Read data from ring buffer into user buffer */
00195         *data = rb.rx[rb.rx_tail];
00196         data++;
00197 
00198         /* Update tail pointer */
00199         __BUF_INCR(rb.rx_tail);
00200 
00201         /* Increment data count and decrement buffer size count */
00202         bytes++;
00203         buflen--;
00204     }
00205 
00206     /* Re-enable UART interrupts */
00207     UART_IntConfig(UARTPort, UART_INTCFG_RBR, ENABLE);
00208 
00209     return bytes;
00210 }
00211 
00212 /*********************************************************************//**
00213  * @brief       Print Welcome menu
00214  * @param[in]   none
00215  * @return      None
00216  **********************************************************************/
00217 void print_menu(void)
00218 {
00219     UART_Send(LPC_UART0, menu1, sizeof(menu1), BLOCKING);
00220     UART_Send(LPC_UART0, menu2, sizeof(menu2), BLOCKING);
00221 }
00222 
00223 
00224 
00225 /*-------------------------MAIN FUNCTION------------------------------*/
00226 /*********************************************************************//**
00227  * @brief       c_entry: Main UART-RS485 program body
00228  * @param[in]   None
00229  * @return      int
00230  **********************************************************************/
00231 int c_entry(void)
00232 {
00233     // UART Configuration structure variable
00234     UART_CFG_Type UARTConfigStruct;
00235     // UART FIFO configuration Struct variable
00236     UART_FIFO_CFG_Type UARTFIFOConfigStruct;
00237     // Pin configuration
00238     PINSEL_CFG_Type PinCfg;
00239     // RS485 configuration
00240     UART1_RS485_CTRLCFG_Type rs485cfg;
00241     // Temp. data
00242     uint32_t idx, len;
00243     uint8_t buffer[10];
00244     int32_t exit_flag, addr_toggle;
00245 
00246     // UART0 section ----------------------------------------------------
00247     /*
00248      * Initialize UART0 pin connect
00249      */
00250     PinCfg.Funcnum = 1;
00251     PinCfg.OpenDrain = 0;
00252     PinCfg.Pinmode = 0;
00253     PinCfg.Pinnum = 2;
00254     PinCfg.Portnum = 0;
00255     PINSEL_ConfigPin(&PinCfg);
00256     PinCfg.Pinnum = 3;
00257     PINSEL_ConfigPin(&PinCfg);
00258 
00259     /* Initialize UART Configuration parameter structure to default state:
00260      * Baudrate = 115200 bps
00261      * 8 data bit
00262      * 1 Stop bit
00263      * None parity
00264      */
00265     UART_ConfigStructInit(&UARTConfigStruct);
00266     UARTConfigStruct.Baud_rate = 115200;
00267 
00268     // Initialize UART0 peripheral with given to corresponding parameter
00269     UART_Init(LPC_UART0, &UARTConfigStruct);
00270 
00271     /* Initialize FIFOConfigStruct to default state:
00272      *              - FIFO_DMAMode = DISABLE
00273      *              - FIFO_Level = UART_FIFO_TRGLEV0
00274      *              - FIFO_ResetRxBuf = ENABLE
00275      *              - FIFO_ResetTxBuf = ENABLE
00276      *              - FIFO_State = ENABLE
00277      */
00278     UART_FIFOConfigStructInit(&UARTFIFOConfigStruct);
00279 
00280     // Initialize FIFO for UART0 peripheral
00281     UART_FIFOConfig(LPC_UART0, &UARTFIFOConfigStruct);
00282 
00283     // Enable UART Transmit
00284     UART_TxCmd(LPC_UART0, ENABLE);
00285 
00286     // print welcome screen
00287     print_menu();
00288 
00289 
00290     // UART1 - RS485 section -------------------------------------------------
00291     /*
00292      * Initialize UART1 pin connect
00293      */
00294     PinCfg.Funcnum = 2;
00295     PinCfg.OpenDrain = 0;
00296     PinCfg.Pinmode = 0;
00297     // TXD1 - P2.0
00298     PinCfg.Pinnum = 0;
00299     PinCfg.Portnum = 2;
00300     PINSEL_ConfigPin(&PinCfg);
00301     // RXD1 - P2.1
00302     PinCfg.Pinnum = 1;
00303     PINSEL_ConfigPin(&PinCfg);
00304     // DTR1 - P2.5
00305     PinCfg.Pinnum = 5;
00306     PINSEL_ConfigPin(&PinCfg);
00307 
00308 
00309 
00310     /* Initialize UART Configuration parameter structure to default state:
00311      * Baudrate = 9600 bps
00312      * 8 data bit
00313      * 1 Stop bit
00314      * Parity: None
00315      * Note: Parity will be enabled later in UART_RS485Config() function.
00316      */
00317     UART_ConfigStructInit(&UARTConfigStruct);
00318 
00319     // Initialize UART0 peripheral with given to corresponding parameter
00320     UART_Init((LPC_UART_TypeDef *)LPC_UART1, &UARTConfigStruct);
00321 
00322     /* Initialize FIFOConfigStruct to default state:
00323      *              - FIFO_DMAMode = DISABLE
00324      *              - FIFO_Level = UART_FIFO_TRGLEV0
00325      *              - FIFO_ResetRxBuf = ENABLE
00326      *              - FIFO_ResetTxBuf = ENABLE
00327      *              - FIFO_State = ENABLE
00328      */
00329     UART_FIFOConfigStructInit(&UARTFIFOConfigStruct);
00330 
00331     // Initialize FIFO for UART0 peripheral
00332     UART_FIFOConfig((LPC_UART_TypeDef *)LPC_UART1, &UARTFIFOConfigStruct);
00333 
00334     // Configure RS485
00335     /*
00336      * - Auto Direction in Tx/Rx driving is enabled
00337      * - Direction control pin is set to DTR1
00338      * - Direction control pole is set to "1" that means direction pin
00339      * will drive to high state before transmit data.
00340      * - Multidrop mode is disable
00341      * - Auto detect address is disabled
00342      * - Receive state is enable
00343      */
00344     rs485cfg.AutoDirCtrl_State = ENABLE;
00345     rs485cfg.DirCtrlPin = UART1_RS485_DIRCTRL_DTR;
00346     rs485cfg.DirCtrlPol_Level = SET;
00347     rs485cfg.DelayValue = 50;
00348     rs485cfg.NormalMultiDropMode_State = DISABLE;
00349     rs485cfg.AutoAddrDetect_State = DISABLE;
00350     rs485cfg.MatchAddrValue = 0;
00351     rs485cfg.Rx_State = ENABLE;
00352     UART_RS485Config(LPC_UART1, &rs485cfg);
00353 
00354     /* Enable UART Rx interrupt */
00355     UART_IntConfig((LPC_UART_TypeDef *)LPC_UART1, UART_INTCFG_RBR, ENABLE);
00356     /* Enable UART line status interrupt */
00357     UART_IntConfig((LPC_UART_TypeDef *)LPC_UART1, UART_INTCFG_RLS, ENABLE);
00358 
00359     /* preemption = 1, sub-priority = 1 */
00360     NVIC_SetPriority(UART1_IRQn, ((0x01<<3)|0x01));
00361     /* Enable Interrupt for UART0 channel */
00362     NVIC_EnableIRQ(UART1_IRQn);
00363 
00364     // Enable UART Transmit
00365     UART_TxCmd((LPC_UART_TypeDef *)LPC_UART1, ENABLE);
00366 
00367     addr_toggle = 1;
00368     // for testing...
00369     while (1){
00370 
00371         // Send slave addr -----------------------------------------
00372         UART_Send(LPC_UART0, send_menu, sizeof(send_menu), BLOCKING);
00373         // Send slave addr on RS485 bus
00374         if (addr_toggle){
00375             UART_RS485SendSlvAddr(LPC_UART1, SLAVE_ADDR_A);
00376         } else {
00377             UART_RS485SendSlvAddr(LPC_UART1, SLAVE_ADDR_B);
00378         }
00379         // delay for a while
00380         for (len = 0; len < 1000; len++);
00381 
00382         // Send data -----------------------------------------------
00383         if (addr_toggle){
00384             UART_RS485SendData(LPC_UART1, slaveA_msg, sizeof(slaveA_msg));
00385         } else {
00386             UART_RS485SendData(LPC_UART1, slaveB_msg, sizeof(slaveB_msg));
00387         }
00388         // Send terminator
00389         UART_RS485SendData(LPC_UART1, &terminator, 1);
00390         // delay for a while
00391          for (len = 0; len < 1000; len++);
00392 
00393          // Receive data from slave --------------------------------
00394         UART_Send(LPC_UART0, recv_menu, sizeof(recv_menu), BLOCKING);
00395         // If address 'A' required response...
00396         if (addr_toggle){
00397             exit_flag = 0;
00398             while (!exit_flag){
00399                 len = UARTReceive((LPC_UART_TypeDef *)LPC_UART1, buffer, sizeof(buffer));
00400                 /* Got some data */
00401                 idx = 0;
00402                 while (idx < len)
00403                 {
00404                     if (buffer[idx] == 13){
00405                         exit_flag = 1;
00406                     } else {
00407                         /* Echo it back */
00408                         UART_Send(LPC_UART0, &buffer[idx], 1, BLOCKING);
00409                     }
00410                     idx++;
00411                 }
00412             }
00413         }
00414 
00415         UART_Send(LPC_UART0, nextline, sizeof(nextline), BLOCKING);
00416         addr_toggle = (addr_toggle ? 0 : 1);
00417         // long delay here
00418         for (len = 0; len < 10000000; len++);
00419     }
00420 
00421     return 1;
00422 }
00423 
00424 /* With ARM and GHS toolsets, the entry point is main() - this will
00425    allow the linker to generate wrapper code to setup stacks, allocate
00426    heap area, and initialize and copy code and data segments. For GNU
00427    toolsets, the entry point is through __start() in the crt0_gnu.asm
00428    file, and that startup code will setup stacks and data */
00429 int main(void)
00430 {
00431     return c_entry();
00432 }
00433 
00434 
00435 #ifdef  DEBUG
00436 /*******************************************************************************
00437 * @brief        Reports the name of the source file and the source line number
00438 *               where the CHECK_PARAM error has occurred.
00439 * @param[in]    file Pointer to the source file name
00440 * @param[in]    line assert_param error line source number
00441 * @return       None
00442 *******************************************************************************/
00443 void check_failed(uint8_t *file, uint32_t line)
00444 {
00445     /* User can add his own implementation to report the file name and line number,
00446      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
00447 
00448     /* Infinite loop */
00449     while(1);
00450 }
00451 #endif
00452 
00453 /*
00454  * @}
00455  */