00001
00044 #include "hw/hw_ser.h"
00045 #include <hw/hw_cpufreq.h>
00046
00047 #include "cfg/cfg_ser.h"
00048
00049 #include <cfg/macros.h>
00050 #include <cfg/debug.h>
00051
00052 #include <drv/ser.h>
00053 #include <drv/ser_p.h>
00054 #include <drv/timer.h>
00055
00056 #include <struct/fifobuf.h>
00057
00058 #include <avr/io.h>
00059 #include <avr/interrupt.h>
00060
00061
00062
00063
00064
00065
00066 #ifndef USART_SCALE_FACTOR
00067 #define USART_SCALE_FACTOR (-7)
00068 #else
00069 #if USART_SCALE_FACTOR > 7 || USART_SCALE_FACTOR < -7
00070 #error USART_SCALE_FACTOR should be an integer between -7 and 7
00071 #endif
00072 #endif
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 #define USART_SET_BAUDRATE(_usart, _bselValue, _bScaleFactor) \
00101 (_usart)->BAUDCTRLA =(uint8_t)_bselValue; \
00102 (_usart)->BAUDCTRLB =(_bScaleFactor << USART_BSCALE0_bp)|(_bselValue >> 8)
00103
00104
00105
00106
00107
00108 #define USART_RX_ENABLE(_usart) ((_usart)->CTRLB |= USART_RXEN_bm)
00109
00110
00111
00112
00113
00114 #define USART_RX_DISABLE(_usart) ((_usart)->CTRLB &= ~USART_RXEN_bm)
00115
00116
00117
00118
00119
00120 #define USART_TX_ENABLE(_usart) ((_usart)->CTRLB |= USART_TXEN_bm)
00121
00122
00123
00124
00125
00126 #define USART_TX_DISABLE(_usart) ((_usart)->CTRLB &= ~USART_TXEN_bm)
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 #define USART_SET_RX_INTERRUPT_LEVEL(_usart, _rxdIntLevel) \
00137 ((_usart)->CTRLA = ((_usart)->CTRLA & ~USART_RXCINTLVL_gm) | _rxdIntLevel)
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 #define USART_SET_TX_INTERRUPT_LEVEL(_usart, _txdIntLevel) \
00148 (_usart)->CTRLA = ((_usart)->CTRLA & ~USART_TXCINTLVL_gm) | _txdIntLevel
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 #define USART_SET_DRE_INTERRUPT_LEVEL(_usart, _dreIntLevel) \
00159 (_usart)->CTRLA = ((_usart)->CTRLA & ~USART_DREINTLVL_gm) | _dreIntLevel
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 #define USART_SET_MODE(_usart, _usartMode) \
00175 ((_usart)->CTRLC = ((_usart)->CTRLC & (~USART_CMODE_gm)) | _usartMode)
00176
00177
00178
00179
00180
00181 #define USART_IS_TX_DATA_REGISTER_EMPTY(_usart) (((_usart)->STATUS & USART_DREIF_bm) != 0)
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 #define USART_PUT_CHAR(_usart, _data) ((_usart)->DATA = _data)
00192
00193
00194
00195
00196
00197
00198
00199 #define USART_IS_RX_COMPLETE(_usart) (((_usart)->STATUS & USART_RXCIF_bm) != 0)
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 #define USART_GET_CHAR(_usart) ((_usart)->DATA)
00211
00212
00213
00214 #if !CONFIG_SER_HWHANDSHAKE
00215
00219 #define RTS_ON do {} while (0)
00220 #define RTS_OFF do {} while (0)
00221 #define IS_CTS_ON true
00222 #define EIMSKF_CTS 0
00223
00224 #endif
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 #ifndef SER_UART_BUS_TXINIT
00248
00249
00250
00251
00252
00253
00254 #define SER_UART_BUS_TXINIT(_usart) do { \
00255 USART_RX_ENABLE(_usart); \
00256 USART_TX_ENABLE(_usart); \
00257 USART_SET_RX_INTERRUPT_LEVEL(_usart, USART_RXCINTLVL_MED_gc); \
00258 } while (0)
00259 #endif
00260
00261 #ifndef SER_UART_BUS_TXBEGIN
00262
00263
00264
00265
00266
00267
00268 #define SER_UART_BUS_TXBEGIN(_usart) do { \
00269 USART_SET_RX_INTERRUPT_LEVEL(_usart, USART_RXCINTLVL_MED_gc); \
00270 USART_SET_DRE_INTERRUPT_LEVEL(_usart, USART_DREINTLVL_MED_gc);\
00271 } while (0)
00272 #endif
00273
00274 #ifndef SER_UART_BUS_TXCHAR
00275
00276
00277
00278 #define SER_UART_BUS_TXCHAR(_usart, c) do { \
00279 USART_PUT_CHAR(_usart, c); \
00280 } while (0)
00281 #endif
00282
00283 #ifndef SER_UART_BUS_TXEND
00284
00285
00286
00287
00288
00289
00290
00291 #define SER_UART_BUS_TXEND(_usart) do { \
00292 USART_SET_DRE_INTERRUPT_LEVEL(_usart, USART_DREINTLVL_OFF_gc); \
00293 } while (0)
00294 #endif
00295
00296 #ifndef SER_UART_BUS_TXOFF
00297
00298
00299
00300
00301
00302
00303
00304 #ifdef __doxygen__
00305 #define SER_UART_BUS_TXOFF(_usart)
00306 #endif
00307 #endif
00308
00309
00310
00311
00312 extern struct Serial *ser_handles[SER_CNT];
00313
00314
00315 static unsigned char uart0_txbuffer[CONFIG_UART0_TXBUFSIZE];
00316 static unsigned char uart0_rxbuffer[CONFIG_UART0_RXBUFSIZE];
00317 static unsigned char uart1_txbuffer[CONFIG_UART1_TXBUFSIZE];
00318 static unsigned char uart1_rxbuffer[CONFIG_UART1_RXBUFSIZE];
00319 #ifdef CPU_AVR_XMEGA_A
00320 static unsigned char uart2_txbuffer[CONFIG_UART2_TXBUFSIZE];
00321 static unsigned char uart2_rxbuffer[CONFIG_UART2_RXBUFSIZE];
00322 static unsigned char uart3_txbuffer[CONFIG_UART3_TXBUFSIZE];
00323 static unsigned char uart3_rxbuffer[CONFIG_UART3_RXBUFSIZE];
00324 static unsigned char uart4_txbuffer[CONFIG_UART4_TXBUFSIZE];
00325 static unsigned char uart4_rxbuffer[CONFIG_UART4_RXBUFSIZE];
00326 #endif
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 struct AvrxmegaSerial
00358 {
00359 struct SerialHardware hw;
00360 volatile bool sending;
00361 volatile USART_t* usart;
00362 volatile PORT_t* port;
00363 uint8_t txpin;
00364 uint8_t rxpin;
00365 };
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389 static void uart_init(struct SerialHardware * _hw, UNUSED_ARG(struct Serial *, ser))
00390 {
00391 struct AvrxmegaSerial *hw = (struct AvrxmegaSerial *)_hw;
00392
00393 hw->port->DIRSET = BV(hw->txpin);
00394 hw->port->OUTCLR = BV(hw->txpin);
00395
00396 hw->port->DIRCLR = BV(hw->rxpin);
00397
00398 SER_UART_BUS_TXINIT(hw->usart);
00399 RTS_ON;
00400 SER_STROBE_INIT;
00401 }
00402
00403
00404
00405
00406
00407
00408 static void uart_cleanup(struct SerialHardware * _hw)
00409 {
00410 struct AvrxmegaSerial *hw = (struct AvrxmegaSerial *)_hw;
00411 hw->usart->CTRLA = 0;
00412 hw->usart->CTRLB = 0;
00413 }
00414
00415
00416
00417
00418
00419
00420 static void uart_enabletxirq(struct SerialHardware *_hw)
00421 {
00422 struct AvrxmegaSerial *hw = (struct AvrxmegaSerial *)_hw;
00423
00424
00425
00426
00427
00428
00429 if (!hw->sending)
00430 {
00431 hw->sending = true;
00432 SER_UART_BUS_TXBEGIN(hw->usart);
00433 }
00434 }
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462 static void uart_setbaudrate(struct SerialHardware * _hw, unsigned long _rate)
00463 {
00464 struct AvrxmegaSerial *hw = (struct AvrxmegaSerial *)_hw;
00465
00466 #if USART_SCALE_FACTOR < 0
00467 uint16_t bsel = DIV_ROUND((1 << (-(USART_SCALE_FACTOR))) * (CPU_FREQ - (16 * _rate)), 16 * _rate);
00468 #else
00469 uint16_t bsel = DIV_ROUND(CPU_FREQ, (1 << (USART_SCALE_FACTOR)) * 16 * _rate) - 1;
00470 #endif
00471 USART_SET_BAUDRATE(hw->usart, bsel, USART_SCALE_FACTOR);
00472 }
00473
00474
00475
00476
00477
00478
00479
00480 static void uart_setparity(struct SerialHardware * _hw, int _parity)
00481 {
00482 struct AvrxmegaSerial *hw = (struct AvrxmegaSerial *)_hw;
00483 USART_SET_MODE(hw->usart, _parity);
00484 }
00485
00486
00487
00488
00489
00490
00491
00492 static bool tx_sending(struct SerialHardware* _hw)
00493 {
00494 struct AvrxmegaSerial *hw = (struct AvrxmegaSerial *)_hw;
00495 return hw->sending;
00496 }
00497
00498
00499
00500 #if COMPILER_C99
00501 #define C99INIT(name,val) .name = val
00502 #elif defined(__GNUC__)
00503 #define C99INIT(name,val) name: val
00504 #else
00505 #warning No designated initializers, double check your code
00506 #define C99INIT(name,val) (val)
00507 #endif
00508
00509
00510
00511
00512 static const struct SerialHardwareVT UART_VT =
00513 {
00514 C99INIT(init, uart_init),
00515 C99INIT(cleanup, uart_cleanup),
00516 C99INIT(setBaudrate, uart_setbaudrate),
00517 C99INIT(setParity, uart_setparity),
00518 C99INIT(txStart, uart_enabletxirq),
00519 C99INIT(txSending, tx_sending)
00520 };
00521
00522 static struct AvrxmegaSerial UARTDescs[SER_CNT] =
00523 {
00524 {
00525 C99INIT(hw, ) {
00526 C99INIT(table, &UART_VT),
00527 C99INIT(txbuffer, uart0_txbuffer),
00528 C99INIT(rxbuffer, uart0_rxbuffer),
00529 C99INIT(txbuffer_size, sizeof(uart0_txbuffer)),
00530 C99INIT(rxbuffer_size, sizeof(uart0_rxbuffer)),
00531 },
00532 C99INIT(sending, false),
00533 C99INIT(usart, &USARTC0),
00534 C99INIT(port, &PORTC),
00535 C99INIT(txpin, PIN3_bp),
00536 C99INIT(rxpin, PIN2_bp),
00537 },
00538 {
00539 C99INIT(hw, ) {
00540 C99INIT(table, &UART_VT),
00541 C99INIT(txbuffer, uart1_txbuffer),
00542 C99INIT(rxbuffer, uart1_rxbuffer),
00543 C99INIT(txbuffer_size, sizeof(uart1_txbuffer)),
00544 C99INIT(rxbuffer_size, sizeof(uart1_rxbuffer)),
00545 },
00546 C99INIT(sending, false),
00547 C99INIT(usart, &USARTD0),
00548 C99INIT(port, &PORTD),
00549 C99INIT(txpin, PIN3_bp),
00550 C99INIT(rxpin, PIN2_bp),
00551 },
00552 #ifdef CPU_AVR_XMEGA_A
00553 {
00554 C99INIT(hw, ) {
00555 C99INIT(table, &UART_VT),
00556 C99INIT(txbuffer, uart2_txbuffer),
00557 C99INIT(rxbuffer, uart2_rxbuffer),
00558 C99INIT(txbuffer_size, sizeof(uart2_txbuffer)),
00559 C99INIT(rxbuffer_size, sizeof(uart2_rxbuffer)),
00560 },
00561 C99INIT(sending, false),
00562 C99INIT(usart, &USARTC1),
00563 C99INIT(port, &PORTC),
00564 C99INIT(txpin, PIN7_bp),
00565 C99INIT(rxpin, PIN6_bp),
00566 },
00567 {
00568 C99INIT(hw, ) {
00569 C99INIT(table, &UART_VT),
00570 C99INIT(txbuffer, uart3_txbuffer),
00571 C99INIT(rxbuffer, uart3_rxbuffer),
00572 C99INIT(txbuffer_size, sizeof(uart3_txbuffer)),
00573 C99INIT(rxbuffer_size, sizeof(uart3_rxbuffer)),
00574 },
00575 C99INIT(sending, false),
00576 C99INIT(usart, &USARTD1),
00577 C99INIT(port, &PORTD),
00578 C99INIT(txpin, PIN7_bp),
00579 C99INIT(rxpin, PIN6_bp),
00580 },
00581 {
00582 C99INIT(hw, ) {
00583 C99INIT(table, &UART_VT),
00584 C99INIT(txbuffer, uart4_txbuffer),
00585 C99INIT(rxbuffer, uart4_rxbuffer),
00586 C99INIT(txbuffer_size, sizeof(uart4_txbuffer)),
00587 C99INIT(rxbuffer_size, sizeof(uart4_rxbuffer)),
00588 },
00589 C99INIT(sending, false),
00590 C99INIT(usart, &USARTE0),
00591 C99INIT(port, &PORTE),
00592 C99INIT(txpin, PIN3_bp),
00593 C99INIT(rxpin, PIN2_bp),
00594 },
00595 #endif //CPU_AVR_XMEGA_A
00596 };
00597
00598 struct SerialHardware *ser_hw_getdesc(int unit)
00599 {
00600 ASSERT(unit < SER_CNT);
00601 return &UARTDescs[unit].hw;
00602 }
00603
00604
00605
00606
00607
00608 static inline void usart_handleDreInterrupt(uint8_t usartNumber)
00609 {
00610 SER_STROBE_ON;
00611 struct FIFOBuffer * const txfifo = &ser_handles[usartNumber]->txfifo;
00612 if (fifo_isempty(txfifo))
00613 {
00614 SER_UART_BUS_TXEND(UARTDescs[usartNumber].usart);
00615 #ifndef SER_UART_BUS_TXOFF
00616 UARTDescs[usartNumber].sending = false;
00617 #endif
00618 }
00619 else
00620 {
00621 char c = fifo_pop(txfifo);
00622 SER_UART_BUS_TXCHAR(UARTDescs[usartNumber].usart, c);
00623 }
00624 SER_STROBE_OFF;
00625 }
00626
00627 #define USART_DRE_INTERRUPT_VECTOR(_vector, _usart) \
00628 DECLARE_ISR(_vector) \
00629 { \
00630 usart_handleDreInterrupt( _usart ); \
00631 }
00632
00633 USART_DRE_INTERRUPT_VECTOR(USARTC0_DRE_vect, SER_UART0)
00634 USART_DRE_INTERRUPT_VECTOR(USARTD0_DRE_vect, SER_UART1)
00635 #ifdef CPU_AVR_XMEGA_A
00636 USART_DRE_INTERRUPT_VECTOR(USARTC1_DRE_vect, SER_UART2)
00637 USART_DRE_INTERRUPT_VECTOR(USARTD1_DRE_VECT, SER_UART3)
00638 USART_DRE_INTERRUPT_VECTOR(USARTE0_DRE_vect, SER_UART4)
00639 #endif
00640
00641 #ifdef SER_UART_BUS_TXOFF
00642 static inline void USART_handleTXCInterrupt(uint8_t usartNumber)
00643 {
00644 SER_STROBE_ON;
00645 struct FIFOBuffer * const txfifo = &ser_handles[usartNumber]->txfifo;
00646 if (fifo_isempty(txfifo))
00647 {
00648 SER_UART_BUS_TXOFF(UARTDescs[usartNumber].usart);
00649 UARTDescs[usartNumber].sending = false;
00650 }
00651 else
00652 {
00653 SER_UART_BUS_TXBEGIN(UARTDescs[usartNumber].usart);
00654 }
00655 SER_STROBE_OFF;
00656 }
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673 #define USART_TXC_INTERRUPT_VECTOR(_vector, _usart) \
00674 DECLARE_ISR(_vector) \
00675 { \
00676 USART_handleTXCInterrupt( _usart ); \
00677 }
00678
00679 USART_TXC_INTERRUPT_VECTOR(USARTC0_TXC_vect, SER_UART0)
00680 USART_TXC_INTERRUPT_VECTOR(USARTD0_TXC_vect, SER_UART1)
00681 #ifdef CPU_AVR_XMEGA_A
00682 USART_TXC_INTERRUPT_VECTOR(USARTC1_TXC_vect, SER_UART2)
00683 USART_TXC_INTERRUPT_VECTOR(USARTD1_TXC_vect, SER_UART3)
00684 USART_TXC_INTERRUPT_VECTOR(USARTE0_TXC_vect, SER_UART4)
00685 #endif
00686 #endif
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697 static inline void USART_handleRXCInterrupt(uint8_t usartNumber)
00698 {
00699 SER_STROBE_ON;
00700
00701 ser_handles[usartNumber]->status |= (UARTDescs[usartNumber].usart)->STATUS & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
00702
00703
00704
00705
00706 char c = (UARTDescs[usartNumber].usart)->DATA;
00707 struct FIFOBuffer * const rxfifo = &ser_handles[usartNumber]->rxfifo;
00708 if (fifo_isfull(rxfifo))
00709 {
00710 ser_handles[usartNumber]->status |= SERRF_RXFIFOOVERRUN;
00711 }
00712 else
00713 {
00714 fifo_push(rxfifo, c);
00715 #if CONFIG_SER_HWHANDSHAKE
00716 if (fifo_isfull(rxfifo))
00717 {
00718 RTS_OFF(UARTDescs[usartNumber].usart);
00719 }
00720 #endif
00721 }
00722 SER_STROBE_OFF;
00723 }
00724
00725 #define USART_RXC_INTERRUPT_VECTOR(_vector, _usart) \
00726 DECLARE_ISR(_vector) \
00727 { \
00728 USART_handleRXCInterrupt( _usart ); \
00729 }
00730 USART_RXC_INTERRUPT_VECTOR(USARTC0_RXC_vect, SER_UART0)
00731 USART_RXC_INTERRUPT_VECTOR(USARTD0_RXC_vect, SER_UART1)
00732 #ifdef CPU_AVR_XMEGA_A
00733 USART_RXC_INTERRUPT_VECTOR(USARTC1_RXC_vect, SER_UART2)
00734 USART_RXC_INTERRUPT_VECTOR(USARTD1_RXC_vect, SER_UART3)
00735 USART_RXC_INTERRUPT_VECTOR(USARTE0_RXC_vect, SER_UART4)
00736 #endif