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 uint8_t devnum;
00738 ureg_t cs;
00739
00740 if (dev == 0) {
00741 dev = &devUsartAt910;
00742 }
00743
00744 devnum = dev->dev_base;
00745 dcb = dev->dev_dcb;
00746
00747 switch (req) {
00748
00749 case UART_SETSPEED:
00750
00751 AhdlcAt91Disable(dcb->dcb_base);
00752 #if defined(AT91_PLL_MAINCK)
00753 outr(USART1_BASE + US_BRGR_OFF, (At91GetMasterClock() / (8 * (*lvp)) + 1) / 2);
00754 #else
00755 outr(USART1_BASE + US_BRGR_OFF, (NutGetCpuClock() / (8 * (*lvp)) + 1) / 2);
00756 #endif
00757 AhdlcAt91Enable(dcb->dcb_base);
00758 break;
00759
00760 case UART_GETSPEED:
00761 cs = inr(USART1_BASE + US_MR_OFF);
00762 uint32_t clk;
00763 #if defined(AT91_PLL_MAINCK)
00764 clk = At91GetMasterClock();
00765 #else
00766 clk = NutGetCpuClock();
00767 #endif
00768 if ((cs & US_CLKS) == US_CLKS_MCK8) {
00769 clk /= 8;
00770 } else if ((cs & US_CLKS) != US_CLKS_MCK) {
00771 clk = 0;
00772 }
00773 *lvp = (clk / (16UL * (inr(USART1_BASE + US_BRGR_OFF) & 0xFFFF)));
00774 break;
00775
00776 case UART_GETSTATUS:
00777 AhdlcAt91GetStatus(dev, lvp);
00778 break;
00779 case UART_SETSTATUS:
00780 AhdlcAt91SetStatus(dev, *lvp);
00781 break;
00782
00783 case UART_SETREADTIMEOUT:
00784 dcb->dcb_rtimeout = *lvp;
00785 break;
00786 case UART_GETREADTIMEOUT:
00787 *lvp = dcb->dcb_rtimeout;
00788 break;
00789
00790 case UART_SETWRITETIMEOUT:
00791 dcb->dcb_wtimeout = *lvp;
00792 break;
00793 case UART_GETWRITETIMEOUT:
00794 *lvp = dcb->dcb_wtimeout;
00795 break;
00796
00797 case UART_SETLOCALECHO:
00798 bv = (uint8_t) (*lvp);
00799 if (bv)
00800 dcb->dcb_modeflags |= UART_MF_LOCALECHO;
00801 else
00802 dcb->dcb_modeflags &= ~UART_MF_LOCALECHO;
00803 break;
00804 case UART_GETLOCALECHO:
00805 if (dcb->dcb_modeflags & UART_MF_LOCALECHO)
00806 *lvp = 1;
00807 else
00808 *lvp = 0;
00809 break;
00810
00811 case UART_SETFLOWCONTROL:
00812 bv = (uint8_t) (*lvp);
00813 if (bv)
00814 dcb->dcb_modeflags |= UART_MF_LOCALECHO;
00815 else
00816 dcb->dcb_modeflags &= ~UART_MF_LOCALECHO;
00817 break;
00818 case UART_GETFLOWCONTROL:
00819 break;
00820
00821 case UART_SETRAWMODE:
00822 bv = (uint8_t) (*lvp);
00823 if (bv)
00824 dcb->dcb_modeflags |= UART_MF_RAWMODE;
00825 else
00826 dcb->dcb_modeflags &= ~UART_MF_RAWMODE;
00827 break;
00828
00829 case UART_GETRAWMODE:
00830 if (dcb->dcb_modeflags & UART_MF_RAWMODE)
00831 *lvp = 1;
00832 else
00833 *lvp = 0;
00834 break;
00835
00836 case HDLC_SETIFNET:
00837 if (ppv && (*ppv != 0)) {
00838 dev->dev_icb = *ppv;
00839 dev->dev_type = IFTYP_NET;
00840 NutEventPost(&dcb->dcb_mf_evt);
00841 } else {
00842
00843 dev->dev_type = IFTYP_CHAR;
00844
00845 if (dev->dev_icb != 0) {
00846 dev->dev_icb = 0;
00847
00848
00849
00850
00851 NutEventPost(&dcb->dcb_rx_rdy);
00852 }
00853 }
00854 break;
00855
00856 case HDLC_GETIFNET:
00857 *ppv = dev->dev_icb;
00858 break;
00859
00860 default:
00861 rc = -1;
00862 break;
00863 }
00864 return rc;
00865 }
00866
00867
00880 int AhdlcAt91Init(NUTDEVICE * dev)
00881 {
00882 int rc = 0;
00883 AHDLCDCB *dcb;
00884
00885
00886
00887 AhdlcAt91Disable(dev->dev_base);
00888
00889
00890 dcb = dev->dev_dcb;
00891 memset(dcb, 0, sizeof(AHDLCDCB));
00892 dcb->dcb_base = dev->dev_base;
00893 dcb->dcb_rx_buf = NutHeapAlloc(256);
00894 dcb->dcb_tx_buf = NutHeapAlloc(256);
00895 dcb->dcb_rx_mru = 1500;
00896 dcb->dcb_tx_mru = 1500;
00897 dcb->dcb_tx_accm = 0xFFFFFFFF;
00898
00899
00900 if (NutRegisterIrqHandler(&SIG_UART, At91UsartInterrupt, dcb)) {
00901 return -1;
00902 }
00903
00904 outr(PMC_PCER, _BV(US1_ID));
00905
00906 outr(PIOA_PDR, US_GPIO_PINS);
00907
00908
00909 outr(US1_CR, US_RSTRX | US_RSTTX | US_RXDIS | US_TXDIS);
00910
00911 outr(US1_IDR, 0xFFFFFFFF);
00912
00913 #if defined (US_RCR_OFF)
00914 outr(US1_RCR, 0);
00915 #endif
00916 #if defined (US_TCR_OFF)
00917 outr(US1_TCR, 0);
00918 #endif
00919
00920 #if defined(AT91_PLL_MAINCK)
00921 outr(US1_BRGR, (At91GetMasterClock() / (8 * (115200)) + 1) / 2);
00922 #else
00923 outr(US1_BRGR, (NutGetCpuClock() / (8 * (115200)) + 1) / 2);
00924 #endif
00925
00926 outr(US1_MR, US_CHMODE_NORMAL | US_CHRL_8 | US_PAR_NO | US_NBSTOP_1 | US_MODE_HWHANDSHAKE);
00927
00928
00929 outr(USART1_BASE + PERIPH_PTCR_OFF, PDC_RXTDIS);
00930 outr(USART1_BASE + PERIPH_RPR_OFF, (unsigned int) DMA_RxBuf0);
00931 outr(USART1_BASE + PERIPH_RCR_OFF, NUT_AHDLC_RECV_DMA_SIZE);
00932 outr(USART1_BASE + PERIPH_RNPR_OFF, 0);
00933 outr(USART1_BASE + PERIPH_RNCR_OFF, 0);
00934
00935
00936
00937
00938
00939 if (rc == 0 && NutThreadCreate("ahdlcrx", AhdlcRx, dev,
00940 (NUT_THREAD_AHDLCRXSTACK * NUT_THREAD_STACK_MULT) + NUT_THREAD_STACK_ADD)) {
00941
00942 return 0;
00943 }
00944
00945
00946 if (dcb->dcb_rx_buf)
00947 NutHeapFree((void *) dcb->dcb_rx_buf);
00948 if (dcb->dcb_tx_buf)
00949 NutHeapFree((void *) dcb->dcb_tx_buf);
00950
00951 return -1;
00952 }
00953
00954
00955
00956
00983 int AhdlcAt91Read(NUTFILE * fp, void *buffer, int size)
00984 {
00985 int rc = 0;
00986 AHDLCDCB *dcb = fp->nf_dev->dev_dcb;
00987 uint8_t *cp = buffer;
00988
00989
00990
00991
00992 if (buffer) {
00993 while (rc < size) {
00994 if (dcb->dcb_rd_idx != dcb->dcb_rx_idx) {
00995 *cp++ = dcb->dcb_rx_buf[dcb->dcb_rd_idx++];
00996 rc++;
00997 } else if (rc || NutEventWait(&dcb->dcb_rx_rdy, dcb->dcb_rtimeout))
00998 break;
00999 }
01000 }
01001
01002
01003
01004
01005 else
01006 dcb->dcb_rd_idx = dcb->dcb_rx_idx;
01007
01008 return rc;
01009 }
01010
01023 int AhdlcAt91Put(NUTDEVICE * dev, CONST void *buffer, int len, int pflg)
01024 {
01025 int rc = 0;
01026 AHDLCDCB *dcb = dev->dev_dcb;
01027 CONST uint8_t *cp = buffer;
01028
01029
01030
01031
01032 if (buffer) {
01033 while (rc < len) {
01034 if (SendRawByte(dcb, pflg ? PRG_RDB(cp) : *cp, 0))
01035 break;
01036 cp++;
01037 rc++;
01038 }
01039 }
01040
01041
01042
01043
01044 else {
01045
01046 NutEnterCritical();
01047
01048 outr(US1_IER, US_TXRDY);
01049
01050 NutExitCritical();
01051 }
01052 return rc;
01053 }
01054
01074 int AhdlcAt91Write(NUTFILE * fp, CONST void *buffer, int len)
01075 {
01076 return AhdlcAt91Put(fp->nf_dev, buffer, len, 0);
01077 }
01078
01100 int AhdlcAt91Write_P(NUTFILE * fp, PGM_P buffer, int len)
01101 {
01102 return AhdlcAt91Put(fp->nf_dev, (CONST char *) buffer, len, 1);
01103 }
01104
01121 NUTFILE *AhdlcAt91Open(NUTDEVICE * dev, CONST char *name, int mode, int acc)
01122 {
01123 NUTFILE *fp;
01124
01125 if ((fp = NutHeapAlloc(sizeof(NUTFILE))) == 0)
01126 return NUTFILE_EOF;
01127
01128 fp->nf_next = 0;
01129 fp->nf_dev = dev;
01130 fp->nf_fcb = 0;
01131
01132 outr(US1_RTOR, UART_RECEIVER_TIMEOUT);
01133 outr(USART1_BASE + PERIPH_PTCR_OFF, PDC_RXTEN);
01134 outr(US1_CR, US_TXEN | US_RXEN | US_STTTO);
01135
01136
01137 outr(US1_IER, US_ENDRX | US_RXBUFF | US_TIMEOUT);
01138
01139 NutEnterCritical();
01140
01141 NutIrqEnable(&SIG_UART);
01142
01143 NutExitCritical();
01144
01145 return fp;
01146 }
01147
01161 int AhdlcAt91Close(NUTFILE * fp)
01162 {
01163 if (fp && fp != NUTFILE_EOF) {
01164 NutHeapFree(fp);
01165 return 0;
01166 }
01167 return -1;
01168 }
01169