4 * Copyright (C) 2003,2004 Develer S.r.l. (http://www.develer.com/)
10 * \author Stefano Fedrigo <aleph@develer.com>
11 * \author Giovanni Bajo <rasky@develer.com>
13 * \brief DSP5680x CPU specific serial I/O driver
18 * Revision 1.2 2004/05/23 18:21:53 bernie
19 * Trim CVS logs and cleanup header info.
25 #include <drv/kdebug.h>
27 #include <DSP56F807.H>
29 // GPIO E is shared with SPI (in DSP56807). Pins 0&1 are TXD0 and RXD0. To use
30 // the serial, we need to disable the GPIO functions on them.
31 #define REG_GPIO_SERIAL REG_GPIO_E
32 #define REG_GPIO_SERIAL_MASK 0x3
34 // Check flag consistency
35 #if (SERRF_PARITYERROR != REG_SCI_SR_PF) || \
36 (SERRF_RXSROVERRUN != REG_SCI_SR_OR) || \
37 (SERRF_FRAMEERROR != REG_SCI_SR_FE) || \
38 (SERRF_NOISEERROR != REG_SCI_SR_NF)
39 #error error flags do not match with register bits
44 struct SerialHardware hw;
45 struct Serial* serial;
46 volatile struct REG_SCI_STRUCT* regs;
52 static inline void enable_tx_irq_bare(volatile struct REG_SCI_STRUCT* regs)
54 regs->CR |= REG_SCI_CR_TEIE | REG_SCI_CR_TIIE;
57 static inline void enable_rx_irq_bare(volatile struct REG_SCI_STRUCT* regs)
59 regs->CR |= REG_SCI_CR_RIE | REG_SCI_CR_REIE;
62 static inline void disable_tx_irq_bare(volatile struct REG_SCI_STRUCT* regs)
64 regs->CR &= ~(REG_SCI_CR_TEIE | REG_SCI_CR_TIIE);
67 static inline void disable_rx_irq_bare(volatile struct REG_SCI_STRUCT* regs)
69 regs->CR &= ~(REG_SCI_CR_RIE | REG_SCI_CR_REIE);
72 static inline void disable_tx_irq(struct SerialHardware* _hw)
74 struct SCI* hw = (struct SCI*)_hw;
75 volatile struct REG_SCI_STRUCT* regs = hw->regs;
77 disable_tx_irq_bare(regs);
80 static inline void enable_tx_irq(struct SerialHardware* _hw)
82 struct SCI* hw = (struct SCI*)_hw;
83 volatile struct REG_SCI_STRUCT* regs = hw->regs;
85 enable_tx_irq_bare(regs);
88 static inline void enable_rx_irq(struct SerialHardware* _hw)
90 struct SCI* hw = (struct SCI*)_hw;
91 volatile struct REG_SCI_STRUCT* regs = hw->regs;
93 enable_rx_irq_bare(regs);
96 INLINE void tx_isr(struct SCI *hw)
98 volatile struct REG_SCI_STRUCT* regs = hw->regs;
100 if (fifo_isempty(&hw->serial->txfifo))
101 disable_tx_irq_bare(regs);
104 // Clear transmitter flags before sending data
106 regs->DR = fifo_pop(&hw->serial->txfifo);
110 INLINE void rx_isr(struct SCI *hw)
112 volatile struct REG_SCI_STRUCT* regs = hw->regs;
114 hw->serial->status |= regs->SR & (SERRF_PARITYERROR |
119 if (fifo_isfull(&hw->serial->rxfifo))
120 hw->serial->status |= SERRF_RXFIFOOVERRUN;
122 fifo_push(&hw->serial->rxfifo, regs->DR);
124 // Writing anything to the status register clear the
129 static void init(struct SerialHardware* _hw, struct Serial* ser)
131 struct SCI* hw = (struct SCI*)_hw;
132 volatile struct REG_SCI_STRUCT* regs = hw->regs;
134 // Clear status register (IRQ/status flags)
138 // Clear data register
141 // Set priorities for both IRQs
142 irq_setpriority(hw->irq_tx, IRQ_PRIORITY_SCI_TX);
143 irq_setpriority(hw->irq_rx, IRQ_PRIORITY_SCI_RX);
145 // Activate the RX error interrupts, and RX/TX transmissions
146 regs->CR = REG_SCI_CR_TE | REG_SCI_CR_RE;
147 enable_rx_irq_bare(regs);
149 // Disable GPIO pins for TX and RX lines
150 REG_GPIO_SERIAL->PER |= REG_GPIO_SERIAL_MASK;
155 static void cleanup(struct SerialHardware* _hw)
161 static void setbaudrate(struct SerialHardware* _hw, unsigned long rate)
163 struct SCI* hw = (struct SCI*)_hw;
165 // SCI has an internal 16x divider on the input clock, which comes
166 // from the IPbus (see the scheme in user manual, 12.7.3). We apply
167 // it to calculate the period to store in the register.
168 hw->regs->BR = (IPBUS_FREQ + rate * 8ul) / (rate * 16ul);
171 static void setparity(struct SerialHardware* _hw, int parity)
178 static const struct SerialHardwareVT SCI_VT =
182 .setbaudrate = setbaudrate,
183 .setparity = setparity,
184 .enabletxirq = enable_tx_irq,
187 static struct SCI SCIDescs[2] =
190 .hw = { .table = &SCI_VT },
192 .irq_rx = IRQ_SCI0_RECEIVER_FULL,
193 .irq_tx = IRQ_SCI0_TRANSMITTER_READY,
197 .hw = { .table = &SCI_VT },
199 .irq_rx = IRQ_SCI1_RECEIVER_FULL,
200 .irq_tx = IRQ_SCI1_TRANSMITTER_READY,
206 void ser_hw_tx_isr_0(void);
207 void ser_hw_tx_isr_0(void)
209 #pragma interrupt warn
210 tx_isr(&SCIDescs[0]);
213 void ser_hw_rx_isr_0(void);
214 void ser_hw_rx_isr_0(void)
216 #pragma interrupt warn
217 rx_isr(&SCIDescs[0]);
220 void ser_hw_tx_isr_1(void);
221 void ser_hw_tx_isr_1(void)
223 #pragma interrupt warn
224 tx_isr(&SCIDescs[1]);
227 void ser_hw_rx_isr_1(void);
228 void ser_hw_rx_isr_1(void)
230 #pragma interrupt warn
231 rx_isr(&SCIDescs[1]);
234 struct SerialHardware* ser_hw_getdesc(int unit)
237 return &SCIDescs[unit].hw;