diff options
-rw-r--r-- | .gdbinit | 23 | ||||
-rw-r--r-- | .gitignore | 5 | ||||
-rw-r--r-- | .gitmodules | 3 | ||||
-rw-r--r-- | SConstruct | 11 | ||||
m--------- | laks | 0 | ||||
-rw-r--r-- | main.cpp | 129 |
6 files changed, 171 insertions, 0 deletions
diff --git a/.gdbinit b/.gdbinit new file mode 100644 index 0000000..2844d70 --- /dev/null +++ b/.gdbinit @@ -0,0 +1,23 @@ +define flash +file demo.elf +load +end + +define restart +run +end + +define attach_swd +mon swdp_scan +attach 1 +end + +define attach_jtag +mon jtag_scan +attach 1 +end + +file demo.elf +target extended-remote /dev/cu.usbmodem7FC181B1 + +set mem inaccessible-by-default off diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b137a4a --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.o +*.a +*.elf +*.swp +.sconsign.dblite diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..cd4f3c2 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "laks"] + path = laks + url = git://git.jvnv.net/laks.git diff --git a/SConstruct b/SConstruct new file mode 100644 index 0000000..ef5b6f5 --- /dev/null +++ b/SConstruct @@ -0,0 +1,11 @@ +import os
+
+env = Environment(
+ ENV = os.environ,
+)
+
+SConscript('laks/build_rules')
+
+env.SelectMCU('stm32f373cc')
+
+env.Firmware('demo.elf', Glob('*.cpp'))
diff --git a/laks b/laks new file mode 160000 +Subproject 410007558fa8d314e3f2fdfb385d2d8ab07e1e6 diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..de86129 --- /dev/null +++ b/main.cpp @@ -0,0 +1,129 @@ +#include <rcc/rcc.h> +#include <gpio/pin.h> +#include <os/time.h> +#include <usb/usb.h> +#include <usb/descriptor.h> + +template <uint32_t S> +struct raw_t { + uint8_t a[S]; +} __attribute__((packed)); + +uint8_t report_desc[] = { + 0x05, 0x01, // Usage page: Generic Desktop + 0x09, 0x05, // Usage: Gamepad + 0xa1, 0x01, // Collection: Application + 0xa1, 0x00, // Collection: Physical + 0x05, 0x09, // Usage page: Button + 0x19, 0x01, // Usage minimum: Button 1 + 0x29, 0x20, // Usage maximum: Button 32 + 0x15, 0x00, // Logical minimum: 0 + 0x25, 0x01, // Logical maximum: 1 + 0x95, 0x20, // Report count: 32 + 0x75, 0x01, // Report size: 1 + 0x81, 0x02, // Input (data, var, abs) + 0xc0, // End collection + 0xc0, // End collection +}; + +raw_t<9> hid_desc = {{0x09, 0x21, 0x11, 0x01, 0x00, 0x01, 0x22, sizeof(report_desc), 0x00}}; + +auto dev_desc = device_desc(0x200, 0, 0, 0, 64, 0x1234, 0x5678, 0, 0, 0, 0, 1); +auto conf_desc = configuration_desc(1, 1, 0, 0xc0, 0, + // HID interface. + interface_desc(0, 0, 1, 0x03, 0x00, 0x00, 0, + hid_desc, + endpoint_desc(0x81, 0x03, 16, 1) + ) +); + +desc_t dev_desc_p = {sizeof(dev_desc), (void*)&dev_desc}; +desc_t conf_desc_p = {sizeof(conf_desc), (void*)&conf_desc}; + +Pin& usb_dm = PA11; +Pin& usb_dp = PA12; +Pin usb_disc = {GPIOF, 6}; + +USB_f1 usb(USB, dev_desc_p, conf_desc_p); + +class USB_HID : public USB_class_driver { + private: + USB_generic& usb; + + uint32_t buf[16]; + + public: + USB_HID(USB_generic& usbd) : usb(usbd) { + usb.register_driver(this); + } + + protected: + virtual SetupStatus handle_setup(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength) { + // Get report descriptor. + if(bmRequestType == 0x81 && bRequest == 0x06 && wValue == 0x2200) { + usb.write(0, (uint32_t*)report_desc, sizeof(report_desc) < wLength ? sizeof(report_desc) : wLength); + return SetupStatus::Ok; + } + + return SetupStatus::Unhandled; + } + + virtual void handle_set_configuration(uint8_t configuration) { + if(configuration) { + //usb.register_out_handler(this, 1); + usb.hw_conf_ep(0x81, EPType::Interrupt, 16); + } + } + + virtual void handle_out(uint8_t ep, uint32_t len) { + if(ep == 0) { + usb.write(0, nullptr, 0); + } + } +}; + +USB_HID usb_hid(usb); + +uint32_t buttons; + +int main() { + // Initialize system timer. + STK.LOAD = 72000000 / 8 / 1000; // 1000 Hz. + STK.CTRL = 0x03; + + RCC.enable(RCC.GPIOA); + + usb_disc.set_mode(Pin::Output); + usb_disc.on(); + + usb_dm.set_mode(Pin::AF); + usb_dm.set_af(14); + usb_dp.set_mode(Pin::AF); + usb_dp.set_af(14); + + RCC.enable(RCC.USB); + + usb.init(); + + Time::sleep(100); + usb_disc.off(); + + uint32_t last_time = 0; + + while(1) { + usb.process(); + + int32_t time_delta = Time::time() - last_time; + + if(time_delta >= 500) { + if(!(buttons <<= 1)) { + buttons = 1; + } + last_time += time_delta; + } + + if(usb.ep_ready(1)) { + usb.write(1, &buttons, sizeof(buttons)); + } + } +} |