00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 #define NUT_DEPRECATED
00056
00057 #include <cfg/ahdlc.h>
00058
00059 #include <string.h>
00060 #include <stdlib.h>
00061 #include <fcntl.h>
00062
00063 #include <sys/nutconfig.h>
00064 #include <sys/atom.h>
00065 #include <sys/heap.h>
00066 #include <sys/event.h>
00067 #include <sys/timer.h>
00068 #include <sys/thread.h>
00069
00070 #include <dev/irqreg.h>
00071 #include <dev/ppp.h>
00072
00073 #include <netinet/if_ppp.h>
00074 #include <net/ppp.h>
00075 #include <net/if_var.h>
00076
00077 #include <dev/usartat91.h>
00078 #include <dev/at91_ahdlc.h>
00079
00080
00081 #ifndef NUT_AHDLC_RECV_DMA_SIZE
00082 #define NUT_AHDLC_RECV_DMA_SIZE 64
00083 #endif
00084
00085
00086 static unsigned char DMA_RxBuf0[NUT_AHDLC_RECV_DMA_SIZE];
00087
00088 #define UART_RECEIVER_TIMEOUT 32
00089
00090 #define SIG_UART sig_UART1
00091 #define US_ID US1_ID
00092 #define US_GPIO_PINS 0x00000360
00093
00094
00095
00100
00101 static AHDLCDCB dcb_ahdlc;
00102
00109 NUTDEVICE devAhdlc1 = {
00110 0,
00111 {'u', 'a', 'r', 't', '1', 0, 0, 0, 0},
00112 IFTYP_CHAR,
00113 1,
00114 0,
00115 0,
00116 &dcb_ahdlc,
00117 AhdlcAt91Init,
00118 AhdlcAt91IOCtl,
00119 AhdlcAt91Read,
00120 AhdlcAt91Write,
00121 AhdlcAt91Open,
00122 AhdlcAt91Close,
00123 0
00124 };
00125
00126
00127
00128
00129
00130 static prog_char fcstab[512] = {
00131 0x00, 0x00, 0x11, 0x89, 0x23, 0x12, 0x32, 0x9b, 0x46, 0x24, 0x57, 0xad, 0x65, 0x36, 0x74, 0xbf,
00132 0x8c, 0x48, 0x9d, 0xc1, 0xaf, 0x5a, 0xbe, 0xd3, 0xca, 0x6c, 0xdb, 0xe5, 0xe9, 0x7e, 0xf8, 0xf7,
00133 0x10, 0x81, 0x01, 0x08, 0x33, 0x93, 0x22, 0x1a, 0x56, 0xa5, 0x47, 0x2c, 0x75, 0xb7, 0x64, 0x3e,
00134 0x9c, 0xc9, 0x8d, 0x40, 0xbf, 0xdb, 0xae, 0x52, 0xda, 0xed, 0xcb, 0x64, 0xf9, 0xff, 0xe8, 0x76,
00135 0x21, 0x02, 0x30, 0x8b, 0x02, 0x10, 0x13, 0x99, 0x67, 0x26, 0x76, 0xaf, 0x44, 0x34, 0x55, 0xbd,
00136 0xad, 0x4a, 0xbc, 0xc3, 0x8e, 0x58, 0x9f, 0xd1, 0xeb, 0x6e, 0xfa, 0xe7, 0xc8, 0x7c, 0xd9, 0xf5,
00137 0x31, 0x83, 0x20, 0x0a, 0x12, 0x91, 0x03, 0x18, 0x77, 0xa7, 0x66, 0x2e, 0x54, 0xb5, 0x45, 0x3c,
00138 0xbd, 0xcb, 0xac, 0x42, 0x9e, 0xd9, 0x8f, 0x50, 0xfb, 0xef, 0xea, 0x66, 0xd8, 0xfd, 0xc9, 0x74,
00139
00140 0x42, 0x04, 0x53, 0x8d, 0x61, 0x16, 0x70, 0x9f, 0x04, 0x20, 0x15, 0xa9, 0x27, 0x32, 0x36, 0xbb,
00141 0xce, 0x4c, 0xdf, 0xc5, 0xed, 0x5e, 0xfc, 0xd7, 0x88, 0x68, 0x99, 0xe1, 0xab, 0x7a, 0xba, 0xf3,
00142 0x52, 0x85, 0x43, 0x0c, 0x71, 0x97, 0x60, 0x1e, 0x14, 0xa1, 0x05, 0x28, 0x37, 0xb3, 0x26, 0x3a,
00143 0xde, 0xcd, 0xcf, 0x44, 0xfd, 0xdf, 0xec, 0x56, 0x98, 0xe9, 0x89, 0x60, 0xbb, 0xfb, 0xaa, 0x72,
00144 0x63, 0x06, 0x72, 0x8f, 0x40, 0x14, 0x51, 0x9d, 0x25, 0x22, 0x34, 0xab, 0x06, 0x30, 0x17, 0xb9,
00145 0xef, 0x4e, 0xfe, 0xc7, 0xcc, 0x5c, 0xdd, 0xd5, 0xa9, 0x6a, 0xb8, 0xe3, 0x8a, 0x78, 0x9b, 0xf1,
00146 0x73, 0x87, 0x62, 0x0e, 0x50, 0x95, 0x41, 0x1c, 0x35, 0xa3, 0x24, 0x2a, 0x16, 0xb1, 0x07, 0x38,
00147 0xff, 0xcf, 0xee, 0x46, 0xdc, 0xdd, 0xcd, 0x54, 0xb9, 0xeb, 0xa8, 0x62, 0x9a, 0xf9, 0x8b, 0x70,
00148
00149 0x84, 0x08, 0x95, 0x81, 0xa7, 0x1a, 0xb6, 0x93, 0xc2, 0x2c, 0xd3, 0xa5, 0xe1, 0x3e, 0xf0, 0xb7,
00150 0x08, 0x40, 0x19, 0xc9, 0x2b, 0x52, 0x3a, 0xdb, 0x4e, 0x64, 0x5f, 0xed, 0x6d, 0x76, 0x7c, 0xff,
00151 0x94, 0x89, 0x85, 0x00, 0xb7, 0x9b, 0xa6, 0x12, 0xd2, 0xad, 0xc3, 0x24, 0xf1, 0xbf, 0xe0, 0x36,
00152 0x18, 0xc1, 0x09, 0x48, 0x3b, 0xd3, 0x2a, 0x5a, 0x5e, 0xe5, 0x4f, 0x6c, 0x7d, 0xf7, 0x6c, 0x7e,
00153 0xa5, 0x0a, 0xb4, 0x83, 0x86, 0x18, 0x97, 0x91, 0xe3, 0x2e, 0xf2, 0xa7, 0xc0, 0x3c, 0xd1, 0xb5,
00154 0x29, 0x42, 0x38, 0xcb, 0x0a, 0x50, 0x1b, 0xd9, 0x6f, 0x66, 0x7e, 0xef, 0x4c, 0x74, 0x5d, 0xfd,
00155 0xb5, 0x8b, 0xa4, 0x02, 0x96, 0x99, 0x87, 0x10, 0xf3, 0xaf, 0xe2, 0x26, 0xd0, 0xbd, 0xc1, 0x34,
00156 0x39, 0xc3, 0x28, 0x4a, 0x1a, 0xd1, 0x0b, 0x58, 0x7f, 0xe7, 0x6e, 0x6e, 0x5c, 0xf5, 0x4d, 0x7c,
00157
00158 0xc6, 0x0c, 0xd7, 0x85, 0xe5, 0x1e, 0xf4, 0x97, 0x80, 0x28, 0x91, 0xa1, 0xa3, 0x3a, 0xb2, 0xb3,
00159 0x4a, 0x44, 0x5b, 0xcd, 0x69, 0x56, 0x78, 0xdf, 0x0c, 0x60, 0x1d, 0xe9, 0x2f, 0x72, 0x3e, 0xfb,
00160 0xd6, 0x8d, 0xc7, 0x04, 0xf5, 0x9f, 0xe4, 0x16, 0x90, 0xa9, 0x81, 0x20, 0xb3, 0xbb, 0xa2, 0x32,
00161 0x5a, 0xc5, 0x4b, 0x4c, 0x79, 0xd7, 0x68, 0x5e, 0x1c, 0xe1, 0x0d, 0x68, 0x3f, 0xf3, 0x2e, 0x7a,
00162 0xe7, 0x0e, 0xf6, 0x87, 0xc4, 0x1c, 0xd5, 0x95, 0xa1, 0x2a, 0xb0, 0xa3, 0x82, 0x38, 0x93, 0xb1,
00163 0x6b, 0x46, 0x7a, 0xcf, 0x48, 0x54, 0x59, 0xdd, 0x2d, 0x62, 0x3c, 0xeb, 0x0e, 0x70, 0x1f, 0xf9,
00164 0xf7, 0x8f, 0xe6, 0x06, 0xd4, 0x9d, 0xc5, 0x14, 0xb1, 0xab, 0xa0, 0x22, 0x92, 0xb9, 0x83, 0x30,
00165 0x7b, 0xc7, 0x6a, 0x4e, 0x58, 0xd5, 0x49, 0x5c, 0x3d, 0xe3, 0x2c, 0x6a, 0x1e, 0xf1, 0x0f, 0x78
00166 };
00167
00171 #define IN_ACC_MAP(c, m) (( ((uint8_t) (c)) < 0x20) && ((m) & (1UL << (c))) != 0)
00172
00173 #ifndef NUT_THREAD_AHDLCRXSTACK
00174 #define NUT_THREAD_AHDLCRXSTACK 2048
00175 #endif
00176
00177
00178
00184 static void At91UsartInterrupt(void *arg)
00185 {
00186 AHDLCDCB *dcb = arg;
00187 uint16_t count, i;
00188 ureg_t csr = inr(US1_CSR);
00189
00190 if (csr & (US_ENDRX | US_RXBUFF | US_TIMEOUT)) {
00191
00192
00193 if (csr & US_TIMEOUT) {
00194 count = NUT_AHDLC_RECV_DMA_SIZE - inr(USART1_BASE + PERIPH_RCR_OFF);
00195 } else {
00196 count = NUT_AHDLC_RECV_DMA_SIZE;
00197 }
00198
00199 for (i = 0; i < count; i++) {
00200 dcb->dcb_rx_buf[dcb->dcb_rx_idx] = DMA_RxBuf0[i];
00201 dcb->dcb_rx_idx++;
00202 }
00203
00204 outr(USART1_BASE + PERIPH_RPR_OFF, (unsigned int) DMA_RxBuf0);
00205 outr(USART1_BASE + PERIPH_RCR_OFF, NUT_AHDLC_RECV_DMA_SIZE);
00206 outr(USART1_BASE + PERIPH_PTCR_OFF, PDC_RXTEN);
00207 outr(US1_CR, inr(US1_CR) | US_STTTO);
00208 NutEventPostFromIrq(&dcb->dcb_rx_rdy);
00209 }
00210
00211 if (csr & US_TXRDY) {
00212 if (dcb->dcb_tx_idx != dcb->dcb_wr_idx) {
00213 outr(US1_THR, dcb->dcb_tx_buf[dcb->dcb_tx_idx]);
00214 dcb->dcb_tx_idx++;
00215 } else {
00216 outr(US1_IDR, US_TXRDY);
00217 NutEventPostFromIrq(&dcb->dcb_tx_rdy);
00218 }
00219 }
00220
00221 }
00222
00223
00224
00225
00226
00227
00228 static int SendRawByte(AHDLCDCB * dcb, uint8_t ch, uint8_t flush)
00229 {
00230
00231
00232
00233
00234 while ((uint8_t) (dcb->dcb_wr_idx + 1) == dcb->dcb_tx_idx) {
00235 if (NutEventWait(&dcb->dcb_tx_rdy, dcb->dcb_wtimeout))
00236 break;
00237 }
00238
00239
00240
00241
00242 if ((uint8_t) (dcb->dcb_wr_idx + 1) == dcb->dcb_tx_idx) {
00243 return -1;
00244 }
00245
00246
00247
00248
00249
00250 dcb->dcb_tx_buf[dcb->dcb_wr_idx] = ch;
00251 dcb->dcb_wr_idx++;
00252
00253
00254
00255
00256
00257 if (flush || (uint8_t) (dcb->dcb_wr_idx + 1) == dcb->dcb_tx_idx) {
00258
00259 NutEnterCritical();
00260
00261 outr(US1_IER, US_TXRDY);
00262
00263 NutExitCritical();
00264 }
00265 return 0;
00266 }
00267
00268
00269
00270
00271
00272
00273
00274 static int SendHdlcData(AHDLCDCB * dcb, CONST uint8_t * data, uint16_t len, uint16_t * txfcs)
00275 {
00276 uint16_t tbx;
00277 uint16_t fcs;
00278
00279 if (txfcs)
00280 fcs = *txfcs;
00281 else
00282 fcs = 0;
00283
00284 while (len) {
00285 tbx = (uint16_t) ((uint8_t) fcs ^ *data) << 1;
00286 fcs >>= 8;
00287 fcs ^= ((uint16_t) PRG_RDB(fcstab + tbx) << 8) | PRG_RDB(fcstab + tbx + 1);
00288
00289 if (IN_ACC_MAP(*data, dcb->dcb_tx_accm) || *data == AHDLC_FLAG || *data == AHDLC_ESCAPE) {
00290 if (SendRawByte(dcb, AHDLC_ESCAPE, 0)) {
00291 return -1;
00292 }
00293 if (SendRawByte(dcb, *data ^ AHDLC_TRANS, 0)) {
00294 return -1;
00295 }
00296 } else if (SendRawByte(dcb, *data, 0)) {
00297 return -1;
00298 }
00299 data++;
00300 len--;
00301 }
00302 if (txfcs)
00303 *txfcs = fcs;
00304
00305 return 0;
00306 }
00307
00318 int AhdlcOutput(NUTDEVICE * dev, NETBUF * nb)
00319 {
00320 uint16_t txfcs;
00321 AHDLCDCB *dcb = dev->dev_dcb;
00322 uint16_t sz;
00323
00324
00325
00326
00327
00328 if (dcb->dcb_modeflags & UART_MF_RAWMODE) {
00329 return 0;
00330 }
00331
00332
00333
00334
00335
00336 sz = nb->nb_dl.sz + nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz;
00337
00338 if (sz > dcb->dcb_tx_mru) {
00339 return -1;
00340 }
00341
00342
00343
00344
00345 SendRawByte(dcb, AHDLC_FLAG, 0);
00346
00347
00348 txfcs = AHDLC_INITFCS;
00349 if (SendHdlcData(dcb, nb->nb_dl.vp, nb->nb_dl.sz, &txfcs))
00350 return -1;
00351 if (SendHdlcData(dcb, nb->nb_nw.vp, nb->nb_nw.sz, &txfcs))
00352 return -1;
00353 if (SendHdlcData(dcb, nb->nb_tp.vp, nb->nb_tp.sz, &txfcs))
00354 return -1;
00355 if (SendHdlcData(dcb, nb->nb_ap.vp, nb->nb_ap.sz, &txfcs))
00356 return -1;
00357
00358
00359 txfcs ^= 0xffff;
00360 if (SendHdlcData(dcb, (uint8_t *) & txfcs, 2, 0))
00361 return -1;
00362
00363 SendRawByte(dcb, AHDLC_FLAG, 1);
00364
00365 return 0;
00366 }
00367
00374 THREAD(AhdlcRx, arg)
00375 {
00376 NUTDEVICE *dev = arg;
00377 NUTDEVICE *netdev;
00378 AHDLCDCB *dcb = dev->dev_dcb;
00379 IFNET *ifn;
00380 NETBUF *nb;
00381 uint8_t *rxbuf;
00382 uint8_t *rxptr;
00383 uint16_t rxcnt;
00384 uint8_t ch;
00385 uint16_t tbx;
00386 uint8_t inframe;
00387 uint8_t escaped;
00388 uint16_t rxfcs;
00389
00390 NutThreadSetPriority(9);
00391 for (;;) {
00392
00393
00394
00395 rxptr = 0;
00396 rxcnt = 0;
00397 escaped = 0;
00398 rxfcs = AHDLC_INITFCS;
00399 inframe = 0;
00400
00401 for (;;) {
00402
00403
00404
00405
00406
00407
00408
00409 while ((netdev = dev->dev_icb) == 0) {
00410 if (NutEventWait(&dcb->dcb_mf_evt, 1000) == 0) {
00411 NutSleep(100);
00412 }
00413 }
00414 ifn = netdev->dev_icb;
00415 dcb->dcb_rtimeout = 1000;
00416 inframe = 0;
00417
00418
00419
00420
00421
00422
00423 if ((rxbuf = NutHeapAlloc(dcb->dcb_rx_mru)) != 0) {
00424 break;
00425 }
00426 NutSleep(1000);
00427 }
00428
00429
00430
00431
00432 ifn->if_send = AhdlcOutput;
00433 netdev->dev_ioctl(netdev, LCP_LOWERUP, 0);
00434
00435 for (;;) {
00436
00437
00438
00439
00440 while (dcb->dcb_rd_idx == dcb->dcb_rx_idx) {
00441 if (dev->dev_icb == 0)
00442 break;
00443
00444 if (NutEventWait(&dcb->dcb_rx_rdy, dcb->dcb_rtimeout)) {
00445 continue;
00446 }
00447 }
00448
00449
00450
00451
00452 if (dev->dev_icb == 0)
00453 break;
00454
00455
00456
00457
00458
00459 if (dcb->dcb_modeflags & UART_MF_RAWMODE) {
00460
00461
00462
00463
00464
00465 NutSleep(100);
00466 continue;
00467 }
00468
00469
00470
00471
00472 ch = dcb->dcb_rx_buf[dcb->dcb_rd_idx++];
00473
00474 if (inframe) {
00475 if (ch != AHDLC_FLAG) {
00476 if (ch == AHDLC_ESCAPE) {
00477 escaped = 1;
00478 continue;
00479 }
00480 if (escaped) {
00481 ch ^= AHDLC_TRANS;
00482 escaped = 0;
00483 }
00484
00485
00486
00487
00488
00489
00490 if (rxcnt++ < dcb->dcb_rx_mru) {
00491
00492 tbx = (uint16_t) ((uint8_t) rxfcs ^ ch) << 1;
00493 rxfcs >>= 8;
00494 rxfcs ^= ((uint16_t) PRG_RDB(fcstab + tbx) << 8) | PRG_RDB(fcstab + tbx + 1);
00495 *rxptr++ = ch;
00496 } else
00497 inframe = 0;
00498 continue;
00499 }
00500
00501 if (rxcnt > 6 && rxfcs == AHDLC_GOODFCS) {
00502
00503
00504
00505
00506 rxcnt -= 2;
00507 if ((nb = NutNetBufAlloc(0, NBAF_DATALINK, rxcnt)) != 0) {
00508 memcpy(nb->nb_dl.vp, rxbuf, rxcnt);
00509 (*ifn->if_recv) (netdev, nb);
00510 }
00511 }
00512 }
00513
00514
00515
00516
00517 if (ch == AHDLC_FLAG) {
00518 inframe = 1;
00519 escaped = 0;
00520 rxptr = rxbuf;
00521 rxcnt = 0;
00522 rxfcs = AHDLC_INITFCS;
00523 }
00524 }
00525
00526
00527
00528 netdev->dev_ioctl(netdev, LCP_LOWERDOWN, 0);
00529
00530
00531 if (rxbuf) {
00532 NutHeapFree(rxbuf);
00533 rxbuf = 0;
00534 }
00535 }
00536 }
00537
00538
00539
00540
00541
00542
00543 static int AhdlcAt91GetStatus(NUTDEVICE * dev, uint32_t * status)
00544 {
00545 AHDLCDCB *dcb = dev->dev_dcb;
00546
00547
00548 *status = 0;
00549
00550 #ifdef __AVR_ENHANCED__
00551 if (dev->dev_base) {
00552 #ifdef UART1_CTS_BIT
00553 if (bit_is_set(UART1_CTS_PIN, UART1_CTS_BIT))
00554 *status |= UART_CTSDISABLED;
00555 else
00556 *status |= UART_CTSENABLED;
00557 #endif
00558 #ifdef UART1_RTS_BIT
00559 if (bit_is_set(UART1_RTS_PORT, UART1_RTS_BIT))
00560 *status |= UART_RTSDISABLED;
00561 else
00562 *status |= UART_RTSENABLED;
00563 #endif
00564 #ifdef UART1_DTR_BIT
00565 if (bit_is_set(UART1_DTR_PORT, UART1_DTR_BIT))
00566 *status |= UART_DTRDISABLED;
00567 else
00568 *status |= UART_DTRENABLED;
00569 #endif
00570 us = inb(UCSR1A);
00571 } else
00572 #endif
00573 {
00574 #ifdef UART0_CTS_BIT
00575 if (bit_is_set(UART0_CTS_PIN, UART0_CTS_BIT))
00576 *status |= UART_CTSDISABLED;
00577 else
00578 *status |= UART_CTSENABLED;
00579 #endif
00580 #ifdef UART0_RTS_BIT
00581 if (bit_is_set(UART0_RTS_PORT, UART0_RTS_BIT))
00582 *status |= UART_RTSDISABLED;
00583 else
00584 *status |= UART_RTSENABLED;
00585 #endif
00586 #ifdef UART0_DTR_BIT
00587 if (bit_is_set(UART0_DTR_PORT, UART0_DTR_BIT))
00588 *status |= UART_DTRDISABLED;
00589 else
00590 *status |= UART_DTRENABLED;
00591 #endif
00592
00593 }
00594
00595
00596
00597
00598 if (dcb->dcb_tx_idx == dcb->dcb_wr_idx)
00599 *status |= UART_TXBUFFEREMPTY;
00600 if (dcb->dcb_rd_idx == dcb->dcb_rx_idx)
00601 *status |= UART_RXBUFFEREMPTY;
00602
00603 return 0;
00604 }
00605
00606
00607
00608
00609
00610
00611 static int AhdlcAt91SetStatus(NUTDEVICE * dev, uint32_t status)
00612 {
00613
00614 #ifdef __AVR_ENHANCED__
00615 if (dev->dev_base) {
00616 #ifdef UART1_RTS_BIT
00617 if (status & UART_RTSDISABLED)
00618 sbi(UART1_RTS_PORT, UART1_RTS_BIT);
00619 else if (status & UART_RTSENABLED)
00620 cbi(UART1_RTS_PORT, UART1_RTS_BIT);
00621 #endif
00622 #ifdef UART1_DTR_BIT
00623 if (status & UART_DTRDISABLED)
00624 sbi(UART1_DTR_PORT, UART1_DTR_BIT);
00625 else if (status & UART_DTRENABLED)
00626 cbi(UART1_DTR_PORT, UART1_DTR_BIT);
00627 #endif
00628 } else
00629 #endif
00630 {
00631 #ifdef UART0_RTS_BIT
00632 if (status & UART_RTSDISABLED)
00633 sbi(UART0_RTS_PORT, UART0_RTS_BIT);
00634 else if (status & UART_RTSENABLED)
00635 cbi(UART0_RTS_PORT, UART0_RTS_BIT);
00636 #endif
00637 #ifdef UART0_DTR_BIT
00638 if (status & UART_DTRDISABLED)
00639 sbi(UART0_DTR_PORT, UART0_DTR_BIT);
00640 else if (status & UART_DTRENABLED)
00641 cbi(UART0_DTR_PORT, UART0_DTR_BIT);
00642 #endif
00643 }
00644 return 0;
00645 }
00646
00647
00648
00649
00650 static void AhdlcAt91Enable(uint16_t base)
00651 {
00652
00653 NutEnterCritical();
00654
00655 outr(US1_RTOR, UART_RECEIVER_TIMEOUT);
00656 outr(USART1_BASE + PERIPH_PTCR_OFF, PDC_RXTEN);
00657 outr(US1_CR, US_TXEN | US_RXEN | US_STTTO);
00658
00659
00660 outr(US1_IER, US_ENDRX | US_RXBUFF | US_TIMEOUT);
00661
00662 NutIrqEnable(&SIG_UART);
00663
00664 NutExitCritical();
00665 }
00666
00667
00668
00669
00670
00671 static void AhdlcAt91Disable(uint16_t base)
00672 {
00673
00674 NutEnterCritical();
00675
00676 NutIrqDisable(&SIG_UART);
00677
00678 outr(US1_IDR, -1);
00679 outr(USART1_BASE + PERIPH_PTCR_OFF, PDC_RXTDIS);
00680
00681 NutExitCritical();
00682
00683
00684
00685 NutDelay(10);
00686
00687
00688
00689
00690 outr(US1_CR, US_RXDIS | US_TXDIS);
00691 }
00692
00730 int AhdlcAt91IOCtl(NUTDEVICE * dev, int req, void *conf)
00731 {
00732 int rc = 0;
00733 AHDLCDCB *dcb;
00734 void **ppv = (void **) conf;
00735 uint32_t *lvp = (uint32_t *) conf;
00736 uint8_t bv;
00737 ureg_t cs;
00738
00739 if (dev == 0) {
00740 dev = &devUsartAt910;
00741 }
00742
00743 dcb = dev->dev_dcb;
00744
00745 switch (req) {
00746
00747 case UART_SETSPEED:
00748
00749 AhdlcAt91Disable(dcb->dcb_base);
00750 #if defined(AT91_PLL_MAINCK)
00751 outr(USART1_BASE + US_BRGR_OFF, (At91GetMasterClock() / (8 * (*lvp)) + 1) / 2);
00752 #else
00753 outr(USART1_BASE + US_BRGR_OFF, (NutGetCpuClock() / (8 * (*lvp)) + 1) / 2);
00754 #endif
00755 AhdlcAt91Enable(dcb->dcb_base);
00756 break;
00757
00758 case UART_GETSPEED:
00759 cs = inr(USART1_BASE + US_MR_OFF);
00760 uint32_t clk;
00761 #if defined(AT91_PLL_MAINCK)
00762 clk = At91GetMasterClock();
00763 #else
00764 clk = NutGetCpuClock();
00765 #endif
00766 if ((cs & US_CLKS) == US_CLKS_MCK8) {
00767 clk /= 8;
00768 } else if ((cs & US_CLKS) != US_CLKS_MCK) {
00769 clk = 0;
00770 }
00771 *lvp = (clk / (16UL * (inr(USART1_BASE + US_BRGR_OFF) & 0xFFFF)));
00772 break;
00773
00774 case UART_GETSTATUS:
00775 AhdlcAt91GetStatus(dev, lvp);
00776 break;
00777 case UART_SETSTATUS:
00778 AhdlcAt91SetStatus(dev, *lvp);
00779 break;
00780
00781 case UART_SETREADTIMEOUT:
00782 dcb->dcb_rtimeout = *lvp;
00783 break;
00784 case UART_GETREADTIMEOUT:
00785 *lvp = dcb->dcb_rtimeout;
00786 break;
00787
00788 case UART_SETWRITETIMEOUT:
00789 dcb->dcb_wtimeout = *lvp;
00790 break;
00791 case UART_GETWRITETIMEOUT:
00792 *lvp = dcb->dcb_wtimeout;
00793 break;
00794
00795 case UART_SETLOCALECHO:
00796 bv = (uint8_t) (*lvp);
00797 if (bv)
00798 dcb->dcb_modeflags |= UART_MF_LOCALECHO;
00799 else
00800 dcb->dcb_modeflags &= ~UART_MF_LOCALECHO;
00801 break;
00802 case UART_GETLOCALECHO:
00803 if (dcb->dcb_modeflags & UART_MF_LOCALECHO)
00804 *lvp = 1;
00805 else
00806 *lvp = 0;
00807 break;
00808
00809 case UART_SETFLOWCONTROL:
00810 bv = (uint8_t) (*lvp);
00811 if (bv)
00812 dcb->dcb_modeflags |= UART_MF_LOCALECHO;
00813 else
00814 dcb->dcb_modeflags &= ~UART_MF_LOCALECHO;
00815 break;
00816 case UART_GETFLOWCONTROL:
00817 break;
00818
00819 case UART_SETRAWMODE:
00820 bv = (uint8_t) (*lvp);
00821 if (bv)
00822 dcb->dcb_modeflags |= UART_MF_RAWMODE;
00823 else
00824 dcb->dcb_modeflags &= ~UART_MF_RAWMODE;
00825 break;
00826
00827 case UART_GETRAWMODE:
00828 if (dcb->dcb_modeflags & UART_MF_RAWMODE)
00829 *lvp = 1;
00830 else
00831 *lvp = 0;
00832 break;
00833
00834 case HDLC_SETIFNET:
00835 if (ppv && (*ppv != 0)) {
00836 dev->dev_icb = *ppv;
00837 dev->dev_type = IFTYP_NET;
00838 NutEventPost(&dcb->dcb_mf_evt);
00839 } else {
00840
00841 dev->dev_type = IFTYP_CHAR;
00842
00843 if (dev->dev_icb != 0) {
00844 dev->dev_icb = 0;
00845
00846
00847
00848
00849 NutEventPost(&dcb->dcb_rx_rdy);
00850 }
00851 }
00852 break;
00853
00854 case HDLC_GETIFNET:
00855 *ppv = dev->dev_icb;
00856 break;
00857
00858 default:
00859 rc = -1;
00860 break;
00861 }
00862 return rc;
00863 }
00864
00865
00878 int AhdlcAt91Init(NUTDEVICE * dev)
00879 {
00880 int rc = 0;
00881 AHDLCDCB *dcb;
00882
00883
00884
00885 AhdlcAt91Disable(dev->dev_base);
00886
00887
00888 dcb = dev->dev_dcb;
00889 memset(dcb, 0, sizeof(AHDLCDCB));
00890 dcb->dcb_base = dev->dev_base;
00891 dcb->dcb_rx_buf = NutHeapAlloc(256);
00892 dcb->dcb_tx_buf = NutHeapAlloc(256);
00893 dcb->dcb_rx_mru = 1500;
00894 dcb->dcb_tx_mru = 1500;
00895 dcb->dcb_tx_accm = 0xFFFFFFFF;
00896
00897
00898 if (NutRegisterIrqHandler(&SIG_UART, At91UsartInterrupt, dcb)) {
00899 return -1;
00900 }
00901
00902 outr(PMC_PCER, _BV(US1_ID));
00903
00904 outr(PIOA_PDR, US_GPIO_PINS);
00905
00906
00907 outr(US1_CR, US_RSTRX | US_RSTTX | US_RXDIS | US_TXDIS);
00908
00909 outr(US1_IDR, 0xFFFFFFFF);
00910
00911 #if defined (US_RCR_OFF)
00912 outr(US1_RCR, 0);
00913 #endif
00914 #if defined (US_TCR_OFF)
00915 outr(US1_TCR, 0);
00916 #endif
00917
00918 #if defined(AT91_PLL_MAINCK)
00919 outr(US1_BRGR, (At91GetMasterClock() / (8 * (115200)) + 1) / 2);
00920 #else
00921 outr(US1_BRGR, (NutGetCpuClock() / (8 * (115200)) + 1) / 2);
00922 #endif
00923
00924 outr(US1_MR, US_CHMODE_NORMAL | US_CHRL_8 | US_PAR_NO | US_NBSTOP_1 | US_MODE_HWHANDSHAKE);
00925
00926
00927 outr(USART1_BASE + PERIPH_PTCR_OFF, PDC_RXTDIS);
00928 outr(USART1_BASE + PERIPH_RPR_OFF, (unsigned int) DMA_RxBuf0);
00929 outr(USART1_BASE + PERIPH_RCR_OFF, NUT_AHDLC_RECV_DMA_SIZE);
00930 outr(USART1_BASE + PERIPH_RNPR_OFF, 0);
00931 outr(USART1_BASE + PERIPH_RNCR_OFF, 0);
00932
00933
00934
00935
00936
00937 if (rc == 0 && NutThreadCreate("ahdlcrx", AhdlcRx, dev,
00938 (NUT_THREAD_AHDLCRXSTACK * NUT_THREAD_STACK_MULT) + NUT_THREAD_STACK_ADD)) {
00939
00940 return 0;
00941 }
00942
00943
00944 if (dcb->dcb_rx_buf)
00945 NutHeapFree((void *) dcb->dcb_rx_buf);
00946 if (dcb->dcb_tx_buf)
00947 NutHeapFree((void *) dcb->dcb_tx_buf);
00948
00949 return -1;
00950 }
00951
00952
00953
00954
00981 int AhdlcAt91Read(NUTFILE * fp, void *buffer, int size)
00982 {
00983 int rc = 0;
00984 AHDLCDCB *dcb = fp->nf_dev->dev_dcb;
00985 uint8_t *cp = buffer;
00986
00987
00988
00989
00990 if (buffer) {
00991 while (rc < size) {
00992 if (dcb->dcb_rd_idx != dcb->dcb_rx_idx) {
00993 *cp++ = dcb->dcb_rx_buf[dcb->dcb_rd_idx++];
00994 rc++;
00995 } else if (rc || NutEventWait(&dcb->dcb_rx_rdy, dcb->dcb_rtimeout))
00996 break;
00997 }
00998 }
00999
01000
01001
01002
01003 else
01004 dcb->dcb_rd_idx = dcb->dcb_rx_idx;
01005
01006 return rc;
01007 }
01008
01021 int AhdlcAt91Put(NUTDEVICE * dev, CONST void *buffer, int len, int pflg)
01022 {
01023 int rc = 0;
01024 AHDLCDCB *dcb = dev->dev_dcb;
01025 CONST uint8_t *cp = buffer;
01026
01027
01028
01029
01030 if (buffer) {
01031 while (rc < len) {
01032 if (SendRawByte(dcb, pflg ? PRG_RDB(cp) : *cp, 0))
01033 break;
01034 cp++;
01035 rc++;
01036 }
01037 }
01038
01039
01040
01041
01042 else {
01043
01044 NutEnterCritical();
01045
01046 outr(US1_IER, US_TXRDY);
01047
01048 NutExitCritical();
01049 }
01050 return rc;
01051 }
01052
01072 int AhdlcAt91Write(NUTFILE * fp, CONST void *buffer, int len)
01073 {
01074 return AhdlcAt91Put(fp->nf_dev, buffer, len, 0);
01075 }
01076
01098 int AhdlcAt91Write_P(NUTFILE * fp, PGM_P buffer, int len)
01099 {
01100 return AhdlcAt91Put(fp->nf_dev, (CONST char *) buffer, len, 1);
01101 }
01102
01119 NUTFILE *AhdlcAt91Open(NUTDEVICE * dev, CONST char *name, int mode, int acc)
01120 {
01121 NUTFILE *fp;
01122
01123 if ((fp = NutHeapAlloc(sizeof(NUTFILE))) == 0)
01124 return NUTFILE_EOF;
01125
01126 fp->nf_next = 0;
01127 fp->nf_dev = dev;
01128 fp->nf_fcb = 0;
01129
01130 outr(US1_RTOR, UART_RECEIVER_TIMEOUT);
01131 outr(USART1_BASE + PERIPH_PTCR_OFF, PDC_RXTEN);
01132 outr(US1_CR, US_TXEN | US_RXEN | US_STTTO);
01133
01134
01135 outr(US1_IER, US_ENDRX | US_RXBUFF | US_TIMEOUT);
01136
01137 NutEnterCritical();
01138
01139 NutIrqEnable(&SIG_UART);
01140
01141 NutExitCritical();
01142
01143 return fp;
01144 }
01145
01159 int AhdlcAt91Close(NUTFILE * fp)
01160 {
01161 if (fp && fp != NUTFILE_EOF) {
01162 NutHeapFree(fp);
01163 return 0;
01164 }
01165 return -1;
01166 }
01167