summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorroot <root@lab.ourano.james.local>2021-02-26 12:12:38 +0000
committerroot <root@lab.ourano.james.local>2021-02-26 12:12:38 +0000
commit3d48137c00511b3f2d35511482d1a76f8d06382d (patch)
treed75c88220cc847007869b0795a240c5077948262 /app
parent6d3a824e1cdae6e28146b7de380724b49488f3c2 (diff)
downloadclock-3d48137c00511b3f2d35511482d1a76f8d06382d.tar.gz
clock-3d48137c00511b3f2d35511482d1a76f8d06382d.tar.bz2
clock-3d48137c00511b3f2d35511482d1a76f8d06382d.zip
works
Diffstat (limited to 'app')
-rw-r--r--app/Makefile35
-rw-r--r--app/cdcacm.c213
-rw-r--r--app/dcf77.c2
-rw-r--r--app/dfu.c81
-rw-r--r--app/gps.c44
-rw-r--r--app/lwip/lwipopts.h5
-rw-r--r--app/lwip_glue.c36
-rw-r--r--app/main.c31
-rw-r--r--app/max7219.c44
-rw-r--r--app/project.h13
-rw-r--r--app/prototypes.h14
-rw-r--r--app/roofclock.ld20
-rw-r--r--app/stdio.c1
-rw-r--r--app/steth.c31
-rw-r--r--app/steth.h2
-rw-r--r--app/sysclk.c81
-rw-r--r--app/usart.c11
-rw-r--r--app/usb.c99
18 files changed, 689 insertions, 74 deletions
diff --git a/app/Makefile b/app/Makefile
index f38aea4..4a007a6 100644
--- a/app/Makefile
+++ b/app/Makefile
@@ -17,15 +17,16 @@
## along with this library. If not, see <http://www.gnu.org/licenses/>.
##
-LDSCRIPT = ../arch_max.ld
CPROTO=cproto
-PROG=msf
+PROG=roofclock
+
+LDSCRIPT = ${PROG}.ld
V=1
default: ${PROG}.elf
-CSRCS=led.c ticker.c ring.c usart.c stdio.c lwip_glue.c steth.c msf.c abs.c pll.c main.c time_fn.c ntp.c dcf77.c util.c stats.c gps.c hexdump.c bits.c max7219.c report.c sysclk.c cdcacm.c usb.c
+CSRCS=led.c ticker.c ring.c usart.c stdio.c lwip_glue.c steth.c msf.c abs.c pll.c main.c time_fn.c ntp.c dcf77.c util.c stats.c gps.c hexdump.c bits.c max7219.c report.c sysclk.c cdcacm.c usb.c dfu.c
HSRCS= events.h gps.h project.h ring.h steth.h time_fn.h ubx.h
@@ -69,7 +70,7 @@ OBJS=${MYOBJS} ${LWIP_OBJS}
include ../Makefile.include
CFLAGS+=-Wno-redundant-decls -Wno-unused-parameter
-CPPFLAGS += -I../libopencm3-local -I${LWIP_PATH}/${LWIP}/src/include -Ilwip -I${LWIP_PATH}/${LWIP}/src/include/ipv4 -I${LWIP_LOCAL}/port/stm32f4x7 -I.
+CPPFLAGS += -I.. -I../libopencm3-local -I${LWIP_PATH}/${LWIP}/src/include -Ilwip -I${LWIP_PATH}/${LWIP}/src/include/ipv4 -I${LWIP_LOCAL}/port/stm32f4x7 -I.
LDLIBS+= -lm
@@ -90,9 +91,35 @@ reset:
-c shutdown
+
+test-dfu: ${PROG}.dfu
+ ../dfu-util/src/dfu-util -v -R -a 0 -d ${VID}:${DID} -s 0x08004000:leave -D $<
+ $(Q)$(OOCD) -f ../oocd/interface/$(OOCD_INTERFACE).cfg \
+ -f ../oocd/board/$(OOCD_BOARD).cfg \
+ -c "init" -c "dump_image readback.img 0x8004000 0x7c000" \
+ -c shutdown
+
+ hexdump -C ${PROG}.dfu > a
+ hexdump -C readback.img> b
+ diff -uN a b > c
+
+
fl: ${PROG}.hex
ssh ${HOST} flash_stm32 < ${PROG}.hex
+
+DID=$(shell printf '\#include "id.h"\nID_PRODUCT' | ${CC} -I.. -E - | grep -v ^\# )
+VID=$(shell printf '\#include "id.h"\nID_VENDOR' | ${CC} -I.. -E - | grep -v ^\# )
+
+
+%.dfu: %.elf
+ @#printf " OBJCOPY $(*).dfu\n"
+ $(Q)$(OBJCOPY) -Obinary $(*).elf $(*).dfu
+
+dfu:${PROG}.dfu
+ dfu-util -R -a 0 -d ${VID}:${DID} -s 0x08004000:leave -D $<
+
+
program: ${PROG}.hex
scp $< ${HOST}:/tmp/img.hex
echo init | nc -t ${HOST} 4444
diff --git a/app/cdcacm.c b/app/cdcacm.c
new file mode 100644
index 0000000..213592e
--- /dev/null
+++ b/app/cdcacm.c
@@ -0,0 +1,213 @@
+#include "project.h"
+
+
+#define BUFFER_SIZE 512
+
+ring_t cdcacm_rx_ring;
+static uint8_t cdcacm_rx_ring_buf[BUFFER_SIZE];
+
+ring_t cdcacm_tx_ring;
+static uint8_t cdcacm_tx_ring_buf[BUFFER_SIZE];
+
+static int cdcacm_ready = 0;
+
+static const struct usb_endpoint_descriptor comm_endp[] = {
+ {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 0x83,
+ .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
+ .wMaxPacketSize = 16,
+ .bInterval = 255,
+ }
+};
+
+static const struct usb_endpoint_descriptor data_endp[] = {
+ {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 0x01,
+ .bmAttributes = USB_ENDPOINT_ATTR_BULK,
+ .wMaxPacketSize = 64,
+ .bInterval = 1,
+ },
+ {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 0x82,
+ .bmAttributes = USB_ENDPOINT_ATTR_BULK,
+ .wMaxPacketSize = 64,
+ .bInterval = 1,
+ }
+};
+
+static const struct {
+ struct usb_cdc_header_descriptor header;
+ struct usb_cdc_call_management_descriptor call_mgmt;
+ struct usb_cdc_acm_descriptor acm;
+ struct usb_cdc_union_descriptor cdc_union;
+} __attribute__ ((packed)) cdcacm_functional_descriptors = {
+ .header = {
+ .bFunctionLength = sizeof (struct usb_cdc_header_descriptor),
+ .bDescriptorType = CS_INTERFACE,
+ .bDescriptorSubtype = USB_CDC_TYPE_HEADER,
+ .bcdCDC = 0x0110,
+ },
+ .call_mgmt = {
+ .bFunctionLength =
+ sizeof (struct usb_cdc_call_management_descriptor),
+ .bDescriptorType = CS_INTERFACE,
+ .bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT,
+ .bmCapabilities = 0,
+ .bDataInterface = 1,
+ },
+ .acm = {
+ .bFunctionLength = sizeof (struct usb_cdc_acm_descriptor),
+ .bDescriptorType = CS_INTERFACE,
+ .bDescriptorSubtype = USB_CDC_TYPE_ACM,
+ .bmCapabilities = 0,
+ },
+ .cdc_union = {
+ .bFunctionLength = sizeof (struct usb_cdc_union_descriptor),
+ .bDescriptorType = CS_INTERFACE,
+ .bDescriptorSubtype = USB_CDC_TYPE_UNION,
+ .bControlInterface = 0,
+ .bSubordinateInterface0 = 1,
+ }
+};
+
+const struct usb_interface_descriptor comm_iface = {
+ .bLength = USB_DT_INTERFACE_SIZE,
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bInterfaceNumber = 0,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 1,
+ .bInterfaceClass = USB_CLASS_CDC,
+ .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
+ .bInterfaceProtocol = USB_CDC_PROTOCOL_AT,
+ .iInterface = 0,
+ .endpoint = comm_endp,
+ .extra = &cdcacm_functional_descriptors,
+ .extralen = sizeof (cdcacm_functional_descriptors)
+};
+
+const struct usb_interface_descriptor data_iface = {
+ .bLength = USB_DT_INTERFACE_SIZE,
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bInterfaceNumber = 1,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 2,
+ .bInterfaceClass = USB_CLASS_DATA,
+ .bInterfaceSubClass = 0,
+ .bInterfaceProtocol = 0,
+ .iInterface = 0,
+ .endpoint = data_endp,
+};
+
+
+
+
+static int cdcacm_control_request (usbd_device *usbd_dev,
+ struct usb_setup_data *req,
+ uint8_t **buf,
+ uint16_t *len,
+ usbd_control_complete_callback *complete)
+{
+ (void) complete;
+ (void) buf;
+ (void) usbd_dev;
+
+ if (dfu_control_request (usbd_dev, req, buf, len, complete))
+ return 1;
+
+
+ switch (req->bRequest) {
+ case USB_CDC_REQ_SET_CONTROL_LINE_STATE: {
+ /*
+ * This Linux cdc_acm driver requires this to be implemented
+ * even though it's optional in the CDC spec, and we don't
+ * advertise it in the ACM functional descriptor.
+ */
+ return 1;
+ }
+
+ case USB_CDC_REQ_SET_LINE_CODING:
+ if (*len < sizeof (struct usb_cdc_line_coding))
+ return 0;
+
+ return 1;
+ }
+
+ return 0;
+}
+
+
+
+void cdcacm_tick (void)
+{
+ unsigned ep = 0x82;
+ uint8_t buf[16];
+ uint8_t *ptr = buf;
+ size_t n = 0;
+
+ if (!cdcacm_ready)
+ return;
+
+
+ if (ring_empty (&cdcacm_tx_ring))
+ return;
+
+ /* Return if endpoint is already enabled. */
+ if (OTG_FS_DIEPTSIZ (ep & 0x7f) & OTG_DIEPSIZ0_PKTCNT)
+ return;
+
+ while (!ring_read_byte (&cdcacm_tx_ring, ptr++)) {
+ n++;
+
+ if (n == sizeof (buf)) break;
+ }
+
+ usbd_ep_write_packet (usb_device, ep, buf, n);
+}
+
+int cdcacm_write (char *ptr, int len, int blocking)
+{
+ int ret;
+
+ ret = ring_write (&cdcacm_tx_ring, (uint8_t *) ptr, len, blocking);
+ return ret;
+}
+
+
+
+static void cdcacm_data_rx_cb (usbd_device *usbd_dev, uint8_t ep)
+{
+ (void) ep;
+ uint8_t buf[64];
+ int len = usbd_ep_read_packet (usbd_dev, 0x01, buf, 64);
+
+ if (len)
+ ring_write (&cdcacm_rx_ring, buf, len, 0);
+}
+
+void cdcacm_set_config (usbd_device *usbd_dev, uint16_t wValue)
+{
+ (void) wValue;
+ usbd_ep_setup (usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb);
+ usbd_ep_setup (usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL);
+ usbd_ep_setup (usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
+ usbd_register_control_callback (usbd_dev,
+ USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
+ USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
+ cdcacm_control_request);
+
+ cdcacm_ready = 1;
+}
+
+void cdcacm_rings_init (void)
+{
+ ring_init (&cdcacm_rx_ring, cdcacm_rx_ring_buf, sizeof (cdcacm_rx_ring_buf));
+ ring_init (&cdcacm_tx_ring, cdcacm_tx_ring_buf, sizeof (cdcacm_tx_ring_buf));
+}
+
+
diff --git a/app/dcf77.c b/app/dcf77.c
index 124eea5..71c227c 100644
--- a/app/dcf77.c
+++ b/app/dcf77.c
@@ -124,7 +124,7 @@ void dcf77_dispatch (void)
{
static uint32_t last_0, last_1, last_s;
static int second, bit, had_m;
- uint32_t pulse_w,offset ;
+ uint32_t pulse_w, offset ;
static uint64_t abs;
int is_s = 0;
diff --git a/app/dfu.c b/app/dfu.c
new file mode 100644
index 0000000..c505585
--- /dev/null
+++ b/app/dfu.c
@@ -0,0 +1,81 @@
+#include "project.h"
+
+const struct usb_dfu_descriptor dfu_function = {
+ .bLength = sizeof (struct usb_dfu_descriptor),
+ .bDescriptorType = DFU_FUNCTIONAL,
+ .bmAttributes = USB_DFU_CAN_DOWNLOAD,
+ .wDetachTimeout = 255,
+ .wTransferSize = 1024,
+ .bcdDFUVersion = 0x011A,
+};
+
+const struct usb_interface_descriptor dfu_iface = {
+ .bLength = USB_DT_INTERFACE_SIZE,
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bInterfaceNumber = 2,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 0,
+ .bInterfaceClass = 0xFE,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 1,
+ .iInterface = 4,
+
+ .extra = &dfu_function,
+ .extralen = sizeof (dfu_function),
+};
+
+
+static int
+dfu_detach_complete (usbd_device *usbd_dev, struct usb_setup_data *req)
+{
+ (void) req;
+ (void) usbd_dev;
+ dfu_flag = 0xfee1dead;
+ //SCB_VTOR=0;
+
+ //SCB_AIRCR = SCB_AIRCR_VECTKEY | SCB_AIRCR_VECTRESET;
+ //SCB_AIRCR= SCB_AIRCR_SYSRESETREQ;
+
+ scb_reset_core();
+ return 1;
+}
+
+int
+dfu_control_request (usbd_device *usbd_dev, struct usb_setup_data *req,
+ uint8_t **buf, uint16_t *len,
+ usbd_control_complete_callback *complete)
+{
+ (void) buf;
+ (void) len;
+ (void) usbd_dev;
+
+ if ((req->bmRequestType & 0x7F) != 0x21) {
+ return 0; /* Only accept class request. */
+ }
+
+ switch (req->bRequest) {
+ case DFU_GETSTATUS: {
+ (*buf) [0] = DFU_STATUS_OK;
+ (*buf) [1] = 0;
+ (*buf) [2] = 0;
+ (*buf) [3] = 0;
+ (*buf) [4] = STATE_APP_IDLE;
+ (*buf) [5] = 0; /* iString not used here */
+ *len = 6;
+ return 1;
+ }
+
+ case DFU_GETSTATE:
+ /* Return state with no state transision. */
+ *buf[0] = STATE_APP_IDLE;
+ *len = 1;
+ return 1;
+
+ case DFU_DETACH:
+ *complete = dfu_detach_complete;
+ return 1;
+ }
+
+ return 0;
+}
+
diff --git a/app/gps.c b/app/gps.c
index 101413f..206f0c0 100644
--- a/app/gps.c
+++ b/app/gps.c
@@ -138,7 +138,7 @@ ubx_recv_nav_status (uint8_t *ptr, unsigned len)
uint8_t gps_fix, flags, fix_stat, flags2;
uint32_t d;
- unsigned kick_off_survey_mode=300;
+ unsigned kick_off_survey_mode = 300;
if ((!ptr) || (len != 16))
return -1;
@@ -175,7 +175,7 @@ ubx_recv_nav_status (uint8_t *ptr, unsigned len)
case 5:
fix = 'T';
gps_locked = 1;
- kick_off_survey_mode=0;
+ kick_off_survey_mode = 0;
break;
default:
@@ -205,6 +205,8 @@ ubx_recv_nav_status (uint8_t *ptr, unsigned len)
fix2 = '?';
}
+ max7219_report_fix (fix, fix2);
+
// printf ("fix: %c%c happy %d Fix %02x flags %02x fix_stat %02x flags2 %02x \r\n",fix,fix2,gps_happy, gps_fix, flags,fix_stat,flags2);
@@ -215,13 +217,13 @@ ubx_recv_nav_status (uint8_t *ptr, unsigned len)
gps_happy = 0;
- if (kick_off_survey_mode>0) {
- kick_off_survey_mode--;
+ if (kick_off_survey_mode > 0) {
+ kick_off_survey_mode--;
- if (!kick_off_survey_mode) {
- printf("GPS no time fix - kicking off survey mode\n");
- ubx_cfg_tmode (1, 0, 0, 0, 0, 3600, 3600); // 1 hour and 6cm
- }
+ if (!kick_off_survey_mode) {
+ printf ("GPS no time fix - kicking off survey mode\n");
+ ubx_cfg_tmode (1, 0, 0, 0, 0, 3600, 3600); // 1 hour and 6cm
+ }
}
return 0;
@@ -371,6 +373,7 @@ static int ubx_recv_nav_sbas (uint8_t *ptr, unsigned len)
int8_t sys;
uint8_t n;
+ if (!chatty_gps) return0 ;
ptr += ubx_get_u32 (ptr, &d4);
ptr += ubx_get_u8 (ptr, &prn);
@@ -381,7 +384,7 @@ static int ubx_recv_nav_sbas (uint8_t *ptr, unsigned len)
ptr += ubx_get_u8 (ptr, &n);
ptr += 3;
-// printf ("GPS SBAS PRN:%d M:%d S:%d SVC:%02x SVS:", prn, mode, sys, service);
+ printf ("GPS SBAS PRN:%d M:%d S:%d SVC:%02x SVS:", prn, mode, sys, service);
while (n--) {
ptr += ubx_get_u8 (ptr, &prn);
@@ -401,7 +404,7 @@ static int ubx_recv_nav_svinfo (uint8_t *ptr, unsigned len)
uint8_t n, flags, cflags;
const char *st;
- return 0;
+ if (!chatty_gps) return 0;
ptr += ubx_get_u32 (ptr, &d4);
ptr += ubx_get_u8 (ptr, &n);
@@ -485,6 +488,8 @@ static int ubx_recv_tim_svin (uint8_t *ptr, unsigned len)
printf ("TIM-SVIN dur %u var %u obs %u valid %02x active %02x\r\n",
(unsigned) dur, (unsigned) var, (unsigned) obs, valid, active);
+ max7219_report_svin (valid, active);
+
return 0;
}
@@ -750,6 +755,7 @@ static void gps_pps_dispatch (void)
if (gps_happy)
led3_set (v);
+
gps_ring.rx_ptr = (gps_ring.rx_ptr + 1) & ERING_MASK;
@@ -815,7 +821,8 @@ ubx_send (uint8_t class, uint8_t id, const void *_payload, unsigned len)
static int
ubx_handshake (uint8_t class, uint8_t id, const void *payload, unsigned len)
{
- uint32_t timeout=4000;
+ uint32_t timeout = 4000;
+ unsigned tries = 4;
ubx_ack = 0;
ubx_nack = 0;
@@ -825,15 +832,24 @@ ubx_handshake (uint8_t class, uint8_t id, const void *payload, unsigned len)
if (!timeout) {
printf ("GPS timeout resending packet\r\n");
+
+ if (!tries) {
+ printf ("GPS 3 timesout - resetting system\r\n");
+ usart2_drain();
+ scb_reset_system();
+ }
+
usart1_drain();
ubx_send (class, id, payload, len);
- timeout = 40000;
+ timeout = 4000;
+ tries--;
}
+
timeout--;
gps_dispatch();
- delay_ms(1);
+ delay_ms (1);
}
return !!ubx_nack;
@@ -1176,7 +1192,7 @@ gps_init (void)
ubx_cfg_poll (0x6, 0x16);
-// ubx_aid_ini (522202400, 1279080, 2900, 20000);
+ // ubx_aid_ini (522202400, 1279080, 2900, 20000);
printf ("GNSS ready\r\n");
#else
diff --git a/app/lwip/lwipopts.h b/app/lwip/lwipopts.h
index 3358cad..c590df9 100644
--- a/app/lwip/lwipopts.h
+++ b/app/lwip/lwipopts.h
@@ -86,7 +86,7 @@ a lot of data that needs to be copied, this should be set high. */
#define MEMP_NUM_TCP_SEG 12
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
timeouts. */
-#define MEMP_NUM_SYS_TIMEOUT 3
+#define MEMP_NUM_SYS_TIMEOUT 4
#define PBUF_POOL_FREE_OOSEQ 0
@@ -130,8 +130,9 @@ a lot of data that needs to be copied, this should be set high. */
/* Define LWIP_DHCP to 1 if you want DHCP configuration of
interfaces. DHCP is not implemented in lwIP 0.5.1, however, so
turning this on does currently not work. */
-#define LWIP_DHCP 0
+#define LWIP_DHCP 1
#define LWIP_AUTOIP 0
+#define LWIP_DHCP_BOOTP_FILE 0
/* ---------- UDP options ---------- */
diff --git a/app/lwip_glue.c b/app/lwip_glue.c
index 1e69fc0..9fed1e6 100644
--- a/app/lwip_glue.c
+++ b/app/lwip_glue.c
@@ -11,6 +11,11 @@ uint32_t sys_now (void)
void dispatch_lwip (void)
{
#if 0
+ static uint32_t fine_timer,coarse_timer;
+ uint32_t now=ticks;
+#endif
+
+#if 0
if (link_lost())
netif_set_down (&if0);
@@ -23,15 +28,14 @@ void dispatch_lwip (void)
sys_check_timeouts();
#if 0
-
/* Fine DHCP periodic process every 500ms */
- if (localtime - DHCPfineTimer >= DHCP_FINE_TIMER_MSECS) {
- DHCPfineTimer = localtime;
+ if (now - fine_timer >= DHCP_FINE_TIMER_MSECS) {
+ fine_timer = now;
dhcp_fine_tmr();
if ((DHCP_state != DHCP_ADDRESS_ASSIGNED) && (DHCP_state != DHCP_TIMEOUT)) {
/* toggle LED1 to indicate DHCP on-going process */
- STM_EVAL_LEDToggle (LED1);
+ //STM_EVAL_LEDToggle (LED1);
/* process DHCP state machine */
LwIP_DHCP_Process_Handle();
@@ -39,43 +43,31 @@ void dispatch_lwip (void)
}
/* DHCP Coarse periodic process every 60s */
- if (localtime - DHCPcoarseTimer >= DHCP_COARSE_TIMER_MSECS) {
- DHCPcoarseTimer = localtime;
+ if (now - coarse_timer >= DHCP_COARSE_TIMER_MSECS) {
+ coarse_timer = now;
dhcp_coarse_tmr();
}
-
#endif
+
}
void start_lwip (void)
{
- struct ip_addr ipaddr;
- struct ip_addr netmask;
- struct ip_addr gw;
-
- // uint8_t macaddress[6]={0,0,0,0,0,1};
lwip_init();
-#if 0
- IP4_ADDR (&ipaddr, 10, 32, 99, 73);
- IP4_ADDR (&netmask, 255, 255, 255, 0);
- IP4_ADDR (&gw, 10, 32, 99, 1);
-#else
- IP4_ADDR (&ipaddr, 10, 32, 96, 47);
- IP4_ADDR (&netmask, 255, 255, 255, 0);
- IP4_ADDR (&gw, 10, 32, 96, 1);
-#endif
- netif_add (&if0, &ipaddr, &netmask, &gw, NULL, steth_lwip_init, ethernet_input);
+ netif_add (&if0, NULL,NULL,NULL, NULL, steth_lwip_init, ethernet_input);
/* Registers the default network interface.*/
netif_set_default (&if0);
netif_set_up (&if0);
+ dhcp_start(&if0);
+
}
diff --git a/app/main.c b/app/main.c
index 22ee23e..d5b5ec4 100644
--- a/app/main.c
+++ b/app/main.c
@@ -221,7 +221,7 @@ static void ptp_clock_start (void)
static void clock_setup (void)
{
-static uint32_t fail;
+ static uint32_t fail;
/*
* Caution, The PLL is somewhat rubbish, and causes all sorts of misery
* so sysclk isn't really a reference, if we use it, however not using it
@@ -240,16 +240,16 @@ static uint32_t fail;
/* confiure HSE as input not oscillator */
- rcc_osc_bypass_enable (HSE);
+ rcc_osc_bypass_enable (HSE);
rcc_osc_on (HSE);
while ((RCC_CR & RCC_CR_HSERDY) == 0) {
- if (fail++ == 4000000) {
- /*No external clock, try seeing if we have a crystal */
- rcc_osc_off (HSE);
- rcc_osc_bypass_disable (HSE);
- rcc_osc_on (HSE);
- }
+ if (fail++ == 4000000) {
+ /*No external clock, try seeing if we have a crystal */
+ rcc_osc_off (HSE);
+ rcc_osc_bypass_disable (HSE);
+ rcc_osc_on (HSE);
+ }
}
/* turn off SSC */
@@ -372,6 +372,7 @@ board_setup (void)
nvic_set_priority (NVIC_USART2_IRQ, 0x30);
nvic_set_priority (NVIC_ETH_IRQ, 0x40);
nvic_set_priority (NVIC_SYSTICK_IRQ, 0x50);
+ nvic_set_priority (NVIC_OTG_FS_IRQ, 0x60);
// nvic_enable_irq (NVIC_EXTI15_10_IRQ);
@@ -382,32 +383,42 @@ board_setup (void)
static void
system_init (void)
{
+ cdcacm_rings_init();
+ usart_rings_init();
board_setup();
timer_setup();
led_init();
+
ticker_init();
usart_init();
+ usb_init();
+
msf_init();
dcf77_init();
+
+ steth_calculate_mac();
printf ("LWIP\r\n");
start_lwip();
printf ("STETH\r\n");
+
+
steth_init();
ptp_clock_start();
max7219_init (1, 8);
+
gps_init();
ntp_init();
- usb_init();
+
}
@@ -456,7 +467,7 @@ main (void)
dispatch_lwip();
max7219_dispatch();
- cdcacm_dispatch();
+
}
diff --git a/app/max7219.c b/app/max7219.c
index 8c1c859..85e66a7 100644
--- a/app/max7219.c
+++ b/app/max7219.c
@@ -115,10 +115,10 @@ write_regs (uint8_t reg, uint8_t data1, uint8_t data2, uint8_t data3)
unlock();
}
-static void write_pair (uint8_t reg, int d1, int d2, int d3)
+static void write_triad (uint8_t reg, int d1, int d2, int d3, unsigned dm)
{
- write_regs (reg, d1 / 10, d2 / 10, d3 / 10);
- write_regs (reg - 1, (d1 % 10) | 0x80, (d2 % 10) | 0x80, (d3 % 10) | 0x80);
+ write_regs (reg++, (d1 % 10) | ((dm & 0x1) ? 0x80 : 0), (d2 % 10) | ((dm & 0x4) ? 0x80 : 0), (d3 % 10) | ((dm & 0x10) ? 0x80 : 0));
+ write_regs (reg, (d1 / 10) | ((dm & 0x2) ? 0x80 : 0), (d2 / 10) | ((dm & 0x8) ? 0x80 : 0), (d3 / 10) | ((dm & 0x20) ? 0x80 : 0));
}
@@ -153,6 +153,29 @@ static void st_test (void)
#endif
+unsigned fix_dots, fix_dots_even;
+
+void max7219_report_fix (char fix, char fix2)
+{
+ fix_dots = 0;
+
+
+ if (fix == 'L')
+ fix_dots |= 0x1;
+
+ if (fix2 == 'D') fix_dots |= 0x4;
+
+ if (fix == 'T') fix_dots |= 0x11;
+}
+
+void max7219_report_svin (int valid, int active)
+{
+ fix_dots_even = 0;
+
+ if (active || valid) fix_dots_even |= 0x10;
+}
+
+
void max7219_dispatch (void)
{
uint32_t now = HW_CLOCK_REG;
@@ -162,6 +185,8 @@ void max7219_dispatch (void)
UTC u;
UTC gu;
ST l;
+ unsigned last_dots;
+
e = pll_decompose (abs);
@@ -171,10 +196,15 @@ void max7219_dispatch (void)
e.s += gps_utc_diff;
gu = time_epoch_to_utc (e);
- write_pair (8, u.hour, l.hour, gps_wday);
- write_pair (6, u.minute, l.minute, gu.hour);
- write_pair (4, u.second, l.second, gu.minute);
- write_pair (2, u.nanosecond / 10000000, l.nanosecond / 10000000, gu.second);
+ last_dots = fix_dots;
+
+ if (u.nanosecond < 500000000) last_dots |= fix_dots_even;
+
+
+ write_triad (1, u.nanosecond / 10000000, l.nanosecond / 10000000, gu.second, last_dots);
+ write_triad (3, u.second, l.second, gu.minute, 0x15);
+ write_triad (5, u.minute, l.minute, gu.hour, 0x15);
+ write_triad (7, u.hour, l.hour, gps_wday, 0x15);
if (u.minute == m) return;
diff --git a/app/project.h b/app/project.h
index 5785628..ca623de 100644
--- a/app/project.h
+++ b/app/project.h
@@ -27,14 +27,16 @@
#include <libopencm3/stm32/syscfg.h>
#include <libopencm3/stm32/otg_common.h>
#include <libopencm3/stm32/otg_fs.h>
+#include <libopencm3/stm32/desig.h>
/* Drivers */
#include <libopencm3/ethernet/mac_stm32fxx7.h>
#include <libopencm3/ethernet/phy.h>
#include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/cdc.h>
-#ifdef INCLUDE_DFU_INTERFACE
#include <libopencm3/usb/dfu.h>
-#endif
+
+#include "id.h"
+
@@ -44,7 +46,7 @@
#include <lwip/mem.h>
#include <lwip/memp.h>
#include <lwip/timers.h>
-#include <lwip/timers.h>
+#include <lwip/dhcp.h>
#include <netif/etharp.h>
#include "time_fn.h"
@@ -84,5 +86,6 @@
extern const unsigned char almanac_alp[];
extern unsigned int almanac_alp_len;
-#define ID_VENDOR 0x0483
-#define ID_PRODUCT 0x5740
+extern uint32_t dfu_flag;
+
+
diff --git a/app/prototypes.h b/app/prototypes.h
index f409da8..4b20c86 100644
--- a/app/prototypes.h
+++ b/app/prototypes.h
@@ -33,6 +33,7 @@ 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_rings_init(void);
extern void usart_init(void);
/* stdio.c */
extern int _open(const char *name, int flags, int mode);
@@ -49,6 +50,7 @@ extern uint32_t sys_now(void);
extern void dispatch_lwip(void);
extern void start_lwip(void);
/* steth.c */
+extern void steth_calculate_mac(void);
extern void eth_isr(void);
extern void steth_isr(void);
extern err_t steth_lwip_init(struct netif *netif);
@@ -119,6 +121,10 @@ extern void hexdump(void *_d, int len);
/* bits.c */
extern void dump_bits(char *wot, uint8_t *bits);
/* max7219.c */
+extern unsigned fix_dots;
+extern unsigned fix_dots_even;
+extern void max7219_report_fix(char fix, char fix2);
+extern void max7219_report_svin(int valid, int active);
extern void max7219_dispatch(void);
extern void max7219_init(int on, int brightness);
/* report.c */
@@ -133,11 +139,15 @@ extern ring_t cdcacm_tx_ring;
extern const struct usb_interface_descriptor comm_iface;
extern const struct usb_interface_descriptor data_iface;
extern void cdcacm_tick(void);
+extern int cdcacm_write(char *ptr, int len, int blocking);
extern void cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue);
-extern void cdcacm_init(void);
-extern void cdcacm_dispatch(void);
+extern void cdcacm_rings_init(void);
/* usb.c */
extern uint8_t usbd_control_buffer[128];
extern usbd_device *usb_device;
extern void otg_fs_isr(void);
extern void usb_init(void);
+/* dfu.c */
+extern const struct usb_dfu_descriptor dfu_function;
+extern const struct usb_interface_descriptor dfu_iface;
+extern int dfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf, uint16_t *len, usbd_control_complete_callback *complete);
diff --git a/app/roofclock.ld b/app/roofclock.ld
new file mode 100644
index 0000000..325e7ce
--- /dev/null
+++ b/app/roofclock.ld
@@ -0,0 +1,20 @@
+/* Linker script for STM32F407VET6, 512K flash, 192K RAM. */
+
+/* Define memory regions. */
+MEMORY
+{
+ rom (rx) : ORIGIN = 0x08004000, LENGTH = 496K
+ ram (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
+}
+
+/* Include the common ld script. */
+INCLUDE libopencm3_stm32f4.ld
+
+dfu_shared_location = ORIGIN(ram) + LENGTH(ram) - 1024;
+
+SECTIONS
+{
+ .dfu_shared dfu_shared_location :{
+ dfu_flag = .;
+ }
+}
diff --git a/app/stdio.c b/app/stdio.c
index 9a8c74a..c1015dc 100644
--- a/app/stdio.c
+++ b/app/stdio.c
@@ -28,6 +28,7 @@ _write (int file,
ret = usart2_write (buf, nbytes, 1);
+ cdcacm_write (buf, nbytes, 0);
if (ret < 0) {
errno = -ret;
diff --git a/app/steth.c b/app/steth.c
index 26429aa..5b94e1d 100644
--- a/app/steth.c
+++ b/app/steth.c
@@ -14,7 +14,7 @@ static int ready;
static uint8_t __attribute__ ((aligned (4))) eth_buf[ETH_BUF_LEN];
-static uint8_t sa[ETHARP_HWADDR_LEN] = { 0xc0, 0xf1, 0xee, 0xc0, 0xff, 0xdd };
+static uint8_t sa[ETHARP_HWADDR_LEN];
extern uint32_t TxBD;
extern uint32_t RxBD;
@@ -32,6 +32,29 @@ extern uint32_t RxBD;
+void steth_calculate_mac(void)
+{
+ uint32_t uid[3];
+ uint8_t *ptr;
+ unsigned i;
+ desig_get_unique_id (uid);
+
+ ptr=(uint8_t *)uid;
+
+ for (i=0;i<ETHARP_HWADDR_LEN;++i)
+ sa[i]^=*(ptr++);
+ for (i=0;i<ETHARP_HWADDR_LEN;++i)
+ sa[i]^=*(ptr++);
+
+ sa[0]&=0xfe; /*Clear I/G */
+ sa[0]|=0x2; /*Set U/L */
+
+printf("MAC ADDRESS is %02x:%02x:%02x:%02x:%02x:%02x\r\n",sa[0],sa[1],sa[2],sa[3],sa[4],sa[5]);
+}
+
+
+
+
static void mac_stat (void)
{
//uint32_t d, s;
@@ -122,6 +145,7 @@ steth_rx (void)
struct pbuf *p;
uint32_t len;
+
p = pbuf_alloc (PBUF_RAW, MTU, PBUF_POOL);
if (!p) return ERR_MEM;
@@ -166,6 +190,7 @@ steth_lwip_init (struct netif *netif)
{
LWIP_ASSERT ("netif != NULL", (netif != NULL));
+
#if LWIP_NETIF_HOSTNAME
/* Initialize interface hostname */
netif->hostname = "lwip";
@@ -297,8 +322,8 @@ static void eth_reset (void)
phy_stat();
eth_set_mac (sa);
- eth_enable_checksum_offload();
eth_desc_init (eth_buf, TX_BUFS, RX_BUFS, FRAME_SZ, FRAME_SZ, 1);
+ // eth_enable_checksum_offload();
eth_irq_enable (ETH_DMAIER_NISE);
eth_irq_enable (ETH_DMAIER_RIE);
@@ -314,6 +339,8 @@ static void eth_start_an (void)
phy_autoneg_enable (PHY);
}
+
+
void
steth_init (void)
{
diff --git a/app/steth.h b/app/steth.h
index ca752a7..f4efee1 100644
--- a/app/steth.h
+++ b/app/steth.h
@@ -1,5 +1,5 @@
-#define PHY PHY0
+#define PHY PHY1
#define TXEN GPIO11
#define TXEN_PORT GPIOG
diff --git a/app/sysclk.c b/app/sysclk.c
new file mode 100644
index 0000000..1847c28
--- /dev/null
+++ b/app/sysclk.c
@@ -0,0 +1,81 @@
+#include "project.h"
+
+
+
+static Event_ring sysclk_ring;
+
+void sysclk_event (void)
+{
+ uint32_t refclk_now = HW_CLOCK_REG;
+ uint32_t sysclk_now = SCS_DWT_CYCCNT;
+
+
+ sysclk_ring.events[sysclk_ring.tx_ptr].when = refclk_now;
+ sysclk_ring.events[sysclk_ring.tx_ptr].value = sysclk_now;
+ sysclk_ring.tx_ptr = (sysclk_ring.tx_ptr + 1) & ERING_MASK;
+
+}
+
+static uint32_t high_tick;
+
+#define QUARTER (1UL << 29)
+#define HALF (1UL << 30)
+#define THREE_QUARTERS (HALF+QUARTER)
+#define ONE (~(uint32_t)0)
+
+uint64_t sysclk_extend (uint32_t now)
+{
+ static int m;
+ uint64_t ret;
+
+
+ if (!m) {
+ ret = high_tick;
+ ret <<= 32;
+ ret |= now;
+
+
+ if ((now > THREE_QUARTERS) && (now <= ONE)) {
+ high_tick++;
+ m = 1;
+ }
+
+ } else {
+ if (now < HALF) {
+ ret = high_tick;
+ ret <<= 32;
+ ret |= now;
+ } else {
+ ret = high_tick - 1;
+ ret <<= 32;
+ ret |= now;
+ }
+
+ if ((now > QUARTER) && (now < HALF))
+ m = 0;
+ }
+
+ return ret;
+}
+void sysclk_dispatch (void)
+{
+ //char buf[80];
+ uint64_t refclk_abs;
+ uint32_t refclk_now, sysclk_now;
+ EPOCH e;
+ //UTC u;
+
+ if (sysclk_ring.rx_ptr == sysclk_ring.tx_ptr) return;
+
+ sysclk_now = sysclk_ring.events[sysclk_ring.rx_ptr].value;
+ refclk_now = sysclk_ring.events[sysclk_ring.rx_ptr].when;
+ sysclk_ring.rx_ptr = (sysclk_ring.rx_ptr + 1) & ERING_MASK;
+
+ refclk_abs = abs_extend (refclk_now);
+ e.s = sysclk_extend (sysclk_now);
+ e.ns = 0;
+
+ report_time ("SYS", e, refclk_abs, "");
+}
+
+
diff --git a/app/usart.c b/app/usart.c
index 5d5614d..26616da 100644
--- a/app/usart.c
+++ b/app/usart.c
@@ -137,13 +137,18 @@ usart1_write (char *ptr, int len, int blocking)
return ret;
}
+void usart_rings_init (void)
+{
+ ring_init (&rx1_ring, rx1_ring_buf, sizeof (rx1_ring_buf));
+ ring_init (&tx1_ring, tx1_ring_buf, sizeof (tx1_ring_buf));
+ ring_init (&rx2_ring, rx2_ring_buf, sizeof (rx2_ring_buf));
+ ring_init (&tx2_ring, tx2_ring_buf, sizeof (tx2_ring_buf));
+}
void
usart_init (void)
{
- ring_init (&rx2_ring, rx2_ring_buf, sizeof (rx2_ring_buf));
- ring_init (&tx2_ring, tx2_ring_buf, sizeof (tx2_ring_buf));
MAP_OUTPUT_PP (RX2_EN);
SET (RX2_EN);
@@ -166,8 +171,6 @@ usart_init (void)
nvic_enable_irq (NVIC_USART2_IRQ);
- ring_init (&rx1_ring, rx1_ring_buf, sizeof (rx1_ring_buf));
- ring_init (&tx1_ring, tx1_ring_buf, sizeof (tx1_ring_buf));
MAP_INPUT (RX1);
MAP_AF (TX1, GPIO_AF7);
diff --git a/app/usb.c b/app/usb.c
new file mode 100644
index 0000000..053f126
--- /dev/null
+++ b/app/usb.c
@@ -0,0 +1,99 @@
+#include "project.h"
+
+#define USB_DM GPIO11
+#define USB_DM_PORT GPIOA
+#define USB_DP GPIO12
+#define USB_DP_PORT GPIOA
+
+/* Buffer to be used for control requests. */
+uint8_t usbd_control_buffer[128];
+usbd_device *usb_device;
+
+static const struct usb_device_descriptor dev = {
+ .bLength = USB_DT_DEVICE_SIZE,
+ .bDescriptorType = USB_DT_DEVICE,
+ .bcdUSB = 0x0200,
+ .bDeviceClass = USB_CLASS_CDC,
+ .bDeviceSubClass = 0,
+ .bDeviceProtocol = 0,
+ .bMaxPacketSize0 = 64,
+ .idVendor = ID_VENDOR,
+ .idProduct = ID_PRODUCT,
+ .bcdDevice = 0x0200,
+ .iManufacturer = 1,
+ .iProduct = 2,
+ .iSerialNumber = 3,
+ .bNumConfigurations = 1,
+};
+
+
+static const struct usb_interface ifaces[] = {
+ {
+ .num_altsetting = 1,
+ .altsetting = &comm_iface,
+ },
+ {
+ .num_altsetting = 1,
+ .altsetting = &data_iface,
+ },
+ {
+ .num_altsetting = 1,
+ .altsetting = &dfu_iface,
+ },
+};
+
+static const struct usb_config_descriptor config = {
+ .bLength = USB_DT_CONFIGURATION_SIZE,
+ .bDescriptorType = USB_DT_CONFIGURATION,
+ .wTotalLength = 0,
+ .bNumInterfaces = 3,
+ .bConfigurationValue = 1,
+ .iConfiguration = 0,
+ .bmAttributes = 0x80,
+ .bMaxPower = 0x32,
+ .interface = ifaces,
+};
+
+static const char *usb_strings[] = {
+ VENDOR_NAME,
+ PRODUCT_NAME,
+ SERIAL_NUMBER,
+ "DFU",
+};
+
+void otg_fs_isr (void)
+{
+ usbd_poll (usb_device);
+}
+
+
+
+
+void usb_init (void)
+{
+ MAP_AF_100 (USB_DP, GPIO_AF10);
+ MAP_AF_100 (USB_DM, GPIO_AF10);
+
+
+ usb_device = usbd_init (&otgfs_usb_driver,
+ &dev,
+ &config,
+ usb_strings,
+ 4,
+ usbd_control_buffer,
+ sizeof (usbd_control_buffer));
+
+ /* Disable VBUS sensing */
+
+ OTG_FS_GCCFG |= OTG_GCCFG_NOVBUSSENS;
+ OTG_FS_GCCFG &= ~OTG_GCCFG_VBUSASEN;
+ OTG_FS_GCCFG &= ~OTG_GCCFG_VBUSBSEN;
+
+ usbd_register_set_config_callback (usb_device, cdcacm_set_config);
+
+
+ nvic_enable_irq (NVIC_OTG_FS_IRQ);
+
+}
+
+