icE1usb fw/gps: Use ericsson GPS 02/03 on aux uart
Signed-off-by: Sylvain Munaut <tnt@246tNt.com> Change-Id: Ia90d4e537445be2e037807c681d41e2d8f2759e2
This commit is contained in:
parent
f5e51f5d9f
commit
34b0d02865
|
@ -57,6 +57,7 @@ HEADERS_app=\
|
|||
ice1usb_proto.h \
|
||||
i2c.h \
|
||||
misc.h \
|
||||
rs422.h \
|
||||
usb_desc_ids.h \
|
||||
usb_dev.h \
|
||||
usb_e1.h \
|
||||
|
@ -72,6 +73,7 @@ SOURCES_app=\
|
|||
gpsdo.c \
|
||||
i2c.c \
|
||||
misc.c \
|
||||
rs422.c \
|
||||
usb_desc_app.c \
|
||||
usb_dev.c \
|
||||
usb_e1.c \
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#define MISC_BASE 0x88000000
|
||||
#define GPS_UART_BASE 0x89000000
|
||||
#define I2C_BASE 0x8a000000
|
||||
#define AUX_UART_BASE 0x8b000000
|
||||
|
||||
/* Alias for common code */
|
||||
#define UART_BASE DBG_UART_BASE
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "console.h"
|
||||
#include "gps.h"
|
||||
#include "misc.h"
|
||||
#include "rs422.h"
|
||||
#include "usb_gps.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
@ -28,7 +29,7 @@ struct gps_uart {
|
|||
#define GPS_UART_CSR_TX_EMPTY (1 << 29)
|
||||
#define GPS_UART_DATA_EMPTY (1 << 31)
|
||||
|
||||
static volatile struct gps_uart * const gps_uart_regs = (void*)(GPS_UART_BASE);
|
||||
static volatile struct gps_uart * const gps_uart_regs = (void*)(AUX_UART_BASE);
|
||||
|
||||
|
||||
static struct {
|
||||
|
@ -159,37 +160,11 @@ _gps_query(void)
|
|||
void
|
||||
_gps_parse_nmea(const char *nmea)
|
||||
{
|
||||
/* Very basic parsing, we just look at GSA messages and consider
|
||||
* that if we have a 3D fix with PDOP < 5, the timing data should
|
||||
* be usable
|
||||
*/
|
||||
if (!strncmp(nmea, "$GPGSA", 6))
|
||||
/* Very basic parsing, we just look at $PERC,GPsts message for
|
||||
* state 1 (survey mode) and 2 (position-hold) */
|
||||
if (!strncmp(nmea, "$PERC,GPsts,", 12))
|
||||
{
|
||||
/* Check for Autonomous 3D fix (fixed field positions) */
|
||||
if ((nmea[7] != 'A') || (nmea[9] != '3')) {
|
||||
g_gps.fix.valid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find PDOP */
|
||||
const char *p = nmea;
|
||||
for (int i=0; (i < 15) && (*p != '*'); i += (*(p++)==',') );
|
||||
|
||||
/* Is it low enough ? */
|
||||
g_gps.fix.valid = (p[1] < '5');
|
||||
}
|
||||
|
||||
/* Parse TXT ANTENNA Status */
|
||||
if (!strncmp(nmea, "$GPTXT", 6) && nmea[13] == '0' && nmea[14] == '1')
|
||||
{
|
||||
if (!strncmp(&nmea[16], "ANTENNA OK", 10))
|
||||
g_gps.antenna = ANT_OK;
|
||||
else if (!strncmp(&nmea[16], "ANTENNA OPEN", 12))
|
||||
g_gps.antenna = ANT_OPEN;
|
||||
else if (!strncmp(&nmea[16], "ANTENNA SHORT", 13))
|
||||
g_gps.antenna = ANT_SHORT;
|
||||
else
|
||||
g_gps.antenna = ANT_UNKNOWN;
|
||||
g_gps.fix.valid = (nmea[12] == '1') || (nmea[12] == '2');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -226,65 +201,31 @@ gps_poll(void)
|
|||
void
|
||||
gps_init(void)
|
||||
{
|
||||
int i;
|
||||
uint32_t start_time = time_now_read();
|
||||
bool init_ok;
|
||||
|
||||
/* State init */
|
||||
memset(&g_gps, 0x00, sizeof(g_gps));
|
||||
|
||||
/* Configure reset gpio */
|
||||
/* Hold onboard GPS in reset */
|
||||
gpio_out(3, false);
|
||||
gpio_dir(3, true);
|
||||
|
||||
/* Attempt reset sequence at 9600 baud and then 115200 baud */
|
||||
for (i=0; i<2; i++)
|
||||
{
|
||||
uint32_t start_time = time_now_read();
|
||||
bool init_ok;
|
||||
/* Init RS422 board */
|
||||
rs422_init();
|
||||
|
||||
/* Assert reset */
|
||||
gpio_out(3, false);
|
||||
/* Configure uart and empty buffer */
|
||||
gps_uart_regs->csr = GPS_UART_CSR_DIV(9600);
|
||||
_gps_empty(false);
|
||||
|
||||
/* Configure uart and empty buffer */
|
||||
gps_uart_regs->csr = i ? GPS_UART_CSR_DIV(115200) : GPS_UART_CSR_DIV(9600);
|
||||
_gps_empty(false);
|
||||
|
||||
/* Wait 100 ms */
|
||||
delay(100);
|
||||
|
||||
/* Release reset line */
|
||||
gpio_out(3, true);
|
||||
|
||||
/* Wait for first line of output as sign it's ready, timeout after 1s */
|
||||
while (!time_elapsed(start_time, SYS_CLK_FREQ))
|
||||
if ((init_ok = (_gps_query() != NULL)))
|
||||
break;
|
||||
|
||||
if (init_ok) {
|
||||
printf("[+] GPS ok at %d baud\n", i ? 115200 : 9600);
|
||||
/* Wait for first line of output as sign it's ready, timeout after 10 s */
|
||||
while (!time_elapsed(start_time, 10 * SYS_CLK_FREQ))
|
||||
if ((init_ok = (_gps_query() != NULL)))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Failed ? */
|
||||
if (i == 2) {
|
||||
if (init_ok) {
|
||||
printf("[+] GPS ok\n");
|
||||
} else {
|
||||
printf("[!] GPS init failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* If success was at 9600 baud, need to speed up */
|
||||
if (i == 0) {
|
||||
/* Configure GPS to use serial at 115200 baud */
|
||||
_gps_send("PCAS01,5");
|
||||
|
||||
/* Add dummy byte which will be mangled during baudrate switch ... */
|
||||
gps_uart_regs->data = 0x00;
|
||||
while (!(gps_uart_regs->csr & GPS_UART_CSR_TX_EMPTY));
|
||||
|
||||
/* Set uart to 115200 and empty uart buffer, line aligned */
|
||||
gps_uart_regs->csr = GPS_UART_CSR_DIV(115200) ;
|
||||
_gps_empty(true);
|
||||
}
|
||||
|
||||
/* Configure GPS to be GPS-only (no GLONASS/BEIDOU) */
|
||||
_gps_send("PCAS04,1");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* rs422.c
|
||||
*
|
||||
* Copyright (C) 2022 Sylvain Munaut <tnt@246tNt.com>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "console.h"
|
||||
#include "i2c.h"
|
||||
#include "misc.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
/* Local side buffer control */
|
||||
#define BUF_TCA9534_ADDR 0x42
|
||||
#define BUF_TXD_RXEN_n (1 << 0)
|
||||
#define BUF_TXD_TXEN_n (1 << 1)
|
||||
#define BUF_PPS_RXEN_n (1 << 4)
|
||||
#define BUF_PPS_TXEN_n (1 << 5)
|
||||
#define BUF_RXD_RXEN_n (1 << 6)
|
||||
#define BUF_RXD_TXEN_n (1 << 7)
|
||||
|
||||
/* Isolated side line driver control */
|
||||
#define LDRV_TCA9534_ADDR 0x40
|
||||
#define LDRV_TXD_RE_n (1 << 0)
|
||||
#define LDRV_TXD_DE (1 << 1)
|
||||
#define LDRV_RXD_RE_n (1 << 2)
|
||||
#define LDRV_RXD_DE (1 << 3)
|
||||
#define LDRV_PPS_DE (1 << 4)
|
||||
#define LDRV_PPS_RE_n (1 << 5)
|
||||
|
||||
|
||||
static void
|
||||
tca9534_set_out(uint8_t dev, uint8_t data)
|
||||
{
|
||||
/* Check device */
|
||||
if (!i2c_probe(dev)) {
|
||||
printf("[1] Unable to configure TCA9534 at address %02x\n", dev);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Output values */
|
||||
i2c_write_reg(dev, 1, data);
|
||||
|
||||
/* No inversion */
|
||||
i2c_write_reg(dev, 2, 0x00);
|
||||
|
||||
/* All pins as output to avoid floating pins */
|
||||
i2c_write_reg(dev, 3, 0x00);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
rs422_init(void)
|
||||
{
|
||||
/* Reset GPS receiver to free I2C bus */
|
||||
gpio_out(3, false);
|
||||
gpio_dir(3, true);
|
||||
|
||||
/* Configure:
|
||||
* - TXD pair: Receive
|
||||
* - RXD pair: Transmit
|
||||
* - PPS pair: Receive
|
||||
*/
|
||||
tca9534_set_out(BUF_TCA9534_ADDR,
|
||||
BUF_TXD_TXEN_n |
|
||||
BUF_RXD_RXEN_n |
|
||||
BUF_PPS_TXEN_n |
|
||||
0
|
||||
);
|
||||
|
||||
tca9534_set_out(LDRV_TCA9534_ADDR,
|
||||
LDRV_RXD_RE_n |
|
||||
#if 0
|
||||
/* We don't actually TX anything to the module and
|
||||
* this burns power ... */
|
||||
LDRV_RXD_DE |
|
||||
#endif
|
||||
0
|
||||
);
|
||||
|
||||
/* Configure GPIO alt functions */
|
||||
/* Aux UART RX */
|
||||
gpio_sfn(0, true);
|
||||
|
||||
/* Aux UART TX */
|
||||
gpio_sfn(1, true);
|
||||
|
||||
/* PPS input */
|
||||
gpio_dir(2, false);
|
||||
gpio_sfn(2, true);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* rs422.h
|
||||
*
|
||||
* Copyright (C) 2022 Sylvain Munaut <tnt@246tNt.com>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void rs422_init(void);
|
Loading…
Reference in New Issue