Initial commit

This commit is contained in:
Gericom
2025-11-23 14:02:39 +01:00
commit 3bb550c12e
53 changed files with 4301 additions and 0 deletions

29
platform/DSPicoUsb.h Normal file
View File

@@ -0,0 +1,29 @@
#pragma once
#include <libtwl/card/card.h>
#define DSPICO_CMD_USB_COMMAND(command, arguments) (0xE800000000000000ull | ((u64)(command) << 48) | (arguments))
#define DSPICO_CMD_USB_COMMAND_INIT DSPICO_CMD_USB_COMMAND(1, 0)
#define DSPICO_CMD_USB_COMMAND_BEGIN_SET_ADDRESS DSPICO_CMD_USB_COMMAND(2, 0)
#define DSPICO_CMD_USB_COMMAND_REMOTE_WAKEUP DSPICO_CMD_USB_COMMAND(3, 0)
#define DSPICO_CMD_USB_COMMAND_CONNECT DSPICO_CMD_USB_COMMAND(4, 0)
#define DSPICO_CMD_USB_COMMAND_DISCONNECT DSPICO_CMD_USB_COMMAND(5, 0)
#define DSPICO_CMD_USB_COMMAND_SOF_ENABLE DSPICO_CMD_USB_COMMAND(6, 0)
#define DSPICO_CMD_USB_COMMAND_SOF_DISABLE DSPICO_CMD_USB_COMMAND(7, 0)
#define DSPICO_CMD_USB_COMMAND_EP_CLOSE_ALL DSPICO_CMD_USB_COMMAND(8, 0)
#define DSPICO_CMD_USB_COMMAND_EP_STALL(ep) DSPICO_CMD_USB_COMMAND(9, (u64)(ep) << 40)
#define DSPICO_CMD_USB_COMMAND_EP_CLEAR_STALL(ep) DSPICO_CMD_USB_COMMAND(10, (u64)(ep) << 40)
#define DSPICO_CMD_USB_COMMAND_EP_CLOSE(ep) DSPICO_CMD_USB_COMMAND(11, (u64)(ep) << 40)
#define DSPICO_CMD_USB_COMMAND_FINISH_SET_ADDRESS(addr) DSPICO_CMD_USB_COMMAND(12, (u64)(addr) << 40)
#define DSPICO_CMD_USB_COMMAND_EP_OPEN(ep, maxPktSize, xfer) DSPICO_CMD_USB_COMMAND(13, ((u64)(ep) << 40) | ((u64)((xfer) & 3) << 32) | ((u64)((maxPktSize) & 0x7FF)))
#define DSPICO_CMD_USB_COMMAND_CLEAR_EVENT_QUEUE DSPICO_CMD_USB_COMMAND(14, 0)
#define DSPICO_CMD_USB_COMMAND_DEINIT DSPICO_CMD_USB_COMMAND(15, 0)
#define DSPICO_CMD_USB_COMMAND_BEGIN_TRANSFER(ep, offset, length) DSPICO_CMD_USB_COMMAND(16, ((u64)(ep) << 40) | ((u64)(offset) << 32) | (length))
#define DSPICO_CMD_USB_COMMAND_INTERRUPT_ENABLE DSPICO_CMD_USB_COMMAND(17, 0)
#define DSPICO_CMD_USB_COMMAND_INTERRUPT_DISABLE DSPICO_CMD_USB_COMMAND(18, 0)
#define DSPICO_CMD_USB_WRITE_DATA(offset, endpoint, isLast, totalLength) (0xE900000000000000ull | ((u64)(offset) << 48) | ((u64)(endpoint) << 40) | ((u64)(isLast) << 32) | (totalLength))
#define DSPICO_CMD_USB_READ_DATA(offset, endpoint) (0xEA00000000000000ull | ((u64)(offset) << 32) | ((u64)(endpoint) << 40))
#define DSPICO_CMD_USB_GET_EVENT 0xEB00000000000000ull
#define DSPICO_USB_DEFAULT_COMMAND_SETTINGS (MCCNT1_DIR_READ | MCCNT1_RESET_OFF | MCCNT1_CLK_6_7_MHZ | MCCNT1_LEN_0 | MCCNT1_CMD_SCRAMBLE |\
MCCNT1_LATENCY2(0) | MCCNT1_CLOCK_SCRAMBLER | MCCNT1_READ_DATA_DESCRAMBLE | MCCNT1_LATENCY1(0))

