tnt has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-e1-hardware/+/29611 )
Change subject: icE1usb fw: Add Notify PPS on Carrier Detect option ......................................................................
icE1usb fw: Add Notify PPS on Carrier Detect option
This is disabled by default because turns out the kernel doesn't actually support PPS on CD for USB-CDC devices :(
And this also increase the interrupt traffic ...
Signed-off-by: Sylvain Munaut tnt@246tNt.com Change-Id: Ie5d163434323a23912228003add9870fafefedf9 --- M firmware/ice40-riscv/icE1usb/usb_desc_app.c M firmware/ice40-riscv/icE1usb/usb_gps.c 2 files changed, 66 insertions(+), 0 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-e1-hardware refs/changes/11/29611/1
diff --git a/firmware/ice40-riscv/icE1usb/usb_desc_app.c b/firmware/ice40-riscv/icE1usb/usb_desc_app.c index 25472e0..7dfc304 100644 --- a/firmware/ice40-riscv/icE1usb/usb_desc_app.c +++ b/firmware/ice40-riscv/icE1usb/usb_desc_app.c @@ -250,7 +250,11 @@ .bmAttributes = 0x03, /* Longest notif is SERIAL_STATE with 2 data bytes */ .wMaxPacketSize = sizeof(struct usb_ctrl_req) + 2, +#ifdef GPS_PPS_ON_CD + .bInterval = 1, +#else .bInterval = 0x40, +#endif }, .intf_data = { .bLength = sizeof(struct usb_intf_desc), diff --git a/firmware/ice40-riscv/icE1usb/usb_gps.c b/firmware/ice40-riscv/icE1usb/usb_gps.c index 1c10033..42da5a2 100644 --- a/firmware/ice40-riscv/icE1usb/usb_gps.c +++ b/firmware/ice40-riscv/icE1usb/usb_gps.c @@ -17,6 +17,7 @@ #include <no2usb/usb_cdc_proto.h>
#include "console.h" +#include "misc.h" #include "usb_desc_ids.h"
@@ -34,9 +35,23 @@ unsigned int rd; char data[BUF_SIZE] __attribute__((aligned(4))); } buf; + +#ifdef GPS_PPS_ON_CD + /* PPS tracking */ + struct { + uint32_t last; + bool set; + } pps; +#endif } g_usb_gps;
+struct usb_cdc_notif_serial_state { + struct usb_ctrl_req hdr; + uint16_t bits; +}; + + static void _usb_gps_set_active(bool active) { @@ -120,6 +135,53 @@ else ep_regs->bd[0].csr = 0; } + +#ifdef GPS_PPS_ON_CD + /* IN EP CTL: Send PPS pulse */ + ep_regs = &usb_ep_regs[USB_EP_GPS_CDC_CTL & 0x1f].in; + + if ((ep_regs->bd[0].csr & USB_BD_STATE_MSK) != USB_BD_STATE_RDY_DATA) + { + /* Default request */ + struct usb_cdc_notif_serial_state notif = { + .hdr = { + .bmRequestType = USB_REQ_READ | USB_REQ_TYPE_CLASS | USB_REQ_RCPT_INTF, + .bRequest = USB_NOTIF_CDC_SERIAL_STATE, + .wValue = 0, + .wIndex = USB_INTF_GPS_CDC_CTL, + .wLength = 2 + }, + .bits = 0x00 + }; + + /* Check if PPS occured */ + uint32_t pps_now = time_pps_read(); + + if (pps_now != g_usb_gps.pps.last) + { + /* Update last */ + g_usb_gps.pps.last = pps_now; + + /* Queue CD Set */ + notif.bits = 1; + usb_data_write(ep_regs->bd[0].ptr, ¬if, 12); + ep_regs->bd[0].csr = USB_BD_STATE_RDY_DATA | USB_BD_LEN(10); + + /* Need to clear in the future */ + g_usb_gps.pps.set = true; + } + else if (g_usb_gps.pps.set) + { + /* Queue CD Clear */ + notif.bits = 0; + usb_data_write(ep_regs->bd[0].ptr, ¬if, 12); + ep_regs->bd[0].csr = USB_BD_STATE_RDY_DATA | USB_BD_LEN(10); + + /* Cleared */ + g_usb_gps.pps.set = false; + } + } +#endif }