![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
blinky example from NXP code bundle for LPC11Uxx. No mbed library used
KEIL_LPC11U_COMMON_LIB/uart.c@1:0f1be4e75668, 2012-05-28 (annotated)
- Committer:
- alexan_e
- Date:
- Mon May 28 00:13:23 2012 +0000
- Revision:
- 1:0f1be4e75668
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
alexan_e | 1:0f1be4e75668 | 1 | /**************************************************************************** |
alexan_e | 1:0f1be4e75668 | 2 | * $Id:: uart.c 9188 2012-02-16 20:53:43Z nxp41306 $ |
alexan_e | 1:0f1be4e75668 | 3 | * Project: NXP LPC11Uxx UART example |
alexan_e | 1:0f1be4e75668 | 4 | * |
alexan_e | 1:0f1be4e75668 | 5 | * Description: |
alexan_e | 1:0f1be4e75668 | 6 | * This file contains UART code example which include UART |
alexan_e | 1:0f1be4e75668 | 7 | * initialization, UART interrupt handler, and related APIs for |
alexan_e | 1:0f1be4e75668 | 8 | * UART access. |
alexan_e | 1:0f1be4e75668 | 9 | * |
alexan_e | 1:0f1be4e75668 | 10 | **************************************************************************** |
alexan_e | 1:0f1be4e75668 | 11 | * Software that is described herein is for illustrative purposes only |
alexan_e | 1:0f1be4e75668 | 12 | * which provides customers with programming information regarding the |
alexan_e | 1:0f1be4e75668 | 13 | * products. This software is supplied "AS IS" without any warranties. |
alexan_e | 1:0f1be4e75668 | 14 | * NXP Semiconductors assumes no responsibility or liability for the |
alexan_e | 1:0f1be4e75668 | 15 | * use of the software, conveys no license or title under any patent, |
alexan_e | 1:0f1be4e75668 | 16 | * copyright, or mask work right to the product. NXP Semiconductors |
alexan_e | 1:0f1be4e75668 | 17 | * reserves the right to make changes in the software without |
alexan_e | 1:0f1be4e75668 | 18 | * notification. NXP Semiconductors also make no representation or |
alexan_e | 1:0f1be4e75668 | 19 | * warranty that such application will be suitable for the specified |
alexan_e | 1:0f1be4e75668 | 20 | * use without further testing or modification. |
alexan_e | 1:0f1be4e75668 | 21 | |
alexan_e | 1:0f1be4e75668 | 22 | * Permission to use, copy, modify, and distribute this software and its |
alexan_e | 1:0f1be4e75668 | 23 | * documentation is hereby granted, under NXP Semiconductors |
alexan_e | 1:0f1be4e75668 | 24 | * relevant copyright in the software, without fee, provided that it |
alexan_e | 1:0f1be4e75668 | 25 | * is used in conjunction with NXP Semiconductors microcontrollers. This |
alexan_e | 1:0f1be4e75668 | 26 | * copyright, permission, and disclaimer notice must appear in all copies of |
alexan_e | 1:0f1be4e75668 | 27 | * this code. |
alexan_e | 1:0f1be4e75668 | 28 | |
alexan_e | 1:0f1be4e75668 | 29 | ****************************************************************************/ |
alexan_e | 1:0f1be4e75668 | 30 | |
alexan_e | 1:0f1be4e75668 | 31 | #include "LPC11Uxx.h" |
alexan_e | 1:0f1be4e75668 | 32 | #include "type.h" |
alexan_e | 1:0f1be4e75668 | 33 | #include "uart.h" |
alexan_e | 1:0f1be4e75668 | 34 | |
alexan_e | 1:0f1be4e75668 | 35 | volatile uint32_t UARTStatus; |
alexan_e | 1:0f1be4e75668 | 36 | volatile uint8_t UARTTxEmpty = 1; |
alexan_e | 1:0f1be4e75668 | 37 | volatile uint8_t UARTBuffer[BUFSIZE]; |
alexan_e | 1:0f1be4e75668 | 38 | volatile uint32_t UARTCount = 0; |
alexan_e | 1:0f1be4e75668 | 39 | |
alexan_e | 1:0f1be4e75668 | 40 | #if AUTOBAUD_ENABLE |
alexan_e | 1:0f1be4e75668 | 41 | volatile uint32_t UARTAutoBaud = 0, AutoBaudTimeout = 0; |
alexan_e | 1:0f1be4e75668 | 42 | #endif |
alexan_e | 1:0f1be4e75668 | 43 | |
alexan_e | 1:0f1be4e75668 | 44 | /***************************************************************************** |
alexan_e | 1:0f1be4e75668 | 45 | ** Function name: UART_IRQHandler |
alexan_e | 1:0f1be4e75668 | 46 | ** |
alexan_e | 1:0f1be4e75668 | 47 | ** Descriptions: UART interrupt handler |
alexan_e | 1:0f1be4e75668 | 48 | ** |
alexan_e | 1:0f1be4e75668 | 49 | ** parameters: None |
alexan_e | 1:0f1be4e75668 | 50 | ** Returned value: None |
alexan_e | 1:0f1be4e75668 | 51 | ** |
alexan_e | 1:0f1be4e75668 | 52 | *****************************************************************************/ |
alexan_e | 1:0f1be4e75668 | 53 | void UART_IRQHandler(void) |
alexan_e | 1:0f1be4e75668 | 54 | { |
alexan_e | 1:0f1be4e75668 | 55 | uint8_t IIRValue, LSRValue; |
alexan_e | 1:0f1be4e75668 | 56 | uint8_t Dummy = Dummy; |
alexan_e | 1:0f1be4e75668 | 57 | |
alexan_e | 1:0f1be4e75668 | 58 | IIRValue = LPC_USART->IIR; |
alexan_e | 1:0f1be4e75668 | 59 | |
alexan_e | 1:0f1be4e75668 | 60 | IIRValue >>= 1; /* skip pending bit in IIR */ |
alexan_e | 1:0f1be4e75668 | 61 | IIRValue &= 0x07; /* check bit 1~3, interrupt identification */ |
alexan_e | 1:0f1be4e75668 | 62 | if (IIRValue == IIR_RLS) /* Receive Line Status */ |
alexan_e | 1:0f1be4e75668 | 63 | { |
alexan_e | 1:0f1be4e75668 | 64 | LSRValue = LPC_USART->LSR; |
alexan_e | 1:0f1be4e75668 | 65 | /* Receive Line Status */ |
alexan_e | 1:0f1be4e75668 | 66 | if (LSRValue & (LSR_OE | LSR_PE | LSR_FE | LSR_RXFE | LSR_BI)) |
alexan_e | 1:0f1be4e75668 | 67 | { |
alexan_e | 1:0f1be4e75668 | 68 | /* There are errors or break interrupt */ |
alexan_e | 1:0f1be4e75668 | 69 | /* Read LSR will clear the interrupt */ |
alexan_e | 1:0f1be4e75668 | 70 | UARTStatus = LSRValue; |
alexan_e | 1:0f1be4e75668 | 71 | Dummy = LPC_USART->RBR; /* Dummy read on RX to clear |
alexan_e | 1:0f1be4e75668 | 72 | interrupt, then bail out */ |
alexan_e | 1:0f1be4e75668 | 73 | return; |
alexan_e | 1:0f1be4e75668 | 74 | } |
alexan_e | 1:0f1be4e75668 | 75 | if (LSRValue & LSR_RDR) /* Receive Data Ready */ |
alexan_e | 1:0f1be4e75668 | 76 | { |
alexan_e | 1:0f1be4e75668 | 77 | /* If no error on RLS, normal ready, save into the data buffer. */ |
alexan_e | 1:0f1be4e75668 | 78 | /* Note: read RBR will clear the interrupt */ |
alexan_e | 1:0f1be4e75668 | 79 | UARTBuffer[UARTCount++] = LPC_USART->RBR; |
alexan_e | 1:0f1be4e75668 | 80 | if (UARTCount == BUFSIZE) |
alexan_e | 1:0f1be4e75668 | 81 | { |
alexan_e | 1:0f1be4e75668 | 82 | UARTCount = 0; /* buffer overflow */ |
alexan_e | 1:0f1be4e75668 | 83 | } |
alexan_e | 1:0f1be4e75668 | 84 | } |
alexan_e | 1:0f1be4e75668 | 85 | } |
alexan_e | 1:0f1be4e75668 | 86 | else if (IIRValue == IIR_RDA) /* Receive Data Available */ |
alexan_e | 1:0f1be4e75668 | 87 | { |
alexan_e | 1:0f1be4e75668 | 88 | /* Receive Data Available */ |
alexan_e | 1:0f1be4e75668 | 89 | UARTBuffer[UARTCount++] = LPC_USART->RBR; |
alexan_e | 1:0f1be4e75668 | 90 | if (UARTCount == BUFSIZE) |
alexan_e | 1:0f1be4e75668 | 91 | { |
alexan_e | 1:0f1be4e75668 | 92 | UARTCount = 0; /* buffer overflow */ |
alexan_e | 1:0f1be4e75668 | 93 | } |
alexan_e | 1:0f1be4e75668 | 94 | } |
alexan_e | 1:0f1be4e75668 | 95 | else if (IIRValue == IIR_CTI) /* Character timeout indicator */ |
alexan_e | 1:0f1be4e75668 | 96 | { |
alexan_e | 1:0f1be4e75668 | 97 | /* Character Time-out indicator */ |
alexan_e | 1:0f1be4e75668 | 98 | UARTStatus |= 0x100; /* Bit 9 as the CTI error */ |
alexan_e | 1:0f1be4e75668 | 99 | } |
alexan_e | 1:0f1be4e75668 | 100 | else if (IIRValue == IIR_THRE) /* THRE, transmit holding register empty */ |
alexan_e | 1:0f1be4e75668 | 101 | { |
alexan_e | 1:0f1be4e75668 | 102 | /* THRE interrupt */ |
alexan_e | 1:0f1be4e75668 | 103 | LSRValue = LPC_USART->LSR; /* Check status in the LSR to see if |
alexan_e | 1:0f1be4e75668 | 104 | valid data in U0THR or not */ |
alexan_e | 1:0f1be4e75668 | 105 | if (LSRValue & LSR_THRE) |
alexan_e | 1:0f1be4e75668 | 106 | { |
alexan_e | 1:0f1be4e75668 | 107 | UARTTxEmpty = 1; |
alexan_e | 1:0f1be4e75668 | 108 | } |
alexan_e | 1:0f1be4e75668 | 109 | else |
alexan_e | 1:0f1be4e75668 | 110 | { |
alexan_e | 1:0f1be4e75668 | 111 | UARTTxEmpty = 0; |
alexan_e | 1:0f1be4e75668 | 112 | } |
alexan_e | 1:0f1be4e75668 | 113 | } |
alexan_e | 1:0f1be4e75668 | 114 | #if AUTOBAUD_ENABLE |
alexan_e | 1:0f1be4e75668 | 115 | if (LPC_USART->IIR & IIR_ABEO) /* End of Auto baud */ |
alexan_e | 1:0f1be4e75668 | 116 | { |
alexan_e | 1:0f1be4e75668 | 117 | LPC_USART->IER &= ~IIR_ABEO; |
alexan_e | 1:0f1be4e75668 | 118 | /* clear bit ABEOInt in the IIR by set ABEOIntClr in the ACR register */ |
alexan_e | 1:0f1be4e75668 | 119 | LPC_USART->ACR |= IIR_ABEO; |
alexan_e | 1:0f1be4e75668 | 120 | UARTAutoBaud = 1; |
alexan_e | 1:0f1be4e75668 | 121 | } |
alexan_e | 1:0f1be4e75668 | 122 | else if (LPC_USART->IIR & IIR_ABTO)/* Auto baud time out */ |
alexan_e | 1:0f1be4e75668 | 123 | { |
alexan_e | 1:0f1be4e75668 | 124 | LPC_USART->IER &= ~IIR_ABTO; |
alexan_e | 1:0f1be4e75668 | 125 | AutoBaudTimeout = 1; |
alexan_e | 1:0f1be4e75668 | 126 | /* clear bit ABTOInt in the IIR by set ABTOIntClr in the ACR register */ |
alexan_e | 1:0f1be4e75668 | 127 | LPC_USART->ACR |= IIR_ABTO; |
alexan_e | 1:0f1be4e75668 | 128 | } |
alexan_e | 1:0f1be4e75668 | 129 | #endif |
alexan_e | 1:0f1be4e75668 | 130 | return; |
alexan_e | 1:0f1be4e75668 | 131 | } |
alexan_e | 1:0f1be4e75668 | 132 | |
alexan_e | 1:0f1be4e75668 | 133 | #if MODEM_TEST |
alexan_e | 1:0f1be4e75668 | 134 | /***************************************************************************** |
alexan_e | 1:0f1be4e75668 | 135 | ** Function name: ModemInit |
alexan_e | 1:0f1be4e75668 | 136 | ** |
alexan_e | 1:0f1be4e75668 | 137 | ** Descriptions: Initialize UART0 port as modem, setup pin select. |
alexan_e | 1:0f1be4e75668 | 138 | ** |
alexan_e | 1:0f1be4e75668 | 139 | ** parameters: None |
alexan_e | 1:0f1be4e75668 | 140 | ** Returned value: None |
alexan_e | 1:0f1be4e75668 | 141 | ** |
alexan_e | 1:0f1be4e75668 | 142 | *****************************************************************************/ |
alexan_e | 1:0f1be4e75668 | 143 | void ModemInit( void ) |
alexan_e | 1:0f1be4e75668 | 144 | { |
alexan_e | 1:0f1be4e75668 | 145 | |
alexan_e | 1:0f1be4e75668 | 146 | LPC_IOCON->PIO0_7 &= ~0x07; /* UART I/O config */ |
alexan_e | 1:0f1be4e75668 | 147 | LPC_IOCON->PIO0_7 |= 0x01; /* UART CTS */ |
alexan_e | 1:0f1be4e75668 | 148 | LPC_IOCON->PIO0_17 &= ~0x07; /* UART I/O config */ |
alexan_e | 1:0f1be4e75668 | 149 | LPC_IOCON->PIO0_17 |= 0x01; /* UART RTS */ |
alexan_e | 1:0f1be4e75668 | 150 | #if 1 |
alexan_e | 1:0f1be4e75668 | 151 | LPC_IOCON->PIO1_13 &= ~0x07; /* UART I/O config */ |
alexan_e | 1:0f1be4e75668 | 152 | LPC_IOCON->PIO1_13 |= 0x01; /* UART DTR */ |
alexan_e | 1:0f1be4e75668 | 153 | LPC_IOCON->PIO1_14 &= ~0x07; /* UART I/O config */ |
alexan_e | 1:0f1be4e75668 | 154 | LPC_IOCON->PIO1_14 |= 0x01; /* UART DSR */ |
alexan_e | 1:0f1be4e75668 | 155 | LPC_IOCON->PIO1_15 &= ~0x07; /* UART I/O config */ |
alexan_e | 1:0f1be4e75668 | 156 | LPC_IOCON->PIO1_15 |= 0x01; /* UART DCD */ |
alexan_e | 1:0f1be4e75668 | 157 | LPC_IOCON->PIO1_16 &= ~0x07; /* UART I/O config */ |
alexan_e | 1:0f1be4e75668 | 158 | LPC_IOCON->PIO1_16 |= 0x01; /* UART RI */ |
alexan_e | 1:0f1be4e75668 | 159 | |
alexan_e | 1:0f1be4e75668 | 160 | #else |
alexan_e | 1:0f1be4e75668 | 161 | LPC_IOCON->PIO1_19 &= ~0x07; /* UART I/O config */ |
alexan_e | 1:0f1be4e75668 | 162 | LPC_IOCON->PIO1_19 |= 0x01; /* UART DTR */ |
alexan_e | 1:0f1be4e75668 | 163 | LPC_IOCON->PIO1_20 &= ~0x07; /* UART I/O config */ |
alexan_e | 1:0f1be4e75668 | 164 | LPC_IOCON->PIO1_20 |= 0x01; /* UART DSR */ |
alexan_e | 1:0f1be4e75668 | 165 | LPC_IOCON->PIO1_21 &= ~0x07; /* UART I/O config */ |
alexan_e | 1:0f1be4e75668 | 166 | LPC_IOCON->PIO1_21 |= 0x01; /* UART DCD */ |
alexan_e | 1:0f1be4e75668 | 167 | LPC_IOCON->PIO1_22 &= ~0x07; /* UART I/O config */ |
alexan_e | 1:0f1be4e75668 | 168 | LPC_IOCON->PIO1_22 |= 0x01; /* UART RI */ |
alexan_e | 1:0f1be4e75668 | 169 | #endif |
alexan_e | 1:0f1be4e75668 | 170 | LPC_USART->MCR = 0xC0; /* Enable Auto RTS and Auto CTS. */ |
alexan_e | 1:0f1be4e75668 | 171 | return; |
alexan_e | 1:0f1be4e75668 | 172 | } |
alexan_e | 1:0f1be4e75668 | 173 | #endif |
alexan_e | 1:0f1be4e75668 | 174 | |
alexan_e | 1:0f1be4e75668 | 175 | /*********************************************************************** |
alexan_e | 1:0f1be4e75668 | 176 | * |
alexan_e | 1:0f1be4e75668 | 177 | * Function: uart_set_divisors |
alexan_e | 1:0f1be4e75668 | 178 | * |
alexan_e | 1:0f1be4e75668 | 179 | * Purpose: Determines best dividers to get a target clock rate |
alexan_e | 1:0f1be4e75668 | 180 | * |
alexan_e | 1:0f1be4e75668 | 181 | * Processing: |
alexan_e | 1:0f1be4e75668 | 182 | * See function. |
alexan_e | 1:0f1be4e75668 | 183 | * |
alexan_e | 1:0f1be4e75668 | 184 | * Parameters: |
alexan_e | 1:0f1be4e75668 | 185 | * UARTClk : UART clock |
alexan_e | 1:0f1be4e75668 | 186 | * baudrate : Desired UART baud rate |
alexan_e | 1:0f1be4e75668 | 187 | * |
alexan_e | 1:0f1be4e75668 | 188 | * Outputs: |
alexan_e | 1:0f1be4e75668 | 189 | * baudrate : Sets the estimated buadrate value in DLL, DLM, and FDR. |
alexan_e | 1:0f1be4e75668 | 190 | * |
alexan_e | 1:0f1be4e75668 | 191 | * Returns: Error status. |
alexan_e | 1:0f1be4e75668 | 192 | * |
alexan_e | 1:0f1be4e75668 | 193 | * Notes: None |
alexan_e | 1:0f1be4e75668 | 194 | * |
alexan_e | 1:0f1be4e75668 | 195 | **********************************************************************/ |
alexan_e | 1:0f1be4e75668 | 196 | uint32_t uart_set_divisors(uint32_t UARTClk, uint32_t baudrate) |
alexan_e | 1:0f1be4e75668 | 197 | { |
alexan_e | 1:0f1be4e75668 | 198 | uint32_t uClk; |
alexan_e | 1:0f1be4e75668 | 199 | uint32_t calcBaudrate = 0; |
alexan_e | 1:0f1be4e75668 | 200 | uint32_t temp = 0; |
alexan_e | 1:0f1be4e75668 | 201 | |
alexan_e | 1:0f1be4e75668 | 202 | uint32_t mulFracDiv, dividerAddFracDiv; |
alexan_e | 1:0f1be4e75668 | 203 | uint32_t diviser = 0 ; |
alexan_e | 1:0f1be4e75668 | 204 | uint32_t mulFracDivOptimal = 1; |
alexan_e | 1:0f1be4e75668 | 205 | uint32_t dividerAddOptimal = 0; |
alexan_e | 1:0f1be4e75668 | 206 | uint32_t diviserOptimal = 0; |
alexan_e | 1:0f1be4e75668 | 207 | |
alexan_e | 1:0f1be4e75668 | 208 | uint32_t relativeError = 0; |
alexan_e | 1:0f1be4e75668 | 209 | uint32_t relativeOptimalError = 100000; |
alexan_e | 1:0f1be4e75668 | 210 | |
alexan_e | 1:0f1be4e75668 | 211 | /* get UART block clock */ |
alexan_e | 1:0f1be4e75668 | 212 | uClk = UARTClk >> 4; /* div by 16 */ |
alexan_e | 1:0f1be4e75668 | 213 | /* In the Uart IP block, baud rate is calculated using FDR and DLL-DLM registers |
alexan_e | 1:0f1be4e75668 | 214 | * The formula is : |
alexan_e | 1:0f1be4e75668 | 215 | * BaudRate= uClk * (mulFracDiv/(mulFracDiv+dividerAddFracDiv) / (16 * (DLL) |
alexan_e | 1:0f1be4e75668 | 216 | * It involves floating point calculations. That's the reason the formulae are adjusted with |
alexan_e | 1:0f1be4e75668 | 217 | * Multiply and divide method.*/ |
alexan_e | 1:0f1be4e75668 | 218 | /* The value of mulFracDiv and dividerAddFracDiv should comply to the following expressions: |
alexan_e | 1:0f1be4e75668 | 219 | * 0 < mulFracDiv <= 15, 0 <= dividerAddFracDiv <= 15 */ |
alexan_e | 1:0f1be4e75668 | 220 | for (mulFracDiv = 1; mulFracDiv <= 15; mulFracDiv++) |
alexan_e | 1:0f1be4e75668 | 221 | { |
alexan_e | 1:0f1be4e75668 | 222 | for (dividerAddFracDiv = 0; dividerAddFracDiv <= 15; dividerAddFracDiv++) |
alexan_e | 1:0f1be4e75668 | 223 | { |
alexan_e | 1:0f1be4e75668 | 224 | temp = (mulFracDiv * uClk) / ((mulFracDiv + dividerAddFracDiv)); |
alexan_e | 1:0f1be4e75668 | 225 | diviser = temp / baudrate; |
alexan_e | 1:0f1be4e75668 | 226 | if ((temp % baudrate) > (baudrate / 2)) |
alexan_e | 1:0f1be4e75668 | 227 | diviser++; |
alexan_e | 1:0f1be4e75668 | 228 | |
alexan_e | 1:0f1be4e75668 | 229 | if (diviser > 2 && diviser < 65536) |
alexan_e | 1:0f1be4e75668 | 230 | { |
alexan_e | 1:0f1be4e75668 | 231 | calcBaudrate = temp / diviser; |
alexan_e | 1:0f1be4e75668 | 232 | |
alexan_e | 1:0f1be4e75668 | 233 | if (calcBaudrate <= baudrate) |
alexan_e | 1:0f1be4e75668 | 234 | relativeError = baudrate - calcBaudrate; |
alexan_e | 1:0f1be4e75668 | 235 | else |
alexan_e | 1:0f1be4e75668 | 236 | relativeError = calcBaudrate - baudrate; |
alexan_e | 1:0f1be4e75668 | 237 | |
alexan_e | 1:0f1be4e75668 | 238 | if ((relativeError < relativeOptimalError)) |
alexan_e | 1:0f1be4e75668 | 239 | { |
alexan_e | 1:0f1be4e75668 | 240 | mulFracDivOptimal = mulFracDiv ; |
alexan_e | 1:0f1be4e75668 | 241 | dividerAddOptimal = dividerAddFracDiv; |
alexan_e | 1:0f1be4e75668 | 242 | diviserOptimal = diviser; |
alexan_e | 1:0f1be4e75668 | 243 | relativeOptimalError = relativeError; |
alexan_e | 1:0f1be4e75668 | 244 | if (relativeError == 0) |
alexan_e | 1:0f1be4e75668 | 245 | break; |
alexan_e | 1:0f1be4e75668 | 246 | } |
alexan_e | 1:0f1be4e75668 | 247 | } /* End of if */ |
alexan_e | 1:0f1be4e75668 | 248 | } /* end of inner for loop */ |
alexan_e | 1:0f1be4e75668 | 249 | if (relativeError == 0) |
alexan_e | 1:0f1be4e75668 | 250 | break; |
alexan_e | 1:0f1be4e75668 | 251 | } /* end of outer for loop */ |
alexan_e | 1:0f1be4e75668 | 252 | |
alexan_e | 1:0f1be4e75668 | 253 | if (relativeOptimalError < (baudrate / 30)) |
alexan_e | 1:0f1be4e75668 | 254 | { |
alexan_e | 1:0f1be4e75668 | 255 | /* Set the `Divisor Latch Access Bit` and enable so the DLL/DLM access*/ |
alexan_e | 1:0f1be4e75668 | 256 | /* Initialise the `Divisor latch LSB` and `Divisor latch MSB` registers */ |
alexan_e | 1:0f1be4e75668 | 257 | LPC_USART->DLM = (diviserOptimal >> 8) & 0xFF; |
alexan_e | 1:0f1be4e75668 | 258 | LPC_USART->DLL = diviserOptimal & 0xFF; |
alexan_e | 1:0f1be4e75668 | 259 | |
alexan_e | 1:0f1be4e75668 | 260 | /* Initialise the Fractional Divider Register */ |
alexan_e | 1:0f1be4e75668 | 261 | LPC_USART->FDR = ((mulFracDivOptimal & 0xF) << 4) | (dividerAddOptimal & 0xF); |
alexan_e | 1:0f1be4e75668 | 262 | return( TRUE ); |
alexan_e | 1:0f1be4e75668 | 263 | } |
alexan_e | 1:0f1be4e75668 | 264 | return ( FALSE ); |
alexan_e | 1:0f1be4e75668 | 265 | } |
alexan_e | 1:0f1be4e75668 | 266 | |
alexan_e | 1:0f1be4e75668 | 267 | /***************************************************************************** |
alexan_e | 1:0f1be4e75668 | 268 | ** Function name: UARTInit |
alexan_e | 1:0f1be4e75668 | 269 | ** |
alexan_e | 1:0f1be4e75668 | 270 | ** Descriptions: Initialize UART0 port, setup pin select, |
alexan_e | 1:0f1be4e75668 | 271 | ** clock, parity, stop bits, FIFO, etc. |
alexan_e | 1:0f1be4e75668 | 272 | ** |
alexan_e | 1:0f1be4e75668 | 273 | ** parameters: UART baudrate |
alexan_e | 1:0f1be4e75668 | 274 | ** Returned value: None |
alexan_e | 1:0f1be4e75668 | 275 | ** |
alexan_e | 1:0f1be4e75668 | 276 | *****************************************************************************/ |
alexan_e | 1:0f1be4e75668 | 277 | void UARTInit(uint32_t baudrate) |
alexan_e | 1:0f1be4e75668 | 278 | { |
alexan_e | 1:0f1be4e75668 | 279 | #if !AUTOBAUD_ENABLE |
alexan_e | 1:0f1be4e75668 | 280 | uint32_t Fdiv; |
alexan_e | 1:0f1be4e75668 | 281 | #endif |
alexan_e | 1:0f1be4e75668 | 282 | volatile uint32_t regVal; |
alexan_e | 1:0f1be4e75668 | 283 | |
alexan_e | 1:0f1be4e75668 | 284 | UARTTxEmpty = 1; |
alexan_e | 1:0f1be4e75668 | 285 | UARTCount = 0; |
alexan_e | 1:0f1be4e75668 | 286 | |
alexan_e | 1:0f1be4e75668 | 287 | NVIC_DisableIRQ(UART_IRQn); |
alexan_e | 1:0f1be4e75668 | 288 | /* Select only one location from below. */ |
alexan_e | 1:0f1be4e75668 | 289 | #if 1 |
alexan_e | 1:0f1be4e75668 | 290 | LPC_IOCON->PIO0_18 &= ~0x07; /* UART I/O config */ |
alexan_e | 1:0f1be4e75668 | 291 | LPC_IOCON->PIO0_18 |= 0x01; /* UART RXD */ |
alexan_e | 1:0f1be4e75668 | 292 | LPC_IOCON->PIO0_19 &= ~0x07; |
alexan_e | 1:0f1be4e75668 | 293 | LPC_IOCON->PIO0_19 |= 0x01; /* UART TXD */ |
alexan_e | 1:0f1be4e75668 | 294 | #endif |
alexan_e | 1:0f1be4e75668 | 295 | #if 0 |
alexan_e | 1:0f1be4e75668 | 296 | LPC_IOCON->PIO1_14 &= ~0x07; /* UART I/O config */ |
alexan_e | 1:0f1be4e75668 | 297 | LPC_IOCON->PIO1_14 |= 0x03; /* UART RXD */ |
alexan_e | 1:0f1be4e75668 | 298 | LPC_IOCON->PIO1_13 &= ~0x07; |
alexan_e | 1:0f1be4e75668 | 299 | LPC_IOCON->PIO1_13 |= 0x03; /* UART TXD */ |
alexan_e | 1:0f1be4e75668 | 300 | #endif |
alexan_e | 1:0f1be4e75668 | 301 | #if 0 |
alexan_e | 1:0f1be4e75668 | 302 | LPC_IOCON->PIO1_17 &= ~0x07; /* UART I/O config */ |
alexan_e | 1:0f1be4e75668 | 303 | LPC_IOCON->PIO1_17 |= 0x02; /* UART RXD */ |
alexan_e | 1:0f1be4e75668 | 304 | LPC_IOCON->PIO1_18 &= ~0x07; |
alexan_e | 1:0f1be4e75668 | 305 | LPC_IOCON->PIO1_18 |= 0x02; /* UART TXD */ |
alexan_e | 1:0f1be4e75668 | 306 | #endif |
alexan_e | 1:0f1be4e75668 | 307 | #if 0 |
alexan_e | 1:0f1be4e75668 | 308 | LPC_IOCON->PIO1_26 &= ~0x07; /* UART I/O config */ |
alexan_e | 1:0f1be4e75668 | 309 | LPC_IOCON->PIO1_26 |= 0x02; /* UART RXD */ |
alexan_e | 1:0f1be4e75668 | 310 | LPC_IOCON->PIO1_27 &= ~0x07; |
alexan_e | 1:0f1be4e75668 | 311 | LPC_IOCON->PIO1_27 |= 0x02; /* UART TXD */ |
alexan_e | 1:0f1be4e75668 | 312 | #endif |
alexan_e | 1:0f1be4e75668 | 313 | |
alexan_e | 1:0f1be4e75668 | 314 | /* Enable UART clock */ |
alexan_e | 1:0f1be4e75668 | 315 | LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12); |
alexan_e | 1:0f1be4e75668 | 316 | LPC_SYSCON->UARTCLKDIV = 0x1; /* divided by 1 */ |
alexan_e | 1:0f1be4e75668 | 317 | |
alexan_e | 1:0f1be4e75668 | 318 | LPC_USART->LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */ |
alexan_e | 1:0f1be4e75668 | 319 | #if !AUTOBAUD_ENABLE |
alexan_e | 1:0f1be4e75668 | 320 | #if FDR_CALIBRATION |
alexan_e | 1:0f1be4e75668 | 321 | if ( uart_set_divisors(SystemCoreClock/LPC_SYSCON->UARTCLKDIV, baudrate) != TRUE ) |
alexan_e | 1:0f1be4e75668 | 322 | { |
alexan_e | 1:0f1be4e75668 | 323 | Fdiv = ((SystemCoreClock/LPC_SYSCON->UARTCLKDIV)/16)/baudrate ; /*baud rate */ |
alexan_e | 1:0f1be4e75668 | 324 | LPC_USART->DLM = Fdiv / 256; |
alexan_e | 1:0f1be4e75668 | 325 | LPC_USART->DLL = Fdiv % 256; |
alexan_e | 1:0f1be4e75668 | 326 | LPC_USART->FDR = 0x10; /* Default */ |
alexan_e | 1:0f1be4e75668 | 327 | } |
alexan_e | 1:0f1be4e75668 | 328 | #else |
alexan_e | 1:0f1be4e75668 | 329 | Fdiv = ((SystemCoreClock/LPC_SYSCON->UARTCLKDIV)/16)/baudrate ; /*baud rate */ |
alexan_e | 1:0f1be4e75668 | 330 | LPC_USART->DLM = Fdiv / 256; |
alexan_e | 1:0f1be4e75668 | 331 | LPC_USART->DLL = Fdiv % 256; |
alexan_e | 1:0f1be4e75668 | 332 | LPC_USART->FDR = 0x10; /* Default */ |
alexan_e | 1:0f1be4e75668 | 333 | #endif |
alexan_e | 1:0f1be4e75668 | 334 | #endif |
alexan_e | 1:0f1be4e75668 | 335 | LPC_USART->LCR = 0x03; /* DLAB = 0 */ |
alexan_e | 1:0f1be4e75668 | 336 | LPC_USART->FCR = 0x07; /* Enable and reset TX and RX FIFO. */ |
alexan_e | 1:0f1be4e75668 | 337 | |
alexan_e | 1:0f1be4e75668 | 338 | /* Read to clear the line status. */ |
alexan_e | 1:0f1be4e75668 | 339 | regVal = LPC_USART->LSR; |
alexan_e | 1:0f1be4e75668 | 340 | |
alexan_e | 1:0f1be4e75668 | 341 | /* Ensure a clean start, no data in either TX or RX FIFO. */ |
alexan_e | 1:0f1be4e75668 | 342 | while (( LPC_USART->LSR & (LSR_THRE|LSR_TEMT)) != (LSR_THRE|LSR_TEMT) ); |
alexan_e | 1:0f1be4e75668 | 343 | while ( LPC_USART->LSR & LSR_RDR ) |
alexan_e | 1:0f1be4e75668 | 344 | { |
alexan_e | 1:0f1be4e75668 | 345 | regVal = LPC_USART->RBR; /* Dump data from RX FIFO */ |
alexan_e | 1:0f1be4e75668 | 346 | } |
alexan_e | 1:0f1be4e75668 | 347 | |
alexan_e | 1:0f1be4e75668 | 348 | /* Enable the UART Interrupt */ |
alexan_e | 1:0f1be4e75668 | 349 | NVIC_EnableIRQ(UART_IRQn); |
alexan_e | 1:0f1be4e75668 | 350 | |
alexan_e | 1:0f1be4e75668 | 351 | #if TX_INTERRUPT |
alexan_e | 1:0f1be4e75668 | 352 | LPC_USART->IER = IER_RBR | IER_THRE | IER_RLS; /* Enable UART interrupt */ |
alexan_e | 1:0f1be4e75668 | 353 | #else |
alexan_e | 1:0f1be4e75668 | 354 | LPC_USART->IER = IER_RBR | IER_RLS; /* Enable UART interrupt */ |
alexan_e | 1:0f1be4e75668 | 355 | #endif |
alexan_e | 1:0f1be4e75668 | 356 | #if AUTOBAUD_ENABLE |
alexan_e | 1:0f1be4e75668 | 357 | LPC_USART->IER |= IER_ABEO | IER_ABTO; |
alexan_e | 1:0f1be4e75668 | 358 | #endif |
alexan_e | 1:0f1be4e75668 | 359 | return; |
alexan_e | 1:0f1be4e75668 | 360 | } |
alexan_e | 1:0f1be4e75668 | 361 | |
alexan_e | 1:0f1be4e75668 | 362 | /***************************************************************************** |
alexan_e | 1:0f1be4e75668 | 363 | ** Function name: UARTSend |
alexan_e | 1:0f1be4e75668 | 364 | ** |
alexan_e | 1:0f1be4e75668 | 365 | ** Descriptions: Send a block of data to the UART 0 port based |
alexan_e | 1:0f1be4e75668 | 366 | ** on the data length |
alexan_e | 1:0f1be4e75668 | 367 | ** |
alexan_e | 1:0f1be4e75668 | 368 | ** parameters: buffer pointer, and data length |
alexan_e | 1:0f1be4e75668 | 369 | ** Returned value: None |
alexan_e | 1:0f1be4e75668 | 370 | ** |
alexan_e | 1:0f1be4e75668 | 371 | *****************************************************************************/ |
alexan_e | 1:0f1be4e75668 | 372 | void UARTSend(uint8_t *BufferPtr, uint32_t Length) |
alexan_e | 1:0f1be4e75668 | 373 | { |
alexan_e | 1:0f1be4e75668 | 374 | |
alexan_e | 1:0f1be4e75668 | 375 | while ( Length != 0 ) |
alexan_e | 1:0f1be4e75668 | 376 | { |
alexan_e | 1:0f1be4e75668 | 377 | /* THRE status, contain valid data */ |
alexan_e | 1:0f1be4e75668 | 378 | #if !TX_INTERRUPT |
alexan_e | 1:0f1be4e75668 | 379 | while ( !(LPC_USART->LSR & LSR_THRE) ); |
alexan_e | 1:0f1be4e75668 | 380 | LPC_USART->THR = *BufferPtr; |
alexan_e | 1:0f1be4e75668 | 381 | #else |
alexan_e | 1:0f1be4e75668 | 382 | /* Below flag is set inside the interrupt handler when THRE occurs. */ |
alexan_e | 1:0f1be4e75668 | 383 | while ( !(UARTTxEmpty & 0x01) ); |
alexan_e | 1:0f1be4e75668 | 384 | LPC_USART->THR = *BufferPtr; |
alexan_e | 1:0f1be4e75668 | 385 | UARTTxEmpty = 0; /* not empty in the THR until it shifts out */ |
alexan_e | 1:0f1be4e75668 | 386 | #endif |
alexan_e | 1:0f1be4e75668 | 387 | BufferPtr++; |
alexan_e | 1:0f1be4e75668 | 388 | Length--; |
alexan_e | 1:0f1be4e75668 | 389 | } |
alexan_e | 1:0f1be4e75668 | 390 | return; |
alexan_e | 1:0f1be4e75668 | 391 | } |
alexan_e | 1:0f1be4e75668 | 392 | |
alexan_e | 1:0f1be4e75668 | 393 | /***************************************************************************** |
alexan_e | 1:0f1be4e75668 | 394 | ** Function name: print_string |
alexan_e | 1:0f1be4e75668 | 395 | ** |
alexan_e | 1:0f1be4e75668 | 396 | ** Descriptions: print out string on the terminal |
alexan_e | 1:0f1be4e75668 | 397 | ** |
alexan_e | 1:0f1be4e75668 | 398 | ** parameters: pointer to the string end with NULL char. |
alexan_e | 1:0f1be4e75668 | 399 | ** Returned value: none. |
alexan_e | 1:0f1be4e75668 | 400 | ** |
alexan_e | 1:0f1be4e75668 | 401 | *****************************************************************************/ |
alexan_e | 1:0f1be4e75668 | 402 | void print_string( uint8_t *str_ptr ) |
alexan_e | 1:0f1be4e75668 | 403 | { |
alexan_e | 1:0f1be4e75668 | 404 | while(*str_ptr != 0x00) |
alexan_e | 1:0f1be4e75668 | 405 | { |
alexan_e | 1:0f1be4e75668 | 406 | while((LPC_USART->LSR & 0x60) != 0x60); |
alexan_e | 1:0f1be4e75668 | 407 | LPC_USART->THR = *str_ptr; |
alexan_e | 1:0f1be4e75668 | 408 | str_ptr++; |
alexan_e | 1:0f1be4e75668 | 409 | } |
alexan_e | 1:0f1be4e75668 | 410 | return; |
alexan_e | 1:0f1be4e75668 | 411 | } |
alexan_e | 1:0f1be4e75668 | 412 | |
alexan_e | 1:0f1be4e75668 | 413 | /***************************************************************************** |
alexan_e | 1:0f1be4e75668 | 414 | ** Function name: get_key |
alexan_e | 1:0f1be4e75668 | 415 | ** |
alexan_e | 1:0f1be4e75668 | 416 | ** Descriptions: Get a character from the terminal |
alexan_e | 1:0f1be4e75668 | 417 | ** |
alexan_e | 1:0f1be4e75668 | 418 | ** parameters: None |
alexan_e | 1:0f1be4e75668 | 419 | ** Returned value: character, zero is none. |
alexan_e | 1:0f1be4e75668 | 420 | ** |
alexan_e | 1:0f1be4e75668 | 421 | *****************************************************************************/ |
alexan_e | 1:0f1be4e75668 | 422 | uint8_t get_key( void ) |
alexan_e | 1:0f1be4e75668 | 423 | { |
alexan_e | 1:0f1be4e75668 | 424 | uint8_t dummy; |
alexan_e | 1:0f1be4e75668 | 425 | |
alexan_e | 1:0f1be4e75668 | 426 | while ( !(LPC_USART->LSR & 0x01) ); |
alexan_e | 1:0f1be4e75668 | 427 | dummy = LPC_USART->RBR; |
alexan_e | 1:0f1be4e75668 | 428 | if ((dummy>=65) && (dummy<=90)) |
alexan_e | 1:0f1be4e75668 | 429 | { |
alexan_e | 1:0f1be4e75668 | 430 | /* convert capital to non-capital character, A2a, B2b, C2c. */ |
alexan_e | 1:0f1be4e75668 | 431 | dummy +=32; |
alexan_e | 1:0f1be4e75668 | 432 | } |
alexan_e | 1:0f1be4e75668 | 433 | /* echo */ |
alexan_e | 1:0f1be4e75668 | 434 | LPC_USART->THR = dummy; |
alexan_e | 1:0f1be4e75668 | 435 | return(dummy); |
alexan_e | 1:0f1be4e75668 | 436 | } |
alexan_e | 1:0f1be4e75668 | 437 | |
alexan_e | 1:0f1be4e75668 | 438 | /****************************************************************************** |
alexan_e | 1:0f1be4e75668 | 439 | ** End Of File |
alexan_e | 1:0f1be4e75668 | 440 | ******************************************************************************/ |