summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfishsoupisgood <github@madingley.org>2019-05-04 12:37:04 +0100
committerfishsoupisgood <github@madingley.org>2019-05-04 12:39:08 +0100
commit74e577ac110513669a6d677842ceca4c5b1252ca (patch)
treecfe45c037717a740fa2fa6b1c99aa66814047055
parent1b0a5f886412f0a292ec2b198e65760e3a1f45a1 (diff)
downloadclock-74e577ac110513669a6d677842ceca4c5b1252ca.tar.gz
clock-74e577ac110513669a6d677842ceca4c5b1252ca.tar.bz2
clock-74e577ac110513669a6d677842ceca4c5b1252ca.zip
cut #1
-rw-r--r--Makefile.include2
-rw-r--r--app/Makefile39
-rw-r--r--app/bits.c2
-rw-r--r--app/dcf77.c89
-rw-r--r--app/events.h10
-rw-r--r--app/gps.c316
-rw-r--r--app/gps_neo8.c1204
-rw-r--r--app/led.c76
-rw-r--r--app/lwip_glue.c11
-rw-r--r--app/main.c160
-rw-r--r--app/max7219.c143
-rw-r--r--app/msf.c96
-rw-r--r--app/new_almanac.c53
-rwxr-xr-xapp/parse_alamanc.pl91
-rw-r--r--app/pll.c2
-rw-r--r--app/project.h5
-rw-r--r--app/prototypes.h36
-rw-r--r--app/report.c15
-rw-r--r--app/stdio.c4
-rw-r--r--app/steth.c13
-rw-r--r--app/steth.h16
-rw-r--r--app/ticker.c5
-rw-r--r--app/time_fn.c8
-rw-r--r--app/time_fn.h4
-rw-r--r--app/ubx.h8
-rw-r--r--app/usart.c87
-rw-r--r--oocd/board/stm32f407zet6.cfg5
-rw-r--r--oocd/stm32-f407.cfg6
28 files changed, 2277 insertions, 229 deletions
diff --git a/Makefile.include b/Makefile.include
index 9225b89..5f26c34 100644
--- a/Makefile.include
+++ b/Makefile.include
@@ -32,7 +32,7 @@ OOCD ?= openocd
#OOCD_INTERFACE ?= cmsis-dap
#OOCD_BOARD ?= arch_max
OOCD_INTERFACE ?= stlink-v2
-OOCD_BOARD ?= stm32f407vet6
+OOCD_BOARD ?= stm32f407zet6
################################################################################
# Black Magic Probe specific variables
diff --git a/app/Makefile b/app/Makefile
index 20e34f1..c0bbf4c 100644
--- a/app/Makefile
+++ b/app/Makefile
@@ -25,8 +25,9 @@ PROG=msf
V=1
default: ${PROG}.elf
-CSRCS=led.c ticker.c ring.c usart.c stdio.c lwip_glue.c steth.c msf.c abs.c pll.c main.c time_fn.c ntp.c dcf77.c util.c stats.c gps.c hexdump.c bits.c
-HSRCS=project.h ring.h pins.h gps.h ubx.h
+CSRCS=led.c ticker.c ring.c usart.c stdio.c lwip_glue.c steth.c msf.c abs.c pll.c main.c time_fn.c ntp.c dcf77.c util.c stats.c gps.c hexdump.c bits.c max7219.c report.c
+HSRCS= events.h gps.h project.h ring.h steth.h time_fn.h ubx.h
+
@@ -63,7 +64,7 @@ objs:${OBJS}
${MYOBJS}: project.h prototypes.h
${LWIP_OBJS}: lwip/lwipopts.h
-OBJS=${MYOBJS} ${LWIP_OBJS} almanac.o
+OBJS=${MYOBJS} ${LWIP_OBJS}
include ../Makefile.include
@@ -73,11 +74,26 @@ CPPFLAGS += -I../libopencm3-local -I${LWIP_PATH}/${LWIP}/src/include -Il
fish: ${OBJS}
echo ${OBJS}
+HOST=clock-lnx
+#HOST=10.32.91.140
+
+
+reset:
+ $(Q)$(OOCD) -f ../oocd/interface/$(OOCD_INTERFACE).cfg \
+ -f ../oocd/board/$(OOCD_BOARD).cfg \
+ -c "init" -c "reset run" \
+ -c shutdown
+
+
+fl: ${PROG}.hex
+ ssh ${HOST} flash_stm32 < ${PROG}.hex
+
program: ${PROG}.hex
- echo init | nc -t localhost 4444
- echo reset init | nc -t localhost 4444
- echo flash write_image erase ${PWD}/$< | nc -t localhost 4444
- echo reset run | nc -t localhost 4444
+ scp $< ${HOST}:/tmp/img.hex
+ echo init | nc -t ${HOST} 4444
+ echo reset init | nc -t ${HOST} 4444
+ echo flash write_image erase /tmp/img.hex | nc -t ${HOST} 4444
+ echo reset run | nc -t ${HOST} 4444
ds:
$(Q)$(OOCD) -f ../oocd/interface/$(OOCD_INTERFACE).cfg \
@@ -93,9 +109,12 @@ protos: ${CSRCS}
${CPROTO} -E "${CPP} $(CPPFLAGS)" -e -v ${CSRCS} > prototypes.h.tmp
mv -f prototypes.h.tmp prototypes.h
-almanac.c:almanac.alp
- echo const > $@
- xxd -i $< >> $@
+almanac.txt:
+ wget -O $@ 'https://navcen.uscg.gov/?pageName=currentAlmanac&format=yuma'
+
+almanac.h:alamanc.txt parse_alamanc.pl
+ ./parse_alamanc.pl < almanac.txt > $@ || /bin/rm -f $@
+
almanac.alp: almanac
diff --git a/app/bits.c b/app/bits.c
index 6978c74..3fe7833 100644
--- a/app/bits.c
+++ b/app/bits.c
@@ -17,6 +17,6 @@ void dump_bits (char *wot, uint8_t *bits)
* (ptr++) = '\r';
* (ptr++) = '\n';
*ptr = 0;
- usart1_write (buf, (unsigned) (ptr - buf), 1);
+ usart2_write (buf, (unsigned) (ptr - buf), 1);
}
diff --git a/app/dcf77.c b/app/dcf77.c
index 2a952cd..e55fcfc 100644
--- a/app/dcf77.c
+++ b/app/dcf77.c
@@ -1,37 +1,54 @@
#include "project.h"
-#define P1 (GPIO11)
-#define P1_PORT GPIOD
+#define J2(a,b) a ## b
+#define J3(a,b,c) a ## b ## c
-#define T (GPIO12)
-#define T_PORT GPIOD
+#define P1 (GPIO4)
+#define P1_PORT GPIOE
+
+#define T_BIT 2
+#define T_PORT GPIOE
+#define T_EXTI_LINE T_BIT
+
+
+
+#define M_T(a) J2(GPIO,a)
+#define T M_T(T_BIT)
+#define M_EXTI_T(a) J2(EXTI,a)
+#define EXTI_T M_EXTI_T(T_EXTI_LINE)
+#define M_exti_t_isr(a) J3(exti,a,_isr)
+#define exti_t_isr M_exti_t_isr(T_EXTI_LINE)
+#define M_NVIC_EXTI_T_IRQ(a) J3(NVIC_EXTI,a,_IRQ)
+#define NVIC_EXTI_T_IRQ M_NVIC_EXTI_T_IRQ(T_EXTI_LINE)
static Event_ring dcf77_ring;
+static EPOCH dcf77_time;
static uint64_t dcf77_last_second;
uint64_t dcf77_last_happy;
-void exti15_10_isr (void)
+static char dcf77_info[40];
+
+void exti_t_isr (void)
{
uint32_t now = SCS_DWT_CYCCNT;
int v;
v = !!gpio_get (T_PORT, T);
- nvic_disable_irq (NVIC_EXTI15_10_IRQ);
- exti_reset_request (EXTI12);
+ nvic_disable_irq (NVIC_EXTI_T_IRQ);
+
+ exti_reset_request (EXTI_T);
dcf77_ring.events[dcf77_ring.tx_ptr].when = now;
dcf77_ring.events[dcf77_ring.tx_ptr].value = v;
dcf77_ring.tx_ptr = (dcf77_ring.tx_ptr + 1) & ERING_MASK;
- nvic_enable_irq (NVIC_EXTI15_10_IRQ);
-}
-
-
+ nvic_enable_irq (NVIC_EXTI_T_IRQ);
+}
static uint8_t bits[60];
@@ -39,7 +56,7 @@ static uint8_t bits[60];
static void process_bits (uint64_t abs)
{
UTC u;
- EPOCH dcf77_time;
+ EPOCH e;
if (bits[0]) return;
@@ -63,23 +80,28 @@ static void process_bits (uint64_t abs)
- dcf77_time = time_utc_to_epoch (u);
+ e = time_utc_to_epoch (u);
+
+
+ e.s -= 3600; /*CET*/
- dcf77_time.s -= 2; /*Message arrives 2s early*/
+ if (bits[17]) e.s -= 3600; /*CEST*/
- dcf77_time.s -= 3600; /*CET*/
- if (bits[17]) dcf77_time.s -= 3600; /*CEST*/
+ e.s -= 2; /*Message arrives 2s early*/
+
+ dcf77_time = e;
dcf77_last_happy = make_happy (abs, 60);
- pll_set_offset (dcf77_time, abs);
+ pll_set_offset (e, abs);
+
printf ("DCF77: Next minute is: %02d-%02d-%02d %02d:%02d\r\n", u.year, u.month, u.mday, u.hour, u.minute);
- time_print_epoch ("DCF77: ", dcf77_time);
+ time_print_epoch ("DCF77: ", e, dcf77_info);
dump_bits ("dcf77", bits);
}
@@ -97,14 +119,6 @@ static void report_bit (uint64_t abs, int second, int b)
}
-static void report_time (uint64_t abs)
-{
-#if 1
- EPOCH e = pll_decompose (abs);
- time_print_epoch ("DCF77: ", e);
-#endif
-}
-
void dcf77_dispatch (void)
{
@@ -117,6 +131,7 @@ void dcf77_dispatch (void)
uint32_t now;
int v;
+ led2_set (!!gpio_get (T_PORT, T));
@@ -125,6 +140,9 @@ void dcf77_dispatch (void)
v = dcf77_ring.events[dcf77_ring.rx_ptr].value;
now = dcf77_ring.events[dcf77_ring.rx_ptr].when;
+
+ //led2_set(v);
+
dcf77_ring.rx_ptr = (dcf77_ring.rx_ptr + 1) & ERING_MASK;
if (v) {
@@ -137,6 +155,7 @@ void dcf77_dispatch (void)
last_s = now;
is_s = 1;
second++;
+ dcf77_time.s++;
}
if (pulse_w > 1300) {
@@ -153,6 +172,9 @@ void dcf77_dispatch (void)
else
bit = 0;
+
+ sprintf (dcf77_info, "m=%d s=%02d b=%d", had_m, second, bit);
+
if (had_m)
report_bit (abs, second, bit);
@@ -168,8 +190,7 @@ void dcf77_dispatch (void)
pll_dispatch (dcf77_last_happy, abs, "DCF77");
- if (time_known)
- report_time (abs);
+ report_time ("DCF", dcf77_time, abs, dcf77_info);
}
@@ -183,12 +204,16 @@ dcf77_init (void)
MAP_INPUT (T);
MAP_OUTPUT_PP (P1);
+
+ gpio_set (P1_PORT, P1);
+ delay_ms (50);
gpio_clear (P1_PORT, P1);
- exti_select_source (EXTI12, T_PORT);
- exti_set_trigger (EXTI12, EXTI_TRIGGER_BOTH);
- exti_enable_request (EXTI12);
- nvic_enable_irq (NVIC_EXTI15_10_IRQ);
+ exti_select_source (EXTI_T, T_PORT);
+ exti_set_trigger (EXTI_T, EXTI_TRIGGER_BOTH);
+ exti_enable_request (EXTI_T);
+
+ nvic_enable_irq (NVIC_EXTI_T_IRQ);
}
diff --git a/app/events.h b/app/events.h
index eb0fe89..8468851 100644
--- a/app/events.h
+++ b/app/events.h
@@ -2,13 +2,13 @@
#define ERING_MASK (ERING_SIZE -1)
typedef struct {
- uint32_t when;
- int value;
+ uint32_t when;
+ int value;
} Event;
typedef struct {
- Event events[ERING_SIZE];
- uint32_t rx_ptr,tx_ptr;
+ Event events[ERING_SIZE];
+ uint32_t rx_ptr, tx_ptr;
} Event_ring;
-
+
diff --git a/app/gps.c b/app/gps.c
index 39bb13f..9d5a992 100644
--- a/app/gps.c
+++ b/app/gps.c
@@ -1,12 +1,15 @@
#include "project.h"
-#define PPS (GPIO2)
-#define PPS_PORT GPIOD
+#define PPS (GPIO9)
+#define PPS_PORT GPIOC
#define UBX_BUF_LEN 256
#define TIMEOUT 4000
+
+static EPOCH next_sec;
+
static int ubx_ack = 0;
static int ubx_ack_xfer = 0;
@@ -24,22 +27,24 @@ static const int fish[] = { 1, 2, 3, 4, 5, 6, 7 };
static Event_ring gps_ring;
+static char gps_info[60];
-void exti2_isr (void)
+
+void exti9_5_isr (void)
{
uint32_t now = SCS_DWT_CYCCNT;
int v;
v = !!gpio_get (PPS_PORT, PPS);
- nvic_disable_irq (NVIC_EXTI2_IRQ);
- exti_reset_request (EXTI2);
+ nvic_disable_irq (NVIC_EXTI9_5_IRQ);
+ exti_reset_request (EXTI9);
gps_ring.events[gps_ring.tx_ptr].when = now;
gps_ring.events[gps_ring.tx_ptr].value = v;
gps_ring.tx_ptr = (gps_ring.tx_ptr + 1) & ERING_MASK;
- nvic_enable_irq (NVIC_EXTI2_IRQ);
+ nvic_enable_irq (NVIC_EXTI9_5_IRQ);
}
@@ -48,19 +53,51 @@ void exti2_isr (void)
static inline int
ubx_recv_byte (uint8_t *v)
{
- return !ring_read_byte (&rx3_ring, v);
+ return !ring_read_byte (&rx1_ring, v);
}
static inline void
ubx_send_byte (uint8_t v)
{
- usart3_queue (v);
+ usart1_queue (v);
+}
+
+#define ALMANAC_SIZE
+
+static int ubx_recv_almanac (uint8_t *ptr, unsigned len)
+{
+ uint32_t sv, week;
+ uint32_t almanac[8];
+
+ ptr += ubx_get_u32 (ptr, &sv);
+ len -= 4;
+ ptr += ubx_get_u32 (ptr, &week);
+ len -= 4;
+
+ if (len > sizeof (almanac))
+ len = sizeof (almanac);
+
+ bzero (almanac, sizeof (almanac));
+ memcpy (almanac, ptr, len);
+
+ printf (" Almanac: %2d %d %06x %06x %06x %06x %06x %06x %06x %06x\r\n",
+ (int) sv, (int) week,
+ (unsigned) almanac[0],
+ (unsigned) almanac[1],
+ (unsigned) almanac[2],
+ (unsigned) almanac[3],
+ (unsigned) almanac[4],
+ (unsigned) almanac[5],
+ (unsigned) almanac[6],
+ (unsigned) almanac[7]);
+
+ return 0;
}
static int
ubx_recv_nav_status (uint8_t *ptr, unsigned len)
{
- uint8_t gps_fix, flags;
+ uint8_t gps_fix, flags, fix_stat, flags2;
uint32_t d;
if ((!ptr) || (len != 16))
@@ -69,6 +106,8 @@ ubx_recv_nav_status (uint8_t *ptr, unsigned len)
ptr += ubx_get_u32 (ptr, &d); //TOW
ptr += ubx_get_u8 (ptr, &gps_fix); //fix type
ptr += ubx_get_u8 (ptr, &flags); //fix type
+ ptr += ubx_get_u8 (ptr, &fix_stat);
+ ptr += ubx_get_u8 (ptr, &flags2);
switch (gps_fix) {
@@ -170,7 +209,7 @@ ubx_recv_utc (uint8_t *ptr, unsigned len)
int32_t nano;
uint32_t acc;
uint16_t year;
- uint8_t hour, min, sec, day, month;
+ uint8_t hour, min, sec, day, month, valid;
uint32_t d;
// char buf[40];
@@ -186,15 +225,31 @@ ubx_recv_utc (uint8_t *ptr, unsigned len)
ptr += ubx_get_u8 (ptr, &hour);
ptr += ubx_get_u8 (ptr, &min);
ptr += ubx_get_u8 (ptr, &sec);
+ ptr += ubx_get_u8 (ptr, &valid);
- printf ("GPS META-DATA %04d-%02d-%02d %02d:%02d:%02d Fix:%c%c TXCO %+8dE-12\r\n",
- year,
- month,
- day,
- hour,
- min,
- sec,
+#if 0
+ printf ("GPS META-DATA %04d-%02d-%02d %02d:%02d:%02d V:%02x Fix:%c%c TXCO %+8dE-12\r\n",
+ (int) year,
+ (int) month,
+ (int) day,
+ (int) hour,
+ (int) min,
+ (int) sec,
+ (unsigde) valid,
fix, fix2, (int) freq);
+#endif
+
+ sprintf (gps_info, " %04d-%02d-%02d %02d:%02d:%02d V:%02x Fix:%c%c TXCO %+8dE-12",
+
+ (int)year,
+ (int)month,
+ (int)day,
+ (int)hour,
+ (int)min,
+ (int)sec,
+ (unsigned) valid, fix, fix2, (int) freq);
+
+
if (gps_happy > 3) {
UTC u;
@@ -213,6 +268,7 @@ ubx_recv_utc (uint8_t *ptr, unsigned len)
gps_time = time_utc_to_epoch (u);
+ next_sec = gps_time;
now = SCS_DWT_CYCCNT;
abs = abs_extend (now);
@@ -234,6 +290,60 @@ ubx_recv_utc (uint8_t *ptr, unsigned len)
return 0;
}
+
+
+static int ubx_recv_nav_sbas (uint8_t *ptr, unsigned len)
+{
+ uint8_t prn, mode, service;
+ int8_t sys;
+ uint8_t n;
+
+ ptr += 4;
+
+ ptr += ubx_get_u8 (ptr, &prn);
+ ptr += ubx_get_u8 (ptr, &mode);
+ ptr += ubx_get_i8 (ptr, &sys);
+ ptr += ubx_get_u8 (ptr, &service);
+
+ ptr += ubx_get_u8 (ptr, &n);
+ ptr += 3;
+
+ printf ("GPS SBAS PRN:%d M:%d S:%d SVC:%02x\r\n", prn, mode, sys, service);
+
+ while (n--) {
+ ptr += ubx_get_u8 (ptr, &prn);
+ ptr += 11;
+ printf ("GPS SBAS SV:%d\r\n", prn);
+ }
+
+ return 0;
+}
+
+static int ubx_recv_nav_sat (uint8_t *ptr, unsigned len)
+{
+ uint8_t gnssid, prn, cno, ver;
+ uint8_t n;
+
+ ptr += 4;
+
+ ptr += ubx_get_u8 (ptr, &ver);
+ ptr += ubx_get_u8 (ptr, &n);
+ ptr += 2;
+
+ while (n--) {
+ ptr += ubx_get_u8 (ptr, &gnssid);
+ ptr += ubx_get_u8 (ptr, &prn);
+ ptr += ubx_get_u8 (ptr, &cno);
+ ptr += 9;
+
+ printf ("GPS GNSS:%2d PRN:%3d CNO:%3d\r\n", gnssid, prn, cno);
+ }
+
+
+ return 0;
+}
+
+
static int ubx_recv_rinex (uint8_t *payload, unsigned len)
{
@@ -263,6 +373,14 @@ ubx_recv (uint8_t class, uint8_t id, uint8_t *payload, unsigned len)
ubx_recv_clock_stats (payload, len);
break;
+ case 0x32:
+ ubx_recv_nav_sbas (payload, len);
+ break;
+
+ case 0x35:
+ ubx_recv_nav_sat (payload, len);
+ break;
+
default:
printf ("RX> %02x.%02x (%d bytes)\r\n", class, id, len);
hexdump (payload, len);
@@ -280,6 +398,20 @@ ubx_recv (uint8_t class, uint8_t id, uint8_t *payload, unsigned len)
break;
+ case 4:
+ switch (id) {
+ case 0x4:
+ break;
+
+ default:
+ printf ("RX> %02x.%02x (%d bytes)\r\n", class, id, len);
+ hexdump (payload, len);
+ }
+
+ break;
+
+
+
case 5:
ubx_ack++;
printf (" %s for %02x.%02x\r\n", id ? "ACK" : "NAK", payload[0],
@@ -289,6 +421,10 @@ ubx_recv (uint8_t class, uint8_t id, uint8_t *payload, unsigned len)
case 0x0b:
switch (id) {
+ case 0x30:
+ ubx_recv_almanac (payload, len);
+ break;
+
case 0x50:
printf ("xfer ack\r\n");
ubx_ack_xfer++;
@@ -450,6 +586,9 @@ static void gps_pps_dispatch (void)
v = gps_ring.events[gps_ring.rx_ptr].value;
now = gps_ring.events[gps_ring.rx_ptr].when;
+ if (gps_happy)
+ led3_set (v);
+
gps_ring.rx_ptr = (gps_ring.rx_ptr + 1) & ERING_MASK;
@@ -459,14 +598,16 @@ static void gps_pps_dispatch (void)
- if (gps_happy)
+ if (gps_happy > 30)
pll_dispatch (gps_last_happy, abs, "GPS");
e = pll_decompose (abs);
//u = time_epoch_to_utc (e);
- time_print_epoch ("GPS : ", e);
+ //time_print_epoch ("GPS : ", e, gps_info);
+
+ report_time ("GPS", next_sec, abs, gps_info);
}
@@ -476,6 +617,7 @@ gps_dispatch (void)
{
ubx_dispatch_search (-1, -1, NULL);
gps_pps_dispatch();
+
}
static void
@@ -525,7 +667,7 @@ ubx_handshake (uint8_t class, uint8_t id, const void *payload, unsigned len)
if (ticks > timeout) {
printf ("GPS timeout resending packet\r\n");
- usart3_drain();
+ usart1_drain();
ubx_send (class, id, payload, len);
timeout = ticks + TIMEOUT;
}
@@ -546,7 +688,7 @@ ubx_handshake_xfer (uint8_t class, uint8_t id, const void *payload,
uint32_t timeout;
ubx_ack_xfer = 0;
- // usart3_drain();
+ // usart1_drain();
ubx_send (class, id, payload, len);
@@ -557,7 +699,7 @@ ubx_handshake_xfer (uint8_t class, uint8_t id, const void *payload,
if (ticks > timeout) {
printf ("GPS timeout resending packet\r\n");
- // usart3_drain();
+ // usart1_drain();
ubx_send (class, id, payload, len);
timeout = ticks + TIMEOUT;
}
@@ -580,7 +722,7 @@ ubx_fetch (uint8_t class, uint8_t id, void *payload, unsigned len,
{
uint8_t *ret;
- while (!ring_empty (&tx3_ring) || !ring_empty (&rx3_ring))
+ while (!ring_empty (&tx1_ring) || !ring_empty (&rx1_ring))
gps_dispatch();
ubx_send (class, id, payload, len);
@@ -591,6 +733,19 @@ ubx_fetch (uint8_t class, uint8_t id, void *payload, unsigned len,
return ret;
}
+static int ubx_set_nav_rate (uint16_t ms)
+{
+ uint8_t buf[6], *ptr;
+
+ ptr = buf;
+
+ ptr += ubx_put_u16 (ptr, ms);
+ ptr += ubx_put_u16 (ptr, 1); /*1:1*/
+ ptr += ubx_put_u16 (ptr, 0); /*UTC*/
+
+ return ubx_handshake (0x06, 0x08, buf, (unsigned) (ptr - buf));
+}
+
static int
ubx_set_message_rate_port1 (uint8_t class, uint8_t id, uint8_t rate)
{
@@ -640,7 +795,7 @@ gps_set_ref (int ref_hz)
ptr = buf;
ptr += ubx_put_u8 (ptr, 0); //timepluse 1
- ptr += ubx_put_u8 (ptr, 0); //reserved
+ ptr += ubx_put_u8 (ptr, 0); //version 0
ptr += ubx_put_u16 (ptr, 0); //reserved
// ptr += ubx_put_u16 (ptr, 32); //ant cable delay ns
@@ -650,8 +805,8 @@ gps_set_ref (int ref_hz)
ptr += ubx_put_u32 (ptr, 1000000 / ref_hz); //period locked/us
// ptr += ubx_put_u32 (ptr, 0); //pulse width unlocked/us
- ptr += ubx_put_u32 (ptr, 500000 / ref_hz); //pulse width unlocked/us
- ptr += ubx_put_u32 (ptr, 500000 / ref_hz); //pulse width locked/us
+ ptr += ubx_put_u32 (ptr, 100000 / ref_hz); //pulse width unlocked/us
+ ptr += ubx_put_u32 (ptr, 100000 / ref_hz); //pulse width locked/us
ptr += ubx_put_i32 (ptr, 0); // ? delay
@@ -660,7 +815,7 @@ gps_set_ref (int ref_hz)
ptr += ubx_put_u32 (ptr, 0xf7);
#else
/*Same numbers for locked/unlocked*/
- ptr += ubx_put_u32 (ptr, 0xf3);
+ ptr += ubx_put_u32 (ptr, 0xf7);
#endif
@@ -677,15 +832,16 @@ gps_init (void)
unsigned len;
// uint16_t u2;
- usart3_drain();
+ usart1_drain();
- while (!ring_empty (&tx3_ring) || !ring_empty (&rx3_ring))
+ while (!ring_empty (&tx1_ring) || !ring_empty (&rx1_ring))
gps_dispatch();
printf ("Testing GNSS...\r\n");
ubx_handshake (0x06, 0x00, NULL, 0);
printf ("GNSS there\r\n");
+
// Set up port
ptr = buf;
ptr += ubx_put_u8 (ptr, 1); //uart1
@@ -693,7 +849,7 @@ gps_init (void)
ptr += ubx_put_u16 (ptr, 0x0); //flow control off
ptr += ubx_put_u32 (ptr, 0x8c0); //no parity, 8 bits
ptr += ubx_put_u32 (ptr, 9600); // baudrate
- ptr += ubx_put_u16 (ptr, 0x7); // receive RTCM, NMEA, UBX
+ ptr += ubx_put_u16 (ptr, 0x3); // receive NMEA, UBX
ptr += ubx_put_u16 (ptr, 0x1); // transmit UBX
ptr += ubx_put_u16 (ptr, 0x0); // no txtimeout
ptr += ubx_put_u16 (ptr, 0x0); // reserved
@@ -701,7 +857,7 @@ gps_init (void)
printf ("configured GNSS protocol\r\n");
-#if 1
+#if 0
ptr = buf;
ptr += ubx_put_u16 (ptr, 0x14);
ptr += ubx_put_u16 (ptr, 0x00);
@@ -749,17 +905,30 @@ gps_init (void)
printf ("configured GNSS data\r\n");
+ gps_set_ref (1);
+
ubx_fetch (0x06, 0x31, NULL, 0, &len);
printf ("configured GNSS 6.31\r\n");
+
+ ubx_set_nav_rate (1000);
+
#if 1
ubx_set_message_rate_port1 (0x01, 0x03, 1);
+ ubx_set_message_rate_port1 (0x01, 0x06, 0);
ubx_set_message_rate_port1 (0x01, 0x21, 1);
ubx_set_message_rate_port1 (0x01, 0x22, 1);
ubx_set_message_rate_port1 (0x01, 0x32, 0);
+
+ ubx_set_message_rate_port1 (0x01, 0x32, 0); /*SBAS*/
+ ubx_set_message_rate_port1 (0x01, 0x35, 0); /*SV in view*/
+
ubx_set_message_rate_port1 (0x03, 0x0a, 0);
- //ubx_set_message_rate_port1 (0x03, 0x10, 0);
+ ubx_set_message_rate_port1 (0x03, 0x10, 0);
+ ubx_set_message_rate_port1 (0x03, 0x21, 0);
+ ubx_set_message_rate_port1 (0x04, 0x04, 0);
+
printf ("GNSS ready\r\n");
#else
ubx_set_message_rate_port1 (0x01, 0x03, 0);
@@ -771,7 +940,7 @@ gps_init (void)
printf ("GNSS ready\r\n");
#endif
-#if 1
+#if 0
ptr = buf;
ptr += ubx_put_u8 (ptr, 0x1);
ptr += ubx_put_u8 (ptr, 0x7);
@@ -791,16 +960,16 @@ gps_init (void)
MAP_INPUT (PPS);
- exti_select_source (EXTI2, PPS_PORT);
- exti_set_trigger (EXTI2, EXTI_TRIGGER_BOTH);
- exti_enable_request (EXTI2);
- nvic_enable_irq (NVIC_EXTI2_IRQ);
+ exti_select_source (EXTI9, PPS_PORT);
+ exti_set_trigger (EXTI9, EXTI_TRIGGER_BOTH);
+ exti_enable_request (EXTI9);
+ nvic_enable_irq (NVIC_EXTI9_5_IRQ);
return 0;
}
-#define ALMANAC_LUMP 128
+#define ALMANAC_LUMP 64
int
gps_almanac (void)
@@ -831,6 +1000,75 @@ gps_almanac (void)
return 0;
}
+void gps_dump_almanac (void)
+{
+ ubx_send (0xb, 0x30, NULL, 0);
+}
+
+
+#if 1
+int gps_bs (void)
+{
+ uint32_t now = SCS_DWT_CYCCNT;
+ uint64_t abs = abs_extend (now);
+ EPOCH e = pll_decompose (abs);
+ UTC u = time_epoch_to_utc (e);
+
+ uint8_t buf[80], *ptr;
+ int ret;
+
+ ptr = buf;
+
+ ptr += ubx_put_u32 (ptr, 391706007); /*19 sleaford st*/
+ ptr += ubx_put_u32 (ptr, 955140);
+ ptr += ubx_put_u32 (ptr, 501672842);
+ ptr += ubx_put_u32 (ptr, 100000); /*1km std dev*/
+
+ ptr += ubx_put_u16 (ptr, 0); /*no time mark*/
+
+ ptr += ubx_put_u16 (ptr, (u.year - 2000) * 100 + u.month);
+ ptr += ubx_put_u32 (ptr, (u.mday * 1000000) + (u.hour * 10000) + (u.minute * 100) + u.second);
+ ptr += ubx_put_u32 (ptr, u.nanosecond);
+
+ ptr += ubx_put_u32 (ptr, 2000); /* time good to 2s */
+ ptr += ubx_put_u32 (ptr, 0);
+
+ ptr += ubx_put_u32 (ptr, 0);
+ ptr += ubx_put_u32 (ptr, 0);
+
+ ptr += ubx_put_u32 (ptr, 0x403);
+
+ printf ("Bootstrapping GPS\r\n");
+
+ hexdump (buf, (unsigned) (ptr - buf));
+
+ ubx_send (0x0b, 0x01, buf, (unsigned) (ptr - buf));
+
+
+ ret = 0;
+
+
+ /*
+ 00000: 97 f5 58 17
+ 04 93 0e 00
+ 8a eb e6 1d
+ a0 86 01 00
+ 00010: 00 00
+ 6f 07 19/03
+ 03 cb 06 01 /17 22:24:03
+ 65 ca af 02 45075045ns
+
+ d0 07 00 00 2000ms
+ 00020: 00 00 00 00 0ns
+ 00 00 00 00
+ 00 00 00 00
+ 03 04 00 00
+ */
+
+ return ret;
+}
+
+#endif
void
@@ -846,7 +1084,7 @@ gps_reset (void)
ubx_cfg_rst (REPHEMERIDIES | RALMANAC | RPOS | RRTC);
delay_ms (1000);
- usart3_drain();
+ usart1_drain();
printf ("Testing GNSS...\r\n");
diff --git a/app/gps_neo8.c b/app/gps_neo8.c
new file mode 100644
index 0000000..ea5d984
--- /dev/null
+++ b/app/gps_neo8.c
@@ -0,0 +1,1204 @@
+#include "project.h"
+
+#define PPS (GPIO9)
+#define PPS_PORT GPIOC
+
+#define UBX_BUF_LEN 256
+
+#define TIMEOUT 4000
+
+static int ubx_ack = 0;
+static int ubx_ack_xfer = 0;
+
+static int current_ref_hz = 1;
+
+static int gps_locked;
+static int gps_happy;
+
+uint64_t gps_last_happy;
+
+static char fix, fix2;
+static int32_t freq = 0;
+
+static const int fish[] = { 1, 2, 3, 4, 5, 6, 7 };
+
+static Event_ring gps_ring;
+
+static char gps_info[60];
+
+
+void exti9_5_isr (void)
+{
+ uint32_t now = SCS_DWT_CYCCNT;
+ int v;
+
+ v = !!gpio_get (PPS_PORT, PPS);
+
+ nvic_disable_irq (NVIC_EXTI9_5_IRQ);
+ exti_reset_request (EXTI9);
+
+ gps_ring.events[gps_ring.tx_ptr].when = now;
+ gps_ring.events[gps_ring.tx_ptr].value = v;
+ gps_ring.tx_ptr = (gps_ring.tx_ptr + 1) & ERING_MASK;
+
+ nvic_enable_irq (NVIC_EXTI9_5_IRQ);
+
+}
+
+
+
+static inline int
+ubx_recv_byte (uint8_t *v)
+{
+ return !ring_read_byte (&rx1_ring, v);
+}
+
+static inline void
+ubx_send_byte (uint8_t v)
+{
+ usart1_queue (v);
+}
+
+#define ALMANAC_SIZE
+
+static int ubx_recv_almanac(uint8_t *ptr,unsigned len)
+{
+uint32_t sv,week;
+uint32_t almanac[8];
+
+ptr+=ubx_get_u32(ptr,&sv);
+len-=4;
+ptr+=ubx_get_u32(ptr,&week);
+len-=4;
+
+if (len>sizeof(almanac))
+ len=sizeof(almanac);
+
+bzero(almanac,sizeof(almanac));
+memcpy(almanac,ptr,len);
+
+printf(" Almanac: %2d %d %06x %06x %06x %06x %06x %06x %06x %06x\r\n",
+ (int) sv,(int) week,
+ (unsigned) almanac[0],
+ (unsigned) almanac[1],
+ (unsigned) almanac[2],
+ (unsigned) almanac[3],
+ (unsigned) almanac[4],
+ (unsigned) almanac[5],
+ (unsigned) almanac[6],
+ (unsigned) almanac[7]);
+
+return 0;
+}
+
+static int
+ubx_recv_nav_status (uint8_t *ptr, unsigned len)
+{
+ uint8_t gps_fix, flags,fix_stat,flags2;
+ uint32_t d;
+
+ if ((!ptr) || (len != 16))
+ return -1;
+
+ ptr += ubx_get_u32 (ptr, &d); //TOW
+ ptr += ubx_get_u8 (ptr, &gps_fix); //fix type
+ ptr += ubx_get_u8 (ptr, &flags); //fix type
+ ptr += ubx_get_u8 (ptr, &fix_stat);
+ ptr += ubx_get_u8 (ptr, &flags2);
+
+
+ switch (gps_fix) {
+ case 0:
+ case 1:
+ fix = '-';
+ gps_locked = 0;
+ break;
+
+ case 2:
+ fix = '2';
+ gps_locked = 0;
+ break;
+
+ case 3:
+ fix = 'L';
+ gps_locked = 1;
+ break;
+
+ case 4:
+ fix = 'R';
+ gps_locked = 0;
+ break;
+
+ case 5:
+ fix = 'T';
+ gps_locked = 0;
+ break;
+
+ default:
+ fix = '?';
+ gps_locked = 0;
+ }
+
+ switch (flags & 3) {
+ case 0:
+ case 2:
+ fix2 = '!';
+ break;
+
+ case 1:
+ fix2 = '-';
+ break;
+
+ case 3:
+ fix2 = 'D';
+
+ if (gps_locked == 1)
+ gps_locked = 2;
+
+ break;
+
+ default:
+ fix2 = '?';
+ }
+
+
+ // printf ("fix: %c%c\r\n",fix,fix2);
+
+
+ if ((gps_locked) && (gps_happy < 10000))
+ gps_happy++;
+ else
+ gps_happy = 0;
+
+ return 0;
+}
+
+
+static int
+ubx_recv_clock_stats (uint8_t *ptr, unsigned len)
+{
+ //char buf[40];
+ int32_t drift;
+ uint32_t d;
+
+ if ((!ptr) || (len != 20))
+ return -1;
+
+ ptr += ubx_get_u32 (ptr, &d); //TOW
+ ptr += ubx_get_u32 (ptr, &d); //bias
+ ptr += ubx_get_i32 (ptr, &drift); //drift
+ ptr += ubx_get_u32 (ptr, &d); //time acc estimate
+ ptr += ubx_get_i32 (ptr, &freq); //freq acc estimate
+
+ // printf ("TCXO %+8dE-12\r\n", (int) freq);
+#if 0
+ sprintf (buf, "TCXO %+8dE-12", (int) freq);
+ lcd_erase_line (18, 0);
+ lcd_write (buf, 0, 0);
+#endif
+ return 0;
+
+}
+
+static int
+ubx_recv_utc (uint8_t *ptr, unsigned len)
+{
+ int32_t nano;
+ uint32_t acc;
+ uint16_t year;
+ uint8_t hour, min, sec, day, month,valid;
+ uint32_t d;
+ // char buf[40];
+
+ if ((!ptr) || (len != 20))
+ return -1;
+
+ ptr += ubx_get_u32 (ptr, &d); //TOW
+ ptr += ubx_get_u32 (ptr, &acc); //bias
+ ptr += ubx_get_i32 (ptr, &nano);
+ ptr += ubx_get_u16 (ptr, &year);
+ ptr += ubx_get_u8 (ptr, &month);
+ ptr += ubx_get_u8 (ptr, &day);
+ ptr += ubx_get_u8 (ptr, &hour);
+ ptr += ubx_get_u8 (ptr, &min);
+ ptr += ubx_get_u8 (ptr, &sec);
+ ptr += ubx_get_u8 (ptr, &valid);
+
+#if 0
+ printf ("GPS META-DATA %04d-%02d-%02d %02d:%02d:%02d V:%02x Fix:%c%c TXCO %+8dE-12\r\n",
+ (int) year,
+ (int) month,
+ (int) day,
+ (int) hour,
+ (int) min,
+ (int) sec,
+ (unsigde) valid,
+ fix, fix2, (int) freq);
+#endif
+
+ sprintf(gps_info, " %04d-%02d-%02d %02d:%02d:%02d V:%02x Fix:%c%c TXCO %+8dE-12",
+
+ (int )year,
+ (int )month,
+ (int )day,
+ (int )hour,
+ (int )min,
+ (int )sec,
+(unsigned) valid, fix, fix2, (int) freq);
+
+
+
+ if (gps_happy > 3) {
+ UTC u;
+ EPOCH gps_time;
+ uint32_t now;
+ uint64_t abs;
+
+ u.jday = 0;
+ u.year = year;
+ u.month = month;
+ u.mday = day;
+ u.hour = hour;
+ u.minute = min;
+ u.second = sec;
+ u.nanosecond = 0;
+
+ gps_time = time_utc_to_epoch (u);
+
+
+ now = SCS_DWT_CYCCNT;
+ abs = abs_extend (now);
+
+ gps_last_happy = make_happy (abs, 180);
+
+ pll_set_offset (gps_time, abs);
+
+ }
+
+
+#if 0
+ sprintf (buf, "%+6dE-12 %02d%02d%02d", (int) freq,
+ (int) hour, (int)min, (int) sec);
+ lcd_erase_line (18, 0);
+ lcd_write (buf, 0, 0);
+#endif
+
+ return 0;
+}
+
+
+
+static int ubx_recv_nav_sbas(uint8_t *ptr,unsigned len)
+{
+uint8_t prn,mode,service;
+int8_t sys;
+uint8_t n;
+
+ ptr+=4;
+
+ ptr += ubx_get_u8 (ptr, &prn);
+ ptr += ubx_get_u8 (ptr, &mode);
+ ptr += ubx_get_i8 (ptr, &sys);
+ ptr += ubx_get_u8 (ptr, &service);
+
+ ptr += ubx_get_u8 (ptr, &n);
+ ptr+=3;
+
+ printf("GPS SBAS PRN:%d M:%d S:%d SVC:%02x\r\n",prn,mode,sys,service);
+
+ while (n--) {
+ ptr += ubx_get_u8 (ptr, &prn);
+ ptr+=11;
+ printf("GPS SBAS SV:%d\r\n",prn);
+ }
+
+return 0;
+}
+
+static int ubx_recv_nav_sat(uint8_t *ptr,unsigned len)
+{
+uint8_t gnssid,prn,cno,ver;
+uint8_t n;
+
+ ptr+=4;
+
+ ptr += ubx_get_u8 (ptr, &ver);
+ ptr += ubx_get_u8 (ptr, &n);
+ ptr+=2;
+
+ while (n--) {
+ ptr += ubx_get_u8 (ptr, &gnssid);
+ ptr += ubx_get_u8 (ptr, &prn);
+ ptr += ubx_get_u8 (ptr, &cno);
+ ptr+=9;
+
+ printf("GPS GNSS:%2d PRN:%3d CNO:%3d\r\n",gnssid,prn,cno);
+ }
+
+
+return 0;
+}
+
+
+static int ubx_recv_rinex (uint8_t *payload, unsigned len)
+{
+
+ printf ("Rinex\r\n");
+ return 0;
+}
+
+
+
+static void
+ubx_recv (uint8_t class, uint8_t id, uint8_t *payload, unsigned len)
+{
+ // printf ("RX> %02x.%02x (%d bytes)\r\n", class, id, len);
+
+ switch (class) {
+ case 1:
+ switch (id) {
+ case 0x3:
+ ubx_recv_nav_status (payload, len);
+ break;
+
+ case 0x21:
+ ubx_recv_utc (payload, len);
+ break;
+
+ case 0x22:
+ ubx_recv_clock_stats (payload, len);
+ break;
+
+ case 0x32:
+ ubx_recv_nav_sbas(payload,len);
+ break;
+
+ case 0x35:
+ ubx_recv_nav_sat(payload,len);
+ break;
+
+ default:
+ printf ("RX> %02x.%02x (%d bytes)\r\n", class, id, len);
+ hexdump (payload, len);
+ }
+
+ break;
+
+ case 2:
+ switch (id) {
+ case 0x10:
+ ubx_recv_rinex (payload, len);
+
+ break;
+ }
+
+ break;
+
+ case 4:
+ switch (id) {
+ case 0x4:
+ break;
+ default:
+ printf ("RX> %02x.%02x (%d bytes)\r\n", class, id, len);
+ hexdump (payload, len);
+ }
+
+ break;
+
+
+
+ case 5:
+ ubx_ack++;
+ printf (" %s for %02x.%02x\r\n", id ? "ACK" : "NAK", payload[0],
+ payload[1]);
+
+ break;
+
+ case 0x0b:
+ switch (id) {
+ case 0x30:
+ ubx_recv_almanac(payload,len);
+ break;
+ case 0x50:
+ printf ("xfer ack\r\n");
+ ubx_ack_xfer++;
+ break;
+
+ default:
+ printf ("RX> %02x.%02x (%d bytes)\r\n", class, id, len);
+ hexdump (payload, len);
+ }
+
+ break;
+
+ default:
+ printf ("RX> %02x.%02x (%d bytes)\r\n", class, id, len);
+
+ if (class != 0x03)
+ hexdump (payload, len);
+ }
+
+
+}
+
+
+typedef enum {
+ UBX_SM_LOST = 0,
+ UBX_SM_S2,
+ UBX_SM_C,
+ UBX_SM_I,
+ UBX_SM_L1,
+ UBX_SM_L2,
+ UBX_SM_DATA,
+ UBX_SM_CKA,
+ UBX_SM_CKB
+} ubx_sm_t;
+
+
+
+
+static uint8_t *
+ubx_dispatch_search (int s_class, int s_id, unsigned *len_ptr)
+{
+ static uint8_t buf[UBX_BUF_LEN];
+ static ubx_sm_t sm = UBX_SM_LOST;
+ static uint8_t class, id;
+ static unsigned ptr;
+ static unsigned len;
+ static uint8_t ck_a, ck_b;
+
+
+ void ubx_ck (uint8_t v) {
+ ck_a += v;
+ ck_b = ck_b + ck_a;
+ }
+
+
+ uint8_t c;
+
+ while (ubx_recv_byte (&c)) {
+
+ switch (sm) {
+ case UBX_SM_LOST:
+ if (c == 0xb5)
+ sm = UBX_SM_S2;
+
+ break;
+
+ case UBX_SM_S2:
+ if (c == 0x62)
+ sm = UBX_SM_C;
+ else
+ sm = UBX_SM_LOST;
+
+ break;
+
+ case UBX_SM_C:
+ ck_a = ck_b = class = c;
+ sm = UBX_SM_I;
+ break;
+
+ case UBX_SM_I:
+ ubx_ck (c);
+ id = c;
+ sm = UBX_SM_L1;
+ break;
+
+ case UBX_SM_L1:
+ ubx_ck (c);
+ len = c;
+ sm = UBX_SM_L2;
+ break;
+
+ case UBX_SM_L2:
+ ubx_ck (c);
+ len |= c << 8;
+
+ ptr = 0;
+
+ if (len)
+ sm = UBX_SM_DATA;
+ else
+ sm = UBX_SM_CKA;
+
+ break;
+
+ case UBX_SM_DATA:
+ ubx_ck (c);
+
+ if (ptr < UBX_BUF_LEN)
+ buf[ptr] = c;
+
+ ptr++;
+
+ if (ptr == len)
+ sm = UBX_SM_CKA;
+
+ break;
+
+ case UBX_SM_CKA:
+ if (c == ck_a)
+ sm = UBX_SM_CKB;
+ else
+ sm = UBX_SM_LOST;
+
+ break;
+
+ case UBX_SM_CKB:
+ sm = UBX_SM_LOST;
+
+ if (c != ck_b)
+ break;
+
+ ubx_recv (class, id, buf, len);
+
+ if ((class == s_class) && (id == s_id)) {
+ if (len_ptr)
+ *len_ptr = len;
+
+ return buf;
+ }
+
+ break;
+ }
+
+ }
+
+ return NULL;
+}
+static void gps_pps_dispatch (void)
+{
+ //char buf[80];
+ uint32_t now;
+ uint64_t abs;
+ int v;
+ EPOCH e;
+ //UTC u;
+
+ if (gps_ring.rx_ptr == gps_ring.tx_ptr) return;
+
+ v = gps_ring.events[gps_ring.rx_ptr].value;
+ now = gps_ring.events[gps_ring.rx_ptr].when;
+
+ led3_set(v);
+
+ gps_ring.rx_ptr = (gps_ring.rx_ptr + 1) & ERING_MASK;
+
+
+ if (!v) return;
+
+ abs = abs_extend (now);
+
+ if (gps_happy)
+ pll_dispatch (gps_last_happy, abs, "GPS");
+
+ e = pll_decompose (abs);
+
+
+ //u = time_epoch_to_utc (e);
+ time_print_epoch ("GPS : ", e, gps_info);
+
+}
+
+
+void
+gps_dispatch (void)
+{
+ ubx_dispatch_search (-1, -1, NULL);
+ gps_pps_dispatch();
+
+}
+
+static void
+ubx_send (uint8_t class, uint8_t id, const void *_payload, unsigned len)
+{
+ uint8_t ck_a = 0, ck_b = 0;
+ uint8_t *payload = (uint8_t *) _payload;
+
+ void ubx_send_byte_ck (uint8_t v) {
+ ubx_send_byte (v);
+ ck_a += v;
+ ck_b = ck_b + ck_a;
+ }
+
+
+ ubx_send_byte (0xb5);
+ ubx_send_byte (0x62);
+
+ ubx_send_byte_ck (class);
+ ubx_send_byte_ck (id);
+ ubx_send_byte_ck (len & 0xff);
+ ubx_send_byte_ck (len >> 8);
+
+ while (len--)
+ ubx_send_byte_ck (* (payload++));
+
+ ubx_send_byte (ck_a);
+ ubx_send_byte (ck_b);
+
+ // printf ("TX> %02x.%02x\r\n", class, id);
+
+}
+
+static int
+ubx_handshake (uint8_t class, uint8_t id, const void *payload, unsigned len)
+{
+ uint32_t timeout;
+
+ ubx_ack = 0;
+ ubx_send (class, id, payload, len);
+
+
+
+ timeout = ticks + TIMEOUT;
+
+ while (!ubx_ack) {
+
+ if (ticks > timeout) {
+ printf ("GPS timeout resending packet\r\n");
+ usart1_drain();
+ ubx_send (class, id, payload, len);
+ timeout = ticks + TIMEOUT;
+ }
+
+
+
+
+ gps_dispatch();
+ }
+
+ return 0;
+}
+
+static int
+ubx_handshake_xfer (uint8_t class, uint8_t id, const void *payload,
+ unsigned len)
+{
+ uint32_t timeout;
+
+ ubx_ack_xfer = 0;
+ // usart1_drain();
+ ubx_send (class, id, payload, len);
+
+
+
+ timeout = ticks + TIMEOUT;
+
+ while (!ubx_ack_xfer) {
+
+ if (ticks > timeout) {
+ printf ("GPS timeout resending packet\r\n");
+ // usart1_drain();
+ ubx_send (class, id, payload, len);
+ timeout = ticks + TIMEOUT;
+ }
+
+
+
+
+ gps_dispatch();
+ }
+
+ return 0;
+}
+
+
+
+
+static uint8_t *
+ubx_fetch (uint8_t class, uint8_t id, void *payload, unsigned len,
+ unsigned *len_ptr)
+{
+ uint8_t *ret;
+
+ while (!ring_empty (&tx1_ring) || !ring_empty (&rx1_ring))
+ gps_dispatch();
+
+ ubx_send (class, id, payload, len);
+
+ while (! (ret = ubx_dispatch_search (class, id, len_ptr)));
+
+
+ return ret;
+}
+
+static int ubx_set_nav_rate (uint16_t ms)
+{
+ uint8_t buf[6], *ptr;
+
+ ptr = buf;
+
+ ptr += ubx_put_u16 (ptr, ms);
+ ptr += ubx_put_u16 (ptr, 1); /*1:1*/
+ ptr += ubx_put_u16 (ptr, 0); /*UTC*/
+
+ return ubx_handshake (0x06, 0x08, buf, (unsigned) (ptr - buf));
+}
+
+static int
+ubx_set_message_rate_port1 (uint8_t class, uint8_t id, uint8_t rate)
+{
+ uint8_t buf[8], *ptr;
+
+ ptr = buf;
+
+ ptr += ubx_put_u8 (ptr, class);
+ ptr += ubx_put_u8 (ptr, id); //reserved
+ ptr += ubx_put_u8 (ptr, 0); //nothing on port i2c
+ ptr += ubx_put_u8 (ptr, rate); //rate on uart
+ ptr += ubx_put_u8 (ptr, 0); //nothing on port 2
+ ptr += ubx_put_u8 (ptr, 0); //nothing on usb
+ ptr += ubx_put_u8 (ptr, 0); //nothing on spi
+ ptr += ubx_put_u8 (ptr, 0); //nothing on port 5
+
+ return ubx_handshake (0x06, 0x01, buf, (unsigned) (ptr - buf));
+}
+
+
+static int
+ubx_cfg_rst (uint16_t flags)
+{
+ uint8_t buf[8], *ptr;
+
+ ptr = buf;
+
+ ptr += ubx_put_u16 (ptr, flags); //Flags
+ ptr += ubx_put_u8 (ptr, 0x4); //Hardware reset after shutdown
+ ptr += ubx_put_u8 (ptr, 0); //reserved
+
+ ubx_send (0x06, 0x04, buf, (unsigned) (ptr - buf));
+ return 0;
+}
+
+
+static int
+gps_set_ref (int ref_hz)
+{
+ uint8_t buf[80], *ptr;
+ int ret;
+
+ printf ("setting gps ref to %d hz\r\n", ref_hz);
+
+ current_ref_hz = ref_hz;
+
+ ptr = buf;
+
+ ptr += ubx_put_u8 (ptr, 0); //timepluse 1
+ ptr += ubx_put_u8 (ptr, 0); //version 0
+ ptr += ubx_put_u16 (ptr, 0); //reserved
+
+ // ptr += ubx_put_u16 (ptr, 32); //ant cable delay ns
+ ptr += ubx_put_u16 (ptr, 0); //ant cable delay ns
+ ptr += ubx_put_u16 (ptr, 0); //rf group delay ns
+ ptr += ubx_put_u32 (ptr, 1000000 / ref_hz); //period unlocked/us
+ ptr += ubx_put_u32 (ptr, 1000000 / ref_hz); //period locked/us
+
+ // ptr += ubx_put_u32 (ptr, 0); //pulse width unlocked/us
+ ptr += ubx_put_u32 (ptr, 100000 / ref_hz); //pulse width unlocked/us
+ ptr += ubx_put_u32 (ptr, 100000 / ref_hz); //pulse width locked/us
+
+ ptr += ubx_put_i32 (ptr, 0); // ? delay
+
+#if 0
+ /*Separate numbers for locked/unlocked*/
+ ptr += ubx_put_u32 (ptr, 0xf7);
+#else
+ /*Same numbers for locked/unlocked*/
+ ptr += ubx_put_u32 (ptr, 0xf7);
+#endif
+
+
+ ret = ubx_handshake (0x06, 0x31, buf, (unsigned) (ptr - buf));
+
+ return ret;
+}
+
+
+static inline int
+ubx_put_gnss_cfg (uint8_t *buf, uint8_t gnss_id,uint8_t r_chan,uint8_t m_chan,
+uint16_t enable, uint16_t sig_mask)
+{
+ uint8_t *ptr=buf;
+
+ ptr += ubx_put_u8(ptr,gnss_id);
+ ptr += ubx_put_u8(ptr,r_chan);
+ ptr += ubx_put_u8(ptr,m_chan);
+ ptr += ubx_put_u8(ptr,0);
+ ptr += ubx_put_u16(ptr,enable);
+ ptr += ubx_put_u16(ptr,sig_mask);
+
+ return (unsigned) (ptr - buf);
+}
+
+void gps_set_gnss(void)
+{
+ uint8_t buf[80], *ptr;
+
+ ptr = buf;
+ ptr += ubx_put_u8 (ptr, 0x0); /* Ver 0 */
+ ptr += ubx_put_u8 (ptr, 0x20);
+ ptr += ubx_put_u8 (ptr, 0x20);
+ ptr += ubx_put_u8 (ptr, 0x7);
+
+ ptr += ubx_put_gnss_cfg(ptr,0,8,16,1,0x101);
+ ptr += ubx_put_gnss_cfg(ptr,1,1,3,1,0x101);
+ ptr += ubx_put_gnss_cfg(ptr,2,4,8,0,0x101);
+ ptr += ubx_put_gnss_cfg(ptr,3,8,16,0,0x101);
+ ptr += ubx_put_gnss_cfg(ptr,4,0,7,0,0x301);
+ ptr += ubx_put_gnss_cfg(ptr,5,0,3,1,0x501);
+ ptr += ubx_put_gnss_cfg(ptr,6,8,14,1,0x101);
+
+ ubx_handshake (0x06, 0x3e, buf, (unsigned) (ptr - buf));
+
+ printf ("configured SBAS\r\n");
+
+ ubx_handshake (0x06, 0x3e, buf, 0);
+}
+
+
+int
+gps_init (void)
+{
+ uint8_t buf[80], *ptr;
+ unsigned len;
+ // uint16_t u2;
+
+ usart1_drain();
+
+ while (!ring_empty (&tx1_ring) || !ring_empty (&rx1_ring))
+ gps_dispatch();
+
+
+ printf ("Testing GNSS...\r\n");
+ ubx_handshake (0x06, 0x00, NULL, 0);
+ printf ("GNSS there\r\n");
+
+ //reset GNSS
+
+#if 0
+ ptr=buf;
+ ptr += ubx_put_u32 (ptr, 0xe1f ); //uart1
+ ptr += ubx_put_u32 (ptr, 0 ); //uart1
+ ptr += ubx_put_u32 (ptr, 0 ); //uart1
+ ubx_handshake (0x06, 0x09, buf, (unsigned) (ptr - buf));
+
+ printf ("reset\r\n");
+#endif
+
+
+ // Set up port
+ ptr = buf;
+ ptr += ubx_put_u8 (ptr, 1); //uart1
+ ptr += ubx_put_u8 (ptr, 0); //reserved
+ ptr += ubx_put_u16 (ptr, 0x0); //flow control off
+ ptr += ubx_put_u32 (ptr, 0x8c0); //no parity, 8 bits
+ ptr += ubx_put_u32 (ptr, 9600); // baudrate
+ ptr += ubx_put_u16 (ptr, 0x7); // receive RTCM, NMEA, UBX
+ ptr += ubx_put_u16 (ptr, 0x1); // transmit UBX
+ ptr += ubx_put_u16 (ptr, 0x0); // no txtimeout
+ ptr += ubx_put_u16 (ptr, 0x0); // reserved
+ ubx_handshake (0x06, 0x00, buf, (unsigned) (ptr - buf));
+
+ printf ("configured GNSS protocol\r\n");
+
+
+#if 0
+ ptr = buf;
+ ptr += ubx_put_u16 (ptr, 0x1b);
+ ptr += ubx_put_u16 (ptr, 0x00);
+ ubx_handshake (0x06, 0x13, buf, (unsigned) (ptr - buf));
+
+ printf ("configured antenna pins\r\n");
+#endif
+
+
+
+#if 0
+ // Check we're in WGS84
+ ptr = ubx_fetch (0x06, 0x06, NULL, 0, &len);
+ ptr += ubx_get_u16 (ptr, &u2);
+
+ if (u2)
+ return -1;
+
+ printf ("configured GNSS datum\r\n");
+#endif
+
+ ptr = buf;
+
+ ptr += ubx_put_u8 (ptr, 0); //UBX
+ ptr += ubx_put_u8 (ptr, 0); //reserved
+ ptr += ubx_put_u16 (ptr, 0); //reserved
+ ptr += ubx_put_u8 (ptr, 0); //nothing on port i2c
+ ptr += ubx_put_u8 (ptr, 0x18); //everything on uart
+ ptr += ubx_put_u8 (ptr, 0); //nothing on port 2
+ ptr += ubx_put_u8 (ptr, 0); //nothing on usb
+ ptr += ubx_put_u8 (ptr, 0); //nothing on spi
+ ptr += ubx_put_u8 (ptr, 0); //nothing on port 5
+
+ ptr += ubx_put_u8 (ptr, 1); //NMEA
+ ptr += ubx_put_u8 (ptr, 0); //reserved
+ ptr += ubx_put_u16 (ptr, 0); //reserved
+ ptr += ubx_put_u8 (ptr, 0); //nothing on port i2c
+ ptr += ubx_put_u8 (ptr, 0); //nothing on uart
+ ptr += ubx_put_u8 (ptr, 0); //nothing on port 2
+ ptr += ubx_put_u8 (ptr, 0); //nothing on usb
+ ptr += ubx_put_u8 (ptr, 0); //nothing on spi
+ ptr += ubx_put_u8 (ptr, 0); //nothing on port 5
+
+ ubx_handshake (0x06, 0x02, buf, (unsigned) (ptr - buf));
+
+ printf ("configured GNSS data\r\n");
+
+ gps_set_ref (1);
+
+ ubx_fetch (0x06, 0x31, NULL, 0, &len);
+
+ printf ("configured GNSS 6.31\r\n");
+
+
+ ubx_set_nav_rate(1000);
+
+#if 1
+ ubx_set_message_rate_port1 (0x01, 0x03, 1);
+ ubx_set_message_rate_port1 (0x01, 0x21, 1);
+ ubx_set_message_rate_port1 (0x01, 0x22, 1);
+ ubx_set_message_rate_port1 (0x01, 0x32, 0);
+
+ ubx_set_message_rate_port1 (0x01, 0x32, 0); /*SBAS*/
+ ubx_set_message_rate_port1 (0x01, 0x35, 0); /*SV in view*/
+
+ ubx_set_message_rate_port1 (0x03, 0x0a, 0);
+ ubx_set_message_rate_port1 (0x03, 0x10, 0);
+ ubx_set_message_rate_port1 (0x03, 0x21, 0);
+ ubx_set_message_rate_port1 (0x04, 0x04, 0);
+
+ printf ("GNSS ready\r\n");
+#else
+ ubx_set_message_rate_port1 (0x01, 0x03, 0);
+ ubx_set_message_rate_port1 (0x01, 0x21, 0);
+ ubx_set_message_rate_port1 (0x01, 0x22, 0);
+ ubx_set_message_rate_port1 (0x01, 0x32, 0);
+ ubx_set_message_rate_port1 (0x03, 0x0a, 0);
+ //ubx_set_message_rate_port1 (0x03, 0x10, 0);
+ printf ("GNSS ready\r\n");
+#endif
+
+
+
+ // printf ("GPS ready\r\n");
+ // ubx_get_clock_stats();
+
+ MAP_INPUT (PPS);
+
+ exti_select_source (EXTI9, PPS_PORT);
+ exti_set_trigger (EXTI9, EXTI_TRIGGER_BOTH);
+ exti_enable_request (EXTI9);
+ nvic_enable_irq (NVIC_EXTI9_5_IRQ);
+
+ return 0;
+}
+
+
+#define ALMANAC_LUMP 64
+
+int
+gps_almanac (void)
+{
+ uint32_t len = almanac_alp_len;
+ const uint8_t *ptr = almanac_alp;
+ uint32_t lumpsz;
+ uint8_t dummy;
+
+ printf ("Downloading GPS almanac %x %x %x\r\n", (int) ptr[0], (int) ptr[1],
+ (int) ptr[2]);
+
+
+ while (len) {
+ printf ("%d bytes to go\r\n", (int) len);
+
+ lumpsz = len > ALMANAC_LUMP ? ALMANAC_LUMP : len;
+
+ ubx_handshake_xfer (0x0b, 0x50, ptr, lumpsz);
+
+ ptr += lumpsz;
+ len -= lumpsz;
+
+ }
+
+ ubx_handshake_xfer (0x0b, 0x50, &dummy, 1);
+
+ return 0;
+}
+
+void gps_dump_almanac(void)
+{
+ ubx_send (0xb, 0x30, NULL,0);
+}
+
+
+#if 0
+int gps_bs(void)
+{
+ uint32_t now = SCS_DWT_CYCCNT;
+ uint64_t abs = abs_extend (now);
+ EPOCH e = pll_decompose (abs);
+ UTC u = time_epoch_to_utc (e);
+
+ uint8_t buf[80], *ptr;
+ int ret;
+
+ ptr = buf;
+
+ ptr += ubx_put_u32 (ptr, 391706007); /*19 sleaford st*/
+ ptr += ubx_put_u32 (ptr, 955140);
+ ptr += ubx_put_u32 (ptr, 501672842);
+ ptr += ubx_put_u32 (ptr, 100000); /*1km std dev*/
+
+ ptr += ubx_put_u16 (ptr, 0); /*no time mark*/
+
+ ptr += ubx_put_u16 (ptr, (u.year-2000)*100 + u.month);
+ ptr += ubx_put_u32 (ptr, (u.mday*1000000) + (u.hour*10000) + (u.minute *100) +u.second);
+ ptr += ubx_put_u32 (ptr, u.nanosecond);
+
+ ptr += ubx_put_u32 (ptr, 2000); /* time good to 2s */
+ ptr += ubx_put_u32 (ptr, 0);
+
+ ptr += ubx_put_u32 (ptr, 0);
+ ptr += ubx_put_u32 (ptr, 0);
+
+ ptr += ubx_put_u32 (ptr, 0x403);
+
+ printf("Bootstrapping GPS\r\n");
+
+ hexdump (buf, (unsigned) (ptr-buf));
+
+ ubx_send (0x0b, 0x01, buf, (unsigned) (ptr - buf));
+
+
+ ret = 0;
+
+
+/*
+ 00000: 97 f5 58 17
+ 04 93 0e 00
+ 8a eb e6 1d
+ a0 86 01 00
+ 00010: 00 00
+ 6f 07 19/03
+ 03 cb 06 01 /17 22:24:03
+ 65 ca af 02 45075045ns
+
+ d0 07 00 00 2000ms
+ 00020: 00 00 00 00 0ns
+ 00 00 00 00
+ 00 00 00 00
+ 03 04 00 00
+*/
+
+ return ret;
+}
+
+#endif
+
+int gps_bs(void)
+{
+ uint32_t now = SCS_DWT_CYCCNT;
+ uint64_t abs = abs_extend (now);
+ EPOCH e = pll_decompose (abs);
+ UTC u = time_epoch_to_utc (e);
+
+ uint8_t buf[80], *ptr;
+ int ret;
+
+ ptr = buf;
+
+ ptr += ubx_put_u8 (ptr, 0x0);
+ ptr += ubx_put_u8 (ptr, 0x0);
+ ptr += ubx_put_u8 (ptr, 0x0);
+ ptr += ubx_put_u8 (ptr, 0x0);
+
+ ptr += ubx_put_u32 (ptr, 391706007); /*19 sleaford st*/
+ ptr += ubx_put_u32 (ptr, 955140);
+ ptr += ubx_put_u32 (ptr, 501672842);
+ ptr += ubx_put_u32 (ptr, 100000); /*1km std dev*/
+
+ hexdump (buf, (unsigned) (ptr-buf));
+ ubx_send (0x13, 0x40, buf, (unsigned) (ptr-buf));
+
+
+ ptr = buf;
+
+ ptr += ubx_put_u8 (ptr, 0x10);
+ ptr += ubx_put_u8 (ptr, 0x0);
+ ptr += ubx_put_u8 (ptr, 0x0);
+ ptr += ubx_put_u8 (ptr, 0x80);
+
+ ptr += ubx_put_u16 (ptr,u.year-2000);
+ ptr += ubx_put_u8 (ptr,u.month);
+ ptr += ubx_put_u8 (ptr,u.mday);
+
+ ptr += ubx_put_u8 (ptr,u.hour);
+ ptr += ubx_put_u8 (ptr,u.minute);
+ ptr += ubx_put_u8 (ptr,u.second);
+ ptr += ubx_put_u8 (ptr,0);
+
+ ptr += ubx_put_u32 (ptr,u.nanosecond);
+
+ ptr += ubx_put_u16 (ptr, 2); /* time good to 2s */
+ ptr += ubx_put_u8 (ptr,0);
+ ptr += ubx_put_u8 (ptr,0);
+
+ ptr += ubx_put_u32 (ptr, 0);
+
+ hexdump (buf, (unsigned) (ptr-buf));
+ ubx_send (0x13, 0x40, buf, (unsigned) (ptr-buf));
+
+
+ ret = 0;
+
+ return ret;
+}
+
+
+void
+gps_reset (void)
+{
+ printf ("Restting gps..\r\n");
+
+#define REPHEMERIDIES (1UL << 0)
+#define RALMANAC (1UL << 1)
+#define RPOS (1UL << 4)
+#define RRTC (1UL << 8)
+
+ ubx_cfg_rst (REPHEMERIDIES | RALMANAC | RPOS | RRTC);
+
+ delay_ms (1000);
+ usart1_drain();
+
+
+ printf ("Testing GNSS...\r\n");
+ ubx_handshake (0x06, 0x00, NULL, 0);
+ printf ("GNSS there\r\n");
+
+ gps_init();
+
+ gps_set_ref (current_ref_hz);
+
+ gps_set_gnss();
+}
+
+#if 0
+static int
+ubx_get_clock_stats (void)
+{
+ uint8_t *ptr;
+
+ unsigned len;
+
+ ptr = ubx_fetch (0x01, 0x22, NULL, 0, &len);
+
+ //return ubx_recv_clock_stats(ptr,len);
+ return ptr ? 0 : -1;
+}
+#endif
diff --git a/app/led.c b/app/led.c
index b7f34a0..2dc285b 100644
--- a/app/led.c
+++ b/app/led.c
@@ -1,29 +1,83 @@
#include "project.h"
-#define LED (GPIO6)
-#define LED_PORT GPIOA
-
+#define LED1 (GPIO8)
+#define LED1_PORT GPIOE
+#define LED2 (GPIO9)
+#define LED2_PORT GPIOE
+#define LED3 (GPIO10)
+#define LED3_PORT GPIOE
+#define LED4 (GPIO11)
+#define LED4_PORT GPIOE
+#define LED5 (GPIO10)
+#define LED5_PORT GPIOB
+#define LED6 (GPIO11)
+#define LED6_PORT GPIOB
+#define LED7 (GPIO12)
+#define LED7_PORT GPIOB
+#define LED8 (GPIO13)
+#define LED8_PORT GPIOB
+#define LED9 (GPIO0)
+#define LED9_PORT GPIOD
+#define LED10 (GPIO1)
+#define LED10_PORT GPIOD
static unsigned led_ms;
void
led_init (void)
{
+ MAP_OUTPUT_PP (LED1);
+ MAP_OUTPUT_PP (LED2);
+ MAP_OUTPUT_PP (LED3);
+ MAP_OUTPUT_PP (LED4);
+ MAP_OUTPUT_PP (LED5);
+ MAP_OUTPUT_PP (LED6);
+ MAP_OUTPUT_PP (LED7);
+ MAP_OUTPUT_PP (LED8);
+ MAP_OUTPUT_PP (LED9);
+ MAP_OUTPUT_PP (LED10);
+
+ SET (LED1);
+ SET (LED2);
+ SET (LED3);
+ SET (LED4);
+ SET (LED5);
+ SET (LED6);
+ SET (LED7);
+ SET (LED8);
+ SET (LED9);
+ SET (LED10);
+
+}
+
+void led1_set (int v)
+{
+ if (!v) SET (LED1);
+ else CLEAR (LED1);
+}
- MAP_OUTPUT_PP (LED);
+void led2_set (int v)
+{
+ if (!v) SET (LED2);
+ else CLEAR (LED2);
}
+void led3_set (int v)
+{
+ if (!v) SET (LED3);
+ else CLEAR (LED3);
+}
void
led_clear (void)
{
- SET (LED);
+ SET (LED4);
}
void
led_set()
{
- CLEAR (LED);
+ CLEAR (LED4);
}
void led_blink (unsigned ms)
@@ -43,3 +97,13 @@ led_tick (void)
if (!led_ms) led_clear();
}
+
+void led_slow_tick (void)
+{
+ static int c;
+
+
+ c++;
+ c &= 7;
+}
+
diff --git a/app/lwip_glue.c b/app/lwip_glue.c
index 556fa0e..03380a4 100644
--- a/app/lwip_glue.c
+++ b/app/lwip_glue.c
@@ -59,10 +59,15 @@ void start_lwip (void)
lwip_init();
- IP4_ADDR (&ipaddr, 10, 32, 94, 9);
+#if 1
+ IP4_ADDR (&ipaddr, 10, 32, 99, 73);
IP4_ADDR (&netmask, 255, 255, 255, 0);
- IP4_ADDR (&gw, 10, 32, 94, 1);
-
+ IP4_ADDR (&gw, 10, 32, 99, 1);
+#else
+ IP4_ADDR (&ipaddr, 192, 168, 1, 1);
+ IP4_ADDR (&netmask, 255, 255, 255, 0);
+ IP4_ADDR (&gw, 192, 168, 1, 254);
+#endif
netif_add (&if0, &ipaddr, &netmask, &gw, NULL, steth_lwip_init , ethernet_input);
diff --git a/app/main.c b/app/main.c
index 356d4da..707d230 100644
--- a/app/main.c
+++ b/app/main.c
@@ -2,12 +2,24 @@
int time_known;
+#if 0
+void exti15_10_isr (void)
+{
+ nvic_disable_irq (NVIC_EXTI15_10_IRQ);
+
+ if (exti_get_flag_status (EXTI10)) exti10_isr();
+
+ if (exti_get_flag_status (EXTI11)) exti11_isr();
+
+ nvic_enable_irq (NVIC_EXTI15_10_IRQ);
+}
+#endif
static void cmd_dispatch (void)
{
uint8_t c;
- while (!ring_read_byte (&rx1_ring, &c)) {
+ while (!ring_read_byte (&rx2_ring, &c)) {
printf ("KEY> %c\r\n", c);
@@ -21,8 +33,13 @@ static void cmd_dispatch (void)
gps_reset();
break;
+ case 'I':
+ gps_bs();
+ break;
+
case 'A':
- gps_almanac();
+ //gps_almanac();
+ gps_dump_almanac();
break;
}
}
@@ -43,7 +60,123 @@ static const clock_scale_t hse_10mhz_3v3_168 = {
.apb2_frequency = 84000000,
};
+static const clock_scale_t hse_10mhz_3v3_120 = {
+ /* 120 */
+ .pllm = 10,
+ .plln = 240,
+ .pllp = 2,
+ .pllq = 5,
+ .hpre = RCC_CFGR_HPRE_DIV_NONE,
+ .ppre1 = RCC_CFGR_PPRE_DIV_4,
+ .ppre2 = RCC_CFGR_PPRE_DIV_2,
+ .power_save = 1,
+ .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE |
+ FLASH_ACR_LATENCY_3WS,
+ .apb1_frequency = 30000000,
+ .apb2_frequency = 60000000,
+};
+
+static const clock_scale_t hse_10mhz_3v3_84 = {
+ .pllm = 10,
+ .plln = 336,
+ .pllp = 4,
+ .pllq = 7,
+ .hpre = RCC_CFGR_HPRE_DIV_NONE,
+ .ppre1 = RCC_CFGR_PPRE_DIV_2,
+ .ppre2 = RCC_CFGR_PPRE_DIV_NONE,
+ .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE |
+ FLASH_ACR_LATENCY_2WS,
+ .apb1_frequency = 42000000,
+ .apb2_frequency = 84000000,
+};
+
+
+static const clock_scale_t hse_10mhz_3v3_48 = {
+ .pllm = 10,
+ .plln = 96,
+ .pllp = 2,
+ .pllq = 2,
+ .hpre = RCC_CFGR_HPRE_DIV_NONE,
+ .ppre1 = RCC_CFGR_PPRE_DIV_4,
+ .ppre2 = RCC_CFGR_PPRE_DIV_2,
+ .power_save = 1,
+ .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE |
+ FLASH_ACR_LATENCY_3WS,
+ .apb1_frequency = 12000000,
+ .apb2_frequency = 24000000,
+};
+
+static void pd_port (uint32_t p)
+{
+ unsigned c;
+
+ for (c = 0; c < 32; ++c) {
+
+ if ((p == GPIOA) && ((c == 13) || (c == 14))) continue;
+
+ gpio_mode_setup (p, GPIO_MODE_INPUT, GPIO_PUPD_NONE, 1UL << c);
+ }
+}
+
+
+static void pd_clear (uint32_t g, uint32_t b)
+{
+ gpio_mode_setup (g, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, b);
+ gpio_set_output_options (g, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, b);
+ gpio_clear (g, b);
+}
+
+
+static void pd_set (uint32_t g, uint32_t b)
+{
+ gpio_mode_setup (g, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, b);
+ gpio_set_output_options (g, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, b);
+ gpio_set (g, b);
+}
+
+
+static void pd(void)
+{
+ pd_port (GPIOA);
+ pd_port (GPIOB);
+ pd_port (GPIOC);
+ pd_port (GPIOD);
+ pd_port (GPIOE);
+ pd_port (GPIOF);
+ pd_port (GPIOG);
+
+ pd_set (GPIOB, GPIO10);
+
+ pd_set (GPIOG, GPIO4);
+ pd_set (GPIOD, GPIO10);
+
+ pd_set (GPIOD, GPIO1);
+ pd_set (GPIOB, GPIO13);
+
+ pd_set (GPIOE, GPIO3);
+ pd_set (GPIOE, GPIO4);
+
+
+ rcc_periph_clock_disable (RCC_ETHMACPTP);
+ rcc_periph_clock_disable (RCC_ETHMACRX);
+ rcc_periph_clock_disable (RCC_ETHMACTX);
+ rcc_periph_clock_disable (RCC_ETHMAC);
+ rcc_periph_clock_disable (RCC_USART2);
+ rcc_periph_clock_disable (RCC_USART1);
+ rcc_periph_clock_disable (RCC_GPIOG);
+ rcc_periph_clock_disable (RCC_GPIOF);
+ rcc_periph_clock_disable (RCC_GPIOE);
+ rcc_periph_clock_disable (RCC_GPIOD);
+ rcc_periph_clock_disable (RCC_GPIOC);
+ rcc_periph_clock_disable (RCC_GPIOB);
+ rcc_periph_clock_disable (RCC_GPIOA);
+ rcc_periph_clock_disable (RCC_SYSCFG);
+
+
+
+ for (;;);
+}
static void
board_setup (void)
@@ -58,22 +191,24 @@ board_setup (void)
rcc_periph_clock_enable (RCC_GPIOC);
rcc_periph_clock_enable (RCC_GPIOD);
rcc_periph_clock_enable (RCC_GPIOE);
+ rcc_periph_clock_enable (RCC_GPIOF);
+ rcc_periph_clock_enable (RCC_GPIOG);
rcc_periph_clock_enable (RCC_USART1);
- rcc_periph_clock_enable (RCC_USART3);
+ rcc_periph_clock_enable (RCC_USART2);
rcc_periph_clock_enable (RCC_ETHMAC);
rcc_periph_clock_enable (RCC_ETHMACTX);
rcc_periph_clock_enable (RCC_ETHMACRX);
rcc_periph_clock_enable (RCC_ETHMACPTP);
-
-
- nvic_set_priority (NVIC_EXTI2_IRQ, 0x0);
- nvic_set_priority (NVIC_EXTI0_IRQ, 0x10);
- nvic_set_priority (NVIC_EXTI15_10_IRQ, 0x20);
+ nvic_set_priority (NVIC_EXTI9_5_IRQ, 0x00);
+ nvic_set_priority (NVIC_EXTI3_IRQ, 0x10);
+ nvic_set_priority (NVIC_EXTI4_IRQ, 0x20);
nvic_set_priority (NVIC_USART1_IRQ, 0x30);
- nvic_set_priority (NVIC_USART3_IRQ, 0x30);
+ nvic_set_priority (NVIC_USART2_IRQ, 0x30);
nvic_set_priority (NVIC_ETH_IRQ, 0x40);
nvic_set_priority (NVIC_SYSTICK_IRQ, 0x50);
+
+ // nvic_enable_irq (NVIC_EXTI15_10_IRQ);
}
@@ -95,6 +230,8 @@ system_init (void)
printf ("STETH\r\n");
steth_init();
+ max7219_init (1);
+
gps_init();
ntp_init();
@@ -123,9 +260,6 @@ main (void)
-
-
-
while (1) {
#if 0
{
@@ -147,6 +281,8 @@ main (void)
cmd_dispatch();
dispatch_lwip();
+ max7219_dispatch();
+
}
return 0;
diff --git a/app/max7219.c b/app/max7219.c
new file mode 100644
index 0000000..fbba10d
--- /dev/null
+++ b/app/max7219.c
@@ -0,0 +1,143 @@
+#include "project.h"
+
+#define NCS (GPIO7)
+#define NCS_PORT GPIOG
+
+#define SCK (GPIO3)
+#define SCK_PORT GPIOB
+
+#define MOSI (GPIO5)
+#define MOSI_PORT GPIOB
+
+
+static void
+set (int sck, int ncs, int mosi)
+{
+ if (sck)
+ SET (SCK);
+ else
+ CLEAR (SCK);
+
+
+ if (ncs)
+ SET (NCS);
+ else
+ CLEAR (NCS);
+
+
+ if (mosi)
+ SET (MOSI);
+ else
+ CLEAR (MOSI);
+
+ //delay_us(10);
+
+}
+
+static void
+spip_send_8 (uint8_t wot)
+{
+ int i;
+
+ for (i = 0; i < 8; ++i) {
+ set (0, 0, wot & 0x80);
+ set (1, 0, wot & 0x80);
+ set (0, 0, wot & 0x80);
+ wot <<= 1;
+ }
+}
+
+
+static int mutex = 0;
+
+static int
+lock (void)
+{
+ if (__sync_add_and_fetch (&mutex, 1) != 1) {
+ __sync_sub_and_fetch (&mutex, 1);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static void
+unlock (void)
+{
+ __sync_sub_and_fetch (&mutex, 1);
+}
+
+
+static void
+write_reg (uint8_t reg, uint8_t data)
+{
+ while (lock());
+
+ set (0, 1, 0);
+ set (0, 0, 0);
+
+ spip_send_8 (reg);
+ spip_send_8 (data);
+
+ set (0, 0, 0);
+ set (0, 1, 0);
+ unlock();
+}
+
+static void write_pair (uint8_t reg, int d)
+{
+ write_reg (reg, d / 10);
+ write_reg (reg - 1, (d % 10) | 0x80);
+}
+
+void max7219_write (int d, int h, int m, int s)
+{
+
+ write_pair (8, d);
+ write_pair (6, h);
+ write_pair (4, m);
+ write_pair (2, s);
+
+}
+
+void max7219_dispatch (void)
+{
+ uint32_t now = SCS_DWT_CYCCNT;
+ uint64_t abs = abs_extend (now);
+ EPOCH e = pll_decompose (abs);
+ UTC u = time_epoch_to_utc (e);
+
+
+ max7219_write (u.mday, u.hour, u.minute, u.second);
+}
+
+void
+max7219_init (int on)
+{
+ MAP_OUTPUT_PP (SCK);
+ MAP_OUTPUT_PP (NCS);
+ MAP_OUTPUT_PP (MOSI);
+
+ set (0, 1, 0);
+
+
+ if (on) {
+
+ write_reg (0xc, 0x1); //Power up
+ write_reg (0xf, 0x0); //normal mode
+
+ write_reg (0x9, 0xff); //BCD decode
+ write_reg (0xb, 0x7); //8 digits
+ write_reg (0xa, 0x8); //intensity
+ } else {
+ write_reg (0xc, 0x0); //Power up
+ }
+
+
+
+}
+
+
+
+
diff --git a/app/msf.c b/app/msf.c
index 82dea7d..954e57f 100644
--- a/app/msf.c
+++ b/app/msf.c
@@ -1,47 +1,51 @@
#include "project.h"
-#define P1 (GPIO1)
+#define J2(a,b) a ## b
+#define J3(a,b,c) a ## b ## c
+
+#define P1 (GPIO3)
#define P1_PORT GPIOE
-#define T (GPIO0)
+#define T_BIT 1
#define T_PORT GPIOE
+#define T_EXTI_LINE T_BIT
+
+
+#define M_T(a) J2(GPIO,a)
+#define T M_T(T_BIT)
+#define M_EXTI_T(a) J2(EXTI,a)
+#define EXTI_T M_EXTI_T(T_EXTI_LINE)
+#define M_exti_t_isr(a) J3(exti,a,_isr)
+#define exti_t_isr M_exti_t_isr(T_EXTI_LINE)
+#define M_NVIC_EXTI_T_IRQ(a) J3(NVIC_EXTI,a,_IRQ)
+#define NVIC_EXTI_T_IRQ M_NVIC_EXTI_T_IRQ(T_EXTI_LINE)
+
static Event_ring msf_ring;
static uint64_t msf_last_second;
uint64_t msf_last_happy;
+static char msf_info[40];
+static EPOCH msf_time;
-void exti0_isr (void)
+void exti_t_isr (void)
{
uint32_t now = SCS_DWT_CYCCNT;
int v;
v = !!gpio_get (T_PORT, T);
- nvic_disable_irq (NVIC_EXTI0_IRQ);
- exti_reset_request (EXTI0);
+ nvic_disable_irq (NVIC_EXTI_T_IRQ);
+
+ exti_reset_request (EXTI_T);
msf_ring.events[msf_ring.tx_ptr].when = now;
msf_ring.events[msf_ring.tx_ptr].value = v;
msf_ring.tx_ptr = (msf_ring.tx_ptr + 1) & ERING_MASK;
-#if 0
-
- if (time_known) {
- uint64_t abs = abs_extend (now);
- EPOCH e = pll_decompose (abs);
- UTC u = time_epoch_to_utc (e);
-
- printf ("QRR %d.%09d %d\r\n", (u.minute * 60) + u.second, u.nanosecond, (int) !v);
- printf ("QRR %d.%09d %d\r\n", (u.minute * 60) + u.second, u.nanosecond, (int) v);
- }
-
-#endif
-
- nvic_enable_irq (NVIC_EXTI0_IRQ);
-
+ nvic_enable_irq (NVIC_EXTI_T_IRQ);
}
@@ -78,7 +82,7 @@ static int check_min_ident (uint8_t *i)
static void process_bits (uint64_t abs)
{
UTC u;
- EPOCH msf_time;
+ EPOCH e;
if (check_min_ident (&bitsa[52])) return;
@@ -102,17 +106,23 @@ static void process_bits (uint64_t abs)
/* This is always valid a check_min_ident will fail for leap seconds*/
- msf_time = time_utc_to_epoch (u);
+ e = time_utc_to_epoch (u);
+
+ if (bitsb[58]) e.s -= 3600; /*BST*/
msf_last_happy = make_happy (abs, 0);
- pll_set_offset (msf_time, abs);
+ pll_set_offset (e, abs);
dump_bits ("msfa", bitsa);
dump_bits ("msfb", bitsb);
printf ("MSF: Next minute is: %02d-%02d-%02d %02d:%02d\r\n", u.year, u.month, u.mday, u.hour, u.minute);
- //time_print_epoch (msf_time);
+
+ msf_time = e;
+ msf_time.s -= 1;
+
+ //time_print_epoch (e);
}
@@ -127,15 +137,6 @@ static void report_bits (uint64_t abs, int second, int a, int b)
}
-static void report_time (uint64_t abs)
-{
-#if 1
- EPOCH e = pll_decompose (abs);
- time_print_epoch ("MSF : ", e);
-#endif
-}
-
-
void msf_dispatch (void)
{
static uint32_t last_0, last_1, last_s;
@@ -153,8 +154,21 @@ void msf_dispatch (void)
v = msf_ring.events[msf_ring.rx_ptr].value;
now = msf_ring.events[msf_ring.rx_ptr].when;
+ led1_set (v);
+
msf_ring.rx_ptr = (msf_ring.rx_ptr + 1) & ERING_MASK;
+#if 0
+ {
+ abs = abs_extend (now);
+ EPOCH e = pll_decompose (abs);
+ UTC u = time_epoch_to_utc (e);
+
+ printf (" MSF %d %02d:%02d.%06d\r\n", v, u.minute, u.second, (int) (u.nanosecond / 1000));
+ }
+#endif
+
+
if (v) {
pulse_w = now - last_0;
pulse_w /= (HZ / 1000);
@@ -162,6 +176,7 @@ void msf_dispatch (void)
if (pulse_w > 300) {
last_s = now;
is_s = 1;
+ msf_time.s++;
}
last_1 = now;
@@ -189,14 +204,14 @@ void msf_dispatch (void)
pll_dispatch (msf_last_happy, abs, "MSF");
+ sprintf (msf_info, "m=%d s=%02d b=%d%d", had_m, second, bita, bitb);
if (had_m) {
report_bits (abs, second, bita, bitb);
second++;
}
- if (time_known)
- report_time (abs);
+ report_time ("MSF", msf_time, abs, msf_info);
// stats();
}
@@ -229,12 +244,15 @@ msf_init (void)
MAP_INPUT (T);
MAP_OUTPUT_PP (P1);
+ gpio_set (P1_PORT, P1);
+ delay_ms (50);
gpio_clear (P1_PORT, P1);
- exti_select_source (EXTI0, T_PORT);
- exti_set_trigger (EXTI0, EXTI_TRIGGER_BOTH);
- exti_enable_request (EXTI0);
- nvic_enable_irq (NVIC_EXTI0_IRQ);
+ exti_select_source (EXTI_T, T_PORT);
+ exti_set_trigger (EXTI_T, EXTI_TRIGGER_BOTH);
+ exti_enable_request (EXTI_T);
+
+ nvic_enable_irq (NVIC_EXTI_T_IRQ);
}
diff --git a/app/new_almanac.c b/app/new_almanac.c
new file mode 100644
index 0000000..f31d51d
--- /dev/null
+++ b/app/new_almanac.c
@@ -0,0 +1,53 @@
+
+/*
+
+201343145 m=1 s=26 b=0
+MSF : Thr 1970-Jan-01 00:00:32.207630295 m=1 s=26 b=11
+GPS : Thr 1970-Jan-01 00:00:33.165197086 V:37 Fix:-! TXCO +186919E-12
+MSF : Thr 1970-Jan-01 00:00:33.213616575 m=1 s=27 b=10
+GPS : Thr 1970-Jan-01 00:00:34.165197586 V:37 Fix:-! TXCO +187035E-12
+MSF : Thr 1970-Jan-01 00:00:34.210351926 m=1 s=28 b=00
+DCF77: Thr 1970-Jan-01 00:00:34.219091892 m=1 s=27 b=0
+GPS : Thr 1970-Jan-01 00:00:35.165198092 V:37 Fix:-! TXCO +187150E-12
+DCF77: Thr 1970-Jan-01 00:00:35.201664603 m=1 s=00 b=0
+MSF : Thr 1970-Jan-01 00:00:35.212095260 m=1 s=00 b=11
+KEY> A
+ Almanac: 1 2045 4145ce 3914d0 fd2a00 a10ccc b9a536 1bda53 8963ea e7ffdc
+ Almanac: 2 2045 429b0b 390736 fd1b00 a10ce2 b6e6de b85dab 955a7a eaffa0
+ Almanac: 3 2045 430fe4 390d29 fd4800 a10c1c e42323 17f9b8 62b239 180010
+ Almanac: 4 0 000000 000000 000000 000000 000000 000000 000000 000000
+ Almanac: 5 2045 452da0 390498 fd3c00 a10ccc e31523 1cc9aa 01918b 000004
+ Almanac: 6 2045 460d3e 391499 fd2a00 a10bec b94ec9 d12419 915098 21ffc0
+ Almanac: 7 2045 476511 390898 fd2700 a10c48 3a0ba3 9b355c 707ac6 01ffd0
+ Almanac: 8 2045 4823cf 39123f fd5a00 a10d5c 8e3279 f3a1f4 ecd967 ee0004
+ Almanac: 9 2045 490b51 3906d7 fd5000 a10d59 0e2fd6 46ade7 ef5573 3affc0
+ Almanac: 10 2045 4a242a 390d2f fd4c00 a10cf2 e40114 913453 34ffea 0cffc8
+ Almanac: 11 2045 4b8770 39e9ef fd0100 a10cfd a773e2 4c3b4e 6c97aa ab005c
+ Almanac: 12 2045 4c3e21 391acf fd6300 a10d19 66d384 2abce7 5226da 21fffc
+ Almanac: 13 2045 4d1df9 3910e4 fd5b00 a10cf2 13bbb3 36e767 b5dc0e f60014
+GPS : Thr 1970-Jan-01 00:00:36.165198597 V:37 Fix:-! TXCO +189311E-12
+ Almanac: 14 2045 4e545e 390c12 fd5500 a10d14 11f1aa b0aece d7fa67 f40010
+MSF : Thr 1970-Jan-01 00:00:36.209535367 m=1 s=01 b=00
+DCF77: Thr 1970-Jan-01 00:00:36.221746226 m=1 s=01 b=0
+ Almanac: 15 2045 4f5c1d 39f6e6 fd4000 a10cd1 0affca 1f3bf7 bde400 d50038
+ Almanac: 16 2045 50587c 391b0e fd6600 a10c02 6798bd 16957f 041094 fcfff0
+ Almanac: 17 2045 5169b8 391b32 fd6000 a10d62 90e872 ba1b87 df6525 03004c
+ Almanac: 18 2045 527bbf 3906d0 fd1900 a10d47 b775a0 382ff7 7f7598 040038
+ Almanac: 19 2045 534d54 3919bb fd5e00 a10cb2 92cc0e 376849 51e9ee d3002c
+ Almanac: 20 2045 5423b2 39f808 fd2700 a10cfb df459e 5e294a 7b9ab3 440014
+ Almanac: 21 2045 55cb07 39031d fd1600 a10db2 b71a2d c46c6b 405027 e1005c
+ Almanac: 22 2045 563b9a 39f5ee fd2600 a10bf7 e143b9 c70a7b c2ce9d a8ffd0
+ Almanac: 23 2045 576a02 3900db fd4b00 a10c93 0e0162 a2dedb a8436e e60014
+ Almanac: 24 2045 584380 39fda1 fd1500 a10d3b 376775 18921c 94aa72 f70014
+ Almanac: 25 2045 594482 391299 fd5400 a10d8a 643dbf 23858e 44f767 9ffff4
+ Almanac: 26 2045 5a1e67 39066c fd4500 a10c29 6320f6 05cf4c 29e18b 140064
+ Almanac: 27 2045 5b384f 3917a4 fd6000 a10cc8 8ea338 121aed e1e112 f4ffc8
+ Almanac: 28 2045 5c9cdb 391a5d fd6600 a10d45 67c27b c4112b 038947 640010
+ Almanac: 29 2045 5d06a1 391c21 fd6100 a10c16 915b70 3b6ed0 03bbec 20ffc8
+ Almanac: 30 2045 5e1ed8 39ff21 fd1800 a10c58 3b3c5a 8515d5 70d4f6 f6ffd4
+ Almanac: 31 2045 5f4b9e 390b92 fd2a00 a10c1d 3a9b64 ffcada 601fce 06fff8
+ Almanac: 32 2045 60165d 3909a2 fd5400 a10dc2 0e7261 96ae2c fe3295 e900a8
+GPS : Thr 1970-Jan-01 00:00:37.165199103 V:37 Fix:-! TXCO +189311E-12
+DCF77: Thr 1970-Jan-01 00:00:37.206403420 m=1 s=02 b=0
+
+*/
diff --git a/app/parse_alamanc.pl b/app/parse_alamanc.pl
new file mode 100755
index 0000000..ee946b7
--- /dev/null
+++ b/app/parse_alamanc.pl
@@ -0,0 +1,91 @@
+#!/usr/bin/env perl
+
+use strict;
+use Data::Dumper;
+use Math::Trig;
+
+
+
+sub rad_to_ss($)
+{
+my $r=shift;
+return undef unless defined $r;
+return $r/pi;
+}
+
+
+sub rad_to_d_ss($)
+{
+my $r=shift;
+return undef unless defined $r;
+return ($r/pi)-0.3;
+}
+
+
+sub squirt_bits($$$)
+{
+my ($v,$n,$s)=@_;
+
+#die unless defined $v;
+
+$s=2.0**-$s;
+
+my $i=int(($v*$s) +.5);
+
+my $m=1 << $n;
+if ($i<0) {
+ $i+=$m;
+}
+
+print "v=$v became 0<=$i<$m\n";
+
+my $b=reverse(sprintf ("%0".$n."B",$i));
+
+return $b ." ";
+}
+
+
+
+sub process_sv($)
+{
+my $h=shift;
+my $a="";
+
+
+$a.=squirt_bits($h->{'ID'},32,0);
+$a.=squirt_bits($h->{'week'},32,0);
+$a.=squirt_bits($h->{'Eccentricity'},16,-21);
+$a.=squirt_bits($h->{'Time of Applicability(s)'},8,12);
+
+
+$a.=squirt_bits(rad_to_d_ss($h->{'Orbital Inclination(rad)'}),16,-19);
+$a.=squirt_bits(rad_to_ss($h->{'Rate of Right Ascen(r/s)'}),16,-38);
+$a.=squirt_bits($h->{'SQRT(A) (m 1/2)'},16,-11);
+$a.=squirt_bits(rad_to_ss($h->{'Right Ascen at Week(rad)'}),24,-23);
+$a.=squirt_bits(rad_to_ss($h->{'Argument of Perigee(rad)'}),24,-23);
+$a.=squirt_bits(rad_to_ss($h->{'Mean Anom(rad)'}),24,-23);
+$a.=squirt_bits($h->{'Af0(s)'},11,-20);
+$a.=squirt_bits($h->{'Af1(s/s)'},11,-38);
+
+
+print Dumper($h);
+}
+
+
+
+my $hash={};
+
+
+while (<>) {
+chomp;
+
+if (/^\*{5}/) {
+ process_sv($hash);
+ $hash={};
+} elsif (/^([^:]+):\s*([^\r\n]+)[\r\n]*$/) {
+ $hash->{$1}=$2;
+}
+}
+
+
+
diff --git a/app/pll.c b/app/pll.c
index 460b789..986034c 100644
--- a/app/pll.c
+++ b/app/pll.c
@@ -176,7 +176,7 @@ void pll_dispatch (uint64_t happy, uint64_t edge, const char *src)
led_blink (100);
-#if 1
+#if 0
printf ("EDGE %08x%08x\r\n",
(unsigned) (edge >> 32),
(unsigned) (edge & 0xffffffff));
diff --git a/app/project.h b/app/project.h
index 869cb3d..47eecb3 100644
--- a/app/project.h
+++ b/app/project.h
@@ -14,6 +14,7 @@
#include <libopencm3/stm32/spi.h>
#include <libopencm3/stm32/adc.h>
#include <libopencm3/stm32/exti.h>
+#include <libopencm3/stm32/pwr.h>
#include <libopencm3/ethernet/mac_stm32fxx7.h>
#include <libopencm3/ethernet/phy.h>
#include <libopencm3/stm32/syscfg.h>
@@ -23,6 +24,7 @@
#include <libopencm3/cm3/scs.h>
#include <libopencm3/cm3/scb.h>
+
#include <lwip/init.h>
#include <lwip/sys.h>
#include <lwip/udp.h>
@@ -43,7 +45,8 @@
#include "prototypes.h"
-#define HZ 167999973
+#define HZ 10000000
+//#define HZ 167999973
//#define HZ 168000000
//#define HZ 167968615
//#define HZ 165925490
diff --git a/app/prototypes.h b/app/prototypes.h
index 933e583..667262b 100644
--- a/app/prototypes.h
+++ b/app/prototypes.h
@@ -1,9 +1,13 @@
/* led.c */
extern void led_init(void);
+extern void led1_set(int v);
+extern void led2_set(int v);
+extern void led3_set(int v);
extern void led_clear(void);
extern void led_set(void);
extern void led_blink(unsigned ms);
extern void led_tick(void);
+extern void led_slow_tick(void);
/* ticker.c */
extern volatile uint32_t ticks;
extern void delay_us(uint32_t d);
@@ -17,14 +21,14 @@ extern int ring_read_byte(volatile ring_t *r, uint8_t *c);
extern int ring_write(volatile ring_t *r, uint8_t *buf, size_t len, int blocking);
extern int ring_empty(volatile ring_t *r);
/* usart.c */
-extern volatile ring_t rx3_ring;
-extern volatile ring_t tx3_ring;
+extern volatile ring_t rx2_ring;
+extern volatile ring_t tx2_ring;
extern volatile ring_t rx1_ring;
extern volatile ring_t tx1_ring;
-extern void usart3_isr(void);
-extern void usart3_queue(uint8_t d);
-extern void usart3_drain(void);
-extern int usart3_write(char *ptr, int len, int blocking);
+extern void usart2_isr(void);
+extern void usart2_queue(uint8_t d);
+extern void usart2_drain(void);
+extern int usart2_write(char *ptr, int len, int blocking);
extern void usart1_isr(void);
extern void usart1_queue(uint8_t d);
extern void usart1_drain(void);
@@ -52,7 +56,7 @@ extern void steth_init(void);
extern void steth_slow_tick(void);
/* msf.c */
extern uint64_t msf_last_happy;
-extern void exti0_isr(void);
+extern void exti1_isr(void);
extern void msf_dispatch(void);
extern void msf_init(void);
/* abs.c */
@@ -64,6 +68,7 @@ extern void abs_slow_tick(void);
extern int64_t pll_freq;
extern uint64_t pll_last_update;
extern int pll_valid;
+extern int pll_ready;
extern void pll_meh(void);
extern uint64_t make_happy(uint64_t abs, int64_t shift);
extern void pll_dispatch(uint64_t happy, uint64_t edge, const char *src);
@@ -73,18 +78,19 @@ extern EPOCH pll_decompose_diff(int64_t diff);
extern EPOCH pll_decompose(uint64_t abs);
/* main.c */
extern int time_known;
+extern void rcc_clock_setup_hse_3v3_no_pll(const clock_scale_t *clock);
extern int main(void);
/* time_fn.c */
extern UTC time_epoch_to_utc(EPOCH epoch);
extern EPOCH time_utc_to_epoch(UTC u);
extern void utc_to_str(char *dst, UTC u);
-extern void time_print_utc(const char *p, UTC u);
-extern void time_print_epoch(const char *p, EPOCH e);
+extern void time_print_utc(const char *p, UTC u, const char *t);
+extern void time_print_epoch(const char *p, EPOCH e, const char *t);
/* ntp.c */
extern void ntp_init(void);
/* dcf77.c */
extern uint64_t dcf77_last_happy;
-extern void exti15_10_isr(void);
+extern void exti2_isr(void);
extern void dcf77_dispatch(void);
extern void dcf77_init(void);
/* util.c */
@@ -94,12 +100,20 @@ extern unsigned le_bcd(uint8_t *d, unsigned s, unsigned e);
/* stats.c */
/* gps.c */
extern uint64_t gps_last_happy;
-extern void exti2_isr(void);
+extern void exti9_5_isr(void);
extern void gps_dispatch(void);
extern int gps_init(void);
extern int gps_almanac(void);
+extern void gps_dump_almanac(void);
+extern int gps_bs(void);
extern void gps_reset(void);
/* hexdump.c */
extern void hexdump(void *_d, int len);
/* bits.c */
extern void dump_bits(char *wot, uint8_t *bits);
+/* max7219.c */
+extern void max7219_write(int d, int h, int m, int s);
+extern void max7219_dispatch(void);
+extern void max7219_init(int on);
+/* report.c */
+extern void report_time(const char *src, EPOCH e, uint64_t abs, const char *info);
diff --git a/app/report.c b/app/report.c
new file mode 100644
index 0000000..a7bd4db
--- /dev/null
+++ b/app/report.c
@@ -0,0 +1,15 @@
+#include "project.h"
+
+
+void report_time (const char *src, EPOCH e, uint64_t abs, const char *info)
+{
+ printf ("%s %08x%08x %08x%08x %s\r\n",
+ src,
+ (unsigned) (abs >> 32),
+ (unsigned) (abs & 0xffffffff),
+ (unsigned) (e.s >> 32),
+ (unsigned) (e.s & 0xffffffff),
+ info);
+}
+
+
diff --git a/app/stdio.c b/app/stdio.c
index 4a46f3f..9a8c74a 100644
--- a/app/stdio.c
+++ b/app/stdio.c
@@ -27,7 +27,7 @@ _write (int file,
int ret;
- ret = usart1_write (buf, nbytes, 1);
+ ret = usart2_write (buf, nbytes, 1);
if (ret < 0) {
errno = -ret;
@@ -77,5 +77,5 @@ isatty (int file)
void stdio_drain (void)
{
- usart1_drain();
+ usart2_drain();
}
diff --git a/app/steth.c b/app/steth.c
index ead4efd..7b23b3c 100644
--- a/app/steth.c
+++ b/app/steth.c
@@ -260,11 +260,16 @@ static void eth_reset (void)
rcc_periph_reset_release (RST_ETHMAC);
+#ifdef NRST
+#if 0
delay_us (1000);
CLEAR (NRST);
delay_us (1);
SET (NRST);
delay_us (1000);
+#endif
+#endif
+
TRACE;
ETH_DMABMR |= ETH_DMABMR_SR;
@@ -285,7 +290,7 @@ static void eth_reset (void)
TRACE;
my_eth_init (PHY, ETH_CLK_150_168MHZ);
- phy_set_ignore_address();
+ //phy_set_ignore_address();
TRACE;
phy_stat();
@@ -323,7 +328,9 @@ steth_init (void)
delay_ms (1);
rcc_periph_reset_release (RST_ETHMAC);
+#ifdef NRST
MAP_OUTPUT_PP (NRST);
+#endif
MAP_OUTPUT_PP (RXD0);
MAP_OUTPUT_PP (RXD1);
@@ -335,16 +342,20 @@ steth_init (void)
SET (RXD1);
SET (CRS_DV);
+#ifdef NRST
delay_ms (1);
CLEAR (NRST);
delay_ms (1);
SET (NRST);
delay_ms (1);
+#endif
MAP_AF_100 (MDIO, GPIO_AF11);
MAP_AF_100 (CRS_DV, GPIO_AF11);
+#ifdef RXER
MAP_AF_100 (RXER, GPIO_AF11);
+#endif
MAP_AF_100 (TXEN, GPIO_AF11);
MAP_AF_100 (TXD0, GPIO_AF11);
MAP_AF_100 (TXD1, GPIO_AF11);
diff --git a/app/steth.h b/app/steth.h
index d2a1352..ca752a7 100644
--- a/app/steth.h
+++ b/app/steth.h
@@ -1,17 +1,14 @@
#define PHY PHY0
-#define RXER GPIO10
-#define RXER_PORT GPIOB
-
#define TXEN GPIO11
-#define TXEN_PORT GPIOB
+#define TXEN_PORT GPIOG
-#define TXD0 GPIO12
-#define TXD0_PORT GPIOB
+#define TXD0 GPIO13
+#define TXD0_PORT GPIOG
-#define TXD1 GPIO13
-#define TXD1_PORT GPIOB
+#define TXD1 GPIO14
+#define TXD1_PORT GPIOG
#define RXD0 GPIO4
#define RXD0_PORT GPIOC
@@ -31,9 +28,6 @@
#define REF_CLK GPIO1
#define REF_CLK_PORT GPIOA
-#define NRST GPIO2
-#define NRST_PORT GPIOE
-
#define DESC_SZ ETH_DES_EXT_SIZE
#define FRAME_SZ 1516
diff --git a/app/ticker.c b/app/ticker.c
index 0f2b3e3..2016058 100644
--- a/app/ticker.c
+++ b/app/ticker.c
@@ -35,6 +35,7 @@ sys_tick_handler (void)
abs_slow_tick();
steth_slow_tick();
+ led_slow_tick();
}
@@ -53,8 +54,8 @@ ticker_init (void)
{
uint32_t v, w;
- /*168MHz / 168000 -> 1ms */
- systick_set_reload (168000);
+ /*10MHz / 10000 -> 1ms */
+ systick_set_reload (10000);
systick_set_clocksource (STK_CSR_CLKSOURCE_AHB);
systick_counter_enable();
/* this done last */
diff --git a/app/time_fn.c b/app/time_fn.c
index 957bc47..87fb48f 100644
--- a/app/time_fn.c
+++ b/app/time_fn.c
@@ -217,16 +217,16 @@ void utc_to_str (char *dst, UTC u)
}
-void time_print_utc (const char *p, UTC u)
+void time_print_utc (const char *p, UTC u, const char *t)
{
const char *dname[] = {"Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat", "Sun"};
const char *mname[] = {"", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
- printf ("%s%s %04d-%s-%02d %02d:%02d:%02d.%09d\r\n", p ? p : "", dname[u.wday], u.year, mname[u.month], u.mday, u.hour, u.minute, u.second, u.nanosecond);
+ printf ("%s%s %04d-%s-%02d %02d:%02d:%02d.%09d %s\r\n", p ? p : "", dname[u.wday], u.year, mname[u.month], u.mday, u.hour, u.minute, u.second, u.nanosecond , t ? t : "");
}
-void time_print_epoch (const char *p, EPOCH e)
+void time_print_epoch (const char *p, EPOCH e, const char *t)
{
UTC u = time_epoch_to_utc (e);
- time_print_utc (p, u);
+ time_print_utc (p, u, t);
}
diff --git a/app/time_fn.h b/app/time_fn.h
index a1a4602..2409eeb 100644
--- a/app/time_fn.h
+++ b/app/time_fn.h
@@ -12,8 +12,8 @@ typedef struct {
} UTC;
typedef struct {
- int64_t s;
- int64_t ns;
+ int64_t s;
+ int64_t ns;
} EPOCH;
diff --git a/app/ubx.h b/app/ubx.h
index 44c4782..4874e92 100644
--- a/app/ubx.h
+++ b/app/ubx.h
@@ -6,6 +6,14 @@ ubx_get_u8 (uint8_t *ptr, uint8_t *v)
}
static inline int
+ubx_get_i8 (uint8_t *ptr, int8_t *v)
+{
+ *v = (int8_t) * ptr;
+ return 1;
+}
+
+
+static inline int
ubx_get_u16 (uint8_t *ptr, uint16_t *v)
{
memcpy (v, ptr, sizeof (*v));
diff --git a/app/usart.c b/app/usart.c
index e826a22..5d5614d 100644
--- a/app/usart.c
+++ b/app/usart.c
@@ -4,11 +4,11 @@
#define BIG_BUFFER_SIZE 600
-volatile ring_t rx3_ring;
-static uint8_t rx3_ring_buf[BUFFER_SIZE];
+volatile ring_t rx2_ring;
+static uint8_t rx2_ring_buf[BUFFER_SIZE];
-volatile ring_t tx3_ring;
-static uint8_t tx3_ring_buf[BUFFER_SIZE];
+volatile ring_t tx2_ring;
+static uint8_t tx2_ring_buf[BUFFER_SIZE];
volatile ring_t rx1_ring;
static uint8_t rx1_ring_buf[BUFFER_SIZE];
@@ -23,62 +23,64 @@ static uint8_t tx1_ring_buf[BUFFER_SIZE];
#define RX1 GPIO10
#define RX1_PORT GPIOA
-#define TX3 GPIO10
-#define TX3_PORT GPIOC
+#define TX2 GPIO5
+#define TX2_PORT GPIOD
-#define RX3 GPIO11
-#define RX3_PORT GPIOC
+#define RX2 GPIO6
+#define RX2_PORT GPIOD
+#define RX2_EN GPIO4
+#define RX2_EN_PORT GPIOG
-void usart3_isr (void)
+void usart2_isr (void)
{
uint8_t data;
/* Check if we were called because of RXNE. */
- if (((USART_CR1 (USART3) & USART_CR1_RXNEIE) != 0) &&
- ((USART_SR (USART3) & USART_SR_RXNE) != 0)) {
+ if (((USART_CR1 (USART2) & USART_CR1_RXNEIE) != 0) &&
+ ((USART_SR (USART2) & USART_SR_RXNE) != 0)) {
/* Retrieve the data from the peripheral. */
- data = usart_recv (USART3);
+ data = usart_recv (USART2);
- ring_write_byte (&rx3_ring, data);
+ ring_write_byte (&rx2_ring, data);
//usart6_queue(data);
}
/* Check if we were called because of TXE. */
- if (((USART_CR1 (USART3) & USART_CR1_TXEIE) != 0) &&
- ((USART_SR (USART3) & USART_SR_TXE) != 0)) {
+ if (((USART_CR1 (USART2) & USART_CR1_TXEIE) != 0) &&
+ ((USART_SR (USART2) & USART_SR_TXE) != 0)) {
- if (ring_read_byte (&tx3_ring, &data)) {
+ if (ring_read_byte (&tx2_ring, &data)) {
/*No more data, Disable the TXE interrupt, it's no longer needed. */
- usart_disable_tx_interrupt (USART3);
+ usart_disable_tx_interrupt (USART2);
} else
- usart_send_blocking (USART3, data);
+ usart_send_blocking (USART2, data);
}
}
void
-usart3_queue (uint8_t d)
+usart2_queue (uint8_t d)
{
- ring_write_byte (&tx3_ring, d);
- usart_enable_tx_interrupt (USART3);
+ ring_write_byte (&tx2_ring, d);
+ usart_enable_tx_interrupt (USART2);
}
void
-usart3_drain (void)
+usart2_drain (void)
{
- while (!ring_empty (&tx3_ring));
+ while (!ring_empty (&tx2_ring));
}
int
-usart3_write (char *ptr, int len, int blocking)
+usart2_write (char *ptr, int len, int blocking)
{
int ret;
- ret = ring_write (&tx3_ring, (uint8_t *) ptr, len, blocking);
- usart_enable_tx_interrupt (USART3);
+ ret = ring_write (&tx2_ring, (uint8_t *) ptr, len, blocking);
+ usart_enable_tx_interrupt (USART2);
return ret;
}
@@ -140,33 +142,38 @@ void
usart_init (void)
{
- ring_init (&rx3_ring, rx3_ring_buf, sizeof (rx3_ring_buf));
- ring_init (&tx3_ring, tx3_ring_buf, sizeof (tx3_ring_buf));
+ ring_init (&rx2_ring, rx2_ring_buf, sizeof (rx2_ring_buf));
+ ring_init (&tx2_ring, tx2_ring_buf, sizeof (tx2_ring_buf));
- MAP_AF (TX3, GPIO_AF7);
- MAP_AF_PU (RX3, GPIO_AF7);
+ MAP_OUTPUT_PP (RX2_EN);
+ SET (RX2_EN);
- usart_set_baudrate (USART3, 9600);
- usart_set_databits (USART3, 8);
- usart_set_stopbits (USART3, USART_STOPBITS_1);
- usart_set_parity (USART3, USART_PARITY_NONE);
- usart_set_flow_control (USART3, USART_FLOWCONTROL_NONE);
- usart_set_mode (USART3, USART_MODE_TX_RX);
+ MAP_INPUT (RX2);
+ MAP_AF (TX2, GPIO_AF7);
+ MAP_AF_PU (RX2, GPIO_AF7);
- usart_enable_rx_interrupt (USART3);
+ usart_set_baudrate (USART2, 38400);
+ usart_set_databits (USART2, 8);
+ usart_set_stopbits (USART2, USART_STOPBITS_1);
+ usart_set_parity (USART2, USART_PARITY_NONE);
+ usart_set_flow_control (USART2, USART_FLOWCONTROL_NONE);
+ usart_set_mode (USART2, USART_MODE_TX_RX);
- usart_enable (USART3);
+ usart_enable_rx_interrupt (USART2);
- nvic_enable_irq (NVIC_USART3_IRQ);
+ usart_enable (USART2);
+
+ nvic_enable_irq (NVIC_USART2_IRQ);
ring_init (&rx1_ring, rx1_ring_buf, sizeof (rx1_ring_buf));
ring_init (&tx1_ring, tx1_ring_buf, sizeof (tx1_ring_buf));
+ MAP_INPUT (RX1);
MAP_AF (TX1, GPIO_AF7);
MAP_AF_PU (RX1, GPIO_AF7);
- usart_set_baudrate (USART1, 38400);
+ usart_set_baudrate (USART1, 9600);
usart_set_databits (USART1, 8);
usart_set_stopbits (USART1, USART_STOPBITS_1);
usart_set_parity (USART1, USART_PARITY_NONE);
diff --git a/oocd/board/stm32f407zet6.cfg b/oocd/board/stm32f407zet6.cfg
new file mode 100644
index 0000000..9be7ac5
--- /dev/null
+++ b/oocd/board/stm32f407zet6.cfg
@@ -0,0 +1,5 @@
+
+source [find target/stm32f4x.cfg]
+
+#reset_config srst_only
+reset_config trst_only
diff --git a/oocd/stm32-f407.cfg b/oocd/stm32-f407.cfg
deleted file mode 100644
index 0809223..0000000
--- a/oocd/stm32-f407.cfg
+++ /dev/null
@@ -1,6 +0,0 @@
-#
-telnet_port 4444
-gdb_port 3333
-
-source [find interface/jlink.cfg]
-source [find target/stm32f1x.cfg]