From 8acfdb97b59c9414b24d2b04b07829c68b5b57dc Mon Sep 17 00:00:00 2001
From: jaseg <git@jaseg.net>
Date: Thu, 24 Dec 2020 15:35:50 +0100
Subject: Fix ALL the bugs

---
 fw/src/main.c      | 200 ++++-------------------------------------------------
 fw/src/usbd_conf.c |   4 +-
 fw/src/usbd_hid.c  | 147 +++++++++++++++++++++++----------------
 fw/src/usbd_hid.h  |   3 +
 4 files changed, 109 insertions(+), 245 deletions(-)

(limited to 'fw/src')

diff --git a/fw/src/main.c b/fw/src/main.c
index 982b1c2..f4a34d7 100644
--- a/fw/src/main.c
+++ b/fw/src/main.c
@@ -104,21 +104,6 @@ int main(void)
     }
 }
 
-void __libc_init_array(void);
-void __libc_init_array() {
-    /* FIXME Do we even need this? */
-}
-
-void _init(void);
-void _init() {
-    /* FIXME Do we even need this? */
-}
-
-void __assert_func (const char *file, int line, const char * func, const char * exp) {
-    asm volatile ("bkpt");
-    while (1);
-}
-
 static uint32_t poll_encoders() {
     static bool tx_vol_reset = 0;
     static uint16_t tim1_last = 0, tim3_last = 0; /* timers init to 0 */
@@ -173,176 +158,6 @@ static uint32_t poll_keys() {
     return keybits;
 }
 
-const uint8_t _asciimap[128] =
-{
-    0x00,             // NUL
-    0x00,             // SOH
-    0x00,             // STX
-    0x00,             // ETX
-    0x00,             // EOT
-    0x00,             // ENQ
-    0x00,             // ACK
-    0x00,             // BEL
-    0x2a,           // BS   Backspace
-    0x2b,           // TAB  Tab
-    0x28,           // LF   Enter
-    0x00,             // VT
-    0x00,             // FF
-    0x00,             // CR
-    0x00,             // SO
-    0x00,             // SI
-    0x00,             // DEL
-    0x00,             // DC1
-    0x00,             // DC2
-    0x00,             // DC3
-    0x00,             // DC4
-    0x00,             // NAK
-    0x00,             // SYN
-    0x00,             // ETB
-    0x00,             // CAN
-    0x00,             // EM
-    0x00,             // SUB
-    0x00,             // ESC
-    0x00,             // FS
-    0x00,             // GS
-    0x00,             // RS
-    0x00,             // US
-
-    0x2c,          //  ' '
-    0x1e|0x80,    // !
-    0x34|0x80,    // "
-    0x20|0x80,    // #
-    0x21|0x80,    // $
-    0x22|0x80,    // %
-    0x24|0x80,    // &
-    0x34,          // '
-    0x26|0x80,    // (
-    0x27|0x80,    // )
-    0x25|0x80,    // *
-    0x2e|0x80,    // +
-    0x36,          // ,
-    0x2d,          // -
-    0x37,          // .
-    0x38,          // /
-    0x27,          // 0
-    0x1e,          // 1
-    0x1f,          // 2
-    0x20,          // 3
-    0x21,          // 4
-    0x22,          // 5
-    0x23,          // 6
-    0x24,          // 7
-    0x25,          // 8
-    0x26,          // 9
-    0x33|0x80,      // :
-    0x33,          // ;
-    0x36|0x80,      // <
-    0x2e,          // =
-    0x37|0x80,      // >
-    0x38|0x80,      // ?
-    0x1f|0x80,      // @
-    0x04|0x80,      // A
-    0x05|0x80,      // B
-    0x06|0x80,      // C
-    0x07|0x80,      // D
-    0x08|0x80,      // E
-    0x09|0x80,      // F
-    0x0a|0x80,      // G
-    0x0b|0x80,      // H
-    0x0c|0x80,      // I
-    0x0d|0x80,      // J
-    0x0e|0x80,      // K
-    0x0f|0x80,      // L
-    0x10|0x80,      // M
-    0x11|0x80,      // N
-    0x12|0x80,      // O
-    0x13|0x80,      // P
-    0x14|0x80,      // Q
-    0x15|0x80,      // R
-    0x16|0x80,      // S
-    0x17|0x80,      // T
-    0x18|0x80,      // U
-    0x19|0x80,      // V
-    0x1a|0x80,      // W
-    0x1b|0x80,      // X
-    0x1c|0x80,      // Y
-    0x1d|0x80,      // Z
-    0x2f,          // [
-    0x31,          // bslash
-    0x30,          // ]
-    0x23|0x80,    // ^
-    0x2d|0x80,    // _
-    0x35,          // `
-    0x04,          // a
-    0x05,          // b
-    0x06,          // c
-    0x07,          // d
-    0x08,          // e
-    0x09,          // f
-    0x0a,          // g
-    0x0b,          // h
-    0x0c,          // i
-    0x0d,          // j
-    0x0e,          // k
-    0x0f,          // l
-    0x10,          // m
-    0x11,          // n
-    0x12,          // o
-    0x13,          // p
-    0x14,          // q
-    0x15,          // r
-    0x16,          // s
-    0x17,          // t
-    0x18,          // u
-    0x19,          // v
-    0x1a,          // w
-    0x1b,          // x
-    0x1c,          // y
-    0x1d,          // z
-    0x2f|0x80,    // {
-    0x31|0x80,    // |
-    0x30|0x80,    // }
-    0x35|0x80,    // ~
-    0               // DEL
-};
-
-
-void sendChar(uint8_t ch){
-    if( ch > 128 ) ch -=128;
-
-    key.id = 1;
-    key.keycode[0]=_asciimap[ch]&0x7F;
-    key.keycode[1]=0;
-
-    if ( _asciimap[ch] & 0x80) key.modifier |= 0x02;
-
-    for(int i=0; i< 4;i++){
-        USBD_HID_SendReport(&hUsbDeviceFS, (uint8_t *)&key, sizeof(key));
-        HAL_Delay(10);
-    }
-    memset(key.keycode, 0 , sizeof(key.keycode));
-    key.modifier = 0;
-    USBD_HID_SendReport(&hUsbDeviceFS, (uint8_t *)&key, sizeof(key));
-    HAL_Delay(10);
-}
-
-void sendCharWrong(uint8_t ch){
-    key.id = 1;
-    key.keycode[0]=ch&0x7F;
-    key.keycode[1]=0;
-
-    if ( _asciimap[ch] & 0x80) key.modifier |= 0x02;
-
-    for(int i=0; i< 4;i++){
-        USBD_HID_SendReport(&hUsbDeviceFS, (uint8_t *)&key, sizeof(key));
-        HAL_Delay(10);
-    }
-    memset(key.keycode, 0 , sizeof(key.keycode));
-    key.modifier = 0;
-    USBD_HID_SendReport(&hUsbDeviceFS, (uint8_t *)&key, sizeof(key));
-    HAL_Delay(10);
-}
-
 void sendKeybits(uint8_t keybits){
     uint8_t report[2];
     report[0]= HID_MEDIA_REPORT;
@@ -477,3 +292,18 @@ void Error_Handler(void)
     }
 }
 