View File

@@ -0,0 +1,100 @@
#include "common.h"
#include "libtwl/dma/dmaNitro.h"
#include "tusb.h"
#include "device/dcd.h"
#include "DSPicoUsb.h"
#include "DSPicoUsbInEndpoint.h"
void DSPicoUsbInEndpoint::BeginTransfer(const u8* buffer, u32 length)
{
rtos_lockMutex(&_mutex);
{
_buffer = buffer;
_bufferLength = length;
_remaining = length;
_bufferOffset = 0;
_currentDSPicoBuffer = 0;
_transferActive = true;
SendUsbBlock(true);
SendUsbBlock(false);
}
rtos_unlockMutex(&_mutex);
}
void DSPicoUsbInEndpoint::ProcessTransferCompleteEvent(u32 transferredBytes)
{
rtos_lockMutex(&_mutex);
{
if (_transferActive)
{
_remaining -= transferredBytes;
if (_remaining == 0)
{
dcd_event_xfer_complete(0, _endpointAddress, _bufferLength, XFER_RESULT_SUCCESS, true);
_transferActive = false;
}
else
{
u32 length = _remaining;
if (length > 512)
{
length = 512;
}
rtos_lockMutex(&gCardMutex);
{
card_romSetCmd(DSPICO_CMD_USB_COMMAND_BEGIN_TRANSFER(_endpointAddress, 1 - _currentDSPicoBuffer, length));
card_romStartXfer(DSPICO_USB_DEFAULT_COMMAND_SETTINGS, false);
card_romWaitBusy();
}
rtos_unlockMutex(&gCardMutex);
SendUsbBlock(false);
}
}
else
{
// This seems to happen only once on the control endpoint. Idk why.
dcd_event_xfer_complete(0, _endpointAddress, transferredBytes, XFER_RESULT_SUCCESS, true);
}
}
rtos_unlockMutex(&_mutex);
}
void DSPicoUsbInEndpoint::SendUsbBlock(bool startTransfer)
{
u32 length = _bufferLength - _bufferOffset;
if (length > 0)
{
if (length > 512)
{
length = 512;
}
rtos_lockMutex(&gCardMutex);
{
REG_DMA3SAD = (u32)(_buffer + _bufferOffset);
REG_DMA3DAD = (u32)&REG_MCD1;
REG_DMA3CNT = 0xA6400001;
card_romSetCmd(DSPICO_CMD_USB_WRITE_DATA(_currentDSPicoBuffer, _endpointAddress, startTransfer, length));
card_romStartXfer(MCCNT1_DIR_WRITE | MCCNT1_RESET_OFF | MCCNT1_CLK_6_7_MHZ | MCCNT1_LEN_512 | MCCNT1_CMD_SCRAMBLE |
MCCNT1_LATENCY2(8) | MCCNT1_CLOCK_SCRAMBLER | MCCNT1_READ_DATA_DESCRAMBLE | MCCNT1_LATENCY1(0), false);
card_romWaitBusy();
REG_DMA3CNT = 0;
}
rtos_unlockMutex(&gCardMutex);
_bufferOffset += length;
_currentDSPicoBuffer = 1 - _currentDSPicoBuffer;
}
else if (startTransfer)
{
// zero length transfer
rtos_lockMutex(&gCardMutex);
{
card_romSetCmd(DSPICO_CMD_USB_WRITE_DATA(_currentDSPicoBuffer, _endpointAddress, true, 0));
card_romStartXfer(DSPICO_USB_DEFAULT_COMMAND_SETTINGS, false);
card_romWaitBusy();
}
rtos_unlockMutex(&gCardMutex);
}
}

View File

@@ -0,0 +1,28 @@
#pragma once
#include "libtwl/rtos/rtosMutex.h"
class DSPicoUsbInEndpoint
{
public:
explicit DSPicoUsbInEndpoint(u8 endpointAddress)
: _endpointAddress(endpointAddress), _currentDSPicoBuffer(0), _buffer(nullptr)
, _bufferLength(0), _remaining(0), _bufferOffset(0), _transferActive(false)
{
rtos_createMutex(&_mutex);
}
void BeginTransfer(const u8* buffer, u32 length);
void ProcessTransferCompleteEvent(u32 transferredBytes);
private:
u8 _endpointAddress;
u8 _currentDSPicoBuffer;
const u8* _buffer;
u32 _bufferLength;
u32 _remaining;
u32 _bufferOffset;
rtos_mutex_t _mutex;
bool _transferActive;
void SendUsbBlock(bool startTransfer);
};

