]> git.donarmstrong.com Git - kiibohd-controller.git/blobdiff - Bootloader/kinetis.c
Adding examples of custom action/capabilties
[kiibohd-controller.git] / Bootloader / kinetis.c
index da6c9f76c083f84bcab8ad79998df3464399ccab..e65b12b1aaf007d9d4e90f1796a820b28dbb2a74 100644 (file)
@@ -55,272 +55,272 @@ static struct USB_BD_t bdt[USB_MAX_EP * 2 *2] __attribute__((section(".usbdescri
 static struct USB_BD_t *
 usb_get_bd(struct usbd_ep_pipe_state_t *s)
 {
-        return (&bdt[(s->ep_num << 2) | (s->ep_dir << 1) | s->pingpong]);
+       return (&bdt[(s->ep_num << 2) | (s->ep_dir << 1) | s->pingpong]);
 }
 
 static struct USB_BD_t *
 usb_get_bd_stat(struct USB_STAT_t *stat)
 {
-        return (((void *)(uintptr_t)bdt + (stat->raw << 1)));
+       return (((void *)(uintptr_t)bdt + (stat->raw << 1)));
 }
 
 void *usb_get_xfer_data(struct usb_xfer_info *i)
 {
-        return (usb_get_bd_stat(i)->addr);
+       return (usb_get_bd_stat(i)->addr);
 }
 
 enum usb_tok_pid usb_get_xfer_pid(struct usb_xfer_info *i)
 {
-        return (usb_get_bd_stat(i)->tok_pid);
+       return (usb_get_bd_stat(i)->tok_pid);
 }
 
 int usb_get_xfer_ep(struct usb_xfer_info *i)
 {
-        return (i->ep);
+       return (i->ep);
 }
 
 enum usb_ep_dir usb_get_xfer_dir(struct usb_xfer_info *i)
 {
-        return (i->dir);
+       return (i->dir);
 }
 
 void usb_enable_xfers(void)
 {
-        USB0.ctl.raw = ((struct USB_CTL_t){
-                        .txd_suspend = 0,
-                                .usben = 1
-                                }).raw;
+       USB0.ctl.raw = ((struct USB_CTL_t){
+                       .txd_suspend = 0,
+                               .usben = 1
+                               }).raw;
 }
 
 void usb_set_addr(int addr)
 {
-        USB0.addr.raw = addr;
+       USB0.addr.raw = addr;
 }
 
 
 void usb_pipe_stall(struct usbd_ep_pipe_state_t *s)
 {
-        volatile struct USB_BD_t *bd = usb_get_bd(s);
-        bd->raw = ((struct USB_BD_BITS_t){
-                        .stall = 1,
-                                .own = 1
-                                }).raw;
+       volatile struct USB_BD_t *bd = usb_get_bd(s);
+       bd->raw = ((struct USB_BD_BITS_t){
+                       .stall = 1,
+                               .own = 1
+                               }).raw;
 }
 
 void usb_pipe_unstall(struct usbd_ep_pipe_state_t *s)
 {
-        volatile struct USB_BD_t *bd = usb_get_bd(s);
-        struct USB_BD_BITS_t state = { .raw = bd->raw };
+       volatile struct USB_BD_t *bd = usb_get_bd(s);
+       struct USB_BD_BITS_t state = { .raw = bd->raw };
 
-        if (state.own && state.stall)
-                bd->raw = 0;
+       if (state.own && state.stall)
+               bd->raw = 0;
 }
 
 void usb_pipe_enable(struct usbd_ep_pipe_state_t *s)
 {
-        USB0.endpt[s->ep_num].raw |= ((struct USB_ENDPT_t){
-                        .eptxen = s->ep_dir == USB_EP_TX,
-                                .eprxen = s->ep_dir == USB_EP_RX,
-                                .ephshk = 1, /* XXX ISO */
-                                .epctldis = s->ep_num != 0
-                                }).raw;
+       USB0.endpt[s->ep_num].raw |= ((struct USB_ENDPT_t){
+                       .eptxen = s->ep_dir == USB_EP_TX,
+                               .eprxen = s->ep_dir == USB_EP_RX,
+                               .ephshk = 1, /* XXX ISO */
+                               .epctldis = s->ep_num != 0
+                               }).raw;
 }
 
 void usb_pipe_disable(struct usbd_ep_pipe_state_t *s)
 {
-        USB0.endpt[s->ep_num].raw &= ~((struct USB_ENDPT_t){
-                        .eptxen = s->ep_dir == USB_EP_TX,
-                                .eprxen = s->ep_dir == USB_EP_RX,
-                                .epctldis = 1
-                                }).raw;
+       USB0.endpt[s->ep_num].raw &= ~((struct USB_ENDPT_t){
+                       .eptxen = s->ep_dir == USB_EP_TX,
+                               .eprxen = s->ep_dir == USB_EP_RX,
+                               .epctldis = 1
+                               }).raw;
 }
 
 size_t usb_ep_get_transfer_size(struct usbd_ep_pipe_state_t *s)
 {
-        struct USB_BD_t *bd = usb_get_bd(s);
-        return (bd->bc);
+       struct USB_BD_t *bd = usb_get_bd(s);
+       return (bd->bc);
 }
 
 void usb_queue_next(struct usbd_ep_pipe_state_t *s, void *addr, size_t len)
 {
-        volatile struct USB_BD_t *bd = usb_get_bd(s);
-
-        bd->addr = addr;
-        /* damn you bitfield problems */
-        bd->raw = ((struct USB_BD_BITS_t){
-                        .dts = 1,
-                                .own = 1,
-                                .data01 = s->data01,
-                                .bc = len,
-                                }).raw;
+       volatile struct USB_BD_t *bd = usb_get_bd(s);
+
+       bd->addr = addr;
+       /* damn you bitfield problems */
+       bd->raw = ((struct USB_BD_BITS_t){
+                       .dts = 1,
+                               .own = 1,
+                               .data01 = s->data01,
+                               .bc = len,
+                               }).raw;
 }
 
 static void usb_reset(void)
 {
-        /* reset pingpong state */
-        /* For some obscure reason, we need to use or here. */
-        USB0.ctl.raw |= ((struct USB_CTL_t){
-                        .txd_suspend = 1,
-                                .oddrst = 1,
-                                }).raw;
-
-        /* clear all interrupt bits - not sure if needed */
-        USB0.istat.raw = 0xff;
-        USB0.errstat.raw = 0xff;
-        USB0.otgistat.raw = 0xff;
-
-        /* zap also BDT pingpong & queued transactions */
-        memset(bdt, 0, sizeof(bdt));
-        USB0.addr.raw = 0;
-
-        usb_restart();
-
-        USB0.ctl.raw = ((struct USB_CTL_t){
-                               .txd_suspend = 0,
-                                .usben = 1
-                                }).raw;
-
-        /* we're only interested in reset and transfers */
-        USB0.inten.raw = ((struct USB_ISTAT_t){
-                               .tokdne = 1,
-                                .usbrst = 1,
-                                .stall = 1,
-                                .sleep = 1,
-                                }).raw;
-
-        USB0.usbtrc0.usbresmen = 0;
-        USB0.usbctrl.susp = 0;
+       /* reset pingpong state */
+       /* For some obscure reason, we need to use or here. */
+       USB0.ctl.raw |= ((struct USB_CTL_t){
+                       .txd_suspend = 1,
+                               .oddrst = 1,
+                               }).raw;
+
+       /* clear all interrupt bits - not sure if needed */
+       USB0.istat.raw = 0xff;
+       USB0.errstat.raw = 0xff;
+       USB0.otgistat.raw = 0xff;
+
+       /* zap also BDT pingpong & queued transactions */
+       memset(bdt, 0, sizeof(bdt));
+       USB0.addr.raw = 0;
+
+       usb_restart();
+
+       USB0.ctl.raw = ((struct USB_CTL_t){
+                               .txd_suspend = 0,
+                               .usben = 1
+                               }).raw;
+
+       /* we're only interested in reset and transfers */
+       USB0.inten.raw = ((struct USB_ISTAT_t){
+                               .tokdne = 1,
+                               .usbrst = 1,
+                               .stall = 1,
+                               .sleep = 1,
+                               }).raw;
+
+       USB0.usbtrc0.usbresmen = 0;
+       USB0.usbctrl.susp = 0;
 }
 
 void usb_enable(void)
 {
-        SIM.sopt2.usbsrc = 1;   /* usb from mcg */
-        SIM.scgc4.usbotg = 1;   /* enable usb clock */
-
-        /* reset module - not sure if needed */
-        USB0.usbtrc0.raw = ((struct USB_USBTRC0_t){
-                               .usbreset = 1,
-                                .usbresmen = 1
-                                }).raw;
-        while (USB0.usbtrc0.usbreset)
-                /* NOTHING */;
-
-        USB0.bdtpage1 = (uintptr_t)bdt >> 8;
-        USB0.bdtpage2 = (uintptr_t)bdt >> 16;
-        USB0.bdtpage3 = (uintptr_t)bdt >> 24;
-
-        USB0.control.raw = ((struct USB_CONTROL_t){
-                               .dppullupnonotg = 1 /* enable pullup */
-                                }).raw;
-
-        USB0.usbctrl.raw = 0; /* resume peripheral & disable pulldowns */
-        usb_reset();          /* this will start usb processing */
-
-        /* really only one thing we want */
-        USB0.inten.raw = ((struct USB_ISTAT_t){
-                                .usbrst = 1,
-                                }).raw;
-
-        /**
-         * Suspend transceiver now - we'll wake up at reset again.
-         */
+       SIM.sopt2.usbsrc = 1;   /* usb from mcg */
+       SIM.scgc4.usbotg = 1;   /* enable usb clock */
+
+       /* reset module - not sure if needed */
+       USB0.usbtrc0.raw = ((struct USB_USBTRC0_t){
+                               .usbreset = 1,
+                               .usbresmen = 1
+                               }).raw;
+       while (USB0.usbtrc0.usbreset)
+               /* NOTHING */;
+
+       USB0.bdtpage1 = (uintptr_t)bdt >> 8;
+       USB0.bdtpage2 = (uintptr_t)bdt >> 16;
+       USB0.bdtpage3 = (uintptr_t)bdt >> 24;
+
+       USB0.control.raw = ((struct USB_CONTROL_t){
+                               .dppullupnonotg = 1 /* enable pullup */
+                               }).raw;
+
+       USB0.usbctrl.raw = 0; /* resume peripheral & disable pulldowns */
+       usb_reset();          /* this will start usb processing */
+
+       /* really only one thing we want */
+       USB0.inten.raw = ((struct USB_ISTAT_t){
+                               .usbrst = 1,
+                               }).raw;
+
+       /**
+        * Suspend transceiver now - we'll wake up at reset again.
+        */
        // TODO - Possible removal
-        USB0.usbctrl.susp = 1;
-        USB0.usbtrc0.usbresmen = 1;
+       USB0.usbctrl.susp = 1;
+       USB0.usbtrc0.usbresmen = 1;
 }
 
 void USB0_Handler(void)
 {
-        struct USB_ISTAT_t stat = {.raw = USB0.istat.raw };
-
-        if (stat.usbrst) {
-                usb_reset();
-                return;
-        }
-        if (stat.stall) {
-                /* XXX need more work for non-0 ep */
-                volatile struct USB_BD_t *bd = usb_get_bd(&usb.ep_state[0].rx);
-                if (bd->stall)
-                        usb_setup_control();
-        }
-        if (stat.tokdne) {
-                struct usb_xfer_info stat = USB0.stat;
-                usb_handle_transaction(&stat);
-        }
-        if (stat.sleep) {
-                USB0.inten.sleep = 0;
-                USB0.inten.resume = 1;
-                USB0.usbctrl.susp = 1;
-                USB0.usbtrc0.usbresmen = 1;
-
-                /**
-                 * Clear interrupts now so that we can detect a fresh
-                 * resume later on.
-                 */
-                USB0.istat.raw = stat.raw;
-
-                const struct usbd_config *c = usb_get_config_data(-1);
-                if (c && c->suspend)
-                        c->suspend();
-        }
-        /**
-         * XXX it is unclear whether we will receive a synchronous
-         * resume interrupt if we were in sleep.  This code assumes we
-         * do.
-         */
-        if (stat.resume || USB0.usbtrc0.usb_resume_int) {
-                USB0.inten.resume = 0;
-                USB0.inten.sleep = 1;
-                USB0.usbtrc0.usbresmen = 0;
-                USB0.usbctrl.susp = 0;
-
-                const struct usbd_config *c = usb_get_config_data(-1);
-                if (c && c->resume)
-                        c->resume();
-
-                stat.resume = 1; /* always clear bit */
-        }
-        USB0.istat.raw = stat.raw;
+       struct USB_ISTAT_t stat = {.raw = USB0.istat.raw };
+
+       if (stat.usbrst) {
+               usb_reset();
+               return;
+       }
+       if (stat.stall) {
+               /* XXX need more work for non-0 ep */
+               volatile struct USB_BD_t *bd = usb_get_bd(&usb.ep_state[0].rx);
+               if (bd->stall)
+                       usb_setup_control();
+       }
+       if (stat.tokdne) {
+               struct usb_xfer_info stat = USB0.stat;
+               usb_handle_transaction(&stat);
+       }
+       if (stat.sleep) {
+               USB0.inten.sleep = 0;
+               USB0.inten.resume = 1;
+               USB0.usbctrl.susp = 1;
+               USB0.usbtrc0.usbresmen = 1;
+
+               /**
+                * Clear interrupts now so that we can detect a fresh
+                * resume later on.
+                */
+               USB0.istat.raw = stat.raw;
+
+               const struct usbd_config *c = usb_get_config_data(-1);
+               if (c && c->suspend)
+                       c->suspend();
+       }
+       /**
+        * XXX it is unclear whether we will receive a synchronous
+        * resume interrupt if we were in sleep.  This code assumes we
+        * do.
+        */
+       if (stat.resume || USB0.usbtrc0.usb_resume_int) {
+               USB0.inten.resume = 0;
+               USB0.inten.sleep = 1;
+               USB0.usbtrc0.usbresmen = 0;
+               USB0.usbctrl.susp = 0;
+
+               const struct usbd_config *c = usb_get_config_data(-1);
+               if (c && c->resume)
+                       c->resume();
+
+               stat.resume = 1; /* always clear bit */
+       }
+       USB0.istat.raw = stat.raw;
 }
 
 void usb_poll(void)
 {
-        USB0_Handler();
+       USB0_Handler();
 }
 
 int usb_tx_serialno(size_t reqlen)
 {
-        struct usb_desc_string_t *d;
-        const size_t nregs = 3;
-        /**
-         * actually 4, but UIDH is 0xffffffff.  Also our output buffer
-         * is only 64 bytes, and 128 bit + desc header exceeds this by
-         * 2 bytes.
-         */
-        const size_t len = nregs * 4 * 2 * 2 + sizeof(*d);
-
-        d = usb_ep0_tx_inplace_prepare(len);
-
-        if (d == NULL)
-                return (-1);
-
-        d->bLength = len;
-        d->bDescriptorType = USB_DESC_STRING;
-
-        size_t bufpos = 0;
-        for (size_t reg = 0; reg < nregs; ++reg) {
-                /* registers run MSW first */
-                uint32_t val = (&SIM.uidmh)[reg];
-
-                for (size_t bits = 32; bits > 0; bits -= 4, val <<= 4) {
-                        int nibble = val >> 28;
-
-                        if (nibble > 9)
-                                nibble += 'a' - '9' - 1;
-                        ((char16_t *)d->bString)[bufpos++] = nibble + '0';
-                }
-        }
-        usb_ep0_tx(d, len, reqlen, NULL, NULL);
-        return (0);
+       struct usb_desc_string_t *d;
+       const size_t nregs = 3;
+       /**
+        * actually 4, but UIDH is 0xffffffff.  Also our output buffer
+        * is only 64 bytes, and 128 bit + desc header exceeds this by
+        * 2 bytes.
+        */
+       const size_t len = nregs * 4 * 2 * 2 + sizeof(*d);
+
+       d = usb_ep0_tx_inplace_prepare(len);
+
+       if (d == NULL)
+               return (-1);
+
+       d->bLength = len;
+       d->bDescriptorType = USB_DESC_STRING;
+
+       size_t bufpos = 0;
+       for (size_t reg = 0; reg < nregs; ++reg) {
+               /* registers run MSW first */
+               uint32_t val = (&SIM.uidmh)[reg];
+
+               for (size_t bits = 32; bits > 0; bits -= 4, val <<= 4) {
+                       int nibble = val >> 28;
+
+                       if (nibble > 9)
+                               nibble += 'a' - '9' - 1;
+                       ((char16_t *)d->bString)[bufpos++] = nibble + '0';
+               }
+       }
+       usb_ep0_tx(d, len, reqlen, NULL, NULL);
+       return (0);
 }