From f72ad02f5ec370f45995ecd2b3e8b322e9a7e4dc Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Mon, 26 Jul 2010 15:33:30 -0700 Subject: New branch with firmware dir from USRP2P branch. --- firmware/microblaze/lib/hal_uart.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'firmware/microblaze/lib/hal_uart.c') diff --git a/firmware/microblaze/lib/hal_uart.c b/firmware/microblaze/lib/hal_uart.c index 75b12b432..fe3b7515a 100644 --- a/firmware/microblaze/lib/hal_uart.c +++ b/firmware/microblaze/lib/hal_uart.c @@ -39,16 +39,25 @@ divisor_table[MAX_WB_DIV+1][NSPEEDS] = { #define u uart_regs +static char uart_mode = UART_MODE_ONLCR; + +void +hal_uart_set_mode(int mode) +{ + uart_mode = mode; +} + void hal_uart_init(void) { + hal_uart_set_mode(UART_MODE_ONLCR); u->clkdiv = 217; // 230400 bps } void hal_uart_putc(int ch) { - if (ch == '\n') // FIXME for now map \n -> \r\n + if (ch == '\n')// && (uart_mode == UART_MODE_ONLCR)) //map \n->\r\n if necessary hal_uart_putc('\r'); while (u->txlevel == 0) // wait for fifo to have space @@ -60,7 +69,7 @@ hal_uart_putc(int ch) void hal_uart_putc_nowait(int ch) { - if (ch == '\n') // FIXME for now map \n -> \r\n + if (ch == '\n')// && (uart_mode == UART_MODE_ONLCR)) //map \n->\r\n if necessary hal_uart_putc('\r'); if(u->txlevel) // If fifo has space -- cgit v1.2.3 From dfafbd5f2dbf0758df33d10922eec3c1a37dd32b Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Wed, 11 Aug 2010 14:20:50 -0700 Subject: Branch to make use of quad UART on USRP2P. --- firmware/microblaze/lib/hal_io.c | 14 +++++----- firmware/microblaze/lib/hal_uart.c | 48 ++++++++++++++++++++++++--------- firmware/microblaze/lib/hal_uart.h | 8 +++--- firmware/microblaze/usrp2p/memory_map.h | 5 +++- 4 files changed, 50 insertions(+), 25 deletions(-) (limited to 'firmware/microblaze/lib/hal_uart.c') diff --git a/firmware/microblaze/lib/hal_io.c b/firmware/microblaze/lib/hal_io.c index 58b1e681e..b68067308 100644 --- a/firmware/microblaze/lib/hal_io.c +++ b/firmware/microblaze/lib/hal_io.c @@ -102,7 +102,7 @@ hal_finish(void) // %c inline int -putchar(int ch) +fputchar(int ch) { hal_gpio_set_rx((s << 8) | W, 0xff80); hal_gpio_set_rx(0, 0xff80); @@ -124,14 +124,14 @@ hal_finish(void) // %c inline int -putchar(int ch) +fputchar(int ch) { hal_uart_putc(ch); return ch; } int -getchar(void) +fgetchar(void) { return hal_uart_getc(); } @@ -172,13 +172,13 @@ getchar(void) // \n inline void -newline(void) +fnewline(void) { putchar('\n'); } int -putstr(const char *s) +fputstr(const char *s) { while (*s) putchar(*s++); @@ -187,7 +187,7 @@ putstr(const char *s) } int -puts(const char *s) +fputs(const char *s) { putstr(s); putchar('\n'); @@ -195,7 +195,7 @@ puts(const char *s) } char * -gets(char * const s) +fgets(char * const s) { char *x = s; while((*x=(char)hal_uart_getc()) != '\n') x++; diff --git a/firmware/microblaze/lib/hal_uart.c b/firmware/microblaze/lib/hal_uart.c index fe3b7515a..91d67b5e0 100644 --- a/firmware/microblaze/lib/hal_uart.c +++ b/firmware/microblaze/lib/hal_uart.c @@ -37,28 +37,30 @@ divisor_table[MAX_WB_DIV+1][NSPEEDS] = { { 163, 81, 41, 27, 14, 7 }, // 4: 25 MHz }; -#define u uart_regs +//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 = UART_MODE_ONLCR; +static char uart_mode[4] = {UART_MODE_ONLCR, UART_MODE_ONLCR, UART_MODE_ONLCR, UART_MODE_ONLCR}; void -hal_uart_set_mode(int mode) +hal_uart_set_mode(int uart, int mode) { - uart_mode = mode; + uart_mode[uart] = mode; } void hal_uart_init(void) { - hal_uart_set_mode(UART_MODE_ONLCR); - u->clkdiv = 217; // 230400 bps + 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 + } } void -hal_uart_putc(int ch) +hal_uart_putc(uart_regs_t *u, int ch) { - if (ch == '\n')// && (uart_mode == UART_MODE_ONLCR)) //map \n->\r\n if necessary - hal_uart_putc('\r'); + if (ch == '\n')// && (uart_mode[uart] == UART_MODE_ONLCR)) //map \n->\r\n if necessary + hal_uart_putc(u, '\r'); while (u->txlevel == 0) // wait for fifo to have space ; @@ -67,20 +69,40 @@ hal_uart_putc(int ch) } void -hal_uart_putc_nowait(int ch) +hal_uart_putc_nowait(uart_regs_t *u, int ch) { - if (ch == '\n')// && (uart_mode == UART_MODE_ONLCR)) //map \n->\r\n if necessary - hal_uart_putc('\r'); + if (ch == '\n')// && (uart_mode[uart] == UART_MODE_ONLCR)) //map \n->\r\n if necessary + hal_uart_putc(u, '\r'); if(u->txlevel) // If fifo has space u->txchar = ch; } int -hal_uart_getc(void) +hal_uart_getc(uart_regs_t *u) { while ((u->rxlevel) == 0) // wait for data to be ready ; return 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 dfd73c323..218bd7cb4 100644 --- a/firmware/microblaze/lib/hal_uart.h +++ b/firmware/microblaze/lib/hal_uart.h @@ -28,7 +28,7 @@ /* * \brief Set uart mode */ -void hal_uart_set_mode(int flags); +void hal_uart_set_mode(int uart, int flags); /*! * \brief one-time call to init @@ -62,17 +62,17 @@ void hal_uart_get_config(hal_uart_config_t *c); /*! * \brief Enqueue \p ch for output over serial port */ -void hal_uart_putc(int ch); +void hal_uart_putc(uart_regs_t *u, int ch); /*! * \brief Enqueue \p ch for output over serial port, silent fail if queue is full */ -void hal_uart_putc_nowait(int ch); +void hal_uart_putc_nowait(uart_regs_t *u, int ch); /* * \brief Blocking read of next char from serial port */ -int hal_uart_getc(void); +int hal_uart_getc(uart_regs_t *u); #endif /* INCLUDED_HAL_UART_H */ diff --git a/firmware/microblaze/usrp2p/memory_map.h b/firmware/microblaze/usrp2p/memory_map.h index 9c5b576d7..b69cc59bd 100644 --- a/firmware/microblaze/usrp2p/memory_map.h +++ b/firmware/microblaze/usrp2p/memory_map.h @@ -781,7 +781,10 @@ typedef struct { volatile uint32_t rxchar; // Read received characters here } uart_regs_t; -#define uart_regs ((uart_regs_t *) UART_BASE) +#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) /////////////////////////////////////////////////// // ATR Controller, Slave 11 -- cgit v1.2.3 From 32c40b5f5956d29e3be1fc3c94a213f8f0d68f42 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Thu, 12 Aug 2010 10:23:33 -0700 Subject: 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. --- firmware/microblaze/lib/hal_io.c | 66 ++++++++++++++++++------ firmware/microblaze/lib/hal_io.h | 2 + firmware/microblaze/lib/hal_uart.c | 89 ++++++++++++++++----------------- firmware/microblaze/lib/hal_uart.h | 42 +++++++++------- firmware/microblaze/usrp2p/memory_map.h | 6 +-- 5 files changed, 122 insertions(+), 83 deletions(-) (limited to 'firmware/microblaze/lib/hal_uart.c') 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 #include #include @@ -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 . */ +#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 -- cgit v1.2.3 From e42230e7fae59d91186d21ab6ba8311421649375 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Thu, 12 Aug 2010 15:17:58 -0700 Subject: Added UART transactions to the DUDE/BRO protocol. --- firmware/microblaze/apps/txrx_uhd.c | 19 +++++++++++++++++++ firmware/microblaze/lib/hal_io.c | 21 +++++++++++++++++++++ firmware/microblaze/lib/hal_io.h | 2 ++ firmware/microblaze/lib/hal_uart.c | 2 +- host/lib/usrp/usrp2/fw_common.h | 11 +++++++++++ 5 files changed, 54 insertions(+), 1 deletion(-) (limited to 'firmware/microblaze/lib/hal_uart.c') diff --git a/firmware/microblaze/apps/txrx_uhd.c b/firmware/microblaze/apps/txrx_uhd.c index f0a9702be..42a3f4b89 100644 --- a/firmware/microblaze/apps/txrx_uhd.c +++ b/firmware/microblaze/apps/txrx_uhd.c @@ -311,6 +311,25 @@ void handle_udp_ctrl_packet( ctrl_data_out.id = USRP2_CTRL_ID_WOAH_I_DEFINITELY_PEEKED_IT_DUDE; break; + case USRP2_CTRL_ID_SO_LIKE_CAN_YOU_READ_THIS_UART_BRO:{ + //executes a readline()-style read, up to num_bytes long, up to and including newline + int num_bytes = ctrl_data_in->data.uart_args.bytes; + if(num_bytes > 20) num_bytes = 20; + num_bytes = fngets(ctrl_data_in->data.uart_args.dev, (char *) ctrl_data_in->data.uart_args.data, num_bytes); + ctrl_data_out.id = USRP2_CTRL_ID_I_HELLA_READ_THAT_UART_DUDE; + ctrl_data_out.data.uart_args.bytes = num_bytes; + break; + } + + case USRP2_CTRL_ID_HEY_WRITE_THIS_UART_FOR_ME_BRO:{ + int num_bytes = ctrl_data_in->data.uart_args.bytes; + if(num_bytes > 20) num_bytes = 20; + fnputstr(ctrl_data_in->data.uart_args.dev, (char *) ctrl_data_in->data.uart_args.data, num_bytes); + ctrl_data_out.id = USRP2_CTRL_ID_MAN_I_TOTALLY_WROTE_THAT_UART_DUDE; + ctrl_data_out.data.i2c_args.bytes = num_bytes; + break; + } + default: ctrl_data_out.id = USRP2_CTRL_ID_HUH_WHAT; diff --git a/firmware/microblaze/lib/hal_io.c b/firmware/microblaze/lib/hal_io.c index 8bb5e2af8..549990311 100644 --- a/firmware/microblaze/lib/hal_io.c +++ b/firmware/microblaze/lib/hal_io.c @@ -205,6 +205,18 @@ fputstr(hal_uart_name_t u, const char *s) return 0; } +int +fnputstr(hal_uart_name_t u, const char *s, int len) +{ + int x; + while (*s && (len > x)) { + fputchar(u, *s++); + x++; + } + + return x; +} + int putstr(const char *s) { @@ -233,6 +245,15 @@ fgets(hal_uart_name_t u, char * const s) return s; } +int +fngets(hal_uart_name_t u, char * const s, int len) +{ + char *x = s; + while(((*x=(char)hal_uart_getc(u)) != '\n') && ((x-s) < len)) x++; + *x = 0; + return (x-s)-1; +} + char * gets(char * const s) { diff --git a/firmware/microblaze/lib/hal_io.h b/firmware/microblaze/lib/hal_io.h index 99f8f7fc9..45e23755f 100644 --- a/firmware/microblaze/lib/hal_io.h +++ b/firmware/microblaze/lib/hal_io.h @@ -26,6 +26,8 @@ void hal_io_init(void); void hal_finish(); char *gets(char * const s); int fputstr(hal_uart_name_t u, const char *s); +int fnputstr(hal_uart_name_t u, const char *s, int len); +int fngets(hal_uart_name_t u, char * const s, int len); /* * ------------------------------------------------------------------------ diff --git a/firmware/microblaze/lib/hal_uart.c b/firmware/microblaze/lib/hal_uart.c index 6717cd5e8..c85bcaca3 100644 --- a/firmware/microblaze/lib/hal_uart.c +++ b/firmware/microblaze/lib/hal_uart.c @@ -47,7 +47,7 @@ static char uart_mode[4] = { static char uart_speeds[4] = { [UART_DEBUG] = US_230400, [UART_EXP] = US_230400, - [UART_GPS] = US_230400 + [UART_GPS] = US_115200 }; void diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h index 85d41d57f..fc1e6f2a7 100644 --- a/host/lib/usrp/usrp2/fw_common.h +++ b/host/lib/usrp/usrp2/fw_common.h @@ -83,6 +83,12 @@ typedef enum{ USRP2_CTRL_ID_PEEK_AT_THIS_REGISTER_FOR_ME_BRO = 'r', USRP2_CTRL_ID_WOAH_I_DEFINITELY_PEEKED_IT_DUDE = 'R', + USRP2_CTRL_ID_HEY_WRITE_THIS_UART_FOR_ME_BRO = 'u', + USRP2_CTRL_ID_MAN_I_TOTALLY_WROTE_THAT_UART_DUDE = 'U', + + USRP2_CTRL_ID_SO_LIKE_CAN_YOU_READ_THIS_UART_BRO = 'v', + USRP2_CTRL_ID_I_HELLA_READ_THAT_UART_DUDE = 'V', + USRP2_CTRL_ID_PEACE_OUT = '~' } usrp2_ctrl_id_t; @@ -123,6 +129,11 @@ typedef struct{ __stdint(uint32_t) datahi; __stdint(uint8_t) num_bytes; //1, 2, 4, 8 } poke_args; + struct { + __stdint(uint8_t) dev; + __stdint(uint8_t) bytes; + __stdint(uint8_t) data[20]; + } uart_args; } data; } usrp2_ctrl_data_t; -- cgit v1.2.3 From 6be2b64ce86f4bb9f36bae8758d7de2ddbabe2b1 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Thu, 12 Aug 2010 18:13:45 -0700 Subject: Fixed GPS UART stuff. Works OK. --- firmware/microblaze/apps/txrx_uhd.c | 4 ++-- firmware/microblaze/lib/hal_io.c | 6 ++---- firmware/microblaze/lib/hal_uart.c | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) (limited to 'firmware/microblaze/lib/hal_uart.c') diff --git a/firmware/microblaze/apps/txrx_uhd.c b/firmware/microblaze/apps/txrx_uhd.c index 42a3f4b89..2065830ff 100644 --- a/firmware/microblaze/apps/txrx_uhd.c +++ b/firmware/microblaze/apps/txrx_uhd.c @@ -315,7 +315,7 @@ void handle_udp_ctrl_packet( //executes a readline()-style read, up to num_bytes long, up to and including newline int num_bytes = ctrl_data_in->data.uart_args.bytes; if(num_bytes > 20) num_bytes = 20; - num_bytes = fngets(ctrl_data_in->data.uart_args.dev, (char *) ctrl_data_in->data.uart_args.data, num_bytes); + num_bytes = fngets(ctrl_data_in->data.uart_args.dev, (char *) ctrl_data_out.data.uart_args.data, num_bytes); ctrl_data_out.id = USRP2_CTRL_ID_I_HELLA_READ_THAT_UART_DUDE; ctrl_data_out.data.uart_args.bytes = num_bytes; break; @@ -326,7 +326,7 @@ void handle_udp_ctrl_packet( if(num_bytes > 20) num_bytes = 20; fnputstr(ctrl_data_in->data.uart_args.dev, (char *) ctrl_data_in->data.uart_args.data, num_bytes); ctrl_data_out.id = USRP2_CTRL_ID_MAN_I_TOTALLY_WROTE_THAT_UART_DUDE; - ctrl_data_out.data.i2c_args.bytes = num_bytes; + ctrl_data_out.data.uart_args.bytes = num_bytes; break; } diff --git a/firmware/microblaze/lib/hal_io.c b/firmware/microblaze/lib/hal_io.c index 549990311..18cc34aaf 100644 --- a/firmware/microblaze/lib/hal_io.c +++ b/firmware/microblaze/lib/hal_io.c @@ -208,11 +208,9 @@ fputstr(hal_uart_name_t u, const char *s) int fnputstr(hal_uart_name_t u, const char *s, int len) { - int x; - while (*s && (len > x)) { + int x = 0; + while (*s && (len > x++)) fputchar(u, *s++); - x++; - } return x; } diff --git a/firmware/microblaze/lib/hal_uart.c b/firmware/microblaze/lib/hal_uart.c index c85bcaca3..a8344daf5 100644 --- a/firmware/microblaze/lib/hal_uart.c +++ b/firmware/microblaze/lib/hal_uart.c @@ -64,7 +64,7 @@ void hal_uart_set_speed(hal_uart_name_t uart, hal_uart_speed_t speed) void hal_uart_init(void) { - for(int i = 0; i < 2; i++) { //uart 3 is unused + for(int i = 0; i < 3; i++) { hal_uart_set_mode(i, uart_mode[i]); hal_uart_set_speed(i, uart_speeds[i]); } -- cgit v1.2.3 From f09d9820ed40371f552d3a910bc2d8170d290653 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Fri, 13 Aug 2010 11:34:07 -0700 Subject: first stab at a GPS driver in gps_ctrl.cpp. not the most expandable thing in the world but there's only so many GPS interfaces out there. --- firmware/microblaze/apps/txrx_uhd.c | 3 + firmware/microblaze/lib/hal_uart.c | 7 ++ firmware/microblaze/lib/hal_uart.h | 1 + host/lib/usrp/usrp2/CMakeLists.txt | 2 + host/lib/usrp/usrp2/gps_ctrl.cpp | 140 ++++++++++++++++++++++++++++++++++++ host/lib/usrp/usrp2/gps_ctrl.hpp | 53 ++++++++++++++ host/lib/usrp/usrp2/mboard_impl.cpp | 7 +- host/lib/usrp/usrp2/usrp2_impl.hpp | 2 + 8 files changed, 209 insertions(+), 6 deletions(-) create mode 100644 host/lib/usrp/usrp2/gps_ctrl.cpp create mode 100644 host/lib/usrp/usrp2/gps_ctrl.hpp (limited to 'firmware/microblaze/lib/hal_uart.c') diff --git a/firmware/microblaze/apps/txrx_uhd.c b/firmware/microblaze/apps/txrx_uhd.c index 2065830ff..9fe17e262 100644 --- a/firmware/microblaze/apps/txrx_uhd.c +++ b/firmware/microblaze/apps/txrx_uhd.c @@ -324,6 +324,9 @@ void handle_udp_ctrl_packet( case USRP2_CTRL_ID_HEY_WRITE_THIS_UART_FOR_ME_BRO:{ int num_bytes = ctrl_data_in->data.uart_args.bytes; if(num_bytes > 20) num_bytes = 20; + //before we write to the UART, we flush the receive buffer + //this assumes that we're interested in the reply + hal_uart_rx_flush(ctrl_data_in->data.uart_args.dev); fnputstr(ctrl_data_in->data.uart_args.dev, (char *) ctrl_data_in->data.uart_args.data, num_bytes); ctrl_data_out.id = USRP2_CTRL_ID_MAN_I_TOTALLY_WROTE_THAT_UART_DUDE; ctrl_data_out.data.uart_args.bytes = num_bytes; diff --git a/firmware/microblaze/lib/hal_uart.c b/firmware/microblaze/lib/hal_uart.c index a8344daf5..8f7f83a68 100644 --- a/firmware/microblaze/lib/hal_uart.c +++ b/firmware/microblaze/lib/hal_uart.c @@ -101,3 +101,10 @@ hal_uart_getc(hal_uart_name_t u) return uart_regs[u].rxchar; } +int hal_uart_rx_flush(hal_uart_name_t u) +{ + char x; + while(uart_regs[u].rxlevel) x = uart_regs[u].rxchar; + return x; +} + diff --git a/firmware/microblaze/lib/hal_uart.h b/firmware/microblaze/lib/hal_uart.h index 81f4a6777..051dffe92 100644 --- a/firmware/microblaze/lib/hal_uart.h +++ b/firmware/microblaze/lib/hal_uart.h @@ -82,5 +82,6 @@ void hal_uart_putc_nowait(hal_uart_name_t u, int ch); */ int hal_uart_getc(hal_uart_name_t u); +int hal_uart_rx_flush(hal_uart_name_t u); #endif /* INCLUDED_HAL_UART_H */ diff --git a/host/lib/usrp/usrp2/CMakeLists.txt b/host/lib/usrp/usrp2/CMakeLists.txt index b4a90a6ba..47d74cec8 100644 --- a/host/lib/usrp/usrp2/CMakeLists.txt +++ b/host/lib/usrp/usrp2/CMakeLists.txt @@ -26,6 +26,8 @@ LIBUHD_APPEND_SOURCES( ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dboard_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dboard_iface.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dsp_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/gps_ctrl.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/gps_ctrl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/io_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/mboard_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/serdes_ctrl.cpp diff --git a/host/lib/usrp/usrp2/gps_ctrl.cpp b/host/lib/usrp/usrp2/gps_ctrl.cpp new file mode 100644 index 000000000..5c015be14 --- /dev/null +++ b/host/lib/usrp/usrp2/gps_ctrl.cpp @@ -0,0 +1,140 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#include "gps_ctrl.hpp" +#include +#include +#include +#include + +using namespace uhd; +using namespace boost::gregorian; +using namespace boost::posix_time; + +/*! + * A usrp2 GPS control for Jackson Labs devices + */ + +//TODO: multiple baud rate support (requires mboard_impl changes for poking UART registers), NMEA support, better autodetection +class usrp2_gps_ctrl_impl : public usrp2_gps_ctrl{ +public: + usrp2_gps_ctrl_impl(usrp2_iface::sptr iface){ + _iface = iface; + //do init here + //so the Jackson Labs Firefly (and Fury) don't acknowledge successful commands -- only invalid ones. + //first we test to see if there's a Firefly/Fury connected by sending an invalid packet and listening for the response + + std::string reply; + + //TODO: try multiple baud rates (many GPS's are set up for 4800bps, you're fixed at 115200bps 8N1 right now) + //you have to poke registers in order to set baud rate, there's no dude/bro interface for it + _iface->write_uart(GPS_UART, "HAAAY GUYYYYS\n"); + try { + reply = _iface->read_uart(GPS_UART, 20); + } catch (std::runtime_error err) { + if(err.what() != std::string("usrp2 no control response")) throw; //sorry can't cope with that + else { //we don't actually have a GPS installed + gps_type = GPS_TYPE_NONE; + } + } + + if(reply == "Command Error") gps_type = GPS_TYPE_JACKSON_LABS; + else gps_type = GPS_TYPE_NONE; //we'll add NMEA support later + + switch(gps_type) { + case GPS_TYPE_JACKSON_LABS: + //issue some setup stuff so it quits spewing data out when not asked to + //none of these should issue replies so we don't bother looking for it + _iface->write_uart(GPS_UART, "SYST:COMM:SER:"); + _iface->write_uart(GPS_UART, "ECHO OFF\n"); //we split lines before 20 chars right now -- TODO: fix driver to split writes/reads for you + _iface->write_uart(GPS_UART, "SYST:COMM:SER:"); + _iface->write_uart(GPS_UART, "PRO OFF\n"); + _iface->write_uart(GPS_UART, "GPS:GPGGA 0\n"); + _iface->write_uart(GPS_UART, "GPS:GGAST 0\n"); + break; + + case GPS_TYPE_GENERIC_NMEA: + case GPS_TYPE_NONE: + default: + + break; + } + } + + ~usrp2_gps_ctrl_impl(void){ + + } + + ptime get_time(void) { + std::string reply; + ptime now; + switch(gps_type) { + case GPS_TYPE_JACKSON_LABS: + _iface->write_uart(GPS_UART, "PTIME:TIME\n"); + reply = _iface->read_uart(GPS_UART, 20); + now = ptime(get_date(), duration_from_string(reply)); + break; + case GPS_TYPE_GENERIC_NMEA: + case GPS_TYPE_NONE: + default: + throw std::runtime_error("get_time(): Unsupported GPS or no GPS detected\n"); + break; + } + return now; + } + + date get_date(void) { + std::string reply; + date today; + switch(gps_type) { + case GPS_TYPE_JACKSON_LABS: + _iface->write_uart(GPS_UART, "PTIME:DATE\n"); + reply = _iface->read_uart(GPS_UART, 20); + today = from_string(reply); + break; + case GPS_TYPE_GENERIC_NMEA: + case GPS_TYPE_NONE: + default: + throw std::runtime_error("get_date(): Unsupported GPS or no GPS detected\n"); + break; + } + return today; + } + + bool gps_detected(void) { + return (gps_type != GPS_TYPE_NONE); + } + +private: + usrp2_iface::sptr _iface; + + enum { + GPS_TYPE_JACKSON_LABS, + GPS_TYPE_GENERIC_NMEA, + GPS_TYPE_NONE + } gps_type; + + static const int GPS_UART = 2; //TODO: this should be plucked from fw_common.h or memory_map.h or somewhere in common with the firmware + +}; + +/*********************************************************************** + * Public make function for the GPS control + **********************************************************************/ +usrp2_gps_ctrl::sptr usrp2_gps_ctrl::make(usrp2_iface::sptr iface){ + return sptr(new usrp2_gps_ctrl_impl(iface)); +} diff --git a/host/lib/usrp/usrp2/gps_ctrl.hpp b/host/lib/usrp/usrp2/gps_ctrl.hpp new file mode 100644 index 000000000..5936a6fb6 --- /dev/null +++ b/host/lib/usrp/usrp2/gps_ctrl.hpp @@ -0,0 +1,53 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#ifndef INCLUDED_GPS_CTRL_HPP +#define INCLUDED_GPS_CTRL_HPP + +#include "usrp2_iface.hpp" +#include +#include +#include + +using namespace boost::posix_time; + +class usrp2_gps_ctrl : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + + /*! + * Make a GPS config for Jackson Labs or generic NMEA GPS devices + */ + static sptr make(usrp2_iface::sptr iface); + + /*! + * Get the current GPS time and date + * \return current GPS time and date as boost::posix_time::ptime object + */ + virtual ptime get_time(void) = 0; + + /*! + * Tell you if there's a supported GPS connected or not + * \return true if a supported GPS is connected + */ + virtual bool gps_detected(void) = 0; + + //TODO: other fun things you can do with a GPS. + +}; + +#endif /* INCLUDED_CLOCK_CTRL_HPP */ diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 96c98f6c5..ed6398405 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -51,16 +51,11 @@ usrp2_mboard_impl::usrp2_mboard_impl( //set the device revision (USRP2 or USRP2+) based on the above _iface->set_hw_rev((_rev_hi << 8) | _rev_lo); - //TODO DEBUG! this is just here to test writing to and reading from the UART. - std::string mystr = "PTIME:TIME?\n"; - _iface->write_uart(2, mystr); - mystr = _iface->read_uart(2, 20); - std::cout << "what time is it? " << mystr.c_str(); - //contruct the interfaces to mboard perifs _clock_ctrl = usrp2_clock_ctrl::make(_iface); _codec_ctrl = usrp2_codec_ctrl::make(_iface); _serdes_ctrl = usrp2_serdes_ctrl::make(_iface); + _gps_ctrl = usrp2_gps_ctrl::make(_iface); //TODO move to dsp impl... //load the allowed decim/interp rates diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 21a56cb67..b37c61488 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -21,6 +21,7 @@ #include "usrp2_iface.hpp" #include "clock_ctrl.hpp" #include "codec_ctrl.hpp" +#include "gps_ctrl.hpp" #include "serdes_ctrl.hpp" #include #include @@ -151,6 +152,7 @@ private: usrp2_clock_ctrl::sptr _clock_ctrl; usrp2_codec_ctrl::sptr _codec_ctrl; usrp2_serdes_ctrl::sptr _serdes_ctrl; + usrp2_gps_ctrl::sptr _gps_ctrl; //rx and tx dboard methods and objects uhd::usrp::dboard_manager::sptr _dboard_manager; -- cgit v1.2.3 From 6bde8e29eb28b746109531553d38fec91a89dc73 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Fri, 13 Aug 2010 12:09:28 -0700 Subject: Added timeout functionality for UART gets() calls. use fngets_timeout(). timeout defined in hal_uart.h. --- firmware/microblaze/apps/txrx_uhd.c | 2 +- firmware/microblaze/lib/hal_io.c | 9 +++++++++ firmware/microblaze/lib/hal_io.h | 1 + firmware/microblaze/lib/hal_uart.c | 11 +++++++++++ firmware/microblaze/lib/hal_uart.h | 7 +++++++ 5 files changed, 29 insertions(+), 1 deletion(-) (limited to 'firmware/microblaze/lib/hal_uart.c') diff --git a/firmware/microblaze/apps/txrx_uhd.c b/firmware/microblaze/apps/txrx_uhd.c index 9fe17e262..9cf4c163f 100644 --- a/firmware/microblaze/apps/txrx_uhd.c +++ b/firmware/microblaze/apps/txrx_uhd.c @@ -315,7 +315,7 @@ void handle_udp_ctrl_packet( //executes a readline()-style read, up to num_bytes long, up to and including newline int num_bytes = ctrl_data_in->data.uart_args.bytes; if(num_bytes > 20) num_bytes = 20; - num_bytes = fngets(ctrl_data_in->data.uart_args.dev, (char *) ctrl_data_out.data.uart_args.data, num_bytes); + num_bytes = fngets_timeout(ctrl_data_in->data.uart_args.dev, (char *) ctrl_data_out.data.uart_args.data, num_bytes); ctrl_data_out.id = USRP2_CTRL_ID_I_HELLA_READ_THAT_UART_DUDE; ctrl_data_out.data.uart_args.bytes = num_bytes; break; diff --git a/firmware/microblaze/lib/hal_io.c b/firmware/microblaze/lib/hal_io.c index 18cc34aaf..0e3754958 100644 --- a/firmware/microblaze/lib/hal_io.c +++ b/firmware/microblaze/lib/hal_io.c @@ -252,6 +252,15 @@ fngets(hal_uart_name_t u, char * const s, int len) return (x-s)-1; } +int +fngets_timeout(hal_uart_name_t u, char * const s, int len) +{ + char *x = s; + while(((*x=(char)hal_uart_getc_timeout(u)) != '\n') && ((x-s) < len)) x++; + *x = 0; + return (x-s)-1; +} + char * gets(char * const s) { diff --git a/firmware/microblaze/lib/hal_io.h b/firmware/microblaze/lib/hal_io.h index 45e23755f..950f8d591 100644 --- a/firmware/microblaze/lib/hal_io.h +++ b/firmware/microblaze/lib/hal_io.h @@ -28,6 +28,7 @@ char *gets(char * const s); int fputstr(hal_uart_name_t u, const char *s); int fnputstr(hal_uart_name_t u, const char *s, int len); int fngets(hal_uart_name_t u, char * const s, int len); +int fngets_timeout(hal_uart_name_t u, char * const s, int len); /* * ------------------------------------------------------------------------ diff --git a/firmware/microblaze/lib/hal_uart.c b/firmware/microblaze/lib/hal_uart.c index 8f7f83a68..4d754d5e5 100644 --- a/firmware/microblaze/lib/hal_uart.c +++ b/firmware/microblaze/lib/hal_uart.c @@ -19,6 +19,7 @@ #include "memory_map.h" #include "hal_uart.h" #include "hal_io.h" +#include "mdelay.h" //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. @@ -101,6 +102,16 @@ hal_uart_getc(hal_uart_name_t u) return uart_regs[u].rxchar; } +int +hal_uart_getc_timeout(hal_uart_name_t u) +{ + int timeout = 0; + while (((uart_regs[u].rxlevel) == 0) && (timeout++ < HAL_UART_TIMEOUT_MS)) + mdelay(1); + + return (uart_regs[u].rxlevel == 0) ? 0 : uart_regs[u].rxchar; +} + int hal_uart_rx_flush(hal_uart_name_t u) { char x; diff --git a/firmware/microblaze/lib/hal_uart.h b/firmware/microblaze/lib/hal_uart.h index 051dffe92..b9b0a5e14 100644 --- a/firmware/microblaze/lib/hal_uart.h +++ b/firmware/microblaze/lib/hal_uart.h @@ -27,6 +27,8 @@ #define DEFAULT_UART UART_DEBUG //which UART printf, gets, etc. use +#define HAL_UART_TIMEOUT_MS 100 + typedef enum { US_9600 = 0, US_19200 = 1, @@ -82,6 +84,11 @@ void hal_uart_putc_nowait(hal_uart_name_t u, int ch); */ int hal_uart_getc(hal_uart_name_t u); +/* + * \brief Blocking read of next char from serial port with timeout + */ +int hal_uart_getc_timeout(hal_uart_name_t u); + int hal_uart_rx_flush(hal_uart_name_t u); #endif /* INCLUDED_HAL_UART_H */ -- cgit v1.2.3 From d96e9f907e17900a59247ba6d28d33c26a1c4468 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Fri, 13 Aug 2010 13:07:14 -0700 Subject: Increased UART timeout for slow Jackson Labs GPSDO. Fixed up timeout code. --- firmware/microblaze/lib/hal_io.c | 1 + firmware/microblaze/lib/hal_uart.c | 2 +- firmware/microblaze/lib/hal_uart.h | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) (limited to 'firmware/microblaze/lib/hal_uart.c') diff --git a/firmware/microblaze/lib/hal_io.c b/firmware/microblaze/lib/hal_io.c index 0e3754958..f93b20030 100644 --- a/firmware/microblaze/lib/hal_io.c +++ b/firmware/microblaze/lib/hal_io.c @@ -258,6 +258,7 @@ fngets_timeout(hal_uart_name_t u, char * const s, int len) char *x = s; while(((*x=(char)hal_uart_getc_timeout(u)) != '\n') && ((x-s) < len)) x++; *x = 0; + if(x==s) return 0; return (x-s)-1; } diff --git a/firmware/microblaze/lib/hal_uart.c b/firmware/microblaze/lib/hal_uart.c index 4d754d5e5..9697f5b20 100644 --- a/firmware/microblaze/lib/hal_uart.c +++ b/firmware/microblaze/lib/hal_uart.c @@ -109,7 +109,7 @@ hal_uart_getc_timeout(hal_uart_name_t u) while (((uart_regs[u].rxlevel) == 0) && (timeout++ < HAL_UART_TIMEOUT_MS)) mdelay(1); - return (uart_regs[u].rxlevel == 0) ? 0 : uart_regs[u].rxchar; + return (timeout == HAL_UART_TIMEOUT_MS) ? '\n' : uart_regs[u].rxchar; //return a newline if nothing there, this will trip fngets to quit } int hal_uart_rx_flush(hal_uart_name_t u) diff --git a/firmware/microblaze/lib/hal_uart.h b/firmware/microblaze/lib/hal_uart.h index b9b0a5e14..758c8cb5e 100644 --- a/firmware/microblaze/lib/hal_uart.h +++ b/firmware/microblaze/lib/hal_uart.h @@ -27,7 +27,7 @@ #define DEFAULT_UART UART_DEBUG //which UART printf, gets, etc. use -#define HAL_UART_TIMEOUT_MS 100 +#define HAL_UART_TIMEOUT_MS 300 typedef enum { US_9600 = 0, -- cgit v1.2.3 From f626a4f21d7301e573bcb601f16bf6ba38352c34 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Fri, 13 Aug 2010 17:28:08 -0700 Subject: Fixed behavior when no GPS present. --- firmware/microblaze/lib/hal_io.c | 4 ++-- firmware/microblaze/lib/hal_uart.c | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'firmware/microblaze/lib/hal_uart.c') diff --git a/firmware/microblaze/lib/hal_io.c b/firmware/microblaze/lib/hal_io.c index a8654bce7..261c8cc2a 100644 --- a/firmware/microblaze/lib/hal_io.c +++ b/firmware/microblaze/lib/hal_io.c @@ -256,9 +256,9 @@ int fngets_timeout(hal_uart_name_t u, char * const s, int len) { char *x = s; - while(((*x=(char)hal_uart_getc_timeout(u)) != '\n') && ((x-s) < len)) x++; + + while(((*x=(char)hal_uart_getc_timeout(u)) != '\n') && (*x != -1) && ((x-s) < len)) x++; *x = 0; - if(x==s) return 0; return (x-s); } diff --git a/firmware/microblaze/lib/hal_uart.c b/firmware/microblaze/lib/hal_uart.c index 9697f5b20..0ac6abd69 100644 --- a/firmware/microblaze/lib/hal_uart.c +++ b/firmware/microblaze/lib/hal_uart.c @@ -108,8 +108,7 @@ hal_uart_getc_timeout(hal_uart_name_t u) int timeout = 0; while (((uart_regs[u].rxlevel) == 0) && (timeout++ < HAL_UART_TIMEOUT_MS)) mdelay(1); - - return (timeout == HAL_UART_TIMEOUT_MS) ? '\n' : uart_regs[u].rxchar; //return a newline if nothing there, this will trip fngets to quit + return (timeout == HAL_UART_TIMEOUT_MS) ? -1 : uart_regs[u].rxchar; //return -1 if nothing there, cause fngets to quit } int hal_uart_rx_flush(hal_uart_name_t u) -- cgit v1.2.3 From 40faee2e6d87f7364a0c0c2cf310f1483c0331cf Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Mon, 16 Aug 2010 16:09:52 -0700 Subject: Finished GPS driver, more or less. Should detect any 115kbaud GPS on the serial port, as long as it outputs GPRMC packets. Tweaked the serial driver for a stupid off-by-one mistake. --- firmware/microblaze/lib/hal_io.c | 17 +++--- firmware/microblaze/lib/hal_uart.c | 2 +- host/lib/usrp/usrp2/gps_ctrl.cpp | 116 +++++++++++++++++++++++++++---------- 3 files changed, 97 insertions(+), 38 deletions(-) (limited to 'firmware/microblaze/lib/hal_uart.c') diff --git a/firmware/microblaze/lib/hal_io.c b/firmware/microblaze/lib/hal_io.c index 261c8cc2a..be4c570c7 100644 --- a/firmware/microblaze/lib/hal_io.c +++ b/firmware/microblaze/lib/hal_io.c @@ -237,10 +237,10 @@ int puts(const char *s) char * fgets(hal_uart_name_t u, char * const s) { - char *x = s; - while((*x=(char)hal_uart_getc(u)) != '\n') x++; - *x = 0; - return s; + char *x = s; + while((*x=(char)hal_uart_getc(u)) != '\n') x++; + *x = 0; + return s; } int @@ -248,8 +248,8 @@ fngets(hal_uart_name_t u, char * const s, int len) { char *x = s; while(((*x=(char)hal_uart_getc(u)) != '\n') && ((x-s) < len)) x++; - *x = 0; - return (x-s); + *x = 0; + return (x-s); } int @@ -258,8 +258,9 @@ fngets_timeout(hal_uart_name_t u, char * const s, int len) char *x = s; while(((*x=(char)hal_uart_getc_timeout(u)) != '\n') && (*x != -1) && ((x-s) < len)) x++; - *x = 0; - return (x-s); + *x = 0; + //printf("Returning from fngets() with string %d of length %d\n", s[0], x-s); + return (x-s); } char * diff --git a/firmware/microblaze/lib/hal_uart.c b/firmware/microblaze/lib/hal_uart.c index 0ac6abd69..7836240fe 100644 --- a/firmware/microblaze/lib/hal_uart.c +++ b/firmware/microblaze/lib/hal_uart.c @@ -108,7 +108,7 @@ hal_uart_getc_timeout(hal_uart_name_t u) int timeout = 0; while (((uart_regs[u].rxlevel) == 0) && (timeout++ < HAL_UART_TIMEOUT_MS)) mdelay(1); - return (timeout == HAL_UART_TIMEOUT_MS) ? -1 : uart_regs[u].rxchar; //return -1 if nothing there, cause fngets to quit + return (timeout >= HAL_UART_TIMEOUT_MS) ? -1 : uart_regs[u].rxchar; //return -1 if nothing there, cause fngets to quit } int hal_uart_rx_flush(hal_uart_name_t u) diff --git a/host/lib/usrp/usrp2/gps_ctrl.cpp b/host/lib/usrp/usrp2/gps_ctrl.cpp index 20d670f81..2273b2cd9 100644 --- a/host/lib/usrp/usrp2/gps_ctrl.cpp +++ b/host/lib/usrp/usrp2/gps_ctrl.cpp @@ -33,74 +33,130 @@ using namespace boost::algorithm; * A usrp2 GPS control for Jackson Labs devices */ -//TODO: multiple baud rate support (requires mboard_impl changes for poking UART registers), NMEA support, better autodetection +//TODO: multiple baud rate support (requires mboard_impl changes for poking UART registers) class usrp2_gps_ctrl_impl : public usrp2_gps_ctrl{ public: usrp2_gps_ctrl_impl(usrp2_iface::sptr iface){ _iface = iface; - //do init here - //so the Jackson Labs Firefly (and Fury) don't acknowledge successful commands -- only invalid ones. - //first we test to see if there's a Firefly/Fury connected by sending an invalid packet and listening for the response std::string reply; + bool i_heard_some_nmea = false, i_heard_something_weird = false; - //TODO: try multiple baud rates (many GPS's are set up for 4800bps, you're fixed at 115200bps 8N1 right now) - //you have to poke registers in order to set baud rate, there's no dude/bro interface for it - _iface->read_uart(GPS_UART); //flush it out - _iface->write_uart(GPS_UART, "HAAAY GUYYYYS\n"); - try { - reply = _iface->read_uart(GPS_UART); - //std::cerr << "Got reply from GPS: " << reply.c_str() << " with length = " << reply.length() << std::endl; - } catch (std::runtime_error err) { - if(err.what() != std::string("usrp2 no control response")) throw; //sorry can't cope with that - else { //we don't actually have a GPS installed - gps_type = GPS_TYPE_NONE; + gps_type = GPS_TYPE_NONE; + +// set_uart_baud_rate(GPS_UART, 115200); + //first we look for a Jackson Labs Firefly (since that's what we sell with the USRP2+...) + + _iface->read_uart(GPS_UART); //get whatever junk is in the rx buffer right now, and throw it away + _iface->write_uart(GPS_UART, "HAAAY GUYYYYS\n"); //to elicit a response from the Firefly + + //then we loop until we either timeout, or until we get a response that indicates we're a JL device + int timeout = GPS_TIMEOUT_TRIES; + while(timeout--) { + reply = safe_gps_read(); + if(trim_right_copy(reply) == "Command Error") { + gps_type = GPS_TYPE_JACKSON_LABS; + break; } + else if(reply.substr(0, 3) == "$GP") i_heard_some_nmea = true; //but keep looking for that "Command Error" response + else if(reply.length() != 0) i_heard_something_weird = true; //probably wrong baud rate } - if(trim_right_copy(reply) == "Command Error") gps_type = GPS_TYPE_JACKSON_LABS; - else gps_type = GPS_TYPE_NONE; //we'll add NMEA support later + if((i_heard_some_nmea) && (gps_type != GPS_TYPE_JACKSON_LABS)) gps_type = GPS_TYPE_GENERIC_NMEA; + + //otherwise, we can try some other common baud rates looking to see if a GPS is connected (todo, later) + if((gps_type == GPS_TYPE_NONE) && i_heard_something_weird) { + std::cout << "Invalid reply, possible incorrect baud rate" << std::endl; + } + + bool found_gprmc = false; switch(gps_type) { case GPS_TYPE_JACKSON_LABS: - std::cerr << "Found a Jackson Labs GPS" << std::endl; - //issue some setup stuff so it quits spewing data out when not asked to - //none of these should issue replies so we don't bother looking for it + std::cout << "Found a Jackson Labs GPS" << std::endl; + //issue some setup stuff so it spits out the appropriate data + //none of these should issue replies so we don't bother looking for them //we have to sleep between commands because the JL device, despite not acking, takes considerable time to process each command. - boost::this_thread::sleep(boost::posix_time::milliseconds(200)); + boost::this_thread::sleep(boost::posix_time::milliseconds(FIREFLY_STUPID_DELAY_MS)); _iface->write_uart(GPS_UART, "SYST:COMM:SER:ECHO OFF\n"); - boost::this_thread::sleep(boost::posix_time::milliseconds(200)); + boost::this_thread::sleep(boost::posix_time::milliseconds(FIREFLY_STUPID_DELAY_MS)); _iface->write_uart(GPS_UART, "SYST:COMM:SER:PRO OFF\n"); - boost::this_thread::sleep(boost::posix_time::milliseconds(200)); + boost::this_thread::sleep(boost::posix_time::milliseconds(FIREFLY_STUPID_DELAY_MS)); _iface->write_uart(GPS_UART, "GPS:GPGGA 0\n"); - boost::this_thread::sleep(boost::posix_time::milliseconds(200)); + boost::this_thread::sleep(boost::posix_time::milliseconds(FIREFLY_STUPID_DELAY_MS)); _iface->write_uart(GPS_UART, "GPS:GGAST 0\n"); - boost::this_thread::sleep(boost::posix_time::milliseconds(200)); + boost::this_thread::sleep(boost::posix_time::milliseconds(FIREFLY_STUPID_DELAY_MS)); _iface->write_uart(GPS_UART, "GPS:GPRMC 1\n"); - boost::this_thread::sleep(boost::posix_time::milliseconds(200)); - break; + boost::this_thread::sleep(boost::posix_time::milliseconds(FIREFLY_STUPID_DELAY_MS)); + +// break; case GPS_TYPE_GENERIC_NMEA: + if(gps_type == GPS_TYPE_GENERIC_NMEA) std::cout << "Found a generic NMEA GPS device" << std::endl; + found_gprmc = false; + //here we loop around looking for a GPRMC packet. if we don't get one, we don't have a usable GPS. + timeout = GPS_TIMEOUT_TRIES; + while(timeout--) { + reply = safe_gps_read(); + if(reply.substr(0, 6) == "$GPRMC") { + found_gprmc = true; + break; + } + } + if(!found_gprmc) { + if(gps_type == GPS_TYPE_JACKSON_LABS) std::cout << "Firefly GPS not locked or warming up." << std::endl; + else std::cout << "GPS does not output GPRMC packets. Cannot retrieve time." << std::endl; + gps_type = GPS_TYPE_NONE; + } + break; + case GPS_TYPE_NONE: default: - break; + } + + } ~usrp2_gps_ctrl_impl(void){ } + std::string safe_gps_read() { + std::string reply; + try { + reply = _iface->read_uart(GPS_UART); + //std::cerr << "Got reply from GPS: " << reply.c_str() << " with length = " << reply.length() << std::endl; + } catch (std::runtime_error err) { + if(err.what() != std::string("usrp2 no control response")) throw; //sorry can't cope with that + else { //we don't actually have a GPS installed + reply = std::string(); + } + } + return reply; + } + ptime get_time(void) { std::string reply; ptime now; boost::tokenizer > tok(reply); std::vector toked; + int timeout = GPS_TIMEOUT_TRIES; + bool found_gprmc = false; switch(gps_type) { case GPS_TYPE_JACKSON_LABS: //deprecated in favor of a single NMEA parser case GPS_TYPE_GENERIC_NMEA: - while(reply.length() == 0) reply = _iface->read_uart(GPS_UART); //loop until we hear something + + while(timeout--) { + reply = safe_gps_read(); + if(reply.substr(0, 6) == "$GPRMC") { + found_gprmc = true; + break; + } + } + UHD_ASSERT_THROW(found_gprmc); + tok.assign(reply); toked.assign(tok.begin(), tok.end()); @@ -138,6 +194,8 @@ private: } gps_type; static const int GPS_UART = 2; //TODO: this should be plucked from fw_common.h or memory_map.h or somewhere in common with the firmware + static const int GPS_TIMEOUT_TRIES = 5; + static const int FIREFLY_STUPID_DELAY_MS = 200; }; -- cgit v1.2.3