diff options
| -rw-r--r-- | Makefile.include | 2 | ||||
| -rw-r--r-- | app/Makefile | 39 | ||||
| -rw-r--r-- | app/bits.c | 2 | ||||
| -rw-r--r-- | app/dcf77.c | 89 | ||||
| -rw-r--r-- | app/events.h | 10 | ||||
| -rw-r--r-- | app/gps.c | 316 | ||||
| -rw-r--r-- | app/gps_neo8.c | 1204 | ||||
| -rw-r--r-- | app/led.c | 76 | ||||
| -rw-r--r-- | app/lwip_glue.c | 11 | ||||
| -rw-r--r-- | app/main.c | 160 | ||||
| -rw-r--r-- | app/max7219.c | 143 | ||||
| -rw-r--r-- | app/msf.c | 96 | ||||
| -rw-r--r-- | app/new_almanac.c | 53 | ||||
| -rwxr-xr-x | app/parse_alamanc.pl | 91 | ||||
| -rw-r--r-- | app/pll.c | 2 | ||||
| -rw-r--r-- | app/project.h | 5 | ||||
| -rw-r--r-- | app/prototypes.h | 36 | ||||
| -rw-r--r-- | app/report.c | 15 | ||||
| -rw-r--r-- | app/stdio.c | 4 | ||||
| -rw-r--r-- | app/steth.c | 13 | ||||
| -rw-r--r-- | app/steth.h | 16 | ||||
| -rw-r--r-- | app/ticker.c | 5 | ||||
| -rw-r--r-- | app/time_fn.c | 8 | ||||
| -rw-r--r-- | app/time_fn.h | 4 | ||||
| -rw-r--r-- | app/ubx.h | 8 | ||||
| -rw-r--r-- | app/usart.c | 87 | ||||
| -rw-r--r-- | oocd/board/stm32f407zet6.cfg | 5 | ||||
| -rw-r--r-- | oocd/stm32-f407.cfg | 6 | 
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 @@ -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; -	 + @@ -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 @@ -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); @@ -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 +  } + + + +} + + + + @@ -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; +} +} + + + @@ -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; @@ -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]  | 