+void __libc_init_array(void);
+void __libc_init_array() {
+    /* FIXME Do we even need this? */
+}
+
+void _init(void);
+void _init() {
+    /* FIXME Do we even need this? */
+}
+
+void __assert_func (const char *file, int line, const char * func, const char * exp) {
+    asm volatile ("bkpt");
+    while (1);
+}
+
diff --git a/fw/src/usbd_conf.c b/fw/src/usbd_conf.c
index b6815e5..9d82e40 100644
--- a/fw/src/usbd_conf.c
+++ b/fw/src/usbd_conf.c
@@ -578,14 +578,14 @@ void USBD_LL_Delay(uint32_t Delay /* ms */)
     HAL_Delay(Delay);
 }
 
-static USBD_HID_HandleTypeDef *static_hid_handle;
+static USBD_HID_HandleTypeDef static_hid_handle;
 static bool static_hid_handle_allocated = false;
 
 void *USBD_static_malloc(uint32_t size)
 {
     assert(!static_hid_handle_allocated);
     static_hid_handle_allocated = true;
-    return static_hid_handle;
+    return &static_hid_handle;
 }
 
 void USBD_static_free(void *p)
diff --git a/fw/src/usbd_hid.c b/fw/src/usbd_hid.c
index 4d313b4..eaf7878 100644
--- a/fw/src/usbd_hid.c
+++ b/fw/src/usbd_hid.c
@@ -10,6 +10,7 @@ static uint8_t  *USBD_HID_GetCfgDesc (uint16_t *length);
 static uint8_t  *USBD_HID_GetDeviceQualifierDesc (uint16_t *length); 
 static uint8_t  USBD_HID_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum); 
 static uint8_t  USBD_HID_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum);