View File

@@ -0,0 +1,141 @@
#include "common.h"
#include "libtwl/dma/dmaNitro.h"
#include "tusb.h"
#include "device/dcd.h"
#include "DSPicoUsb.h"
#include "DSPicoUsbOutEndpoint.h"
void DSPicoUsbOutEndpoint::BeginTransfer(u8* buffer, u32 length)
{
rtos_lockMutex(&_mutex);
{
_buffer = buffer;
_bufferLength = length;
_bufferOffset = 0;
_totalReceived = 0;
_currentDSPicoBuffer = 0;
_transferActive = true;
u32 firstReceiveLength = _bufferLength;
if (firstReceiveLength > 512)
{
firstReceiveLength = 512;
}
rtos_lockMutex(&gCardMutex);
{
card_romSetCmd(DSPICO_CMD_USB_COMMAND_BEGIN_TRANSFER(_endpointAddress, _currentDSPicoBuffer, firstReceiveLength));
card_romStartXfer(DSPICO_USB_DEFAULT_COMMAND_SETTINGS, false);
card_romWaitBusy();
}
rtos_unlockMutex(&gCardMutex);
}
rtos_unlockMutex(&_mutex);
}
void DSPicoUsbOutEndpoint::ProcessTransferCompleteEvent(u32 transferredBytes)
{
rtos_lockMutex(&_mutex);
{
if (_transferActive)
{
_totalReceived += transferredBytes;
int length = _bufferLength - _bufferOffset - 512;
if (length > 512)
{
length = 512;
}
if (transferredBytes == 512)
{
if (length > 0)
{
rtos_lockMutex(&gCardMutex);
{
card_romSetCmd(DSPICO_CMD_USB_COMMAND_BEGIN_TRANSFER(_endpointAddress, 1 - _currentDSPicoBuffer, length));
card_romStartXfer(DSPICO_USB_DEFAULT_COMMAND_SETTINGS, false);
card_romWaitBusy();
}
rtos_unlockMutex(&gCardMutex);
}
}
ReceiveUsbBlock();
if (transferredBytes < 512 || length == 0)
{
dcd_event_xfer_complete(0, _endpointAddress, _bufferOffset, XFER_RESULT_SUCCESS, true);
_transferActive = false;
}
}
else
{
// idk
dcd_event_xfer_complete(0, _endpointAddress, transferredBytes, XFER_RESULT_SUCCESS, true);
}
}
rtos_unlockMutex(&_mutex);
}
void DSPicoUsbOutEndpoint::ReceiveUsbBlock()
{
u32 length = _totalReceived - _bufferOffset;
if (length > 0)
{
if (length > 512)
{
length = 512;
}
rtos_lockMutex(&gCardMutex);
{
if (length == 512)
{
REG_DMA3SAD = (u32)&REG_MCD1;
REG_DMA3DAD = (u32)(_buffer + _bufferOffset);
REG_DMA3CNT = 0xA7000001;
}
card_romSetCmd(DSPICO_CMD_USB_READ_DATA(_currentDSPicoBuffer, _endpointAddress));
card_romStartXfer(MCCNT1_DIR_READ | MCCNT1_RESET_OFF | MCCNT1_CLK_6_7_MHZ | MCCNT1_LEN_512 | MCCNT1_CMD_SCRAMBLE |
MCCNT1_LATENCY2(4) | MCCNT1_CLOCK_SCRAMBLER | MCCNT1_LATENCY1(0), false);
if (length == 512)
{
card_romWaitBusy();
REG_DMA3CNT = 0;
}
else if (length & 3)
{
u8* target = _buffer + _bufferOffset + length;
u8* dst = _buffer + _bufferOffset;
do
{
// Read data if available
if (card_romIsDataReady())
{
u32 data = card_romGetData();
if (dst + 3 < target)
{
*(u32*)dst = data;
dst += 4;
}
else if (dst < target)
{
*dst++ = data & 0xFF;
if (dst < target)
{
*dst++ = (data >> 8) & 0xFF;
if (dst < target)
{
*dst++ = (data >> 16) & 0xFF;
}
}
}
}
} while (card_romIsBusy());
}
else
{
card_romCpuRead((u32*)(_buffer + _bufferOffset), length >> 2);
}
}
rtos_unlockMutex(&gCardMutex);
_bufferOffset += length;
_currentDSPicoBuffer = 1 - _currentDSPicoBuffer;
}
}

