diff options
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | Makefile.include | 6 | ||||
| -rw-r--r-- | app/Makefile | 27 | ||||
| -rw-r--r-- | app/bits.c | 22 | ||||
| -rw-r--r-- | app/dcf77.c | 186 | ||||
| -rw-r--r-- | app/events.h | 14 | ||||
| -rw-r--r-- | app/gps.c | 839 | ||||
| -rw-r--r-- | app/gps.h | 11 | ||||
| -rw-r--r-- | app/hexdump.c | 57 | ||||
| -rw-r--r-- | app/lwip/lwipopts.h | 8 | ||||
| -rw-r--r-- | app/lwip_glue.c | 2 | ||||
| -rw-r--r-- | app/main.c | 48 | ||||
| -rw-r--r-- | app/msf.c | 4 | ||||
| -rw-r--r-- | app/pins.h | 11 | ||||
| -rw-r--r-- | app/pll.c | 4 | ||||
| -rw-r--r-- | app/project.h | 12 | ||||
| -rw-r--r-- | app/prototypes.h | 38 | ||||
| -rw-r--r-- | app/stats.c | 44 | ||||
| -rw-r--r-- | app/stdio.c | 4 | ||||
| -rw-r--r-- | app/steth.c | 255 | ||||
| -rw-r--r-- | app/ubx.h | 56 | ||||
| -rw-r--r-- | app/usart.c | 163 | ||||
| -rw-r--r-- | app/util.c | 66 | ||||
| -rw-r--r-- | oocd/board/stm32f407vet6.cfg | 4 | ||||
| -rw-r--r-- | oocd/interface/j-link.cfg | 3 | 
25 files changed, 1712 insertions, 174 deletions
| @@ -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); @@ -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(); @@ -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); @@ -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) @@ -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 <libopencm3/stm32/spi.h>  #include <libopencm3/stm32/adc.h>  #include <libopencm3/stm32/exti.h> -#include <libopencm3/stm32/ethernet.h> +#include <libopencm3/ethernet/mac_stm32fxx7.h>  #include <libopencm3/ethernet/phy.h>  #include <libopencm3/stm32/syscfg.h>  #include <libopencm3/cm3/systick.h> @@ -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 | 
