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
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 #include <cfg/ahdlc.h>
00086
00087 #include <string.h>
00088 #include <stdlib.h>
00089
00090 #include <sys/nutconfig.h>
00091 #include <sys/atom.h>
00092 #include <sys/heap.h>
00093 #include <sys/event.h>
00094 #include <sys/timer.h>
00095 #include <sys/thread.h>
00096
00097 #include <dev/irqreg.h>
00098 #include <dev/uartavr.h>
00099
00100 #include <fcntl.h>
00101
00102 #include <dev/ppp.h>
00103 #include <dev/ahdlcavr.h>
00104
00105 #include <stdio.h>
00106
00111
00112
00113
00114
00115 static prog_char fcstab[512] = {
00116 0x00, 0x00, 0x11, 0x89, 0x23, 0x12, 0x32, 0x9b, 0x46, 0x24, 0x57, 0xad, 0x65, 0x36, 0x74, 0xbf,
00117 0x8c, 0x48, 0x9d, 0xc1, 0xaf, 0x5a, 0xbe, 0xd3, 0xca, 0x6c, 0xdb, 0xe5, 0xe9, 0x7e, 0xf8, 0xf7,
00118 0x10, 0x81, 0x01, 0x08, 0x33, 0x93, 0x22, 0x1a, 0x56, 0xa5, 0x47, 0x2c, 0x75, 0xb7, 0x64, 0x3e,
00119 0x9c, 0xc9, 0x8d, 0x40, 0xbf, 0xdb, 0xae, 0x52, 0xda, 0xed, 0xcb, 0x64, 0xf9, 0xff, 0xe8, 0x76,
00120 0x21, 0x02, 0x30, 0x8b, 0x02, 0x10, 0x13, 0x99, 0x67, 0x26, 0x76, 0xaf, 0x44, 0x34, 0x55, 0xbd,
00121 0xad, 0x4a, 0xbc, 0xc3, 0x8e, 0x58, 0x9f, 0xd1, 0xeb, 0x6e, 0xfa, 0xe7, 0xc8, 0x7c, 0xd9, 0xf5,
00122 0x31, 0x83, 0x20, 0x0a, 0x12, 0x91, 0x03, 0x18, 0x77, 0xa7, 0x66, 0x2e, 0x54, 0xb5, 0x45, 0x3c,
00123 0xbd, 0xcb, 0xac, 0x42, 0x9e, 0xd9, 0x8f, 0x50, 0xfb, 0xef, 0xea, 0x66, 0xd8, 0xfd, 0xc9, 0x74,
00124
00125 0x42, 0x04, 0x53, 0x8d, 0x61, 0x16, 0x70, 0x9f, 0x04, 0x20, 0x15, 0xa9, 0x27, 0x32, 0x36, 0xbb,
00126 0xce, 0x4c, 0xdf, 0xc5, 0xed, 0x5e, 0xfc, 0xd7, 0x88, 0x68, 0x99, 0xe1, 0xab, 0x7a, 0xba, 0xf3,
00127 0x52, 0x85, 0x43, 0x0c, 0x71, 0x97, 0x60, 0x1e, 0x14, 0xa1, 0x05, 0x28, 0x37, 0xb3, 0x26, 0x3a,
00128 0xde, 0xcd, 0xcf, 0x44, 0xfd, 0xdf, 0xec, 0x56, 0x98, 0xe9, 0x89, 0x60, 0xbb, 0xfb, 0xaa, 0x72,
00129 0x63, 0x06, 0x72, 0x8f, 0x40, 0x14, 0x51, 0x9d, 0x25, 0x22, 0x34, 0xab, 0x06, 0x30, 0x17, 0xb9,
00130 0xef, 0x4e, 0xfe, 0xc7, 0xcc, 0x5c, 0xdd, 0xd5, 0xa9, 0x6a, 0xb8, 0xe3, 0x8a, 0x78, 0x9b, 0xf1,
00131 0x73, 0x87, 0x62, 0x0e, 0x50, 0x95, 0x41, 0x1c, 0x35, 0xa3, 0x24, 0x2a, 0x16, 0xb1, 0x07, 0x38,
00132 0xff, 0xcf, 0xee, 0x46, 0xdc, 0xdd, 0xcd, 0x54, 0xb9, 0xeb, 0xa8, 0x62, 0x9a, 0xf9, 0x8b, 0x70,
00133
00134 0x84, 0x08, 0x95, 0x81, 0xa7, 0x1a, 0xb6, 0x93, 0xc2, 0x2c, 0xd3, 0xa5, 0xe1, 0x3e, 0xf0, 0xb7,
00135 0x08, 0x40, 0x19, 0xc9, 0x2b, 0x52, 0x3a, 0xdb, 0x4e, 0x64, 0x5f, 0xed, 0x6d, 0x76, 0x7c, 0xff,
00136 0x94, 0x89, 0x85, 0x00, 0xb7, 0x9b, 0xa6, 0x12, 0xd2, 0xad, 0xc3, 0x24, 0xf1, 0xbf, 0xe0, 0x36,
00137 0x18, 0xc1, 0x09, 0x48, 0x3b, 0xd3, 0x2a, 0x5a, 0x5e, 0xe5, 0x4f, 0x6c, 0x7d, 0xf7, 0x6c, 0x7e,
00138 0xa5, 0x0a, 0xb4, 0x83, 0x86, 0x18, 0x97, 0x91, 0xe3, 0x2e, 0xf2, 0xa7, 0xc0, 0x3c, 0xd1, 0xb5,
00139 0x29, 0x42, 0x38, 0xcb, 0x0a, 0x50, 0x1b, 0xd9, 0x6f, 0x66, 0x7e, 0xef, 0x4c, 0x74, 0x5d, 0xfd,
00140 0xb5, 0x8b, 0xa4, 0x02, 0x96, 0x99, 0x87, 0x10, 0xf3, 0xaf, 0xe2, 0x26, 0xd0, 0xbd, 0xc1, 0x34,
00141 0x39, 0xc3, 0x28, 0x4a, 0x1a, 0xd1, 0x0b, 0x58, 0x7f, 0xe7, 0x6e, 0x6e, 0x5c, 0xf5, 0x4d, 0x7c,
00142
00143 0xc6, 0x0c, 0xd7, 0x85, 0xe5, 0x1e, 0xf4, 0x97, 0x80, 0x28, 0x91, 0xa1, 0xa3, 0x3a, 0xb2, 0xb3,
00144 0x4a, 0x44, 0x5b, 0xcd, 0x69, 0x56, 0x78, 0xdf, 0x0c, 0x60, 0x1d, 0xe9, 0x2f, 0x72, 0x3e, 0xfb,
00145 0xd6, 0x8d, 0xc7, 0x04, 0xf5, 0x9f, 0xe4, 0x16, 0x90, 0xa9, 0x81, 0x20, 0xb3, 0xbb, 0xa2, 0x32,
00146 0x5a, 0xc5, 0x4b, 0x4c, 0x79, 0xd7, 0x68, 0x5e, 0x1c, 0xe1, 0x0d, 0x68, 0x3f, 0xf3, 0x2e, 0x7a,
00147 0xe7, 0x0e, 0xf6, 0x87, 0xc4, 0x1c, 0xd5, 0x95, 0xa1, 0x2a, 0xb0, 0xa3, 0x82, 0x38, 0x93, 0xb1,
00148 0x6b, 0x46, 0x7a, 0xcf, 0x48, 0x54, 0x59, 0xdd, 0x2d, 0x62, 0x3c, 0xeb, 0x0e, 0x70, 0x1f, 0xf9,
00149 0xf7, 0x8f, 0xe6, 0x06, 0xd4, 0x9d, 0xc5, 0x14, 0xb1, 0xab, 0xa0, 0x22, 0x92, 0xb9, 0x83, 0x30,
00150 0x7b, 0xc7, 0x6a, 0x4e, 0x58, 0xd5, 0x49, 0x5c, 0x3d, 0xe3, 0x2c, 0x6a, 0x1e, 0xf1, 0x0f, 0x78
00151 };
00152
00156 #define IN_ACC_MAP(c, m) (( ((uint8_t) (c)) < 0x20) && ((m) & (1UL << (c))) != 0)
00157
00158 #ifndef NUT_THREAD_AHDLCRXSTACK
00159 #define NUT_THREAD_AHDLCRXSTACK 512
00160 #endif
00161
00162
00163
00164
00165 static void Tx0Complete(void *arg)
00166 {
00167 AHDLCDCB *dcb = arg;
00168
00169 if (dcb->dcb_tx_idx != dcb->dcb_wr_idx) {
00170 #ifdef UART0_CTS_BIT
00171 if (bit_is_set(UART0_CTS_PIN, UART0_CTS_BIT)) {
00172 cbi(UCR, UDRIE);
00173 return;
00174 }
00175 #endif
00176 outp(dcb->dcb_tx_buf[dcb->dcb_tx_idx], UDR);
00177 dcb->dcb_tx_idx++;
00178 } else {
00179 cbi(UCR, UDRIE);
00180 NutEventPostFromIrq(&dcb->dcb_tx_rdy);
00181 }
00182 }
00183
00184 #ifdef UART0_CTS_BIT
00185
00186
00187
00188 static void Cts0Interrupt(void *arg)
00189 {
00190 sbi(UCR, UDRIE);
00191 }
00192 #endif
00193
00194 #ifdef __AVR_ENHANCED__
00195
00196
00197
00198 static void Tx1Complete(void *arg)
00199 {
00200 register AHDLCDCB *dcb = arg;
00201
00202 if (dcb->dcb_tx_idx != dcb->dcb_wr_idx) {
00203 #ifdef UART1_CTS_BIT
00204 if (bit_is_set(UART1_CTS_PIN, UART1_CTS_BIT)) {
00205 cbi(UCSR1B, UDRIE);
00206 return;
00207 }
00208 #endif
00209 outp(dcb->dcb_tx_buf[dcb->dcb_tx_idx], UDR1);
00210 dcb->dcb_tx_idx++;
00211 } else {
00212 cbi(UCSR1B, UDRIE);
00213 NutEventPostFromIrq(&dcb->dcb_tx_rdy);
00214 }
00215 }
00216
00217 #ifdef UART1_CTS_BIT
00218
00219
00220
00221 static void Cts1Interrupt(void *arg)
00222 {
00223 sbi(UCSR1B, UDRIE);
00224 }
00225 #endif
00226
00227 #endif
00228
00229
00230
00231
00232 static void Rx0Complete(void *arg)
00233 {
00234 AHDLCDCB *dcb = arg;
00235
00236 dcb->dcb_rx_buf[dcb->dcb_rx_idx] = inp(UDR);
00237 if (dcb->dcb_rd_idx == dcb->dcb_rx_idx)
00238 NutEventPostFromIrq(&dcb->dcb_rx_rdy);
00239
00240 dcb->dcb_rx_idx++;
00241 }
00242
00243 #ifdef __AVR_ENHANCED__
00244
00245
00246
00247 static void Rx1Complete(void *arg)
00248 {
00249 AHDLCDCB *dcb = arg;
00250
00251 dcb->dcb_rx_buf[dcb->dcb_rx_idx] = inp(UDR1);
00252 if (dcb->dcb_rd_idx == dcb->dcb_rx_idx)
00253 NutEventPostFromIrq(&dcb->dcb_rx_rdy);
00254
00255 dcb->dcb_rx_idx++;
00256 }
00257 #endif
00258
00259
00260
00261
00262 static int SendRawByte(AHDLCDCB * dcb, uint8_t ch, uint8_t flush)
00263 {
00264
00265
00266
00267
00268 while ((uint8_t) (dcb->dcb_wr_idx + 1) == dcb->dcb_tx_idx) {
00269 if (NutEventWait(&dcb->dcb_tx_rdy, dcb->dcb_wtimeout))
00270 break;
00271 }
00272
00273
00274
00275
00276 if ((uint8_t) (dcb->dcb_wr_idx + 1) == dcb->dcb_tx_idx) {
00277 return -1;
00278 }
00279
00280
00281
00282
00283
00284 dcb->dcb_tx_buf[dcb->dcb_wr_idx] = ch;
00285 dcb->dcb_wr_idx++;
00286
00287
00288
00289
00290
00291 if (flush || (uint8_t) (dcb->dcb_wr_idx + 1) == dcb->dcb_tx_idx) {
00292
00293
00294
00295
00296 NutEnterCritical();
00297 #ifdef __AVR_ENHANCED__
00298 if (dcb->dcb_base)
00299 sbi(UCSR1B, UDRIE);
00300 else
00301 #endif
00302 sbi(UCR, UDRIE);
00303 NutExitCritical();
00304 }
00305 return 0;
00306 }
00307
00308
00309
00310
00311
00312
00313 static int SendHdlcData(AHDLCDCB * dcb, CONST uint8_t * data, uint16_t len, uint16_t * txfcs)
00314 {
00315 uint16_t tbx;
00316 register uint16_t fcs;
00317
00318 if (txfcs)
00319 fcs = *txfcs;
00320 else
00321 fcs = 0;
00322 while (len) {
00323 tbx = (uint16_t) ((uint8_t) fcs ^ *data) << 1;
00324 fcs >>= 8;
00325 fcs ^= ((uint16_t) PRG_RDB(fcstab + tbx) << 8) | PRG_RDB(fcstab + tbx + 1);
00326 if (IN_ACC_MAP(*data, dcb->dcb_tx_accm) || *data == AHDLC_FLAG || *data == AHDLC_ESCAPE) {
00327 if (SendRawByte(dcb, AHDLC_ESCAPE, 0))
00328 return -1;
00329 if (SendRawByte(dcb, *data ^ AHDLC_TRANS, 0))
00330 return -1;
00331 } else if (SendRawByte(dcb, *data, 0))
00332 return -1;
00333 data++;
00334 len--;
00335 }
00336 if (txfcs)
00337 *txfcs = fcs;
00338
00339 return 0;
00340 }
00341
00352 int AhdlcOutput(NUTDEVICE * dev, NETBUF * nb)
00353 {
00354 uint16_t txfcs;
00355 AHDLCDCB *dcb = dev->dev_dcb;
00356 uint16_t sz;
00357
00358
00359
00360
00361
00362 if (dcb->dcb_modeflags & UART_MF_RAWMODE) {
00363 return 0;
00364 }
00365
00366
00367
00368
00369
00370 sz = nb->nb_dl.sz + nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz;
00371
00372 if (sz > dcb->dcb_tx_mru) {
00373 return -1;
00374 }
00375
00376
00377
00378
00379 SendRawByte(dcb, AHDLC_FLAG, 0);
00380
00381
00382 txfcs = AHDLC_INITFCS;
00383 if (SendHdlcData(dcb, nb->nb_dl.vp, nb->nb_dl.sz, &txfcs))
00384 return -1;
00385 if (SendHdlcData(dcb, nb->nb_nw.vp, nb->nb_nw.sz, &txfcs))
00386 return -1;
00387 if (SendHdlcData(dcb, nb->nb_tp.vp, nb->nb_tp.sz, &txfcs))
00388 return -1;
00389 if (SendHdlcData(dcb, nb->nb_ap.vp, nb->nb_ap.sz, &txfcs))
00390 return -1;
00391
00392
00393 txfcs ^= 0xffff;
00394 if (SendHdlcData(dcb, (uint8_t *) & txfcs, 2, 0))
00395 return -1;
00396 SendRawByte(dcb, AHDLC_FLAG, 1);
00397
00398 return 0;
00399 }
00400
00407 THREAD(AhdlcRx, arg)
00408 {
00409 NUTDEVICE *dev = arg;
00410 NUTDEVICE *netdev;
00411 AHDLCDCB *dcb = dev->dev_dcb;
00412 IFNET *ifn;
00413 NETBUF *nb;
00414 uint8_t *rxbuf;
00415 uint8_t *rxptr;
00416 uint16_t rxcnt;
00417 uint8_t ch;
00418 uint16_t tbx;
00419 uint8_t inframe;
00420 uint8_t escaped;
00421 uint16_t rxfcs;
00422
00423 NutThreadSetPriority(9);
00424 for (;;) {
00425
00426
00427
00428 rxptr = 0;
00429 rxcnt = 0;
00430 escaped = 0;
00431 rxfcs = AHDLC_INITFCS;
00432 inframe = 0;
00433
00434 for (;;) {
00435
00436
00437
00438
00439
00440
00441
00442 while ((netdev = dev->dev_icb) == 0) {
00443 NutEventWait(&dcb->dcb_mf_evt, 1000);
00444 }
00445 ifn = netdev->dev_icb;
00446 dcb->dcb_rtimeout = 1000;
00447 inframe = 0;
00448
00449
00450
00451
00452
00453
00454 if ((rxbuf = NutHeapAlloc(dcb->dcb_rx_mru)) != 0) {
00455 break;
00456 }
00457 NutSleep(1000);
00458 }
00459
00460
00461
00462
00463 ifn->if_send = AhdlcOutput;
00464 netdev->dev_ioctl(netdev, LCP_LOWERUP, 0);
00465
00466 for (;;) {
00467
00468
00469
00470
00471 while (dcb->dcb_rd_idx == dcb->dcb_rx_idx) {
00472 if (dev->dev_icb == 0)
00473 break;
00474
00475 if (NutEventWait(&dcb->dcb_rx_rdy, dcb->dcb_rtimeout)) {
00476 continue;
00477 }
00478 }
00479
00480
00481
00482
00483 if (dev->dev_icb == 0)
00484 break;
00485
00486
00487
00488
00489
00490 if (dcb->dcb_modeflags & UART_MF_RAWMODE) {
00491
00492
00493
00494
00495
00496 NutSleep(100);
00497 continue;
00498 }
00499
00500
00501
00502
00503 ch = dcb->dcb_rx_buf[dcb->dcb_rd_idx++];
00504
00505 if (inframe) {
00506 if (ch != AHDLC_FLAG) {
00507 if (ch == AHDLC_ESCAPE) {
00508 escaped = 1;
00509 continue;
00510 }
00511 if (escaped) {
00512 ch ^= AHDLC_TRANS;
00513 escaped = 0;
00514 }
00515
00516
00517
00518
00519
00520
00521 if (rxcnt++ < dcb->dcb_rx_mru) {
00522
00523 tbx = (uint16_t) ((uint8_t) rxfcs ^ ch) << 1;
00524 rxfcs >>= 8;
00525 rxfcs ^= ((uint16_t) PRG_RDB(fcstab + tbx) << 8) | PRG_RDB(fcstab + tbx + 1);
00526 *rxptr++ = ch;
00527 } else
00528 inframe = 0;
00529 continue;
00530 }
00531
00532 if (rxcnt > 6 && rxfcs == AHDLC_GOODFCS) {
00533
00534
00535
00536
00537 rxcnt -= 2;
00538 if ((nb = NutNetBufAlloc(0, NBAF_DATALINK, rxcnt)) != 0) {
00539 memcpy(nb->nb_dl.vp, rxbuf, rxcnt);
00540 (*ifn->if_recv) (netdev, nb);
00541 }
00542 }
00543 }
00544
00545
00546
00547
00548 if (ch == AHDLC_FLAG) {
00549 inframe = 1;
00550 escaped = 0;
00551 rxptr = rxbuf;
00552 rxcnt = 0;
00553 rxfcs = AHDLC_INITFCS;
00554 }
00555 }
00556
00557
00558 netdev->dev_ioctl(netdev, LCP_LOWERDOWN, 0);
00559
00560
00561 if (rxbuf) {
00562 NutHeapFree(rxbuf);
00563 rxbuf = 0;
00564 }
00565 }
00566 }
00567
00568
00569
00570
00571
00572
00573 static int AhdlcAvrGetStatus(NUTDEVICE * dev, uint32_t * status)
00574 {
00575 AHDLCDCB *dcb = dev->dev_dcb;
00576 uint8_t us;
00577
00578 *status = 0;
00579
00580 #ifdef __AVR_ENHANCED__
00581 if (dev->dev_base) {
00582 #ifdef UART1_CTS_BIT
00583 if (bit_is_set(UART1_CTS_PIN, UART1_CTS_BIT))
00584 *status |= UART_CTSDISABLED;
00585 else
00586 *status |= UART_CTSENABLED;
00587 #endif
00588 #ifdef UART1_RTS_BIT
00589 if (bit_is_set(UART1_RTS_PORT, UART1_RTS_BIT))
00590 *status |= UART_RTSDISABLED;
00591 else
00592 *status |= UART_RTSENABLED;
00593 #endif
00594 #ifdef UART1_DTR_BIT
00595 if (bit_is_set(UART1_DTR_PORT, UART1_DTR_BIT))
00596 *status |= UART_DTRDISABLED;
00597 else
00598 *status |= UART_DTRENABLED;
00599 #endif
00600 us = inp(UCSR1A);
00601 } else
00602 #endif
00603 {
00604 #ifdef UART0_CTS_BIT
00605 if (bit_is_set(UART0_CTS_PIN, UART0_CTS_BIT))
00606 *status |= UART_CTSDISABLED;
00607 else
00608 *status |= UART_CTSENABLED;
00609 #endif
00610 #ifdef UART0_RTS_BIT
00611 if (bit_is_set(UART0_RTS_PORT, UART0_RTS_BIT))
00612 *status |= UART_RTSDISABLED;
00613 else
00614 *status |= UART_RTSENABLED;
00615 #endif
00616 #ifdef UART0_DTR_BIT
00617 if (bit_is_set(UART0_DTR_PORT, UART0_DTR_BIT))
00618 *status |= UART_DTRDISABLED;
00619 else
00620 *status |= UART_DTRENABLED;
00621 #endif
00622 us = inp(USR);
00623 }
00624 if (us & FE)
00625 *status |= UART_FRAMINGERROR;
00626 if (us & DOR)
00627 *status |= UART_OVERRUNERROR;
00628 if (dcb->dcb_tx_idx == dcb->dcb_wr_idx)
00629 *status |= UART_TXBUFFEREMPTY;
00630 if (dcb->dcb_rd_idx == dcb->dcb_rx_idx)
00631 *status |= UART_RXBUFFEREMPTY;
00632
00633 return 0;
00634 }
00635
00636
00637
00638
00639
00640
00641 static int AhdlcAvrSetStatus(NUTDEVICE * dev, uint32_t status)
00642 {
00643 #ifdef __AVR_ENHANCED__
00644 if (dev->dev_base) {
00645 #ifdef UART1_RTS_BIT
00646 if (status & UART_RTSDISABLED)
00647 sbi(UART1_RTS_PORT, UART1_RTS_BIT);
00648 else if (status & UART_RTSENABLED)
00649 cbi(UART1_RTS_PORT, UART1_RTS_BIT);
00650 #endif
00651 #ifdef UART1_DTR_BIT
00652 if (status & UART_DTRDISABLED)
00653 sbi(UART1_DTR_PORT, UART1_DTR_BIT);
00654 else if (status & UART_DTRENABLED)
00655 cbi(UART1_DTR_PORT, UART1_DTR_BIT);
00656 #endif
00657 } else
00658 #endif
00659 {
00660 #ifdef UART0_RTS_BIT
00661 if (status & UART_RTSDISABLED)
00662 sbi(UART0_RTS_PORT, UART0_RTS_BIT);
00663 else if (status & UART_RTSENABLED)
00664 cbi(UART0_RTS_PORT, UART0_RTS_BIT);
00665 #endif
00666 #ifdef UART0_DTR_BIT
00667 if (status & UART_DTRDISABLED)
00668 sbi(UART0_DTR_PORT, UART0_DTR_BIT);
00669 else if (status & UART_DTRENABLED)
00670 cbi(UART0_DTR_PORT, UART0_DTR_BIT);
00671 #endif
00672 }
00673 return 0;
00674 }
00675
00676
00677
00678
00679 static void AhdlcAvrEnable(uint16_t base)
00680 {
00681 NutEnterCritical();
00682
00683 #ifdef __AVR_ENHANCED__
00684 if (base) {
00685 #ifdef UART1_CTS_BIT
00686 sbi(EIMSK, UART1_CTS_BIT);
00687 #endif
00688 outp(BV(RXCIE) | BV(RXEN) | BV(TXEN), UCSR1B);
00689 } else
00690 #endif
00691 {
00692 #ifdef UART0_CTS_BIT
00693 sbi(EIMSK, UART0_CTS_BIT);
00694 #endif
00695 outp(BV(RXCIE) | BV(RXEN) | BV(TXEN), UCR);
00696 }
00697 NutExitCritical();
00698 }
00699
00700
00701
00702
00703 static void AhdlcAvrDisable(uint16_t base)
00704 {
00705
00706
00707
00708 NutEnterCritical();
00709 #ifdef __AVR_ENHANCED__
00710 if (base) {
00711 #ifdef UART1_CTS_BIT
00712 cbi(EIMSK, UART1_CTS_BIT);
00713 #endif
00714 outp(inp(UCSR1B) & ~(BV(RXCIE) | BV(UDRIE)), UCSR1B);
00715 } else
00716 #endif
00717 {
00718 #ifdef UART0_CTS_BIT
00719 cbi(EIMSK, UART0_CTS_BIT);
00720 #endif
00721 outp(inp(UCR) & ~(BV(RXCIE) | BV(UDRIE)), UCR);
00722 }
00723 NutExitCritical();
00724
00725
00726
00727
00728 NutDelay(10);
00729
00730
00731
00732
00733 #ifdef __AVR_ENHANCED__
00734 if (base)
00735 outp(inp(UCSR1B) & ~(BV(RXEN) | BV(TXEN)), UCSR1B);
00736 else
00737 #endif
00738 outp(inp(UCR) & ~(BV(RXEN) | BV(TXEN)), UCR);
00739 }
00740
00784 int AhdlcAvrIOCtl(NUTDEVICE * dev, int req, void *conf)
00785 {
00786 int rc = 0;
00787 AHDLCDCB *dcb;
00788 void **ppv = (void **) conf;
00789 uint32_t *lvp = (uint32_t *) conf;
00790 uint8_t bv;
00791 uint16_t sv;
00792 uint8_t devnum;
00793
00794 if (dev == 0)
00795 dev = &devUart0;
00796
00797 devnum = dev->dev_base;
00798 dcb = dev->dev_dcb;
00799
00800 switch (req) {
00801 case UART_SETSPEED:
00802 AhdlcAvrDisable(devnum);
00803 sv = (uint16_t) ((((2UL * NutGetCpuClock()) / (*lvp * 16UL)) + 1UL) / 2UL) - 1;
00804 #ifdef __AVR_ENHANCED__
00805 if (devnum) {
00806 outp((uint8_t) sv, UBRR1L);
00807 outp((uint8_t) (sv >> 8), UBRR1H);
00808 } else {
00809 outp((uint8_t) sv, UBRR0L);
00810 outp((uint8_t) (sv >> 8), UBRR0H);
00811 }
00812 #else
00813 outp((uint8_t) sv, UBRR);
00814 #endif
00815 AhdlcAvrEnable(devnum);
00816 break;
00817
00818 case UART_GETSPEED:
00819 #ifdef __AVR_ENHANCED__
00820 if (devnum)
00821 sv = (uint16_t) inp(UBRR1H) << 8 | inp(UBRR1L);
00822 else
00823 sv = (uint16_t) inp(UBRR0H) << 8 | inp(UBRR0L);
00824 #else
00825 sv = inp(UBRR);
00826 #endif
00827 *lvp = NutGetCpuClock() / (16UL * (uint32_t) (sv + 1));
00828 break;
00829
00830 case UART_SETDATABITS:
00831 AhdlcAvrDisable(devnum);
00832 bv = (uint8_t)(*lvp);
00833 #ifdef __AVR_ENHANCED__
00834 if (bv >= 5 && bv <= 8) {
00835 bv = (bv - 5) << 1;
00836 if (devnum) {
00837 outp((inp(UCSR1C) & 0xF9) | bv, UCSR1C);
00838 outp(inp(UCSR1B) & 0xFB, UCSR1B);
00839 } else {
00840 outp((inp(UCSR0C) & 0xF9) | bv, UCSR0C);
00841 outp(inp(UCSR0B) & 0xFB, UCSR0B);
00842 }
00843 } else
00844 rc = -1;
00845 #else
00846 if (bv != 8)
00847 rc = -1;
00848 #endif
00849 AhdlcAvrEnable(devnum);
00850 break;
00851
00852 case UART_GETDATABITS:
00853 #ifdef __AVR_ENHANCED__
00854 if (devnum)
00855 *lvp = ((inp(UCSR1C) & 0x06) >> 1) + 5;
00856 else
00857 *lvp = ((inp(UCSR0C) & 0x06) >> 1) + 5;
00858 #else
00859 *lvp = 8;
00860 #endif
00861 break;
00862
00863 case UART_SETPARITY:
00864 AhdlcAvrDisable(devnum);
00865 bv = (uint8_t)(*lvp);
00866 #ifdef __AVR_ENHANCED__
00867 if (bv <= 2) {
00868 if (bv == 1)
00869 bv = 3;
00870 bv <<= 4;
00871 if (devnum)
00872 outp((inp(UCSR1C) & 0xCF) | bv, UCSR1C);
00873 else
00874 outp((inp(UCSR0C) & 0xCF) | bv, UCSR0C);
00875 } else
00876 rc = -1;
00877 #endif
00878 if (bv)
00879 rc = -1;
00880 AhdlcAvrEnable(devnum);
00881 break;
00882
00883 case UART_GETPARITY:
00884 #ifdef __AVR_ENHANCED__
00885 if (devnum)
00886 bv = (inp(UCSR1C) & 0x30) >> 4;
00887 else
00888 bv = (inp(UCSR0C) & 0x30) >> 4;
00889 if (bv == 3)
00890 bv = 1;
00891 #else
00892 bv = 0;
00893 #endif
00894 *lvp = bv;
00895 break;
00896
00897 case UART_SETSTOPBITS:
00898 AhdlcAvrDisable(devnum);
00899 bv = (uint8_t)(*lvp);
00900 #ifdef __AVR_ENHANCED__
00901 if (bv == 1 || bv == 2) {
00902 bv = (bv - 1) << 3;
00903 if (devnum)
00904 outp((inp(UCSR1C) & 0xF7) | bv, UCSR1C);
00905 else
00906 outp((inp(UCSR0C) & 0xF7) | bv, UCSR0C);
00907 } else
00908 rc = -1;
00909 #else
00910 if (bv != 1)
00911 rc = -1;
00912 #endif
00913 AhdlcAvrEnable(devnum);
00914 break;
00915
00916 case UART_GETSTOPBITS:
00917 #ifdef __AVR_ENHANCED__
00918 if (devnum)
00919 *lvp = ((inp(UCSR1C) & 0x08) >> 3) + 1;
00920 else
00921 *lvp = ((inp(UCSR0C) & 0x08) >> 3) + 1;
00922 #else
00923 *lvp = 1;
00924 #endif
00925 break;
00926
00927 case UART_GETSTATUS:
00928 AhdlcAvrGetStatus(dev, lvp);
00929 break;
00930 case UART_SETSTATUS:
00931 AhdlcAvrSetStatus(dev, *lvp);
00932 break;
00933
00934 case UART_SETREADTIMEOUT:
00935 dcb->dcb_rtimeout = *lvp;
00936 break;
00937 case UART_GETREADTIMEOUT:
00938 *lvp = dcb->dcb_rtimeout;
00939 break;
00940
00941 case UART_SETWRITETIMEOUT:
00942 dcb->dcb_wtimeout = *lvp;
00943 break;
00944 case UART_GETWRITETIMEOUT:
00945 *lvp = dcb->dcb_wtimeout;
00946 break;
00947
00948 case UART_SETLOCALECHO:
00949 bv = (uint8_t)(*lvp);
00950 if (bv)
00951 dcb->dcb_modeflags |= UART_MF_LOCALECHO;
00952 else
00953 dcb->dcb_modeflags &= ~UART_MF_LOCALECHO;
00954 break;
00955 case UART_GETLOCALECHO:
00956 if (dcb->dcb_modeflags & UART_MF_LOCALECHO)
00957 *lvp = 1;
00958 else
00959 *lvp = 0;
00960 break;
00961
00962 case UART_SETFLOWCONTROL:
00963 bv = (uint8_t)(*lvp);
00964 if (bv)
00965 dcb->dcb_modeflags |= UART_MF_LOCALECHO;
00966 else
00967 dcb->dcb_modeflags &= ~UART_MF_LOCALECHO;
00968 break;
00969 case UART_GETFLOWCONTROL:
00970 break;
00971
00972 case UART_SETRAWMODE:
00973 bv = (uint8_t)(*lvp);
00974 if (bv)
00975 dcb->dcb_modeflags |= UART_MF_RAWMODE;
00976 else
00977 dcb->dcb_modeflags &= ~UART_MF_RAWMODE;
00978 break;
00979
00980 case UART_GETRAWMODE:
00981 if (dcb->dcb_modeflags & UART_MF_RAWMODE)
00982 *lvp = 1;
00983 else
00984 *lvp = 0;
00985 break;
00986
00987 case HDLC_SETIFNET:
00988 if (ppv && (*ppv != 0)) {
00989 dev->dev_icb = *ppv;
00990 dev->dev_type = IFTYP_NET;
00991 NutEventPost(&dcb->dcb_mf_evt);
00992 } else {
00993 dev->dev_type = IFTYP_CHAR;
00994
00995 if (dev->dev_icb != 0)
00996 {
00997 dev->dev_icb = 0;
00998
00999
01000
01001
01002 NutEventPost(&dcb->dcb_rx_rdy);
01003 }
01004 }
01005 break;
01006 case HDLC_GETIFNET:
01007 *ppv = dev->dev_icb;
01008 break;
01009
01010 default:
01011 rc = -1;
01012 break;
01013 }
01014 return rc;
01015 }
01016
01029 int AhdlcAvrInit(NUTDEVICE * dev)
01030 {
01031 int rc = 0;
01032 AHDLCDCB *dcb;
01033 uint32_t baudrate = 9600;
01034
01035
01036 AhdlcAvrDisable(dev->dev_base);
01037
01038
01039 dcb = dev->dev_dcb;
01040 memset(dcb, 0, sizeof(AHDLCDCB));
01041 dcb->dcb_base = dev->dev_base;
01042 dcb->dcb_rx_buf = NutHeapAlloc(256);
01043 dcb->dcb_tx_buf = NutHeapAlloc(256);
01044 dcb->dcb_rx_mru = 1500;
01045 dcb->dcb_tx_mru = 1500;
01046 dcb->dcb_tx_accm = 0xFFFFFFFF;
01047
01048
01049
01050
01051 if (dev->dev_base) {
01052 #ifdef __AVR_ENHANCED__
01053
01054 #ifdef UART1_CTS_BIT
01055 sbi(UART1_CTS_PORT, UART1_CTS_BIT);
01056 cbi(UART1_CTS_DDR, UART1_CTS_BIT);
01057
01058 #if UART1_CTS_BIT == 4
01059 sbi(EICR, 1);
01060 #elif UART1_CTS_BIT == 5
01061 sbi(EICR, 3);
01062 #elif UART1_CTS_BIT == 6
01063 sbi(EICR, 5);
01064 #elif UART1_CTS_BIT == 7
01065 sbi(EICR, 7);
01066 #endif
01067 #endif
01068 #ifdef UART1_RTS_BIT
01069 sbi(UART1_RTS_PORT, UART1_RTS_BIT);
01070 sbi(UART1_RTS_DDR, UART1_RTS_BIT);
01071 #endif
01072 #ifdef UART1_DTR_BIT
01073 sbi(UART1_DTR_PORT, UART1_DTR_BIT);
01074 sbi(UART1_DTR_DDR, UART1_DTR_BIT);
01075 #endif
01076
01077 if (NutRegisterIrqHandler(&sig_UART1_RECV, Rx1Complete, dcb))
01078 rc = -1;
01079 else if (NutRegisterIrqHandler(&sig_UART1_DATA, Tx1Complete, dcb))
01080 #ifdef UART1_CTS_BIT
01081 rc = -1;
01082 else if (NutRegisterIrqHandler(&UART1_CTS_SIGNAL, Cts1Interrupt, dev))
01083 #endif
01084 #endif
01085 rc = -1;
01086
01087 } else {
01088
01089 #ifdef UART0_CTS_BIT
01090 sbi(UART0_CTS_PORT, UART0_CTS_BIT);
01091 cbi(UART0_CTS_DDR, UART0_CTS_BIT);
01092 #if UART0_CTS_BIT == 4
01093 sbi(EICR, 1);
01094 #elif UART0_CTS_BIT == 5
01095 sbi(EICR, 3);
01096 #elif UART0_CTS_BIT == 6
01097 sbi(EICR, 5);
01098 #elif UART0_CTS_BIT == 7
01099 sbi(EICR, 7);
01100 #endif
01101 #endif
01102 #ifdef UART0_RTS_BIT
01103 sbi(UART0_RTS_PORT, UART0_RTS_BIT);
01104 sbi(UART0_RTS_DDR, UART0_RTS_BIT);
01105 #endif
01106 #ifdef UART0_DTR_BIT
01107 sbi(UART0_DTR_PORT, UART0_DTR_BIT);
01108 sbi(UART0_DTR_DDR, UART0_DTR_BIT);
01109 #endif
01110
01111 if (NutRegisterIrqHandler(&sig_UART0_RECV, Rx0Complete, dcb))
01112 rc = -1;
01113 else if (NutRegisterIrqHandler(&sig_UART0_DATA, Tx0Complete, dcb))
01114 rc = -1;
01115 #ifdef UART0_CTS_BIT
01116 else if (NutRegisterIrqHandler(&UART0_CTS_SIGNAL, Cts0Interrupt, dev))
01117 rc = -1;
01118 #endif
01119 }
01120
01121
01122
01123
01124
01125
01126 if (rc == 0 && NutThreadCreate("ahdlcrx", AhdlcRx, dev,
01127 (NUT_THREAD_AHDLCRXSTACK * NUT_THREAD_STACK_MULT) + NUT_THREAD_STACK_ADD)) {
01128 AhdlcAvrIOCtl(dev, UART_SETSPEED, &baudrate);
01129
01130 return 0;
01131 }
01132
01133
01134 if (dcb->dcb_rx_buf)
01135 NutHeapFree((void *) dcb->dcb_rx_buf);
01136 if (dcb->dcb_tx_buf)
01137 NutHeapFree((void *) dcb->dcb_tx_buf);
01138
01139 return -1;
01140 }
01141
01168 int AhdlcAvrRead(NUTFILE * fp, void *buffer, int size)
01169 {
01170 int rc = 0;
01171 AHDLCDCB *dcb = fp->nf_dev->dev_dcb;
01172 uint8_t *cp = buffer;
01173
01174
01175
01176
01177 if (buffer) {
01178 while (rc < size) {
01179 if (dcb->dcb_rd_idx != dcb->dcb_rx_idx) {
01180 *cp++ = dcb->dcb_rx_buf[dcb->dcb_rd_idx++];
01181 rc++;
01182 } else if (rc || NutEventWait(&dcb->dcb_rx_rdy, dcb->dcb_rtimeout))
01183 break;
01184 }
01185 }
01186
01187
01188
01189
01190 else
01191 dcb->dcb_rd_idx = dcb->dcb_rx_idx;
01192
01193 return rc;
01194 }
01195
01208 int AhdlcAvrPut(NUTDEVICE * dev, CONST void *buffer, int len, int pflg)
01209 {
01210 int rc = 0;
01211 AHDLCDCB *dcb = dev->dev_dcb;
01212 CONST uint8_t *cp = buffer;
01213
01214
01215
01216
01217 if (buffer) {
01218 while (rc < len) {
01219 if (SendRawByte(dcb, pflg ? PRG_RDB(cp) : *cp, 0))
01220 break;
01221 cp++;
01222 rc++;
01223 }
01224 }
01225
01226
01227
01228
01229 else {
01230
01231
01232
01233 #ifdef __AVR_ENHANCED__
01234 if (dev->dev_base)
01235 sbi(UCSR1B, UDRIE);
01236 else
01237 #endif
01238 sbi(UCR, UDRIE);
01239 }
01240 return rc;
01241 }
01242
01262 int AhdlcAvrWrite(NUTFILE * fp, CONST void *buffer, int len)
01263 {
01264 return AhdlcAvrPut(fp->nf_dev, buffer, len, 0);
01265 }
01266
01288 int AhdlcAvrWrite_P(NUTFILE * fp, PGM_P buffer, int len)
01289 {
01290 return AhdlcAvrPut(fp->nf_dev, (CONST char *) buffer, len, 1);
01291 }
01292
01309 NUTFILE *AhdlcAvrOpen(NUTDEVICE * dev, CONST char *name, int mode, int acc)
01310 {
01311 NUTFILE *fp;
01312
01313 if ((fp = NutHeapAlloc(sizeof(NUTFILE))) == 0)
01314 return NUTFILE_EOF;
01315
01316 fp->nf_next = 0;
01317 fp->nf_dev = dev;
01318 fp->nf_fcb = 0;
01319
01320
01321 #ifdef __AVR_ENHANCED__
01322 if (dev->dev_base) {
01323 #ifdef UART1_RTS_BIT
01324 cbi(UART1_RTS_PORT, UART1_RTS_BIT);
01325 #endif
01326 #ifdef UART1_DTR_BIT
01327 cbi(UART1_DTR_PORT, UART1_DTR_BIT);
01328 #endif
01329 } else
01330 #endif
01331 {
01332 #ifdef UART0_RTS_BIT
01333 cbi(UART0_RTS_PORT, UART0_RTS_BIT);
01334 #endif
01335 #ifdef UART0_DTR_BIT
01336 cbi(UART0_DTR_PORT, UART0_DTR_BIT);
01337 #endif
01338 }
01339 return fp;
01340 }
01341
01355 int AhdlcAvrClose(NUTFILE * fp)
01356 {
01357 if (fp && fp != NUTFILE_EOF) {
01358
01359 #ifdef __AVR_ENHANCED__
01360 if (fp->nf_dev->dev_base) {
01361 #ifdef UART1_RTS_BIT
01362 sbi(UART1_RTS_PORT, UART1_RTS_BIT);
01363 #endif
01364 #ifdef UART1_DTR_BIT
01365 sbi(UART1_DTR_PORT, UART1_DTR_BIT);
01366 #endif
01367 } else
01368 #endif
01369 {
01370 #ifdef UART0_RTS_BIT
01371 sbi(UART0_RTS_PORT, UART0_RTS_BIT);
01372 #endif
01373 #ifdef UART0_DTR_BIT
01374 sbi(UART0_DTR_PORT, UART0_DTR_BIT);
01375 #endif
01376 }
01377 NutHeapFree(fp);
01378 return 0;
01379 }
01380 return -1;
01381 }
01382