View File

@@ -0,0 +1,26 @@
#pragma once
class DSPicoUsbOutEndpoint
{
public:
explicit DSPicoUsbOutEndpoint(u8 endpointAddress)
: _endpointAddress(endpointAddress), _currentDSPicoBuffer(0), _buffer(nullptr)
, _bufferLength(0), _bufferOffset(0), _totalReceived(0), _transferActive(false)
{
rtos_createMutex(&_mutex);
}
void BeginTransfer(u8* buffer, u32 length);
void ProcessTransferCompleteEvent(u32 transferredBytes);
private:
u8 _endpointAddress;
u8 _currentDSPicoBuffer;
u8* _buffer;
u32 _bufferLength;
u32 _bufferOffset;
u32 _totalReceived;
bool _transferActive;
rtos_mutex_t _mutex;
void ReceiveUsbBlock();
};

View File

@@ -0,0 +1,25 @@
#pragma once
#include "tusb.h"
template<std::size_t N>
struct UsbStringDescriptor
{
u8 length = 2 * N;
u8 descriptorType = TUSB_DESC_STRING;
char16_t string[N - 1];
explicit constexpr UsbStringDescriptor(const char16_t(&str)[N])
{
for (size_t i = 0; i < N - 1; i++)
{
string[i] = str[i];
}
}
explicit constexpr UsbStringDescriptor(u16 languageId)
{
string[0] = languageId;
}
};
#define USB_STRING_DESCRIPTOR(str) ({ static const UsbStringDescriptor descriptor(str); (const u16*)&descriptor; })

315
platform/dcd_dspico.cpp Normal file
View File

