Added USB Serial interface and HID Lighting stubs
parent
61c912cec6
commit
9818707c06
@ -1,20 +1,132 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#include "usbcfg.h"
|
||||
|
||||
/*
|
||||
* HID report sizes (data only, excluding the report ID byte prepended by the
|
||||
* USB host). These match the LampArray HID descriptor in usbcfg.c.
|
||||
*/
|
||||
#define RPT1_LEN 22 /* LampArrayAttributesReport */
|
||||
#define RPT3_LEN 28 /* LampAttributesResponseReport */
|
||||
#define RPT6_LEN 1 /* LampArrayControlReport */
|
||||
|
||||
/*
|
||||
* Called from ISR context — fill buf with the response for report `id`.
|
||||
* buf[0] must be set to the report ID; *len must be set to the total length.
|
||||
* Return false to stall (unknown ID).
|
||||
*/
|
||||
bool isr_hid_get_report(uint8_t id, uint8_t *buf, size_t *len) {
|
||||
switch (id) {
|
||||
case 1: /* LampArrayAttributesReport */
|
||||
*len = 1 + RPT1_LEN;
|
||||
memset(buf, 0, *len);
|
||||
buf[0] = 1;
|
||||
/* LampCount, BoundingBox*, LampArrayKind, MinUpdateInterval all zero */
|
||||
return true;
|
||||
|
||||
case 3: /* LampAttributesResponseReport */
|
||||
*len = 1 + RPT3_LEN;
|
||||
memset(buf, 0, *len);
|
||||
buf[0] = 3;
|
||||
/* All lamp attribute fields zero until real lamp state is added */
|
||||
return true;
|
||||
|
||||
case 6: /* LampArrayControlReport */
|
||||
*len = 1 + RPT6_LEN;
|
||||
buf[0] = 6;
|
||||
buf[1] = 0; /* AutonomousMode = 0 (host-controlled) */
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from ISR context — process an incoming SET_REPORT payload.
|
||||
* buf[0] is the report ID; len includes that byte.
|
||||
*/
|
||||
void isr_hid_set_report(uint8_t id, const uint8_t *buf, size_t len) {
|
||||
(void)buf;
|
||||
(void)len;
|
||||
switch (id) {
|
||||
case 2: /* LampAttributesRequestReport — which lamp to query next */
|
||||
break;
|
||||
case 4: /* LampMultiUpdateReport — set up to 8 lamps */
|
||||
break;
|
||||
case 5: /* LampRangeUpdateReport — set a range of lamps */
|
||||
break;
|
||||
case 6: /* LampArrayControlReport — autonomous mode flag */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define SERIAL_LINE_BUF 128
|
||||
|
||||
static THD_WORKING_AREA(waSerial, 512);
|
||||
static THD_FUNCTION(SerialThread, arg) {
|
||||
(void)arg;
|
||||
chRegSetThreadName("serial");
|
||||
|
||||
char buf[SERIAL_LINE_BUF];
|
||||
int len;
|
||||
|
||||
while (true) {
|
||||
while (SDU1.config->usbp->state != USB_ACTIVE || !cdc_dtr)
|
||||
chThdSleepMilliseconds(100);
|
||||
|
||||
len = 0;
|
||||
chnWrite((BaseChannel *)&SDU1, (uint8_t *)"> ", 2);
|
||||
|
||||
while (SDU1.config->usbp->state == USB_ACTIVE && cdc_dtr) {
|
||||
msg_t c = chnGetTimeout((BaseChannel *)&SDU1, TIME_MS2I(100));
|
||||
if (c < MSG_OK)
|
||||
continue;
|
||||
|
||||
uint8_t ch = (uint8_t)c;
|
||||
|
||||
if (ch == '\r' || ch == '\n') {
|
||||
chnWrite((BaseChannel *)&SDU1, (uint8_t *)"\r\n", 2);
|
||||
if (len > 0) {
|
||||
chnWrite((BaseChannel *)&SDU1, (uint8_t *)buf, (size_t)len);
|
||||
chnWrite((BaseChannel *)&SDU1, (uint8_t *)"\r\n", 2);
|
||||
len = 0;
|
||||
}
|
||||
chnWrite((BaseChannel *)&SDU1, (uint8_t *)"> ", 2);
|
||||
} else if (ch == 0x08 || ch == 0x7F) { /* backspace / DEL */
|
||||
if (len > 0) {
|
||||
len--;
|
||||
chnWrite((BaseChannel *)&SDU1, (uint8_t *)"\b \b", 3);
|
||||
}
|
||||
} else if (ch >= 0x20 && ch < 0x7F) { /* printable ASCII */
|
||||
if (len < SERIAL_LINE_BUF - 1) {
|
||||
buf[len++] = (char)ch;
|
||||
chnWrite((BaseChannel *)&SDU1, &ch, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
halInit();
|
||||
chSysInit();
|
||||
|
||||
sduObjectInit(&SDU1);
|
||||
sduStart(&SDU1, &serusbcfg);
|
||||
|
||||
usbDisconnectBus(&USBD1);
|
||||
chThdSleepMilliseconds(1500);
|
||||
usbStart(&USBD1, &usbcfg);
|
||||
usbConnectBus(&USBD1);
|
||||
|
||||
while(true) {
|
||||
chThdSleepMilliseconds(1000);
|
||||
}
|
||||
chThdCreateStatic(waSerial, sizeof(waSerial), NORMALPRIO, SerialThread, NULL);
|
||||
|
||||
chThdSleep(TIME_INFINITE);
|
||||
}
|
||||
|
||||
@ -1,24 +1,16 @@
|
||||
/*
|
||||
ChibiOS - Copyright (C) 2006..2018 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.
|
||||
*/
|
||||
|
||||
#ifndef USBCFG_H
|
||||
#define USBCFG_H
|
||||
|
||||
extern const USBConfig usbcfg;
|
||||
extern const SerialUSBConfig serusbcfg;
|
||||
extern SerialUSBDriver SDU1;
|
||||
extern volatile bool cdc_dtr;
|
||||
|
||||
/* Called from ISR context to fill a GET_REPORT response.
|
||||
Returns false to stall the request (unknown report id). */
|
||||
bool isr_hid_get_report(uint8_t id, uint8_t *buf, size_t *len);
|
||||
|
||||
#endif /* USBCFG_H */
|
||||
/* Called from ISR context when a SET_REPORT payload has arrived. */
|
||||
void isr_hid_set_report(uint8_t id, const uint8_t *buf, size_t len);
|
||||
|
||||
/** @} */
|
||||
#endif /* USBCFG_H */
|
||||
|
||||
Loading…
Reference in New Issue