From b3c6320899d6b27899ab3c67c745e8d3b29af3a2 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 19 Feb 2019 13:46:18 +0000 Subject: working ethernet --- .gitignore | 2 + Makefile.include | 6 +- app/Makefile | 27 +- app/bits.c | 22 ++ app/dcf77.c | 186 ++++++++++ app/events.h | 14 + app/gps.c | 839 +++++++++++++++++++++++++++++++++++++++++++ app/gps.h | 11 + app/hexdump.c | 57 +++ app/lwip/lwipopts.h | 8 +- app/lwip_glue.c | 2 +- app/main.c | 48 ++- app/msf.c | 4 +- app/pins.h | 11 +- app/pll.c | 4 +- app/project.h | 12 +- app/prototypes.h | 38 +- app/stats.c | 44 +++ app/stdio.c | 4 +- app/steth.c | 255 ++++++++----- app/ubx.h | 56 +++ app/usart.c | 163 ++++++--- app/util.c | 66 ++++ oocd/board/stm32f407vet6.cfg | 4 + oocd/interface/j-link.cfg | 3 + 25 files changed, 1712 insertions(+), 174 deletions(-) create mode 100644 app/bits.c create mode 100644 app/dcf77.c create mode 100644 app/events.h create mode 100644 app/gps.c create mode 100644 app/gps.h create mode 100644 app/hexdump.c create mode 100644 app/stats.c create mode 100644 app/ubx.h create mode 100644 app/util.c create mode 100644 oocd/board/stm32f407vet6.cfg diff --git a/.gitignore b/.gitignore index 09e26f4..ac3f06d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ *.hex *.map .*.swp +almanac.c +almanac.alp diff --git a/Makefile.include b/Makefile.include index 1288fe0..7a60f2f 100644 --- a/Makefile.include +++ b/Makefile.include @@ -29,8 +29,10 @@ ARCH_FLAGS = -mthumb -mcpu=cortex-m4 $(FP_FLAGS) # OpenOCD specific variables OOCD ?= openocd -OOCD_INTERFACE ?= cmsis-dap -OOCD_BOARD ?= arch_max +#OOCD_INTERFACE ?= cmsis-dap +#OOCD_BOARD ?= arch_max +OOCD_INTERFACE ?= j-link +OOCD_BOARD ?= stm32f407vet6 ################################################################################ # Black Magic Probe specific variables diff --git a/app/Makefile b/app/Makefile index e5d6731..dd4b6e7 100644 --- a/app/Makefile +++ b/app/Makefile @@ -25,8 +25,11 @@ 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 -HSRCS=project.h ring.h pins.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 debug_eth.c +HSRCS=project.h ring.h pins.h gps.h ubx.h + + + LWIP=lwip/lwip-1.4.1 LWIP_PATH=.. @@ -55,12 +58,12 @@ BINARY = ${PROG} MYOBJS = ${CSRCS:%.c=%.o} LWIP_OBJS = ${LWIP_CSRCS:%.c=%.o} -objs:${OBJS} +objs:${OBJS} ${MYOBJS}: project.h prototypes.h ${LWIP_OBJS}: lwip/lwipopts.h -OBJS=${MYOBJS} ${LWIP_OBJS} +OBJS=${MYOBJS} ${LWIP_OBJS} almanac.o include ../Makefile.include @@ -78,19 +81,29 @@ program: ${PROG}.hex ds: $(Q)$(OOCD) -f ../oocd/interface/$(OOCD_INTERFACE).cfg \ - -f ../oocd/board/$(OOCD_BOARD).cfg + -f ../oocd/board/$(OOCD_BOARD).cfg debug: ${PROG}.elf ${PREFIX}-gdb -x gdb.script ${PROG}.elf # openocd -protos: ${CSRCS} +protos: ${CSRCS} echo -n > prototypes.h ${CPROTO} -E "${CPP} $(CPPFLAGS)" -e -v ${CSRCS} > prototypes.h.tmp mv -f prototypes.h.tmp prototypes.h -EXTRA_CLEAN=${OBJS} ${LWIP_OBJS:%.o=%.d} +almanac.c:almanac.alp + echo const > $@ + xxd -i $< >> $@ + +almanac.alp: almanac + +almanac: + wget -O almanac.alp http://alp.u-blox.com/current_7d.alp + + +EXTRA_CLEAN=${OBJS} ${LWIP_OBJS:%.o=%.d} almanac.c tidy: astyle -A3 -s2 --attach-extern-c -L -c -w -Y -m0 -f -p -H -U -k3 -xj -xd ${CSRCS} ${HSRCS} diff --git a/app/bits.c b/app/bits.c new file mode 100644 index 0000000..03d5c31 --- /dev/null +++ b/app/bits.c @@ -0,0 +1,22 @@ +#include "project.h" + +void dump_bits(char *wot,uint8_t *bits) +{ +char buf[128]; +char *ptr=buf; +unsigned i=60; + + +ptr+=sprintf(buf,"%s bits: ",wot); + + +while (i--) +*(ptr++)=*(bits++) ? '1':'0'; + + +*(ptr++)='\r'; +*(ptr++)='\n'; +*ptr=0; +usart1_write(buf,(unsigned) (ptr-buf),1); + +} diff --git a/app/dcf77.c b/app/dcf77.c new file mode 100644 index 0000000..edc152b --- /dev/null +++ b/app/dcf77.c @@ -0,0 +1,186 @@ +#include "project.h" + +#define P1 (GPIO11) +#define P1_PORT GPIOD + +#define T (GPIO12) +#define T_PORT GPIOD + + +static Event_ring dcf77_ring; + + +uint64_t dcf77_last_second; + +void exti15_10_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); + + 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); +} + + + + +static uint8_t bits[60]; + +static int time_known; + +static void process_bits (uint64_t abs) +{ + UTC u; + EPOCH dcf77_time; + + + if (bits[0]) return; + + if (!bits[20]) return; + + if (!check_parity (bits, 21, 27, bits[28])) return; + + if (!check_parity (bits, 29, 34, bits[35])) return; + + if (!check_parity (bits, 36, 57, bits[58])) return; + + u.jday = 0; + u.year = le_bcd (bits, 50, 57); + u.month = le_bcd (bits, 45, 49); + u.mday = bcd (bits, 36, 41); + u.hour = bcd (bits, 29, 34); + u.minute = bcd (bits, 21, 27); + u.second = 58; + u.nanosecond = 0; + + + dcf77_time = time_utc_to_epoch (u); + dcf77_time.s -= 58; + +#if 0 + pll_set_offset (dcf77_time, abs); +#endif + time_known = 1; + + 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); + + dump_bits("dcf77",bits); +} + + +static void report_bit (uint64_t abs, int second, int b) +{ + if ((second < 0) || (second > 58)) return; + + bits[second] = b; + + // printf("DCF77: bits[%d]=%d\r\n",second,b); + + if (second == 58) process_bits (abs); + +} + +static void report_time (uint64_t abs) +{ +#if 0 + EPOCH e = pll_decompose (abs); + time_print_epoch ("DCF77: ", e); +#endif +} + + +void dcf77_dispatch (void) +{ + static uint32_t last_0, last_1, last_s; + static int second, bit, had_m; + uint32_t pulse_w, offset; + static uint64_t abs; + int is_s = 0; + + uint32_t now; + int v; + + + + + if (dcf77_ring.rx_ptr == dcf77_ring.tx_ptr) return; + + v = dcf77_ring.events[dcf77_ring.rx_ptr].value; + now = dcf77_ring.events[dcf77_ring.rx_ptr].when; + + dcf77_ring.rx_ptr = (dcf77_ring.rx_ptr + 1) & ERING_MASK; + + if (v) { + pulse_w = now - last_0; + pulse_w /= (HZ / 1000); + + last_1 = now; + + if (pulse_w > 300) { + last_s = now; + is_s = 1; + second++; + } + + if (pulse_w > 1300) { + had_m = 1; + second = 0; + } + + } else { + pulse_w = now - last_1; + pulse_w /= (HZ / 1000); + + if (pulse_w > 150) + bit = 1; + else + bit = 0; + + if (had_m) + report_bit (abs, second, bit); + + last_0 = now; + } + + offset = now - last_s; + offset /= (HZ / 1000); + + if (is_s) { + abs = abs_extend (now); + dcf77_last_second = abs; + + //pll_dispatch (abs); + + if (time_known) + report_time (abs); + } + + +} + + + +void +dcf77_init (void) +{ + MAP_INPUT (T); + MAP_OUTPUT_PP (P1); + + 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); +} + + diff --git a/app/events.h b/app/events.h new file mode 100644 index 0000000..eb0fe89 --- /dev/null +++ b/app/events.h @@ -0,0 +1,14 @@ +#define ERING_SIZE 16 +#define ERING_MASK (ERING_SIZE -1) + +typedef struct { + uint32_t when; + int value; +} Event; + + +typedef struct { + Event events[ERING_SIZE]; + uint32_t rx_ptr,tx_ptr; +} Event_ring; + diff --git a/app/gps.c b/app/gps.c new file mode 100644 index 0000000..9fc60de --- /dev/null +++ b/app/gps.c @@ -0,0 +1,839 @@ +#include "project.h" + +#define PPS (GPIO2) +#define PPS_PORT GPIOD + +#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; + +int gps_locked; +int gps_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; + + +void exti2_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); + + 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); + +} + + + +static inline int +ubx_recv_byte (uint8_t *v) +{ + return !ring_read_byte (&rx3_ring, v); +} + +static inline void +ubx_send_byte (uint8_t v) +{ + usart3_queue (v); +} + +static int +ubx_recv_nav_status (uint8_t *ptr, unsigned len) +{ + uint8_t gps_fix, flags; + 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 + + + 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; + 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); + +// printf ("gps %02d:%02d:%02d %09d\r\n", (int) hour, (int) min, (int) sec, (int) nano); + +#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_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; + + 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 5: + ubx_ack++; + printf (" %s for %02x.%02x\r\n", id ? "ACK" : "NAK", payload[0], + payload[1]); + + break; + + case 0x0b: + switch (id) { + 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]; + uint64_t abs; + uint32_t now; + 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; + + gps_ring.rx_ptr = (gps_ring.rx_ptr + 1) & ERING_MASK; + + + if (!v) return; + + + + abs = abs_extend (now); + pll_dispatch(abs); + + e = pll_decompose (abs); + + u=time_epoch_to_utc(e); + + printf ("GPS %02d:%02d:%02d.%09d Fix:%c%c TXCO %+8dE-12\r\n", + u.hour, + u.minute, + u.second, + u.nanosecond, + fix,fix2,(int) freq); + + +} + + +void +gps_dispatch (void) +{ + ubx_dispatch_search (-1, -1, NULL); + gps_pps_dispatch(); +} + +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); + +} + +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"); + usart3_drain(); + ubx_send (class, id, payload, len); + timeout = ticks + TIMEOUT; + } + + + + + gps_dispatch(); + } + + return 0; +} + +int +ubx_handshake_xfer (uint8_t class, uint8_t id, const void *payload, + unsigned len) +{ + uint32_t timeout; + + ubx_ack_xfer = 0; +// usart3_drain(); + ubx_send (class, id, payload, len); + + + + timeout = ticks + TIMEOUT; + + while (!ubx_ack_xfer) { + + if (ticks > timeout) { + printf ("GPS timeout resending packet\r\n"); +// usart3_drain(); + ubx_send (class, id, payload, len); + timeout = ticks + TIMEOUT; + } + + + + + gps_dispatch(); + } + + return 0; +} + + + + +uint8_t * +ubx_fetch (uint8_t class, uint8_t id, void *payload, unsigned len, + unsigned *len_ptr) +{ + uint8_t *ret; + + while (!ring_empty (&tx3_ring) || !ring_empty (&rx3_ring)) + gps_dispatch(); + + ubx_send (class, id, payload, len); + + while (! (ret = ubx_dispatch_search (class, id, len_ptr))); + + + return ret; +} + +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)); +} + + +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; +} + + +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); //reserved + 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, 500000 / ref_hz); //pulse width unlocked/us + ptr += ubx_put_u32 (ptr, 500000 / 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, 0xf3); +#endif + + + ret = ubx_handshake (0x06, 0x31, buf, (unsigned) (ptr - buf)); + + return ret; +} + + +int +gps_init (void) +{ + uint8_t buf[80], *ptr; + unsigned len; + uint16_t u2; + + usart3_drain(); + + while (!ring_empty (&tx3_ring) || !ring_empty (&rx3_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 + 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 1 +ptr = buf; + ptr += ubx_put_u16 (ptr, 0x14); + 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"); + + ubx_fetch (0x06, 0x31, NULL, 0, &len); + + printf ("configured GNSS 6.31\r\n"); + +#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 (0x03, 0x0a, 0); + //ubx_set_message_rate_port1 (0x03, 0x10, 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 + +#if 1 +ptr = buf; + ptr += ubx_put_u8 (ptr, 0x1); + ptr += ubx_put_u8 (ptr, 0x7); + ptr += ubx_put_u8 (ptr, 0x1); + ptr += ubx_put_u8 (ptr, 0xf); + ptr += ubx_put_u32 (ptr, 0xffffffff); + ubx_handshake (0x06, 0x16, buf, (unsigned) (ptr - buf)); + + printf ("configured SBAS\r\n"); + + ubx_handshake (0x06, 0x16, buf, 0); +#endif + + + // printf ("GPS ready\r\n"); + // ubx_get_clock_stats(); + + 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); + + return 0; +} + + +#define ALMANAC_LUMP 128 + +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_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); +usart3_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); + +} + +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; +} diff --git a/app/gps.h b/app/gps.h new file mode 100644 index 0000000..ce6ee14 --- /dev/null +++ b/app/gps.h @@ -0,0 +1,11 @@ +extern int gps_happy; + +static inline int gps_is_happy (void) +{ + return gps_happy > 15; +} +static inline int gps_is_stable (void) +{ + return gps_happy > 60; +} + diff --git a/app/hexdump.c b/app/hexdump.c new file mode 100644 index 0000000..83f02ea --- /dev/null +++ b/app/hexdump.c @@ -0,0 +1,57 @@ +#include "project.h" + +void +hexdump (void *_d, int len) +{ + uint8_t *d = (uint8_t *) _d; + int i, j, k; + int e; + + if (!d || len < 0) + return; + + e = len + 15; + e &= ~15; + + for (i = 0; i < e; i += 16) { + usart1_drain(); + printf (" %05x:", i); + + for (j = 0; j < 16; ++j) { + k = i + j; + + if (k < len) + printf (" %02x", d[k]); + else + printf (" "); + + if (j == 7) + printf (" "); + } + + printf (" "); + + for (j = 0; j < 16; ++j) { + k = i + j; + + if (k < len) { + uint8_t c = d[k]; + + if (c < 33) + c = '.'; + + if (c > 126) + c = '.'; + + printf ("%c", c); + } + + if (j == 7) + printf (" "); + } + + printf ("\r\n"); + } + + usart1_drain(); +} diff --git a/app/lwip/lwipopts.h b/app/lwip/lwipopts.h index e535e59..3358cad 100644 --- a/app/lwip/lwipopts.h +++ b/app/lwip/lwipopts.h @@ -29,6 +29,8 @@ #define MTU 1500 +#define ICMP_TTL 64 + #if 0 #define ICMP_DEBUG LWIP_DBG_ON #define UDP_DEBUG LWIP_DBG_ON @@ -156,11 +158,11 @@ The STM32F4x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums */ /* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/ -#define CHECKSUM_GEN_IP 0 +#define CHECKSUM_GEN_IP 1 /* CHECKSUM_GEN_UDP==0: Generate checksums by hardware for outgoing UDP packets.*/ -#define CHECKSUM_GEN_UDP 0 +#define CHECKSUM_GEN_UDP 1 /* CHECKSUM_GEN_TCP==0: Generate checksums by hardware for outgoing TCP packets.*/ -#define CHECKSUM_GEN_TCP 0 +#define CHECKSUM_GEN_TCP 1 /* CHECKSUM_CHECK_IP==0: Check checksums by hardware for incoming IP packets.*/ #define CHECKSUM_CHECK_IP 1 /* CHECKSUM_CHECK_UDP==0: Check checksums by hardware for incoming UDP packets.*/ diff --git a/app/lwip_glue.c b/app/lwip_glue.c index 6c66de8..3771c38 100644 --- a/app/lwip_glue.c +++ b/app/lwip_glue.c @@ -67,7 +67,7 @@ void start_lwip (void) lwip_init(); - IP4_ADDR (&ipaddr, 10, 32, 48, 99); + IP4_ADDR (&ipaddr, 10, 32, 48, 98); IP4_ADDR (&netmask, 255, 255, 255, 0); IP4_ADDR (&gw, 10, 32, 48, 1); diff --git a/app/main.c b/app/main.c index 48828c8..368839c 100644 --- a/app/main.c +++ b/app/main.c @@ -1,6 +1,26 @@ #include "project.h" +static void cmd_dispatch() +{ +uint8_t c; +while (!ring_read_byte(&rx1_ring,&c)) { + + printf("KEY> %c\r\n",c); + +switch(c) { + + case 'R': + gps_reset (); + break; + case 'A': + gps_almanac (); + break; +} +} +} + + static void board_setup (void) { @@ -10,13 +30,17 @@ board_setup (void) rcc_periph_clock_enable (RCC_GPIOB); rcc_periph_clock_enable (RCC_GPIOC); rcc_periph_clock_enable (RCC_GPIOD); - rcc_periph_clock_enable (RCC_USART6); + rcc_periph_clock_enable (RCC_USART1); + rcc_periph_clock_enable (RCC_USART3); + rcc_periph_clock_enable (RCC_SYSCFG); - nvic_set_priority (NVIC_EXTI0_IRQ, 0); - nvic_set_priority (NVIC_EXTI15_10_IRQ, 1); - nvic_set_priority (NVIC_USART6_IRQ, 2); - nvic_set_priority (NVIC_ETH_IRQ, 3); - nvic_set_priority (NVIC_SYSTICK_IRQ, 4) ; + + nvic_set_priority (NVIC_EXTI2_IRQ, 0); + nvic_set_priority (NVIC_EXTI0_IRQ, 1); + nvic_set_priority (NVIC_EXTI15_10_IRQ, 2); + nvic_set_priority (NVIC_USART1_IRQ, 3); + nvic_set_priority (NVIC_ETH_IRQ, 4); + nvic_set_priority (NVIC_SYSTICK_IRQ, 5) ; } @@ -32,9 +56,13 @@ system_init (void) msf_init(); dcf77_init(); + printf ("LWIP\r\n"); start_lwip(); + printf ("STETH\r\n"); steth_init(); + //gps_init(); + } int @@ -48,8 +76,12 @@ main (void) while (1) { - msf_dispatch(); - dcf77_dispatch(); +// msf_dispatch(); +// dcf77_dispatch(); + + //gps_dispatch(); + + cmd_dispatch(); dispatch_lwip(); steth_dispatch(); diff --git a/app/msf.c b/app/msf.c index 2e7dd93..241998e 100644 --- a/app/msf.c +++ b/app/msf.c @@ -95,6 +95,8 @@ static void process_bits (uint64_t abs) time_known = 1; stats_stamp (u, 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); @@ -171,7 +173,7 @@ void msf_dispatch (void) abs = abs_extend (now); msf_last_second = abs; - pll_dispatch (abs); + //pll_dispatch (abs); diff --git a/app/pins.h b/app/pins.h index 16da24c..723ca82 100644 --- a/app/pins.h +++ b/app/pins.h @@ -1,4 +1,9 @@ +#define MAP_AF_100(a, af) do { \ + gpio_mode_setup( a ## _PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, a ); \ + gpio_set_output_options( a ## _PORT, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, a); \ + gpio_set_af( a ## _PORT, af, a); \ + } while (0) #define MAP_AF(a, af) do { \ gpio_mode_setup( a ## _PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, a ); \ @@ -24,10 +29,14 @@ gpio_set_output_options( a ## _PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, a); \ } while (0) +#define MAP_OUTPUT_PP_PU(a) do { \ + gpio_mode_setup( a ## _PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, a ); \ + gpio_set_output_options( a ## _PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, a); \ + } while (0) #define MAP_OUTPUT_OD(a) do { \ gpio_mode_setup( a ## _PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, a ); \ - gpio_set_output_options( a ## _PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, a); \ + gpio_set_output_options( a ## _PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, a); \ } while (0) diff --git a/app/pll.c b/app/pll.c index 03d214c..742aad0 100644 --- a/app/pll.c +++ b/app/pll.c @@ -2,8 +2,8 @@ #define JUMP_THRESH 0.1 #define JUMP_TICKS 30 -#define FEEDBACK 0.000001 -#define WARM_UP 30 +#define FEEDBACK 0.01 +#define WARM_UP 3 static int64_t offset; diff --git a/app/project.h b/app/project.h index 013ceea..f3a49f1 100644 --- a/app/project.h +++ b/app/project.h @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include @@ -36,10 +36,18 @@ #include "events.h" #include "ring.h" +#include "ubx.h" +#include "gps.h" #include "prototypes.h" //#define HZ 168000000 -#define HZ 167968615 +//#define HZ 167968615 +//#define HZ 165925490 +#define HZ 167996682 #define TRACE do { stdio_drain(); printf("%s:%d\r\n",__FUNCTION__,__LINE__); } while (0) + +extern const unsigned char almanac_alp[]; +extern unsigned int almanac_alp_len; + diff --git a/app/prototypes.h b/app/prototypes.h index 8675022..48ad192 100644 --- a/app/prototypes.h +++ b/app/prototypes.h @@ -16,12 +16,18 @@ 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 rx6_ring; -extern volatile ring_t tx6_ring; -extern void usart6_isr(void); -extern void usart6_queue(uint8_t d); -extern void usart6_drain(void); -extern int usart6_write(char *ptr, int len, int blocking); +extern volatile ring_t rx3_ring; +extern volatile ring_t tx3_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 usart1_isr(void); +extern void usart1_queue(uint8_t d); +extern void usart1_drain(void); +extern int usart1_write(char *ptr, int len, int blocking); extern void usart_init(void); /* stdio.c */ extern int _open(const char *name, int flags, int mode); @@ -82,3 +88,23 @@ extern unsigned le_bcd(uint8_t *d, unsigned s, unsigned e); /* stats.c */ extern void stats(void); extern void stats_stamp(UTC m, uint64_t abs); +/* gps.c */ +extern int gps_locked; +extern int gps_happy; +extern void exti2_isr(void); +extern void gps_dispatch(void); +extern void ubx_send(uint8_t class, uint8_t id, const void *_payload, unsigned len); +extern int ubx_handshake(uint8_t class, uint8_t id, const void *payload, unsigned len); +extern int ubx_handshake_xfer(uint8_t class, uint8_t id, const void *payload, unsigned len); +extern uint8_t *ubx_fetch(uint8_t class, uint8_t id, void *payload, unsigned len, unsigned *len_ptr); +extern int ubx_set_message_rate_port1(uint8_t class, uint8_t id, uint8_t rate); +extern int ubx_cfg_rst(uint16_t flags); +extern int gps_set_ref(int ref_hz); +extern int gps_init(void); +extern int gps_almanac(void); +extern void gps_reset(void); +extern int ubx_get_clock_stats(void); +/* hexdump.c */ +extern void hexdump(void *_d, int len); +/* bits.c */ +extern void dump_bits(char *wot, uint8_t *bits); diff --git a/app/stats.c b/app/stats.c new file mode 100644 index 0000000..dfed017 --- /dev/null +++ b/app/stats.c @@ -0,0 +1,44 @@ +#include "project.h" + + +void stats (void) +{ + int64_t d; + EPOCH e; + UTC m, g; + float ms; + + d = msf_last_second; + d -= (int64_t) dcf77_last_second; + + g = time_epoch_to_utc (pll_decompose (dcf77_last_second)); + m = time_epoch_to_utc (pll_decompose (msf_last_second)); + e = pll_decompose_diff (d); + + ms = (float) e.ns; + ms = ms / 1000000.0; + + printf ("MSF %02d:%02d:%02d.%09d %02d.%09d %+.6f ms %u\r\n", + m.hour, + m.minute, + m.second, + m.nanosecond, + g.second, + g.nanosecond, + ms, + (unsigned) pll_freq); + +} +void stats_stamp (UTC m, uint64_t abs) +{ + uint32_t v, w; + v = msf_last_second & 0xffffffff; + w = msf_last_second >> 32; + + printf ("STAMP: %02d:%02d:%02d %08x`%08x\r\n", m.hour, + m.minute, + m.second, + w, v); + + +} diff --git a/app/stdio.c b/app/stdio.c index 286d4d2..4a46f3f 100644 --- a/app/stdio.c +++ b/app/stdio.c @@ -27,7 +27,7 @@ _write (int file, int ret; - ret = usart6_write (buf, nbytes, 1); + ret = usart1_write (buf, nbytes, 1); if (ret < 0) { errno = -ret; @@ -77,5 +77,5 @@ isatty (int file) void stdio_drain (void) { - usart6_drain(); + usart1_drain(); } diff --git a/app/steth.c b/app/steth.c index d7eea7e..8672163 100644 --- a/app/steth.c +++ b/app/steth.c @@ -3,6 +3,9 @@ #define PHY PHY0 +#define RXER GPIO10 +#define RXER_PORT GPIOB + #define TXEN GPIO11 #define TXEN_PORT GPIOB @@ -53,6 +56,80 @@ extern uint32_t TxBD; extern uint32_t RxBD; +static void mac_stat(void) +{ + uint32_t d, s; + + printf ("Net:\r\n"); + printf (" ETH_MACCR: %08" PRIx32 "\r\n", ETH_MACCR); +#if 0 + printf (" ETH_MACFFR: %08" PRIx32 "\r\n", ETH_MACFFR); + printf (" ETH_MACFCR: %08" PRIx32 "\r\n", ETH_MACFCR); + printf (" ETH_MACDBGR: %08" PRIx32 "\r\n", ETH_MACDBGR); + printf (" ETH_MACSR: %08" PRIx32 "\r\n", ETH_MACSR); +#endif + printf (" ETH_DMAOMR: %08" PRIx32 "\r\n", ETH_DMAOMR); + printf (" ETH_DMASR: %08" PRIx32 " ebs=%x tps=%x rps=%x\r\n", ETH_DMASR, + (ETH_DMASR >>23) & 7 , + (ETH_DMASR >>20) & 7 , + (ETH_DMASR >>17) & 7 ); + printf (" ETH_DMAIER: %08" PRIx32 "\r\n", ETH_DMAIER); + printf (" ETH_DMACHTDR: %08" PRIx32 "\r\n", ETH_DMACHTDR); + printf (" ETH_DMACHRDR: %08" PRIx32 "\r\n", ETH_DMACHRDR); + printf (" ETH_DMAOMR: %08" PRIx32 "\r\n", ETH_DMAOMR); + printf (" ETH_DMATDLAR: %08" PRIx32 "\r\n", ETH_DMATDLAR); + printf (" ETH_DMARDLAR: %08" PRIx32 "\r\n", ETH_DMARDLAR); + printf (" ETH_DMABMR: %08" PRIx32 "\r\n", ETH_DMABMR); + + s = d = RxBD; + + +if (running) + do { + printf (" %08" PRIx32 ": %08" PRIx32 " %08" PRIx32 " %08" PRIx32 " %08" + PRIx32 "\r\n", d, ETH_DES0 (d), ETH_DES1 (d), ETH_DES2 (d), + ETH_DES3 (d)); + + d = ETH_DES3 (d); + + } while (d != s); + +} + +static void phy_stat_reg(unsigned i) +{ +static uint16_t last_phy[0x20]; +uint16_t cur=eth_smi_read(PHY,i); + +if (cur==last_phy[i]) return; + +printf(" phy:%02x %4x (was %4x +%4x -%4x)\r\n", + i,(unsigned) cur,(unsigned) last_phy[i], + (unsigned) ((last_phy[i] ^ cur) & cur), + (unsigned) ((last_phy[i] ^ cur) & last_phy[i])); + +last_phy[i]=cur; +} + +static void phy_stat(void) +{ + phy_stat_reg(0x0); + phy_stat_reg(0x1); + phy_stat_reg(0x4); + phy_stat_reg(0x5); + phy_stat_reg(0x6); + phy_stat_reg(0x11); + phy_stat_reg(0x12); + phy_stat_reg(0x1f); + + + + + +} + + + bool phy_link_an_done (uint8_t phy) @@ -110,6 +187,8 @@ steth_rx (void) struct pbuf *p; uint32_t len; +//printf("Packet\r\n"); + #if 0 struct pbuf *q; static uint8_t rx_buf[FRAME_SZ]; @@ -236,94 +315,112 @@ steth_init (void) { unsigned i; - MAP_AF (TXEN, GPIO_AF11); - MAP_AF (TXD0, GPIO_AF11); - MAP_AF (TXD1, GPIO_AF11); - - MAP_AF (RXD0, GPIO_AF11); - MAP_AF (RXD1, GPIO_AF11); - - MAP_AF (CRS_DV, GPIO_AF11); + rcc_periph_clock_enable (RCC_GPIOA); + rcc_periph_clock_enable (RCC_GPIOB); + rcc_periph_clock_enable (RCC_GPIOC); + rcc_periph_clock_enable (RCC_SYSCFG); + rcc_periph_clock_enable (RCC_ETHMAC); + rcc_periph_clock_enable (RCC_ETHMACTX); + rcc_periph_clock_enable (RCC_ETHMACRX); + rcc_periph_clock_enable (RCC_ETHMACPTP); - MAP_INPUT_PU(MDC); + rcc_periph_reset_hold(RST_ETHMAC); + delay_ms(1); - MAP_AF_PU (MDIO, GPIO_AF11); - MAP_AF_PU (MDC, GPIO_AF11); +#ifndef SYSCFG_PMC_MII_RMII_SEL +#define SYSCFG_PMC_MII_RMII_SEL (1UL << 23) +#endif - MAP_AF (REF_CLK, GPIO_AF11); + SYSCFG_PMC |= SYSCFG_PMC_MII_RMII_SEL; + delay_ms(1); + rcc_periph_reset_release(RST_ETHMAC); MAP_OUTPUT_PP (NRST); + MAP_OUTPUT_PP (RXD0 ); + MAP_OUTPUT_PP (RXD1 ); + MAP_OUTPUT_PP (CRS_DV ); + + SET(RXD0); + SET(RXD1); + SET(CRS_DV); CLEAR(NRST); delay_ms(1); SET (NRST); -TRACE; + MAP_AF_100 (REF_CLK, GPIO_AF11); + MAP_AF_100 (MDIO, GPIO_AF11); + MAP_AF_100 (CRS_DV, GPIO_AF11); - /* The switch to RMII has be done with steth under reset, with no clock */ + MAP_AF_100(RXER,GPIO_AF11); + MAP_AF_100(TXEN,GPIO_AF11); + MAP_AF_100(TXD0,GPIO_AF11); + MAP_AF_100(TXD1,GPIO_AF11); - rcc_periph_clock_enable (RCC_APB2ENR_SYSCFGEN); + MAP_AF_100 (MDC, GPIO_AF11); + MAP_AF_100 (RXD0, GPIO_AF11); + MAP_AF_100 (RXD1, GPIO_AF11); - RCC_AHB1RSTR |= RCC_AHB1RSTR_ETHMACRST; /*Assert RESET */ -#if 0 - rcc_periph_clock_disable (RCC_ETHMACPTP); - rcc_periph_clock_disable (RCC_ETHMACRX); - rcc_periph_clock_disable (RCC_ETHMACTX); - rcc_periph_clock_disable (RCC_ETHMAC); -#endif + /* The switch to RMII has be done with steth under reset, with no clock */ - delay_us (1); + rcc_periph_reset_hold(RST_ETHMAC); + delay_ms(1); #ifndef SYSCFG_PMC_MII_RMII_SEL #define SYSCFG_PMC_MII_RMII_SEL (1UL << 23) #endif SYSCFG_PMC |= SYSCFG_PMC_MII_RMII_SEL; + delay_ms(1); + rcc_periph_reset_release(RST_ETHMAC); -TRACE; - RCC_AHB1RSTR &= ~RCC_AHB1RSTR_ETHMACRST; /*De-sssert RESET */ - - - rcc_periph_clock_enable (RCC_ETHMAC); - rcc_periph_clock_enable (RCC_ETHMACTX); - rcc_periph_clock_enable (RCC_ETHMACRX); - rcc_periph_clock_enable (RCC_ETHMACPTP); - - delay_ms (10); ETH_DMABMR|=1; - delay_ms (10); - -TRACE; - eth_desc_init (eth_buf, TX_BUFS, RX_BUFS, FRAME_SZ, FRAME_SZ, 1); -TRACE; - for (i=0;i<32;++i) { - printf("phy:%x %x\r\n",i,eth_smi_read(PHY,i)); + TRACE; + while (ETH_DMABMR & 1) { + mac_stat(); + delay_ms(1000); } +TRACE; /*MDC = HCLK / 102 (0b100) => 1.6MHz */ - eth_init (PHY, 0x4); TRACE; -// eth_init (PHY, 0x14); -TRACE; - eth_enable_checksum_offload(); -TRACE; - - eth_set_mac (sa); + phy_stat(); +#if 0 +// eth_smi_write (PHY, PHY_REG_BCR, 0x2100); printf ("Waiting for link\r\n"); - while (!phy_link_isup (PHY)); - + while (!phy_link_isup (PHY)) { + phy_stat(); + delay_ms(1000); + } +#else + eth_smi_write (PHY, PHY_REG_ANTX, 0x1e1); phy_autoneg_enable (PHY); printf ("Waiting for autonegociation\r\n"); - while (!phy_link_an_done (PHY)); +i=0; + while (!phy_link_an_done (PHY)) { + phy_stat(); + delay_ms(1000); + + +#if 0 +if (i>4) { + phy_autoneg_enable (PHY); + i=0; +} +#endif +i++; + + } +#endif switch (phy_link_status (PHY)) { case LINK_HD_10M: @@ -353,6 +450,15 @@ TRACE; ; } +TRACE; + eth_set_mac (sa); +TRACE; + eth_enable_checksum_offload(); +TRACE; + eth_desc_init (eth_buf, TX_BUFS, RX_BUFS, FRAME_SZ, FRAME_SZ, 1); +TRACE; + + ETH_MACCR &= ~ETH_MACCR_RD; @@ -367,6 +473,7 @@ TRACE; running++; + nvic_enable_irq (NVIC_ETH_IRQ); printf ("Running\r\n"); @@ -376,57 +483,9 @@ TRACE; void steth_dispatch (void) { -#if 1 - uint32_t d, s; -#endif if (!running) return; -#if 1 - printf ("Net:\r\n"); - printf (" ETH_MACCR: %08" PRIx32 "\r\n", ETH_MACCR); -#if 0 - printf (" ETH_MACFFR: %08" PRIx32 "\r\n", ETH_MACFFR); - printf (" ETH_MACFCR: %08" PRIx32 "\r\n", ETH_MACFCR); - printf (" ETH_MACDBGR: %08" PRIx32 "\r\n", ETH_MACDBGR); - printf (" ETH_MACSR: %08" PRIx32 "\r\n", ETH_MACSR); -#endif - printf (" ETH_DMAOMR: %08" PRIx32 "\r\n", ETH_DMAOMR); - printf (" ETH_DMASR: %08" PRIx32 " ebs=%x tps=%x rps=%x\r\n", ETH_DMASR, - (ETH_DMASR >>23) & 7 , - (ETH_DMASR >>20) & 7 , - (ETH_DMASR >>17) & 7 ); - printf (" ETH_DMAIER: %08" PRIx32 "\r\n", ETH_DMAIER); - printf (" ETH_DMACHTDR: %08" PRIx32 "\r\n", ETH_DMACHTDR); - printf (" ETH_DMACHRDR: %08" PRIx32 "\r\n", ETH_DMACHRDR); - printf (" ETH_DMAOMR: %08" PRIx32 "\r\n", ETH_DMAOMR); - printf (" ETH_DMATDLAR: %08" PRIx32 "\r\n", ETH_DMATDLAR); - printf (" ETH_DMARDLAR: %08" PRIx32 "\r\n", ETH_DMARDLAR); - printf (" ETH_DMABMR: %08" PRIx32 "\r\n", ETH_DMABMR); - - - s = d = RxBD; - - - do { - printf (" %08" PRIx32 ": %08" PRIx32 " %08" PRIx32 " %08" PRIx32 " %08" - PRIx32 "\r\n", d, ETH_DES0 (d), ETH_DES1 (d), ETH_DES2 (d), - ETH_DES3 (d)); - - d = ETH_DES3 (d); - - } while (d != s); - -#endif - -{ -int i; -for (i=0;i<1000;++i) { -delay_ms(1); - steth_isr(); -} - -} } diff --git a/app/ubx.h b/app/ubx.h new file mode 100644 index 0000000..44c4782 --- /dev/null +++ b/app/ubx.h @@ -0,0 +1,56 @@ +static inline int +ubx_get_u8 (uint8_t *ptr, uint8_t *v) +{ + *v = *ptr; + return 1; +} + +static inline int +ubx_get_u16 (uint8_t *ptr, uint16_t *v) +{ + memcpy (v, ptr, sizeof (*v)); + return sizeof (*v); +} + +static inline int +ubx_get_u32 (uint8_t *ptr, uint32_t *v) +{ + memcpy (v, ptr, sizeof (*v)); + return sizeof (*v); +} + +static inline int +ubx_get_i32 (uint8_t *ptr, int32_t *v) +{ + memcpy (v, ptr, sizeof (*v)); + return sizeof (*v); +} + + +static inline int +ubx_put_u8 (uint8_t *ptr, uint8_t v) +{ + *ptr = v; + return sizeof (v); +} + +static inline int +ubx_put_u16 (uint8_t *ptr, uint16_t v) +{ + memcpy (ptr, &v, sizeof (v)); + return sizeof (v); +} + +static inline int +ubx_put_u32 (uint8_t *ptr, uint32_t v) +{ + memcpy (ptr, &v, sizeof (v)); + return sizeof (v); +} + +static inline int +ubx_put_i32 (uint8_t *ptr, int32_t v) +{ + memcpy (ptr, &v, sizeof (v)); + return sizeof (v); +} diff --git a/app/usart.c b/app/usart.c index 9b2a454..e826a22 100644 --- a/app/usart.c +++ b/app/usart.c @@ -3,68 +3,135 @@ #define BUFFER_SIZE 256 #define BIG_BUFFER_SIZE 600 -volatile ring_t rx6_ring; -static uint8_t rx6_ring_buf[BUFFER_SIZE]; -volatile ring_t tx6_ring; -static uint8_t tx6_ring_buf[BUFFER_SIZE]; +volatile ring_t rx3_ring; +static uint8_t rx3_ring_buf[BUFFER_SIZE]; +volatile ring_t tx3_ring; +static uint8_t tx3_ring_buf[BUFFER_SIZE]; -#define TX6 GPIO6 -#define TX6_PORT GPIOC +volatile ring_t rx1_ring; +static uint8_t rx1_ring_buf[BUFFER_SIZE]; -#define RX6 GPIO7 -#define RX6_PORT GPIOC +volatile ring_t tx1_ring; +static uint8_t tx1_ring_buf[BUFFER_SIZE]; -void usart6_isr (void) +#define TX1 GPIO9 +#define TX1_PORT GPIOA + +#define RX1 GPIO10 +#define RX1_PORT GPIOA + +#define TX3 GPIO10 +#define TX3_PORT GPIOC + +#define RX3 GPIO11 +#define RX3_PORT GPIOC + + +void usart3_isr (void) { uint8_t data; /* Check if we were called because of RXNE. */ - if (((USART_CR1 (USART6) & USART_CR1_RXNEIE) != 0) && - ((USART_SR (USART6) & USART_SR_RXNE) != 0)) { + if (((USART_CR1 (USART3) & USART_CR1_RXNEIE) != 0) && + ((USART_SR (USART3) & USART_SR_RXNE) != 0)) { /* Retrieve the data from the peripheral. */ - data = usart_recv (USART6); + data = usart_recv (USART3); - ring_write_byte (&rx6_ring, data); + ring_write_byte (&rx3_ring, data); + //usart6_queue(data); } /* Check if we were called because of TXE. */ - if (((USART_CR1 (USART6) & USART_CR1_TXEIE) != 0) && - ((USART_SR (USART6) & USART_SR_TXE) != 0)) { + if (((USART_CR1 (USART3) & USART_CR1_TXEIE) != 0) && + ((USART_SR (USART3) & USART_SR_TXE) != 0)) { - if (ring_read_byte (&tx6_ring, &data)) { + if (ring_read_byte (&tx3_ring, &data)) { /*No more data, Disable the TXE interrupt, it's no longer needed. */ - usart_disable_tx_interrupt (USART6); + usart_disable_tx_interrupt (USART3); } else - usart_send_blocking (USART6, data); + usart_send_blocking (USART3, data); } } void -usart6_queue (uint8_t d) +usart3_queue (uint8_t d) { - ring_write_byte (&tx6_ring, d); - usart_enable_tx_interrupt (USART6); + ring_write_byte (&tx3_ring, d); + usart_enable_tx_interrupt (USART3); } void -usart6_drain (void) +usart3_drain (void) { - while (!ring_empty (&tx6_ring)); + while (!ring_empty (&tx3_ring)); } int -usart6_write (char *ptr, int len, int blocking) +usart3_write (char *ptr, int len, int blocking) { int ret; - ret = ring_write (&tx6_ring, (uint8_t *) ptr, len, blocking); - usart_enable_tx_interrupt (USART6); + ret = ring_write (&tx3_ring, (uint8_t *) ptr, len, blocking); + usart_enable_tx_interrupt (USART3); + return ret; +} + + + +void usart1_isr (void) +{ + uint8_t data; + + /* Check if we were called because of RXNE. */ + if (((USART_CR1 (USART1) & USART_CR1_RXNEIE) != 0) && + ((USART_SR (USART1) & USART_SR_RXNE) != 0)) { + + /* Retrieve the data from the peripheral. */ + data = usart_recv (USART1); + + ring_write_byte (&rx1_ring, data); + } + + /* Check if we were called because of TXE. */ + if (((USART_CR1 (USART1) & USART_CR1_TXEIE) != 0) && + ((USART_SR (USART1) & USART_SR_TXE) != 0)) { + + if (ring_read_byte (&tx1_ring, &data)) { + /*No more data, Disable the TXE interrupt, it's no longer needed. */ + usart_disable_tx_interrupt (USART1); + } else + usart_send_blocking (USART1, data); + } + +} + +void +usart1_queue (uint8_t d) +{ + ring_write_byte (&tx1_ring, d); + usart_enable_tx_interrupt (USART1); +} + +void +usart1_drain (void) +{ + while (!ring_empty (&tx1_ring)); +} + + +int +usart1_write (char *ptr, int len, int blocking) +{ + int ret; + + ret = ring_write (&tx1_ring, (uint8_t *) ptr, len, blocking); + usart_enable_tx_interrupt (USART1); return ret; } @@ -73,28 +140,42 @@ void usart_init (void) { - ring_init (&rx6_ring, rx6_ring_buf, sizeof (rx6_ring_buf)); - ring_init (&tx6_ring, tx6_ring_buf, sizeof (tx6_ring_buf)); + ring_init (&rx3_ring, rx3_ring_buf, sizeof (rx3_ring_buf)); + ring_init (&tx3_ring, tx3_ring_buf, sizeof (tx3_ring_buf)); + + MAP_AF (TX3, GPIO_AF7); + MAP_AF_PU (RX3, GPIO_AF7); + + 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); + + usart_enable_rx_interrupt (USART3); - /* Map pins, and set usart2 to have pull ups */ + usart_enable (USART3); - MAP_AF (TX6, GPIO_AF8); - MAP_AF_PU (RX6, GPIO_AF8); + nvic_enable_irq (NVIC_USART3_IRQ); - usart_set_baudrate (USART6, 38400); - usart_set_databits (USART6, 8); - usart_set_stopbits (USART6, USART_STOPBITS_1); - usart_set_parity (USART6, USART_PARITY_NONE); - usart_set_flow_control (USART6, USART_FLOWCONTROL_NONE); - usart_set_mode (USART6, USART_MODE_TX_RX); + ring_init (&rx1_ring, rx1_ring_buf, sizeof (rx1_ring_buf)); + ring_init (&tx1_ring, tx1_ring_buf, sizeof (tx1_ring_buf)); - usart_enable_rx_interrupt (USART6); + MAP_AF (TX1, GPIO_AF7); + MAP_AF_PU (RX1, GPIO_AF7); - /* Finally enable the USARTs. */ - usart_enable (USART6); + usart_set_baudrate (USART1, 38400); + usart_set_databits (USART1, 8); + usart_set_stopbits (USART1, USART_STOPBITS_1); + usart_set_parity (USART1, USART_PARITY_NONE); + usart_set_flow_control (USART1, USART_FLOWCONTROL_NONE); + usart_set_mode (USART1, USART_MODE_TX_RX); - nvic_enable_irq (NVIC_USART6_IRQ); + usart_enable_rx_interrupt (USART1); + usart_enable (USART1); + nvic_enable_irq (NVIC_USART1_IRQ); } diff --git a/app/util.c b/app/util.c new file mode 100644 index 0000000..ff35288 --- /dev/null +++ b/app/util.c @@ -0,0 +1,66 @@ +#include "project.h" + +int check_parity (uint8_t *d, unsigned s, unsigned e, uint8_t p) +{ + unsigned i; + + for (i = s; i <= e; ++i) + p ^= d[i]; + + return !p; +} + + +unsigned bcd (uint8_t *d, unsigned s, unsigned e) +{ + unsigned ret = 0, c, b, i; + + for (i = e, c = 1, b = 0; i >= s; --i, b++) { + + if (d[i]) ret += c; + + + switch (b & 3) { + case 0: + case 1: + case 2: + c <<= 1; + break; + + default: + c >>= 3; + c *= 10; + } + } + + return ret; +} + + + +unsigned le_bcd (uint8_t *d, unsigned s, unsigned e) +{ + unsigned ret = 0, c, b, i; + + for (i = s, c = 1, b = 0; i <= e; ++i, b++) { + + if (d[i]) ret += c; + + + switch (b & 3) { + case 0: + case 1: + case 2: + c <<= 1; + break; + + default: + c >>= 3; + c *= 10; + } + } + + return ret; +} + + diff --git a/oocd/board/stm32f407vet6.cfg b/oocd/board/stm32f407vet6.cfg new file mode 100644 index 0000000..4ba3a0a --- /dev/null +++ b/oocd/board/stm32f407vet6.cfg @@ -0,0 +1,4 @@ + +source [find target/stm32f4x.cfg] + +reset_config srst_only diff --git a/oocd/interface/j-link.cfg b/oocd/interface/j-link.cfg index 3e95768..ab1c025 100644 --- a/oocd/interface/j-link.cfg +++ b/oocd/interface/j-link.cfg @@ -3,3 +3,6 @@ telnet_port 4444 gdb_port 3333 source [find interface/jlink.cfg] + + +transport select swd -- cgit v1.2.3