These are the examples provided for [[/users/frank26080115/libraries/LPC1700CMSIS_Lib/]] Note, the entire "program" is not compilable!
USBDEV/USBCDC/serial.c@0:bf7b9fba3924, 2011-03-20 (annotated)
- Committer:
- frank26080115
- Date:
- Sun Mar 20 05:38:56 2011 +0000
- Revision:
- 0:bf7b9fba3924
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
frank26080115 | 0:bf7b9fba3924 | 1 | /*---------------------------------------------------------------------------- |
frank26080115 | 0:bf7b9fba3924 | 2 | * Name: serial.c |
frank26080115 | 0:bf7b9fba3924 | 3 | * Purpose: serial port handling for LPC17xx |
frank26080115 | 0:bf7b9fba3924 | 4 | * Version: V1.20 |
frank26080115 | 0:bf7b9fba3924 | 5 | *---------------------------------------------------------------------------- |
frank26080115 | 0:bf7b9fba3924 | 6 | * This software is supplied "AS IS" without any warranties, express, |
frank26080115 | 0:bf7b9fba3924 | 7 | * implied or statutory, including but not limited to the implied |
frank26080115 | 0:bf7b9fba3924 | 8 | * warranties of fitness for purpose, satisfactory quality and |
frank26080115 | 0:bf7b9fba3924 | 9 | * noninfringement. Keil extends you a royalty-free right to reproduce |
frank26080115 | 0:bf7b9fba3924 | 10 | * and distribute executable files created using this software for use |
frank26080115 | 0:bf7b9fba3924 | 11 | * on NXP Semiconductors LPC microcontroller devices only. Nothing else |
frank26080115 | 0:bf7b9fba3924 | 12 | * gives you the right to use this software. |
frank26080115 | 0:bf7b9fba3924 | 13 | * |
frank26080115 | 0:bf7b9fba3924 | 14 | * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. |
frank26080115 | 0:bf7b9fba3924 | 15 | *---------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 16 | #include "LPC17xx.h" // LPC17xx definitions |
frank26080115 | 0:bf7b9fba3924 | 17 | #include "lpc_types.h" |
frank26080115 | 0:bf7b9fba3924 | 18 | #include "serial.h" |
frank26080115 | 0:bf7b9fba3924 | 19 | |
frank26080115 | 0:bf7b9fba3924 | 20 | |
frank26080115 | 0:bf7b9fba3924 | 21 | /*---------------------------------------------------------------------------- |
frank26080115 | 0:bf7b9fba3924 | 22 | Defines for ring buffers |
frank26080115 | 0:bf7b9fba3924 | 23 | *---------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 24 | #define SER_BUF_SIZE (128) // serial buffer in bytes (power 2) |
frank26080115 | 0:bf7b9fba3924 | 25 | #define SER_BUF_MASK (SER_BUF_SIZE-1ul) // buffer size mask |
frank26080115 | 0:bf7b9fba3924 | 26 | |
frank26080115 | 0:bf7b9fba3924 | 27 | /* Buffer read / write macros */ |
frank26080115 | 0:bf7b9fba3924 | 28 | #define SER_BUF_RESET(serBuf) (serBuf.rdIdx = serBuf.wrIdx = 0) |
frank26080115 | 0:bf7b9fba3924 | 29 | #define SER_BUF_WR(serBuf, dataIn) (serBuf.data[SER_BUF_MASK & serBuf.wrIdx++] = (dataIn)) |
frank26080115 | 0:bf7b9fba3924 | 30 | #define SER_BUF_RD(serBuf) (serBuf.data[SER_BUF_MASK & serBuf.rdIdx++]) |
frank26080115 | 0:bf7b9fba3924 | 31 | #define SER_BUF_EMPTY(serBuf) (serBuf.rdIdx == serBuf.wrIdx) |
frank26080115 | 0:bf7b9fba3924 | 32 | #define SER_BUF_FULL(serBuf) (serBuf.rdIdx == serBuf.wrIdx+1) |
frank26080115 | 0:bf7b9fba3924 | 33 | #define SER_BUF_COUNT(serBuf) (SER_BUF_MASK & (serBuf.wrIdx - serBuf.rdIdx)) |
frank26080115 | 0:bf7b9fba3924 | 34 | |
frank26080115 | 0:bf7b9fba3924 | 35 | // buffer type |
frank26080115 | 0:bf7b9fba3924 | 36 | typedef struct __SER_BUF_T { |
frank26080115 | 0:bf7b9fba3924 | 37 | unsigned char data[SER_BUF_SIZE]; |
frank26080115 | 0:bf7b9fba3924 | 38 | unsigned int wrIdx; |
frank26080115 | 0:bf7b9fba3924 | 39 | unsigned int rdIdx; |
frank26080115 | 0:bf7b9fba3924 | 40 | } SER_BUF_T; |
frank26080115 | 0:bf7b9fba3924 | 41 | |
frank26080115 | 0:bf7b9fba3924 | 42 | unsigned long ser_txRestart; // NZ if TX restart is required |
frank26080115 | 0:bf7b9fba3924 | 43 | unsigned short ser_lineState; // ((msr << 8) | (lsr)) |
frank26080115 | 0:bf7b9fba3924 | 44 | SER_BUF_T ser_out; // Serial data buffers |
frank26080115 | 0:bf7b9fba3924 | 45 | SER_BUF_T ser_in; |
frank26080115 | 0:bf7b9fba3924 | 46 | |
frank26080115 | 0:bf7b9fba3924 | 47 | /*---------------------------------------------------------------------------- |
frank26080115 | 0:bf7b9fba3924 | 48 | open the serial port |
frank26080115 | 0:bf7b9fba3924 | 49 | *---------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 50 | void ser_OpenPort (char portNum) { |
frank26080115 | 0:bf7b9fba3924 | 51 | |
frank26080115 | 0:bf7b9fba3924 | 52 | if ( portNum == 0 ) |
frank26080115 | 0:bf7b9fba3924 | 53 | { |
frank26080115 | 0:bf7b9fba3924 | 54 | /* Port 0 */ |
frank26080115 | 0:bf7b9fba3924 | 55 | NVIC_DisableIRQ(UART0_IRQn); |
frank26080115 | 0:bf7b9fba3924 | 56 | LPC_PINCON->PINSEL0 &= ~0x000000F0; |
frank26080115 | 0:bf7b9fba3924 | 57 | LPC_PINCON->PINSEL0 |= 0x00000050; /* RxD0 is P0.3 and TxD0 is P0.2 */ |
frank26080115 | 0:bf7b9fba3924 | 58 | } |
frank26080115 | 0:bf7b9fba3924 | 59 | else |
frank26080115 | 0:bf7b9fba3924 | 60 | { |
frank26080115 | 0:bf7b9fba3924 | 61 | /* Port 1 */ |
frank26080115 | 0:bf7b9fba3924 | 62 | NVIC_DisableIRQ(UART1_IRQn); |
frank26080115 | 0:bf7b9fba3924 | 63 | LPC_PINCON->PINSEL4 &= ~0x0000000F; |
frank26080115 | 0:bf7b9fba3924 | 64 | LPC_PINCON->PINSEL4 |= 0x0000000A; /* Enable RxD1 P2.1, TxD1 P2.0 */ |
frank26080115 | 0:bf7b9fba3924 | 65 | } |
frank26080115 | 0:bf7b9fba3924 | 66 | return; |
frank26080115 | 0:bf7b9fba3924 | 67 | } |
frank26080115 | 0:bf7b9fba3924 | 68 | |
frank26080115 | 0:bf7b9fba3924 | 69 | /*---------------------------------------------------------------------------- |
frank26080115 | 0:bf7b9fba3924 | 70 | close the serial port |
frank26080115 | 0:bf7b9fba3924 | 71 | *---------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 72 | void ser_ClosePort (char portNum ) { |
frank26080115 | 0:bf7b9fba3924 | 73 | if ( portNum == 0 ) |
frank26080115 | 0:bf7b9fba3924 | 74 | { |
frank26080115 | 0:bf7b9fba3924 | 75 | /* POrt 0 */ |
frank26080115 | 0:bf7b9fba3924 | 76 | LPC_PINCON->PINSEL0 &= ~0x000000F0; |
frank26080115 | 0:bf7b9fba3924 | 77 | /* Disable the interrupt in the VIC and UART controllers */ |
frank26080115 | 0:bf7b9fba3924 | 78 | LPC_UART0->IER = 0; |
frank26080115 | 0:bf7b9fba3924 | 79 | NVIC_DisableIRQ(UART0_IRQn); |
frank26080115 | 0:bf7b9fba3924 | 80 | } |
frank26080115 | 0:bf7b9fba3924 | 81 | else |
frank26080115 | 0:bf7b9fba3924 | 82 | { |
frank26080115 | 0:bf7b9fba3924 | 83 | /* Port 1 */ |
frank26080115 | 0:bf7b9fba3924 | 84 | LPC_PINCON->PINSEL4 &= ~0x0000000F; |
frank26080115 | 0:bf7b9fba3924 | 85 | /* Disable the interrupt in the VIC and UART controllers */ |
frank26080115 | 0:bf7b9fba3924 | 86 | LPC_UART1->IER = 0; |
frank26080115 | 0:bf7b9fba3924 | 87 | NVIC_DisableIRQ(UART1_IRQn); |
frank26080115 | 0:bf7b9fba3924 | 88 | } |
frank26080115 | 0:bf7b9fba3924 | 89 | return; |
frank26080115 | 0:bf7b9fba3924 | 90 | } |
frank26080115 | 0:bf7b9fba3924 | 91 | |
frank26080115 | 0:bf7b9fba3924 | 92 | /*---------------------------------------------------------------------------- |
frank26080115 | 0:bf7b9fba3924 | 93 | initialize the serial port |
frank26080115 | 0:bf7b9fba3924 | 94 | *---------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 95 | void ser_InitPort0 (unsigned long baudrate, unsigned int databits, |
frank26080115 | 0:bf7b9fba3924 | 96 | unsigned int parity, unsigned int stopbits) { |
frank26080115 | 0:bf7b9fba3924 | 97 | |
frank26080115 | 0:bf7b9fba3924 | 98 | unsigned char lcr_p, lcr_s, lcr_d; |
frank26080115 | 0:bf7b9fba3924 | 99 | unsigned int dll; |
frank26080115 | 0:bf7b9fba3924 | 100 | unsigned int pclkdiv, pclk; |
frank26080115 | 0:bf7b9fba3924 | 101 | |
frank26080115 | 0:bf7b9fba3924 | 102 | switch (databits) { |
frank26080115 | 0:bf7b9fba3924 | 103 | case 5: // 5 Data bits |
frank26080115 | 0:bf7b9fba3924 | 104 | lcr_d = 0x00; |
frank26080115 | 0:bf7b9fba3924 | 105 | break; |
frank26080115 | 0:bf7b9fba3924 | 106 | case 6: // 6 Data bits |
frank26080115 | 0:bf7b9fba3924 | 107 | lcr_d = 0x01; |
frank26080115 | 0:bf7b9fba3924 | 108 | break; |
frank26080115 | 0:bf7b9fba3924 | 109 | case 7: // 7 Data bits |
frank26080115 | 0:bf7b9fba3924 | 110 | lcr_d = 0x02; |
frank26080115 | 0:bf7b9fba3924 | 111 | break; |
frank26080115 | 0:bf7b9fba3924 | 112 | case 8: // 8 Data bits |
frank26080115 | 0:bf7b9fba3924 | 113 | default: |
frank26080115 | 0:bf7b9fba3924 | 114 | lcr_d = 0x03; |
frank26080115 | 0:bf7b9fba3924 | 115 | break; |
frank26080115 | 0:bf7b9fba3924 | 116 | } |
frank26080115 | 0:bf7b9fba3924 | 117 | |
frank26080115 | 0:bf7b9fba3924 | 118 | switch (stopbits) { |
frank26080115 | 0:bf7b9fba3924 | 119 | case 1: // 1,5 Stop bits |
frank26080115 | 0:bf7b9fba3924 | 120 | case 2: // 2 Stop bits |
frank26080115 | 0:bf7b9fba3924 | 121 | lcr_s = 0x04; |
frank26080115 | 0:bf7b9fba3924 | 122 | break; |
frank26080115 | 0:bf7b9fba3924 | 123 | case 0: // 1 Stop bit |
frank26080115 | 0:bf7b9fba3924 | 124 | default: |
frank26080115 | 0:bf7b9fba3924 | 125 | lcr_s = 0x00; |
frank26080115 | 0:bf7b9fba3924 | 126 | break; |
frank26080115 | 0:bf7b9fba3924 | 127 | } |
frank26080115 | 0:bf7b9fba3924 | 128 | |
frank26080115 | 0:bf7b9fba3924 | 129 | switch (parity) { |
frank26080115 | 0:bf7b9fba3924 | 130 | case 1: // Parity Odd |
frank26080115 | 0:bf7b9fba3924 | 131 | lcr_p = 0x08; |
frank26080115 | 0:bf7b9fba3924 | 132 | break; |
frank26080115 | 0:bf7b9fba3924 | 133 | case 2: // Parity Even |
frank26080115 | 0:bf7b9fba3924 | 134 | lcr_p = 0x18; |
frank26080115 | 0:bf7b9fba3924 | 135 | break; |
frank26080115 | 0:bf7b9fba3924 | 136 | case 3: // Parity Mark |
frank26080115 | 0:bf7b9fba3924 | 137 | lcr_p = 0x28; |
frank26080115 | 0:bf7b9fba3924 | 138 | break; |
frank26080115 | 0:bf7b9fba3924 | 139 | case 4: // Parity Space |
frank26080115 | 0:bf7b9fba3924 | 140 | lcr_p = 0x38; |
frank26080115 | 0:bf7b9fba3924 | 141 | break; |
frank26080115 | 0:bf7b9fba3924 | 142 | case 0: // Parity None |
frank26080115 | 0:bf7b9fba3924 | 143 | default: |
frank26080115 | 0:bf7b9fba3924 | 144 | lcr_p = 0x00; |
frank26080115 | 0:bf7b9fba3924 | 145 | break; |
frank26080115 | 0:bf7b9fba3924 | 146 | } |
frank26080115 | 0:bf7b9fba3924 | 147 | |
frank26080115 | 0:bf7b9fba3924 | 148 | SER_BUF_RESET(ser_out); // reset out buffer |
frank26080115 | 0:bf7b9fba3924 | 149 | SER_BUF_RESET(ser_in); // reset in buffer |
frank26080115 | 0:bf7b9fba3924 | 150 | |
frank26080115 | 0:bf7b9fba3924 | 151 | /* Bit 6~7 is for UART0 */ |
frank26080115 | 0:bf7b9fba3924 | 152 | pclkdiv = (LPC_SC->PCLKSEL0 >> 6) & 0x03; |
frank26080115 | 0:bf7b9fba3924 | 153 | |
frank26080115 | 0:bf7b9fba3924 | 154 | switch ( pclkdiv ) |
frank26080115 | 0:bf7b9fba3924 | 155 | { |
frank26080115 | 0:bf7b9fba3924 | 156 | case 0x00: |
frank26080115 | 0:bf7b9fba3924 | 157 | default: |
frank26080115 | 0:bf7b9fba3924 | 158 | pclk = SystemCoreClock/4; |
frank26080115 | 0:bf7b9fba3924 | 159 | break; |
frank26080115 | 0:bf7b9fba3924 | 160 | case 0x01: |
frank26080115 | 0:bf7b9fba3924 | 161 | pclk = SystemCoreClock; |
frank26080115 | 0:bf7b9fba3924 | 162 | break; |
frank26080115 | 0:bf7b9fba3924 | 163 | case 0x02: |
frank26080115 | 0:bf7b9fba3924 | 164 | pclk = SystemCoreClock/2; |
frank26080115 | 0:bf7b9fba3924 | 165 | break; |
frank26080115 | 0:bf7b9fba3924 | 166 | case 0x03: |
frank26080115 | 0:bf7b9fba3924 | 167 | pclk = SystemCoreClock/8; |
frank26080115 | 0:bf7b9fba3924 | 168 | break; |
frank26080115 | 0:bf7b9fba3924 | 169 | } |
frank26080115 | 0:bf7b9fba3924 | 170 | |
frank26080115 | 0:bf7b9fba3924 | 171 | dll = (pclk/16)/baudrate ; /*baud rate */ |
frank26080115 | 0:bf7b9fba3924 | 172 | LPC_UART0->FDR = 0; // Fractional divider not used |
frank26080115 | 0:bf7b9fba3924 | 173 | LPC_UART0->LCR = 0x80 | lcr_d | lcr_p | lcr_s; // Data bits, Parity, Stop bit |
frank26080115 | 0:bf7b9fba3924 | 174 | LPC_UART0->DLL = dll; // Baud Rate depending on PCLK |
frank26080115 | 0:bf7b9fba3924 | 175 | LPC_UART0->DLM = (dll >> 8); // High divisor latch |
frank26080115 | 0:bf7b9fba3924 | 176 | LPC_UART0->LCR = 0x00 | lcr_d | lcr_p | lcr_s; // DLAB = 0 |
frank26080115 | 0:bf7b9fba3924 | 177 | LPC_UART0->IER = 0x03; // Enable TX/RX interrupts |
frank26080115 | 0:bf7b9fba3924 | 178 | |
frank26080115 | 0:bf7b9fba3924 | 179 | LPC_UART0->FCR = 0x07; /* Enable and reset TX and RX FIFO. */ |
frank26080115 | 0:bf7b9fba3924 | 180 | ser_txRestart = 1; // TX fifo is empty |
frank26080115 | 0:bf7b9fba3924 | 181 | |
frank26080115 | 0:bf7b9fba3924 | 182 | /* Enable the UART Interrupt */ |
frank26080115 | 0:bf7b9fba3924 | 183 | NVIC_EnableIRQ(UART0_IRQn); |
frank26080115 | 0:bf7b9fba3924 | 184 | return; |
frank26080115 | 0:bf7b9fba3924 | 185 | } |
frank26080115 | 0:bf7b9fba3924 | 186 | |
frank26080115 | 0:bf7b9fba3924 | 187 | /*---------------------------------------------------------------------------- |
frank26080115 | 0:bf7b9fba3924 | 188 | initialize the serial port |
frank26080115 | 0:bf7b9fba3924 | 189 | *---------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 190 | void ser_InitPort1 (unsigned long baudrate, unsigned int databits, |
frank26080115 | 0:bf7b9fba3924 | 191 | unsigned int parity, unsigned int stopbits) { |
frank26080115 | 0:bf7b9fba3924 | 192 | |
frank26080115 | 0:bf7b9fba3924 | 193 | unsigned char lcr_p, lcr_s, lcr_d; |
frank26080115 | 0:bf7b9fba3924 | 194 | unsigned int dll; |
frank26080115 | 0:bf7b9fba3924 | 195 | unsigned int pclkdiv, pclk; |
frank26080115 | 0:bf7b9fba3924 | 196 | |
frank26080115 | 0:bf7b9fba3924 | 197 | switch (databits) { |
frank26080115 | 0:bf7b9fba3924 | 198 | case 5: // 5 Data bits |
frank26080115 | 0:bf7b9fba3924 | 199 | lcr_d = 0x00; |
frank26080115 | 0:bf7b9fba3924 | 200 | break; |
frank26080115 | 0:bf7b9fba3924 | 201 | case 6: // 6 Data bits |
frank26080115 | 0:bf7b9fba3924 | 202 | lcr_d = 0x01; |
frank26080115 | 0:bf7b9fba3924 | 203 | break; |
frank26080115 | 0:bf7b9fba3924 | 204 | case 7: // 7 Data bits |
frank26080115 | 0:bf7b9fba3924 | 205 | lcr_d = 0x02; |
frank26080115 | 0:bf7b9fba3924 | 206 | break; |
frank26080115 | 0:bf7b9fba3924 | 207 | case 8: // 8 Data bits |
frank26080115 | 0:bf7b9fba3924 | 208 | default: |
frank26080115 | 0:bf7b9fba3924 | 209 | lcr_d = 0x03; |
frank26080115 | 0:bf7b9fba3924 | 210 | break; |
frank26080115 | 0:bf7b9fba3924 | 211 | } |
frank26080115 | 0:bf7b9fba3924 | 212 | |
frank26080115 | 0:bf7b9fba3924 | 213 | switch (stopbits) { |
frank26080115 | 0:bf7b9fba3924 | 214 | case 1: // 1,5 Stop bits |
frank26080115 | 0:bf7b9fba3924 | 215 | case 2: // 2 Stop bits |
frank26080115 | 0:bf7b9fba3924 | 216 | lcr_s = 0x04; |
frank26080115 | 0:bf7b9fba3924 | 217 | break; |
frank26080115 | 0:bf7b9fba3924 | 218 | case 0: // 1 Stop bit |
frank26080115 | 0:bf7b9fba3924 | 219 | default: |
frank26080115 | 0:bf7b9fba3924 | 220 | lcr_s = 0x00; |
frank26080115 | 0:bf7b9fba3924 | 221 | break; |
frank26080115 | 0:bf7b9fba3924 | 222 | } |
frank26080115 | 0:bf7b9fba3924 | 223 | |
frank26080115 | 0:bf7b9fba3924 | 224 | switch (parity) { |
frank26080115 | 0:bf7b9fba3924 | 225 | case 1: // Parity Odd |
frank26080115 | 0:bf7b9fba3924 | 226 | lcr_p = 0x08; |
frank26080115 | 0:bf7b9fba3924 | 227 | break; |
frank26080115 | 0:bf7b9fba3924 | 228 | case 2: // Parity Even |
frank26080115 | 0:bf7b9fba3924 | 229 | lcr_p = 0x18; |
frank26080115 | 0:bf7b9fba3924 | 230 | break; |
frank26080115 | 0:bf7b9fba3924 | 231 | case 3: // Parity Mark |
frank26080115 | 0:bf7b9fba3924 | 232 | lcr_p = 0x28; |
frank26080115 | 0:bf7b9fba3924 | 233 | break; |
frank26080115 | 0:bf7b9fba3924 | 234 | case 4: // Parity Space |
frank26080115 | 0:bf7b9fba3924 | 235 | lcr_p = 0x38; |
frank26080115 | 0:bf7b9fba3924 | 236 | break; |
frank26080115 | 0:bf7b9fba3924 | 237 | case 0: // Parity None |
frank26080115 | 0:bf7b9fba3924 | 238 | default: |
frank26080115 | 0:bf7b9fba3924 | 239 | lcr_p = 0x00; |
frank26080115 | 0:bf7b9fba3924 | 240 | break; |
frank26080115 | 0:bf7b9fba3924 | 241 | } |
frank26080115 | 0:bf7b9fba3924 | 242 | |
frank26080115 | 0:bf7b9fba3924 | 243 | SER_BUF_RESET(ser_out); // reset out buffer |
frank26080115 | 0:bf7b9fba3924 | 244 | SER_BUF_RESET(ser_in); // reset in buffer |
frank26080115 | 0:bf7b9fba3924 | 245 | |
frank26080115 | 0:bf7b9fba3924 | 246 | /* Bit 8,9 are for UART1 */ |
frank26080115 | 0:bf7b9fba3924 | 247 | pclkdiv = (LPC_SC->PCLKSEL0 >> 8) & 0x03; |
frank26080115 | 0:bf7b9fba3924 | 248 | |
frank26080115 | 0:bf7b9fba3924 | 249 | switch ( pclkdiv ) |
frank26080115 | 0:bf7b9fba3924 | 250 | { |
frank26080115 | 0:bf7b9fba3924 | 251 | case 0x00: |
frank26080115 | 0:bf7b9fba3924 | 252 | default: |
frank26080115 | 0:bf7b9fba3924 | 253 | pclk = SystemCoreClock/4; |
frank26080115 | 0:bf7b9fba3924 | 254 | break; |
frank26080115 | 0:bf7b9fba3924 | 255 | case 0x01: |
frank26080115 | 0:bf7b9fba3924 | 256 | pclk = SystemCoreClock; |
frank26080115 | 0:bf7b9fba3924 | 257 | break; |
frank26080115 | 0:bf7b9fba3924 | 258 | case 0x02: |
frank26080115 | 0:bf7b9fba3924 | 259 | pclk = SystemCoreClock/2; |
frank26080115 | 0:bf7b9fba3924 | 260 | break; |
frank26080115 | 0:bf7b9fba3924 | 261 | case 0x03: |
frank26080115 | 0:bf7b9fba3924 | 262 | pclk = SystemCoreClock/8; |
frank26080115 | 0:bf7b9fba3924 | 263 | break; |
frank26080115 | 0:bf7b9fba3924 | 264 | } |
frank26080115 | 0:bf7b9fba3924 | 265 | |
frank26080115 | 0:bf7b9fba3924 | 266 | dll = (pclk/16)/baudrate ; /*baud rate */ |
frank26080115 | 0:bf7b9fba3924 | 267 | LPC_UART1->FDR = 0; // Fractional divider not used |
frank26080115 | 0:bf7b9fba3924 | 268 | LPC_UART1->LCR = 0x80 | lcr_d | lcr_p | lcr_s; // Data bits, Parity, Stop bit |
frank26080115 | 0:bf7b9fba3924 | 269 | LPC_UART1->DLL = dll; // Baud Rate depending on PCLK |
frank26080115 | 0:bf7b9fba3924 | 270 | LPC_UART1->DLM = (dll >> 8); // High divisor latch |
frank26080115 | 0:bf7b9fba3924 | 271 | LPC_UART1->LCR = 0x00 | lcr_d | lcr_p | lcr_s; // DLAB = 0 |
frank26080115 | 0:bf7b9fba3924 | 272 | LPC_UART1->IER = 0x03; // Enable TX/RX interrupts |
frank26080115 | 0:bf7b9fba3924 | 273 | |
frank26080115 | 0:bf7b9fba3924 | 274 | LPC_UART1->FCR = 0x07; /* Enable and reset TX and RX FIFO. */ |
frank26080115 | 0:bf7b9fba3924 | 275 | ser_txRestart = 1; // TX fifo is empty |
frank26080115 | 0:bf7b9fba3924 | 276 | |
frank26080115 | 0:bf7b9fba3924 | 277 | /* Enable the UART Interrupt */ |
frank26080115 | 0:bf7b9fba3924 | 278 | NVIC_EnableIRQ(UART1_IRQn); |
frank26080115 | 0:bf7b9fba3924 | 279 | return; |
frank26080115 | 0:bf7b9fba3924 | 280 | } |
frank26080115 | 0:bf7b9fba3924 | 281 | |
frank26080115 | 0:bf7b9fba3924 | 282 | /*---------------------------------------------------------------------------- |
frank26080115 | 0:bf7b9fba3924 | 283 | read data from serial port |
frank26080115 | 0:bf7b9fba3924 | 284 | *---------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 285 | int ser_Read (char *buffer, const int *length) { |
frank26080115 | 0:bf7b9fba3924 | 286 | int bytesToRead, bytesRead; |
frank26080115 | 0:bf7b9fba3924 | 287 | |
frank26080115 | 0:bf7b9fba3924 | 288 | /* Read *length bytes, block if *bytes are not avaialable */ |
frank26080115 | 0:bf7b9fba3924 | 289 | bytesToRead = *length; |
frank26080115 | 0:bf7b9fba3924 | 290 | bytesToRead = (bytesToRead < (*length)) ? bytesToRead : (*length); |
frank26080115 | 0:bf7b9fba3924 | 291 | bytesRead = bytesToRead; |
frank26080115 | 0:bf7b9fba3924 | 292 | |
frank26080115 | 0:bf7b9fba3924 | 293 | while (bytesToRead--) { |
frank26080115 | 0:bf7b9fba3924 | 294 | while (SER_BUF_EMPTY(ser_in)); // Block until data is available if none |
frank26080115 | 0:bf7b9fba3924 | 295 | *buffer++ = SER_BUF_RD(ser_in); |
frank26080115 | 0:bf7b9fba3924 | 296 | } |
frank26080115 | 0:bf7b9fba3924 | 297 | return (bytesRead); |
frank26080115 | 0:bf7b9fba3924 | 298 | } |
frank26080115 | 0:bf7b9fba3924 | 299 | |
frank26080115 | 0:bf7b9fba3924 | 300 | /*---------------------------------------------------------------------------- |
frank26080115 | 0:bf7b9fba3924 | 301 | write data to the serial port |
frank26080115 | 0:bf7b9fba3924 | 302 | *---------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 303 | int ser_Write (char portNum, const char *buffer, int *length) { |
frank26080115 | 0:bf7b9fba3924 | 304 | int bytesToWrite, bytesWritten; |
frank26080115 | 0:bf7b9fba3924 | 305 | |
frank26080115 | 0:bf7b9fba3924 | 306 | // Write *length bytes |
frank26080115 | 0:bf7b9fba3924 | 307 | bytesToWrite = *length; |
frank26080115 | 0:bf7b9fba3924 | 308 | bytesWritten = bytesToWrite; |
frank26080115 | 0:bf7b9fba3924 | 309 | |
frank26080115 | 0:bf7b9fba3924 | 310 | while (!SER_BUF_EMPTY(ser_out)); // Block until space is available if none |
frank26080115 | 0:bf7b9fba3924 | 311 | while (bytesToWrite) { |
frank26080115 | 0:bf7b9fba3924 | 312 | SER_BUF_WR(ser_out, *buffer++); // Read Rx FIFO to buffer |
frank26080115 | 0:bf7b9fba3924 | 313 | bytesToWrite--; |
frank26080115 | 0:bf7b9fba3924 | 314 | } |
frank26080115 | 0:bf7b9fba3924 | 315 | |
frank26080115 | 0:bf7b9fba3924 | 316 | if (ser_txRestart) { |
frank26080115 | 0:bf7b9fba3924 | 317 | ser_txRestart = 0; |
frank26080115 | 0:bf7b9fba3924 | 318 | if ( portNum == 0 ) |
frank26080115 | 0:bf7b9fba3924 | 319 | { |
frank26080115 | 0:bf7b9fba3924 | 320 | LPC_UART0->THR = SER_BUF_RD(ser_out); // Write to the Tx Register |
frank26080115 | 0:bf7b9fba3924 | 321 | } |
frank26080115 | 0:bf7b9fba3924 | 322 | else |
frank26080115 | 0:bf7b9fba3924 | 323 | { |
frank26080115 | 0:bf7b9fba3924 | 324 | LPC_UART1->THR = SER_BUF_RD(ser_out); // Write to the Tx Register |
frank26080115 | 0:bf7b9fba3924 | 325 | } |
frank26080115 | 0:bf7b9fba3924 | 326 | } |
frank26080115 | 0:bf7b9fba3924 | 327 | |
frank26080115 | 0:bf7b9fba3924 | 328 | return (bytesWritten); |
frank26080115 | 0:bf7b9fba3924 | 329 | } |
frank26080115 | 0:bf7b9fba3924 | 330 | |
frank26080115 | 0:bf7b9fba3924 | 331 | /*---------------------------------------------------------------------------- |
frank26080115 | 0:bf7b9fba3924 | 332 | check if character(s) are available at the serial interface |
frank26080115 | 0:bf7b9fba3924 | 333 | *---------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 334 | void ser_AvailChar (int *availChar) { |
frank26080115 | 0:bf7b9fba3924 | 335 | |
frank26080115 | 0:bf7b9fba3924 | 336 | *availChar = SER_BUF_COUNT(ser_in); |
frank26080115 | 0:bf7b9fba3924 | 337 | |
frank26080115 | 0:bf7b9fba3924 | 338 | } |
frank26080115 | 0:bf7b9fba3924 | 339 | |
frank26080115 | 0:bf7b9fba3924 | 340 | /*---------------------------------------------------------------------------- |
frank26080115 | 0:bf7b9fba3924 | 341 | read the line state of the serial port |
frank26080115 | 0:bf7b9fba3924 | 342 | *---------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 343 | void ser_LineState (unsigned short *lineState) { |
frank26080115 | 0:bf7b9fba3924 | 344 | |
frank26080115 | 0:bf7b9fba3924 | 345 | *lineState = ser_lineState; |
frank26080115 | 0:bf7b9fba3924 | 346 | ser_lineState = 0; |
frank26080115 | 0:bf7b9fba3924 | 347 | |
frank26080115 | 0:bf7b9fba3924 | 348 | } |
frank26080115 | 0:bf7b9fba3924 | 349 | |
frank26080115 | 0:bf7b9fba3924 | 350 | /*---------------------------------------------------------------------------- |
frank26080115 | 0:bf7b9fba3924 | 351 | serial port 0 interrupt |
frank26080115 | 0:bf7b9fba3924 | 352 | *---------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 353 | void UART0_IRQHandler(void) |
frank26080115 | 0:bf7b9fba3924 | 354 | { |
frank26080115 | 0:bf7b9fba3924 | 355 | volatile unsigned long iir; |
frank26080115 | 0:bf7b9fba3924 | 356 | |
frank26080115 | 0:bf7b9fba3924 | 357 | iir = LPC_UART0->IIR; |
frank26080115 | 0:bf7b9fba3924 | 358 | |
frank26080115 | 0:bf7b9fba3924 | 359 | if ((iir & 0x4) || (iir & 0xC)) { // RDA or CTI pending |
frank26080115 | 0:bf7b9fba3924 | 360 | while (LPC_UART0->LSR & 0x01) { // Rx FIFO is not empty |
frank26080115 | 0:bf7b9fba3924 | 361 | SER_BUF_WR(ser_in, LPC_UART0->RBR); // Read Rx FIFO to buffer |
frank26080115 | 0:bf7b9fba3924 | 362 | } |
frank26080115 | 0:bf7b9fba3924 | 363 | } |
frank26080115 | 0:bf7b9fba3924 | 364 | if ((iir & 0x2)) { // TXMIS pending |
frank26080115 | 0:bf7b9fba3924 | 365 | if (SER_BUF_COUNT(ser_out) != 0) { |
frank26080115 | 0:bf7b9fba3924 | 366 | LPC_UART0->THR = SER_BUF_RD(ser_out); // Write to the Tx FIFO |
frank26080115 | 0:bf7b9fba3924 | 367 | ser_txRestart = 0; |
frank26080115 | 0:bf7b9fba3924 | 368 | } |
frank26080115 | 0:bf7b9fba3924 | 369 | else { |
frank26080115 | 0:bf7b9fba3924 | 370 | ser_txRestart = 1; |
frank26080115 | 0:bf7b9fba3924 | 371 | } |
frank26080115 | 0:bf7b9fba3924 | 372 | } |
frank26080115 | 0:bf7b9fba3924 | 373 | ser_lineState = LPC_UART0->LSR & 0x1E; // update linestate |
frank26080115 | 0:bf7b9fba3924 | 374 | return; |
frank26080115 | 0:bf7b9fba3924 | 375 | } |
frank26080115 | 0:bf7b9fba3924 | 376 | |
frank26080115 | 0:bf7b9fba3924 | 377 | /*---------------------------------------------------------------------------- |
frank26080115 | 0:bf7b9fba3924 | 378 | serial port 1 interrupt |
frank26080115 | 0:bf7b9fba3924 | 379 | *---------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 380 | void UART1_IRQHandler(void) |
frank26080115 | 0:bf7b9fba3924 | 381 | { |
frank26080115 | 0:bf7b9fba3924 | 382 | volatile unsigned long iir; |
frank26080115 | 0:bf7b9fba3924 | 383 | |
frank26080115 | 0:bf7b9fba3924 | 384 | iir = LPC_UART1->IIR; |
frank26080115 | 0:bf7b9fba3924 | 385 | |
frank26080115 | 0:bf7b9fba3924 | 386 | if ((iir & 0x4) || (iir & 0xC)) { // RDA or CTI pending |
frank26080115 | 0:bf7b9fba3924 | 387 | while (LPC_UART1->LSR & 0x01) { // Rx FIFO is not empty |
frank26080115 | 0:bf7b9fba3924 | 388 | SER_BUF_WR(ser_in, LPC_UART1->RBR); // Read Rx FIFO to buffer |
frank26080115 | 0:bf7b9fba3924 | 389 | } |
frank26080115 | 0:bf7b9fba3924 | 390 | } |
frank26080115 | 0:bf7b9fba3924 | 391 | if ((iir & 0x2)) { // TXMIS pending |
frank26080115 | 0:bf7b9fba3924 | 392 | if (SER_BUF_COUNT(ser_out) != 0) { |
frank26080115 | 0:bf7b9fba3924 | 393 | LPC_UART1->THR = SER_BUF_RD(ser_out); // Write to the Tx FIFO |
frank26080115 | 0:bf7b9fba3924 | 394 | ser_txRestart = 0; |
frank26080115 | 0:bf7b9fba3924 | 395 | } |
frank26080115 | 0:bf7b9fba3924 | 396 | else { |
frank26080115 | 0:bf7b9fba3924 | 397 | ser_txRestart = 1; |
frank26080115 | 0:bf7b9fba3924 | 398 | } |
frank26080115 | 0:bf7b9fba3924 | 399 | } |
frank26080115 | 0:bf7b9fba3924 | 400 | ser_lineState = ((LPC_UART1->MSR<<8)|LPC_UART1->LSR) & 0xE01E; // update linestate |
frank26080115 | 0:bf7b9fba3924 | 401 | return; |
frank26080115 | 0:bf7b9fba3924 | 402 | } |
frank26080115 | 0:bf7b9fba3924 | 403 | |
frank26080115 | 0:bf7b9fba3924 | 404 |