@@ -0,0 +1,315 @@
#include "common.h"
#include <libtwl/card/card.h>
#include <libtwl/rtos/rtosIrq.h>
#include <libtwl/rtos/rtosEvent.h>
#include <libtwl/rtos/rtosThread.h>
#include "tusb_option.h"
#include "tusb.h"
#if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_DSPICO
#include "device/dcd.h"
#include "DSPicoUsb.h"
#include "DSPicoUsbInEndpoint.h"
#include "DSPicoUsbOutEndpoint.h"
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
//--------------------------------------------------------------------+
static rtos_event_t sCardIrqEvent;
static rtos_thread_t sUsbThread;
static u32 sUsbThreadStack[512];
static DSPicoUsbInEndpoint sInEndpoints[16] =
{
DSPicoUsbInEndpoint(TUSB_DIR_IN_MASK | 0),
DSPicoUsbInEndpoint(TUSB_DIR_IN_MASK | 1),
DSPicoUsbInEndpoint(TUSB_DIR_IN_MASK | 2),
DSPicoUsbInEndpoint(TUSB_DIR_IN_MASK | 3),
DSPicoUsbInEndpoint(TUSB_DIR_IN_MASK | 4),
DSPicoUsbInEndpoint(TUSB_DIR_IN_MASK | 5),
DSPicoUsbInEndpoint(TUSB_DIR_IN_MASK | 6),
DSPicoUsbInEndpoint(TUSB_DIR_IN_MASK | 7),
DSPicoUsbInEndpoint(TUSB_DIR_IN_MASK | 8),
DSPicoUsbInEndpoint(TUSB_DIR_IN_MASK | 9),
DSPicoUsbInEndpoint(TUSB_DIR_IN_MASK | 10),
DSPicoUsbInEndpoint(TUSB_DIR_IN_MASK | 11),
DSPicoUsbInEndpoint(TUSB_DIR_IN_MASK | 12),
DSPicoUsbInEndpoint(TUSB_DIR_IN_MASK | 13),
DSPicoUsbInEndpoint(TUSB_DIR_IN_MASK | 14),
DSPicoUsbInEndpoint(TUSB_DIR_IN_MASK | 15)
};
static DSPicoUsbOutEndpoint sOutEndpoints[16] =
{
DSPicoUsbOutEndpoint(0),
DSPicoUsbOutEndpoint(1),
DSPicoUsbOutEndpoint(2),
DSPicoUsbOutEndpoint(3),
DSPicoUsbOutEndpoint(4),
DSPicoUsbOutEndpoint(5),
DSPicoUsbOutEndpoint(6),
DSPicoUsbOutEndpoint(7),
DSPicoUsbOutEndpoint(8),
DSPicoUsbOutEndpoint(9),
DSPicoUsbOutEndpoint(10),
DSPicoUsbOutEndpoint(11),
DSPicoUsbOutEndpoint(12),
DSPicoUsbOutEndpoint(13),
DSPicoUsbOutEndpoint(14),
DSPicoUsbOutEndpoint(15)
};
static void sendCommand(u64 command)
{
rtos_lockMutex(&gCardMutex);
card_romSetCmd(command);
card_romStartXfer(DSPICO_USB_DEFAULT_COMMAND_SETTINGS, false);
card_romWaitBusy();
rtos_unlockMutex(&gCardMutex);
}
static void cardIrq(u32 irqMask)
{
rtos_signalEvent(&sCardIrqEvent);
}
static void usbThreadMain(void* arg)
{
while (true)
{
rtos_waitEvent(&sCardIrqEvent, false, true);
u32 event;
bool lastEvent;
do
{
rtos_lockMutex(&gCardMutex);
card_romSetCmd(DSPICO_CMD_USB_GET_EVENT);
card_romStartXfer(MCCNT1_DIR_READ | MCCNT1_RESET_OFF | MCCNT1_CLK_6_7_MHZ | MCCNT1_LEN_4 | MCCNT1_CMD_SCRAMBLE |
MCCNT1_LATENCY2(4) | MCCNT1_CLOCK_SCRAMBLER | MCCNT1_READ_DATA_DESCRAMBLE | MCCNT1_LATENCY1(0), false);
card_romCpuRead(&event, 1);
rtos_unlockMutex(&gCardMutex);
lastEvent = (event >> 31) != 0;
event &= ~(1 << 31);
if (event == 0)
{
// USB_EVENT_NONE
break;
}
else if ((event >> 30) == 1)
{
// USB_EVENT_SETUP_RECEIVED
tusb_control_request_t setup;
setup.wLength = (event >> 16) & 0x1FFF;
u32 direction = (event >> 29) & 1;
setup.wIndex = event & 0xFFFF;
rtos_lockMutex(&gCardMutex);
card_romSetCmd(DSPICO_CMD_USB_GET_EVENT);
card_romStartXfer(MCCNT1_DIR_READ | MCCNT1_RESET_OFF | MCCNT1_CLK_6_7_MHZ | MCCNT1_LEN_4 | MCCNT1_CMD_SCRAMBLE |
MCCNT1_LATENCY2(4) | MCCNT1_CLOCK_SCRAMBLER | MCCNT1_READ_DATA_DESCRAMBLE | MCCNT1_LATENCY1(0), false);
card_romCpuRead(&event, 1);
rtos_unlockMutex(&gCardMutex);
lastEvent = (event >> 31) != 0;
event &= ~(1 << 31);
setup.wValue = event & 0xFFFF;
setup.bRequest = (event >> 16) & 0xFF;
setup.bmRequestType = (event >> 24) & 0x7F;
setup.bmRequestType_bit.direction = direction;
dcd_event_setup_received(0, (const u8*)&setup, true);
}
else if ((event >> 28) == 2)
{
// USB_EVENT_SOF
dcd_event_sof(0, event & 0x7FF, true);
}
else if ((event >> 28) == 3)
{
// USB_EVENT_XFER_COMPLETE
u32 endpoint = event & 0xFF;
u32 transferredBytes = (event >> 8) & 0x1FFF;
if (tu_edpt_dir(endpoint) == TUSB_DIR_IN)
{
sInEndpoints[endpoint & ~0x80].ProcessTransferCompleteEvent(transferredBytes);
}
else
{
sOutEndpoints[endpoint & ~0x80].ProcessTransferCompleteEvent(transferredBytes);
}
}
else if (event == 1)
{
// USB_EVENT_BUS_RESET
dcd_event_bus_reset(0, TUSB_SPEED_FULL, true);
}
else if (event == 2)
{
// USB_EVENT_UNPLUGGED
dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, true);
}
else if (event == 3)
{
// USB_EVENT_SUSPEND
dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true);
}
else if (event == 4)
{
// USB_EVENT_RESUME
dcd_event_bus_signal(0, DCD_EVENT_RESUME, true);
}
else
{
// invalid
}
} while (!lastEvent);
}
}
/*------------------------------------------------------------------*/
/* Device API
*------------------------------------------------------------------*/
// Initialize controller to device mode
bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init)
{
(void) rhport;
(void) rh_init;
rtos_createEvent(&sCardIrqEvent);
rtos_disableIrqMask(RTOS_IRQ_DS_SLOTA_IREQ);
rtos_setIrqFunc(RTOS_IRQ_DS_SLOTA_IREQ, cardIrq);
rtos_ackIrqMask(RTOS_IRQ_DS_SLOTA_IREQ);
rtos_createThread(&sUsbThread, 2, usbThreadMain, NULL, sUsbThreadStack, sizeof(sUsbThreadStack));
rtos_wakeupThread(&sUsbThread);
sendCommand(DSPICO_CMD_USB_COMMAND_INIT);
return true;
}
bool dcd_deinit(uint8_t rhport)
{
(void) rhport;
rtos_disableIrqMask(RTOS_IRQ_DS_SLOTA_IREQ);
rtos_setIrqFunc(RTOS_IRQ_DS_SLOTA_IREQ, NULL);
rtos_ackIrqMask(RTOS_IRQ_DS_SLOTA_IREQ);
sendCommand(DSPICO_CMD_USB_COMMAND_DEINIT);
return true;
}
// Enable device interrupt
void dcd_int_enable(uint8_t rhport)
{
(void) rhport;
sendCommand(DSPICO_CMD_USB_COMMAND_INTERRUPT_ENABLE);
rtos_enableIrqMask(RTOS_IRQ_DS_SLOTA_IREQ);
}
// Disable device interrupt
void dcd_int_disable(uint8_t rhport)
{
(void) rhport;
rtos_disableIrqMask(RTOS_IRQ_DS_SLOTA_IREQ);
sendCommand(DSPICO_CMD_USB_COMMAND_INTERRUPT_DISABLE);
}
// Receive Set Address request, mcu port must also include status IN response
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
{
(void) rhport;
(void) dev_addr;
sendCommand(DSPICO_CMD_USB_COMMAND_BEGIN_SET_ADDRESS);
}
// Wake up host
void dcd_remote_wakeup(uint8_t rhport)
{
(void) rhport;
sendCommand(DSPICO_CMD_USB_COMMAND_REMOTE_WAKEUP);
}
// Connect by enabling internal pull-up resistor on D+/D-
void dcd_connect(uint8_t rhport)
{
(void) rhport;
sendCommand(DSPICO_CMD_USB_COMMAND_CONNECT);
}
// Disconnect by disabling internal pull-up resistor on D+/D-
void dcd_disconnect(uint8_t rhport)
{
(void) rhport;
sendCommand(DSPICO_CMD_USB_COMMAND_DISCONNECT);
}
void dcd_sof_enable(uint8_t rhport, bool en)
{
(void) rhport;
sendCommand(en ? DSPICO_CMD_USB_COMMAND_SOF_ENABLE : DSPICO_CMD_USB_COMMAND_SOF_DISABLE);
}
//--------------------------------------------------------------------+
// Endpoint API
//--------------------------------------------------------------------+
void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const* request)
{
(void) rhport;
if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE &&
request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD &&
request->bRequest == TUSB_REQ_SET_ADDRESS)
{
sendCommand(DSPICO_CMD_USB_COMMAND_FINISH_SET_ADDRESS((u8)request->wValue));
}
}
// Configure endpoint's registers according to descriptor
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
{
(void) rhport;
sendCommand(DSPICO_CMD_USB_COMMAND_EP_OPEN(
ep_desc->bEndpointAddress, ep_desc->wMaxPacketSize, ep_desc->bmAttributes.xfer));
return true;
}
void dcd_edpt_close_all(uint8_t rhport)
{
(void) rhport;
sendCommand(DSPICO_CMD_USB_COMMAND_EP_CLOSE_ALL);
}
// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes)
{
(void) rhport;
if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN)
{
sInEndpoints[ep_addr & ~0x80].BeginTransfer(buffer, total_bytes);
}
else
{
sOutEndpoints[ep_addr & ~0x80].BeginTransfer(buffer, total_bytes);
}
return true;
}
// Stall endpoint
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
{
(void) rhport;
sendCommand(DSPICO_CMD_USB_COMMAND_EP_STALL(ep_addr));
}
// clear stall, data toggle is also reset to DATA0
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
{
(void) rhport;
sendCommand(DSPICO_CMD_USB_COMMAND_EP_CLEAR_STALL(ep_addr));
}
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
{
(void) rhport;
sendCommand(DSPICO_CMD_USB_COMMAND_EP_CLOSE(ep_addr));
}
#endif

