Skip to content
Merged
4 changes: 2 additions & 2 deletions cores/arduino/Stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,12 @@ class Stream : public Print
float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
// float version of parseInt

size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
virtual size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); }
// terminates if length characters have been read or timeout (see setTimeout)
// returns the number of characters placed in the buffer (0 means no valid data found)

size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
virtual size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); }
// terminates if length characters have been read, timeout, or if the terminator character detected
// returns the number of characters placed in the buffer (0 means no valid data found)
Expand Down
161 changes: 79 additions & 82 deletions cores/arduino/USBSerial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,126 +24,123 @@
#include "usbd_desc.h"
#include "wiring.h"

#define USB_TIMEOUT 50
/* USB Device Core handle declaration */
extern USBD_HandleTypeDef hUSBD_Device_CDC;
extern __IO uint32_t device_connection_status;
extern __IO uint32_t lineState;
extern __IO uint8_t UserTxBuffer[APP_TX_DATA_SIZE];
extern __IO uint8_t UserRxBuffer[APP_RX_DATA_SIZE];
extern __IO uint32_t UserTxBufPtrIn;
extern __IO uint32_t UserTxBufPtrOut;
extern __IO uint32_t UserRxBufPtrIn;
extern __IO uint32_t UserRxBufPtrOut;

USBSerial SerialUSB;
void serialEventUSB() __attribute__((weak));

void USBSerial::begin(void) {
CDC_init();
}

void USBSerial::begin(uint32_t /* baud_count */) {
// uart config is ignored in USB-CDC
begin();
}

void USBSerial::begin(uint32_t /* baud_count */, uint8_t /* config */) {
// uart config is ignored in USB-CDC
begin();
}

