Skip to content

USB Device improvements and stability fixes #27

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Oct 12, 2015
Prev Previous commit
Next Next commit
Update for host and Device USB
  • Loading branch information
jcbuda authored and cmaglie committed Sep 9, 2015
commit fe4d51f851eb15701a41249da99eb020026bef64
60 changes: 19 additions & 41 deletions cores/arduino/USB/USBCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ USBDevice_SAMD21G18x usbd;
static char isRemoteWakeUpEnabled = 0;
static char isEndpointHalt = 0;

extern void (*gpf_isr)(void);

// USB_Handler ISR
extern "C" void UDD_Handler(void) {
USBDevice.ISRHandler();
}



const uint16_t STRING_LANGUAGE[2] = {
(3<<8) | (2+2),
0x0409 // English
Expand Down Expand Up @@ -285,6 +294,8 @@ void USBDeviceClass::init()
while (GCLK->STATUS.bit.SYNCBUSY)
;

UHD_SetStack(&UDD_Handler);

// Reset USB Device
usbd.reset();

Expand Down Expand Up @@ -388,9 +399,6 @@ void USBDeviceClass::initEP(uint32_t ep, uint32_t config)
// Release OUT EP
usbd.epBank0SetMultiPacketSize(ep, 64);
usbd.epBank0SetByteCount(ep, 0);

// The RAM Buffer is empty: we can receive data
//usbd.epBank0ResetReady(ep);
}
else if (config == (USB_ENDPOINT_TYPE_BULK | USB_ENDPOINT_IN(0)))
{
Expand All @@ -405,12 +413,12 @@ void USBDeviceClass::initEP(uint32_t ep, uint32_t config)
else if (config == USB_ENDPOINT_TYPE_CONTROL)
{
// XXX: Needed?
usbd.epBank0DisableAutoZLP(ep);
usbd.epBank1DisableAutoZLP(ep);
// usbd.epBank0DisableAutoZLP(ep);
// usbd.epBank1DisableAutoZLP(ep);

// Setup Control OUT
usbd.epBank0SetSize(ep, 64);
usbd.epBank0SetAddress(ep, &udd_ep_out_cache_buffer[0]);
usbd.epBank0SetAddress(ep, &udd_ep_out_cache_buffer[ep]);
usbd.epBank0SetType(ep, 1); // CONTROL OUT / SETUP

// Setup Control IN
Expand All @@ -424,8 +432,6 @@ void USBDeviceClass::initEP(uint32_t ep, uint32_t config)

// NAK on endpoint OUT, the bank is full.
usbd.epBank0SetReady(ep);
// NAK on endpoint IN, the bank is not yet filled in.
//usbd.epBank1ResetReady(ep);
}
}

Expand Down Expand Up @@ -461,7 +467,6 @@ bool USBDeviceClass::connected()
uint32_t USBDeviceClass::recvControl(void *_data, uint32_t len)
{
uint8_t *data = reinterpret_cast<uint8_t *>(_data);
// NO RXOUT ???????

// The RAM Buffer is empty: we can receive data
usbd.epBank0ResetReady(0);
Expand Down Expand Up @@ -499,17 +504,8 @@ uint32_t USBDeviceClass::recv(uint32_t ep, void *_data, uint32_t len)

usbd.epBank0DisableTransferComplete(ep);

// NAK on endpoint OUT, the bank is full.
//usbd.epBank0SetReady(CDC_ENDPOINT_OUT);

memcpy(_data, udd_ep_out_cache_buffer[ep], len);

// uint8_t *buffer = udd_ep_out_cache_buffer[ep];
// uint8_t *data = reinterpret_cast<uint8_t *>(_data);
// for (uint32_t i=0; i<len; i++) {
// data[i] = buffer[i];
// }

// release empty buffer
if (len && !available(ep)) {
// The RAM Buffer is empty: we can receive data
Expand Down Expand Up @@ -539,40 +535,23 @@ uint8_t USBDeviceClass::armRecvCtrlOUT(uint32_t ep, uint32_t len)
usbd.epBank0SetAddress(ep, &udd_ep_out_cache_buffer[ep]);
usbd.epBank0SetMultiPacketSize(ep, 8);
usbd.epBank0SetByteCount(ep, 0);
//usbd.epBank0ResetReady(0);
//while (!usbd.epBank0IsTransferComplete(ep)) {}
//while (usbd.epBank0IsReady(ep)) {}

//usbd.epBank0SetByteCount(0, 0);
//usbd.epBank0SetMultiPacketSize(0, 8);
usbd.epBank0ResetReady(ep);

// Wait OUT
while (!usbd.epBank0IsReady(ep)) {}
while (!usbd.epBank0IsTransferComplete(ep)) {} // XXX: while(USB->DEVICE.DeviceEndpoint[ep].EPINTFLAG.bit.TRCPT == 0);
while (!usbd.epBank0IsTransferComplete(ep)) {}
return usbd.epBank0ByteCount(ep);
}

uint8_t USBDeviceClass::armRecv(uint32_t ep, uint32_t len)
{
//usbd.epBank0SetSize(ep, 64);
//usbd.epBank0SetAddress(ep, &udd_ep_out_cache_buffer[ep]);
//usbd.epBank0SetMultiPacketSize(ep, 64); // XXX: Should be "len"?
uint16_t count = usbd.epBank0ByteCount(ep);
if (count >= 64) {
usbd.epBank0SetByteCount(ep, count - 64);
} else {
usbd.epBank0SetByteCount(ep, 0);
}
// The RAM Buffer is empty: we can receive data
//usbd.epBank0ResetReady(ep);

// Wait for transfer to complete
//while (!usbd.epBank0IsTransferComplete(ep)) {}
//while (usbd.epBank0IsReady(ep)) {}
// NAK on endpoint OUT, the bank is full.
//usbd.epBank0ResetReady(ep);

return usbd.epBank0ByteCount(ep);
}

Expand Down Expand Up @@ -837,8 +816,7 @@ void USBDeviceClass::ISRHandler()
stall(0);
}

