diff options
m--------- | laks | 0 | ||||
-rw-r--r-- | main.cpp | 109 |
2 files changed, 74 insertions, 35 deletions
diff --git a/laks b/laks -Subproject 066100177770944a376e3a01cf4685ff9d2f562 +Subproject 8d68e3d9823abe8a9ff6f8b0f6f4addee98bb26 @@ -45,45 +45,81 @@ desc_t conf_desc_p = {sizeof(conf_desc), (void*)&conf_desc}; USB_otg usb(OTG_HS, dev_desc_p, conf_desc_p); -bool i2c_read(uint16_t wValue, uint16_t wIndex, uint16_t wLength) { - uint8_t buf[wLength]; - I2C2.read_reg(wValue, wIndex, wLength, buf); +class USB_I2C : public USB_class_driver { + private: + I2C_t& i2c; + + bool i2c_read(uint16_t wValue, uint16_t wIndex, uint16_t wLength) { + uint8_t buf[wLength]; + i2c.read_reg(wValue, wIndex, wLength, buf); + + usb.write(0, (uint32_t*)buf, wLength); + return true; + } - usb.write(0, (uint32_t*)buf, wLength); - return true; -} - -bool jtag_tick(bool tdi, bool tms) { - bool tdo = jtag_tdo.get(); - jtag_tdi.set(tdi); - jtag_tms.set(tms); - jtag_tck.on(); - for(uint32_t i = 0; i < 1000; i++) { - asm volatile("nop"); - } - jtag_tck.off(); - for(uint32_t i = 0; i < 1000; i++) { - asm volatile("nop"); - } - return tdo; -} - -bool jtag_shift(uint16_t wValue, uint16_t wIndex, uint16_t wLength) { - if(wLength > 16) { - return false; - } + public: + USB_I2C(I2C_t& i2c_bus) : i2c(i2c_bus) {} - uint32_t tdo = 0; + protected: + virtual SetupStatus handle_setup(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength) { + if(bmRequestType == 0xc0 && bRequest == 0xf0) { + return i2c_read(wValue, wIndex, wLength) ? SetupStatus::Ok : SetupStatus::Stall; + } + + return SetupStatus::Unhandled; + } +}; + +USB_I2C usb_i2c(I2C2); + +class USB_JTAG : public USB_class_driver { + private: + bool jtag_tick(bool tdi, bool tms) { + bool tdo = jtag_tdo.get(); + jtag_tdi.set(tdi); + jtag_tms.set(tms); + jtag_tck.on(); + for(uint32_t i = 0; i < 1000; i++) { + asm volatile("nop"); + } + jtag_tck.off(); + for(uint32_t i = 0; i < 1000; i++) { + asm volatile("nop"); + } + return tdo; + } + + bool jtag_shift(uint16_t wValue, uint16_t wIndex, uint16_t wLength) { + if(wLength > 16) { + return false; + } + + uint32_t tdo = 0; + + for(int16_t i = 0; i < wLength; i++) { + tdo |= jtag_tick(wValue & 1, wIndex & 1) ? 1 << i : 0; + wValue >>= 1; + wIndex >>= 1; + } + + usb.write(0, &tdo, (wLength + 7) >> 3); + return true; + } - for(int16_t i = 0; i < wLength; i++) { - tdo |= jtag_tick(wValue & 1, wIndex & 1) ? 1 << i : 0; - wValue >>= 1; - wIndex >>= 1; - } + public: + USB_JTAG() {} - usb.write(0, &tdo, (wLength + 7) >> 3); - return true; -} + protected: + virtual SetupStatus handle_setup(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength) { + if(bmRequestType == 0xc0 && bRequest == 0xff) { + return jtag_shift(wValue, wIndex, wLength) ? SetupStatus::Ok : SetupStatus::Stall; + } + + return SetupStatus::Unhandled; + } +}; + +USB_JTAG usb_jtag; template<> void interrupt<(Interrupt::IRQ)77>() { @@ -145,6 +181,9 @@ int main() { usb_thread.start(); + usb.register_control_handler(&usb_i2c); + usb.register_control_handler(&usb_jtag); + RCC.enable(RCC.SPI1); PA5.set_mode(Pin::AF); |