00001 #include <string.h>
00002 #include <mav_common/comm.h>
00003
00004 #include "LPC214x.h"
00005 #include "interrupt_utils.h"
00006 #include "system.h"
00007 #include "main.h"
00008 #include "uart.h"
00009 #include "irq.h"
00010 #include "hardware.h"
00011 #include "gpsmath.h"
00012 #include "ssp.h"
00013 #include "lpcUART.h"
00014
00015 volatile unsigned char transmission_running = 0;
00016
00017 unsigned char UART_syncstate = 0;
00018 unsigned int UART_rxcount = 0;
00019 unsigned char *UART_rxptr;
00020
00021 unsigned uart0_rx_cpsr;
00022 unsigned uart0_tx_cpsr;
00023
00024 #define UART0_DISABLE_TX_INT uart0_tx_cpsr=disableIRQ();U0IER &= ~UIER_ETBEI;restoreIRQ(uart0_tx_cpsr);
00025 #define UART0_ENABLE_TX_INT uart0_tx_cpsr=disableIRQ();U0IER |= UIER_ETBEI;restoreIRQ(uart0_tx_cpsr);
00026 #define UART0_DISABLE_RX_INT uart0_rx_cpsr=disableIRQ();U0IER &= ~UIER_ERBFI;restoreIRQ(uart0_rx_cpsr);
00027 #define UART0_ENABLE_RX_INT uart0_rx_cpsr=disableIRQ();U0IER |= UIER_ERBFI;restoreIRQ(uart0_rx_cpsr);
00028
00029 short uart0_min_tx_buffer = UART0_TX_BUFFERSIZE;
00030 short uart0_min_rx_buffer = UART0_RX_BUFFERSIZE;
00031
00032 uint8_t rxBuffer[UART0_RX_BUFFERSIZE];
00033 uint8_t rxParseBuffer[UART0_RX_BUFFERSIZE];
00034 Fifo rxFifo;
00035
00036 uint8_t txBuffer[UART0_TX_BUFFERSIZE];
00037 Fifo txFifo;
00038
00039 volatile unsigned int UART_rxPacketCount = 0;
00040 volatile unsigned int UART_rxGoodPacketCount = 0;
00041
00042 PacketInfo packetInfo[PACKET_INFO_SIZE];
00043 uint32_t registeredPacketCnt = 0;
00044
00045 volatile char autobaud_in_progress = 0;
00046
00047 void uart0ISR(void) __irq
00048 {
00049 uint8_t t;
00050 uint16_t iid;
00051 short freemem = 0;
00052
00053
00054 while (((iid = U0IIR) & UIIR_NO_INT) == 0)
00055 {
00056 if (iid & 0x100)
00057 {
00058 autobaud_in_progress = 1;
00059 U0ACR |= 0x100;
00060 U0ACR &= ~0x01;
00061 U0IER &= ~((1 << 8) | (1 << 9));
00062
00063 autobaud_in_progress = 0;
00064 }
00065
00066 if (iid & 0x200)
00067 {
00068 autobaud_in_progress = 1;
00069 U0ACR |= 0x200;
00070
00071 autobaud_in_progress = 0;
00072 }
00073
00074 switch (iid & UIIR_ID_MASK)
00075 {
00076 case UIIR_RLS_INT:
00077 U0LSR;
00078 break;
00079
00080 case UIIR_CTI_INT:
00081 case UIIR_RDA_INT:
00082
00083
00084 rxFifo.inUse = 1;
00085 do
00086 {
00087 t = U0RBR;
00088 freemem = Fifo_availableMemory(&rxFifo);
00089 if (freemem < uart0_min_rx_buffer)
00090 uart0_min_rx_buffer = freemem;
00091 if (!Fifo_writeByte(&rxFifo, t))
00092 break;
00093 } while (U0LSR & ULSR_RDR);
00094 rxFifo.inUse = 0;
00095
00096 break;
00097
00098 case UIIR_THRE_INT:
00099
00100 if(!(IOPIN0&(1<<CTS_RADIO))){
00101 txFifo.inUse = 1;
00102 while (U0LSR & ULSR_THRE)
00103 {
00104 if (Fifo_readByte(&txFifo, &t))
00105 {
00106 U0THR = t;
00107 }
00108 else
00109 {
00110 transmission_running = 0;
00111 break;
00112 }
00113 }
00114 txFifo.inUse = 0;
00115 }
00116 break;
00117
00118 default:
00119 U0LSR;
00120 U0RBR;
00121 break;
00122 }
00123 }
00124 VICVectAddr = 0;
00125 }
00126
00127 void Fifo_initialize(Fifo * fifo, uint8_t * buffer, uint32_t bufferSize)
00128 {
00129 fifo->buffer = buffer;
00130 fifo->bufferSize = bufferSize;
00131 fifo->readIdx = 0;
00132 fifo->writeIdx = 0;
00133 fifo->tmp = 0;
00134 fifo->mask = bufferSize - 1;
00135 fifo->inUse = 0;
00136 }
00137
00138 uint8_t Fifo_writeByte(Fifo * fifo, uint8_t byte)
00139 {
00140 fifo->tmp = ((fifo->writeIdx + 1) & fifo->mask);
00141 if (fifo->readIdx == fifo->tmp)
00142 return 0;
00143 fifo->buffer[fifo->writeIdx] = byte;
00144 fifo->writeIdx = fifo->tmp;
00145 return 1;
00146 }
00147
00148 uint8_t Fifo_writeBlock(Fifo * fifo, void *data, uint32_t length)
00149 {
00150 if (Fifo_availableMemory(fifo) <= length)
00151 return 0;
00152 uint8_t *ptr = (uint8_t *)data;
00153 while (length--)
00154 {
00155 fifo->buffer[fifo->writeIdx] = *ptr++;
00156 fifo->writeIdx = (fifo->writeIdx + 1) & fifo->mask;
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 return 1;
00168 }
00169
00170 uint8_t Fifo_readByte(Fifo * fifo, uint8_t * byte)
00171 {
00172 if (fifo->readIdx == fifo->writeIdx)
00173 return 0;
00174 *byte = fifo->buffer[fifo->readIdx];
00175 fifo->readIdx = (fifo->readIdx + 1) & fifo->mask;
00176 return 1;
00177 }
00178
00179 uint16_t Fifo_availableMemory(Fifo * fifo)
00180 {
00181 return (fifo->readIdx - fifo->writeIdx - 1) & fifo->mask;
00182 }
00183
00184 void Fifo_reset(Fifo * fifo)
00185 {
00186 fifo->writeIdx = 0;
00187 fifo->readIdx = 0;
00188 }
00189
00190 PacketInfo* registerPacket(uint8_t descriptor, void * data)
00191 {
00192
00193 packetInfo[registeredPacketCnt].data = data;
00194 packetInfo[registeredPacketCnt].descriptor = descriptor;
00195 packetInfo[registeredPacketCnt].updated = 0;
00196 registeredPacketCnt++;
00197 return &packetInfo[registeredPacketCnt - 1];
00198
00199
00200
00201 }
00202
00203 void parseRxFifo(void)
00204 {
00205 static uint8_t packetType;
00206 static uint8_t flag;
00207 static int packetSize = 0;
00208 static int rxCount = 0;
00209 static uint16_t checksum_computed = 0;
00210 static uint16_t checksum_received = 0;
00211 static uint32_t syncstate = 0;
00212 static MAV_ACK_PKT packet_ack;
00213 uint32_t i = 0;
00214 uint8_t rxdata = 0;
00215
00216 if (rxFifo.inUse == 1)
00217 return;
00218
00219
00220
00221 while (Fifo_readByte(&rxFifo, &rxdata))
00222 {
00223
00224 if (syncstate == 0)
00225 {
00226 if (rxdata == '>')
00227 syncstate++;
00228 else
00229 syncstate = 0;
00230
00231 rxCount = 0;
00232 checksum_received = 0;
00233 UART_rxptr = rxParseBuffer;
00234 packetSize = 0;
00235 flag = 0;
00236 }
00237 else if (syncstate == 1)
00238 {
00239 if (rxdata == '*')
00240 syncstate++;
00241 else
00242 syncstate = 0;
00243 }
00244 else if (syncstate == 2)
00245 {
00246 if (rxdata == '>')
00247 syncstate++;
00248 else
00249 syncstate = 0;
00250 }
00251 else if (syncstate == 3)
00252 {
00253 packetSize = rxdata;
00254 syncstate++;
00255 }
00256 else if (syncstate == 4)
00257 {
00258 packetType = rxdata;
00259 if (packetSize < 1)
00260 syncstate = 0;
00261 else
00262 {
00263 rxCount = packetSize;
00264 syncstate++;
00265 }
00266 }
00267 else if (syncstate == 5)
00268 {
00269 flag = rxdata;
00270 syncstate++;
00271 }
00272 else if (syncstate == 6)
00273 {
00274 rxParseBuffer[packetSize - rxCount] = rxdata;
00275 rxCount--;
00276
00277 if (rxCount == 0)
00278 {
00279 syncstate++;
00280 }
00281 }
00282 else if (syncstate == 7)
00283 {
00284 checksum_received = rxdata & 0xff;
00285 syncstate++;
00286 }
00287 else if (syncstate == 8)
00288 {
00289 checksum_received |= ((unsigned short)rxdata << 8);
00290 UART_rxPacketCount++;
00291
00292 checksum_computed = crc16(&packetType, 1, 0xff);
00293 checksum_computed = crc16(&flag, 1, checksum_computed);
00294 checksum_computed = crc16(rxParseBuffer, packetSize, checksum_computed);
00295
00296 if (checksum_received == checksum_computed)
00297 {
00298 UART_rxGoodPacketCount++;
00299 for (i = 0; i < registeredPacketCnt; i++)
00300 {
00301 if (packetType == packetInfo[i].descriptor)
00302 {
00303 memcpy((packetInfo[i].data), rxParseBuffer, packetSize);
00304 packetInfo[i].updated = 1;
00305 if (flag & MAV_COMM_ACK)
00306 {
00307 packet_ack.ack_packet = flag;
00308 writePacket2Ringbuffer(MAV_ACK_PKT_ID, &packet_ack, sizeof(packet_ack));
00309 }
00310 break;
00311 }
00312 }
00313 }
00314 syncstate = 0;
00315 }
00316 else
00317 syncstate = 0;
00318 }
00319
00320 }
00321
00322 inline int writePacket2Ringbuffer(uint8_t descriptor, void * data, uint8_t length)
00323 {
00324 static uint8_t header[] = {0xFF, 0x09, 0, 0};
00325 uint16_t checksum = 0;
00326 int state = 0;
00327
00328 header[2] = length;
00329 header[3] = descriptor;
00330 checksum = crc16(&descriptor, 1, 0xff);
00331 checksum = crc16(data, length, checksum);
00332
00333 state = 1;
00334 state &= UART0_writeFifo(header, sizeof(header));
00335 state &= UART0_writeFifo(data, length);
00336 state &= UART0_writeFifo(&checksum, sizeof(checksum));
00337
00338 return state;
00339 }
00340
00341 uint8_t UART0_writeFifo(void * data, uint32_t length)
00342 {
00343 uint8_t ret = 0;
00344 short freemem;
00345
00346
00347 ret = Fifo_writeBlock(&txFifo, data, length);
00348 freemem = Fifo_availableMemory(&txFifo);
00349 if (freemem < uart0_min_tx_buffer)
00350 uart0_min_tx_buffer = freemem;
00351
00352 return ret;
00353 }
00354
00355 void UARTInitialize(unsigned int baud)
00356 {
00357 UART0_DISABLE_RX_INT;
00358 UART0_DISABLE_TX_INT;
00359
00360 unsigned int divisor = peripheralClockFrequency() / (16 * baud);
00361
00362
00363 U0LCR = 0x83;
00364 U0DLL = divisor & 0xFF;
00365 U0DLM = (divisor >> 8) & 0xFF;
00366 U0LCR &= ~0x80;
00367 U0FCR = UFCR_FIFO_ENABLE | UFCR_FIFO_TRIG8 | UFCR_RX_FIFO_RESET | UFCR_TX_FIFO_RESET;
00368 Fifo_initialize(&rxFifo, rxBuffer, UART0_RX_BUFFERSIZE);
00369 Fifo_initialize(&txFifo, txBuffer, UART0_TX_BUFFERSIZE);
00370
00371 UART0_ENABLE_RX_INT;
00372 UART0_ENABLE_TX_INT;
00373 }
00374
00375 void startAutoBaud(void)
00376 {
00377 if (U0ACR & 0x01)
00378 return;
00379
00380 U0ACR = 0x01 | 0x04;
00381 U0IER |= ((1 << 8) | (1 << 9));
00382 }
00383
00384 void UART0_rxFlush(void)
00385 {
00386 U0FCR |= UFCR_RX_FIFO_RESET;
00387 Fifo_reset(&rxFifo);
00388 }
00389 void UART0_txFlush(void)
00390 {
00391 U0FCR |= UFCR_TX_FIFO_RESET;
00392 }
00393
00394 int UART0_txEmpty(void)
00395 {
00396 return (U0LSR & (ULSR_THRE | ULSR_TEMT)) == (ULSR_THRE | ULSR_TEMT);
00397 }
00398
00399
00400 void UARTWriteChar(unsigned char ch)
00401 {
00402 while ((U0LSR & 0x20) == 0)
00403 ;
00404 U0THR = ch;
00405 }
00406
00407 unsigned char UARTReadChar(void)
00408 {
00409 while ((U0LSR & 0x01) == 0)
00410 ;
00411 return U0RBR;
00412 }
00413
00414 void __putchar(int ch)
00415 {
00416 if (ch == '\n')
00417 UARTWriteChar('\r');
00418 UARTWriteChar(ch);
00419 }
00420
00421 void UART_send(char *buffer, unsigned char length)
00422 {
00423 unsigned char cnt = 0;
00424 while (!(U0LSR & 0x20))
00425 ;
00426 while (length--)
00427 {
00428 U0THR = buffer[cnt++];
00429 if (cnt > 15)
00430 {
00431 while (!(U0LSR & 0x20))
00432 ;
00433 }
00434 }
00435 }
00436
00437 void UART_send_ringbuffer(void)
00438 {
00439 uint8_t t;
00440 if (!transmission_running)
00441 {
00442 if (Fifo_readByte(&txFifo, &t))
00443 {
00444 transmission_running = 1;
00445 UARTWriteChar(t);
00446 }
00447 }
00448 }
00449
00450 uint16_t crc_update(uint16_t crc, uint8_t data)
00451 {
00452 data ^= (crc & 0xff);
00453 data ^= data << 4;
00454
00455 return ((((uint16_t)data << 8) | ((crc >> 8) & 0xff)) ^ (uint8_t)(data >> 4) ^ ((uint16_t)data << 3));
00456 }
00457
00458 uint16_t crc16(void* data, uint16_t cnt, uint16_t crc)
00459 {
00460 uint8_t * ptr = (uint8_t *)data;
00461 int i;
00462
00463 for (i = 0; i < cnt; i++)
00464 {
00465 crc = crc_update(crc, *ptr);
00466 ptr++;
00467 }
00468 return crc;
00469 }
00470