39#include "system_config.h"
41#include "freertos_drivers/pic32mx/int_pic32mx795/int_defines.h"
45#include "driver/usb/usbfs/drv_usbfs.h"
46#include "usb/usb_device.h"
47#include "usb/usb_device_cdc.h"
122 USB_DEVICE_CDC_EVENT event,
void *pData);
125 static constexpr unsigned USB_CDC_BUFFER_SIZE = 64;
127 static constexpr unsigned TX_BUFFER_SIZE = 3 * USB_CDC_BUFFER_SIZE;
128 static constexpr unsigned RX_DEVICEBUFFER_SIZE = 0;
148 ssize_t
read(
File *file,
void *buf,
size_t count)
override;
250void *usb_device_task(
void *)
255 vTaskDelay(configTICK_RATE_HZ / 20);
268 :
Serial(name, TX_BUFFER_SIZE, RX_DEVICEBUFFER_SIZE)
272 , currentReadBuffer(0)
274 , nextReadBufferFull(0)
277 , irqVector(usb_interrupt_vector_number)
289 SYS_INT_VectorPrioritySet(INT_VECTOR_USB1, INT_PRIORITY_LEVEL1);
292 SYS_INT_VectorSubprioritySet(INT_VECTOR_USB1, INT_SUBPRIORITY_LEVEL0);
367 volatile unsigned rem = buf->data_write_pointer(&data);
368 HASSERT(rem >= USB_CDC_BUFFER_SIZE);
369 auto ret = USB_DEVICE_CDC_Read(
370 USB_DEVICE_CDC_INDEX_0, &
readHandle, data, USB_CDC_BUFFER_SIZE);
371 if (ret != USB_DEVICE_CDC_RESULT_OK)
380 uint8_t *data =
static_cast<uint8_t *
>(buf);
406 if ((file->
flags & O_NONBLOCK) || result > 0)
413 rxBuffers[0]->block_until_condition(file,
true);
418 result += bytes_read;
421 if (!result && (file->
flags & O_NONBLOCK))
441 USB_DEVICE_CDC_TRANSFER_FLAGS flag =
442 USB_DEVICE_CDC_TRANSFER_FLAGS_DATA_COMPLETE;
443 if (len > USB_CDC_BUFFER_SIZE ||
444 ((len == USB_CDC_BUFFER_SIZE) &&
447 len = USB_CDC_BUFFER_SIZE;
448 flag = USB_DEVICE_CDC_TRANSFER_FLAGS_MORE_DATA_PENDING;
451 auto ret = USB_DEVICE_CDC_Write(
452 USB_DEVICE_CDC_INDEX_0, &
writeHandle, data, len, flag);
453 if (ret != USB_DEVICE_CDC_RESULT_OK)
462 const unsigned char *data = (
const unsigned char *)buf;
467 size_t bytes_written = 0;
474 bytes_written =
txBuf->
put(data, count < 64 ? count : 64);
481 if (bytes_written == 0)
484 if ((file->
flags & O_NONBLOCK) || result > 0)
491 txBuf->block_until_condition(file,
false);
496 count -= bytes_written;
497 result += bytes_written;
498 data += bytes_written;
502 if (!result && (file->
flags & O_NONBLOCK))
553static void usb_device_event_handler(
554 USB_DEVICE_EVENT event,
void *pData, uintptr_t context)
571 USB_DEVICE_Open(USB_DEVICE_INDEX_0, DRV_IO_INTENT_READWRITE);
576 USB_DEVICE_EventHandlerSet(
deviceHandle, &usb_device_event_handler, 0);
587static USB_DEVICE_CDC_EVENT_RESPONSE cdc_device_event_handler(
588 USB_DEVICE_CDC_INDEX index, USB_DEVICE_CDC_EVENT event,
void *pData,
598 case USB_DEVICE_EVENT_POWER_REMOVED:
601 case USB_DEVICE_EVENT_POWER_DETECTED:
604 case USB_DEVICE_EVENT_RESET:
605 case USB_DEVICE_EVENT_DECONFIGURED:
610 case USB_DEVICE_EVENT_CONFIGURED:
613 ((USB_DEVICE_EVENT_DATA_CONFIGURED *)pData)->configurationValue;
620 USB_DEVICE_CDC_EventHandlerSet(0, &cdc_device_event_handler, 0);
627 case USB_DEVICE_EVENT_SUSPENDED:
629 case USB_DEVICE_EVENT_RESUMED:
638 USB_DEVICE_CDC_EVENT event,
void *pData)
642 case USB_DEVICE_CDC_EVENT_GET_LINE_CODING:
646 USB_DEVICE_ControlSend(
651 case USB_DEVICE_CDC_EVENT_SET_LINE_CODING:
655 USB_DEVICE_ControlReceive(
660 case USB_DEVICE_CDC_EVENT_SET_CONTROL_LINE_STATE:
667 case USB_DEVICE_CDC_EVENT_CONTROL_TRANSFER_DATA_RECEIVED:
669 USB_DEVICE_ControlStatus(
672 case USB_DEVICE_CDC_EVENT_CONTROL_TRANSFER_DATA_SENT:
674 case USB_DEVICE_CDC_EVENT_SEND_BREAK:
676 case USB_DEVICE_CDC_EVENT_READ_COMPLETE:
679 static_cast<USB_DEVICE_CDC_EVENT_DATA_READ_COMPLETE *
>(pData);
686 case USB_DEVICE_CDC_EVENT_WRITE_COMPLETE:
689 static_cast<USB_DEVICE_CDC_EVENT_DATA_WRITE_COMPLETE *
>(pData);
const USB_DEVICE_INIT usbDevInitData
Initialization structure in flash.
const DRV_USBFS_INIT drvUSBFSInit
Initialization structure in flash.
See OSMutexLock in os/OS.hxx.
Lightweight locking class for protecting small critical sections.
void flush()
flush all the data out of the buffer and reset the buffer.
size_t advance(size_t items)
Add a number of items to the buffer by advancing the writeIndex.
size_t space()
Return the number of items for which space is available.
size_t pending()
Return the number of items in the queue.
size_t consume(size_t items)
Remove a number of items from the buffer by advancing the readIndex.
void select_insert()
Add client to list of clients needing woken.
void signal_condition_from_isr()
Signal the wakeup condition from an ISR context.
Implements a smart buffer specifically designed for character device drivers.
size_t get(T *buf, size_t items)
remove a number of items from the buffer.
size_t put(const T *buf, size_t items)
Insert a number of items to the buffer.
size_t data_read_pointer(T **buf)
Get a reference to the current location in the buffer for read.
void destroy()
Destroy an existing DeviceBuffer instance.
static DeviceBuffer * create(size_t size, size_t level=0)
Create a DeviceBuffer instance.
const char * name
device name
Device driver for PIC32MX USB virtual serial port.
unsigned currentReadBuffer
Index of the buffer for current (userspace) reads.
unsigned isConfigured
true when we have a configured host.
ssize_t write(File *file, const void *buf, size_t count) OVERRIDE
Write to a file or device.
DeviceBuffer< uint8_t > * next_rx_buffer()
unsigned isEnabled
True when we have open fds.
void start_write_atomic()
Issues a write to the USB driver stack.
unsigned nextReadBufferFull
true if the opposite read buffer (the one after current) also has data.
DeviceBuffer< uint8_t > * rxBuffers[2]
Receive buffers.
unsigned irqVector
unused.
SYS_MODULE_OBJ usbDevObject0
Module pointer for USB middleware device.
void flush_buffers() override
Called by the serial driver after the last fd gets closed.
Pic32mxCdc()
Default constructor.
USB_CDC_LINE_CODING lineCodingData
Holds last set line coding data that came from the host.
unsigned txPendingBytes
Zero if no writes are pending, otherwise the number of bytes we sent with the pending write to the US...
unsigned needAttach
true wehen we need to execute an attach command on the usb task.
USB_DEVICE_CDC_TRANSFER_HANDLE readHandle
Handle for the current pending read.
SYS_MODULE_OBJ drvUSBObject
Module pointer for USB core device.
unsigned driverErrors
Counts internal error conditions that should not occur but we are hoping we can recover from them.
void device_tasks()
Background thread for doing USB device driver tasks.
USB_DEVICE_HANDLE deviceHandle
Equivalent of an fd for the USB core driver.
void event_hander_from_isr(USB_DEVICE_EVENT event, void *pData)
This function is called from the interrupt context of the USB driver to notify us about various event...
void interrupt_handler()
Handle an interrupt.
bool select(File *file, int mode) override
Device select method.
void start_read_atomic()
Issues a read to the USB driver stack.
USB_DEVICE_CDC_TRANSFER_HANDLE writeHandle
Handle for the current pending write.
ssize_t read(File *file, void *buf, size_t count) override
Read from a file or device.
unsigned rxPending
true when we have an outstanding read request with the USB driver.
DeviceBuffer< uint8_t > * current_rx_buffer()
void disable() override
Called by the serial driver when the last fd gets closed.
void tx_char() override
Unused.
void enable() override
Called by the serial driver when the first fd gets opened.
USB_DEVICE_CDC_EVENT_RESPONSE cdc_event_hander_from_isr(USB_DEVICE_CDC_EVENT event, void *pData)
This function is called from the interrupt context of the USB driver to notify us about various event...
Private data for a serial device.
DeviceBuffer< uint8_t > * txBuf
transmit buffer
#define FWRITE
Workaround for missing header defines on some newlib versions.
#define FREAD
Workaround for missing header defines on some newlib versions.
#define OVERRIDE
Function attribute for virtual functions declaring that this funciton is overriding a funciton that s...
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
#define DASSERT(x)
Debug assertion facility.
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Removes default copy-constructor and assignment added by C++.
int os_thread_create(os_thread_t *thread, const char *name, int priority, size_t stack_size, void *(*start_routine)(void *), void *arg)
Create a thread.