void stm32fx07_ep_stall_set(usbd_device *usbd_dev, uint8_t addr, uint8_t stall) { if (addr == 0) { if (stall) { REBASE(OTG_DIEPCTL(addr)) |= OTG_FS_DIEPCTL0_STALL; } else { REBASE(OTG_DIEPCTL(addr)) &= ~OTG_FS_DIEPCTL0_STALL; } } if (addr & 0x80) { addr &= 0x7F; if (stall) { REBASE(OTG_DIEPCTL(addr)) |= OTG_FS_DIEPCTL0_STALL; } else { REBASE(OTG_DIEPCTL(addr)) &= ~OTG_FS_DIEPCTL0_STALL; REBASE(OTG_DIEPCTL(addr)) |= OTG_FS_DIEPCTLX_SD0PID; } } else { if (stall) { REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTL0_STALL; } else { REBASE(OTG_DOEPCTL(addr)) &= ~OTG_FS_DOEPCTL0_STALL; REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTLX_SD0PID; } } }
void stm32fx07_ep_nak_set(usbd_device *usbd_dev, u8 addr, u8 nak) { /* It does not make sence to force NAK on IN endpoints. */ if (addr & 0x80) return; usbd_dev->force_nak[addr] = nak; if (nak) REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTL0_SNAK; else REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTL0_CNAK; }
void stm32fx07_ep_nak_set(usbd_device *usbd_dev, uint8_t addr, uint8_t nak) { /* It does not make sense to force NAK on IN endpoints. */ if (addr & 0x80) { return; } usbd_dev->force_nak[addr] = nak; if (nak) { REBASE(OTG_DOEPCTL(addr)) |= OTG_DOEPCTL0_SNAK; } else { REBASE(OTG_DOEPCTL(addr)) |= OTG_DOEPCTL0_CNAK; } }
uint16_t stm32fx07_ep_read_packet(usbd_device *usbd_dev, uint8_t addr, void *buf, uint16_t len) { int i; uint32_t *buf32 = buf; uint32_t extra; len = MIN(len, usbd_dev->rxbcnt); usbd_dev->rxbcnt -= len; volatile uint32_t *fifo = REBASE_FIFO(addr); for (i = len; i >= 4; i -= 4) { *buf32++ = *fifo++; } if (i) { extra = *fifo++; memcpy(buf32, &extra, i); } REBASE(OTG_DOEPTSIZ(addr)) = usbd_dev->doeptsiz[addr]; REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTL0_EPENA | (usbd_dev->force_nak[addr] ? OTG_FS_DOEPCTL0_SNAK : OTG_FS_DOEPCTL0_CNAK); return len; }
u8 stm32fx07_ep_stall_get(usbd_device *usbd_dev, u8 addr) { /* Return non-zero if STALL set. */ if (addr & 0x80) return (REBASE(OTG_DIEPCTL(addr & 0x7f)) & OTG_FS_DIEPCTL0_STALL) ? 1 : 0; else return (REBASE(OTG_DOEPCTL(addr)) & OTG_FS_DOEPCTL0_STALL) ? 1 : 0; }
uint8_t stm32fx07_ep_stall_get(usbd_device *usbd_dev, uint8_t addr) { /* Return non-zero if STALL set. */ if (addr & 0x80) { return (REBASE(OTG_DIEPCTL(addr & 0x7f)) & OTG_DIEPCTL0_STALL) ? 1 : 0; } else { return (REBASE(OTG_DOEPCTL(addr)) & OTG_DOEPCTL0_STALL) ? 1 : 0; } }
void stm32fx07_endpoints_reset(usbd_device *usbd_dev) { int i; /* The core resets the endpoints automatically on reset. */ usbd_dev->fifo_mem_top = usbd_dev->fifo_mem_top_ep0; /* Disable any currently active endpoints */ for (i = 1; i < 4; i++) { if (REBASE(OTG_DOEPCTL(i)) & OTG_DOEPCTL0_EPENA) { REBASE(OTG_DOEPCTL(i)) |= OTG_DOEPCTL0_EPDIS; } if (REBASE(OTG_DIEPCTL(i)) & OTG_DIEPCTL0_EPENA) { REBASE(OTG_DIEPCTL(i)) |= OTG_DIEPCTL0_EPDIS; } } /* Flush all tx/rx fifos */ REBASE(OTG_GRSTCTL) = OTG_GRSTCTL_TXFFLSH | OTG_GRSTCTL_TXFNUM_ALL | OTG_GRSTCTL_RXFFLSH; }
void stm32fx07_ep_setup(usbd_device *usbd_dev, uint8_t addr, uint8_t type, uint16_t max_size, void (*callback) (usbd_device *usbd_dev, uint8_t ep)) { /* * Configure endpoint address and type. Allocate FIFO memory for * endpoint. Install callback funciton. */ uint8_t dir = addr & 0x80; addr &= 0x7f; if (addr == 0) { /* For the default control endpoint */ /* Configure IN part. */ if (max_size >= 64) { REBASE(OTG_DIEPCTL0) = OTG_FS_DIEPCTL0_MPSIZ_64; } else if (max_size >= 32) { REBASE(OTG_DIEPCTL0) = OTG_FS_DIEPCTL0_MPSIZ_32; } else if (max_size >= 16) { REBASE(OTG_DIEPCTL0) = OTG_FS_DIEPCTL0_MPSIZ_16; } else { REBASE(OTG_DIEPCTL0) = OTG_FS_DIEPCTL0_MPSIZ_8; } REBASE(OTG_DIEPTSIZ0) = (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK); REBASE(OTG_DIEPCTL0) |= OTG_FS_DIEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK; /* Configure OUT part. */ usbd_dev->doeptsiz[0] = OTG_FS_DIEPSIZ0_STUPCNT_1 | OTG_FS_DIEPSIZ0_PKTCNT | (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK); REBASE(OTG_DOEPTSIZ(0)) = usbd_dev->doeptsiz[0]; REBASE(OTG_DOEPCTL(0)) |= OTG_FS_DOEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK; REBASE(OTG_GNPTXFSIZ) = ((max_size / 4) << 16) | usbd_dev->driver->rx_fifo_size; usbd_dev->fifo_mem_top += max_size / 4; usbd_dev->fifo_mem_top_ep0 = usbd_dev->fifo_mem_top; return; } if (dir) { REBASE(OTG_DIEPTXF(addr)) = ((max_size / 4) << 16) | usbd_dev->fifo_mem_top; usbd_dev->fifo_mem_top += max_size / 4; REBASE(OTG_DIEPTSIZ(addr)) = (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK); REBASE(OTG_DIEPCTL(addr)) |= OTG_FS_DIEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK | (type << 18) | OTG_FS_DIEPCTL0_USBAEP | OTG_FS_DIEPCTLX_SD0PID | (addr << 22) | max_size; if (callback) { usbd_dev->user_callback_ctr[addr][USB_TRANSACTION_IN] = (void *)callback; } } if (!dir) { usbd_dev->doeptsiz[addr] = OTG_FS_DIEPSIZ0_PKTCNT | (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK); REBASE(OTG_DOEPTSIZ(addr)) = usbd_dev->doeptsiz[addr]; REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTL0_EPENA | OTG_FS_DOEPCTL0_USBAEP | OTG_FS_DIEPCTL0_CNAK | OTG_FS_DOEPCTLX_SD0PID | (type << 18) | max_size; if (callback) { usbd_dev->user_callback_ctr[addr][USB_TRANSACTION_OUT] = (void *)callback; } } }