+static uint8_t  USBD_HID_EP0_RxReady(USBD_HandleTypeDef  *pdev);
 
 USBD_ClassTypeDef  USBD_HID = 
 {
@@ -17,7 +18,7 @@ USBD_ClassTypeDef  USBD_HID =
     USBD_HID_DeInit,
     USBD_HID_Setup,
     NULL, /* EP0_TxSent */  
-    NULL, /* EP0_RxReady */
+    USBD_HID_EP0_RxReady,
     USBD_HID_DataIn,
     USBD_HID_DataOut,
     NULL, /* SOF */
@@ -233,64 +234,73 @@ static uint8_t  USBD_HID_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *
 
     switch (req->bmRequest & USB_REQ_TYPE_MASK)
     {
-    case USB_REQ_TYPE_CLASS :  
-        switch (req->bRequest) {
-        case HID_REQ_SET_PROTOCOL:
-            hhid->Protocol = (uint8_t)(req->wValue);
-            break;
-
-        case HID_REQ_GET_PROTOCOL:
-            USBD_CtlSendData (pdev, 
-                    (uint8_t *)&hhid->Protocol,
-                    1);    
-            break;
-
-        case HID_REQ_SET_IDLE:
-            hhid->IdleState = (uint8_t)(req->wValue >> 8);
-            break;
-
-        case HID_REQ_GET_IDLE:
-            USBD_CtlSendData (pdev, 
-                    (uint8_t *)&hhid->IdleState,
-                    1);        
-            break;      
-
-        default:
-            USBD_CtlError (pdev, req);
-            return USBD_FAIL; 
-        }
-        break;
-
-    case USB_REQ_TYPE_STANDARD:
-        switch (req->bRequest) {
-        case USB_REQ_GET_DESCRIPTOR: 
-            if( req->wValue >> 8 == HID_REPORT_DESC)
-            {
-                len = MIN(HID_REPORT_DESC_SIZE , req->wLength);
-                pbuf = HID_ReportDesc;
+        case USB_REQ_TYPE_CLASS :  
+            switch (req->bRequest) {
+                case HID_REQ_SET_PROTOCOL:
+                    hhid->Protocol = (uint8_t)(req->wValue);
+                    break;
+
+                case HID_REQ_GET_PROTOCOL:
+                    USBD_CtlSendData (pdev, 
+                            (uint8_t *)&hhid->Protocol,
+                            1);    
+                    break;
+
+                case HID_REQ_SET_IDLE:
+                    hhid->IdleState = (uint8_t)(req->wValue >> 8);
+                    break;
+
+                case HID_REQ_GET_IDLE:
+                    USBD_CtlSendData (pdev, 
+                            (uint8_t *)&hhid->IdleState,
+                            1);        
+                    break;      
+
+                case HID_REQ_SET_REPORT:
+                    hhid->IsReportAvailable = 1U;
+                    if (req->wLength > sizeof(hhid->Report_buf)) {
+                        USBD_CtlError (pdev, req);
+                        return USBD_FAIL; 
+                    }
+                    (void)USBD_CtlPrepareRx(pdev, hhid->Report_buf, req->wLength);
+                    break;
+
+                default:
+                    USBD_CtlError (pdev, req);
+                    return USBD_FAIL; 
             }
-            else if( req->wValue >> 8 == HID_DESCRIPTOR_TYPE)
-            {
-                pbuf = USBD_HID_Desc;   
-                len = MIN(USB_HID_DESC_SIZ , req->wLength);
-            }
-
-            USBD_CtlSendData (pdev, 
-                    pbuf,
-                    len);
-
-            break;
-
-        case USB_REQ_GET_INTERFACE :
-            USBD_CtlSendData (pdev,
-                    (uint8_t *)&hhid->AltSetting,
-                    1);
             break;
 
-        case USB_REQ_SET_INTERFACE :
-            hhid->AltSetting = (uint8_t)(req->wValue);
-            break;
-        }
+        case USB_REQ_TYPE_STANDARD:
+            switch (req->bRequest) {
+                case USB_REQ_GET_DESCRIPTOR: 
+                    if( req->wValue >> 8 == HID_REPORT_DESC)
+                    {
+                        len = MIN(HID_REPORT_DESC_SIZE , req->wLength);
+                        pbuf = HID_ReportDesc;
+                    }
+                    else if( req->wValue >> 8 == HID_DESCRIPTOR_TYPE)
+                    {
+                        pbuf = USBD_HID_Desc;   
+                        len = MIN(USB_HID_DESC_SIZ , req->wLength);
+                    }
+
+                    USBD_CtlSendData (pdev, 
+                            pbuf,
+                            len);
+
+                    break;
+
+                case USB_REQ_GET_INTERFACE :
+                    USBD_CtlSendData (pdev,
+                            (uint8_t *)&hhid->AltSetting,
+                            1);
+                    break;
+
+                case USB_REQ_SET_INTERFACE :
+                    hhid->AltSetting = (uint8_t)(req->wValue);
+                    break;
+            }
     }
     return USBD_OK;
 }
@@ -302,8 +312,8 @@ uint8_t USBD_HID_SendReport (USBD_HandleTypeDef  *pdev, uint8_t *report, uint16_
     if (pdev->dev_state != USBD_STATE_CONFIGURED )
         return USBD_OK;
 
-    if(hhid->state == HID_IDLE)
-        return USBD_OK;
+    if(hhid->state != HID_IDLE)
+        return USBD_BUSY;
 
     hhid->state = HID_BUSY;
     USBD_LL_Transmit(pdev, HID_EPIN_ADDR, report, len);
@@ -371,3 +381,24 @@ static uint8_t  *USBD_HID_GetDeviceQualifierDesc (uint16_t *length)
     return USBD_HID_DeviceQualifierDesc;
 }
 
+/**
+ * @brief  USBD_CUSTOM_HID_EP0_RxReady
+ *         Handles control request data.
+ * @param  pdev: device instance
+ * @retval status
+ */
+static uint8_t USBD_HID_EP0_RxReady(USBD_HandleTypeDef *pdev)
+{
+    USBD_HID_HandleTypeDef     *hhid = (USBD_HID_HandleTypeDef*) pdev->pClassData;
+
+    if (!hhid)
+        return (uint8_t)USBD_FAIL;
+
+    if (hhid->IsReportAvailable == 1U) {
+        /* FIXME ignore for now */
+        hhid->IsReportAvailable = 0U;
+    }
+
+    return (uint8_t)USBD_OK;
+}
+
diff --git a/fw/src/usbd_hid.h b/fw/src/usbd_hid.h
index fa2f0a2..528747d 100644
--- a/fw/src/usbd_hid.h
+++ b/fw/src/usbd_hid.h
@@ -35,6 +35,7 @@
 
 /* Includes ------------------------------------------------------------------*/
 #include  "usbd_ioreq.h"
+#include <stdbool.h>
 
 /** @addtogroup STM32_USB_DEVICE_LIBRARY
   * @{
@@ -134,6 +135,8 @@ typedef struct
   uint32_t             Protocol;   
   uint32_t             IdleState;  
   uint32_t             AltSetting;
+  bool                 IsReportAvailable;
+  uint8_t              Report_buf[8];
   HID_StateTypeDef     state;  
 }
 USBD_HID_HandleTypeDef; 
-- 
cgit