void USBSerial::end(void) {

USBD_LL_DeInit(&hUSBD_Device_CDC);
void USBSerial::end() {
CDC_deInit();
}

int USBSerial::availableForWrite(void)
int USBSerial::availableForWrite()
{
int ret_val;

/* UserTxBufPtrOut can be modified by TIM ISR, so in order to be sure that the */
/* value that we read is correct, we need to disable TIM Interrupt. */
CDC_disable_TIM_Interrupt();

if (UserTxBufPtrIn >= UserTxBufPtrOut) {
ret_val = (APP_TX_DATA_SIZE - 1 - UserTxBufPtrIn + UserTxBufPtrOut);
} else {
ret_val = (UserTxBufPtrOut - UserTxBufPtrIn - 1);
}

CDC_enable_TIM_Interrupt();

return ret_val;
// Just transmit queue size, available for write
return static_cast<int>(CDC_TransmitQueue_WriteSize(&TransmitQueue));
}

size_t USBSerial::write(uint8_t ch) {

/* UserTxBufPtrOut can be modified by TIM ISR, so in order to be sure that the */
/* value that we read is correct, we need to disable TIM Interrupt. */
CDC_disable_TIM_Interrupt();

if (((UserTxBufPtrIn + 1) % APP_TX_DATA_SIZE) == UserTxBufPtrOut) {
// Buffer full!!! Force a flush to not loose data and go on
CDC_flush();
}
UserTxBuffer[UserTxBufPtrIn] = ch;
UserTxBufPtrIn = ((UserTxBufPtrIn + 1) % APP_TX_DATA_SIZE);

CDC_enable_TIM_Interrupt();

return 1;
// Just write single-byte buffer.
return write(&ch, 1);
}

size_t USBSerial::write(const uint8_t *buffer, size_t size){
size_t i = 0;
for (i=0; i < size; i++) {
if (write(buffer[i]) != 1) {
break;
}
size_t rest = size;
while(rest > 0) {
// Determine buffer size available for write
auto portion = (size_t)CDC_TransmitQueue_WriteSize(&TransmitQueue);
// Truncate it to content size (if rest is greater)
if (rest < portion) {
portion = rest;
}
if (portion > 0) {
// Only if some space in the buffer exists.
// TS: Only main thread calls write and writeSize methods,
// it's thread-safe since IRQ does not affects
// TransmitQueue write position
CDC_TransmitQueue_Enqueue(&TransmitQueue, buffer, portion);
rest -= portion;
buffer += portion;
// After storing data, start transmitting process
CDC_continue_transmit();
}
}
return i;
return size;
}

int USBSerial::available(void) {
return ((APP_RX_DATA_SIZE + (UserRxBufPtrIn - UserRxBufPtrOut)) % APP_RX_DATA_SIZE);
// Just ReceiveQueue size, available for reading
return static_cast<int>(CDC_ReceiveQueue_ReadSize(&ReceiveQueue));
}

int USBSerial::read(void) {
if (UserRxBufPtrOut == UserRxBufPtrIn) {
return -1;
} else {
unsigned char c = UserRxBuffer[UserRxBufPtrOut];
UserRxBufPtrOut = ((UserRxBufPtrOut + 1) % APP_RX_DATA_SIZE);
// Dequeue only one char from queue
// TS: it safe, because only main thread affects ReceiveQueue->read pos
auto ch = CDC_ReceiveQueue_Dequeue(&ReceiveQueue);
// Resume receive process, if possible
CDC_resume_receive();
return ch;
}

size_t USBSerial::readBytes(char *buffer, size_t length) {
uint16_t read;
auto rest = static_cast<uint16_t>(length);
_startMillis = millis();
do {
read = CDC_ReceiveQueue_Read(&ReceiveQueue, reinterpret_cast<uint8_t*>(buffer), rest);
CDC_resume_receive();
return c;
}
rest -= read;
buffer += read;
if (rest == 0) return length;
} while(millis() - _startMillis < _timeout);
return length - rest;
}

size_t USBSerial::readBytesUntil(char terminator, char *buffer, size_t length) {
uint16_t read;
auto rest = static_cast<uint16_t>(length);
_startMillis = millis();
do {
bool found = CDC_ReceiveQueue_ReadUntil(&ReceiveQueue, static_cast<uint8_t>(terminator),
reinterpret_cast<uint8_t*>(buffer), rest, &read);
CDC_resume_receive();
rest -= read;
buffer += read;
if (found) {
return length - rest;
}
if (rest == 0) {
return length;
}
} while(millis() - _startMillis < _timeout);
return length - rest;
}

int USBSerial::peek(void)
{
if (UserRxBufPtrOut == UserRxBufPtrIn) {
return -1;
} else {
unsigned char c = UserRxBuffer[UserRxBufPtrOut];
return c;
}
// Peek one symbol, it can't change receive avaiablity
return CDC_ReceiveQueue_Peek(&ReceiveQueue);
}

void USBSerial::flush(void)
{
/* UserTxBufPtrOut can be modified by TIM ISR, so in order to be sure that the */
/* value that we read is correct, we need to disable TIM Interrupt. */
CDC_disable_TIM_Interrupt();
CDC_flush();
CDC_enable_TIM_Interrupt();
}

uint8_t USBSerial::pending(void) {
return 0;
}

uint8_t USBSerial::isConnected(void) {

if (device_connection_status == 1) {
return 1;
} else {
return 0;
}
// Wait for TransmitQueue read size becomes zero
// TS: safe, because it not be stopped while receive 0
while(CDC_TransmitQueue_ReadSize(&TransmitQueue) > 0) {}
}

uint32_t USBSerial::baud() {
Expand Down
8 changes: 3 additions & 5 deletions cores/arduino/USBSerial.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@
// Serial over CDC
class USBSerial : public Stream {
public:
USBSerial(void) {};

void begin(void);
void begin(uint32_t);
void begin(uint32_t, uint8_t);
void end(void);
Expand All @@ -37,6 +36,8 @@ class USBSerial : public Stream {
virtual int availableForWrite(void);
virtual int peek(void);
virtual int read(void);
virtual size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
virtual size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
virtual void flush(void);
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *buffer, size_t size);
Expand Down Expand Up @@ -64,9 +65,6 @@ class USBSerial : public Stream {
MARK_PARITY = 3,
SPACE_PARITY = 4,
};

uint8_t isConnected();
uint8_t pending();
};

extern USBSerial SerialUSB;
Expand Down
1 change: 0 additions & 1 deletion cores/arduino/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ extern "C"{
#include "timer.h"
#include "twi.h"
#include "uart.h"
#include "usbd_interface.h"

void init( void ) ;
#ifdef __cplusplus
Expand Down
4 changes: 0 additions & 4 deletions cores/arduino/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,6 @@ int main( void )
{
initVariant();

#if defined(USBCON)
usbd_interface_init();
#endif

setup();

for (;;)
Expand Down
5 changes: 5 additions & 0 deletions cores/arduino/stm32/hw_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
*/
#include "stm32_def.h"
#include "hw_config.h"
#include "usbd_if.h"

#ifdef __cplusplus
extern "C" {
Expand All @@ -54,6 +55,10 @@ void hw_config_init(void)

// Configure the system clock
SystemClock_Config();

#if defined (USBCON) && defined(USBD_USE_CDC)
USBD_CDC_init();
#endif
}
#ifdef __cplusplus
}
Expand Down
Loading