161
platform/tusb_os_custom.h Normal file
View File

@@ -0,0 +1,161 @@
#pragma once
#include "common.h"
#include "libtwl/rtos/rtosMutex.h"
#include "libtwl/rtos/rtosEvent.h"
typedef rtos_event_t osal_semaphore_def_t;
typedef rtos_event_t* osal_semaphore_t;
static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
{
rtos_createEvent(semdef);
return semdef;
}
static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl)
{
(void) semd_hdl;
return true;
}
static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
{
rtos_signalEvent(sem_hdl);
return true;
}
static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec)
{
(void) msec;
rtos_waitEvent(sem_hdl, false, true);
return true;
}
static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl)
{
rtos_clearEvent(sem_hdl);
}
typedef rtos_mutex_t osal_mutex_def_t;
typedef rtos_mutex_t* osal_mutex_t;
static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
{
rtos_createMutex(mdef);
return mdef;
}
static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl)
{
(void) mutex_hdl;
return true;
}
static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec)
{
if (msec == OSAL_TIMEOUT_NOTIMEOUT)
{
return rtos_tryLockMutex(mutex_hdl);
}
else
{
rtos_lockMutex(mutex_hdl);
return true;
}
}
static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
{
rtos_unlockMutex(mutex_hdl);
return true;
}
typedef struct
{
rtos_event_t event;
volatile uint32_t readPtr;
volatile uint32_t writePtr;
uint32_t elementSize;
uint32_t bufferSize;
uint8_t* buffer;
} osal_queue_def_t;
typedef osal_queue_def_t* osal_queue_t;
#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \
uint8_t _name##_buf[(_depth + 1)*sizeof(_type)]; \
osal_queue_def_t _name = { \
.readPtr = 0, \
.writePtr = 0, \
.elementSize = sizeof(_type), \
.bufferSize = (_depth + 1)*sizeof(_type), \
.buffer = _name##_buf \
}
static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
{
rtos_createEvent(&qdef->event);
qdef->readPtr = 0;
qdef->writePtr = 0;
return qdef;
}
static inline bool osal_queue_delete(osal_queue_t qhdl)
{
(void) qhdl;
return true;
}
static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec)
{
do
{
uint32_t readPtr = qhdl->readPtr;
uint32_t writePtr = qhdl->writePtr;
if (readPtr != writePtr)
{
memcpy(data, &qhdl->buffer[readPtr], qhdl->elementSize);
readPtr += qhdl->elementSize;
if (readPtr == qhdl->bufferSize)
{
readPtr = 0;
}
qhdl->readPtr = readPtr;
return true;
}
if (msec == OSAL_TIMEOUT_NOTIMEOUT)
{
return false;
}
rtos_waitEvent(&qhdl->event, false, true);
} while (true);
}
static inline bool osal_queue_send(osal_queue_t qhdl, const void* data, bool in_isr)
{
uint32_t readPtr = qhdl->readPtr;
uint32_t writePtr = qhdl->writePtr;
uint32_t newWritePtr = writePtr + qhdl->elementSize;
if (newWritePtr == qhdl->bufferSize)
{
newWritePtr = 0;
}
if (newWritePtr == readPtr)
{
return false;
}
memcpy(&qhdl->buffer[writePtr], data, qhdl->elementSize);
qhdl->writePtr = newWritePtr;
rtos_signalEvent(&qhdl->event);
return true;
}
static inline bool osal_queue_empty(osal_queue_t qhdl)
{
qhdl->readPtr = 0;
qhdl->writePtr = 0;
return true;
}