$search
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 // Read IIR to clear interrupt and find out the cause 00054 while (((iid = U0IIR) & UIIR_NO_INT) == 0) 00055 { 00056 if (iid & 0x100) 00057 { 00058 autobaud_in_progress = 1; 00059 U0ACR |= 0x100; //clear ABEO interrupt 00060 U0ACR &= ~0x01; // disable autobaud 00061 U0IER &= ~((1 << 8) | (1 << 9)); //disable ABEO and ABTO interrupts 00062 00063 autobaud_in_progress = 0; 00064 } 00065 00066 if (iid & 0x200) 00067 { 00068 autobaud_in_progress = 1; 00069 U0ACR |= 0x200; //clear ABTO int 00070 00071 autobaud_in_progress = 0; 00072 } 00073 00074 switch (iid & UIIR_ID_MASK) 00075 { 00076 case UIIR_RLS_INT: // Receive Line Status 00077 U0LSR; // read LSR to clear 00078 break; 00079 00080 case UIIR_CTI_INT: // <-- keep this together, in order to read remaining bytes below fifo threshold 00081 case UIIR_RDA_INT: 00082 // RDA interrupt 00083 //receive handler 00084 rxFifo.inUse = 1; 00085 do 00086 { // read from fifo as long as there is data available 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 // THRE interrupt 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: // Unknown 00119 U0LSR; 00120 U0RBR; 00121 break; 00122 } 00123 } 00124 VICVectAddr = 0; // Acknowledge Interrupt 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 // //safe method 00160 // int i=0; 00161 // uint8_t *ptr = (uint8_t *)data; 00162 // for(i=0; i<length; i++){ 00163 // if(!Fifo_writeByte(fifo, ptr[i])) 00164 // return 0; 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 // if(registeredPacketCnt < PACKET_INFO_SIZE){ 00193 packetInfo[registeredPacketCnt].data = data; 00194 packetInfo[registeredPacketCnt].descriptor = descriptor; 00195 packetInfo[registeredPacketCnt].updated = 0; 00196 registeredPacketCnt++; 00197 return &packetInfo[registeredPacketCnt - 1]; 00198 // } 00199 // TODO: what if space for packets is exceeded?? 00200 // return NULL; 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 // UART0_DISABLE_RX_INT; 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; // get size of packet 00254 syncstate++; 00255 } 00256 else if (syncstate == 4) 00257 { 00258 packetType = rxdata; // get packet type 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) // read data 00273 { 00274 rxParseBuffer[packetSize - rxCount] = rxdata; 00275 rxCount--; 00276 00277 if (rxCount == 0) 00278 { 00279 syncstate++; 00280 } 00281 } 00282 else if (syncstate == 7) // first byte of checksum 00283 { 00284 checksum_received = rxdata & 0xff; 00285 syncstate++; 00286 } 00287 else if (syncstate == 8) // second byte of checksum + check (and dispatch?) 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 // UART0_ENABLE_RX_INT; 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 // while(txFifo.inUse); 00346 // UART0_DISABLE_TX_INT; 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 // UART0_ENABLE_TX_INT; 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 //UART0 00363 U0LCR = 0x83; /* 8 bit, 1 stop bit, no parity, enable DLAB */ 00364 U0DLL = divisor & 0xFF; 00365 U0DLM = (divisor >> 8) & 0xFF; 00366 U0LCR &= ~0x80; /* Disable DLAB */ 00367 U0FCR = UFCR_FIFO_ENABLE | UFCR_FIFO_TRIG8 | UFCR_RX_FIFO_RESET | UFCR_TX_FIFO_RESET;//1; fifo enable, trigger interrupt after 8 bytes in the fifo 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;// start, mode 0, autorestart 00381 U0IER |= ((1 << 8) | (1 << 9)); //enable ABEO and ABTO interrupts 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 //Write to UART0 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 ; //wait until U0THR and U0TSR are both empty 00426 while (length--) 00427 { 00428 U0THR = buffer[cnt++]; 00429 if (cnt > 15) 00430 { 00431 while (!(U0LSR & 0x20)) 00432 ; //wait until U0THR is empty 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