blob: 802a70c6d08c4385cc546111ad8c9384d7fa0c62 [file] [log] [blame]
Damien4b6e85c2013-10-21 09:56:56 +01001#include <string.h>
2
Damienfee89d52013-10-13 19:02:15 +01003#include "usb_core.h"
4#include "usbd_core.h"
Damien4a175e12013-10-17 22:50:21 +01005#include "usbd_cdc_core.h"
Damienfee89d52013-10-13 19:02:15 +01006#include "usbd_pyb_core.h"
Damiened656052013-10-13 00:42:20 +01007#include "usbd_usr.h"
8#include "usbd_desc.h"
Damien4b6e85c2013-10-21 09:56:56 +01009
10#include "misc.h"
Damien Georgeb5d13c32014-01-22 22:55:07 +000011#include "mpconfig.h"
12#include "qstr.h"
13#include "obj.h"
Damienfb42ec12013-10-19 15:37:09 +010014#include "usb.h"
Damiened656052013-10-13 00:42:20 +010015
Damien Georgeb5d13c32014-01-22 22:55:07 +000016#ifdef USE_DEVICE_MODE
Damien4a175e12013-10-17 22:50:21 +010017extern CDC_IF_Prop_TypeDef VCP_fops;
Damien Georgeb5d13c32014-01-22 22:55:07 +000018#endif
Damiened656052013-10-13 00:42:20 +010019
Damien George75abee22014-01-26 17:41:01 +000020USB_OTG_CORE_HANDLE USB_OTG_Core;
Damien3f69aca2013-10-21 23:46:04 +010021
Damien George75abee22014-01-26 17:41:01 +000022static int dev_is_enabled = 0;
Damien3f69aca2013-10-21 23:46:04 +010023static char rx_buf[64];
24static int rx_buf_in;
25static int rx_buf_out;
Damiened656052013-10-13 00:42:20 +010026
Damien George75abee22014-01-26 17:41:01 +000027void pyb_usb_dev_init(void) {
Damien Georgeb5d13c32014-01-22 22:55:07 +000028#ifdef USE_DEVICE_MODE
Damien George75abee22014-01-26 17:41:01 +000029 if (!dev_is_enabled) {
30 // only init USB once in the device's power-lifetime
31 USBD_Init(&USB_OTG_Core, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_PYB_cb, &USR_cb);
32 //USBD_Init(&USB_OTG_Core, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_PYB_HID_cb, &USR_cb);
Damiene9f1e502013-10-22 23:09:25 +010033 }
Damien4b6e85c2013-10-21 09:56:56 +010034 rx_buf_in = 0;
35 rx_buf_out = 0;
Damien George75abee22014-01-26 17:41:01 +000036 dev_is_enabled = 1;
37#endif
Damien4a175e12013-10-17 22:50:21 +010038}
39
Damien0f654512013-10-23 20:39:20 +010040bool usb_vcp_is_enabled(void) {
Damien George75abee22014-01-26 17:41:01 +000041 return dev_is_enabled;
Damien3f69aca2013-10-21 23:46:04 +010042}
43
Damien4b6e85c2013-10-21 09:56:56 +010044void usb_vcp_receive(const char *buf, uint32_t len) {
Damien George75abee22014-01-26 17:41:01 +000045 if (dev_is_enabled) {
Damienf48cf672013-10-21 10:42:06 +010046 for (int i = 0; i < len; i++) {
47 rx_buf[rx_buf_in++] = buf[i];
48 if (rx_buf_in >= sizeof(rx_buf)) {
49 rx_buf_in = 0;
50 }
51 if (rx_buf_in == rx_buf_out) {
52 rx_buf_out = rx_buf_in + 1;
53 if (rx_buf_out >= sizeof(rx_buf)) {
54 rx_buf_out = 0;
55 }
Damien4b6e85c2013-10-21 09:56:56 +010056 }
57 }
58 }
59}
60
Damien0f654512013-10-23 20:39:20 +010061int usb_vcp_rx_any(void) {
Damien4b6e85c2013-10-21 09:56:56 +010062 if (rx_buf_in >= rx_buf_out) {
63 return rx_buf_in - rx_buf_out;
64 } else {
65 return rx_buf_in + sizeof(rx_buf) - rx_buf_out;
66 }
67}
68
Damien0f654512013-10-23 20:39:20 +010069char usb_vcp_rx_get(void) {
Damien4b6e85c2013-10-21 09:56:56 +010070 while (rx_buf_out == rx_buf_in) {
71 }
72 char c = rx_buf[rx_buf_out];
73 rx_buf_out += 1;
74 if (rx_buf_out >= sizeof(rx_buf)) {
75 rx_buf_out = 0;
76 }
77 return c;
78}
79
80void usb_vcp_send_str(const char *str) {
81 usb_vcp_send_strn(str, strlen(str));
82}
83
84void usb_vcp_send_strn(const char *str, int len) {
Damien Georgeb5d13c32014-01-22 22:55:07 +000085#ifdef USE_DEVICE_MODE
Damien George75abee22014-01-26 17:41:01 +000086 if (dev_is_enabled) {
Damien4b6e85c2013-10-21 09:56:56 +010087 VCP_fops.pIf_DataTx((const uint8_t*)str, len);
Damien4a175e12013-10-17 22:50:21 +010088 }
Damien George75abee22014-01-26 17:41:01 +000089#endif
Damiened656052013-10-13 00:42:20 +010090}
Damien0c5827f2013-10-22 21:13:36 +010091
Damien George328708e2014-01-13 00:20:06 +000092#include "usbd_conf.h"
Damien0c5827f2013-10-22 21:13:36 +010093
94/* These are external variables imported from CDC core to be used for IN
95 transfer management. */
Damien Georgeb5d13c32014-01-22 22:55:07 +000096#ifdef USE_DEVICE_MODE
Damien0c5827f2013-10-22 21:13:36 +010097extern uint8_t APP_Rx_Buffer []; /* Write CDC received data in this buffer.
98 These data will be sent over USB IN endpoint
99 in the CDC core functions. */
100extern uint32_t APP_Rx_ptr_in; /* Increment this pointer or roll it back to
101 start address when writing received data
102 in the buffer APP_Rx_Buffer. */
Damien Georgeb5d13c32014-01-22 22:55:07 +0000103#endif
Damien0c5827f2013-10-22 21:13:36 +0100104
105void usb_vcp_send_strn_cooked(const char *str, int len) {
Damien Georgeb5d13c32014-01-22 22:55:07 +0000106#ifdef USE_DEVICE_MODE
Damien0c5827f2013-10-22 21:13:36 +0100107 for (const char *top = str + len; str < top; str++) {
108 if (*str == '\n') {
109 APP_Rx_Buffer[APP_Rx_ptr_in] = '\r';
110 APP_Rx_ptr_in = (APP_Rx_ptr_in + 1) & (APP_RX_DATA_SIZE - 1);
111 }
112 APP_Rx_Buffer[APP_Rx_ptr_in] = *str;
113 APP_Rx_ptr_in = (APP_Rx_ptr_in + 1) & (APP_RX_DATA_SIZE - 1);
114 }
Damien Georgeb5d13c32014-01-22 22:55:07 +0000115#endif
Damien0c5827f2013-10-22 21:13:36 +0100116}
Damien58a1b4c2013-10-25 20:53:54 +0100117
118void usb_hid_send_report(uint8_t *buf) {
Damien Georgeb5d13c32014-01-22 22:55:07 +0000119#ifdef USE_DEVICE_MODE
Damien George75abee22014-01-26 17:41:01 +0000120 USBD_HID_SendReport(&USB_OTG_Core, buf, 4);
Damien Georgeb5d13c32014-01-22 22:55:07 +0000121#endif
Damien58a1b4c2013-10-25 20:53:54 +0100122}
Damien George328708e2014-01-13 00:20:06 +0000123
124/******************************************************************************/
125// code for experimental USB OTG support
126
127#ifdef USE_HOST_MODE
128
Damien George75abee22014-01-26 17:41:01 +0000129#include "led.h"
130#include "usbh_core.h"
131#include "usbh_usr.h"
132#include "usbh_hid_core.h"
133#include "usbh_hid_keybd.h"
134#include "usbh_hid_mouse.h"
Damien George328708e2014-01-13 00:20:06 +0000135
136__ALIGN_BEGIN USBH_HOST USB_Host __ALIGN_END ;
137
138static int host_is_enabled = 0;
Damien George75abee22014-01-26 17:41:01 +0000139
140void pyb_usb_host_init(void) {
Damien George328708e2014-01-13 00:20:06 +0000141 if (!host_is_enabled) {
142 // only init USBH once in the device's power-lifetime
143 /* Init Host Library */
Damien George75abee22014-01-26 17:41:01 +0000144 USBH_Init(&USB_OTG_Core, USB_OTG_FS_CORE_ID, &USB_Host, &HID_cb, &USR_Callbacks);
Damien George328708e2014-01-13 00:20:06 +0000145 }
146 host_is_enabled = 1;
147}
148
Damien George75abee22014-01-26 17:41:01 +0000149void pyb_usb_host_process(void) {
150 USBH_Process(&USB_OTG_Core, &USB_Host);
Damien Georgeb5d13c32014-01-22 22:55:07 +0000151}
152
Damien George75abee22014-01-26 17:41:01 +0000153uint8_t usb_keyboard_key = 0;
154
155// TODO this is an ugly hack to get key presses
156uint pyb_usb_host_get_keyboard(void) {
157 uint key = usb_keyboard_key;
158 usb_keyboard_key = 0;
159 return key;
Damien George328708e2014-01-13 00:20:06 +0000160}
161
Damien George75abee22014-01-26 17:41:01 +0000162void USR_MOUSE_Init(void) {
163 led_state(4, 1);
164 USB_OTG_BSP_mDelay(100);
165 led_state(4, 0);
166}
167
168void USR_MOUSE_ProcessData(HID_MOUSE_Data_TypeDef *data) {
169 led_state(4, 1);
170 USB_OTG_BSP_mDelay(50);
171 led_state(4, 0);
172}
173
174void USR_KEYBRD_Init(void) {
175 led_state(4, 1);
176 USB_OTG_BSP_mDelay(100);
177 led_state(4, 0);
178}
179
180void USR_KEYBRD_ProcessData(uint8_t pbuf) {
181 led_state(4, 1);
182 USB_OTG_BSP_mDelay(50);
183 led_state(4, 0);
184 //lcd_print_strn((char*)&pbuf, 1);
185 usb_keyboard_key = pbuf;
Damien George3257d352014-01-23 22:16:15 +0000186}
187
Damien George328708e2014-01-13 00:20:06 +0000188#endif // USE_HOST_MODE