// XXX: Should be really cleared?
if (usbd.epBank1IsStalled(0)) // XXX:(USB->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.STALL)
if (usbd.epBank1IsStalled(0))
{
usbd.epBank1AckStalled(0);

Expand Down Expand Up @@ -878,6 +856,6 @@ void USBDeviceClass::ISRHandler()
USBDeviceClass USBDevice;

// USB_Handler ISR
extern "C" void USB_Handler(void) {
USBDevice.ISRHandler();
}
// extern "C" void USB_Handler(void) {
// USBDevice.ISRHandler();
// }
30 changes: 30 additions & 0 deletions cores/arduino/USB/USB_interrupt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
Copyright (c) 2014 Arduino LLC. All right reserved.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

void (*gpf_isr)(void) = (0UL);

void USB_Handler( void )
{
if (gpf_isr)
gpf_isr();
}

void UHD_SetStack(void (*pf_isr)(void))
{
gpf_isr = pf_isr;
}
16 changes: 9 additions & 7 deletions cores/arduino/USB/samd21_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,13 @@
//#define TRACE_UOTGHS_HOST(x) x
#define TRACE_UOTGHS_HOST(x)

//extern void (*gpf_isr)(void);

// Handle UOTGHS Host driver state
static uhd_vbus_state_t uhd_state = UHD_STATE_NO_VBUS;

__attribute__((__aligned__(4))) volatile UsbHostDescriptor usb_pipe_table[USB_EPT_NUM];

extern void (*gpf_isr)(void);

void UHD_SetStack(void (*pf_isr)(void))
{
gpf_isr = pf_isr;
}

// NVM Software Calibration Area Mapping
// USB TRANSN calibration value. Should be written to the USB PADCAL register.
Expand Down Expand Up @@ -180,7 +174,6 @@ void UHD_Init(void)
/**
* \brief Interrupt sub routine for USB Host state machine management.
*/
//static void UHD_ISR(void)
void UHD_Handler(void)
{
uint16_t flags;
Expand Down Expand Up @@ -518,4 +511,13 @@ uint32_t UHD_Pipe_Is_Transfer_Complete(uint32_t ul_pipe, uint32_t ul_token_type)

return 0;
}




// USB_Handler ISR
// void USB_Handler(void) {
// UHD_Handler();
// }

#endif // HOST_DEFINED
4 changes: 2 additions & 2 deletions libraries/USBHost/src/Usb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ e-mail : support@circuitsathome.com
#include "Usb.h"


#ifdef ARDUINO_SAMD_ZERO
//#ifdef ARDUINO_SAMD_ZERO

static uint32_t usb_error = 0;
static uint32_t usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE;
Expand Down Expand Up @@ -854,4 +854,4 @@ uint32_t USBHost::setConf(uint32_t addr, uint32_t ep, uint32_t conf_value) {
return ( ctrlReq(addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL));
}

#endif //ARDUINO_SAMD_ZERO
//#endif //ARDUINO_SAMD_ZERO