efm8 usb bridge working
This commit is contained in:
@@ -6,9 +6,9 @@
|
||||
|
||||
#include "si_toolchain.h"
|
||||
#include "efm8_usb.h"
|
||||
#include "assert.h"
|
||||
//#include "assert.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define SLAB_ASSERT(x)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Global Variables
|
||||
|
||||
@@ -65,8 +65,8 @@ void USBD_AbortAllTransfers(void)
|
||||
|
||||
int8_t USBD_AbortTransfer(uint8_t epAddr)
|
||||
{
|
||||
SI_VARIABLE_SEGMENT_POINTER(ep, USBD_Ep_TypeDef, MEM_MODEL_SEG);
|
||||
int8_t retVal = USB_STATUS_OK;
|
||||
USBD_Ep_TypeDef MEM_MODEL_SEG *ep;
|
||||
uint8_t retVal = USB_STATUS_OK;
|
||||
bool usbIntsEnabled;
|
||||
|
||||
USB_SaveSfrPage();
|
||||
@@ -150,7 +150,7 @@ void USBD_Disconnect(void)
|
||||
|
||||
bool USBD_EpIsBusy(uint8_t epAddr)
|
||||
{
|
||||
SI_VARIABLE_SEGMENT_POINTER(ep, USBD_Ep_TypeDef, MEM_MODEL_SEG);
|
||||
USBD_Ep_TypeDef MEM_MODEL_SEG *ep;
|
||||
|
||||
// Verify this is a valid endpoint address
|
||||
if (epAddr >= SLAB_USB_NUM_EPS_USED)
|
||||
@@ -174,7 +174,7 @@ USBD_State_TypeDef USBD_GetUsbState(void)
|
||||
return myUsbDevice.state;
|
||||
}
|
||||
|
||||
int8_t USBD_Init(SI_VARIABLE_SEGMENT_POINTER(p, const USBD_Init_TypeDef, SI_SEG_GENERIC))
|
||||
int8_t USBD_Init(const USBD_Init_TypeDef *p)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
@@ -190,12 +190,12 @@ int8_t USBD_Init(SI_VARIABLE_SEGMENT_POINTER(p, const USBD_Init_TypeDef, SI_SEG_
|
||||
// Zero out the myUsbDevice struct, then initialize all non-zero members
|
||||
for (i = 0; i < sizeof(myUsbDevice); i++)
|
||||
{
|
||||
*((SI_VARIABLE_SEGMENT_POINTER(, uint8_t, MEM_MODEL_SEG))&myUsbDevice + i) = 0;
|
||||
*((uint8_t MEM_MODEL_SEG *)&myUsbDevice + i) = 0;
|
||||
}
|
||||
|
||||
// Get the USB descriptors from p
|
||||
myUsbDevice.deviceDescriptor = p->deviceDescriptor;
|
||||
myUsbDevice.configDescriptor = p->configDescriptor;
|
||||
myUsbDevice.configDescriptor = (USB_ConfigurationDescriptor_TypeDef *)p->configDescriptor;
|
||||
myUsbDevice.stringDescriptors = p->stringDescriptors;
|
||||
myUsbDevice.numberOfStrings = p->numberOfStrings;
|
||||
|
||||
@@ -246,12 +246,12 @@ int8_t USBD_Init(SI_VARIABLE_SEGMENT_POINTER(p, const USBD_Init_TypeDef, SI_SEG_
|
||||
}
|
||||
|
||||
int8_t USBD_Read(uint8_t epAddr,
|
||||
SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_GENERIC),
|
||||
uint8_t *dat,
|
||||
uint16_t byteCount,
|
||||
bool callback)
|
||||
{
|
||||
bool usbIntsEnabled;
|
||||
SI_VARIABLE_SEGMENT_POINTER(ep, USBD_Ep_TypeDef, MEM_MODEL_SEG);
|
||||
USBD_Ep_TypeDef MEM_MODEL_SEG *ep;
|
||||
|
||||
USB_SaveSfrPage();
|
||||
|
||||
@@ -432,13 +432,8 @@ void USBD_Stop(void)
|
||||
|
||||
void USBD_Suspend(void)
|
||||
{
|
||||
#if (!(SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_FASTWAKE))
|
||||
uint8_t i;
|
||||
#endif
|
||||
bool regulatorEnabled, prefetchEnabled;
|
||||
#if SLAB_USB_REMOTE_WAKEUP_ENABLED
|
||||
bool remoteWakeup = false;
|
||||
#endif
|
||||
|
||||
USB_SaveSfrPage();
|
||||
|
||||
@@ -494,9 +489,8 @@ void USBD_Suspend(void)
|
||||
// wakeup event occurred. If so, exit USBD_Suspend().
|
||||
if (USB_IsSuspended() == true)
|
||||
{
|
||||
remoteWakeup = USBD_RemoteWakeupCb();
|
||||
if (remoteWakeup == true)
|
||||
{
|
||||
if (USBD_RemoteWakeupCb() == true)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -510,13 +504,8 @@ void USBD_Suspend(void)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ((!(SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF)) || \
|
||||
(SLAB_USB_BUS_POWERED))
|
||||
} while (USB_IsSuspended() == true);
|
||||
#else
|
||||
} while ((USB_IsSuspended() == true) || (USB_IsVbusOn() == false));
|
||||
#endif
|
||||
|
||||
// Restore the internal regulator
|
||||
if (regulatorEnabled == true)
|
||||
{
|
||||
@@ -534,20 +523,6 @@ void USBD_Suspend(void)
|
||||
USB_SetNormalClock();
|
||||
#endif
|
||||
USB_EnableTransceiver();
|
||||
|
||||
#if SLAB_USB_REMOTE_WAKEUP_ENABLED
|
||||
// If the device woke from suspend due to a remote wakeup source, call
|
||||
// USBD_RemoteWakeup() here to wake up the host.
|
||||
if (remoteWakeup == true)
|
||||
{
|
||||
// Wake up the host
|
||||
if (USBD_RemoteWakeup() == USB_STATUS_OK)
|
||||
{
|
||||
// If the remote wakeup succeeded, transition out of USB suspend state
|
||||
USBD_SetUsbState(myUsbDevice.savedState);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
USB_RestoreSfrPage();
|
||||
@@ -624,12 +599,12 @@ int8_t USBD_UnStallEp(uint8_t epAddr)
|
||||
}
|
||||
|
||||
int8_t USBD_Write(uint8_t epAddr,
|
||||
SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_GENERIC),
|
||||
uint8_t *dat,
|
||||
uint16_t byteCount,
|
||||
bool callback)
|
||||
{
|
||||
bool usbIntsEnabled;
|
||||
SI_VARIABLE_SEGMENT_POINTER(ep, USBD_Ep_TypeDef, MEM_MODEL_SEG);
|
||||
USBD_Ep_TypeDef MEM_MODEL_SEG *ep;
|
||||
|
||||
USB_SaveSfrPage();
|
||||
|
||||
|
@@ -22,13 +22,14 @@ static USB_Status_TypeDef SetConfiguration(void);
|
||||
static USB_Status_TypeDef SetFeature(void);
|
||||
static USB_Status_TypeDef SetInterface(void);
|
||||
static void USBD_ActivateAllEps(bool forceIdle);
|
||||
static void EP0_Write(SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_GENERIC), uint16_t numBytes);
|
||||
static void EP0_Write(uint8_t *dat, uint16_t numBytes);
|
||||
void SendEp0Stall(void);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Global Variables
|
||||
|
||||
extern SI_SEGMENT_VARIABLE(myUsbDevice, USBD_Device_TypeDef, MEM_MODEL_SEG);
|
||||
const SI_SEGMENT_VARIABLE(txZero[2], uint8_t, SI_SEG_CODE);
|
||||
SI_SEGMENT_VARIABLE(txZero[2], uint8_t, SI_SEG_CODE);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Static Global Variables
|
||||
@@ -91,6 +92,15 @@ USB_Status_TypeDef USBDCH9_SetupCmd(void)
|
||||
break;
|
||||
}
|
||||
|
||||
// Reset index to 0 in case one of the above commands modified it
|
||||
USB_SetIndex(0);
|
||||
|
||||
// If the command resulted in an error, send a procedural stall
|
||||
if (status == USB_STATUS_REQ_ERR)
|
||||
{
|
||||
SendEp0Stall();
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -228,7 +238,7 @@ static USB_Status_TypeDef GetConfiguration(void)
|
||||
{
|
||||
if (myUsbDevice.state == USBD_STATE_ADDRESSED)
|
||||
{
|
||||
EP0_Write((SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))txZero, 1);
|
||||
EP0_Write(txZero, 1);
|
||||
retVal = USB_STATUS_OK;
|
||||
}
|
||||
else if (myUsbDevice.state == USBD_STATE_CONFIGURED)
|
||||
@@ -257,7 +267,7 @@ static USB_Status_TypeDef GetDescriptor(void)
|
||||
|
||||
uint8_t index;
|
||||
uint16_t length = 0;
|
||||
SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_GENERIC);
|
||||
uint8_t *dat;
|
||||
USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;
|
||||
|
||||
if (*((uint8_t *)&myUsbDevice.setup.bmRequestType) ==
|
||||
@@ -272,7 +282,7 @@ static USB_Status_TypeDef GetDescriptor(void)
|
||||
{
|
||||
break;
|
||||
}
|
||||
dat = (SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))myUsbDevice.deviceDescriptor;
|
||||
dat = (uint8_t *)myUsbDevice.deviceDescriptor;
|
||||
length = myUsbDevice.deviceDescriptor->bLength;
|
||||
break;
|
||||
|
||||
@@ -281,14 +291,14 @@ static USB_Status_TypeDef GetDescriptor(void)
|
||||
{
|
||||
break;
|
||||
}
|
||||
dat = (SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))myUsbDevice.configDescriptor;
|
||||
dat = (uint8_t *)myUsbDevice.configDescriptor;
|
||||
length = le16toh(myUsbDevice.configDescriptor->wTotalLength);
|
||||
break;
|
||||
|
||||
case USB_STRING_DESCRIPTOR:
|
||||
#if (SLAB_USB_NUM_LANGUAGES == 1)
|
||||
|
||||
dat = (SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))myUsbDevice.stringDescriptors[index];
|
||||
dat = (uint8_t *)myUsbDevice.stringDescriptors[index];
|
||||
|
||||
// Index 0 is the language string. If SLAB_USB_NUM_LANGUAGES == 1, we
|
||||
// know the length will be 4 and the format will be UTF16LE.
|
||||
@@ -317,7 +327,7 @@ static USB_Status_TypeDef GetDescriptor(void)
|
||||
// Index 0 is the language.
|
||||
if (index == 0)
|
||||
{
|
||||
dat = ((SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))myUsbDevice.stringDescriptors->languageArray[0][index]);
|
||||
dat = ((uint8_t *)myUsbDevice.stringDescriptors->languageArray[0][index]);
|
||||
length = *((uint8_t *)dat);
|
||||
myUsbDevice.ep0String.encoding.type = USB_STRING_DESCRIPTOR_UTF16LE;
|
||||
}
|
||||
@@ -335,7 +345,7 @@ static USB_Status_TypeDef GetDescriptor(void)
|
||||
}
|
||||
if ((langSupported == true) && (index < myUsbDevice.numberOfStrings))
|
||||
{
|
||||
dat = ((SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))myUsbDevice.stringDescriptors->languageArray[lang][index]);
|
||||
dat = ((uint8_t *)myUsbDevice.stringDescriptors->languageArray[lang][index]);
|
||||
length = *(dat + USB_STRING_DESCRIPTOR_LENGTH);
|
||||
myUsbDevice.ep0String.encoding.type = *(dat + USB_STRING_DESCRIPTOR_ENCODING);
|
||||
dat += USB_STRING_DESCRIPTOR_LENGTH;
|
||||
@@ -393,10 +403,10 @@ static USB_Status_TypeDef GetInterface(void)
|
||||
{
|
||||
#if (SLAB_USB_SUPPORT_ALT_INTERFACES)
|
||||
// Return the alternate setting for the specified interface
|
||||
EP0_Write((SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))&myUsbDevice.interfaceAltSetting[interface], 1);
|
||||
EP0_Write(&myUsbDevice.interfaceAltSetting[interface], 1);
|
||||
#else
|
||||
// Alternate interfaces are not supported, so return 0x0000.
|
||||
EP0_Write((SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))&txZero, 1);
|
||||
EP0_Write(&txZero, 1);
|
||||
#endif
|
||||
retVal = USB_STATUS_OK;
|
||||
}
|
||||
@@ -531,7 +541,7 @@ static USB_Status_TypeDef GetStatus(void)
|
||||
// If the command was valid, send the requested status.
|
||||
if (retVal == USB_STATUS_OK)
|
||||
{
|
||||
EP0_Write((SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))&pStatus, 2);
|
||||
EP0_Write((uint8_t *)&pStatus, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -858,11 +868,11 @@ static void USBD_ActivateAllEps(bool forceIdle)
|
||||
* @param numBytes
|
||||
* Number of bytes to transmit on Endpoint 0
|
||||
******************************************************************************/
|
||||
static void EP0_Write(SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_GENERIC), uint16_t numBytes)
|
||||
static void EP0_Write(uint8_t *dat, uint16_t numBytes)
|
||||
{
|
||||
if (myUsbDevice.ep0.state == D_EP_IDLE)
|
||||
{
|
||||
myUsbDevice.ep0.buf = dat;
|
||||
myUsbDevice.ep0.buf = (uint8_t *)dat;
|
||||
myUsbDevice.ep0.remaining = numBytes;
|
||||
myUsbDevice.ep0.state = D_EP_TRANSMITTING;
|
||||
myUsbDevice.ep0.misc.c = 0;
|
||||
|
@@ -40,16 +40,11 @@ static void USB_WriteFIFO_Code(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat
|
||||
|
||||
// -------------------------------
|
||||
// Generic FIFO access functions
|
||||
static void USB_ReadFIFO_Generic(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_GENERIC), uint8_t fifoNum);
|
||||
static void USB_WriteFIFO_Generic(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_GENERIC));
|
||||
static void USB_ReadFIFO_Generic(uint8_t numBytes, uint8_t *dat, uint8_t fifoNum);
|
||||
static void USB_WriteFIFO_Generic(uint8_t numBytes, uint8_t *dat);
|
||||
|
||||
#endif // #ifdef SI_GPTR
|
||||
|
||||
#if (SLAB_USB_EP3OUT_USED && (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_ISOC))
|
||||
static void memclearXdata(SI_VARIABLE_SEGMENT_POINTER(s, uint8_t, SI_SEG_XDATA),
|
||||
uint16_t n);
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Functions
|
||||
|
||||
@@ -67,7 +62,7 @@ static void memclearXdata(SI_VARIABLE_SEGMENT_POINTER(s, uint8_t, SI_SEG_XDATA),
|
||||
// If Isochronous mode is enabled and the max packet size is greater than 255,
|
||||
// break the FIFO reads up into multiple reads of 255 or less bytes.
|
||||
// ----------------------------------------------------------------------------
|
||||
void USB_ReadFIFOIso(uint8_t fifoNum, uint16_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_GENERIC))
|
||||
void USB_ReadFIFOIso(uint8_t fifoNum, uint16_t numBytes, uint8_t *dat)
|
||||
{
|
||||
uint8_t numBytesRead;
|
||||
|
||||
@@ -99,7 +94,7 @@ void USB_ReadFIFOIso(uint8_t fifoNum, uint16_t numBytes, SI_VARIABLE_SEGMENT_POI
|
||||
// If Isochronous mode is enabled and the max packet size is greater than 255,
|
||||
// break the FIFO writes up into multiple writes of 255 or less bytes.
|
||||
// ----------------------------------------------------------------------------
|
||||
void USB_WriteFIFOIso(uint8_t fifoNum, uint16_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_GENERIC))
|
||||
void USB_WriteFIFOIso(uint8_t fifoNum, uint16_t numBytes, uint8_t *dat)
|
||||
{
|
||||
uint8_t numBytesWrite;
|
||||
|
||||
@@ -322,6 +317,7 @@ void handleUsbIn3Int(void)
|
||||
void handleUsbOut1Int(void)
|
||||
{
|
||||
uint8_t count;
|
||||
|
||||
USB_Status_TypeDef status;
|
||||
bool xferComplete = false;
|
||||
|
||||
@@ -361,7 +357,6 @@ void handleUsbOut1Int(void)
|
||||
myUsbDevice.ep1out.state = D_EP_IDLE;
|
||||
xferComplete = true;
|
||||
}
|
||||
|
||||
status = USB_STATUS_OK;
|
||||
USB_EpnClearOutPacketReady();
|
||||
}
|
||||
@@ -371,7 +366,6 @@ void handleUsbOut1Int(void)
|
||||
{
|
||||
myUsbDevice.ep1out.misc.bits.callback = false;
|
||||
}
|
||||
|
||||
USBD_XferCompleteCb(EP1OUT, status, count, myUsbDevice.ep1out.remaining);
|
||||
}
|
||||
}
|
||||
@@ -387,6 +381,7 @@ void handleUsbOut1Int(void)
|
||||
void handleUsbOut2Int(void)
|
||||
{
|
||||
uint8_t count;
|
||||
|
||||
USB_Status_TypeDef status;
|
||||
bool xferComplete = false;
|
||||
|
||||
@@ -451,10 +446,19 @@ void handleUsbOut2Int(void)
|
||||
* @note This function takes no parameters, but it uses the EP3OUT status
|
||||
* variables stored in @ref myUsbDevice.ep3out.
|
||||
******************************************************************************/
|
||||
#if ((SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_BULK) || (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_INTR))
|
||||
void handleUsbOut3Int(void)
|
||||
{
|
||||
#if (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_ISOC)
|
||||
uint16_t nextIdx;
|
||||
#if (SLAB_USB_EP3OUT_MAX_PACKET_SIZE > 255)
|
||||
uint16_t count;
|
||||
#else
|
||||
uint8_t count;
|
||||
#endif // ( SLAB_USB_EP3OUT_MAX_PACKET_SIZE > 255 )
|
||||
#else
|
||||
uint8_t count;
|
||||
#endif // ( SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_ISOC )
|
||||
|
||||
USB_Status_TypeDef status;
|
||||
bool xferComplete = false;
|
||||
|
||||
@@ -474,6 +478,7 @@ void handleUsbOut3Int(void)
|
||||
myUsbDevice.ep3out.misc.bits.outPacketPending = true;
|
||||
status = USB_STATUS_EP_ERROR;
|
||||
}
|
||||
#if ((SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_BULK) || (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_INTR))
|
||||
// Check for overrun of user buffer
|
||||
else if (myUsbDevice.ep3out.remaining < count)
|
||||
{
|
||||
@@ -481,11 +486,12 @@ void handleUsbOut3Int(void)
|
||||
myUsbDevice.ep3out.misc.bits.outPacketPending = true;
|
||||
status = USB_STATUS_EP_RX_BUFFER_OVERRUN;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
#if ((SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_BULK) || (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_INTR))
|
||||
USB_ReadFIFO(3, count, myUsbDevice.ep3out.buf);
|
||||
|
||||
myUsbDevice.ep3out.misc.bits.outPacketPending = false;
|
||||
myUsbDevice.ep3out.remaining -= count;
|
||||
myUsbDevice.ep3out.buf += count;
|
||||
|
||||
@@ -494,7 +500,26 @@ void handleUsbOut3Int(void)
|
||||
myUsbDevice.ep3out.state = D_EP_IDLE;
|
||||
xferComplete = true;
|
||||
}
|
||||
#elif (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_ISOC)
|
||||
nextIdx = count + myUsbDevice.ep3outIsoIdx;
|
||||
|
||||
// In isochronous mode, a circular buffer is used to hold the data
|
||||
// If the next index into the circular buffer passes the end of the
|
||||
// buffer, make two calls to USB_ReadFIFOIso()
|
||||
if (nextIdx > myUsbDevice.ep3out.remaining)
|
||||
{
|
||||
USB_ReadFIFOIso(3, myUsbDevice.ep3out.remaining - myUsbDevice.ep3outIsoIdx, &myUsbDevice.ep3out.buf[myUsbDevice.ep3outIsoIdx]);
|
||||
myUsbDevice.ep3outIsoIdx = nextIdx - myUsbDevice.ep3out.remaining;
|
||||
USB_ReadFIFOIso(3, myUsbDevice.ep3outIsoIdx, myUsbDevice.ep3out.buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
USB_ReadFIFOIso(3, count, &myUsbDevice.ep3out.buf[myUsbDevice.ep3outIsoIdx]);
|
||||
myUsbDevice.ep3outIsoIdx = nextIdx;
|
||||
}
|
||||
#endif // ( ( SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_BULK ) || ( SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_INTR ) )
|
||||
|
||||
myUsbDevice.ep3out.misc.bits.outPacketPending = false;
|
||||
status = USB_STATUS_OK;
|
||||
USB_EpnClearOutPacketReady();
|
||||
}
|
||||
@@ -505,175 +530,18 @@ void handleUsbOut3Int(void)
|
||||
myUsbDevice.ep3out.misc.bits.callback = false;
|
||||
}
|
||||
|
||||
#if ((SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_BULK) || (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_INTR))
|
||||
USBD_XferCompleteCb(EP3OUT, status, count, myUsbDevice.ep3out.remaining);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#elif (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_ISOC)
|
||||
void handleUsbOut3Int(void)
|
||||
{
|
||||
uint16_t nextIdx;
|
||||
uint16_t numZeroBytesFromCb;
|
||||
#if (SLAB_USB_EP3OUT_MAX_PACKET_SIZE > 255)
|
||||
uint16_t count;
|
||||
#else
|
||||
uint8_t count;
|
||||
#endif
|
||||
USB_Status_TypeDef status = USB_STATUS_OK;
|
||||
bool xferComplete = false;
|
||||
|
||||
USB_SetIndex(3);
|
||||
|
||||
if (USB_EpnOutGetSentStall())
|
||||
{
|
||||
USB_EpnOutClearSentStall();
|
||||
}
|
||||
else if (USB_EpnGetOutPacketReady())
|
||||
{
|
||||
count = USB_EpOutGetCount();
|
||||
|
||||
// If USBD_Read() has not been called, return an error
|
||||
if (myUsbDevice.ep3out.state != D_EP_RECEIVING)
|
||||
{
|
||||
myUsbDevice.ep3out.misc.bits.outPacketPending = true;
|
||||
status = USB_STATUS_EP_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
// DATERR bit set (i.e. CRC/bit-stuffing error)
|
||||
if (USB_EpnGetDataError()
|
||||
#ifdef SLAB_USB_ISOC_OUT_MIN_PACKET_SIZE
|
||||
|| (count < SLAB_USB_ISOC_OUT_MIN_PACKET_SIZE)
|
||||
#endif
|
||||
#ifdef SLAB_USB_ISOC_OUT_MAX_PACKET_SIZE
|
||||
|| (count > SLAB_USB_ISOC_OUT_MAX_PACKET_SIZE)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
status = USB_STATUS_DATA_ERROR;
|
||||
}
|
||||
|
||||
#ifdef SLAB_USB_ISOC_OUT_PACKETSIZE_MOD2
|
||||
if ((count % 2) != 0)
|
||||
{
|
||||
status = USB_STATUS_DATA_ERROR;
|
||||
}
|
||||
#elif defined SLAB_USB_ISOC_OUT_PACKETSIZE_MOD4
|
||||
if (( count % 4) != 0)
|
||||
{
|
||||
status = USB_STATUS_DATA_ERROR;
|
||||
}
|
||||
#elif defined SLAB_USB_ISOC_OUT_PACKETSIZE_MOD6
|
||||
if (count % 6) != 0)
|
||||
{
|
||||
status = USB_STATUS_DATA_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (status == USB_STATUS_DATA_ERROR)
|
||||
{
|
||||
count = 0;
|
||||
// Flush FIFO to get rid of bad packet
|
||||
USB_EpnOutFlush();
|
||||
myUsbDevice.ep3out.misc.bits.outPacketPending = false;
|
||||
// Flush clears OPRDY, so no need to call USB_EpnClearOutPacketReady() now
|
||||
}
|
||||
else // No data error
|
||||
{
|
||||
nextIdx = count + myUsbDevice.ep3outIsoIdx;
|
||||
|
||||
// In isochronous mode, a circular buffer is used to hold the data
|
||||
// If the next index into the circular buffer passes the end of the
|
||||
// buffer, make two calls to USB_ReadFIFOIso()
|
||||
if (nextIdx > myUsbDevice.ep3out.remaining)
|
||||
{
|
||||
USB_ReadFIFOIso(3, myUsbDevice.ep3out.remaining - myUsbDevice.ep3outIsoIdx, &myUsbDevice.ep3out.buf[myUsbDevice.ep3outIsoIdx]);
|
||||
myUsbDevice.ep3outIsoIdx = nextIdx - myUsbDevice.ep3out.remaining;
|
||||
USB_ReadFIFOIso(3, myUsbDevice.ep3outIsoIdx, myUsbDevice.ep3out.buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
USB_ReadFIFOIso(3, count, &myUsbDevice.ep3out.buf[myUsbDevice.ep3outIsoIdx]);
|
||||
myUsbDevice.ep3outIsoIdx = nextIdx;
|
||||
}
|
||||
|
||||
myUsbDevice.ep3out.misc.bits.outPacketPending = false;
|
||||
USB_EpnClearOutPacketReady();
|
||||
}
|
||||
}
|
||||
|
||||
if (myUsbDevice.ep3out.misc.bits.callback == true)
|
||||
{
|
||||
if (xferComplete == true)
|
||||
{
|
||||
myUsbDevice.ep3out.misc.bits.callback = false;
|
||||
}
|
||||
|
||||
// In Isochronous mode, the meaning of the USBD_XferCompleteCb parameters changes:
|
||||
// xferred is the number of bytes received in the last packet
|
||||
// remaining is the current index into the circular buffer
|
||||
numZeroBytesFromCb = USBD_XferCompleteCb(EP3OUT, status, count, myUsbDevice.ep3outIsoIdx);
|
||||
|
||||
// If data error occurred, the callback return value specifies how many zero-valued bytes to queue
|
||||
if (numZeroBytesFromCb && (status == USB_STATUS_DATA_ERROR))
|
||||
{
|
||||
uint16_t numZeroBytesToWrite;
|
||||
SI_SEGMENT_VARIABLE_SEGMENT_POINTER(bufPtr,
|
||||
uint8_t,
|
||||
SI_SEG_XDATA,
|
||||
SI_SEG_DATA);
|
||||
|
||||
// Clear status after calling USBD_XferCompleteCb()
|
||||
status = USB_STATUS_OK;
|
||||
|
||||
// Add the specified number of zero-value bytes
|
||||
nextIdx = numZeroBytesFromCb + myUsbDevice.ep3outIsoIdx;
|
||||
|
||||
// Next index is past the end of the buffer (requires two writes)
|
||||
if (nextIdx > myUsbDevice.ep3out.remaining)
|
||||
{
|
||||
// Write up to the end of the buffer
|
||||
numZeroBytesToWrite = myUsbDevice.ep3out.remaining - myUsbDevice.ep3outIsoIdx;
|
||||
bufPtr = &myUsbDevice.ep3out.buf[myUsbDevice.ep3outIsoIdx];
|
||||
memclearXdata(bufPtr, numZeroBytesToWrite);
|
||||
|
||||
// Write the rest, starting at beginning of buffer
|
||||
myUsbDevice.ep3outIsoIdx = nextIdx - myUsbDevice.ep3out.remaining;
|
||||
numZeroBytesToWrite = myUsbDevice.ep3outIsoIdx;
|
||||
bufPtr = &myUsbDevice.ep3out.buf[0];
|
||||
memclearXdata(bufPtr, numZeroBytesToWrite);
|
||||
}
|
||||
// Next index is not past the end of the buffer
|
||||
else
|
||||
{
|
||||
bufPtr = &myUsbDevice.ep3out.buf[myUsbDevice.ep3outIsoIdx];
|
||||
memclearXdata(bufPtr, numZeroBytesFromCb);
|
||||
myUsbDevice.ep3outIsoIdx = nextIdx;
|
||||
}
|
||||
}
|
||||
USBD_XferCompleteCb(EP3OUT, status, count, myUsbDevice.ep3outIsoIdx);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Sets all elements in a contiguous array of XDATA to zero
|
||||
* @param s
|
||||
* Pointer to the block of memory to fill
|
||||
* @param n
|
||||
* Number of bytes to be set to the value
|
||||
******************************************************************************/
|
||||
static void memclearXdata(SI_VARIABLE_SEGMENT_POINTER(s, uint8_t, SI_SEG_XDATA),
|
||||
uint16_t n)
|
||||
{
|
||||
while (n)
|
||||
{
|
||||
*s++ = 0;
|
||||
n--;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #if ((SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_BULK) || (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_INTR))
|
||||
#endif // EP3OUT_USED
|
||||
|
||||
/***************************************************************************//**
|
||||
@@ -685,7 +553,7 @@ static void memclearXdata(SI_VARIABLE_SEGMENT_POINTER(s, uint8_t, SI_SEG_XDATA),
|
||||
* @param dat
|
||||
* Pointer to buffer to hold data read from the FIFO
|
||||
******************************************************************************/
|
||||
void USB_ReadFIFO(uint8_t fifoNum, uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_GENERIC))
|
||||
void USB_ReadFIFO(uint8_t fifoNum, uint8_t numBytes, uint8_t *dat)
|
||||
{
|
||||
if (numBytes > 0)
|
||||
{
|
||||
@@ -699,7 +567,7 @@ void USB_ReadFIFO(uint8_t fifoNum, uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER
|
||||
switch (((SI_GEN_PTR_t *)&dat)->gptr.memtype)
|
||||
{
|
||||
case SI_GPTR_MTYPE_IDATA:
|
||||
USB_ReadFIFO_Idata(numBytes, (SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_IDATA))dat, fifoNum);
|
||||
USB_ReadFIFO_Idata(numBytes, dat, fifoNum);
|
||||
break;
|
||||
|
||||
// For some compilers, IDATA and DATA are treated the same.
|
||||
@@ -712,7 +580,7 @@ void USB_ReadFIFO(uint8_t fifoNum, uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER
|
||||
#endif
|
||||
|
||||
case SI_GPTR_MTYPE_XDATA:
|
||||
USB_ReadFIFO_Xdata(numBytes, (SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_XDATA))dat, fifoNum);
|
||||
USB_ReadFIFO_Xdata(numBytes, dat, fifoNum);
|
||||
break;
|
||||
|
||||
// For some compilers, XDATA and PDATA are treated the same.
|
||||
@@ -750,7 +618,7 @@ void USB_ReadFIFO(uint8_t fifoNum, uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER
|
||||
* If FALSE, the packet will be stored in the FIFO and the
|
||||
* transmission must be started at a later time
|
||||
******************************************************************************/
|
||||
void USB_WriteFIFO(uint8_t fifoNum, uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_GENERIC), bool txPacket)
|
||||
void USB_WriteFIFO(uint8_t fifoNum, uint8_t numBytes, uint8_t *dat, bool txPacket)
|
||||
{
|
||||
USB_EnableWriteFIFO(fifoNum);
|
||||
|
||||
@@ -762,7 +630,7 @@ void USB_WriteFIFO(uint8_t fifoNum, uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTE
|
||||
switch (((SI_GEN_PTR_t *)&dat)->gptr.memtype)
|
||||
{
|
||||
case SI_GPTR_MTYPE_IDATA:
|
||||
USB_WriteFIFO_Idata(numBytes, (SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_IDATA))dat);
|
||||
USB_WriteFIFO_Idata(numBytes, dat);
|
||||
break;
|
||||
|
||||
// For some compilers, IDATA and DATA are treated the same.
|
||||
@@ -775,7 +643,7 @@ void USB_WriteFIFO(uint8_t fifoNum, uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTE
|
||||
#endif
|
||||
|
||||
case SI_GPTR_MTYPE_XDATA:
|
||||
USB_WriteFIFO_Xdata(numBytes, (SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_XDATA))dat);
|
||||
USB_WriteFIFO_Xdata(numBytes, dat);
|
||||
break;
|
||||
|
||||
// For some compilers, XDATA and PDATA are treated the same.
|
||||
@@ -788,7 +656,7 @@ void USB_WriteFIFO(uint8_t fifoNum, uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTE
|
||||
#endif
|
||||
|
||||
case SI_GPTR_MTYPE_CODE:
|
||||
USB_WriteFIFO_Code(numBytes, (SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_CODE))dat);
|
||||
USB_WriteFIFO_Code(numBytes, dat);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -944,10 +812,10 @@ static void USB_ReadFIFO_Data(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat,
|
||||
{
|
||||
while (--numBytes)
|
||||
{
|
||||
USB_GetFIFOByte(dat);
|
||||
USB_GetFIFOByte(*dat);
|
||||
dat++;
|
||||
}
|
||||
USB_GetLastFIFOByte(dat, fifoNum);
|
||||
USB_GetLastFIFOByte(*dat, fifoNum);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
@@ -997,14 +865,14 @@ static void USB_WriteFIFO_Code(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat
|
||||
* @param fifoNum
|
||||
* USB FIFO to read
|
||||
******************************************************************************/
|
||||
static void USB_ReadFIFO_Generic(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_GENERIC), uint8_t fifoNum)
|
||||
static void USB_ReadFIFO_Generic(uint8_t numBytes, uint8_t *dat, uint8_t fifoNum)
|
||||
{
|
||||
while (--numBytes)
|
||||
{
|
||||
USB_GetFIFOByte(dat);
|
||||
USB_GetFIFOByte(*dat);
|
||||
dat++;
|
||||
}
|
||||
USB_GetLastFIFOByte(dat, fifoNum);
|
||||
USB_GetLastFIFOByte(*dat, fifoNum);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
@@ -1016,7 +884,7 @@ static void USB_ReadFIFO_Generic(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(d
|
||||
* @param dat
|
||||
* Pointer to generic buffer holding data to write to the FIFO
|
||||
******************************************************************************/
|
||||
static void USB_WriteFIFO_Generic(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_GENERIC))
|
||||
static void USB_WriteFIFO_Generic(uint8_t numBytes, uint8_t *dat)
|
||||
{
|
||||
while (numBytes--)
|
||||
{
|
||||
|
@@ -13,7 +13,7 @@
|
||||
// Global variables
|
||||
|
||||
extern SI_SEGMENT_VARIABLE(myUsbDevice, USBD_Device_TypeDef, MEM_MODEL_SEG);
|
||||
extern SI_SEGMENT_VARIABLE(txZero[2], const uint8_t, SI_SEG_CODE);
|
||||
extern SI_SEGMENT_VARIABLE(txZero[2], uint8_t, SI_SEG_CODE);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Function prototypes
|
||||
@@ -48,12 +48,6 @@ void handleUsbOut3Int(void);
|
||||
|
||||
void SendEp0Stall(void);
|
||||
|
||||
#if SLAB_USB_UTF8_STRINGS == 1
|
||||
static uint8_t decodeUtf8toUcs2(
|
||||
const uint8_t *pUtf8in,
|
||||
SI_VARIABLE_SEGMENT_POINTER(pUcs2out, uint16_t, MEM_MODEL_SEG));
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Functions
|
||||
|
||||
@@ -218,8 +212,6 @@ void usbIrqHandler(void)
|
||||
******************************************************************************/
|
||||
static void handleUsbEp0Int(void)
|
||||
{
|
||||
USB_Status_TypeDef retVal = USB_STATUS_REQ_UNHANDLED;
|
||||
|
||||
USB_SetIndex(0);
|
||||
|
||||
if (USB_Ep0SentStall() || USB_GetSetupEnd())
|
||||
@@ -242,55 +234,32 @@ static void handleUsbEp0Int(void)
|
||||
|
||||
// Vendor unique, Class or Standard setup commands override?
|
||||
#if SLAB_USB_SETUP_CMD_CB
|
||||
retVal = USBD_SetupCmdCb(&myUsbDevice.setup);
|
||||
|
||||
if (retVal == USB_STATUS_REQ_UNHANDLED)
|
||||
if (USBD_SetupCmdCb(&myUsbDevice.setup) == USB_STATUS_REQ_UNHANDLED)
|
||||
{
|
||||
#endif
|
||||
if (myUsbDevice.setup.bmRequestType.Type == USB_SETUP_TYPE_STANDARD)
|
||||
{
|
||||
retVal = USBDCH9_SetupCmd();
|
||||
}
|
||||
#if SLAB_USB_SETUP_CMD_CB
|
||||
}
|
||||
#endif
|
||||
|
||||
// Reset index to 0 in case the call to USBD_SetupCmdCb() or
|
||||
// USBDCH9_SetupCmd() changed it.
|
||||
USB_SetIndex(0);
|
||||
|
||||
// Put the Enpoint 0 hardware into the correct state here.
|
||||
if (retVal == USB_STATUS_OK)
|
||||
if (myUsbDevice.setup.bmRequestType.Type == USB_SETUP_TYPE_STANDARD)
|
||||
{
|
||||
// If wLength is 0, there is no Data Phase
|
||||
// Set both the Serviced Out Packet Ready and Data End bits
|
||||
if (myUsbDevice.setup.wLength == 0)
|
||||
{
|
||||
USB_Ep0SetLastOutPacketReady();
|
||||
}
|
||||
// If wLength is non-zero, there is a Data Phase.
|
||||
// Set only the Serviced Out Packet Ready bit.
|
||||
else
|
||||
{
|
||||
USB_Ep0ServicedOutPacketReady();
|
||||
|
||||
#if SLAB_USB_SETUP_CMD_CB
|
||||
// If OUT packet but callback didn't set up a USBD_Read and we are expecting a
|
||||
// data byte then we need to wait for the read to be setup and NACK packets until
|
||||
// USBD_Read is called.
|
||||
if ((myUsbDevice.setup.bmRequestType.Direction == USB_SETUP_DIR_OUT)
|
||||
&& (myUsbDevice.ep0.state != D_EP_RECEIVING))
|
||||
{
|
||||
myUsbDevice.ep0.misc.bits.waitForRead = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
USBDCH9_SetupCmd();
|
||||
}
|
||||
// If the setup transaction detected an error, send a stall
|
||||
else
|
||||
{
|
||||
SendEp0Stall();
|
||||
}
|
||||
#if SLAB_USB_SETUP_CMD_CB
|
||||
}
|
||||
else
|
||||
{
|
||||
// If in-packet but callback didn't setup a USBD_Read and we are expecting a data byte then
|
||||
// we need to wait for the read to be setup and nack packets till USBD_Read is called.
|
||||
if ((myUsbDevice.setup.bmRequestType.Direction == USB_SETUP_DIR_OUT)
|
||||
&& (myUsbDevice.ep0.state != D_EP_RECEIVING)
|
||||
&& (myUsbDevice.setup.wLength)
|
||||
)
|
||||
{
|
||||
myUsbDevice.ep0.misc.bits.waitForRead = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (myUsbDevice.ep0.state == D_EP_RECEIVING)
|
||||
{
|
||||
@@ -312,9 +281,11 @@ static void handleUsbEp0Int(void)
|
||||
******************************************************************************/
|
||||
static void USB_ReadFIFOSetup(void)
|
||||
{
|
||||
SI_VARIABLE_SEGMENT_POINTER(ptr, uint16_t, MEM_MODEL_SEG) = (SI_VARIABLE_SEGMENT_POINTER(, uint16_t, MEM_MODEL_SEG))&myUsbDevice.setup;
|
||||
uint16_t MEM_MODEL_SEG *ptr = &myUsbDevice.setup;
|
||||
|
||||
USB_ReadFIFO(0, 8, (SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))ptr);
|
||||
USB_ReadFIFO(0, 8, (uint8_t *)ptr);
|
||||
|
||||
USB_Ep0ServicedOutPacketReady();
|
||||
|
||||
// Modify for Endian-ness of the compiler
|
||||
ptr[1] = le16toh(ptr[1]);
|
||||
@@ -368,11 +339,9 @@ static void handleUsbResetInt(void)
|
||||
USB_EnableSuspendDetection();
|
||||
USB_EnableDeviceInts();
|
||||
|
||||
// If the device is bus-powered, always put it in the Default state.
|
||||
// If the device is self-powered and VBUS is present, put the device in the
|
||||
// Default state. Otherwise, put it in the Attached state.
|
||||
#if (!SLAB_USB_BUS_POWERED) && \
|
||||
(!(SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF))
|
||||
// If VBUS is preset, put the device in the Default state.
|
||||
// Otherwise, put it in the Attached state.
|
||||
#if (!(SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF))
|
||||
if (USB_IsVbusOn())
|
||||
{
|
||||
USBD_SetUsbState(USBD_STATE_DEFAULT);
|
||||
@@ -437,16 +406,12 @@ static void handleUsbEp0Tx(void)
|
||||
// Strings can use the USB_STRING_DESCRIPTOR_UTF16LE_PACKED type to pack
|
||||
// UTF16LE data without the zero's between each character.
|
||||
// If the current string is of type USB_STRING_DESCRIPTOR_UTF16LE_PACKED,
|
||||
// unpack it by inserting a zero between each character in the string.
|
||||
if ((myUsbDevice.ep0String.encoding.type == USB_STRING_DESCRIPTOR_UTF16LE_PACKED)
|
||||
#if SLAB_USB_UTF8_STRINGS == 1
|
||||
|| (myUsbDevice.ep0String.encoding.type == USB_STRING_DESCRIPTOR_UTF8)
|
||||
#endif
|
||||
)
|
||||
// unpacket it by inserting a zero between each character in the string.
|
||||
if (myUsbDevice.ep0String.encoding.type == USB_STRING_DESCRIPTOR_UTF16LE_PACKED)
|
||||
{
|
||||
// If ep0String.encoding.init is true, this is the beginning of the string.
|
||||
// The first two bytes of the string are the bLength and bDescriptorType
|
||||
// fields. These are not packed like the reset of the string, so write them
|
||||
// fields. These are no packed like the reset of the string, so write them
|
||||
// to the FIFO and set ep0String.encoding.init to false.
|
||||
if (myUsbDevice.ep0String.encoding.init == true)
|
||||
{
|
||||
@@ -459,36 +424,9 @@ static void handleUsbEp0Tx(void)
|
||||
// Insert a 0x00 between each character of the string.
|
||||
for (i = 0; i < count / 2; i++)
|
||||
{
|
||||
#if SLAB_USB_UTF8_STRINGS == 1
|
||||
if (myUsbDevice.ep0String.encoding.type == USB_STRING_DESCRIPTOR_UTF8)
|
||||
{
|
||||
SI_SEGMENT_VARIABLE(ucs2, uint16_t, MEM_MODEL_SEG);
|
||||
uint8_t utf8count;
|
||||
|
||||
// decode the utf8 into ucs2 for usb string
|
||||
utf8count = decodeUtf8toUcs2(myUsbDevice.ep0.buf, &ucs2);
|
||||
|
||||
// if consumed utf8 bytes is 0, it means either null byte was
|
||||
// input or bad utf8 byte sequence. Either way its an error and
|
||||
// there's not much we can do. So just advance the input string
|
||||
// by one character and keep going until count is expired.
|
||||
if (utf8count == 0)
|
||||
{
|
||||
utf8count = 1;
|
||||
}
|
||||
|
||||
// adjust to next char in utf8 byte sequence
|
||||
myUsbDevice.ep0.buf += utf8count;
|
||||
ucs2 = htole16(ucs2); // usb 16-bit chars are little endian
|
||||
USB_WriteFIFO(0, 2, (SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))&ucs2, false);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
USB_WriteFIFO(0, 1, (SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))myUsbDevice.ep0.buf, false);
|
||||
myUsbDevice.ep0.buf++;
|
||||
USB_WriteFIFO(0, 1, (SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))&txZero, false);
|
||||
}
|
||||
USB_WriteFIFO(0, 1, myUsbDevice.ep0.buf, false);
|
||||
myUsbDevice.ep0.buf++;
|
||||
USB_WriteFIFO(0, 1, &txZero, false);
|
||||
}
|
||||
}
|
||||
// For any data other than USB_STRING_DESCRIPTOR_UTF16LE_PACKED, just send the
|
||||
@@ -588,98 +526,6 @@ void SendEp0Stall(void)
|
||||
USB_Ep0SendStall();
|
||||
}
|
||||
|
||||
#if SLAB_USB_UTF8_STRINGS == 1
|
||||
/***************************************************************************//**
|
||||
* Decodes UTF-8 to UCS-2 (16-bit) character encoding that is used
|
||||
* for USB string descriptors.
|
||||
*
|
||||
* @param pUtf8in pointer to next character in UTF-8 string
|
||||
* @param pUcs2out pointer to location for 16-bit character output
|
||||
*
|
||||
* Decodes a UTF-8 byte sequence into a single UCS-2 character. This
|
||||
* will only decode up to 16-bit code point and will not handle the
|
||||
* 21-bit case (4 bytes input).
|
||||
*
|
||||
* For valid cases, the UTF8 character sequence decoded into a 16-bit
|
||||
* character and stored at the location pointed at by _pUcs2out_.
|
||||
* The function will then return the number of input bytes that were
|
||||
* consumed (1, 2, or 3). The caller can use the return value to find
|
||||
* the start of the next character sequence in a utf-8 string.
|
||||
*
|
||||
* If either of the input pointers are NULL, then 0 is returned.
|
||||
*
|
||||
* If the first input character is NULL, then the output 16-bit value
|
||||
* will be set to NULL and the function will return 0.
|
||||
*
|
||||
* If any other invalid sequence is detected, then the 16-bit output
|
||||
* will be set to the equivalent of the question mark character (0x003F)
|
||||
* and the return code will be 0.
|
||||
*
|
||||
* @return count of UTF8 bytes consumed
|
||||
******************************************************************************/
|
||||
static uint8_t decodeUtf8toUcs2(
|
||||
const uint8_t *pUtf8in,
|
||||
SI_VARIABLE_SEGMENT_POINTER(pUcs2out, uint16_t, MEM_MODEL_SEG))
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
|
||||
// check the input pointers
|
||||
if (!pUtf8in || !pUcs2out)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// set default decode to error '?';
|
||||
*pUcs2out = '?';
|
||||
|
||||
// valid cases:
|
||||
// 0xxxxxxx (7 bits)
|
||||
// 110xxxxx 10xxxxxx (11 bits)
|
||||
// 1110xxxx 10xxxxxx 10xxxxxx (16 bits)
|
||||
|
||||
// null input
|
||||
if (pUtf8in[0] == 0)
|
||||
{
|
||||
*pUcs2out = 0;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
// 7-bit char
|
||||
else if (pUtf8in[0] < 128)
|
||||
{
|
||||
*pUcs2out = pUtf8in[0];
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
// 11-bit char
|
||||
else if ((pUtf8in[0] & 0xE0) == 0xC0)
|
||||
{
|
||||
if ((pUtf8in[1] & 0xC0) == 0x80)
|
||||
{
|
||||
*pUcs2out = ((pUtf8in[0] & 0x1F) << 6) | (pUtf8in[1] & 0x3F);
|
||||
ret = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// 16-bit char
|
||||
else if ((pUtf8in[0] & 0xF0) == 0xE0)
|
||||
{
|
||||
if ((pUtf8in[1] & 0xC0) == 0x80)
|
||||
{
|
||||
if ((pUtf8in[2] & 0xC0) == 0x80)
|
||||
{
|
||||
*pUcs2out = ((pUtf8in[0] & 0x0F) << 12)
|
||||
| ((pUtf8in[1] & 0x3F) << 6)
|
||||
| (pUtf8in[2] & 0x3F);
|
||||
ret = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif // SLAB_USB_UTF8_STRINGS
|
||||
|
||||
// This function is called from USBD_Init(). It forces the user project to pull
|
||||
// this module from the library so that the declared ISR can be seen and
|
||||
// included. If this is not done then this entire module by never be included
|
||||
|
Reference in New Issue
Block a user