Skip to content

Expose CDC settings to sketch #3343

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 4 commits into from
Aug 14, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions hardware/arduino/avr/cores/arduino/CDC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "USBAPI.h"
#include <avr/wdt.h>
#include <util/atomic.h>

#if defined(USBCON)

Expand All @@ -31,6 +32,7 @@ typedef struct
} LineInfo;

static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 };
static volatile int32_t breakValue = -1;

#define WEAK __attribute__ ((weak))

Expand Down Expand Up @@ -75,6 +77,11 @@ bool CDC_Setup(USBSetup& setup)

if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
{
if (CDC_SEND_BREAK == r)
{
breakValue = ((uint16_t)setup.wValueH << 8) | setup.wValueL;
}

if (CDC_SET_LINE_CODING == r)
{
USB_RecvControl((void*)&_usbLineInfo,7);
Expand Down Expand Up @@ -156,6 +163,11 @@ int Serial_::read(void)
return USB_Recv(CDC_RX);
}

int Serial_::availableForWrite(void)
{
return USB_SendSpace(CDC_TX);
}

void Serial_::flush(void)
{
USB_Flush(CDC_TX);
Expand Down Expand Up @@ -205,6 +217,44 @@ Serial_::operator bool() {
return result;
}

unsigned long Serial_::baud() {
// Disable interrupts while reading a multi-byte value
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
return _usbLineInfo.dwDTERate;
}
}

uint8_t Serial_::stopbits() {
return _usbLineInfo.bCharFormat;
}

uint8_t Serial_::paritytype() {
return _usbLineInfo.bParityType;
}

uint8_t Serial_::numbits() {
return _usbLineInfo.bDataBits;
}

bool Serial_::dtr() {
return _usbLineInfo.lineState & 0x1;
}

bool Serial_::rts() {
return _usbLineInfo.lineState & 0x2;
}

int32_t Serial_::readBreak() {
int32_t ret;
// Disable IRQs while reading and clearing breakValue to make
// sure we don't overwrite a value just set by the ISR.
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
ret = breakValue;
breakValue = -1;
}
return ret;
}

Serial_ Serial;

#endif /* if defined(USBCON) */
3 changes: 1 addition & 2 deletions hardware/arduino/avr/cores/arduino/HardwareSerial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,7 @@ void HardwareSerial::begin(unsigned long baud, byte config)
void HardwareSerial::end()
{
// wait for transmission of outgoing data
while (_tx_buffer_head != _tx_buffer_tail)
;
flush();

cbi(*_ucsrb, RXEN0);
cbi(*_ucsrb, TXEN0);
Expand Down
42 changes: 42 additions & 0 deletions hardware/arduino/avr/cores/arduino/USBAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class Serial_ : public Stream
virtual int available(void);
virtual int peek(void);
virtual int read(void);
int availableForWrite(void);
virtual void flush(void);
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t*, size_t);
Expand All @@ -101,6 +102,46 @@ class Serial_ : public Stream
volatile uint8_t _rx_buffer_head;
volatile uint8_t _rx_buffer_tail;
unsigned char _rx_buffer[SERIAL_BUFFER_SIZE];

// This method allows processing "SEND_BREAK" requests sent by
// the USB host. Those requests indicate that the host wants to
// send a BREAK signal and are accompanied by a single uint16_t
// value, specifying the duration of the break. The value 0
// means to end any current break, while the value 0xffff means
// to start an indefinite break.
// readBreak() will return the value of the most recent break
// request, but will return it at most once, returning -1 when
// readBreak() is called again (until another break request is
// received, which is again returned once).
// This also mean that if two break requests are received
// without readBreak() being called in between, the value of the
// first request is lost.
// Note that the value returned is a long, so it can return
// 0-0xffff as well as -1.
int32_t readBreak();

// These return the settings specified by the USB host for the
// serial port. These aren't really used, but are offered here
// in case a sketch wants to act on these settings.
uint32_t baud();
uint8_t stopbits();
uint8_t paritytype();
uint8_t numbits();
bool dtr();
bool rts();
enum {
ONE_STOP_BIT = 0,
ONE_AND_HALF_STOP_BIT = 1,
TWO_STOP_BITS = 2,
};
enum {
NO_PARITY = 0,
ODD_PARITY = 1,
EVEN_PARITY = 2,
MARK_PARITY = 3,
SPACE_PARITY = 4,
};

};
extern Serial_ Serial;

Expand Down Expand Up @@ -148,6 +189,7 @@ int USB_SendControl(uint8_t flags, const void* d, int len);
int USB_RecvControl(void* d, int len);

uint8_t USB_Available(uint8_t ep);
uint8_t USB_SendSpace(uint8_t ep);
int USB_Send(uint8_t ep, const void* data, int len); // blocking
int USB_Recv(uint8_t ep, void* data, int len); // non-blocking
int USB_Recv(uint8_t ep); // non-blocking
Expand Down
1 change: 1 addition & 0 deletions hardware/arduino/avr/cores/arduino/USBCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
#define CDC_SET_LINE_CODING 0x20
#define CDC_GET_LINE_CODING 0x21
#define CDC_SET_CONTROL_LINE_STATE 0x22
#define CDC_SEND_BREAK 0x23

#define MSC_RESET 0xFF
#define MSC_GET_MAX_LUN 0xFE
Expand Down
24 changes: 24 additions & 0 deletions hardware/arduino/sam/cores/arduino/USB/CDC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,30 @@ Serial_::operator bool()
return result;
}

unsigned long Serial_::baud() {
return _usbLineInfo.dwDTERate;
}

uint8_t Serial_::stopbits() {
return _usbLineInfo.bCharFormat;
}

uint8_t Serial_::paritytype() {
return _usbLineInfo.bParityType;
}

uint8_t Serial_::numbits() {
return _usbLineInfo.bDataBits;
}

bool Serial_::dtr() {
return _usbLineInfo.lineState & 0x1;
}

bool Serial_::rts() {
return _usbLineInfo.lineState & 0x2;
}

Serial_ SerialUSB;

#endif
22 changes: 22 additions & 0 deletions hardware/arduino/sam/cores/arduino/USB/USBAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,28 @@ class Serial_ : public Stream
virtual size_t write(const uint8_t *buffer, size_t size);
using Print::write; // pull in write(str) from Print
operator bool();

// These return the settings specified by the USB host for the
// serial port. These aren't really used, but are offered here
// in case a sketch wants to act on these settings.
uint32_t baud();
uint8_t stopbits();
uint8_t paritytype();
uint8_t numbits();
bool dtr();
bool rts();
enum {
ONE_STOP_BIT = 0,
ONE_AND_HALF_STOP_BIT = 1,
TWO_STOP_BITS = 2,
};
enum {
NO_PARITY = 0,
ODD_PARITY = 1,
EVEN_PARITY = 2,
MARK_PARITY = 3,
SPACE_PARITY = 4,
};
};
extern Serial_ SerialUSB;

Expand Down