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