#define USB_SELF_POWERED
#define USB_NUM_CONFIGURATIONS 1
-
-typedef unsigned int uint;
-typedef uint8_t byte;
-typedef uint16_t u16;
-typedef int16_t s16;
-typedef uint32_t u32;
-typedef int32_t s32;
-
-#define MIN(x,y) ((x) < (y) ? (x) : (y))
-#define MAX(x,y) ((x) > (y) ? (x) : (y))
+#define USB_DEBUG
/*** USB state structure ***/
};
void usb_init(struct usb *usb, PCD_HandleTypeDef *hpcd);
+void usb_start(struct usb *usb);
enum usb_device_state {
USB_STATE_DEFAULT,
USB_EP0_STALL,
};
+#ifdef USB_DEBUG
+#define usb_debug debug_printf
+#else
+static inline void usb_debug(char *msg, ...)
+{ }
+#endif
+
/*** Constants from USB specs ***/
#define USB_REQ_DIRECTION 0x80
--- /dev/null
+#include <stdint.h>
+
+typedef unsigned int uint;
+typedef uint8_t byte;
+typedef uint16_t u16;
+typedef int16_t s16;
+typedef uint32_t u32;
+typedef int32_t s32;
+
+#define MIN(x,y) ((x) < (y) ? (x) : (y))
+#define MAX(x,y) ((x) > (y) ? (x) : (y))
+
+// debug.c
+
+#define DEBUG_SEMIHOSTING
+
+void debug_printf(const char *fmt, ...);
+void debug_puts(const char *s);
+void debug_putc(int c);
C_SOURCES = \
/aux/misc/stm/F1-package/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_exti.c \
Src/main.c \
+Src/debug.c \
Src/usb.c \
/aux/misc/stm/F1-package/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_rcc.c \
/Src/system_stm32f1xx.c \
--- /dev/null
+#include "util.h"
+#include "stm32f1xx_hal.h"
+
+#include <stdarg.h>
+#include <string.h>
+
+void semi_put_char(char c)
+{
+#ifdef DEBUG_SEMIHOSTING
+ // This is tricky, we need to work around GCC bugs
+ volatile char cc = c;
+ asm volatile (
+ "mov r0, #0x03\n" /* SYS_WRITEC */
+ "mov r1, %[msg]\n"
+ "bkpt #0xAB\n"
+ :
+ : [msg] "r" (&cc)
+ : "r0", "r1"
+ );
+#endif
+}
+
+void semi_write_string(char *c)
+{
+#ifdef DEBUG_SEMIHOSTING
+ asm volatile (
+ "mov r0, #0x04\n" /* SYS_WRITE0 */
+ "mov r1, %[msg]\n"
+ "bkpt #0xAB\n"
+ :
+ : [msg] "r" (c)
+ : "r0", "r1"
+ );
+#endif
+}
+
+void debug_putc(int c)
+{
+ static char debug_buf[128];
+ static int debug_i;
+ debug_buf[debug_i++] = c;
+ if (c == '\n' || debug_i >= sizeof(debug_buf) - 1)
+ {
+ debug_buf[debug_i] = 0;
+ semi_write_string(debug_buf);
+ debug_i = 0;
+ }
+}
+
+void debug_puts(const char *s)
+{
+ while (*s)
+ debug_putc(*s++);
+}
+
+enum printf_flags {
+ PF_ZERO_PAD = 1,
+ PF_SIGNED = 2,
+ PF_NEGATIVE = 4,
+ PF_UPPERCASE = 8,
+ PF_LEFT = 16,
+};
+
+static void printf_string(const char *s, uint width, uint flags)
+{
+ uint len = strlen(s);
+ uint pad = (len < width) ? width - len : 0;
+ char pad_char = (flags & PF_ZERO_PAD) ? '0' : ' ';
+
+ if (flags & PF_LEFT)
+ debug_puts(s);
+ while (pad--)
+ debug_putc(pad_char);
+ if (!(flags & PF_LEFT))
+ debug_puts(s);
+}
+
+static void printf_number(uint i, uint width, uint flags, uint base)
+{
+ char buf[16];
+ char *w = buf + sizeof(buf);
+
+ if (flags & PF_SIGNED)
+ {
+ if ((int) i < 0)
+ {
+ i = - (int) i;
+ flags |= PF_NEGATIVE;
+ }
+ }
+
+ *--w = 0;
+ do
+ {
+ uint digit = i % base;
+ if (digit < 10)
+ *--w = '0' + digit;
+ else
+ *--w = ((flags & PF_UPPERCASE) ? 'A' : 'a') + digit - 10;
+ i /= base;
+ }
+ while (i);
+
+ if (flags & PF_NEGATIVE)
+ *--w = '-';
+
+ printf_string(w, width, flags);
+}
+
+void debug_printf(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+
+ while (*fmt)
+ {
+ int c = *fmt++;
+ if (c != '%')
+ {
+ debug_putc(c);
+ continue;
+ }
+
+ uint width = 0;
+ uint flags = 0;
+
+ if (*fmt == '-')
+ {
+ fmt++;
+ flags |= PF_LEFT;
+ }
+
+ if (*fmt == '0')
+ {
+ fmt++;
+ flags |= PF_ZERO_PAD;
+ }
+
+ while (*fmt >= '0' && *fmt <= '9')
+ width = 10*width + *fmt++ - '0';
+
+ c = *fmt++;
+ switch (c)
+ {
+ case 'd':
+ printf_number(va_arg(args, int), width, flags | PF_SIGNED, 10);
+ break;
+ case 'u':
+ printf_number(va_arg(args, int), width, flags, 10);
+ break;
+ case 'X':
+ flags |= PF_UPPERCASE;
+ // fall-thru
+ case 'x':
+ printf_number(va_arg(args, int), width, flags, 16);
+ break;
+ case 's':
+ printf_string(va_arg(args, char *), width, flags);
+ break;
+ default:
+ debug_putc(c);
+ continue;
+ }
+ }
+
+ va_end(args);
+}
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
+#include "util.h"
#include "main.h"
#include "stm32f1xx_hal.h"
#include "usb.h"
/* USER CODE BEGIN 0 */
-#include <stdarg.h>
-#include <stdint.h>
-#include <string.h>
-
-void semi_put_char(char c)
-{
- // This is tricky, we need to work around GCC bugs
- volatile char cc = c;
- asm volatile (
- "mov r0, #0x03\n" /* SYS_WRITEC */
- "mov r1, %[msg]\n"
- "bkpt #0xAB\n"
- :
- : [msg] "r" (&cc)
- : "r0", "r1"
- );
-}
-
-void semi_write_string(char *c)
-{
- asm volatile (
- "mov r0, #0x04\n" /* SYS_WRITE0 */
- "mov r1, %[msg]\n"
- "bkpt #0xAB\n"
- :
- : [msg] "r" (c)
- : "r0", "r1"
- );
-}
-
-void debug_putc(int c)
-{
- static char debug_buf[16];
- static int debug_i;
- debug_buf[debug_i++] = c;
- if (c == '\n' || debug_i >= sizeof(debug_buf) - 1)
- {
- debug_buf[debug_i] = 0;
- semi_write_string(debug_buf);
- debug_i = 0;
- }
-}
-
-void debug_puts(const char *s)
-{
- while (*s)
- debug_putc(*s++);
-}
-
-enum printf_flags {
- PF_ZERO_PAD = 1,
- PF_SIGNED = 2,
- PF_NEGATIVE = 4,
- PF_UPPERCASE = 8,
- PF_LEFT = 16,
-};
-
-static void printf_string(const char *s, uint width, uint flags)
-{
- uint len = strlen(s);
- uint pad = (len < width) ? width - len : 0;
- char pad_char = (flags & PF_ZERO_PAD) ? '0' : ' ';
-
- if (flags & PF_LEFT)
- debug_puts(s);
- while (pad--)
- debug_putc(pad_char);
- if (!(flags & PF_LEFT))
- debug_puts(s);
-}
-
-static void printf_number(uint i, uint width, uint flags, uint base)
-{
- char buf[16];
- char *w = buf + sizeof(buf);
-
- if (flags & PF_SIGNED)
- {
- if ((int) i < 0)
- {
- i = - (int) i;
- flags |= PF_NEGATIVE;
- }
- }
-
- *--w = 0;
- do
- {
- uint digit = i % base;
- if (digit < 10)
- *--w = '0' + digit;
- else
- *--w = ((flags & PF_UPPERCASE) ? 'A' : 'a') + digit - 10;
- i /= base;
- }
- while (i);
-
- if (flags & PF_NEGATIVE)
- *--w = '-';
-
- printf_string(w, width, flags);
-}
-
-void debug_printf(const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
-
- while (*fmt)
- {
- int c = *fmt++;
- if (c != '%')
- {
- debug_putc(c);
- continue;
- }
-
- uint width = 0;
- uint flags = 0;
-
- if (*fmt == '-')
- {
- fmt++;
- flags |= PF_LEFT;
- }
-
- if (*fmt == '0')
- {
- fmt++;
- flags |= PF_ZERO_PAD;
- }
-
- while (*fmt >= '0' && *fmt <= '9')
- width = 10*width + *fmt++ - '0';
-
- c = *fmt++;
- switch (c)
- {
- case 'd':
- printf_number(va_arg(args, int), width, flags | PF_SIGNED, 10);
- break;
- case 'u':
- printf_number(va_arg(args, int), width, flags, 10);
- break;
- case 'X':
- flags |= PF_UPPERCASE;
- // fall-thru
- case 'x':
- printf_number(va_arg(args, int), width, flags, 16);
- break;
- case 's':
- printf_string(va_arg(args, char *), width, flags);
- break;
- default:
- debug_putc(c);
- continue;
- }
- }
-
- va_end(args);
-}
-
/* USER CODE END 0 */
/**
SystemClock_Config();
/* USER CODE BEGIN SysInit */
+ usb_init(&usb, &hpcd_USB_FS);
/* USER CODE END SysInit */
MX_I2C2_Init();
MX_USB_PCD_Init();
/* USER CODE BEGIN 2 */
- usb_init(&usb, &hpcd_USB_FS);
+ usb_start(&usb);
/* USER CODE END 2 */
#include "stm32f1xx.h"
#include "stm32f1xx_hal.h"
+#include "util.h"
#include "usb.h"
#include <string.h>
usb->hpcd = hpcd;
usb->state = USB_STATE_DEFAULT;
usb->ep0_state = USB_EP0_IDLE;
+ hpcd->pData = usb;
+}
- HAL_PCDEx_PMAConfig(hpcd, 0x00, PCD_SNG_BUF, 0x18);
- HAL_PCDEx_PMAConfig(hpcd, 0x80, PCD_SNG_BUF, 0x58);
+void usb_start(struct usb *usb)
+{
+ HAL_PCDEx_PMAConfig(usb->hpcd, 0x00, PCD_SNG_BUF, 0x18);
+ HAL_PCDEx_PMAConfig(usb->hpcd, 0x80, PCD_SNG_BUF, 0x58);
- HAL_PCD_Start(hpcd);
+ HAL_PCD_Start(usb->hpcd);
}
static inline uint get_u16(byte *p)
p[1] = x >> 8;
}
-#if 0 // FIXME
-static struct usb_endpoint *ep_by_addr(struct usb *usb, byte ep_addr)
-{
- return ((ep_addr & 0x80) ? usb->ep_in : usb->ep_out) + (ep_addr & 0x7f);
-}
-#endif
-
static void usb_ctl_send_status(struct usb *usb)
{
+ usb_debug("Control send: status\n");
usb->ep0_state = USB_EP0_STATUS_IN;
usb_ep_transmit(usb, 0x00, NULL, 0);
}
static void usb_ctl_send_data(struct usb *usb, const byte *data, uint len)
{
+ usb_debug("Control send: %u bytes\n", len);
usb->ep0_state = USB_EP0_DATA_IN;
usb->ep0_total_length = len;
usb->ep0_remaining_length = len;
#if 0 // FIXME
static void usb_ctl_recv_data(struct usb *usb, byte *data, uint len)
{
+ usb_debug("Control recv: %u bytes\n", len);
usb->ep0_state = USB_EP0_DATA_OUT;
usb->ep0_total_length = len;
usb->ep0_remaining_length = len;
static void usb_ctl_error(struct usb *usb)
{
+ usb_debug("Control packet error\n");
usb_ep_stall(usb, 0x00);
usb_ep_stall(usb, 0x80);
}
static void usb_ctl_setup_error(struct usb *usb, struct setup_request *setup)
{
+ usb_debug("Setup packet error\n");
usb_ep_stall(usb, setup->bmRequest & USB_REQ_DIRECTION);
}
static void usb_handle_setup(struct usb *usb, struct setup_request *setup)
{
+ usb_debug("Setup: type=%02x req=%02x val=%04x idx=%04x len=%04x\n", setup->bmRequest, setup->bRequest, setup->wValue, setup->wIndex, setup->wLength);
+
usb->ep0_state = USB_EP0_SETUP;
usb->ep0_setup_data_length = setup->wLength;
.bRequest = req[1],
.wValue = get_u16(req+2),
.wIndex = get_u16(req+4),
- .wLength = get_u16(req+2),
+ .wLength = get_u16(req+6),
};
usb_handle_setup(usb, &setup);
}