summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
m---------laks0
-rw-r--r--main.cpp109
2 files changed, 74 insertions, 35 deletions
diff --git a/laks b/laks
-Subproject 066100177770944a376e3a01cf4685ff9d2f562
+Subproject 8d68e3d9823abe8a9ff6f8b0f6f4addee98bb26
diff --git a/main.cpp b/main.cpp
index c35ad7e..9aafa08 100644
--- a/main.cpp
+++ b/main.cpp
@@ -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);