123
Fork of LG by
DeviceUserPort.c@183:c7a9c309086c, 2016-07-31 (annotated)
- Committer:
- Diletant
- Date:
- Sun Jul 31 06:19:02 2016 +0000
- Revision:
- 183:c7a9c309086c
- Parent:
- 182:2bd8ec44998f
Device&... update. More AskGld&Techno functionality.NotFinal!!!
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Diletant | 161:efd949e8d536 | 1 | #include "Device.h" |
Diletant | 161:efd949e8d536 | 2 | |
Diletant | 161:efd949e8d536 | 3 | extern Device device; |
Diletant | 161:efd949e8d536 | 4 | extern unsigned int SystemCoreClock1; |
Diletant | 161:efd949e8d536 | 5 | |
Diletant | 167:bedc0a9d559a | 6 | void InitUserPortDefaultSettings(void) { |
Diletant | 183:c7a9c309086c | 7 | device.user.port.settings.mode = 0; //Baud rate usage: 0 - accept baud rate change; 1 - always 921600 |
Diletant | 182:2bd8ec44998f | 8 | device.user.port.settings.baud = 38400; |
Diletant | 161:efd949e8d536 | 9 | } |
Diletant | 161:efd949e8d536 | 10 | |
Diletant | 167:bedc0a9d559a | 11 | void InitUserPortState(void) { |
Diletant | 183:c7a9c309086c | 12 | device.user.port.state.mode = device.user.port.settings.mode; |
Diletant | 183:c7a9c309086c | 13 | device.user.port.state.baud = userSelectBaudRate(device.user.port.settings.baud); |
Diletant | 167:bedc0a9d559a | 14 | } |
Diletant | 167:bedc0a9d559a | 15 | |
Diletant | 167:bedc0a9d559a | 16 | void DeviceStartUserPort(void) |
Diletant | 161:efd949e8d536 | 17 | { |
Diletant | 161:efd949e8d536 | 18 | LPC_PINCON->PINSEL4 &= ~0x0000000F; |
Diletant | 161:efd949e8d536 | 19 | LPC_PINCON->PINSEL4 |= 0x0000000A; //Enable RxD1 P2.1, TxD1 P2.0 |
Diletant | 182:2bd8ec44998f | 20 | |
Diletant | 182:2bd8ec44998f | 21 | userSetBaudRate(device.user.port.state.baud); |
Diletant | 182:2bd8ec44998f | 22 | |
Diletant | 182:2bd8ec44998f | 23 | device.controller.uart[1].state.FCR = 0x03; |
Diletant | 182:2bd8ec44998f | 24 | LPC_UART1->FCR = device.controller.uart[1].state.FCR; //Enable and reset TX and RX FIFO. |
Diletant | 182:2bd8ec44998f | 25 | |
Diletant | 182:2bd8ec44998f | 26 | /* |
Diletant | 182:2bd8ec44998f | 27 | //Uncomment to use interrupts |
Diletant | 182:2bd8ec44998f | 28 | //NVIC_EnableIRQ(UART1_IRQn); |
Diletant | 182:2bd8ec44998f | 29 | //LPC_UART1->IER = IER_RBR | IER_THRE | IER_RLS; //Enable UART1 interrupt |
Diletant | 182:2bd8ec44998f | 30 | */ |
Diletant | 182:2bd8ec44998f | 31 | } |
Diletant | 182:2bd8ec44998f | 32 | |
Diletant | 183:c7a9c309086c | 33 | uint32_t userSelectBaudRate(uint32_t baud) { |
Diletant | 183:c7a9c309086c | 34 | if (device.user.port.state.mode == 1) |
Diletant | 183:c7a9c309086c | 35 | return 921600; |
Diletant | 183:c7a9c309086c | 36 | else |
Diletant | 183:c7a9c309086c | 37 | return baud; |
Diletant | 183:c7a9c309086c | 38 | } |
Diletant | 183:c7a9c309086c | 39 | |
Diletant | 182:2bd8ec44998f | 40 | void userSetBaudRate(uint32_t baud) { |
Diletant | 183:c7a9c309086c | 41 | baud = userSelectBaudRate(baud); |
Diletant | 182:2bd8ec44998f | 42 | //Peripheral clock of UART1 |
Diletant | 182:2bd8ec44998f | 43 | uint32_t pclkdiv = (LPC_SC->PCLKSEL0 >> 8) & 0x03; //Bits 8,9 are for UART1 |
Diletant | 182:2bd8ec44998f | 44 | uint32_t pclk; |
Diletant | 161:efd949e8d536 | 45 | switch ( pclkdiv ) { |
Diletant | 161:efd949e8d536 | 46 | case 0x00: |
Diletant | 161:efd949e8d536 | 47 | default: |
Diletant | 161:efd949e8d536 | 48 | pclk = SystemCoreClock1/4; |
Diletant | 161:efd949e8d536 | 49 | break; |
Diletant | 161:efd949e8d536 | 50 | case 0x01: |
Diletant | 161:efd949e8d536 | 51 | pclk = SystemCoreClock1; |
Diletant | 161:efd949e8d536 | 52 | break; |
Diletant | 161:efd949e8d536 | 53 | case 0x02: |
Diletant | 161:efd949e8d536 | 54 | pclk = SystemCoreClock1/2; |
Diletant | 161:efd949e8d536 | 55 | break; |
Diletant | 161:efd949e8d536 | 56 | case 0x03: |
Diletant | 161:efd949e8d536 | 57 | pclk = SystemCoreClock1/8; |
Diletant | 161:efd949e8d536 | 58 | break; |
Diletant | 182:2bd8ec44998f | 59 | } |
Diletant | 182:2bd8ec44998f | 60 | //Divider |
Diletant | 182:2bd8ec44998f | 61 | uint32_t Fdiv = ( pclk / 16 ) / baud; |
Diletant | 182:2bd8ec44998f | 62 | //Enable divider write |
Diletant | 161:efd949e8d536 | 63 | device.controller.uart[1].state.LCR = 0x83; |
Diletant | 182:2bd8ec44998f | 64 | LPC_UART1->LCR = device.controller.uart[1].state.LCR; //8 bits, no Parity, 1 Stop bit |
Diletant | 182:2bd8ec44998f | 65 | //Write divider hi byte |
Diletant | 161:efd949e8d536 | 66 | device.controller.uart[1].state.DLM = Fdiv / 256; |
Diletant | 161:efd949e8d536 | 67 | LPC_UART1->DLM = device.controller.uart[1].state.DLM; |
Diletant | 182:2bd8ec44998f | 68 | //Write divider lo byte |
Diletant | 161:efd949e8d536 | 69 | device.controller.uart[1].state.DLL = Fdiv % 256; |
Diletant | 161:efd949e8d536 | 70 | LPC_UART1->DLL = device.controller.uart[1].state.DLL; |
Diletant | 182:2bd8ec44998f | 71 | //Disable divider write |
Diletant | 161:efd949e8d536 | 72 | device.controller.uart[1].state.LCR = 0x03; |
Diletant | 182:2bd8ec44998f | 73 | LPC_UART1->LCR = device.controller.uart[1].state.LCR; //DLAB = 0 |
Diletant | 161:efd949e8d536 | 74 | |
Diletant | 182:2bd8ec44998f | 75 | device.user.port.state.baud = baud; |
Diletant | 182:2bd8ec44998f | 76 | |
Diletant | 182:2bd8ec44998f | 77 | #ifdef DEBUG_USER_BAUD |
Diletant | 182:2bd8ec44998f | 78 | sprintf(device.service.buffer, "userSetBaudRate(%06d)\r\n", baud); WriteConcole(); |
Diletant | 182:2bd8ec44998f | 79 | #endif |
Diletant | 161:efd949e8d536 | 80 | } |
Diletant | 161:efd949e8d536 | 81 | |
Diletant | 177:672ef279c8e0 | 82 | void userReceive(void){ |
Diletant | 161:efd949e8d536 | 83 | if (LPC_UART1->LSR & 0x01) { |
Diletant | 161:efd949e8d536 | 84 | device.user.request.buffer.data[device.user.request.buffer.end] = LPC_UART1->RBR; |
Diletant | 161:efd949e8d536 | 85 | device.user.request.buffer.end = (device.user.request.buffer.end + 1) % InputBufferSize; |
Diletant | 161:efd949e8d536 | 86 | device.user.request.buffer.empty = 0; |
Diletant | 161:efd949e8d536 | 87 | device.user.decoder.canceled = 0; //Clear decode canceled flag |
Diletant | 161:efd949e8d536 | 88 | } |
Diletant | 161:efd949e8d536 | 89 | } |
Diletant | 161:efd949e8d536 | 90 | |
Diletant | 177:672ef279c8e0 | 91 | void userTransmit(void){ |
Diletant | 161:efd949e8d536 | 92 | if (device.user.response.ready) { |
Diletant | 182:2bd8ec44998f | 93 | if (device.user.response.type == RESPONSE_DELAYED) { |
Diletant | 182:2bd8ec44998f | 94 | if (!device.user.response.triggered) return; |
Diletant | 182:2bd8ec44998f | 95 | } |
Diletant | 161:efd949e8d536 | 96 | |
Diletant | 161:efd949e8d536 | 97 | if (device.user.response.buffer.position < device.user.response.buffer.count) { |
Diletant | 161:efd949e8d536 | 98 | if (LPC_UART1->LSR & 0x20) { |
Diletant | 161:efd949e8d536 | 99 | LPC_UART1->THR = device.user.response.buffer.data[device.user.response.buffer.position]; |
Diletant | 161:efd949e8d536 | 100 | device.user.response.buffer.position++; |
Diletant | 161:efd949e8d536 | 101 | if (device.user.response.buffer.position == device.user.response.buffer.count){ |
Diletant | 161:efd949e8d536 | 102 | device.user.response.ready = 0; |
Diletant | 161:efd949e8d536 | 103 | if (device.user.response.type == RESPONSE_PERIODIC) { |
Diletant | 182:2bd8ec44998f | 104 | device.user.response.enabled = 1; //next response encoding required |
Diletant | 182:2bd8ec44998f | 105 | } |
Diletant | 182:2bd8ec44998f | 106 | if (device.user.response.type == RESPONSE_DELAYED) { |
Diletant | 182:2bd8ec44998f | 107 | device.user.response.triggered = 0; //Clear transmission flag, wait next trigger event. Here ok - transmit response in multiple passes! |
Diletant | 161:efd949e8d536 | 108 | } |
Diletant | 161:efd949e8d536 | 109 | device.user.response.buffer.count = 0; |
Diletant | 161:efd949e8d536 | 110 | device.user.response.buffer.position = 0; |
Diletant | 161:efd949e8d536 | 111 | } |
Diletant | 161:efd949e8d536 | 112 | } |
Diletant | 161:efd949e8d536 | 113 | } |
Diletant | 161:efd949e8d536 | 114 | } |
Diletant | 161:efd949e8d536 | 115 | } |
Diletant | 161:efd949e8d536 | 116 | |
Diletant | 182:2bd8ec44998f | 117 | // |
Diletant | 182:2bd8ec44998f | 118 | //Compatibility section |
Diletant | 182:2bd8ec44998f | 119 | // |
Diletant | 182:2bd8ec44998f | 120 | uint8_t var_SRgR(void) { |
Diletant | 182:2bd8ec44998f | 121 | //SysRgR |
Diletant | 182:2bd8ec44998f | 122 | // Unused 3 bits: => xxxxx000 |
Diletant | 182:2bd8ec44998f | 123 | // Hardware: transmitter rate = receiver rate => xxxx1000 |
Diletant | 182:2bd8ec44998f | 124 | // Sending response, so transmitter enabled, no case => 1xxx1000 |
Diletant | 182:2bd8ec44998f | 125 | // Request received, so receiver enabled, no case => 11xx1000 |
Diletant | 182:2bd8ec44998f | 126 | uint8_t res; |
Diletant | 182:2bd8ec44998f | 127 | switch (device.user.port.state.baud) { |
Diletant | 182:2bd8ec44998f | 128 | case 38400: res = 0xc8; break; //11001000 |
Diletant | 182:2bd8ec44998f | 129 | case 115200: res = 0xd8; break; //11011000 |
Diletant | 182:2bd8ec44998f | 130 | case 460800: res = 0xe8; break; //11101000 |
Diletant | 182:2bd8ec44998f | 131 | case 921600: res = 0xf8; break; //11111000 |
Diletant | 182:2bd8ec44998f | 132 | default: res = 0xc8; //11001000 - 38400 |
Diletant | 182:2bd8ec44998f | 133 | } |
Diletant | 182:2bd8ec44998f | 134 | return res; |
Diletant | 182:2bd8ec44998f | 135 | } |
Diletant | 182:2bd8ec44998f | 136 | |
Diletant | 182:2bd8ec44998f | 137 | // |
Diletant | 182:2bd8ec44998f | 138 | //Not used section |
Diletant | 182:2bd8ec44998f | 139 | // Communication using interrupt |
Diletant | 161:efd949e8d536 | 140 | /* |
Diletant | 161:efd949e8d536 | 141 | #define IER_RBR 0x01 |
Diletant | 161:efd949e8d536 | 142 | #define IER_THRE 0x02 |
Diletant | 161:efd949e8d536 | 143 | #define IER_RLS 0x04 |
Diletant | 161:efd949e8d536 | 144 | |
Diletant | 161:efd949e8d536 | 145 | #define IIR_PEND 0x01 |
Diletant | 161:efd949e8d536 | 146 | #define IIR_RLS 0x03 |
Diletant | 161:efd949e8d536 | 147 | #define IIR_RDA 0x02 |
Diletant | 161:efd949e8d536 | 148 | #define IIR_CTI 0x06 |
Diletant | 161:efd949e8d536 | 149 | #define IIR_THRE 0x01 |
Diletant | 161:efd949e8d536 | 150 | |
Diletant | 161:efd949e8d536 | 151 | #define LSR_RDR 0x01 |
Diletant | 161:efd949e8d536 | 152 | #define LSR_OE 0x02 |
Diletant | 161:efd949e8d536 | 153 | #define LSR_PE 0x04 |
Diletant | 161:efd949e8d536 | 154 | #define LSR_FE 0x08 |
Diletant | 161:efd949e8d536 | 155 | #define LSR_BI 0x10 |
Diletant | 161:efd949e8d536 | 156 | #define LSR_THRE 0x20 |
Diletant | 161:efd949e8d536 | 157 | #define LSR_TEMT 0x40 |
Diletant | 161:efd949e8d536 | 158 | #define LSR_RXFE 0x80 |
Diletant | 161:efd949e8d536 | 159 | |
Diletant | 161:efd949e8d536 | 160 | void UART1Send(void) |
Diletant | 161:efd949e8d536 | 161 | { |
Diletant | 161:efd949e8d536 | 162 | uint8_t pos = 0; |
Diletant | 161:efd949e8d536 | 163 | while (device.host.response.buffer.count != pos ) { |
Diletant | 161:efd949e8d536 | 164 | //THRE status, contain valid data |
Diletant | 161:efd949e8d536 | 165 | while ( !(device.host.port.TxEmpty & 0x01) ); |
Diletant | 161:efd949e8d536 | 166 | LPC_UART1->THR = device.host.response.buffer.data[pos]; |
Diletant | 161:efd949e8d536 | 167 | device.host.port.TxEmpty = 0; //not empty in the THR until it shifts out |
Diletant | 161:efd949e8d536 | 168 | pos++; |
Diletant | 161:efd949e8d536 | 169 | } |
Diletant | 161:efd949e8d536 | 170 | device.host.response.buffer.count = 0; |
Diletant | 161:efd949e8d536 | 171 | } |
Diletant | 161:efd949e8d536 | 172 | |
Diletant | 161:efd949e8d536 | 173 | //Not used |
Diletant | 161:efd949e8d536 | 174 | __irq void UART1_IRQHandler (void) |
Diletant | 161:efd949e8d536 | 175 | { |
Diletant | 161:efd949e8d536 | 176 | uint8_t IIRValue, LSRValue; |
Diletant | 161:efd949e8d536 | 177 | uint8_t Dummy = Dummy; |
Diletant | 161:efd949e8d536 | 178 | |
Diletant | 161:efd949e8d536 | 179 | IIRValue = LPC_UART1->IIR; |
Diletant | 161:efd949e8d536 | 180 | |
Diletant | 161:efd949e8d536 | 181 | IIRValue >>= 1; //skip pending bit in IIR |
Diletant | 161:efd949e8d536 | 182 | IIRValue &= 0x07; //check bit 1~3, interrupt identification |
Diletant | 161:efd949e8d536 | 183 | if ( IIRValue == IIR_RLS ) // Receive Line Status |
Diletant | 161:efd949e8d536 | 184 | { |
Diletant | 161:efd949e8d536 | 185 | LSRValue = LPC_UART1->LSR; |
Diletant | 161:efd949e8d536 | 186 | //Receive Line Status |
Diletant | 161:efd949e8d536 | 187 | if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) ) |
Diletant | 161:efd949e8d536 | 188 | { |
Diletant | 161:efd949e8d536 | 189 | //There are errors or break interrupt |
Diletant | 161:efd949e8d536 | 190 | //Read LSR will clear the interrupt |
Diletant | 161:efd949e8d536 | 191 | device.host.port.status = LSRValue; |
Diletant | 161:efd949e8d536 | 192 | Dummy = LPC_UART1->RBR;//Dummy read on RX to clear interrupt, then bail out |
Diletant | 161:efd949e8d536 | 193 | return; |
Diletant | 161:efd949e8d536 | 194 | } |
Diletant | 161:efd949e8d536 | 195 | if ( LSRValue & LSR_RDR )//Receive Data Ready |
Diletant | 161:efd949e8d536 | 196 | { |
Diletant | 161:efd949e8d536 | 197 | //If no error on RLS, normal ready, save into the data buffer. |
Diletant | 161:efd949e8d536 | 198 | //Note: read RBR will clear the interrupt |
Diletant | 161:efd949e8d536 | 199 | device.host.request.buffer.data[device.host.request.buffer.end] = LPC_UART1->RBR; |
Diletant | 161:efd949e8d536 | 200 | device.host.request.buffer.end = (device.host.request.buffer.end + 1) % InputBufferSize; |
Diletant | 161:efd949e8d536 | 201 | } |
Diletant | 161:efd949e8d536 | 202 | } |
Diletant | 161:efd949e8d536 | 203 | else if ( IIRValue == IIR_RDA ) //Receive Data Available |
Diletant | 161:efd949e8d536 | 204 | { |
Diletant | 161:efd949e8d536 | 205 | device.host.request.buffer.data[device.host.request.buffer.end] = LPC_UART1->RBR; |
Diletant | 161:efd949e8d536 | 206 | device.host.request.buffer.end = (device.host.request.buffer.end + 1) % InputBufferSize; |
Diletant | 161:efd949e8d536 | 207 | } |
Diletant | 161:efd949e8d536 | 208 | else if ( IIRValue == IIR_CTI ) //Character timeout indicator |
Diletant | 161:efd949e8d536 | 209 | { |
Diletant | 161:efd949e8d536 | 210 | //Character Time-out indicator |
Diletant | 161:efd949e8d536 | 211 | device.host.port.status |= 0x100; //Bit 9 as the CTI error |
Diletant | 161:efd949e8d536 | 212 | } |
Diletant | 161:efd949e8d536 | 213 | else if ( IIRValue == IIR_THRE ) //THRE, transmit holding register empty |
Diletant | 161:efd949e8d536 | 214 | { |
Diletant | 161:efd949e8d536 | 215 | //THRE interrupt |
Diletant | 161:efd949e8d536 | 216 | LSRValue = LPC_UART1->LSR; //Check status in the LSR to see if valid data in U0THR or not |
Diletant | 161:efd949e8d536 | 217 | if ( LSRValue & LSR_THRE ) |
Diletant | 161:efd949e8d536 | 218 | { |
Diletant | 161:efd949e8d536 | 219 | device.host.port.TxEmpty = 1; |
Diletant | 161:efd949e8d536 | 220 | } |
Diletant | 161:efd949e8d536 | 221 | else |
Diletant | 161:efd949e8d536 | 222 | { |
Diletant | 161:efd949e8d536 | 223 | device.host.port.TxEmpty = 0; |
Diletant | 161:efd949e8d536 | 224 | } |
Diletant | 161:efd949e8d536 | 225 | } |
Diletant | 161:efd949e8d536 | 226 | }*/ |