diff options
| author | Nick Foster <nick@nerdnetworks.org> | 2010-08-12 10:23:33 -0700 | 
|---|---|---|
| committer | Nick Foster <nick@nerdnetworks.org> | 2010-08-12 10:23:33 -0700 | 
| commit | 32c40b5f5956d29e3be1fc3c94a213f8f0d68f42 (patch) | |
| tree | 3e059559d9b1d80e807a114240052b2947684e87 /firmware | |
| parent | dfafbd5f2dbf0758df33d10922eec3c1a37dd32b (diff) | |
| download | uhd-32c40b5f5956d29e3be1fc3c94a213f8f0d68f42.tar.gz uhd-32c40b5f5956d29e3be1fc3c94a213f8f0d68f42.tar.bz2 uhd-32c40b5f5956d29e3be1fc3c94a213f8f0d68f42.zip | |
Working support for multiple UARTs.
Default behavior (printf, gets, etc.) routes to DEFAULT_UART, set in hal_uart.h. Use fputstr() to print to other UARTs. Bring
fgets() from hal_io.c out in hal_io.h if you want to read data from other UARTs.
Still blocking. No interrupt-driven stuff yet.
Diffstat (limited to 'firmware')
| -rw-r--r-- | firmware/microblaze/lib/hal_io.c | 66 | ||||
| -rw-r--r-- | firmware/microblaze/lib/hal_io.h | 2 | ||||
| -rw-r--r-- | firmware/microblaze/lib/hal_uart.c | 89 | ||||
| -rw-r--r-- | firmware/microblaze/lib/hal_uart.h | 42 | ||||
| -rw-r--r-- | firmware/microblaze/usrp2p/memory_map.h | 6 | 
5 files changed, 122 insertions, 83 deletions
| diff --git a/firmware/microblaze/lib/hal_io.c b/firmware/microblaze/lib/hal_io.c index b68067308..8bb5e2af8 100644 --- a/firmware/microblaze/lib/hal_io.c +++ b/firmware/microblaze/lib/hal_io.c @@ -18,9 +18,9 @@  // conditionalized on HAL_IO_USES_DBOARD_PINS && HAL_IO_USES_UART -#include "hal_io.h"  #include "memory_map.h"  #include "hal_uart.h" +#include "hal_io.h"  #include <stdbool.h>  #include <stdio.h>  #include <string.h> @@ -102,7 +102,7 @@ hal_finish(void)  // %c  inline int -fputchar(int ch) +putchar(int ch)  {    hal_gpio_set_rx((s << 8) | W, 0xff80);    hal_gpio_set_rx(0, 0xff80); @@ -124,16 +124,29 @@ hal_finish(void)  // %c  inline int -fputchar(int ch) +fputchar(hal_uart_name_t u, int ch) +{ +  hal_uart_putc(u, ch); +  return ch; +} + +inline int +putchar(int ch)  { -  hal_uart_putc(ch); +  hal_uart_putc(DEFAULT_UART, ch);    return ch;  }  int -fgetchar(void) +fgetchar(hal_uart_name_t u) +{ +  return hal_uart_getc(u); +} + +int +getchar(void)  { -  return hal_uart_getc(); +  return fgetchar(DEFAULT_UART);  }  #else	// nop all i/o @@ -172,34 +185,57 @@ getchar(void)  // \n  inline void  -fnewline(void) +fnewline(hal_uart_name_t u)  { -  putchar('\n'); +  fputchar(u, '\n'); +} + +inline void +newline(void) +{ +  fnewline(DEFAULT_UART);  }  int -fputstr(const char *s) +fputstr(hal_uart_name_t u, const char *s)  {    while (*s) -    putchar(*s++); +    fputchar(u, *s++);    return 0;  }  int -fputs(const char *s) +putstr(const char *s) +{ +  return fputstr(DEFAULT_UART, s); +} + +int +fputs(hal_uart_name_t u, const char *s)  { -  putstr(s); -  putchar('\n'); +  fputstr(u, s); +  fputchar(u, '\n');    return 0;  } +int puts(const char *s) +{ +  return fputs(DEFAULT_UART, s); +} +  char * -fgets(char * const s) +fgets(hal_uart_name_t u, char * const s)  {  	char *x = s; -	while((*x=(char)hal_uart_getc()) != '\n') x++; +	while((*x=(char)hal_uart_getc(u)) != '\n') x++;  	*x = 0;  	return s;  } +char * +gets(char * const s) +{ +  return fgets(DEFAULT_UART, s); +} + diff --git a/firmware/microblaze/lib/hal_io.h b/firmware/microblaze/lib/hal_io.h index c67d96c62..99f8f7fc9 100644 --- a/firmware/microblaze/lib/hal_io.h +++ b/firmware/microblaze/lib/hal_io.h @@ -20,10 +20,12 @@  #define INCLUDED_HAL_IO_H  #include "memory_map.h" +#include "hal_uart.h"  void hal_io_init(void);  void hal_finish();  char *gets(char * const s); +int fputstr(hal_uart_name_t u, const char *s);  /*   * ------------------------------------------------------------------------ diff --git a/firmware/microblaze/lib/hal_uart.c b/firmware/microblaze/lib/hal_uart.c index 91d67b5e0..6717cd5e8 100644 --- a/firmware/microblaze/lib/hal_uart.c +++ b/firmware/microblaze/lib/hal_uart.c @@ -16,93 +16,88 @@   * along with this program.  If not, see <http://www.gnu.org/licenses/>.   */ +#include "memory_map.h"  #include "hal_uart.h"  #include "hal_io.h" -#include "memory_map.h" - -// First pass, no interrupts -// Replaced with divisors.py which generates best divisor -//#define CALC_DIVISOR(rate) (WISHBONE_CLK_RATE / ((rate) * 16)) +//just to save you from going insane, note that firmware/FPGA UARTs [0-2] correspond to serial ports [1-3]. +//so in software, we refer to UART_DEBUG as UART0, but it transmits on pin TXD<1>. see the UART assignments in hal_uart.h.  #define NSPEEDS 6  #define	MAX_WB_DIV 4 +//if you're going to recalculate the divisors, it's just uart_clock_rate / baud_rate. +//uart_clock_rate is 50MHz for USRP2.  static const uint16_t -divisor_table[MAX_WB_DIV+1][NSPEEDS] = { -  {   2,   2,   2,   2,  2,  2},   // 0: can't happen -  { 651, 326, 163, 109, 54, 27 },  // 1: 100 MHz -  { 326, 163,  81,  54, 27, 14 },  // 2:  50 MHz -  { 217, 109,  54,  36, 18,  9 },  // 3:  33.3333 MHz -  { 163,  81,  41,  27, 14,  7 },  // 4:  25 MHz +divisor_table[NSPEEDS] = { +  5208,	//    9600 +  2604,	//   19200 +  1302,	//   38400 +  868,	//   57600 +  434,	//  115200 +  217	//  230400  }; -//we wrap hal_uart_putc hal_uart_putc_nowait, and hal_uart_getc to accept a UART pointer given by hal_get_uart. we modify hal_io.c to use the new versions. +static char uart_mode[4] = { +  [UART_DEBUG] = UART_MODE_ONLCR,  +  [UART_EXP] = UART_MODE_ONLCR,  +  [UART_GPS] = UART_MODE_ONLCR +}; -static char uart_mode[4] = {UART_MODE_ONLCR, UART_MODE_ONLCR, UART_MODE_ONLCR, UART_MODE_ONLCR}; +static char uart_speeds[4] = { +  [UART_DEBUG] = US_230400, +  [UART_EXP] = US_230400, +  [UART_GPS] = US_230400 +};  void -hal_uart_set_mode(int uart, int mode) +hal_uart_set_mode(hal_uart_name_t uart, int mode)  {    uart_mode[uart] = mode;  } +void hal_uart_set_speed(hal_uart_name_t uart, hal_uart_speed_t speed) +{ +  uart_regs[uart].clkdiv = divisor_table[speed]; +} +  void  hal_uart_init(void)  { -  for(int i = 0; i < 4; i++) { -  	hal_uart_set_mode(i, UART_MODE_ONLCR); -    u->clkdiv = 217;  // 230400 bps TODO: change to reflect new quad UART +  for(int i = 0; i < 2; i++) { //uart 3 is unused +  	hal_uart_set_mode(i, uart_mode[i]); +    hal_uart_set_speed(i, uart_speeds[i]);    }  }  void -hal_uart_putc(uart_regs_t *u, int ch) +hal_uart_putc(hal_uart_name_t u, int ch)  { -  if (ch == '\n')// && (uart_mode[uart] == UART_MODE_ONLCR))		//map \n->\r\n if necessary +  if ((ch == '\n') && (uart_mode[u] == UART_MODE_ONLCR))		//map \n->\r\n if necessary      hal_uart_putc(u, '\r'); -  while (u->txlevel == 0)	 // wait for fifo to have space +  while (uart_regs[u].txlevel == 0)	 // wait for fifo to have space      ; -  u->txchar = ch; +  uart_regs[u].txchar = ch;  }  void -hal_uart_putc_nowait(uart_regs_t *u, int ch) +hal_uart_putc_nowait(hal_uart_name_t u, int ch)  { -  if (ch == '\n')// && (uart_mode[uart] == UART_MODE_ONLCR))		//map \n->\r\n if necessary +  if ((ch == '\n') && (uart_mode[u] == UART_MODE_ONLCR))		//map \n->\r\n if necessary      hal_uart_putc(u, '\r'); -  if(u->txlevel)   // If fifo has space -    u->txchar = ch; +  if(uart_regs[u].txlevel)   // If fifo has space +    uart_regs[u].txchar = ch;  }  int -hal_uart_getc(uart_regs_t *u) +hal_uart_getc(hal_uart_name_t u)  { -  while ((u->rxlevel) == 0)  // wait for data to be ready +  while ((uart_regs[u].rxlevel) == 0)  // wait for data to be ready      ; -  return u->rxchar; +  return uart_regs[u].rxchar;  } -uart_regs_t * -hal_get_uart(int number) -{ -  switch(number) { -  case 0: -    return uart_regs_0; -    break; -  case 1: -    return uart_regs_1; -    break; -  case 2: -    return uart_regs_2; -    break; -  case 3: -    return uart_regs_3; -    break; -  default: -    return uart_regs_0; //for safety -} diff --git a/firmware/microblaze/lib/hal_uart.h b/firmware/microblaze/lib/hal_uart.h index 218bd7cb4..81f4a6777 100644 --- a/firmware/microblaze/lib/hal_uart.h +++ b/firmware/microblaze/lib/hal_uart.h @@ -25,29 +25,37 @@  #define	UART_MODE_RAW		0x0000	// no mapping on input or output  #define	UART_MODE_ONLCR	0x0001	// map \n to \r\n on output (default) +#define DEFAULT_UART UART_DEBUG //which UART printf, gets, etc. use + +typedef enum { +  US_9600   = 0, +  US_19200  = 1, +  US_38400  = 2, +  US_57600  = 3, +  US_115200 = 4, +  US_230400 = 5 +} hal_uart_speed_t; + +typedef struct { +  hal_uart_speed_t	speed; +} hal_uart_config_t; + +typedef enum { +  UART_DEBUG = 0, +  UART_EXP   = 1, +  UART_GPS   = 2 +} hal_uart_name_t; +  /*   * \brief Set uart mode   */ -void hal_uart_set_mode(int uart, int flags); +void hal_uart_set_mode(hal_uart_name_t uart, int flags);  /*!   * \brief one-time call to init   */  void hal_uart_init(void); -typedef enum { -  US_9600, -  US_19200, -  US_38400, -  US_57600, -  US_115200, -  US_230400, -} hal_uart_speed_t; - -typedef struct { -  hal_uart_speed_t	speed; -} hal_uart_config_t; -  /*!   * \brief Set uart parameters   *  Default is 115,200 bps, 8N1. @@ -62,17 +70,17 @@ void hal_uart_get_config(hal_uart_config_t *c);  /*!   * \brief Enqueue \p ch for output over serial port   */ -void hal_uart_putc(uart_regs_t *u, int ch); +void hal_uart_putc(hal_uart_name_t u, int ch);  /*!   * \brief Enqueue \p ch for output over serial port, silent fail if queue is full   */ -void hal_uart_putc_nowait(uart_regs_t *u, int ch); +void hal_uart_putc_nowait(hal_uart_name_t u, int ch);  /*   * \brief Blocking read of next char from serial port   */ -int hal_uart_getc(uart_regs_t *u); +int hal_uart_getc(hal_uart_name_t u);  #endif /* INCLUDED_HAL_UART_H */ diff --git a/firmware/microblaze/usrp2p/memory_map.h b/firmware/microblaze/usrp2p/memory_map.h index b69cc59bd..addcf67d4 100644 --- a/firmware/microblaze/usrp2p/memory_map.h +++ b/firmware/microblaze/usrp2p/memory_map.h @@ -779,12 +779,10 @@ typedef struct {    volatile uint32_t rxlevel; // Number of available elements in the FIFO for reads    volatile uint32_t txchar;  // Write characters to be sent here    volatile uint32_t rxchar;  // Read received characters here +  volatile uint32_t x[3]; //padding to reach 32B  } uart_regs_t; -#define uart_regs_0 ((uart_regs_t *) UART_BASE) -#define uart_regs_1 ((uart_regs_t *) UART_BASE + 0x0020) -#define uart_regs_2 ((uart_regs_t *) UART_BASE + 0x0040) -#define uart_regs_3 ((uart_regs_t *) UART_BASE + 0x0060) +#define uart_regs ((uart_regs_t *) UART_BASE)  ///////////////////////////////////////////////////  // ATR Controller, Slave 11 | 
