int main(void)
{
FlashAvr flash;
- SerialKFile ser;
+ Serial ser;
// Set up flash programming functions.
-static SerialKFile fd_ser;
-static SerialKFile tag_ser;
+static Serial fd_ser;
+static Serial tag_ser;
int main(void)
{
/* From the high-level serial driver */
-extern struct Serial ser_handles[SER_CNT];
+extern struct Serial *ser_handles[SER_CNT];
/* TX and RX buffers */
static unsigned char uart0_txbuffer[CONFIG_UART0_TXBUFSIZE];
};
-/*
- * These are to trick GCC into *not* using absolute addressing mode
- * when accessing ser_handles, which is very expensive.
- *
- * Accessing through these pointers generates much shorter
- * (and hopefully faster) code.
- */
-struct Serial *ser_uart0 = &ser_handles[SER_UART0];
-struct Serial *ser_uart1 = &ser_handles[SER_UART1];
-struct Serial *ser_spi0 = &ser_handles[SER_SPI0];
#if CPU_ARM_AT91SAM7X128 || CPU_ARM_AT91SAM7X256
struct Serial *ser_spi1 = &ser_handles[SER_SPI1];
#endif
IRQ_SAVE_DISABLE(flags);
/* Send data only if the SPI is not already transmitting */
- if (!hw->sending && !fifo_isempty(&ser_spi0->txfifo))
+ if (!hw->sending && !fifo_isempty(&ser_handles[SER_SPI0]->txfifo))
{
hw->sending = true;
- SPI0_TDR = fifo_pop(&ser_spi0->txfifo);
+ SPI0_TDR = fifo_pop(&ser_handles[SER_SPI0]->txfifo);
}
IRQ_RESTORE(flags);
{
SER_STROBE_ON;
- struct FIFOBuffer * const txfifo = &ser_uart0->txfifo;
+ struct FIFOBuffer * const txfifo = &ser_handles[SER_UART0]->txfifo;
if (fifo_isempty(txfifo))
{
SER_STROBE_ON;
/* Should be read before US_CRS */
- ser_uart0->status |= US0_CSR & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
+ ser_handles[SER_UART0]->status |= US0_CSR & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
US0_CR = BV(US_RSTSTA);
char c = US0_RHR;
- struct FIFOBuffer * const rxfifo = &ser_uart0->rxfifo;
+ struct FIFOBuffer * const rxfifo = &ser_handles[SER_UART0]->rxfifo;
if (fifo_isfull(rxfifo))
- ser_uart0->status |= SERRF_RXFIFOOVERRUN;
+ ser_handles[SER_UART0]->status |= SERRF_RXFIFOOVERRUN;
else
fifo_push(rxfifo, c);
{
SER_STROBE_ON;
- struct FIFOBuffer * const txfifo = &ser_uart1->txfifo;
+ struct FIFOBuffer * const txfifo = &ser_handles[SER_UART1]->txfifo;
if (fifo_isempty(txfifo))
{
SER_STROBE_ON;
/* Should be read before US_CRS */
- ser_uart1->status |= US1_CSR & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
+ ser_handles[SER_UART1]->status |= US1_CSR & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
US1_CR = BV(US_RSTSTA);
char c = US1_RHR;
- struct FIFOBuffer * const rxfifo = &ser_uart1->rxfifo;
+ struct FIFOBuffer * const rxfifo = &ser_handles[SER_UART1]->rxfifo;
if (fifo_isfull(rxfifo))
- ser_uart1->status |= SERRF_RXFIFOOVERRUN;
+ ser_handles[SER_UART1]->status |= SERRF_RXFIFOOVERRUN;
else
fifo_push(rxfifo, c);
char c = SPI0_RDR;
/* Read incoming byte. */
- if (!fifo_isfull(&ser_spi0->rxfifo))
- fifo_push(&ser_spi0->rxfifo, c);
+ if (!fifo_isfull(&ser_handles[SER_SPI0]->rxfifo))
+ fifo_push(&ser_handles[SER_SPI0]->rxfifo, c);
/*
* FIXME
else
- ser_spi0->status |= SERRF_RXFIFOOVERRUN;
+ ser_handles[SER_SPI0]->status |= SERRF_RXFIFOOVERRUN;
*/
/* Send */
- if (!fifo_isempty(&ser_spi0->txfifo))
- SPI0_TDR = fifo_pop(&ser_spi0->txfifo);
+ if (!fifo_isempty(&ser_handles[SER_SPI0]->txfifo))
+ SPI0_TDR = fifo_pop(&ser_handles[SER_SPI0]->txfifo);
else
UARTDescs[SER_SPI0].sending = false;
/* From the high-level serial driver */
-extern struct Serial ser_handles[SER_CNT];
+extern struct Serial *ser_handles[SER_CNT];
/* TX and RX buffers */
static unsigned char uart0_txbuffer[CONFIG_UART0_TXBUFSIZE];
};
-/*
- * These are to trick GCC into *not* using absolute addressing mode
- * when accessing ser_handles, which is very expensive.
- *
- * Accessing through these pointers generates much shorter
- * (and hopefully faster) code.
- */
-struct Serial *ser_uart0 = &ser_handles[SER_UART0];
-#if AVR_HAS_UART1
-struct Serial *ser_uart1 = &ser_handles[SER_UART1];
-#endif
-struct Serial *ser_spi = &ser_handles[SER_SPI];
-
-
/*
* Callbacks
IRQ_SAVE_DISABLE(flags);
/* Send data only if the SPI is not already transmitting */
- if (!hw->sending && !fifo_isempty(&ser_spi->txfifo))
+ if (!hw->sending && !fifo_isempty(&ser_handles[SER_SPI]->txfifo))
{
hw->sending = true;
- SPDR = fifo_pop(&ser_spi->txfifo);
+ SPDR = fifo_pop(&ser_handles[SER_SPI]->txfifo);
}
IRQ_RESTORE(flags);
{
SER_STROBE_ON;
- struct FIFOBuffer * const txfifo = &ser_uart0->txfifo;
+ struct FIFOBuffer * const txfifo = &ser_handles[SER_UART0]->txfifo;
if (fifo_isempty(txfifo))
{
{
SER_STROBE_ON;
- struct FIFOBuffer * const txfifo = &ser_uart0->txfifo;
+ struct FIFOBuffer * const txfifo = &ser_handles[SER_UART0]->txfifo;
if (fifo_isempty(txfifo))
{
SER_UART0_BUS_TXOFF;
{
SER_STROBE_ON;
- struct FIFOBuffer * const txfifo = &ser_uart1->txfifo;
+ struct FIFOBuffer * const txfifo = &ser_handles[SER_UART1]->txfifo;
if (fifo_isempty(txfifo))
{
{
SER_STROBE_ON;
- struct FIFOBuffer * const txfifo = &ser_uart1->txfifo;
+ struct FIFOBuffer * const txfifo = &ser_handles[SER_UART1]->txfifo;
if (fifo_isempty(txfifo))
{
SER_UART1_BUS_TXOFF;
//IRQ_ENABLE;
/* Should be read before UDR */
- ser_uart0->status |= UCSR0A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
+ ser_handles[SER_UART0]->status |= UCSR0A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
/* To clear the RXC flag we must _always_ read the UDR even when we're
* not going to accept the incoming data, otherwise a new interrupt
* will occur once the handler terminates.
*/
char c = UDR0;
- struct FIFOBuffer * const rxfifo = &ser_uart0->rxfifo;
+ struct FIFOBuffer * const rxfifo = &ser_handles[SER_UART0]->rxfifo;
if (fifo_isfull(rxfifo))
- ser_uart0->status |= SERRF_RXFIFOOVERRUN;
+ ser_handles[SER_UART0]->status |= SERRF_RXFIFOOVERRUN;
else
{
fifo_push(rxfifo, c);
//IRQ_ENABLE;
/* Should be read before UDR */
- ser_uart1->status |= UCSR1A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
+ ser_handles[SER_UART1]->status |= UCSR1A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
/* To avoid an IRQ storm, we must _always_ read the UDR even when we're
* not going to accept the incoming data
*/
char c = UDR1;
- struct FIFOBuffer * const rxfifo = &ser_uart1->rxfifo;
+ struct FIFOBuffer * const rxfifo = &ser_handles[SER_UART1]->rxfifo;
//ASSERT_VALID_FIFO(rxfifo);
if (UNLIKELY(fifo_isfull(rxfifo)))
- ser_uart1->status |= SERRF_RXFIFOOVERRUN;
+ ser_handles[SER_UART1]->status |= SERRF_RXFIFOOVERRUN;
else
{
fifo_push(rxfifo, c);
SER_STROBE_ON;
/* Read incoming byte. */
- if (!fifo_isfull(&ser_spi->rxfifo))
- fifo_push(&ser_spi->rxfifo, SPDR);
+ if (!fifo_isfull(&ser_handles[SER_SPI]->rxfifo))
+ fifo_push(&ser_handles[SER_SPI]->rxfifo, SPDR);
/*
* FIXME
else
- ser_spi->status |= SERRF_RXFIFOOVERRUN;
+ ser_handles[SER_SPI]->status |= SERRF_RXFIFOOVERRUN;
*/
/* Send */
- if (!fifo_isempty(&ser_spi->txfifo))
- SPDR = fifo_pop(&ser_spi->txfifo);
+ if (!fifo_isempty(&ser_handles[SER_SPI]->txfifo))
+ SPDR = fifo_pop(&ser_handles[SER_SPI]->txfifo);
else
UARTDescs[SER_SPI].sending = false;
#endif
-struct Serial ser_handles[SER_CNT];
+struct Serial *ser_handles[SER_CNT];
/**
* Insert \a c in tx FIFO buffer.
* EOF immediatly.
* \note Deprecated, use ser_getchar with rx_timeout set to 0.
*/
-int ser_getchar_nowait(struct SerialKFile *fd)
+int ser_getchar_nowait(struct Serial *fd)
{
- if (fifo_isempty_locked(&fd->ser->rxfifo))
+ if (fifo_isempty_locked(&fd->rxfifo))
return EOF;
/* NOTE: the double cast prevents unwanted sign extension */
- return (int)(unsigned char)fifo_pop_locked(&fd->ser->rxfifo);
+ return (int)(unsigned char)fifo_pop_locked(&fd->rxfifo);
}
*/
static size_t ser_read(struct KFile *fd, void *_buf, size_t size)
{
- SerialKFile *fds = SERIALKFILE(fd);
+ Serial *fds = SERIALKFILE(fd);
size_t i = 0;
char *buf = (char *)_buf;
while (i < size)
{
- if ((c = ser_getchar(fds->ser)) == EOF)
+ if ((c = ser_getchar(fds)) == EOF)
break;
buf[i++] = c;
}
*/
static size_t ser_write(struct KFile *fd, const void *_buf, size_t size)
{
- SerialKFile *fds = SERIALKFILE(fd);
+ Serial *fds = SERIALKFILE(fd);
const char *buf = (const char *)_buf;
size_t i = 0;
while (size--)
{
- if (ser_putchar(*buf++, fds->ser) == EOF)
+ if (ser_putchar(*buf++, fds) == EOF)
break;
i++;
}
#if CONFIG_SER_RXTIMEOUT != -1 || CONFIG_SER_TXTIMEOUT != -1
-void ser_settimeouts(struct SerialKFile *fd, mtime_t rxtimeout, mtime_t txtimeout)
+void ser_settimeouts(struct Serial *fd, mtime_t rxtimeout, mtime_t txtimeout)
{
- fd->ser->rxtimeout = ms_to_ticks(rxtimeout);
- fd->ser->txtimeout = ms_to_ticks(txtimeout);
+ fd->rxtimeout = ms_to_ticks(rxtimeout);
+ fd->txtimeout = ms_to_ticks(txtimeout);
}
#endif /* CONFIG_SER_RXTIMEOUT || CONFIG_SER_TXTIMEOUT */
*
* \note Serial errors are reset before and after executing the purge.
*/
-void ser_resync(struct SerialKFile *fd, mtime_t delay)
+void ser_resync(struct Serial *fd, mtime_t delay)
{
- mtime_t old_rxtimeout = ticks_to_ms(fd->ser->rxtimeout);
+ mtime_t old_rxtimeout = ticks_to_ms(fd->rxtimeout);
- ser_settimeouts(fd, delay, ticks_to_ms(fd->ser->txtimeout));
+ ser_settimeouts(fd, delay, ticks_to_ms(fd->txtimeout));
do
{
- ser_setstatus(fd->ser, 0);
- ser_getchar(fd->ser);
+ ser_setstatus(fd, 0);
+ ser_getchar(fd);
}
- while (!(ser_getstatus(fd->ser) & SERRF_RXTIMEOUT));
+ while (!(ser_getstatus(fd) & SERRF_RXTIMEOUT));
/* Restore port to an usable status */
- ser_setstatus(fd->ser, 0);
- ser_settimeouts(fd, old_rxtimeout, ticks_to_ms(fd->ser->txtimeout));
+ ser_setstatus(fd, 0);
+ ser_settimeouts(fd, old_rxtimeout, ticks_to_ms(fd->txtimeout));
}
#endif /* CONFIG_SER_RXTIMEOUT */
-void ser_setbaudrate(struct SerialKFile *fd, unsigned long rate)
+void ser_setbaudrate(struct Serial *fd, unsigned long rate)
{
- fd->ser->hw->table->setBaudrate(fd->ser->hw, rate);
+ fd->hw->table->setBaudrate(fd->hw, rate);
}
-void ser_setparity(struct SerialKFile *fd, int parity)
+void ser_setparity(struct Serial *fd, int parity)
{
- fd->ser->hw->table->setParity(fd->ser->hw, parity);
+ fd->hw->table->setParity(fd->hw, parity);
}
static int ser_error(struct KFile *fd)
{
- SerialKFile *fds = SERIALKFILE(fd);
- return ser_getstatus(fds->ser);
+ Serial *fds = SERIALKFILE(fd);
+ return ser_getstatus(fds);
}
static void ser_clearerr(struct KFile *fd)
{
- SerialKFile *fds = SERIALKFILE(fd);
- ser_setstatus(fds->ser, 0);
+ Serial *fds = SERIALKFILE(fd);
+ ser_setstatus(fds, 0);
}
/**
* Flush both the RX and TX buffers.
*/
-void ser_purge(struct SerialKFile *fd)
+void ser_purge(struct Serial *fd)
{
ser_purgeRx(fd);
ser_purgeTx(fd);
/**
* Flush RX buffer.
*/
-void ser_purgeRx(struct SerialKFile *fd)
+void ser_purgeRx(struct Serial *fd)
{
- fifo_flush_locked(&fd->ser->rxfifo);
+ fifo_flush_locked(&fd->rxfifo);
}
/**
* Flush TX buffer.
*/
-void ser_purgeTx(struct SerialKFile *fd)
+void ser_purgeTx(struct Serial *fd)
{
- fifo_flush_locked(&fd->ser->txfifo);
+ fifo_flush_locked(&fd->txfifo);
}
*/
static int ser_flush(struct KFile *fd)
{
- SerialKFile *fds = SERIALKFILE(fd);
+ Serial *fds = SERIALKFILE(fd);
/*
* Wait until the FIFO becomes empty, and then until the byte currently in
* the hardware register gets shifted out.
*/
- while (!fifo_isempty(&fds->ser->txfifo)
- || fds->ser->hw->table->txSending(fds->ser->hw))
+ while (!fifo_isempty(&fds->txfifo)
+ || fds->hw->table->txSending(fds->hw))
{
#if CONFIG_KERNEL && CONFIG_KERN_SCHED
/* Give up timeslice to other processes. */
* \param fd KFile Serial struct interface.
* \param unit Serial unit to open. Possible values are architecture dependant.
*/
-static struct Serial *ser_open(struct SerialKFile *fd, unsigned int unit)
+static struct Serial *ser_open(struct Serial *fd, unsigned int unit)
{
- struct Serial *port;
-
ASSERT(unit < countof(ser_handles));
- port = &ser_handles[unit];
- ASSERT(!port->is_open);
- DB(port->is_open = true);
+ ser_handles[unit] = fd;
+ ASSERT(!fd->is_open);
+ DB(fd->is_open = true);
- port->unit = unit;
+ fd->unit = unit;
- port->hw = ser_hw_getdesc(unit);
+ fd->hw = ser_hw_getdesc(unit);
/* Initialize circular buffers */
- ASSERT(port->hw->txbuffer);
- ASSERT(port->hw->rxbuffer);
- fifo_init(&port->txfifo, port->hw->txbuffer, port->hw->txbuffer_size);
- fifo_init(&port->rxfifo, port->hw->rxbuffer, port->hw->rxbuffer_size);
+ ASSERT(fd->hw->txbuffer);
+ ASSERT(fd->hw->rxbuffer);
+ fifo_init(&fd->txfifo, fd->hw->txbuffer, fd->hw->txbuffer_size);
+ fifo_init(&fd->rxfifo, fd->hw->rxbuffer, fd->hw->rxbuffer_size);
- port->hw->table->init(port->hw, port);
+ fd->hw->table->init(fd->hw, fd);
- fd->ser = port;
/* Set default values */
#if CONFIG_SER_RXTIMEOUT != -1 || CONFIG_SER_TXTIMEOUT != -1
ser_settimeouts(fd, CONFIG_SER_RXTIMEOUT, CONFIG_SER_TXTIMEOUT);
#endif
/* Clear error flags */
- ser_setstatus(port, 0);
+ ser_setstatus(fd, 0);
- return port;
+ return fd;
}
*/
static int ser_close(struct KFile *fd)
{
- SerialKFile *fds = SERIALKFILE(fd);
- Serial *port = fds->ser;
+ Serial *fds = SERIALKFILE(fd);
+ Serial *port = fds;
ASSERT(port->is_open);
DB(port->is_open = false);
*/
static struct KFile *ser_reopen(struct KFile *fd)
{
- SerialKFile *fds = SERIALKFILE(fd);
+ Serial *fds = SERIALKFILE(fd);
ser_close(fd);
- ser_open(fds, fds->ser->unit);
+ ser_open(fds, fds->unit);
return (KFile *)fds;
}
/**
* Init serial driver for \a unit.
*/
-void ser_init(struct SerialKFile *fds, unsigned int unit)
+void ser_init(struct Serial *fds, unsigned int unit)
{
memset(fds, 0, sizeof(*fds));
*/
static size_t spimaster_read(struct KFile *fd, void *_buf, size_t size)
{
- SerialKFile *fd_spi = SERIALKFILE(fd);
+ Serial *fd_spi = SERIALKFILE(fd);
ser_flush(&fd_spi->fd);
ser_purgeRx(fd_spi);
* Send and receive chars 1 by 1, otherwise the rxfifo
* will overrun.
*/
- ser_putchar(0, fd_spi->ser);
+ ser_putchar(0, fd_spi);
- if ((c = ser_getchar(fd_spi->ser)) == EOF)
+ if ((c = ser_getchar(fd_spi)) == EOF)
break;
*buf++ = c;
*/
static size_t spimaster_write(struct KFile *fd, const void *buf, size_t size)
{
- SerialKFile *fd_spi = SERIALKFILE(fd);
+ Serial *fd_spi = SERIALKFILE(fd);
ser_purgeRx(fd_spi);
* we have to discard all incoming data. Then, when we want to
* receive, we must write fake data to SPI to trigger slave devices.
*/
-void spimaster_init(SerialKFile *fds, unsigned int unit)
+void spimaster_init(Serial *fds, unsigned int unit)
{
ser_init(fds, unit);
fds->fd.read = spimaster_read;
/** Serial handle structure */
typedef struct Serial
{
+ /** Serial have a KFile struct implementation **/
+ KFile fd;
+
/** Physical port number */
unsigned int unit;
struct SerialHardware* hw;
} Serial;
-typedef struct SerialKFile
-{
- KFile fd;
- Serial *ser;
-} SerialKFile;
/**
* ID for serial.
#define KFT_SERIAL MAKE_ID('S', 'E', 'R', 'L')
-INLINE SerialKFile * SERIALKFILE(KFile *fd)
+INLINE Serial * SERIALKFILE(KFile *fd)
{
ASSERT(fd->_type == KFT_SERIAL);
- return (SerialKFile *)fd;
+ return (Serial *)fd;
}
/* Function prototypes */
//extern int ser_getchar_nowait(struct Serial *port);
-void ser_setbaudrate(struct SerialKFile *fd, unsigned long rate);
-void ser_setparity(struct SerialKFile *fd, int parity);
-void ser_settimeouts(struct SerialKFile *fd, mtime_t rxtimeout, mtime_t txtimeout);
-void ser_resync(struct SerialKFile *fd, mtime_t delay);
-int ser_getchar_nowait(struct SerialKFile *fd);
-
-void ser_purgeRx(struct SerialKFile *fd);
-void ser_purgeTx(struct SerialKFile *fd);
-void ser_purge(struct SerialKFile *fd);
-void ser_init(struct SerialKFile *fds, unsigned int unit);
-void spimaster_init(SerialKFile *fds, unsigned int unit);
+void ser_setbaudrate(struct Serial *fd, unsigned long rate);
+void ser_setparity(struct Serial *fd, int parity);
+void ser_settimeouts(struct Serial *fd, mtime_t rxtimeout, mtime_t txtimeout);
+void ser_resync(struct Serial *fd, mtime_t delay);
+int ser_getchar_nowait(struct Serial *fd);
+
+void ser_purgeRx(struct Serial *fd);
+void ser_purgeTx(struct Serial *fd);
+void ser_purge(struct Serial *fd);
+void ser_init(struct Serial *fds, unsigned int unit);
+void spimaster_init(Serial *fds, unsigned int unit);
/**
#include <cfg/compiler.h> /* size_t */
+
+
struct SerialHardware;
struct Serial;
struct SerialHardware *ser_hw_getdesc(int unit);
+
+
#endif /* DRV_SER_P_H */
*
* \note This function allocates a large amount of stack (\see XM_BUFSIZE).
*/
-bool xmodem_recv(struct SerialKFile *port, KFile *fd)
+bool xmodem_recv(struct Serial *port, KFile *fd)
{
char block_buffer[XM_BUFSIZE]; /* Buffer to hold a block of data */
int c, i, blocksize;
* \note This function allocates a large amount of stack for
* the XModem transfer buffer (\see XM_BUFSIZE).
*/
-bool xmodem_send(struct SerialKFile *port, KFile *fd)
+bool xmodem_send(struct Serial *port, KFile *fd)
{
char block_buffer[XM_BUFSIZE]; /* Buffer to hold a block of data */
size_t size = -1;
/* fwd decl */
-struct SerialKFile;
+struct Serial;
-bool xmodem_recv(struct SerialKFile *port, KFile *fd);
-bool xmodem_send(struct SerialKFile *port, KFile *fd);
+bool xmodem_recv(struct Serial *port, KFile *fd);
+bool xmodem_send(struct Serial *port, KFile *fd);
#endif /* MWARE_XMODEM_H */