Browse Source

More formatting and comments.

master
flabbergast 6 years ago
parent
commit
237c23390b
  1. 1
      .gitignore
  2. 33
      projects/f030-blink/main.c
  3. 62
      projects/f030-serial-echo/main.c
  4. 44
      projects/f042-button-led/main.c
  5. 219
      projects/f042-usb-cdc/main.c
  6. 121
      projects/f072-rawhid/main.c
  7. 665
      projects/f072-rawhid/usb_hid.c
  8. 82
      projects/f072-rawhid/usb_hid.h
  9. 71
      projects/f072-teensy-debug-simple/main.c
  10. 418
      projects/f072-teensy-debug-simple/usb_hid_debug.c
  11. 57
      projects/f072-teensy-debug-simple/usb_hid_debug.h
  12. 71
      projects/f072-teensy-debug/main.c
  13. 466
      projects/f072-teensy-debug/usb_hid_debug.c
  14. 101
      projects/f072-teensy-debug/usb_hid_debug.h
  15. 36
      projects/f072nucleo-demo/main.c

1
.gitignore

@ -1,2 +1,3 @@
build/
.dep/
*.sublime-*

33
projects/f030-blink/main.c

@ -5,20 +5,20 @@
*/
/*
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
* ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
@ -33,10 +33,9 @@
*/
static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {
(void)arg;
chRegSetThreadName("blinker");
while (true) {
while(true) {
palClearPad(GPIOA, GPIOA_LED_AMBER);
palSetPad(GPIOA, GPIOA_PIN5);
chThdSleepMilliseconds(500);
@ -71,7 +70,7 @@ int main(void) {
* Normal main() thread activity, in this demo it does nothing except
* sleeping in a loop and check the button state.
*/
while (true) {
while(true) {
chThdSleepMilliseconds(1000);
}
}

62
projects/f030-serial-echo/main.c

@ -5,20 +5,20 @@
*/
/*
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
* ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
@ -33,10 +33,9 @@
*/
static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {
(void)arg;
chRegSetThreadName("blinker");
while (true) {
while(true) {
palClearPad(GPIOA, GPIOA_LED_AMBER);
chThdSleepMilliseconds(500);
palSetPad(GPIOA, GPIOA_LED_AMBER);
@ -52,19 +51,18 @@ static THD_FUNCTION(thSerEcho, arg) {
eventflags_t flags;
chEvtRegisterMask((event_source_t *)chnGetEventSource(&SD1), &serial_listener, EVENT_MASK(1));
while (true) {
chEvtWaitOneTimeout(EVENT_MASK(1), MS2ST(10));
flags = chEvtGetAndClearFlags(&serial_listener);
if (flags & CHN_INPUT_AVAILABLE) {
msg_t charbuf;
do {
charbuf = chnGetTimeout(&SD1, TIME_IMMEDIATE);
if ( charbuf != Q_TIMEOUT ) {
chSequentialStreamPut(&SD1, charbuf);
}
while(true) {
chEvtWaitOneTimeout(EVENT_MASK(1), MS2ST(10));
flags = chEvtGetAndClearFlags(&serial_listener);
if(flags & CHN_INPUT_AVAILABLE) {
msg_t charbuf;
do {
charbuf = chnGetTimeout(&SD1, TIME_IMMEDIATE);
if(charbuf != Q_TIMEOUT) {
chSequentialStreamPut(&SD1, charbuf);
}
while (charbuf != Q_TIMEOUT);
}
} while(charbuf != Q_TIMEOUT);
}
}
}
@ -101,11 +99,11 @@ int main(void) {
* Normal main() thread activity, in this demo it does nothing except
* sleeping in a loop and check the button state.
*/
while (true) {
if (palReadPad(GPIOB, GPIOB_BUTTON) == PAL_HIGH) {
while(true) {
if(palReadPad(GPIOB, GPIOB_BUTTON) == PAL_HIGH) {
sdWrite(&SD1, (uint8_t *)"hello world\r\n", 13);
//chprintf((BaseSequentialStream *)&SD1, "Hello world\r\n");
//chnWrite((BaseChannel *)&SD1, (uint8_t *)"Hello, world\r\n", 14);
/* chprintf((BaseSequentialStream *)&SD1, "Hello world\r\n"); */
/* chnWrite((BaseChannel *)&SD1, (uint8_t *)"Hello, world\r\n", 14); */
}
chThdSleepMilliseconds(200);
}

44
projects/f042-button-led/main.c

@ -5,20 +5,20 @@
*/
/*
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
* ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ch.h"
#include "hal.h"
@ -30,11 +30,10 @@ static int ledState = 1;
*/
static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {
(void)arg;
chRegSetThreadName("blinker1");
/*
*while (true) {
* while (true) {
* palClearPad(GPIOA, GPIOA_LED_AMBER);
* chThdSleepMilliseconds(250);
* palSetPad(GPIOA, GPIOA_LED_AMBER);
@ -55,15 +54,15 @@ static THD_FUNCTION(Thread2, arg) {
(void)arg;
chRegSetThreadName("checkbutton1");
uint8_t newstate,state = PAL_LOW;
uint8_t newstate, state = PAL_LOW;
while(true) {
if( palReadPad(GPIOB, GPIOB_BUTTON) != state ) {
chThdSleepMilliseconds(20); // debounce
if(palReadPad(GPIOB, GPIOB_BUTTON) != state) {
chThdSleepMilliseconds(20); /* debounce */
newstate = palReadPad(GPIOB, GPIOB_BUTTON);
if( newstate != state ) {
if(newstate != state) {
state = newstate;
if (newstate == PAL_HIGH) {
if(newstate == PAL_HIGH) {
ledState = !ledState;
}
}
@ -76,7 +75,6 @@ static THD_FUNCTION(Thread2, arg) {
* Application entry point.
*/
int main(void) {
/*
* System initializations.
* - HAL initialization, this also initializes the configured device drivers
@ -102,7 +100,7 @@ int main(void) {
* sleeping in a loop and check the button state, when the button is
* pressed ... nothing happens.
*/
while (true) {
while(true) {
chThdSleepMilliseconds(500);
}
}

219
projects/f042-usb-cdc/main.c

@ -2,23 +2,24 @@
* (c) 2015 flabbergast <s3+flabbergast@sdfeu.org>
* Based on ChibiOS 3.0.1 demo code, license below.
* Licensed under the Apache License, Version 2.0.
*
*/
/*
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
*
* ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
@ -28,9 +29,9 @@
#include "chprintf.h"
/*===========================================================================*/
/* USB related stuff. */
/*===========================================================================*/
/*===========================================================================
* USB related stuff.
*===========================================================================*/
/*
* Endpoints to be used for USBD1.
@ -48,18 +49,18 @@ static SerialUSBDriver SDU1;
* USB Device Descriptor.
*/
static const uint8_t vcom_device_descriptor_data[18] = {
USB_DESC_DEVICE (0x0110, /* bcdUSB (1.1). */
0x02, /* bDeviceClass (CDC). */
0x00, /* bDeviceSubClass. */
0x00, /* bDeviceProtocol. */
0x40, /* bMaxPacketSize. */
0x0483, /* idVendor (ST). */
0x5740, /* idProduct. */
0x0200, /* bcdDevice. */
1, /* iManufacturer. */
2, /* iProduct. */
3, /* iSerialNumber. */
1) /* bNumConfigurations. */
USB_DESC_DEVICE(0x0110, /* bcdUSB (1.1). */
0x02, /* bDeviceClass (CDC). */
0x00, /* bDeviceSubClass. */
0x00, /* bDeviceProtocol. */
0x40, /* bMaxPacketSize. */
0x0483, /* idVendor (ST). */
0x5740, /* idProduct. */
0x0200, /* bcdDevice. */
1, /* iManufacturer. */
2, /* iProduct. */
3, /* iSerialNumber. */
1) /* bNumConfigurations. */
};
/*
@ -80,71 +81,71 @@ static const uint8_t vcom_configuration_descriptor_data[67] = {
0xC0, /* bmAttributes (self powered). */
50), /* bMaxPower (100mA). */
/* Interface Descriptor.*/
USB_DESC_INTERFACE (0x00, /* bInterfaceNumber. */
0x00, /* bAlternateSetting. */
0x01, /* bNumEndpoints. */
0x02, /* bInterfaceClass (Communications
Interface Class, CDC section
4.2). */
0x02, /* bInterfaceSubClass (Abstract
Control Model, CDC section 4.3). */
0x01, /* bInterfaceProtocol (AT commands,
CDC section 4.4). */
0), /* iInterface. */
USB_DESC_INTERFACE(0x00, /* bInterfaceNumber. */
0x00, /* bAlternateSetting. */
0x01, /* bNumEndpoints. */
0x02, /* bInterfaceClass (Communications
* Interface Class, CDC section
* 4.2). */
0x02, /* bInterfaceSubClass (Abstract
* Control Model, CDC section 4.3). */
0x01, /* bInterfaceProtocol (AT commands,
* CDC section 4.4). */
0), /* iInterface. */
/* Header Functional Descriptor (CDC section 5.2.3).*/
USB_DESC_BYTE (5), /* bLength. */
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
USB_DESC_BYTE (0x00), /* bDescriptorSubtype (Header
Functional Descriptor. */
USB_DESC_BCD (0x0110), /* bcdCDC. */
USB_DESC_BYTE(5), /* bLength. */
USB_DESC_BYTE(0x24), /* bDescriptorType (CS_INTERFACE). */
USB_DESC_BYTE(0x00), /* bDescriptorSubtype (Header
* Functional Descriptor. */
USB_DESC_BCD(0x0110), /* bcdCDC. */
/* Call Management Functional Descriptor. */
USB_DESC_BYTE (5), /* bFunctionLength. */
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
USB_DESC_BYTE (0x01), /* bDescriptorSubtype (Call Management
Functional Descriptor). */
USB_DESC_BYTE (0x00), /* bmCapabilities (D0+D1). */
USB_DESC_BYTE (0x01), /* bDataInterface. */
USB_DESC_BYTE(5), /* bFunctionLength. */
USB_DESC_BYTE(0x24), /* bDescriptorType (CS_INTERFACE). */
USB_DESC_BYTE(0x01), /* bDescriptorSubtype (Call Management
* Functional Descriptor). */
USB_DESC_BYTE(0x00), /* bmCapabilities (D0+D1). */
USB_DESC_BYTE(0x01), /* bDataInterface. */
/* ACM Functional Descriptor.*/
USB_DESC_BYTE (4), /* bFunctionLength. */
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
USB_DESC_BYTE (0x02), /* bDescriptorSubtype (Abstract
Control Management Descriptor). */
USB_DESC_BYTE (0x02), /* bmCapabilities. */
USB_DESC_BYTE(4), /* bFunctionLength. */
USB_DESC_BYTE(0x24), /* bDescriptorType (CS_INTERFACE). */
USB_DESC_BYTE(0x02), /* bDescriptorSubtype (Abstract
* Control Management Descriptor). */
USB_DESC_BYTE(0x02), /* bmCapabilities. */
/* Union Functional Descriptor.*/
USB_DESC_BYTE (5), /* bFunctionLength. */
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
USB_DESC_BYTE (0x06), /* bDescriptorSubtype (Union
Functional Descriptor). */
USB_DESC_BYTE (0x00), /* bMasterInterface (Communication
Class Interface). */
USB_DESC_BYTE (0x01), /* bSlaveInterface0 (Data Class
Interface). */
USB_DESC_BYTE(5), /* bFunctionLength. */
USB_DESC_BYTE(0x24), /* bDescriptorType (CS_INTERFACE). */
USB_DESC_BYTE(0x06), /* bDescriptorSubtype (Union
* Functional Descriptor). */
USB_DESC_BYTE(0x00), /* bMasterInterface (Communication
* Class Interface). */
USB_DESC_BYTE(0x01), /* bSlaveInterface0 (Data Class
* Interface). */
/* Endpoint 2 Descriptor.*/
USB_DESC_ENDPOINT (USBD1_INTERRUPT_REQUEST_EP|0x80,
0x03, /* bmAttributes (Interrupt). */
0x0008, /* wMaxPacketSize. */
0xFF), /* bInterval. */
USB_DESC_ENDPOINT(USBD1_INTERRUPT_REQUEST_EP | 0x80,
0x03, /* bmAttributes (Interrupt). */
0x0008, /* wMaxPacketSize. */
0xFF), /* bInterval. */
/* Interface Descriptor.*/
USB_DESC_INTERFACE (0x01, /* bInterfaceNumber. */
0x00, /* bAlternateSetting. */
0x02, /* bNumEndpoints. */
0x0A, /* bInterfaceClass (Data Class
Interface, CDC section 4.5). */
0x00, /* bInterfaceSubClass (CDC section
4.6). */
0x00, /* bInterfaceProtocol (CDC section
4.7). */
0x00), /* iInterface. */
USB_DESC_INTERFACE(0x01, /* bInterfaceNumber. */
0x00, /* bAlternateSetting. */
0x02, /* bNumEndpoints. */
0x0A, /* bInterfaceClass (Data Class
* Interface, CDC section 4.5). */
0x00, /* bInterfaceSubClass (CDC section
* 4.6). */
0x00, /* bInterfaceProtocol (CDC section
* 4.7). */
0x00), /* iInterface. */
/* Endpoint 3 Descriptor.*/
USB_DESC_ENDPOINT (USBD1_DATA_AVAILABLE_EP, /* bEndpointAddress.*/
0x02, /* bmAttributes (Bulk). */
0x0040, /* wMaxPacketSize. */
0x00), /* bInterval. */
USB_DESC_ENDPOINT(USBD1_DATA_AVAILABLE_EP, /* bEndpointAddress.*/
0x02, /* bmAttributes (Bulk). */
0x0040, /* wMaxPacketSize. */
0x00), /* bInterval. */
/* Endpoint 1 Descriptor.*/
USB_DESC_ENDPOINT (USBD1_DATA_REQUEST_EP|0x80, /* bEndpointAddress.*/
0x02, /* bmAttributes (Bulk). */
0x0040, /* wMaxPacketSize. */
0x00) /* bInterval. */
USB_DESC_ENDPOINT(USBD1_DATA_REQUEST_EP | 0x80, /* bEndpointAddress.*/
0x02, /* bmAttributes (Bulk). */
0x0040, /* wMaxPacketSize. */
0x00) /* bInterval. */
};
/*
@ -202,10 +203,10 @@ static const uint8_t vcom_string3[] = {
* Strings wrappers array.
*/
static const USBDescriptor vcom_strings[] = {
{sizeof vcom_string0, vcom_string0},
{sizeof vcom_string1, vcom_string1},
{sizeof vcom_string2, vcom_string2},
{sizeof vcom_string3, vcom_string3}
{ sizeof vcom_string0, vcom_string0 },
{ sizeof vcom_string1, vcom_string1 },
{ sizeof vcom_string2, vcom_string2 },
{ sizeof vcom_string3, vcom_string3 }
};
/*
@ -216,16 +217,17 @@ static const USBDescriptor *get_descriptor(USBDriver *usbp,
uint8_t dtype,
uint8_t dindex,
uint16_t lang) {
(void)usbp;
(void)lang;
switch (dtype) {
switch(dtype) {
case USB_DESCRIPTOR_DEVICE:
return &vcom_device_descriptor;
case USB_DESCRIPTOR_CONFIGURATION:
return &vcom_configuration_descriptor;
case USB_DESCRIPTOR_STRING:
if (dindex < 4)
if(dindex < 4)
return &vcom_strings[dindex];
}
return NULL;
@ -282,18 +284,19 @@ static const USBEndpointConfig ep2config = {
* Handles the USB driver global events.
*/
static void usb_event(USBDriver *usbp, usbevent_t event) {
switch (event) {
switch(event) {
case USB_EVENT_RESET:
return;
case USB_EVENT_ADDRESS:
return;
case USB_EVENT_CONFIGURED:
chSysLockFromISR();
/* Enables the endpoints specified into the configuration.
Note, this callback is invoked from an ISR so I-Class functions
must be used.*/
* Note, this callback is invoked from an ISR so I-Class functions
* must be used.*/
usbInitEndpointI(usbp, USBD1_DATA_REQUEST_EP, &ep1config);
usbInitEndpointI(usbp, USBD1_INTERRUPT_REQUEST_EP, &ep2config);
@ -302,10 +305,13 @@ static void usb_event(USBDriver *usbp, usbevent_t event) {
chSysUnlockFromISR();
return;
case USB_EVENT_SUSPEND:
return;
case USB_EVENT_WAKEUP:
return;
case USB_EVENT_STALLED:
return;
}
@ -332,19 +338,18 @@ static const SerialUSBConfig serusbcfg = {
USBD1_INTERRUPT_REQUEST_EP
};
/*===========================================================================*/
/* Generic code. */
/*===========================================================================*/
/*===========================================================================
* Generic code.
*===========================================================================*/
/*
* LED blinker thread, times are in milliseconds.
*/
static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {
(void)arg;
chRegSetThreadName("blinker");
while (true) {
while(true) {
systime_t time = serusbcfg.usbp->state == USB_ACTIVE ? 250 : 500;
palClearPad(GPIOA, GPIOA_LED_AMBER);
chThdSleepMilliseconds(time);
@ -397,11 +402,11 @@ int main(void) {
* Normal main() thread activity, in this demo it does nothing except
* sleeping in a loop and check the button state.
*/
while (true) {
if ( (palReadPad(GPIOB, GPIOB_BUTTON) == PAL_HIGH) && (SDU1.config->usbp->state == USB_ACTIVE)) {
//sdWrite(&SDU1, (uint8_t *)"hello world\r\n", 13);
while(true) {
if((palReadPad(GPIOB, GPIOB_BUTTON) == PAL_HIGH) && (SDU1.config->usbp->state == USB_ACTIVE)) {
/* sdWrite(&SDU1, (uint8_t *)"hello world\r\n", 13); */
chprintf((BaseSequentialStream *)&SDU1, "Hello world\r\n");
//chnWrite((BaseChannel *)&SDU1, (uint8_t *)"Hello, world\r\n", 14);
/* chnWrite((BaseChannel *)&SDU1, (uint8_t *)"Hello, world\r\n", 14); */
}
chThdSleepMilliseconds(200);
}

121
projects/f072-rawhid/main.c

@ -6,28 +6,28 @@
*/
/*
Copyright (c) 2014 Guillaume Duc <guillaume@guiduc.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
*
* Copyright (c) 2014 Guillaume Duc <guillaume@guiduc.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
#include "ch.h"
#include "hal.h"
@ -52,23 +52,22 @@ static THD_FUNCTION(buttonThread, arg) {
wkup_old_state = 0;
while (1) {
wkup_cur_state = palReadPad (GPIOA, GPIOA_BUTTON);
if (wkup_cur_state != wkup_old_state) {
chSysLock ();
if (usbGetDriverStateI (&USBD1) == USB_ACTIVE) {
chSysUnlock ();
// Build the IN report to be sent
usb_build_in_report (&usb_hid_in_report);
// Send the IN report
usb_send_hid_report (&usb_hid_in_report);
}
else
chSysUnlock ();
while(1) {
wkup_cur_state = palReadPad(GPIOA, GPIOA_BUTTON);
if(wkup_cur_state != wkup_old_state) {
chSysLock();
if(usbGetDriverStateI(&USBD1) == USB_ACTIVE) {
chSysUnlock();
/* Build the IN report to be sent */
usb_build_in_report(&usb_hid_in_report);
/* Send the IN report */
usb_send_hid_report(&usb_hid_in_report);
}else
chSysUnlock();
wkup_old_state = wkup_cur_state;
}
chThdSleepMilliseconds (50);
chThdSleepMilliseconds(50);
}
}
@ -81,7 +80,7 @@ static THD_FUNCTION(blinkerThread, arg) {
(void)arg;
chRegSetThreadName("blinkerThread");
while (true) {
while(true) {
systime_t time = USBD1.state == USB_ACTIVE ? 250 : 500;
palClearPad(GPIOC, GPIOC_LED_BLUE);
chThdSleepMilliseconds(time);
@ -94,45 +93,41 @@ static THD_FUNCTION(blinkerThread, arg) {
/*
* Main thread
*/
int main (void) {
// ChibiOS/RT init
halInit ();
chSysInit ();
int main(void) {
/* ChibiOS/RT init */
halInit();
chSysInit();
palSetPad(GPIOC, GPIOC_LED_BLUE);
chThdSleepMilliseconds(400);
palClearPad(GPIOC, GPIOC_LED_BLUE);
// Init USB
//init_usb_serial_string ();
init_usb_queues ();
init_usb_driver ();
/* Init USB */
init_usb_queues();
init_usb_driver();
chThdCreateStatic(waBlinkerThread, sizeof(waBlinkerThread), NORMALPRIO, blinkerThread, NULL);
// Wait until the USB is active
while (USBD1.state != USB_ACTIVE)
chThdSleepMilliseconds (1000);
/* Wait until the USB is active */
while(USBD1.state != USB_ACTIVE)
chThdSleepMilliseconds(1000);
// palSetPad (GPIOC, GPIOC_LED_BLUE);
chThdSleepMilliseconds(500);
chThdSleepMilliseconds (500);
// Start the button thread
/* Start the button thread */
chThdCreateStatic(waButtonThread, sizeof(waButtonThread), NORMALPRIO, buttonThread, NULL);
/*
* Main loop: waits until a OUT report is received and updates the
* LED
* Main loop: waits until a OUT report is received and updates the LED
*/
while (1) {
if (chIQReadTimeout
(&usb_input_queue, (uint8_t *) & usb_hid_out_report,
USB_HID_OUT_REPORT_SIZE, TIME_INFINITE) == USB_HID_OUT_REPORT_SIZE) {
if (usb_hid_out_report.led_value == 0)
palSetPad (GPIOC, GPIOC_LED_RED);
else
palClearPad (GPIOC, GPIOC_LED_RED);
}
while(1) {
if(chIQReadTimeout
(&usb_input_queue, (uint8_t *)&usb_hid_out_report,
USB_HID_OUT_REPORT_SIZE, TIME_INFINITE) == USB_HID_OUT_REPORT_SIZE) {
if(usb_hid_out_report.led_value == 0)
palSetPad(GPIOC, GPIOC_LED_RED);
else
palClearPad(GPIOC, GPIOC_LED_RED);
}
}
}

665
projects/f072-rawhid/usb_hid.c

@ -6,44 +6,44 @@
*/
/*
Copyright (c) 2014 Guillaume Duc <guillaume@guiduc.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
*
* Copyright (c) 2014 Guillaume Duc <guillaume@guiduc.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
#include "ch.h"
#include "hal.h"
#include "usb_hid.h"
// The USB driver to use
/* The USB driver to use */
#define USB_DRIVER USBD1
// HID specific constants
/* HID specific constants */
#define USB_DESCRIPTOR_HID 0x21
#define USB_DESCRIPTOR_HID_REPORT 0x22
#define HID_GET_REPORT 0x01
#define HID_SET_REPORT 0x09
// Endpoints
/* Endpoints */
#define USBD1_IN_EP 1
#define USBD1_OUT_EP 1
@ -55,28 +55,28 @@ static uint8_t usb_output_queue_buffer[USB_OUTPUT_QUEUE_BUFFER_SIZE];
static uint8_t in_report_sequence_number = 0;
// IN EP1 state
/* IN EP1 state */
static USBInEndpointState ep1instate;
// OUT EP1 state
/* OUT EP1 state */
static USBOutEndpointState ep1outstate;
// USB Device Descriptor
/* USB Device Descriptor */
static const uint8_t usb_device_descriptor_data[] = {
USB_DESC_DEVICE (0x0110, // bcdUSB (1.1)
0x00, // bDeviceClass (defined in later in interface)
0x00, // bDeviceSubClass
0x00, // bDeviceProtocol
0x40, // bMaxPacketSize (64 bytes)
0x0483, // idVendor (ST)
0x5740, // idProduct (STM32)
0x0000, // bcdDevice
1, // iManufacturer
2, // iProduct
3, // iSerialNumber
1) // bNumConfigurations
USB_DESC_DEVICE(0x0110, /* bcdUSB (1.1) */
0x00, /* bDeviceClass (defined in later in interface) */
0x00, /* bDeviceSubClass */
0x00, /* bDeviceProtocol */
0x40, /* bMaxPacketSize (64 bytes) */
0x0483, /* idVendor (ST) */
0x5740, /* idProduct (STM32) */
0x0000, /* bcdDevice */
1, /* iManufacturer */
2, /* iProduct */
3, /* iSerialNumber */
1) /* bNumConfigurations */
};
// Device Descriptor wrapper
/* Device Descriptor wrapper */
static const USBDescriptor usb_device_descriptor = {
sizeof usb_device_descriptor_data,
usb_device_descriptor_data
@ -95,51 +95,51 @@ static const USBDescriptor usb_device_descriptor = {
#define HID_DESCRIPTOR_SIZE 9
static const uint8_t hid_configuration_descriptor_data[] = {
// Configuration Descriptor (9 bytes)
USB_DESC_CONFIGURATION (41, // wTotalLength (9+9+9+7+7)
0x01, // bNumInterfaces
0x01, // bConfigurationValue
0, // iConfiguration
0xC0, // bmAttributes (self powered, set to 0x80 if not)
50), // bMaxPower (100mA)
// Interface Descriptor (9 bytes)
USB_DESC_INTERFACE (0x00, // bInterfaceNumber
0x00, // bAlternateSetting
0x02, // bNumEndpoints
0x03, // bInterfaceClass: HID
0x00, // bInterfaceSubClass: None
0x00, // bInterfaceProtocol: None
0), // iInterface
// HID descriptor (9 bytes)
USB_DESC_BYTE (9), // bLength
USB_DESC_BYTE (0x21), // bDescriptorType (HID class)
USB_DESC_BCD (0x0110), // bcdHID: HID version 1.1
USB_DESC_BYTE (0x00), // bCountryCode
USB_DESC_BYTE (0x01), // bNumDescriptors
USB_DESC_BYTE (0x22), // bDescriptorType (report desc)
USB_DESC_WORD (34), // wDescriptorLength
// Endpoint 1 IN Descriptor (7 bytes)
USB_DESC_ENDPOINT (USBD1_IN_EP | 0x80, // bEndpointAddress
0x03, // bmAttributes (Interrupt)
0x0040, // wMaxPacketSize
0x0A), // bInterval (10 ms)
// Endpoint 1 OUT Descriptor (7 bytes)
USB_DESC_ENDPOINT (USBD1_OUT_EP, // bEndpointAddress
0x03, // bmAttributes (Interrupt)
0x0040, // wMaxPacketSize
0x0A) // bInterval (10 ms)
/* Configuration Descriptor (9 bytes) */
USB_DESC_CONFIGURATION(41, /* wTotalLength (9+9+9+7+7) */
0x01, /* bNumInterfaces */
0x01, /* bConfigurationValue */
0, /* iConfiguration */
0xC0, /* bmAttributes (self powered, set to 0x80 if not) */
50), /* bMaxPower (100mA) */
/* Interface Descriptor (9 bytes) */
USB_DESC_INTERFACE(0x00, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x02, /* bNumEndpoints */
0x03, /* bInterfaceClass: HID */
0x00, /* bInterfaceSubClass: None */
0x00, /* bInterfaceProtocol: None */
0), /* iInterface */
/* HID descriptor (9 bytes) */
USB_DESC_BYTE(9), /* bLength */
USB_DESC_BYTE(0x21), /* bDescriptorType (HID class) */
USB_DESC_BCD(0x0110), /* bcdHID: HID version 1.1 */
USB_DESC_BYTE(0x00), /* bCountryCode */
USB_DESC_BYTE(0x01), /* bNumDescriptors */
USB_DESC_BYTE(0x22), /* bDescriptorType (report desc) */
USB_DESC_WORD(34), /* wDescriptorLength */
/* Endpoint 1 IN Descriptor (7 bytes) */
USB_DESC_ENDPOINT(USBD1_IN_EP | 0x80, /* bEndpointAddress */
0x03, /* bmAttributes (Interrupt) */
0x0040, /* wMaxPacketSize */
0x0A), /* bInterval (10 ms) */
/* Endpoint 1 OUT Descriptor (7 bytes) */
USB_DESC_ENDPOINT(USBD1_OUT_EP, /* bEndpointAddress */
0x03, /* bmAttributes (Interrupt) */
0x0040, /* wMaxPacketSize */
0x0A) /* bInterval (10 ms) */
};
// Configuration Descriptor wrapper
/* Configuration Descriptor wrapper */
static const USBDescriptor hid_configuration_descriptor = {
sizeof hid_configuration_descriptor_data,
hid_configuration_descriptor_data
};
// HID descriptor wrapper
/* HID descriptor wrapper */
static const USBDescriptor hid_descriptor = {
HID_DESCRIPTOR_SIZE,
&hid_configuration_descriptor_data[HID_DESCRIPTOR_OFFSET]
@ -157,91 +157,91 @@ static const USBDescriptor hid_descriptor = {
* detailed descrition of all the fields
*/
static const uint8_t hid_report_descriptor_data[] = {
USB_DESC_BYTE (0x06), // Usage Page (vendor-defined)
USB_DESC_WORD (0xFF00),
USB_DESC_BYTE (0x09), // Usage (vendor-defined)
USB_DESC_BYTE (0x01),
USB_DESC_BYTE (0xA1), // Collection (application)
USB_DESC_BYTE (0x01),
USB_DESC_BYTE (0x09), // Usage (vendor-defined)
USB_DESC_BYTE (0x01),
USB_DESC_BYTE (0x15), // Logical minimum (0)
USB_DESC_BYTE (0x00),
USB_DESC_BYTE (0x26), // Logical maximum (255)
USB_DESC_WORD (0x00FF),
USB_DESC_BYTE (0x75), // Report size (8 bits)
USB_DESC_BYTE (0x08),
USB_DESC_BYTE (0x95), // Report count (USB_HID_IN_REPORT_SIZE)
USB_DESC_BYTE (USB_HID_IN_REPORT_SIZE),
USB_DESC_BYTE (0x81), // Input (Data, Variable, Absolute)
USB_DESC_BYTE (0x02),
USB_DESC_BYTE (0x09), // Usage (vendor-defined)
USB_DESC_BYTE (0x01),
USB_DESC_BYTE (0x15), // Logical minimum (0)
USB_DESC_BYTE (0x00),
USB_DESC_BYTE (0x26), // Logical maximum (255)
USB_DESC_WORD (0x00FF),
USB_DESC_BYTE (0x75), // Report size (8 bits)
USB_DESC_BYTE (0x08),
USB_DESC_BYTE (0x95), // Report count (USB_HID_OUT_REPORT_SIZE)
USB_DESC_BYTE (USB_HID_OUT_REPORT_SIZE),
USB_DESC_BYTE (0x91), // Output (Data, Variable, Absolute)
USB_DESC_BYTE (0x02),
USB_DESC_BYTE (0xC0) // End collection
USB_DESC_BYTE(0x06), /* Usage Page (vendor-defined) */
USB_DESC_WORD(0xFF00),
USB_DESC_BYTE(0x09), /* Usage (vendor-defined) */
USB_DESC_BYTE(0x01),
USB_DESC_BYTE(0xA1), /* Collection (application) */
USB_DESC_BYTE(0x01),
USB_DESC_BYTE(0x09), /* Usage (vendor-defined) */
USB_DESC_BYTE(0x01),
USB_DESC_BYTE(0x15), /* Logical minimum (0) */
USB_DESC_BYTE(0x00),
USB_DESC_BYTE(0x26), /* Logical maximum (255) */
USB_DESC_WORD(0x00FF),
USB_DESC_BYTE(0x75), /* Report size (8 bits) */
USB_DESC_BYTE(0x08),
USB_DESC_BYTE(0x95), /* Report count (USB_HID_IN_REPORT_SIZE) */
USB_DESC_BYTE(USB_HID_IN_REPORT_SIZE),
USB_DESC_BYTE(0x81), /* Input (Data, Variable, Absolute) */
USB_DESC_BYTE(0x02),
USB_DESC_BYTE(0x09), /* Usage (vendor-defined) */
USB_DESC_BYTE(0x01),
USB_DESC_BYTE(0x15), /* Logical minimum (0) */
USB_DESC_BYTE(0x00),
USB_DESC_BYTE(0x26), /* Logical maximum (255) */
USB_DESC_WORD(0x00FF),
USB_DESC_BYTE(0x75), /* Report size (8 bits) */
USB_DESC_BYTE(0x08),
USB_DESC_BYTE(0x95), /* Report count (USB_HID_OUT_REPORT_SIZE) */
USB_DESC_BYTE(USB_HID_OUT_REPORT_SIZE),
USB_DESC_BYTE(0x91), /* Output (Data, Variable, Absolute) */
USB_DESC_BYTE(0x02),
USB_DESC_BYTE(0xC0) /* End collection */
};
// HID report descriptor wrapper
/* HID report descriptor wrapper */
static const USBDescriptor hid_report_descriptor = {
sizeof hid_report_descriptor_data,
hid_report_descriptor_data
};
// U.S. English language identifier
/* U.S. English language identifier */
static const uint8_t usb_string_langid[] = {
USB_DESC_BYTE (4), // bLength
USB_DESC_BYTE (USB_DESCRIPTOR_STRING), // bDescriptorType
USB_DESC_WORD (0x0409) // wLANGID (U.S. English)
USB_DESC_BYTE(4), /* bLength */
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType */
USB_DESC_WORD(0x0409) /* wLANGID (U.S. English) */
};
// Vendor string
/* Vendor string */
static const uint8_t usb_string_vendor[] = {
USB_DESC_BYTE (38), // bLength
USB_DESC_BYTE (USB_DESCRIPTOR_STRING), // bDescriptorType
USB_DESC_BYTE(38), /* bLength */
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType */
'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0,
'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0,
'c', 0, 's', 0
};
// Device Description string
/* Device Description string */
static const uint8_t usb_string_description[] = {
USB_DESC_BYTE (48), // bLength
USB_DESC_BYTE (USB_DESCRIPTOR_STRING), // bDescriptorType
USB_DESC_BYTE(48), /* bLength */
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType */
'C', 0, 'h', 0, 'i', 0, 'b', 0, 'i', 0, 'O', 0, 'S', 0, '/', 0,
'R', 0, 'T', 0, ' ', 0, 'U', 0, 'S', 0, 'B', 0, ' ', 0, 'H', 0,
'I', 0, 'D', 0, ' ', 0, 'T', 0, 'e', 0, 's', 0, 't', 0
};
// Serial Number string (will be filled by the function init_usb_serial_string)
/* Serial Number string (will be filled by the function init_usb_serial_string) */
static uint8_t usb_string_serial[] = {
USB_DESC_BYTE (50), // bLength
USB_DESC_BYTE (USB_DESCRIPTOR_STRING), // bDescriptorType
USB_DESC_BYTE(50), /* bLength */
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType */
'1', 0, '2', 0, '3', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0,
'0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0,
'0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0
};
// Strings wrappers array
/* Strings wrappers array */
static const USBDescriptor usb_strings[] = {
{sizeof usb_string_langid, usb_string_langid}
{ sizeof usb_string_langid, usb_string_langid }
,
{sizeof usb_string_vendor, usb_string_vendor}
{ sizeof usb_string_vendor, usb_string_vendor }
,
{sizeof usb_string_description, usb_string_description}
{ sizeof usb_string_description, usb_string_description }
,
{sizeof usb_string_serial, usb_string_serial}
{ sizeof usb_string_serial, usb_string_serial }
};
/*
@ -250,30 +250,33 @@ static const USBDescriptor usb_strings[] = {
* Returns the proper descriptor
*/
static const USBDescriptor *
usb_get_descriptor_cb (USBDriver __attribute__ ((__unused__)) * usbp,
uint8_t dtype,
uint8_t dindex,
uint16_t __attribute__ ((__unused__)) lang)
{
switch (dtype)
{
// Generic descriptors
case USB_DESCRIPTOR_DEVICE: // Device Descriptor
return &usb_device_descriptor;
case USB_DESCRIPTOR_CONFIGURATION: // Configuration Descriptor
return &hid_configuration_descriptor;
case USB_DESCRIPTOR_STRING: // Strings
if (dindex < 4)
return &usb_strings[dindex];
break;
// HID specific descriptors
case USB_DESCRIPTOR_HID: // HID Descriptor
return &hid_descriptor;
case USB_DESCRIPTOR_HID_REPORT: // HID Report Descriptor
return &hid_report_descriptor;
}
usb_get_descriptor_cb(USBDriver *usbp,
uint8_t dtype,
uint8_t dindex,
uint16_t lang){
(void)usbp;
(void)lang;
switch(dtype) {
/* Generic descriptors */
case USB_DESCRIPTOR_DEVICE: /* Device Descriptor */
return &usb_device_descriptor;
case USB_DESCRIPTOR_CONFIGURATION: /* Configuration Descriptor */
return &hid_configuration_descriptor;
case USB_DESCRIPTOR_STRING: /* Strings */
if(dindex < 4)
return &usb_strings[dindex];
break;
/* HID specific descriptors */
case USB_DESCRIPTOR_HID: /* HID Descriptor */
return &hid_descriptor;
case USB_DESCRIPTOR_HID_REPORT: /* HID Report Descriptor */
return &hid_report_descriptor;
}
return NULL;
}
@ -286,23 +289,24 @@ usb_get_descriptor_cb (USBDriver __attribute__ ((__unused__)) * usbp,
* schedule the transmission
*/
static void
ep1in_cb (USBDriver __attribute__ ((__unused__)) * usbp,
usbep_t __attribute__ ((__unused__)) ep)
{
chSysLockFromISR ();
// Check if there is data to send in the output queue
if (chOQGetFullI (&usb_output_queue) >= USB_HID_IN_REPORT_SIZE)
{
chSysUnlockFromISR ();
// Prepare the transmission
usbPrepareQueuedTransmit (&USB_DRIVER, USBD1_IN_EP, &usb_output_queue,
USB_HID_IN_REPORT_SIZE);
chSysLockFromISR ();
usbStartTransmitI (&USB_DRIVER, USBD1_IN_EP);
}
ep1in_cb(USBDriver *usbp,
usbep_t ep){
(void)usbp;
(void)ep;
chSysLockFromISR();
/* Check if there is data to send in the output queue */
if(chOQGetFullI(&usb_output_queue) >= USB_HID_IN_REPORT_SIZE) {
chSysUnlockFromISR();
/* Prepare the transmission */
usbPrepareQueuedTransmit(&USB_DRIVER, USBD1_IN_EP, &usb_output_queue,
USB_HID_IN_REPORT_SIZE);
chSysLockFromISR();
usbStartTransmitI(&USB_DRIVER, USBD1_IN_EP);
}
chSysUnlockFromISR ();
chSysUnlockFromISR();
}
/*
@ -313,135 +317,132 @@ ep1in_cb (USBDriver __attribute__ ((__unused__)) * usbp,
* report.
*/
static void
ep1out_cb (USBDriver __attribute__ ((__unused__)) * usbp,
usbep_t __attribute__ ((__unused__)) ep)
{
chSysLockFromISR ();
// Check if there is still some space left in the input queue
if (chIQGetEmptyI (&usb_input_queue) >= USB_HID_OUT_REPORT_SIZE)
{
chSysUnlockFromISR ();
// Prepares the reception of new data
usbPrepareQueuedReceive (&USB_DRIVER, USBD1_OUT_EP, &usb_input_queue,
USB_HID_OUT_REPORT_SIZE);
chSysLockFromISR ();
usbStartReceiveI (&USB_DRIVER, USBD1_OUT_EP);
}
ep1out_cb(USBDriver *usbp,
usbep_t ep){
(void)usbp;
(void)ep;
chSysLockFromISR();
/* Check if there is still some space left in the input queue */
if(chIQGetEmptyI(&usb_input_queue) >= USB_HID_OUT_REPORT_SIZE) {
chSysUnlockFromISR();
/* Prepares the reception of new data */
usbPrepareQueuedReceive(&USB_DRIVER, USBD1_OUT_EP, &usb_input_queue,
USB_HID_OUT_REPORT_SIZE);
chSysLockFromISR();
usbStartReceiveI(&USB_DRIVER, USBD1_OUT_EP);
}
chSysUnlockFromISR ();
chSysUnlockFromISR();
}
// EP1 initialization structure (both IN and OUT)
/* EP1 initialization structure (both IN and OUT) */
static const USBEndpointConfig ep1config = {
USB_EP_MODE_TYPE_INTR, // Interrupt EP
NULL, // SETUP packet notification callback
ep1in_cb, // IN notification callback
ep1out_cb, // OUT notification callback
0x0040, // IN maximum packet size
0x0040, // OUT maximum packet size
&ep1instate, // IN Endpoint state
&ep1outstate, // OUT endpoint state
2, // IN multiplier
NULL // SETUP buffer (not a SETUP endpoint)
USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
NULL, /* SETUP packet notification callback */
ep1in_cb, /* IN notification callback */
ep1out_cb, /* OUT notification callback */
0x0040, /* IN maximum packet size */
0x0040, /* OUT maximum packet size */
&ep1instate, /* IN Endpoint state */
&ep1outstate, /* OUT endpoint state */
2, /* IN multiplier */
NULL /* SETUP buffer (not a SETUP endpoint) */
};
// Handles the USB driver global events
/* Handles the USB driver global events */
static void
usb_event_cb (USBDriver * usbp, usbevent_t event)
{
switch (event)
{
case USB_EVENT_RESET:
return;
case USB_EVENT_ADDRESS:
return;
case USB_EVENT_CONFIGURED:
chSysLockFromISR ();
// Enable the endpoints specified into the configuration.
usbInitEndpointI (usbp, USBD1_IN_EP, &ep1config);
// Start the reception immediately
chIQResetI (&usb_input_queue);
usbPrepareQueuedReceive (&USB_DRIVER, USBD1_OUT_EP, &usb_input_queue,
USB_HID_OUT_REPORT_SIZE);
usbStartReceiveI (&USB_DRIVER, USBD1_OUT_EP);
chSysUnlockFromISR ();
return;
case USB_EVENT_SUSPEND:
return;
case USB_EVENT_WAKEUP:
return;
case USB_EVENT_STALLED:
return;
}
usb_event_cb(USBDriver *usbp, usbevent_t event){
switch(event) {
case USB_EVENT_RESET:
return;
case USB_EVENT_ADDRESS:
return;
case USB_EVENT_CONFIGURED:
chSysLockFromISR();
/* Enable the endpoints specified into the configuration. */
usbInitEndpointI(usbp, USBD1_IN_EP, &ep1config);
/* Start the reception immediately */
chIQResetI(&usb_input_queue);
usbPrepareQueuedReceive(&USB_DRIVER, USBD1_OUT_EP, &usb_input_queue,
USB_HID_OUT_REPORT_SIZE);
usbStartReceiveI(&USB_DRIVER, USBD1_OUT_EP);
chSysUnlockFromISR();
return;
case USB_EVENT_SUSPEND:
return;
case USB_EVENT_WAKEUP:
return;
case USB_EVENT_STALLED:
return;
}
}
// Function used locally in os/hal/src/usb.c for getting descriptors
// need it here for HID descriptor
/* Function used locally in os/hal/src/usb.c for getting descriptors */
/* need it here for HID descriptor */
static uint16_t get_hword(uint8_t *p) {
uint16_t hw;
hw = (uint16_t)*p++;
hw = (uint16_t)*p++;
hw |= (uint16_t)*p << 8U;
return hw;
}
// Callback for SETUP request on the endpoint 0 (control)
/* Callback for SETUP request on the endpoint 0 (control) */
static bool
usb_request_hook_cb (USBDriver * usbp)
{
usb_request_hook_cb(USBDriver *usbp){
const USBDescriptor *dp;
// Handle HID class specific requests
// Only GetReport is mandatory for HID devices
if ((usbp->setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS)
{
if (usbp->setup[1] == HID_GET_REPORT)
{
/* setup[3] (MSB of wValue) = Report ID (must be 0 as we
* have declared only one IN report)
* setup[2] (LSB of wValue) = Report Type (1 = Input, 3 = Feature)
*/
if ((usbp->setup[3] == 0) && (usbp->setup[2] == 1))
{
struct usb_hid_in_report_s in_report;
usb_build_in_report (&in_report);
usbSetupTransfer (usbp, (uint8_t *) & in_report,
USB_HID_IN_REPORT_SIZE, NULL);
}
}
if (usbp->setup[1] == HID_SET_REPORT)
{
// Not implemented (yet)
}
/* Handle HID class specific requests */
/* Only GetReport is mandatory for HID devices */
if((usbp->setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS) {
if(usbp->setup[1] == HID_GET_REPORT) {
/* setup[3] (MSB of wValue) = Report ID (must be 0 as we
* have declared only one IN report)
* setup[2] (LSB of wValue) = Report Type (1 = Input, 3 = Feature)
*/
if((usbp->setup[3] == 0) && (usbp->setup[2] == 1)) {
struct usb_hid_in_report_s in_report;
usb_build_in_report(&in_report);
usbSetupTransfer(usbp, (uint8_t *)&in_report,
USB_HID_IN_REPORT_SIZE, NULL);
}
}
// Handle the Get_Descriptor Request for HID class (not handled by the default hook)
if ((usbp->setup[0] == 0x81) && (usbp->setup[1] == USB_REQ_GET_DESCRIPTOR))
{
dp =
usbp->config->get_descriptor_cb (usbp, usbp->setup[3], usbp->setup[2],
get_hword(&usbp->setup[4]));
if (dp == NULL)
return FALSE;
usbSetupTransfer (usbp, (uint8_t *) dp->ud_string, dp->ud_size, NULL);
return TRUE;
if(usbp->setup[1] == HID_SET_REPORT) {
/* Not implemented (yet) */
}
}
/* Handle the Get_Descriptor Request for HID class (not handled by the default hook) */
if((usbp->setup[0] == 0x81) && (usbp->setup[1] == USB_REQ_GET_DESCRIPTOR)) {
dp =
usbp->config->get_descriptor_cb(usbp, usbp->setup[3], usbp->setup[2],
get_hword(&usbp->setup[4]));
if(dp == NULL)
return FALSE;
usbSetupTransfer(usbp, (uint8_t *)dp->ud_string, dp->ud_size, NULL);
return TRUE;
}
return FALSE;
}
// USB driver configuration
/* USB driver configuration */
static const USBConfig usbcfg = {
usb_event_cb, // USB events callback
usb_get_descriptor_cb, // Device GET_DESCRIPTOR request callback
usb_request_hook_cb, // Requests hook callback
NULL // Start Of Frame callback
usb_event_cb, /* USB events callback */
usb_get_descriptor_cb, /* Device GET_DESCRIPTOR request callback */
usb_request_hook_cb, /* Requests hook callback */
NULL /* Start Of Frame callback */
};
/*
@ -452,22 +453,20 @@ static const USBConfig usbcfg = {
* report
*/
static void
usb_input_queue_inotify (io_queue_t * qp)
{
usb_input_queue_inotify(io_queue_t *qp){
(void)qp;