00001
00041 #include "hw/hw_ser.h"
00042 #include <hw/hw_cpufreq.h>
00043
00044 #include "cfg/cfg_ser.h"
00045 #include <cfg/debug.h>
00046
00047
00048
00049 #include <io/cm3.h>
00050 #include <drv/irq_cm3.h>
00051
00052 #include <cpu/attr.h>
00053
00054 #include <drv/ser.h>
00055 #include <drv/ser_p.h>
00056
00057 #include <struct/fifobuf.h>
00058
00059
00060 #define SERIRQ_PRIORITY 4 ///< default priority for serial irqs.
00061
00083 #ifndef SER_UART0_BUS_TXINIT
00084
00089 #if CPU_ARM_AT91 && !CPU_ARM_SAM7S_LARGE && !CPU_ARM_SAM7X
00090 #warning Check USART0 pins!
00091 #endif
00092 #define SER_UART0_BUS_TXINIT do { \
00093 PIOA_PDR = BV(RXD0) | BV(TXD0); \
00094 PIO_PERIPH_SEL(PIOA_BASE, BV(RXD0) | BV(TXD0), USART0_PERIPH); \
00095 } while (0)
00096 #endif
00097
00098 #ifndef SER_UART0_BUS_TXBEGIN
00099
00102 #define SER_UART0_BUS_TXBEGIN
00103 #endif
00104
00105 #ifndef SER_UART0_BUS_TXCHAR
00106
00109 #define SER_UART0_BUS_TXCHAR(c) do { \
00110 US0_THR = (c); \
00111 } while (0)
00112 #endif
00113
00114 #ifndef SER_UART0_BUS_TXEND
00115
00118 #define SER_UART0_BUS_TXEND
00119 #endif
00120
00121
00122
00123 #if USART_PORTS > 1
00124
00125 #ifndef SER_UART1_BUS_TXINIT
00126
00131 #if CPU_ARM_AT91 && !CPU_ARM_SAM7S_LARGE && !CPU_ARM_SAM7X
00132 #warning Check USART1 pins!
00133 #endif
00134 #define SER_UART1_BUS_TXINIT do { \
00135 PIOA_PDR = BV(RXD1) | BV(TXD1); \
00136 PIO_PERIPH_SEL(PIOA_BASE, BV(RXD1) | BV(TXD1), USART1_PERIPH); \
00137 } while (0)
00138 #endif
00139
00140 #ifndef SER_UART1_BUS_TXBEGIN
00141
00144 #define SER_UART1_BUS_TXBEGIN
00145 #endif
00146
00147 #ifndef SER_UART1_BUS_TXCHAR
00148
00151 #define SER_UART1_BUS_TXCHAR(c) do { \
00152 US1_THR = (c); \
00153 } while (0)
00154 #endif
00155
00156 #ifndef SER_UART1_BUS_TXEND
00157
00160 #define SER_UART1_BUS_TXEND
00161 #endif
00162
00163 #endif
00164
00174 #ifndef SER_SPI0_BUS_TXINIT
00175
00179 #if CPU_CM3_SAM3
00180 #define SER_SPI0_BUS_TXINIT do { \
00181 \
00182 PIOA_PDR = BV(SPI0_SPCK) | BV(SPI0_MOSI) | BV(SPI0_MISO); \
00183 \
00184 PIO_PERIPH_SEL(PIOA_BASE, BV(SPI0_SPCK) | BV(SPI0_MOSI) | BV(SPI0_MISO), PIO_PERIPH_A); \
00185 } while (0)
00186 #else
00187 #define SER_SPI0_BUS_TXINIT do { \
00188 \
00189 PIOA_PDR = BV(SPI0_SPCK) | BV(SPI0_MOSI) | BV(SPI0_MISO); \
00190 } while (0)
00191 #endif
00192 #endif
00193
00194 #ifndef SER_SPI0_BUS_TXCLOSE
00195
00199 #define SER_SPI0_BUS_TXCLOSE do { \
00200 \
00201 PIOA_PER = BV(SPI0_SPCK) | BV(SPI0_MOSI) | BV(SPI0_MISO); \
00202 } while (0)
00203 #endif
00204
00205 #if CPU_ARM_SAM7X
00206
00207 #ifndef SER_SPI1_BUS_TXINIT
00208
00212 #define SER_SPI1_BUS_TXINIT do { \
00213 \
00214 PIOA_PDR = BV(SPI1_SPCK) | BV(SPI1_MOSI) | BV(SPI1_MISO); \
00215 \
00216 PIOA_BSR = BV(SPI1_SPCK) | BV(SPI1_MOSI) | BV(SPI1_MISO); \
00217 } while (0)
00218 #endif
00219
00220 #ifndef SER_SPI1_BUS_TXCLOSE
00221
00225 #define SER_SPI1_BUS_TXCLOSE do { \
00226 \
00227 PIOA_PER = BV(SPI1_SPCK) | BV(SPI1_MOSI) | BV(SPI1_MISO); \
00228 } while (0)
00229 #endif
00230 #endif
00231
00232
00233
00244 #if CPU_ARM_AT91
00245
00246 INLINE void sysirq_setHandler(sysirq_t irq, sysirq_handler_t handler)
00247 {
00248
00249 AIC_SVR(irq) = uart0_irq_dispatcher;
00250
00251
00252 #if CPU_ARM_SAM7X
00253 if (irq == SPI0_ID || irq == SPI1_ID)
00254 #else
00255 if (irq == SPI0_ID)
00256 #endif
00257 AIC_SMR(irq) = (AIC_SMR(irq) & ~AIC_SRCTYPE_MASK) | AIC_SRCTYPE_INT_EDGE_TRIGGERED;
00258 else
00259 AIC_SMR(irq) = (AIC_SMR(irq) & ~AIC_SRCTYPE_MASK) | AIC_SRCTYPE_INT_LEVEL_SENSITIVE;
00260
00261
00262 AIC_IECR = BV(irq);
00263 }
00264
00265 INLINE void sysirq_setPriority(sysirq_t irq, int prio)
00266 {
00267 AIC_SMR(irq) = (AIC_SMR(irq) & ~AIC_PRIOR_MASK) | SERIRQ_PRIORITY;
00268 }
00269
00271 #define SER_INT_ACK do { \
00272 AIC_EOICR = 0; \
00273 } while (0)
00274
00275 #elif CPU_CM3_SAM3
00276
00278 #define SER_INT_ACK do { } while (0)
00279
00280 #else
00281 #error No interrupt handling macros defined for current architecture
00282 #endif
00283
00284
00285
00286
00287 extern struct Serial *ser_handles[SER_CNT];
00288
00289
00290 static unsigned char uart0_txbuffer[CONFIG_UART0_TXBUFSIZE];
00291 static unsigned char uart0_rxbuffer[CONFIG_UART0_RXBUFSIZE];
00292 #if USART_PORTS > 1
00293 static unsigned char uart1_txbuffer[CONFIG_UART1_TXBUFSIZE];
00294 static unsigned char uart1_rxbuffer[CONFIG_UART1_RXBUFSIZE];
00295 #endif
00296 static unsigned char spi0_txbuffer[CONFIG_SPI0_TXBUFSIZE];
00297 static unsigned char spi0_rxbuffer[CONFIG_SPI0_RXBUFSIZE];
00298 #if CPU_ARM_SAM7X
00299 static unsigned char spi1_txbuffer[CONFIG_SPI1_TXBUFSIZE];
00300 static unsigned char spi1_rxbuffer[CONFIG_SPI1_RXBUFSIZE];
00301 #endif
00302
00319 struct ArmSerial
00320 {
00321 struct SerialHardware hw;
00322 volatile bool sending;
00323 };
00324
00325 static ISR_PROTO(uart0_irq_dispatcher);
00326 #if USART_PORTS > 1
00327 static ISR_PROTO(uart1_irq_dispatcher);
00328 #endif
00329 static ISR_PROTO(spi0_irq_handler);
00330 #if CPU_ARM_SAM7X
00331 static ISR_PROTO(spi1_irq_handler);
00332 #endif
00333
00334
00335
00336 static void uart0_init(
00337 UNUSED_ARG(struct SerialHardware *, _hw),
00338 UNUSED_ARG(struct Serial *, ser))
00339 {
00340 US0_IDR = 0xFFFFFFFF;
00341 pmc_periphEnable(US0_ID);
00342
00343
00344
00345
00346
00347
00348
00349 US0_CR = BV(US_RSTRX) | BV(US_RSTTX);
00350 US0_MR = US_CHMODE_NORMAL | US_CHRL_8 | US_NBSTOP_1 | US_PAR_NO;
00351 US0_CR = BV(US_RXEN) | BV(US_TXEN);
00352 US0_IER = BV(US_RXRDY);
00353
00354 SER_UART0_BUS_TXINIT;
00355
00356 sysirq_setPriority(INT_US0, SERIRQ_PRIORITY);
00357 sysirq_setHandler(INT_US0, uart0_irq_dispatcher);
00358
00359 SER_STROBE_INIT;
00360 }
00361
00362 static void uart0_cleanup(UNUSED_ARG(struct SerialHardware *, _hw))
00363 {
00364 US0_CR = BV(US_RSTRX) | BV(US_RSTTX) | BV(US_RXDIS) | BV(US_TXDIS) | BV(US_RSTSTA);
00365 }
00366
00367 static void uart0_enabletxirq(struct SerialHardware *_hw)
00368 {
00369 struct ArmSerial *hw = (struct ArmSerial *)_hw;
00370
00371
00372
00373
00374
00375
00376 if (!hw->sending)
00377 {
00378 hw->sending = true;
00379
00380
00381
00382
00383 SER_UART0_BUS_TXBEGIN;
00384 US0_IER = BV(US_TXEMPTY);
00385 }
00386 }
00387
00388 static void uart0_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate)
00389 {
00390
00391 US0_BRGR = CPU_FREQ / (16 * rate);
00392
00393 }
00394
00395 static void uart0_setparity(UNUSED_ARG(struct SerialHardware *, _hw), int parity)
00396 {
00397 US0_MR &= ~US_PAR_MASK;
00398
00399 switch(parity)
00400 {
00401 case SER_PARITY_NONE:
00402 {
00403
00404 US0_MR |= US_PAR_NO;
00405 break;
00406 }
00407 case SER_PARITY_EVEN:
00408 {
00409
00410 US0_MR |= US_PAR_EVEN;
00411 break;
00412 }
00413 case SER_PARITY_ODD:
00414 {
00415
00416 US0_MR |= US_PAR_ODD;
00417 break;
00418 }
00419 default:
00420 ASSERT(0);
00421 }
00422 }
00423
00424 #if USART_PORTS > 1
00425
00426
00427
00428
00429 static void uart1_init(
00430 UNUSED_ARG(struct SerialHardware *, _hw),
00431 UNUSED_ARG(struct Serial *, ser))
00432 {
00433 US1_IDR = 0xFFFFFFFF;
00434 pmc_periphEnable(US1_ID);
00435
00436
00437
00438
00439
00440
00441
00442 US1_CR = BV(US_RSTRX) | BV(US_RSTTX);
00443 US1_MR = US_CHMODE_NORMAL | US_CHRL_8 | US_NBSTOP_1 | US_PAR_NO;
00444 US1_CR = BV(US_RXEN) | BV(US_TXEN);
00445 US1_IER = BV(US_RXRDY);
00446
00447 SER_UART1_BUS_TXINIT;
00448
00449 sysirq_setPriority(INT_US1, SERIRQ_PRIORITY);
00450 sysirq_setHandler(INT_US1, uart1_irq_dispatcher);
00451
00452 SER_STROBE_INIT;
00453 }
00454
00455 static void uart1_cleanup(UNUSED_ARG(struct SerialHardware *, _hw))
00456 {
00457 US1_CR = BV(US_RSTRX) | BV(US_RSTTX) | BV(US_RXDIS) | BV(US_TXDIS) | BV(US_RSTSTA);
00458 }
00459
00460 static void uart1_enabletxirq(struct SerialHardware *_hw)
00461 {
00462 struct ArmSerial *hw = (struct ArmSerial *)_hw;
00463
00464
00465
00466
00467
00468
00469 if (!hw->sending)
00470 {
00471 hw->sending = true;
00472
00473
00474
00475
00476 SER_UART1_BUS_TXBEGIN;
00477 US1_IER = BV(US_TXEMPTY);
00478 }
00479 }
00480
00481 static void uart1_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate)
00482 {
00483
00484 US1_BRGR = CPU_FREQ / (16 * rate);
00485
00486 }
00487
00488 static void uart1_setparity(UNUSED_ARG(struct SerialHardware *, _hw), int parity)
00489 {
00490 US1_MR &= ~US_PAR_MASK;
00491
00492 switch(parity)
00493 {
00494 case SER_PARITY_NONE:
00495 {
00496
00497 US1_MR |= US_PAR_NO;
00498 break;
00499 }
00500 case SER_PARITY_EVEN:
00501 {
00502
00503 US1_MR |= US_PAR_EVEN;
00504 break;
00505 }
00506 case SER_PARITY_ODD:
00507 {
00508
00509 US1_MR |= US_PAR_ODD;
00510 break;
00511 }
00512 default:
00513 ASSERT(0);
00514 }
00515 }
00516
00517 #endif
00518
00519
00520 static void spi0_init(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(struct Serial *, ser))
00521 {
00522 SER_SPI0_BUS_TXINIT;
00523
00524
00525 SPI0_CR = BV(SPI_SWRST);
00526
00527
00528
00529
00530
00531 SPI0_MR = BV(SPI_MSTR) | BV(SPI_MODFDIS);
00532
00533
00534
00535
00536
00537
00538
00539
00540 SPI0_CSR0 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT);
00541 SPI0_CSR1 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT);
00542 SPI0_CSR2 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT);
00543 SPI0_CSR3 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT);
00544
00545
00546 SPI0_IDR = 0xFFFFFFFF;
00547
00548
00549 sysirq_setHandler(INT_SPI0, spi0_irq_handler);
00550 pmc_periphEnable(SPI0_ID);
00551
00552
00553 SPI0_CR = BV(SPI_SPIEN);
00554
00555 SER_STROBE_INIT;
00556 }
00557
00558 static void spi0_cleanup(UNUSED_ARG(struct SerialHardware *, _hw))
00559 {
00560
00561 SPI0_CR = BV(SPI_SPIDIS);
00562
00563
00564 SPI0_IDR = 0xFFFFFFFF;
00565
00566 SER_SPI0_BUS_TXCLOSE;
00567 }
00568
00569 static void spi0_starttx(struct SerialHardware *_hw)
00570 {
00571 struct ArmSerial *hw = (struct ArmSerial *)_hw;
00572
00573 cpu_flags_t flags;
00574 IRQ_SAVE_DISABLE(flags);
00575
00576
00577 if (!hw->sending && !fifo_isempty(&ser_handles[SER_SPI0]->txfifo))
00578 {
00579 hw->sending = true;
00580 SPI0_TDR = fifo_pop(&ser_handles[SER_SPI0]->txfifo);
00581
00582 SPI0_IER = BV(SPI_TXEMPTY);
00583 }
00584
00585 IRQ_RESTORE(flags);
00586 }
00587
00588 static void spi0_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate)
00589 {
00590 SPI0_CSR0 &= ~SPI_SCBR;
00591
00592 ASSERT((uint8_t)DIV_ROUND(CPU_FREQ, rate));
00593 SPI0_CSR0 |= DIV_ROUND(CPU_FREQ, rate) << SPI_SCBR_SHIFT;
00594 }
00595
00596 #if CPU_ARM_SAM7X
00597
00598 static void spi1_init(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(struct Serial *, ser))
00599 {
00600 SER_SPI1_BUS_TXINIT;
00601
00602
00603 SPI1_CR = BV(SPI_SWRST);
00604
00605
00606
00607
00608
00609 SPI1_MR = BV(SPI_MSTR) | BV(SPI_MODFDIS);
00610
00611
00612
00613
00614
00615
00616
00617
00618 SPI1_CSR0 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT);
00619 SPI1_CSR1 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT);
00620 SPI1_CSR2 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT);
00621 SPI1_CSR3 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT);
00622
00623
00624 SPI1_IDR = 0xFFFFFFFF;
00625
00626 sysirq_setPriority(INT_SPI1, SERIRQ_PRIORITY);
00627 sysirq_setHandler(INT_SPI1, spi1_irq_dispatcher);
00628 pmc_periphEnable(SPI1_ID);
00629
00630
00631 SPI1_CR = BV(SPI_SPIEN);
00632
00633 SER_STROBE_INIT;
00634 }
00635
00636 static void spi1_cleanup(UNUSED_ARG(struct SerialHardware *, _hw))
00637 {
00638
00639 SPI1_CR = BV(SPI_SPIDIS);
00640
00641
00642 SPI1_IDR = 0xFFFFFFFF;
00643
00644 SER_SPI1_BUS_TXCLOSE;
00645 }
00646
00647 static void spi1_starttx(struct SerialHardware *_hw)
00648 {
00649 struct ArmSerial *hw = (struct ArmSerial *)_hw;
00650
00651 cpu_flags_t flags;
00652 IRQ_SAVE_DISABLE(flags);
00653
00654
00655 if (!hw->sending && !fifo_isempty(&ser_handles[SER_SPI1]->txfifo))
00656 {
00657 hw->sending = true;
00658 SPI1_TDR = fifo_pop(&ser_handles[SER_SPI1]->txfifo);
00659
00660 SPI1_IER = BV(SPI_TXEMPTY);
00661 }
00662
00663 IRQ_RESTORE(flags);
00664 }
00665
00666 static void spi1_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate)
00667 {
00668 SPI1_CSR0 &= ~SPI_SCBR;
00669
00670 ASSERT((uint8_t)DIV_ROUND(CPU_FREQ, rate));
00671 SPI1_CSR0 |= DIV_ROUND(CPU_FREQ, rate) << SPI_SCBR_SHIFT;
00672 }
00673 #endif
00674
00675 static void spi_setparity(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(int, parity))
00676 {
00677
00678 }
00679
00680
00681 static bool tx_sending(struct SerialHardware* _hw)
00682 {
00683 struct ArmSerial *hw = (struct ArmSerial *)_hw;
00684 return hw->sending;
00685 }
00686
00687
00688 #if COMPILER_C99
00689 #define C99INIT(name,val) .name = val
00690 #elif defined(__GNUC__)
00691 #define C99INIT(name,val) name: val
00692 #else
00693 #warning No designated initializers, double check your code
00694 #define C99INIT(name,val) (val)
00695 #endif
00696
00697
00698
00699
00700 static const struct SerialHardwareVT UART0_VT =
00701 {
00702 C99INIT(init, uart0_init),
00703 C99INIT(cleanup, uart0_cleanup),
00704 C99INIT(setBaudrate, uart0_setbaudrate),
00705 C99INIT(setParity, uart0_setparity),
00706 C99INIT(txStart, uart0_enabletxirq),
00707 C99INIT(txSending, tx_sending),
00708 };
00709
00710 #if USART_PORTS > 1
00711
00712 static const struct SerialHardwareVT UART1_VT =
00713 {
00714 C99INIT(init, uart1_init),
00715 C99INIT(cleanup, uart1_cleanup),
00716 C99INIT(setBaudrate, uart1_setbaudrate),
00717 C99INIT(setParity, uart1_setparity),
00718 C99INIT(txStart, uart1_enabletxirq),
00719 C99INIT(txSending, tx_sending),
00720 };
00721
00722 #endif
00723
00724 static const struct SerialHardwareVT SPI0_VT =
00725 {
00726 C99INIT(init, spi0_init),
00727 C99INIT(cleanup, spi0_cleanup),
00728 C99INIT(setBaudrate, spi0_setbaudrate),
00729 C99INIT(setParity, spi_setparity),
00730 C99INIT(txStart, spi0_starttx),
00731 C99INIT(txSending, tx_sending),
00732 };
00733 #if CPU_ARM_SAM7X
00734 static const struct SerialHardwareVT SPI1_VT =
00735 {
00736 C99INIT(init, spi1_init),
00737 C99INIT(cleanup, spi1_cleanup),
00738 C99INIT(setBaudrate, spi1_setbaudrate),
00739 C99INIT(setParity, spi_setparity),
00740 C99INIT(txStart, spi1_starttx),
00741 C99INIT(txSending, tx_sending),
00742 };
00743 #endif
00744
00745 static struct ArmSerial UARTDescs[SER_CNT] =
00746 {
00747 {
00748 C99INIT(hw, ) {
00749 C99INIT(table, &UART0_VT),
00750 C99INIT(txbuffer, uart0_txbuffer),
00751 C99INIT(rxbuffer, uart0_rxbuffer),
00752 C99INIT(txbuffer_size, sizeof(uart0_txbuffer)),
00753 C99INIT(rxbuffer_size, sizeof(uart0_rxbuffer)),
00754 },
00755 C99INIT(sending, false),
00756 },
00757 #if USART_PORTS > 1
00758 {
00759 C99INIT(hw, ) {
00760 C99INIT(table, &UART1_VT),
00761 C99INIT(txbuffer, uart1_txbuffer),
00762 C99INIT(rxbuffer, uart1_rxbuffer),
00763 C99INIT(txbuffer_size, sizeof(uart1_txbuffer)),
00764 C99INIT(rxbuffer_size, sizeof(uart1_rxbuffer)),
00765 },
00766 C99INIT(sending, false),
00767 },
00768 #endif
00769
00770 {
00771 C99INIT(hw, ) {
00772 C99INIT(table, &SPI0_VT),
00773 C99INIT(txbuffer, spi0_txbuffer),
00774 C99INIT(rxbuffer, spi0_rxbuffer),
00775 C99INIT(txbuffer_size, sizeof(spi0_txbuffer)),
00776 C99INIT(rxbuffer_size, sizeof(spi0_rxbuffer)),
00777 },
00778 C99INIT(sending, false),
00779 },
00780 #if CPU_ARM_SAM7X
00781 {
00782 C99INIT(hw, ) {
00783 C99INIT(table, &SPI1_VT),
00784 C99INIT(txbuffer, spi1_txbuffer),
00785 C99INIT(rxbuffer, spi1_rxbuffer),
00786 C99INIT(txbuffer_size, sizeof(spi1_txbuffer)),
00787 C99INIT(rxbuffer_size, sizeof(spi1_rxbuffer)),
00788 },
00789 C99INIT(sending, false),
00790 }
00791
00792 #endif
00793 };
00794
00795 struct SerialHardware *ser_hw_getdesc(int unit)
00796 {
00797 ASSERT(unit < SER_CNT);
00798 return &UARTDescs[unit].hw;
00799 }
00800
00804 INLINE void uart0_irq_tx(void)
00805 {
00806 SER_STROBE_ON;
00807
00808 struct FIFOBuffer * const txfifo = &ser_handles[SER_UART0]->txfifo;
00809
00810 if (fifo_isempty(txfifo))
00811 {
00812
00813
00814
00815 US0_IDR = BV(US_TXEMPTY);
00816 SER_UART0_BUS_TXEND;
00817 UARTDescs[SER_UART0].sending = false;
00818 }
00819 else
00820 {
00821 char c = fifo_pop(txfifo);
00822 SER_UART0_BUS_TXCHAR(c);
00823 }
00824
00825 SER_STROBE_OFF;
00826 }
00827
00831 INLINE void uart0_irq_rx(void)
00832 {
00833 SER_STROBE_ON;
00834
00835
00836 ser_handles[SER_UART0]->status |= US0_CSR & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
00837 US0_CR = BV(US_RSTSTA);
00838
00839 char c = US0_RHR;
00840 struct FIFOBuffer * const rxfifo = &ser_handles[SER_UART0]->rxfifo;
00841
00842 if (fifo_isfull(rxfifo))
00843 ser_handles[SER_UART0]->status |= SERRF_RXFIFOOVERRUN;
00844 else
00845 fifo_push(rxfifo, c);
00846
00847 SER_STROBE_OFF;
00848 }
00849
00853 static DECLARE_ISR(uart0_irq_dispatcher)
00854 {
00855 if (US0_CSR & BV(US_RXRDY))
00856 uart0_irq_rx();
00857
00858 if (US0_CSR & BV(US_TXEMPTY))
00859 uart0_irq_tx();
00860
00861 SER_INT_ACK;
00862 }
00863
00864 #if USART_PORTS > 1
00865
00869 INLINE void uart1_irq_tx(void)
00870 {
00871 SER_STROBE_ON;
00872
00873 struct FIFOBuffer * const txfifo = &ser_handles[SER_UART1]->txfifo;
00874
00875 if (fifo_isempty(txfifo))
00876 {
00877
00878
00879
00880 US1_IDR = BV(US_TXEMPTY);
00881 SER_UART1_BUS_TXEND;
00882 UARTDescs[SER_UART1].sending = false;
00883 }
00884 else
00885 {
00886 char c = fifo_pop(txfifo);
00887 SER_UART1_BUS_TXCHAR(c);
00888 }
00889
00890 SER_STROBE_OFF;
00891 }
00892
00896 INLINE void uart1_irq_rx(void)
00897 {
00898 SER_STROBE_ON;
00899
00900
00901 ser_handles[SER_UART1]->status |= US1_CSR & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
00902 US1_CR = BV(US_RSTSTA);
00903
00904 char c = US1_RHR;
00905 struct FIFOBuffer * const rxfifo = &ser_handles[SER_UART1]->rxfifo;
00906
00907 if (fifo_isfull(rxfifo))
00908 ser_handles[SER_UART1]->status |= SERRF_RXFIFOOVERRUN;
00909 else
00910 fifo_push(rxfifo, c);
00911
00912 SER_STROBE_OFF;
00913 }
00914
00918 static DECLARE_ISR(uart1_irq_dispatcher)
00919 {
00920 if (US1_CSR & BV(US_RXRDY))
00921 uart1_irq_rx();
00922
00923 if (US1_CSR & BV(US_TXEMPTY))
00924 uart1_irq_tx();
00925
00926 SER_INT_ACK;
00927 }
00928
00929 #endif
00930
00934 static DECLARE_ISR(spi0_irq_handler)
00935 {
00936 SER_STROBE_ON;
00937
00938 char c = SPI0_RDR;
00939
00940 if (!fifo_isfull(&ser_handles[SER_SPI0]->rxfifo))
00941 fifo_push(&ser_handles[SER_SPI0]->rxfifo, c);
00942
00943
00944
00945
00946
00947
00948
00949 if (!fifo_isempty(&ser_handles[SER_SPI0]->txfifo))
00950 SPI0_TDR = fifo_pop(&ser_handles[SER_SPI0]->txfifo);
00951 else
00952 {
00953 UARTDescs[SER_SPI0].sending = false;
00954
00955 SPI0_IDR = BV(SPI_TXEMPTY);
00956 }
00957
00958 SER_INT_ACK;
00959
00960 SER_STROBE_OFF;
00961 }
00962
00963
00964 #if CPU_ARM_SAM7X
00965
00968 static DECLARE_ISR(spi1_irq_handler)
00969 {
00970 SER_STROBE_ON;
00971
00972 char c = SPI1_RDR;
00973
00974 if (!fifo_isfull(&ser_handles[SER_SPI1]->rxfifo))
00975 fifo_push(&ser_handles[SER_SPI1]->rxfifo, c);
00976
00977
00978
00979
00980
00981
00982
00983 if (!fifo_isempty(&ser_handles[SER_SPI1]->txfifo))
00984 SPI1_TDR = fifo_pop(&ser_handles[SER_SPI1]->txfifo);
00985 else
00986 {
00987 UARTDescs[SER_SPI1].sending = false;
00988
00989 SPI1_IDR = BV(SPI_TXEMPTY);
00990 }
00991
00992 SER_INT_ACK;
00993
00994 SER_STROBE_OFF;
00995 }
00996 #endif