6 #include "UsbDevice.hpp"
7 #include "LibEndian.hpp"
8 #include "UsbMacros.hpp"
11 UsbHw* UsbDevice::sUsbHw;
14 uint8_t UsbDevice::sAddress;
15 UsbDevice::STATUS UsbDevice::sStatus;
16 size_t UsbDevice::sEp0DataInLen;
17 const uint8_t* UsbDevice::sEp0DataInBuffer;
18 bool UsbDevice::sIsReady =
false;
19 UsbDefs::PKT UsbDevice::sPkt;
20 UsbInCallback* UsbDevice::sInCallback[USB_CFG_MAX_EPN] = { 0 };
21 UsbOutCallback* UsbDevice::sOutCallback[USB_CFG_MAX_EPN] = { 0 };
23 void UsbDevice::init(
Rtos::PRIORITY priority,
size_t stackSize, UsbHw* usbHw) {
24 sTask =
new RtosTask(priority,
"USB", stackSize, run);
29 bool UsbDevice::isReady() {
33 void UsbDevice::notifyDataInReadyForEp(uint8_t ep) {
35 int len = sUsbHw->getEpInFree(ep);
37 if (sInCallback[ep]) {
38 sInCallback[ep]->onDataInFree(ep, len);
44 int UsbDevice::writeBuffer(uint8_t ep,
const uint8_t* buffer,
int len) {
45 return sUsbHw->writeEp(ep, buffer, len);
48 void UsbDevice::registerInCallback(uint8_t ep, UsbInCallback* cb) {
49 USB_ASSERT(ep < USB_CFG_MAX_EPN);
53 void UsbDevice::registerOutCallback(uint8_t ep, UsbOutCallback* cb) {
54 USB_ASSERT(ep < USB_CFG_MAX_EPN);
55 sOutCallback[ep] = cb;
64 sUsbHw->processEvents();
70 void UsbDevice::processEp0Setup(UsbDefs::PKT* pkt) {
71 UsbDefs::USB_SETUP_PACKET* setup = (UsbDefs::USB_SETUP_PACKET*) pkt->data.bytes;
72 setup->wValue = LibEndian::leToHw(setup->wValue);
73 setup->wIndex = LibEndian::leToHw(setup->wIndex);
74 setup->wLength = LibEndian::leToHw(setup->wLength);
77 switch (setup->bmRequestType.bits.type) {
78 case UsbDefs::TYPE_STANDARD:
79 switch (setup->bmRequestType.bits.recipient) {
80 case UsbDefs::RECIPIENT_DEVICE:
81 switch (setup->bRequest) {
82 case UsbDefs::REQ_CODE_GET_STATUS:
83 sUsbHw->writeEp(0, (uint8_t*) &sStatus.value,
sizeof(sStatus.value));
85 case UsbDefs::REQ_CODE_CLEAR_FEATURE:
88 case UsbDefs::REQ_CODE_SET_FEATURE:
91 case UsbDefs::REQ_CODE_SET_ADDR:
92 sAddress = (setup->wValue & 0xFF) | 0x80;
93 sUsbHw->writeEp(0, 0, 0);
95 case UsbDefs::REQ_CODE_GET_DESC:
96 reqGetDeviceDescriptor((UsbDefs::DESC_TYPE) (setup->wValue >> 8), (setup->wValue & 0xFF), setup->wIndex, setup->wLength);
98 case UsbDefs::REQ_CODE_SET_DESC:
101 case UsbDefs::REQ_CODE_GET_CONFIG:
104 case UsbDefs::REQ_CODE_SET_CONFIG:
105 reqSetConfig(setup->wValue & 0xFF);
111 case UsbDefs::RECIPIENT_INTERFACE:
112 switch (setup->bRequest) {
113 case UsbDefs::REQ_CODE_GET_STATUS:
116 case UsbDefs::REQ_CODE_CLEAR_FEATURE:
119 case UsbDefs::REQ_CODE_SET_FEATURE:
122 case UsbDefs::REQ_CODE_GET_INTERFACE:
125 case UsbDefs::REQ_CODE_SET_INTERFACE:
132 case UsbDefs::RECIPIENT_ENDPOINT:
133 switch (setup->bRequest) {
134 case UsbDefs::REQ_CODE_GET_STATUS:
137 case UsbDefs::REQ_CODE_CLEAR_FEATURE:
140 case UsbDefs::REQ_CODE_SET_FEATURE:
143 case UsbDefs::REQ_CODE_SYNCH_FRAME:
151 case UsbDefs::TYPE_CLASS:
153 case UsbDefs::TYPE_VENDOR:
159 void UsbDevice::processEp0DataOut(UsbDefs::PKT* pkt) {
163 const uint8_t* UsbDevice::findInsideDescriptor(UsbDefs::DESC_TYPE descType, uint8_t index) {
164 const uint8_t* parser = sDescriptor;
165 uint8_t currentIndex = 0;
171 if (parser[1] == descType) {
172 if (currentIndex == index) {
182 bool UsbDevice::reqGetDeviceDescriptor(UsbDefs::DESC_TYPE descType, uint8_t index, uint16_t lang, uint16_t len) {
183 sEp0DataInBuffer = findInsideDescriptor(descType, index);
184 if (!sEp0DataInBuffer) {
188 case UsbDefs::DESC_TYPE_CONFIG: {
189 UsbDefs::USB_DESC_CONFIG* config = (UsbDefs::USB_DESC_CONFIG*) sEp0DataInBuffer;
190 if (len > config->wTotalLength) {
191 len = config->wTotalLength;
195 case UsbDefs::DESC_TYPE_DEVICE:
196 case UsbDefs::DESC_TYPE_STRING:
197 case UsbDefs::DESC_TYPE_INTERFACE:
198 case UsbDefs::DESC_TYPE_ENDPOINT:
199 case UsbDefs::DESC_TYPE_DEVICE_QUALIFIER:
200 case UsbDefs::DESC_TYPE_OTHER_SPEED_CONF:
201 case UsbDefs::DESC_TYPE_INTERFACE_POWER:
202 if (len > sEp0DataInBuffer[0]) {
203 len = sEp0DataInBuffer[0];
208 len = sUsbHw->writeEp(0, sEp0DataInBuffer, sEp0DataInLen);
209 sEp0DataInLen -= len;
210 sEp0DataInBuffer += len;
215 bool UsbDevice::reqSetConfig(uint16_t index) {
216 const UsbDefs::USB_DESC_CONFIG* config = (
const UsbDefs::USB_DESC_CONFIG*) findInsideDescriptor(UsbDefs::DESC_TYPE_CONFIG, index - 1);
220 sUsbHw->epResetAll();
222 if (config->bmAttributes & UsbDefs::DESC_CONFIG_ATTR_SELF_POWERED) {
223 sStatus.bits.selfPowered = 1;
225 if (config->bmAttributes & UsbDefs::DESC_CONFIG_ATTR_REMOTE_WAKEUP) {
226 sStatus.bits.remoteWakeup = 1;
229 const uint8_t* parser = (
const uint8_t*) config;
234 if (parser[1] == UsbDefs::DESC_TYPE_ENDPOINT) {
235 sUsbHw->epConfig((
const UsbDefs::USB_DESC_EP*) parser);
239 sUsbHw->writeEp(0, 0, 0);
243 void UsbDevice::onDataIn(uint8_t ep, uint16_t len) {
245 if (sAddress & 0x80) {
246 sAddress = sAddress & 0x7F;
247 sUsbHw->setAddress(sAddress);
249 if (sEp0DataInLen > 0) {
250 sEp0DataInLen -= sUsbHw->writeEp(0, sEp0DataInBuffer, sEp0DataInLen);
253 len = sUsbHw->getEpInFree(ep);
255 if (sInCallback[ep]) {
256 sInCallback[ep]->onDataInFree(ep, len);
261 void UsbDevice::onDataOut(uint8_t ep,
bool isSetup, uint16_t len) {
262 USB_ASSERT(len <= UsbDefs::MAX_PACKET_SIZE)
265 sPkt.header.epn = ep;
266 sPkt.header.len = len;
267 sPkt.header.isSetup = isSetup;
268 sUsbHw->readEp(ep, sPkt.data.bytes, len);
271 processEp0Setup(&sPkt);
274 processEp0DataOut(&sPkt);
277 if (sOutCallback[ep]) {
278 sOutCallback[ep]->onDataOut(&sPkt);
282 void UsbDevice::onReset() {
286 bool UsbDevice::onEventInterrupt() {
287 return sSemaEvent.giveFromInt();