summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorroot <root@lab.panaceas.james.local>2019-02-19 13:46:18 +0000
committerroot <root@lab.panaceas.james.local>2019-02-19 13:46:18 +0000
commitb3c6320899d6b27899ab3c67c745e8d3b29af3a2 (patch)
tree41dc7fc5d71a841a416d0d53923de5d1d44277e3
parentc84e85e0e9641b006a376fab456ac2efcfdb14e2 (diff)
downloadclock-b3c6320899d6b27899ab3c67c745e8d3b29af3a2.tar.gz
clock-b3c6320899d6b27899ab3c67c745e8d3b29af3a2.tar.bz2
clock-b3c6320899d6b27899ab3c67c745e8d3b29af3a2.zip
working ethernet
-rw-r--r--.gitignore2
-rw-r--r--Makefile.include6
-rw-r--r--app/Makefile27
-rw-r--r--app/bits.c22
-rw-r--r--app/dcf77.c186
-rw-r--r--app/events.h14
-rw-r--r--app/gps.c839
-rw-r--r--app/gps.h11
-rw-r--r--app/hexdump.c57
-rw-r--r--app/lwip/lwipopts.h8
-rw-r--r--app/lwip_glue.c2
-rw-r--r--app/main.c48
-rw-r--r--app/msf.c4
-rw-r--r--app/pins.h11
-rw-r--r--app/pll.c4
-rw-r--r--app/project.h12
-rw-r--r--app/prototypes.h38
-rw-r--r--app/stats.c44
-rw-r--r--app/stdio.c4
-rw-r--r--app/steth.c255
-rw-r--r--app/ubx.h56
-rw-r--r--app/usart.c163
-rw-r--r--app/util.c66
-rw-r--r--oocd/board/stm32f407vet6.cfg4
-rw-r--r--oocd/interface/j-link.cfg3
25 files changed, 1712 insertions, 174 deletions
diff --git a/.gitignore b/.gitignore
index 09e26f4..ac3f06d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,5 @@
*.hex
*.map
.*.swp
+almanac.c
+almanac.alp
diff --git a/Makefile.include b/Makefile.include
index 1288fe0..7a60f2f 100644
--- a/Makefile.include
+++ b/Makefile.include
@@ -29,8 +29,10 @@ ARCH_FLAGS = -mthumb -mcpu=cortex-m4 $(FP_FLAGS)
# OpenOCD specific variables
OOCD ?= openocd
-OOCD_INTERFACE ?= cmsis-dap
-OOCD_BOARD ?= arch_max
+#OOCD_INTERFACE ?= cmsis-dap
+#OOCD_BOARD ?= arch_max
+OOCD_INTERFACE ?= j-link
+OOCD_BOARD ?= stm32f407vet6
################################################################################
# Black Magic Probe specific variables
diff --git a/app/Makefile b/app/Makefile
index e5d6731..dd4b6e7 100644
--- a/app/Makefile
+++ b/app/Makefile
@@ -25,8 +25,11 @@ PROG=msf
V=1
default: ${PROG}.elf
-CSRCS=led.c ticker.c ring.c usart.c stdio.c lwip_glue.c steth.c msf.c abs.c pll.c main.c time_fn.c ntp.c dcf77.c util.c stats.c
-HSRCS=project.h ring.h pins.h
+CSRCS=led.c ticker.c ring.c usart.c stdio.c lwip_glue.c steth.c msf.c abs.c pll.c main.c time_fn.c ntp.c dcf77.c util.c stats.c gps.c hexdump.c bits.c debug_eth.c
+HSRCS=project.h ring.h pins.h gps.h ubx.h
+
+
+
LWIP=lwip/lwip-1.4.1
LWIP_PATH=..
@@ -55,12 +58,12 @@ BINARY = ${PROG}
MYOBJS = ${CSRCS:%.c=%.o}
LWIP_OBJS = ${LWIP_CSRCS:%.c=%.o}
-objs:${OBJS}
+objs:${OBJS}
${MYOBJS}: project.h prototypes.h
${LWIP_OBJS}: lwip/lwipopts.h
-OBJS=${MYOBJS} ${LWIP_OBJS}
+OBJS=${MYOBJS} ${LWIP_OBJS} almanac.o
include ../Makefile.include
@@ -78,19 +81,29 @@ program: ${PROG}.hex
ds:
$(Q)$(OOCD) -f ../oocd/interface/$(OOCD_INTERFACE).cfg \
- -f ../oocd/board/$(OOCD_BOARD).cfg
+ -f ../oocd/board/$(OOCD_BOARD).cfg
debug: ${PROG}.elf
${PREFIX}-gdb -x gdb.script ${PROG}.elf
# openocd
-protos: ${CSRCS}
+protos: ${CSRCS}
echo -n > prototypes.h
${CPROTO} -E "${CPP} $(CPPFLAGS)" -e -v ${CSRCS} > prototypes.h.tmp
mv -f prototypes.h.tmp prototypes.h
-EXTRA_CLEAN=${OBJS} ${LWIP_OBJS:%.o=%.d}
+almanac.c:almanac.alp
+ echo const > $@
+ xxd -i $< >> $@
+
+almanac.alp: almanac
+
+almanac:
+ wget -O almanac.alp http://alp.u-blox.com/current_7d.alp
+
+
+EXTRA_CLEAN=${OBJS} ${LWIP_OBJS:%.o=%.d} almanac.c
tidy:
astyle -A3 -s2 --attach-extern-c -L -c -w -Y -m0 -f -p -H -U -k3 -xj -xd ${CSRCS} ${HSRCS}
diff --git a/app/bits.c b/app/bits.c
new file mode 100644
index 0000000..03d5c31
--- /dev/null
+++ b/app/bits.c
@@ -0,0 +1,22 @@
+#include "project.h"
+
+void dump_bits(char *wot,uint8_t *bits)
+{
+char buf[128];
+char *ptr=buf;
+unsigned i=60;
+
+
+ptr+=sprintf(buf,"%s bits: ",wot);
+
+
+while (i--)
+*(ptr++)=*(bits++) ? '1':'0';
+
+
+*(ptr++)='\r';
+*(ptr++)='\n';
+*ptr=0;
+usart1_write(buf,(unsigned) (ptr-buf),1);
+
+}
diff --git a/app/dcf77.c b/app/dcf77.c
new file mode 100644
index 0000000..edc152b
--- /dev/null
+++ b/app/dcf77.c
@@ -0,0 +1,186 @@
+#include "project.h"
+
+#define P1 (GPIO11)
+#define P1_PORT GPIOD
+
+#define T (GPIO12)
+#define T_PORT GPIOD
+
+
+static Event_ring dcf77_ring;
+
+
+uint64_t dcf77_last_second;
+
+void exti15_10_isr (void)
+{
+ uint32_t now = SCS_DWT_CYCCNT;
+ int v;
+
+ v = !!gpio_get (T_PORT, T);
+
+ nvic_disable_irq (NVIC_EXTI15_10_IRQ);
+ exti_reset_request (EXTI12);
+
+ dcf77_ring.events[dcf77_ring.tx_ptr].when = now;
+ dcf77_ring.events[dcf77_ring.tx_ptr].value = v;
+ dcf77_ring.tx_ptr = (dcf77_ring.tx_ptr + 1) & ERING_MASK;
+
+ nvic_enable_irq (NVIC_EXTI15_10_IRQ);
+}
+
+
+
+
+static uint8_t bits[60];
+
+static int time_known;
+
+static void process_bits (uint64_t abs)
+{
+ UTC u;
+ EPOCH dcf77_time;
+
+
+ if (bits[0]) return;
+
+ if (!bits[20]) return;
+
+ if (!check_parity (bits, 21, 27, bits[28])) return;
+
+ if (!check_parity (bits, 29, 34, bits[35])) return;
+
+ if (!check_parity (bits, 36, 57, bits[58])) return;
+
+ u.jday = 0;
+ u.year = le_bcd (bits, 50, 57);
+ u.month = le_bcd (bits, 45, 49);
+ u.mday = bcd (bits, 36, 41);
+ u.hour = bcd (bits, 29, 34);
+ u.minute = bcd (bits, 21, 27);
+ u.second = 58;
+ u.nanosecond = 0;
+
+
+ dcf77_time = time_utc_to_epoch (u);
+ dcf77_time.s -= 58;
+
+#if 0
+ pll_set_offset (dcf77_time, abs);
+#endif
+ time_known = 1;
+
+ printf ("DCF77: Next minute is: %02d-%02d-%02d %02d:%02d\r\n", u.year, u.month, u.mday, u.hour, u.minute);
+ time_print_epoch ("DCF77: ", dcf77_time);
+
+ dump_bits("dcf77",bits);
+}
+
+
+static void report_bit (uint64_t abs, int second, int b)
+{
+ if ((second < 0) || (second > 58)) return;
+
+ bits[second] = b;
+
+ // printf("DCF77: bits[%d]=%d\r\n",second,b);
+
+ if (second == 58) process_bits (abs);
+
+}
+
+static void report_time (uint64_t abs)
+{
+#if 0
+ EPOCH e = pll_decompose (abs);
+ time_print_epoch ("DCF77: ", e);
+#endif
+}
+
+
+void dcf77_dispatch (void)
+{
+ static uint32_t last_0, last_1, last_s;
+ static int second, bit, had_m;
+ uint32_t pulse_w, offset;
+ static uint64_t abs;
+ int is_s = 0;
+
+ uint32_t now;
+ int v;
+
+
+
+
+ if (dcf77_ring.rx_ptr == dcf77_ring.tx_ptr) return;
+
+ v = dcf77_ring.events[dcf77_ring.rx_ptr].value;
+ now = dcf77_ring.events[dcf77_ring.rx_ptr].when;
+
+ dcf77_ring.rx_ptr = (dcf77_ring.rx_ptr + 1) & ERING_MASK;
+
+ if (v) {
+ pulse_w = now - last_0;
+ pulse_w /= (HZ / 1000);
+
+ last_1 = now;
+
+ if (pulse_w > 300) {
+ last_s = now;
+ is_s = 1;
+ second++;
+ }
+
+ if (pulse_w > 1300) {
+ had_m = 1;
+ second = 0;
+ }
+
+ } else {
+ pulse_w = now - last_1;
+ pulse_w /= (HZ / 1000);
+
+ if (pulse_w > 150)
+ bit = 1;
+ else
+ bit = 0;
+
+ if (had_m)
+ report_bit (abs, second, bit);
+
+ last_0 = now;
+ }
+
+ offset = now - last_s;
+ offset /= (HZ / 1000);
+
+ if (is_s) {
+ abs = abs_extend (now);
+ dcf77_last_second = abs;
+
+ //pll_dispatch (abs);
+
+ if (time_known)
+ report_time (abs);
+ }
+
+
+}
+
+
+
+void
+dcf77_init (void)
+{
+ MAP_INPUT (T);
+ MAP_OUTPUT_PP (P1);
+
+ gpio_clear (P1_PORT, P1);
+
+ exti_select_source (EXTI12, T_PORT);
+ exti_set_trigger (EXTI12, EXTI_TRIGGER_BOTH);
+ exti_enable_request (EXTI12);
+ nvic_enable_irq (NVIC_EXTI15_10_IRQ);
+}
+
+
diff --git a/app/events.h b/app/events.h
new file mode 100644
index 0000000..eb0fe89
--- /dev/null
+++ b/app/events.h
@@ -0,0 +1,14 @@
+#define ERING_SIZE 16
+#define ERING_MASK (ERING_SIZE -1)
+
+typedef struct {
+ uint32_t when;
+ int value;
+} Event;
+
+
+typedef struct {
+ Event events[ERING_SIZE];
+ uint32_t rx_ptr,tx_ptr;
+} Event_ring;
+
diff --git a/app/gps.c b/app/gps.c
new file mode 100644
index 0000000..9fc60de
--- /dev/null
+++ b/app/gps.c
@@ -0,0 +1,839 @@
+#include "project.h"
+
+#define PPS (GPIO2)
+#define PPS_PORT GPIOD
+
+#define UBX_BUF_LEN 256
+
+#define TIMEOUT 4000
+
+static int ubx_ack = 0;
+static int ubx_ack_xfer = 0;
+
+static int current_ref_hz=1;
+
+int gps_locked;
+int gps_happy;
+
+static char fix,fix2;
+static int32_t freq = 0;
+
+static const int fish[] = { 1, 2, 3, 4, 5, 6, 7 };
+
+static Event_ring gps_ring;
+
+
+void exti2_isr (void)
+{
+ uint32_t now = SCS_DWT_CYCCNT;
+ int v;
+
+ v = !!gpio_get (PPS_PORT, PPS);
+
+ nvic_disable_irq (NVIC_EXTI2_IRQ);
+ exti_reset_request (EXTI2);
+
+ gps_ring.events[gps_ring.tx_ptr].when = now;
+ gps_ring.events[gps_ring.tx_ptr].value = v;
+ gps_ring.tx_ptr = (gps_ring.tx_ptr + 1) & ERING_MASK;
+
+ nvic_enable_irq (NVIC_EXTI2_IRQ);
+
+}
+
+
+
+static inline int
+ubx_recv_byte (uint8_t *v)
+{
+ return !ring_read_byte (&rx3_ring, v);
+}
+
+static inline void
+ubx_send_byte (uint8_t v)
+{
+ usart3_queue (v);
+}
+
+static int
+ubx_recv_nav_status (uint8_t *ptr, unsigned len)
+{
+ uint8_t gps_fix, flags;
+ uint32_t d;
+
+ if ((!ptr) || (len != 16))
+ return -1;
+
+ ptr += ubx_get_u32 (ptr, &d); //TOW
+ ptr += ubx_get_u8 (ptr, &gps_fix); //fix type
+ ptr += ubx_get_u8 (ptr, &flags); //fix type
+
+
+ switch (gps_fix) {
+ case 0:
+ case 1:
+ fix='-';
+ gps_locked = 0;
+ break;
+
+ case 2:
+ fix='2';
+ gps_locked = 0;
+ break;
+
+ case 3:
+ fix='L';
+ gps_locked = 1;
+ break;
+
+ case 4:
+ fix='R';
+ gps_locked = 0;
+ break;
+
+ case 5:
+ fix='T';
+ gps_locked = 0;
+ break;
+
+ default:
+ fix='?';
+ gps_locked = 0;
+ }
+
+ switch (flags & 3) {
+ case 0:
+ case 2:
+ fix2='!';
+ break;
+
+ case 1:
+ fix2='-';
+ break;
+
+ case 3:
+ fix2='D';
+
+ if (gps_locked == 1)
+ gps_locked = 2;
+
+ break;
+
+ default:
+ fix2='?';
+ }
+
+
+// printf ("fix: %c%c\r\n",fix,fix2);
+
+
+ if ((gps_locked) && (gps_happy < 10000))
+ gps_happy++;
+ else
+ gps_happy = 0;
+
+ return 0;
+}
+
+
+static int
+ubx_recv_clock_stats (uint8_t *ptr, unsigned len)
+{
+ //char buf[40];
+ int32_t drift;
+ uint32_t d;
+
+ if ((!ptr) || (len != 20))
+ return -1;
+
+ ptr += ubx_get_u32 (ptr, &d); //TOW
+ ptr += ubx_get_u32 (ptr, &d); //bias
+ ptr += ubx_get_i32 (ptr, &drift); //drift
+ ptr += ubx_get_u32 (ptr, &d); //time acc estimate
+ ptr += ubx_get_i32 (ptr, &freq); //freq acc estimate
+
+// printf ("TCXO %+8dE-12\r\n", (int) freq);
+#if 0
+ sprintf (buf, "TCXO %+8dE-12", (int) freq);
+ lcd_erase_line (18, 0);
+ lcd_write (buf, 0, 0);
+#endif
+ return 0;
+
+}
+
+static int
+ubx_recv_utc (uint8_t *ptr, unsigned len)
+{
+ int32_t nano;
+ uint32_t acc;
+ uint16_t year;
+ uint8_t hour, min, sec, day, month;
+ uint32_t d;
+ // char buf[40];
+
+ if ((!ptr) || (len != 20))
+ return -1;
+
+ ptr += ubx_get_u32 (ptr, &d); //TOW
+ ptr += ubx_get_u32 (ptr, &acc); //bias
+ ptr += ubx_get_i32 (ptr, &nano);
+ ptr += ubx_get_u16 (ptr, &year);
+ ptr += ubx_get_u8 (ptr, &month);
+ ptr += ubx_get_u8 (ptr, &day);
+ ptr += ubx_get_u8 (ptr, &hour);
+ ptr += ubx_get_u8 (ptr, &min);
+ ptr += ubx_get_u8 (ptr, &sec);
+
+// printf ("gps %02d:%02d:%02d %09d\r\n", (int) hour, (int) min, (int) sec, (int) nano);
+
+#if 0
+ sprintf (buf, "%+6dE-12 %02d%02d%02d", (int) freq,
+ (int) hour, (int)min, (int) sec);
+ lcd_erase_line (18, 0);
+ lcd_write (buf, 0, 0);
+#endif
+
+ return 0;
+}
+
+static int ubx_recv_rinex (uint8_t *payload, unsigned len)
+{
+
+ printf ("Rinex\r\n");
+ return 0;
+}
+
+
+
+static void
+ubx_recv (uint8_t class, uint8_t id, uint8_t *payload, unsigned len)
+{
+ // printf ("RX> %02x.%02x (%d bytes)\r\n", class, id, len);
+
+ switch (class) {
+ case 1:
+ switch (id) {
+ case 0x3:
+ ubx_recv_nav_status (payload, len);
+ break;
+
+ case 0x21:
+ ubx_recv_utc (payload, len);
+ break;
+
+ case 0x22:
+ ubx_recv_clock_stats (payload, len);
+ break;
+
+ default:
+ printf ("RX> %02x.%02x (%d bytes)\r\n", class, id, len);
+ hexdump (payload, len);
+ }
+
+ break;
+
+ case 2:
+ switch (id) {
+ case 0x10:
+ ubx_recv_rinex (payload, len);
+
+ break;
+ }
+
+ break;
+
+ case 5:
+ ubx_ack++;
+ printf (" %s for %02x.%02x\r\n", id ? "ACK" : "NAK", payload[0],
+ payload[1]);
+
+ break;
+
+ case 0x0b:
+ switch (id) {
+ case 0x50:
+ printf ("xfer ack\r\n");
+ ubx_ack_xfer++;
+ break;
+
+ default:
+ printf ("RX> %02x.%02x (%d bytes)\r\n", class, id, len);
+ hexdump (payload, len);
+ }
+
+ break;
+
+ default:
+ printf ("RX> %02x.%02x (%d bytes)\r\n", class, id, len);
+ if (class!=0x03)
+ hexdump (payload, len);
+ }
+
+
+}
+
+
+typedef enum {
+ UBX_SM_LOST = 0,
+ UBX_SM_S2,
+ UBX_SM_C,
+ UBX_SM_I,
+ UBX_SM_L1,
+ UBX_SM_L2,
+ UBX_SM_DATA,
+ UBX_SM_CKA,
+ UBX_SM_CKB
+} ubx_sm_t;
+
+
+
+
+static uint8_t *
+ubx_dispatch_search (int s_class, int s_id, unsigned *len_ptr)
+{
+ static uint8_t buf[UBX_BUF_LEN];
+ static ubx_sm_t sm = UBX_SM_LOST;
+ static uint8_t class, id;
+ static unsigned ptr;
+ static unsigned len;
+ static uint8_t ck_a, ck_b;
+
+
+ void ubx_ck (uint8_t v) {
+ ck_a += v;
+ ck_b = ck_b + ck_a;
+ }
+
+
+ uint8_t c;
+
+ while (ubx_recv_byte (&c)) {
+
+ switch (sm) {
+ case UBX_SM_LOST:
+ if (c == 0xb5)
+ sm = UBX_SM_S2;
+
+ break;
+
+ case UBX_SM_S2:
+ if (c == 0x62)
+ sm = UBX_SM_C;
+ else
+ sm = UBX_SM_LOST;
+
+ break;
+
+ case UBX_SM_C:
+ ck_a = ck_b = class = c;
+ sm = UBX_SM_I;
+ break;
+
+ case UBX_SM_I:
+ ubx_ck (c);
+ id = c;
+ sm = UBX_SM_L1;
+ break;
+
+ case UBX_SM_L1:
+ ubx_ck (c);
+ len = c;
+ sm = UBX_SM_L2;
+ break;
+
+ case UBX_SM_L2:
+ ubx_ck (c);
+ len |= c << 8;
+
+ ptr = 0;
+
+ if (len)
+ sm = UBX_SM_DATA;
+ else
+ sm = UBX_SM_CKA;
+
+ break;
+
+ case UBX_SM_DATA:
+ ubx_ck (c);
+
+ if (ptr < UBX_BUF_LEN)
+ buf[ptr] = c;
+
+ ptr++;
+
+ if (ptr == len)
+ sm = UBX_SM_CKA;
+
+ break;
+
+ case UBX_SM_CKA:
+ if (c == ck_a)
+ sm = UBX_SM_CKB;
+ else
+ sm = UBX_SM_LOST;
+
+ break;
+
+ case UBX_SM_CKB:
+ sm = UBX_SM_LOST;
+
+ if (c != ck_b)
+ break;
+
+ ubx_recv (class, id, buf, len);
+
+ if ((class == s_class) && (id == s_id)) {
+ if (len_ptr)
+ *len_ptr = len;
+
+ return buf;
+ }
+
+ break;
+ }
+
+ }
+
+ return NULL;
+}
+static void gps_pps_dispatch (void)
+{
+ char buf[80];
+ uint64_t abs;
+ uint32_t now;
+ int v;
+ EPOCH e;
+ UTC u;
+
+ if (gps_ring.rx_ptr == gps_ring.tx_ptr) return;
+
+ v = gps_ring.events[gps_ring.rx_ptr].value;
+ now = gps_ring.events[gps_ring.rx_ptr].when;
+
+ gps_ring.rx_ptr = (gps_ring.rx_ptr + 1) & ERING_MASK;
+
+
+ if (!v) return;
+
+
+
+ abs = abs_extend (now);
+ pll_dispatch(abs);
+
+ e = pll_decompose (abs);
+
+ u=time_epoch_to_utc(e);
+
+ printf ("GPS %02d:%02d:%02d.%09d Fix:%c%c TXCO %+8dE-12\r\n",
+ u.hour,
+ u.minute,
+ u.second,
+ u.nanosecond,
+ fix,fix2,(int) freq);
+
+
+}
+
+
+void
+gps_dispatch (void)
+{
+ ubx_dispatch_search (-1, -1, NULL);
+ gps_pps_dispatch();
+}
+
+void
+ubx_send (uint8_t class, uint8_t id, const void *_payload, unsigned len)
+{
+ uint8_t ck_a = 0, ck_b = 0;
+ uint8_t *payload = (uint8_t *) _payload;
+
+ void ubx_send_byte_ck (uint8_t v) {
+ ubx_send_byte (v);
+ ck_a += v;
+ ck_b = ck_b + ck_a;
+ }
+
+
+ ubx_send_byte (0xb5);
+ ubx_send_byte (0x62);
+
+ ubx_send_byte_ck (class);
+ ubx_send_byte_ck (id);
+ ubx_send_byte_ck (len & 0xff);
+ ubx_send_byte_ck (len >> 8);
+
+ while (len--)
+ ubx_send_byte_ck (* (payload++));
+
+ ubx_send_byte (ck_a);
+ ubx_send_byte (ck_b);
+
+ // printf ("TX> %02x.%02x\r\n", class, id);
+
+}
+
+int
+ubx_handshake (uint8_t class, uint8_t id, const void *payload, unsigned len)
+{
+ uint32_t timeout;
+
+ ubx_ack = 0;
+ ubx_send (class, id, payload, len);
+
+
+
+ timeout = ticks + TIMEOUT;
+
+ while (!ubx_ack) {
+
+ if (ticks > timeout) {
+ printf ("GPS timeout resending packet\r\n");
+ usart3_drain();
+ ubx_send (class, id, payload, len);
+ timeout = ticks + TIMEOUT;
+ }
+
+
+
+
+ gps_dispatch();
+ }
+
+ return 0;
+}
+
+int
+ubx_handshake_xfer (uint8_t class, uint8_t id, const void *payload,
+ unsigned len)
+{
+ uint32_t timeout;
+
+ ubx_ack_xfer = 0;
+// usart3_drain();
+ ubx_send (class, id, payload, len);
+
+
+
+ timeout = ticks + TIMEOUT;
+
+ while (!ubx_ack_xfer) {
+
+ if (ticks > timeout) {
+ printf ("GPS timeout resending packet\r\n");
+// usart3_drain();
+ ubx_send (class, id, payload, len);
+ timeout = ticks + TIMEOUT;
+ }
+
+
+
+
+ gps_dispatch();
+ }
+
+ return 0;
+}
+
+
+
+
+uint8_t *
+ubx_fetch (uint8_t class, uint8_t id, void *payload, unsigned len,
+ unsigned *len_ptr)
+{
+ uint8_t *ret;
+
+ while (!ring_empty (&tx3_ring) || !ring_empty (&rx3_ring))
+ gps_dispatch();
+
+ ubx_send (class, id, payload, len);
+
+ while (! (ret = ubx_dispatch_search (class, id, len_ptr)));
+
+
+ return ret;
+}
+
+int
+ubx_set_message_rate_port1 (uint8_t class, uint8_t id, uint8_t rate)
+{
+ uint8_t buf[8], *ptr;
+
+ ptr = buf;
+
+ ptr += ubx_put_u8 (ptr, class);
+ ptr += ubx_put_u8 (ptr, id); //reserved
+ ptr += ubx_put_u8 (ptr, 0); //nothing on port i2c
+ ptr += ubx_put_u8 (ptr, rate); //rate on uart
+ ptr += ubx_put_u8 (ptr, 0); //nothing on port 2
+ ptr += ubx_put_u8 (ptr, 0); //nothing on usb
+ ptr += ubx_put_u8 (ptr, 0); //nothing on spi
+ ptr += ubx_put_u8 (ptr, 0); //nothing on port 5
+
+ return ubx_handshake (0x06, 0x01, buf, (unsigned) (ptr - buf));
+}
+
+
+int
+ubx_cfg_rst (uint16_t flags)
+{
+ uint8_t buf[8], *ptr;
+
+ ptr = buf;
+
+ ptr += ubx_put_u16 (ptr, flags); //Flags
+ ptr += ubx_put_u8 (ptr, 0x4); //Hardware reset after shutdown
+ ptr += ubx_put_u8 (ptr, 0); //reserved
+
+ ubx_send (0x06, 0x04, buf, (unsigned) (ptr - buf));
+ return 0;
+}
+
+
+int
+gps_set_ref (int ref_hz)
+{
+ uint8_t buf[80], *ptr;
+ int ret;
+
+ printf ("setting gps ref to %d hz\r\n", ref_hz);
+
+ current_ref_hz = ref_hz;
+
+ ptr = buf;
+
+ ptr += ubx_put_u8 (ptr, 0); //timepluse 1
+ ptr += ubx_put_u8 (ptr, 0); //reserved
+ ptr += ubx_put_u16 (ptr, 0); //reserved
+
+// ptr += ubx_put_u16 (ptr, 32); //ant cable delay ns
+ ptr += ubx_put_u16 (ptr, 0); //ant cable delay ns
+ ptr += ubx_put_u16 (ptr, 0); //rf group delay ns
+ ptr += ubx_put_u32 (ptr, 1000000 / ref_hz); //period unlocked/us
+ ptr += ubx_put_u32 (ptr, 1000000 / ref_hz); //period locked/us
+
+ // ptr += ubx_put_u32 (ptr, 0); //pulse width unlocked/us
+ ptr += ubx_put_u32 (ptr, 500000 / ref_hz); //pulse width unlocked/us
+ ptr += ubx_put_u32 (ptr, 500000 / ref_hz); //pulse width locked/us
+
+ ptr += ubx_put_i32 (ptr, 0); // ? delay
+
+#if 0
+ /*Separate numbers for locked/unlocked*/
+ ptr += ubx_put_u32 (ptr, 0xf7);
+#else
+ /*Same numbers for locked/unlocked*/
+ ptr += ubx_put_u32 (ptr, 0xf3);
+#endif
+
+
+ ret = ubx_handshake (0x06, 0x31, buf, (unsigned) (ptr - buf));
+
+ return ret;
+}
+
+
+int
+gps_init (void)
+{
+ uint8_t buf[80], *ptr;
+ unsigned len;
+ uint16_t u2;
+
+ usart3_drain();
+
+ while (!ring_empty (&tx3_ring) || !ring_empty (&rx3_ring))
+ gps_dispatch();
+
+
+ printf ("Testing GNSS...\r\n");
+ ubx_handshake (0x06, 0x00, NULL, 0);
+ printf ("GNSS there\r\n");
+ // Set up port
+ ptr = buf;
+ ptr += ubx_put_u8 (ptr, 1); //uart1
+ ptr += ubx_put_u8 (ptr, 0); //reserved
+ ptr += ubx_put_u16 (ptr, 0x0); //flow control off
+ ptr += ubx_put_u32 (ptr, 0x8c0); //no parity, 8 bits
+ ptr += ubx_put_u32 (ptr, 9600); // baudrate
+ ptr += ubx_put_u16 (ptr, 0x7); // receive RTCM, NMEA, UBX
+ ptr += ubx_put_u16 (ptr, 0x1); // transmit UBX
+ ptr += ubx_put_u16 (ptr, 0x0); // no txtimeout
+ ptr += ubx_put_u16 (ptr, 0x0); // reserved
+ ubx_handshake (0x06, 0x00, buf, (unsigned) (ptr - buf));
+
+ printf ("configured GNSS protocol\r\n");
+
+#if 1
+ptr = buf;
+ ptr += ubx_put_u16 (ptr, 0x14);
+ ptr += ubx_put_u16 (ptr, 0x00);
+ ubx_handshake (0x06, 0x13, buf, (unsigned) (ptr - buf));
+
+ printf ("configured antenna pins\r\n");
+#endif
+
+
+
+#if 0
+ // Check we're in WGS84
+ ptr = ubx_fetch (0x06, 0x06, NULL, 0, &len);
+ ptr += ubx_get_u16 (ptr, &u2);
+
+ if (u2)
+ return -1;
+
+ printf ("configured GNSS datum\r\n");
+#endif
+
+ ptr = buf;
+
+ ptr += ubx_put_u8 (ptr, 0); //UBX
+ ptr += ubx_put_u8 (ptr, 0); //reserved
+ ptr += ubx_put_u16 (ptr, 0); //reserved
+ ptr += ubx_put_u8 (ptr, 0); //nothing on port i2c
+ ptr += ubx_put_u8 (ptr, 0x18); //everything on uart
+ ptr += ubx_put_u8 (ptr, 0); //nothing on port 2
+ ptr += ubx_put_u8 (ptr, 0); //nothing on usb
+ ptr += ubx_put_u8 (ptr, 0); //nothing on spi
+ ptr += ubx_put_u8 (ptr, 0); //nothing on port 5
+
+ ptr += ubx_put_u8 (ptr, 1); //NMEA
+ ptr += ubx_put_u8 (ptr, 0); //reserved
+ ptr += ubx_put_u16 (ptr, 0); //reserved
+ ptr += ubx_put_u8 (ptr, 0); //nothing on port i2c
+ ptr += ubx_put_u8 (ptr, 0); //nothing on uart
+ ptr += ubx_put_u8 (ptr, 0); //nothing on port 2
+ ptr += ubx_put_u8 (ptr, 0); //nothing on usb
+ ptr += ubx_put_u8 (ptr, 0); //nothing on spi
+ ptr += ubx_put_u8 (ptr, 0); //nothing on port 5
+
+ ubx_handshake (0x06, 0x02, buf, (unsigned) (ptr - buf));
+
+ printf ("configured GNSS data\r\n");
+
+ ubx_fetch (0x06, 0x31, NULL, 0, &len);
+
+ printf ("configured GNSS 6.31\r\n");
+
+#if 1
+ ubx_set_message_rate_port1 (0x01, 0x03, 1);
+ ubx_set_message_rate_port1 (0x01, 0x21, 1);
+ ubx_set_message_rate_port1 (0x01, 0x22, 1);
+ ubx_set_message_rate_port1 (0x01, 0x32, 0);
+ ubx_set_message_rate_port1 (0x03, 0x0a, 0);
+ //ubx_set_message_rate_port1 (0x03, 0x10, 0);
+ printf ("GNSS ready\r\n");
+#else
+ ubx_set_message_rate_port1 (0x01, 0x03, 0);
+ ubx_set_message_rate_port1 (0x01, 0x21, 0);
+ ubx_set_message_rate_port1 (0x01, 0x22, 0);
+ ubx_set_message_rate_port1 (0x01, 0x32, 0);
+ ubx_set_message_rate_port1 (0x03, 0x0a, 0);
+ //ubx_set_message_rate_port1 (0x03, 0x10, 0);
+ printf ("GNSS ready\r\n");
+#endif
+
+#if 1
+ptr = buf;
+ ptr += ubx_put_u8 (ptr, 0x1);
+ ptr += ubx_put_u8 (ptr, 0x7);
+ ptr += ubx_put_u8 (ptr, 0x1);
+ ptr += ubx_put_u8 (ptr, 0xf);
+ ptr += ubx_put_u32 (ptr, 0xffffffff);
+ ubx_handshake (0x06, 0x16, buf, (unsigned) (ptr - buf));
+
+ printf ("configured SBAS\r\n");
+
+ ubx_handshake (0x06, 0x16, buf, 0);
+#endif
+
+
+ // printf ("GPS ready\r\n");
+ // ubx_get_clock_stats();
+
+ MAP_INPUT (PPS);
+
+ exti_select_source (EXTI2, PPS_PORT);
+ exti_set_trigger (EXTI2, EXTI_TRIGGER_BOTH);
+ exti_enable_request (EXTI2);
+ nvic_enable_irq (NVIC_EXTI2_IRQ);
+
+ return 0;
+}
+
+
+#define ALMANAC_LUMP 128
+
+int
+gps_almanac (void)
+{
+ uint32_t len = almanac_alp_len;
+ const uint8_t *ptr = almanac_alp;
+ uint32_t lumpsz;
+ uint8_t dummy;
+
+ printf ("Downloading GPS almanac %x %x %x\r\n", (int) ptr[0], (int) ptr[1],
+ (int) ptr[2]);
+
+
+ while (len) {
+ printf ("%d bytes to go\r\n", (int) len);
+
+ lumpsz = len > ALMANAC_LUMP ? ALMANAC_LUMP : len;
+
+ ubx_handshake_xfer (0x0b, 0x50, ptr, lumpsz);
+
+ ptr += lumpsz;
+ len -= lumpsz;
+
+ }
+
+ ubx_handshake_xfer (0x0b, 0x50, &dummy, 1);
+
+ return 0;
+}
+
+
+
+void
+gps_reset (void)
+{
+ printf ("Restting gps..\r\n");
+
+#define REPHEMERIDIES (1UL << 0)
+#define RALMANAC (1UL << 1)
+#define RPOS (1UL << 4)
+#define RRTC (1UL << 8)
+
+ ubx_cfg_rst (REPHEMERIDIES | RALMANAC | RPOS | RRTC);
+
+delay_ms(1000);
+usart3_drain();
+
+
+ printf ("Testing GNSS...\r\n");
+ ubx_handshake (0x06, 0x00, NULL, 0);
+ printf ("GNSS there\r\n");
+
+ gps_init();
+
+ gps_set_ref (current_ref_hz);
+
+}
+
+int
+ubx_get_clock_stats (void)
+{
+ uint8_t *ptr;
+
+ unsigned len;
+
+ ptr = ubx_fetch (0x01, 0x22, NULL, 0, &len);
+
+ //return ubx_recv_clock_stats(ptr,len);
+ return ptr ? 0 : -1;
+}
diff --git a/app/gps.h b/app/gps.h
new file mode 100644
index 0000000..ce6ee14
--- /dev/null
+++ b/app/gps.h
@@ -0,0 +1,11 @@
+extern int gps_happy;
+
+static inline int gps_is_happy (void)
+{
+ return gps_happy > 15;
+}
+static inline int gps_is_stable (void)
+{
+ return gps_happy > 60;
+}
+
diff --git a/app/hexdump.c b/app/hexdump.c
new file mode 100644
index 0000000..83f02ea
--- /dev/null
+++ b/app/hexdump.c
@@ -0,0 +1,57 @@
+#include "project.h"
+
+void
+hexdump (void *_d, int len)
+{
+ uint8_t *d = (uint8_t *) _d;
+ int i, j, k;
+ int e;
+
+ if (!d || len < 0)
+ return;
+
+ e = len + 15;
+ e &= ~15;
+
+ for (i = 0; i < e; i += 16) {
+ usart1_drain();
+ printf (" %05x:", i);
+
+ for (j = 0; j < 16; ++j) {
+ k = i + j;
+
+ if (k < len)
+ printf (" %02x", d[k]);
+ else
+ printf (" ");
+
+ if (j == 7)
+ printf (" ");
+ }
+
+ printf (" ");
+
+ for (j = 0; j < 16; ++j) {
+ k = i + j;
+
+ if (k < len) {
+ uint8_t c = d[k];
+
+ if (c < 33)
+ c = '.';
+
+ if (c > 126)
+ c = '.';
+
+ printf ("%c", c);
+ }
+
+ if (j == 7)
+ printf (" ");
+ }
+
+ printf ("\r\n");
+ }
+
+ usart1_drain();
+}
diff --git a/app/lwip/lwipopts.h b/app/lwip/lwipopts.h
index e535e59..3358cad 100644
--- a/app/lwip/lwipopts.h
+++ b/app/lwip/lwipopts.h
@@ -29,6 +29,8 @@
#define MTU 1500
+#define ICMP_TTL 64
+
#if 0
#define ICMP_DEBUG LWIP_DBG_ON
#define UDP_DEBUG LWIP_DBG_ON
@@ -156,11 +158,11 @@ The STM32F4x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums
*/
/* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/
-#define CHECKSUM_GEN_IP 0
+#define CHECKSUM_GEN_IP 1
/* CHECKSUM_GEN_UDP==0: Generate checksums by hardware for outgoing UDP packets.*/
-#define CHECKSUM_GEN_UDP 0
+#define CHECKSUM_GEN_UDP 1
/* CHECKSUM_GEN_TCP==0: Generate checksums by hardware for outgoing TCP packets.*/
-#define CHECKSUM_GEN_TCP 0
+#define CHECKSUM_GEN_TCP 1
/* CHECKSUM_CHECK_IP==0: Check checksums by hardware for incoming IP packets.*/
#define CHECKSUM_CHECK_IP 1
/* CHECKSUM_CHECK_UDP==0: Check checksums by hardware for incoming UDP packets.*/
diff --git a/app/lwip_glue.c b/app/lwip_glue.c
index 6c66de8..3771c38 100644
--- a/app/lwip_glue.c
+++ b/app/lwip_glue.c
@@ -67,7 +67,7 @@ void start_lwip (void)
lwip_init();
- IP4_ADDR (&ipaddr, 10, 32, 48, 99);
+ IP4_ADDR (&ipaddr, 10, 32, 48, 98);
IP4_ADDR (&netmask, 255, 255, 255, 0);
IP4_ADDR (&gw, 10, 32, 48, 1);
diff --git a/app/main.c b/app/main.c
index 48828c8..368839c 100644
--- a/app/main.c
+++ b/app/main.c
@@ -1,6 +1,26 @@
#include "project.h"
+static void cmd_dispatch()
+{
+uint8_t c;
+while (!ring_read_byte(&rx1_ring,&c)) {
+
+ printf("KEY> %c\r\n",c);
+
+switch(c) {
+
+ case 'R':
+ gps_reset ();
+ break;
+ case 'A':
+ gps_almanac ();
+ break;
+}
+}
+}
+
+
static void
board_setup (void)
{
@@ -10,13 +30,17 @@ board_setup (void)
rcc_periph_clock_enable (RCC_GPIOB);
rcc_periph_clock_enable (RCC_GPIOC);
rcc_periph_clock_enable (RCC_GPIOD);
- rcc_periph_clock_enable (RCC_USART6);
+ rcc_periph_clock_enable (RCC_USART1);
+ rcc_periph_clock_enable (RCC_USART3);
+ rcc_periph_clock_enable (RCC_SYSCFG);
- nvic_set_priority (NVIC_EXTI0_IRQ, 0);
- nvic_set_priority (NVIC_EXTI15_10_IRQ, 1);
- nvic_set_priority (NVIC_USART6_IRQ, 2);
- nvic_set_priority (NVIC_ETH_IRQ, 3);
- nvic_set_priority (NVIC_SYSTICK_IRQ, 4) ;
+
+ nvic_set_priority (NVIC_EXTI2_IRQ, 0);
+ nvic_set_priority (NVIC_EXTI0_IRQ, 1);
+ nvic_set_priority (NVIC_EXTI15_10_IRQ, 2);
+ nvic_set_priority (NVIC_USART1_IRQ, 3);
+ nvic_set_priority (NVIC_ETH_IRQ, 4);
+ nvic_set_priority (NVIC_SYSTICK_IRQ, 5) ;
}
@@ -32,9 +56,13 @@ system_init (void)
msf_init();
dcf77_init();
+ printf ("LWIP\r\n");
start_lwip();
+ printf ("STETH\r\n");
steth_init();
+ //gps_init();
+
}
int
@@ -48,8 +76,12 @@ main (void)
while (1) {
- msf_dispatch();
- dcf77_dispatch();
+// msf_dispatch();
+// dcf77_dispatch();
+
+ //gps_dispatch();
+
+ cmd_dispatch();
dispatch_lwip();
steth_dispatch();
diff --git a/app/msf.c b/app/msf.c
index 2e7dd93..241998e 100644
--- a/app/msf.c
+++ b/app/msf.c
@@ -95,6 +95,8 @@ static void process_bits (uint64_t abs)
time_known = 1;
stats_stamp (u, abs);
+ dump_bits("msfa",bitsa);
+ dump_bits("msfb",bitsb);
printf ("MSF: Next minute is: %02d-%02d-%02d %02d:%02d\r\n", u.year, u.month, u.mday, u.hour, u.minute);
//time_print_epoch (msf_time);
@@ -171,7 +173,7 @@ void msf_dispatch (void)
abs = abs_extend (now);
msf_last_second = abs;
- pll_dispatch (abs);
+ //pll_dispatch (abs);
diff --git a/app/pins.h b/app/pins.h
index 16da24c..723ca82 100644
--- a/app/pins.h
+++ b/app/pins.h
@@ -1,4 +1,9 @@
+#define MAP_AF_100(a, af) do { \
+ gpio_mode_setup( a ## _PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, a ); \
+ gpio_set_output_options( a ## _PORT, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, a); \
+ gpio_set_af( a ## _PORT, af, a); \
+ } while (0)
#define MAP_AF(a, af) do { \
gpio_mode_setup( a ## _PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, a ); \
@@ -24,10 +29,14 @@
gpio_set_output_options( a ## _PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, a); \
} while (0)
+#define MAP_OUTPUT_PP_PU(a) do { \
+ gpio_mode_setup( a ## _PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, a ); \
+ gpio_set_output_options( a ## _PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, a); \
+ } while (0)
#define MAP_OUTPUT_OD(a) do { \
gpio_mode_setup( a ## _PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, a ); \
- gpio_set_output_options( a ## _PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, a); \
+ gpio_set_output_options( a ## _PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, a); \
} while (0)
diff --git a/app/pll.c b/app/pll.c
index 03d214c..742aad0 100644
--- a/app/pll.c
+++ b/app/pll.c
@@ -2,8 +2,8 @@
#define JUMP_THRESH 0.1
#define JUMP_TICKS 30
-#define FEEDBACK 0.000001
-#define WARM_UP 30
+#define FEEDBACK 0.01
+#define WARM_UP 3
static int64_t offset;
diff --git a/app/project.h b/app/project.h
index 013ceea..f3a49f1 100644
--- a/app/project.h
+++ b/app/project.h
@@ -13,7 +13,7 @@
#include <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