mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-19 09:42:11 +03:00
Merge of arduino-1.0.1. Work in progress...
This commit is contained in:
@ -23,12 +23,20 @@
|
||||
#if defined(USBCON)
|
||||
#ifdef CDC_ENABLED
|
||||
|
||||
void Reboot()
|
||||
#if (RAMEND < 1000)
|
||||
#define SERIAL_BUFFER_SIZE 16
|
||||
#else
|
||||
#define SERIAL_BUFFER_SIZE 64
|
||||
#endif
|
||||
|
||||
struct ring_buffer
|
||||
{
|
||||
USB.detach();
|
||||
cli();
|
||||
asm volatile("jmp 0x7800"); // jump to bootloader - DiskLoader takes up last 2 kB
|
||||
}
|
||||
unsigned char buffer[SERIAL_BUFFER_SIZE];
|
||||
volatile int head;
|
||||
volatile int tail;
|
||||
};
|
||||
|
||||
ring_buffer cdc_rx_buffer = { { 0 }, 0, 0};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -92,9 +100,28 @@ bool WEAK CDC_Setup(Setup& setup)
|
||||
|
||||
if (CDC_SET_CONTROL_LINE_STATE == r)
|
||||
{
|
||||
if (0 != _usbLineInfo.lineState && 1200 == _usbLineInfo.dwDTERate) // auto-reset is triggered when the port, already open at 1200 bps, is closed
|
||||
Reboot();
|
||||
_usbLineInfo.lineState = setup.wValueL;
|
||||
|
||||
// auto-reset into the bootloader is triggered when the port, already
|
||||
// open at 1200 bps, is closed. this is the signal to start the watchdog
|
||||
// with a relatively long period so it can finish housekeeping tasks
|
||||
// like servicing endpoints before the sketch ends
|
||||
if (1200 == _usbLineInfo.dwDTERate) {
|
||||
// We check DTR state to determine if host port is open (bit 0 of lineState).
|
||||
if ((_usbLineInfo.lineState & 0x01) == 0) {
|
||||
*(uint16_t *)0x0800 = 0x7777;
|
||||
wdt_enable(WDTO_120MS);
|
||||
} else {
|
||||
// Most OSs do some intermediate steps when configuring ports and DTR can
|
||||
// twiggle more than once before stabilizing.
|
||||
// To avoid spurious resets we set the watchdog to 250ms and eventually
|
||||
// cancel if DTR goes back high.
|
||||
|
||||
wdt_disable();
|
||||
wdt_reset();
|
||||
*(uint16_t *)0x0800 = 0x0;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -111,33 +138,49 @@ void Serial_::end(void)
|
||||
{
|
||||
}
|
||||
|
||||
int Serial_::available(void)
|
||||
void Serial_::accept(void)
|
||||
{
|
||||
u8 avail = USB_Available(CDC_RX);
|
||||
if (_serialPeek != -1)
|
||||
avail++;
|
||||
return avail;
|
||||
ring_buffer *buffer = &cdc_rx_buffer;
|
||||
int c = USB_Recv(CDC_RX);
|
||||
int i = (unsigned int)(buffer->head+1) % SERIAL_BUFFER_SIZE;
|
||||
|
||||
// if we should be storing the received character into the location
|
||||
// just before the tail (meaning that the head would advance to the
|
||||
// current location of the tail), we're about to overflow the buffer
|
||||
// and so we don't write the character or advance the head.
|
||||
if (i != buffer->tail) {
|
||||
buffer->buffer[buffer->head] = c;
|
||||
buffer->head = i;
|
||||
}
|
||||
}
|
||||
|
||||
int Serial_::available(void)
|
||||
{
|
||||
ring_buffer *buffer = &cdc_rx_buffer;
|
||||
return (unsigned int)(SERIAL_BUFFER_SIZE + buffer->head - buffer->tail) % SERIAL_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
// peek is nasty
|
||||
int Serial_::peek(void)
|
||||
{
|
||||
if (_serialPeek == -1)
|
||||
_serialPeek = read();
|
||||
return _serialPeek;
|
||||
ring_buffer *buffer = &cdc_rx_buffer;
|
||||
if (buffer->head == buffer->tail) {
|
||||
return -1;
|
||||
} else {
|
||||
return buffer->buffer[buffer->tail];
|
||||
}
|
||||
}
|
||||
|
||||
int Serial_::read(void)
|
||||
{
|
||||
int c;
|
||||
if (_serialPeek != -1)
|
||||
{
|
||||
c = _serialPeek;
|
||||
_serialPeek = -1;
|
||||
ring_buffer *buffer = &cdc_rx_buffer;
|
||||
// if the head isn't ahead of the tail, we don't have any characters
|
||||
if (buffer->head == buffer->tail) {
|
||||
return -1;
|
||||
} else {
|
||||
c = USB_Recv(CDC_RX);
|
||||
}
|
||||
return c;
|
||||
unsigned char c = buffer->buffer[buffer->tail];
|
||||
buffer->tail = (unsigned int)(buffer->tail + 1) % SERIAL_BUFFER_SIZE;
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
void Serial_::flush(void)
|
||||
@ -169,7 +212,22 @@ size_t Serial_::write(uint8_t c)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This operator is a convenient way for a sketch to check whether the
|
||||
// port has actually been configured and opened by the host (as opposed
|
||||
// to just being connected to the host). It can be used, for example, in
|
||||
// setup() before printing to ensure that an application on the host is
|
||||
// actually ready to receive and display the data.
|
||||
// We add a short delay before returning to fix a bug observed by Federico
|
||||
// where the port is configured (lineState != 0) but not quite opened.
|
||||
Serial_::operator bool() {
|
||||
bool result = false;
|
||||
if (_usbLineInfo.lineState > 0)
|
||||
result = true;
|
||||
delay(10);
|
||||
return result;
|
||||
}
|
||||
|
||||
Serial_ Serial;
|
||||
|
||||
#endif
|
||||
#endif /* if defined(USBCON) */
|
||||
#endif /* if defined(USBCON) */
|
||||
|
@ -144,7 +144,6 @@ u8 _hid_protocol = 1;
|
||||
u8 _hid_idle = 1;
|
||||
|
||||
#define WEAK __attribute__ ((weak))
|
||||
#define WEAK
|
||||
|
||||
int WEAK HID_GetInterface(u8* interfaceNum)
|
||||
{
|
||||
@ -202,7 +201,15 @@ bool WEAK HID_Setup(Setup& setup)
|
||||
//================================================================================
|
||||
// Mouse
|
||||
|
||||
Mouse_::Mouse_() : _buttons(0)
|
||||
Mouse_::Mouse_(void) : _buttons(0)
|
||||
{
|
||||
}
|
||||
|
||||
void Mouse_::begin(void)
|
||||
{
|
||||
}
|
||||
|
||||
void Mouse_::end(void)
|
||||
{
|
||||
}
|
||||
|
||||
@ -245,7 +252,7 @@ void Mouse_::release(uint8_t b)
|
||||
|
||||
bool Mouse_::isPressed(uint8_t b)
|
||||
{
|
||||
if (b & _buttons > 0)
|
||||
if ((b & _buttons) > 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@ -254,7 +261,15 @@ bool Mouse_::isPressed(uint8_t b)
|
||||
//================================================================================
|
||||
// Keyboard
|
||||
|
||||
Keyboard_::Keyboard_() : _keyMap(0)
|
||||
Keyboard_::Keyboard_(void)
|
||||
{
|
||||
}
|
||||
|
||||
void Keyboard_::begin(void)
|
||||
{
|
||||
}
|
||||
|
||||
void Keyboard_::end(void)
|
||||
{
|
||||
}
|
||||
|
||||
@ -263,11 +278,6 @@ void Keyboard_::sendReport(KeyReport* keys)
|
||||
HID_SendReport(2,keys,sizeof(KeyReport));
|
||||
}
|
||||
|
||||
void Keyboard_::setKeyMap(KeyMap* keyMap)
|
||||
{
|
||||
_keyMap = keyMap;
|
||||
}
|
||||
|
||||
extern
|
||||
const uint8_t _asciimap[128] PROGMEM;
|
||||
|
||||
@ -406,41 +416,105 @@ const uint8_t _asciimap[128] =
|
||||
};
|
||||
|
||||
uint8_t USBPutChar(uint8_t c);
|
||||
size_t Keyboard_::write(uint8_t c)
|
||||
|
||||
// press() adds the specified key (printing, non-printing, or modifier)
|
||||
// to the persistent key report and sends the report. Because of the way
|
||||
// USB HID works, the host acts like the key remains pressed until we
|
||||
// call release(), releaseAll(), or otherwise clear the report and resend.
|
||||
size_t Keyboard_::press(uint8_t k)
|
||||
{
|
||||
// Keydown
|
||||
{
|
||||
KeyReport keys = {0};
|
||||
if (_keyMap)
|
||||
_keyMap->charToKey(c,&keys);
|
||||
else
|
||||
{
|
||||
if (c >= 128) {
|
||||
setWriteError();
|
||||
return 0;
|
||||
}
|
||||
c = pgm_read_byte(_asciimap + c);
|
||||
if (!c) {
|
||||
setWriteError();
|
||||
return 0;
|
||||
}
|
||||
if (c & 0x80)
|
||||
{
|
||||
keys.modifiers |= KEY_MODIFIER_LEFT_SHIFT;
|
||||
c &= 0x7F;
|
||||
}
|
||||
keys.keys[0] = c;
|
||||
uint8_t i;
|
||||
if (k >= 136) { // it's a non-printing key (not a modifier)
|
||||
k = k - 136;
|
||||
} else if (k >= 128) { // it's a modifier key
|
||||
_keyReport.modifiers |= (1<<(k-128));
|
||||
k = 0;
|
||||
} else { // it's a printing key
|
||||
k = pgm_read_byte(_asciimap + k);
|
||||
if (!k) {
|
||||
setWriteError();
|
||||
return 0;
|
||||
}
|
||||
if (k & 0x80) { // it's a capital letter or other character reached with shift
|
||||
_keyReport.modifiers |= 0x02; // the left shift modifier
|
||||
k &= 0x7F;
|
||||
}
|
||||
sendReport(&keys);
|
||||
}
|
||||
// Keyup
|
||||
{
|
||||
KeyReport keys = {0};
|
||||
sendReport(&keys);
|
||||
|
||||
// Add k to the key report only if it's not already present
|
||||
// and if there is an empty slot.
|
||||
if (_keyReport.keys[0] != k && _keyReport.keys[1] != k &&
|
||||
_keyReport.keys[2] != k && _keyReport.keys[3] != k &&
|
||||
_keyReport.keys[4] != k && _keyReport.keys[5] != k) {
|
||||
|
||||
for (i=0; i<6; i++) {
|
||||
if (_keyReport.keys[i] == 0x00) {
|
||||
_keyReport.keys[i] = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == 6) {
|
||||
setWriteError();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
sendReport(&_keyReport);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// release() takes the specified key out of the persistent key report and
|
||||
// sends the report. This tells the OS the key is no longer pressed and that
|
||||
// it shouldn't be repeated any more.
|
||||
size_t Keyboard_::release(uint8_t k)
|
||||
{
|
||||
uint8_t i;
|
||||
if (k >= 136) { // it's a non-printing key (not a modifier)
|
||||
k = k - 136;
|
||||
} else if (k >= 128) { // it's a modifier key
|
||||
_keyReport.modifiers &= ~(1<<(k-128));
|
||||
k = 0;
|
||||
} else { // it's a printing key
|
||||
k = pgm_read_byte(_asciimap + k);
|
||||
if (!k) {
|
||||
return 0;
|
||||
}
|
||||
if (k & 0x80) { // it's a capital letter or other character reached with shift
|
||||
_keyReport.modifiers &= ~(0x02); // the left shift modifier
|
||||
k &= 0x7F;
|
||||
}
|
||||
}
|
||||
|
||||
// Test the key report to see if k is present. Clear it if it exists.
|
||||
// Check all positions in case the key is present more than once (which it shouldn't be)
|
||||
for (i=0; i<6; i++) {
|
||||
if (0 != k && _keyReport.keys[i] == k) {
|
||||
_keyReport.keys[i] = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
sendReport(&_keyReport);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Keyboard_::releaseAll(void)
|
||||
{
|
||||
_keyReport.keys[0] = 0;
|
||||
_keyReport.keys[1] = 0;
|
||||
_keyReport.keys[2] = 0;
|
||||
_keyReport.keys[3] = 0;
|
||||
_keyReport.keys[4] = 0;
|
||||
_keyReport.keys[5] = 0;
|
||||
_keyReport.modifiers = 0;
|
||||
sendReport(&_keyReport);
|
||||
}
|
||||
|
||||
size_t Keyboard_::write(uint8_t c)
|
||||
{
|
||||
uint8_t p = press(c); // Keydown
|
||||
uint8_t r = release(c); // Keyup
|
||||
return (p); // just return the result of press() since release() almost always returns 1
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* if defined(USBCON) */
|
@ -398,6 +398,10 @@ size_t HardwareSerial::write(uint8_t c)
|
||||
return 1;
|
||||
}
|
||||
|
||||
HardwareSerial::operator bool() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Preinstantiate Objects //////////////////////////////////////////////////////
|
||||
|
||||
#if defined(UBRRH) && defined(UBRRL)
|
||||
|
@ -57,6 +57,7 @@ class HardwareSerial : public Stream
|
||||
virtual void flush(void);
|
||||
virtual size_t write(uint8_t);
|
||||
using Print::write; // pull in write(str) and write(buf, size) from Print
|
||||
operator bool();
|
||||
};
|
||||
|
||||
#if defined(UBRRH) || defined(UBRR0H)
|
||||
|
@ -244,3 +244,27 @@ size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
|
||||
return index; // return number of characters, not including null terminator
|
||||
}
|
||||
|
||||
String Stream::readString()
|
||||
{
|
||||
String ret;
|
||||
int c = timedRead();
|
||||
while (c >= 0)
|
||||
{
|
||||
ret += (char)c;
|
||||
c = timedRead();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
String Stream::readStringUntil(char terminator)
|
||||
{
|
||||
String ret;
|
||||
int c = timedRead();
|
||||
while (c >= 0 && c != terminator)
|
||||
{
|
||||
ret += (char)c;
|
||||
c = timedRead();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -82,6 +82,8 @@ class Stream : public Print
|
||||
// returns the number of characters placed in the buffer (0 means no valid data found)
|
||||
|
||||
// Arduino String functions to be added here
|
||||
String readString();
|
||||
String readStringUntil(char terminator);
|
||||
|
||||
protected:
|
||||
long parseInt(char skipChar); // as above but the given skipChar is ignored
|
||||
|
@ -9,17 +9,17 @@
|
||||
//================================================================================
|
||||
// USB
|
||||
|
||||
class USB_
|
||||
class USBDevice_
|
||||
{
|
||||
public:
|
||||
USB_();
|
||||
USBDevice_();
|
||||
bool configured();
|
||||
|
||||
void attach();
|
||||
void detach(); // Serial port goes down too...
|
||||
void poll();
|
||||
};
|
||||
extern USB_ USB;
|
||||
extern USBDevice_ USBDevice;
|
||||
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
@ -27,15 +27,19 @@ extern USB_ USB;
|
||||
|
||||
class Serial_ : public Stream
|
||||
{
|
||||
private:
|
||||
ring_buffer *_cdc_rx_buffer;
|
||||
public:
|
||||
void begin(uint16_t baud_count);
|
||||
void end(void);
|
||||
|
||||
virtual int available(void);
|
||||
virtual void accept(void);
|
||||
virtual int peek(void);
|
||||
virtual int read(void);
|
||||
virtual void flush(void);
|
||||
virtual size_t write(uint8_t);
|
||||
operator bool();
|
||||
};
|
||||
extern Serial_ Serial;
|
||||
|
||||
@ -54,12 +58,14 @@ private:
|
||||
uint8_t _buttons;
|
||||
void buttons(uint8_t b);
|
||||
public:
|
||||
Mouse_();
|
||||
Mouse_(void);
|
||||
void begin(void);
|
||||
void end(void);
|
||||
void click(uint8_t b = MOUSE_LEFT);
|
||||
void move(signed char x, signed char y, signed char wheel = 0);
|
||||
void press(uint8_t b = MOUSE_LEFT); // press LEFT by default
|
||||
void release(uint8_t b = MOUSE_LEFT); // release LEFT by default
|
||||
bool isPressed(uint8_t b = MOUSE_ALL); // check all buttons by default
|
||||
bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default
|
||||
};
|
||||
extern Mouse_ Mouse;
|
||||
|
||||
@ -67,14 +73,42 @@ extern Mouse_ Mouse;
|
||||
//================================================================================
|
||||
// Keyboard
|
||||
|
||||
#define KEY_MODIFIER_LEFT_CTRL 0x01
|
||||
#define KEY_MODIFIER_LEFT_SHIFT 0x02
|
||||
#define KEY_MODIFIER_LEFT_ALT 0x04
|
||||
#define KEY_MODIFIER_LEFT_GUI 0x08
|
||||
#define KEY_MODIFIER_RIGHT_CTRL 0x010
|
||||
#define KEY_MODIFIER_RIGHT_SHIFT 0x020
|
||||
#define KEY_MODIFIER_RIGHT_ALT 0x040
|
||||
#define KEY_MODIFIER_RIGHT_GUI 0x080
|
||||
#define KEY_LEFT_CTRL 0x80
|
||||
#define KEY_LEFT_SHIFT 0x81
|
||||
#define KEY_LEFT_ALT 0x82
|
||||
#define KEY_LEFT_GUI 0x83
|
||||
#define KEY_RIGHT_CTRL 0x84
|
||||
#define KEY_RIGHT_SHIFT 0x85
|
||||
#define KEY_RIGHT_ALT 0x86
|
||||
#define KEY_RIGHT_GUI 0x87
|
||||
|
||||
#define KEY_UP_ARROW 0xDA
|
||||
#define KEY_DOWN_ARROW 0xD9
|
||||
#define KEY_LEFT_ARROW 0xD8
|
||||
#define KEY_RIGHT_ARROW 0xD7
|
||||
#define KEY_BACKSPACE 0xB2
|
||||
#define KEY_TAB 0xB3
|
||||
#define KEY_RETURN 0xB0
|
||||
#define KEY_ESC 0xB1
|
||||
#define KEY_INSERT 0xD1
|
||||
#define KEY_DELETE 0xD4
|
||||
#define KEY_PAGE_UP 0xD3
|
||||
#define KEY_PAGE_DOWN 0xD6
|
||||
#define KEY_HOME 0xD2
|
||||
#define KEY_END 0xD5
|
||||
#define KEY_CAPS_LOCK 0xC1
|
||||
#define KEY_F1 0xC2
|
||||
#define KEY_F2 0xC3
|
||||
#define KEY_F3 0xC4
|
||||
#define KEY_F4 0xC5
|
||||
#define KEY_F5 0xC6
|
||||
#define KEY_F6 0xC7
|
||||
#define KEY_F7 0xC8
|
||||
#define KEY_F8 0xC9
|
||||
#define KEY_F9 0xCA
|
||||
#define KEY_F10 0xCB
|
||||
#define KEY_F11 0xCC
|
||||
#define KEY_F12 0xCD
|
||||
|
||||
// Low level key report: up to 6 keys and shift, ctrl etc at once
|
||||
typedef struct
|
||||
@ -84,24 +118,19 @@ typedef struct
|
||||
uint8_t keys[6];
|
||||
} KeyReport;
|
||||
|
||||
// Map a character into a key report
|
||||
// Called from Print to map text to keycodes
|
||||
class KeyMap
|
||||
{
|
||||
public:
|
||||
virtual void charToKey(int c, KeyReport* keyReport) = 0;
|
||||
};
|
||||
|
||||
//
|
||||
class Keyboard_ : public Print
|
||||
{
|
||||
private:
|
||||
KeyMap* _keyMap;
|
||||
KeyReport _keyReport;
|
||||
void sendReport(KeyReport* keys);
|
||||
void setKeyMap(KeyMap* keyMap);
|
||||
public:
|
||||
Keyboard_();
|
||||
virtual size_t write(uint8_t);
|
||||
Keyboard_(void);
|
||||
void begin(void);
|
||||
void end(void);
|
||||
virtual size_t write(uint8_t k);
|
||||
virtual size_t press(uint8_t k);
|
||||
virtual size_t release(uint8_t k);
|
||||
virtual void releaseAll(void);
|
||||
};
|
||||
extern Keyboard_ Keyboard;
|
||||
|
||||
|
@ -51,16 +51,20 @@ const u16 STRING_LANGUAGE[2] = {
|
||||
|
||||
const u16 STRING_IPRODUCT[17] = {
|
||||
(3<<8) | (2+2*16),
|
||||
#if USB_PID == USB_PID_LEONARDO
|
||||
#if USB_PID == 0x8036
|
||||
'A','r','d','u','i','n','o',' ','L','e','o','n','a','r','d','o'
|
||||
#elif USB_PID == USB_PID_MICRO
|
||||
'A','r','d','u','i','n','o',' ','M','i','c','r','o',' ',' ',' '
|
||||
#else
|
||||
'U','S','B',' ','I','O',' ','B','o','a','r','d',' ',' ',' ',' '
|
||||
#endif
|
||||
};
|
||||
|
||||
const u16 STRING_IMANUFACTURER[12] = {
|
||||
(3<<8) | (2+2*11),
|
||||
#if USB_VID == 0x2341
|
||||
'A','r','d','u','i','n','o',' ','L','L','C'
|
||||
#else
|
||||
'U','n','k','n','o','w','n',' ',' ',' ',' '
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CDC_ENABLED
|
||||
@ -230,7 +234,7 @@ int USB_Recv(u8 ep, void* d, int len)
|
||||
n = len;
|
||||
u8* dst = (u8*)d;
|
||||
while (n--)
|
||||
*dst++ = USBD_Recv8();
|
||||
*dst++ = Recv8();
|
||||
if (len && !FifoByteCount()) // release empty buffer
|
||||
ReleaseRX();
|
||||
|
||||
@ -599,6 +603,8 @@ ISR(USB_GEN_vect)
|
||||
{
|
||||
#ifdef CDC_ENABLED
|
||||
USB_Flush(CDC_TX); // Send a tx frame if found
|
||||
while (USB_Available(CDC_RX)) // Handle received bytes (if any)
|
||||
Serial.accept();
|
||||
#endif
|
||||
|
||||
// check whether the one-shot period has elapsed. if so, turn off the LED
|
||||
@ -621,13 +627,13 @@ u8 USBConnected()
|
||||
//=======================================================================
|
||||
//=======================================================================
|
||||
|
||||
USB_ USB;
|
||||
USBDevice_ USBDevice;
|
||||
|
||||
USB_::USB_()
|
||||
USBDevice_::USBDevice_()
|
||||
{
|
||||
}
|
||||
|
||||
void USB_::attach()
|
||||
void USBDevice_::attach()
|
||||
{
|
||||
_usbConfiguration = 0;
|
||||
UHWCON = 0x01; // power internal reg
|
||||
@ -635,6 +641,12 @@ void USB_::attach()
|
||||
PLLCSR = 0x12; // Need 16 MHz xtal
|
||||
while (!(PLLCSR & (1<<PLOCK))) // wait for lock pll
|
||||
;
|
||||
|
||||
// Some tests on specific versions of macosx (10.7.3), reported some
|
||||
// strange behaviuors when the board is reset using the serial
|
||||
// port touch at 1200 bps. This delay fixes this behaviour.
|
||||
delay(1);
|
||||
|
||||
USBCON = ((1<<USBE)|(1<<OTGPADE)); // start USB clock
|
||||
UDIEN = (1<<EORSTE)|(1<<SOFE); // Enable interrupts for EOR (End of Reset) and SOF (start of frame)
|
||||
UDCON = 0; // enable attach resistor
|
||||
@ -642,19 +654,19 @@ void USB_::attach()
|
||||
TX_RX_LED_INIT;
|
||||
}
|
||||
|
||||
void USB_::detach()
|
||||
void USBDevice_::detach()
|
||||
{
|
||||
}
|
||||
|
||||
// Check for interrupts
|
||||
// TODO: VBUS detection
|
||||
bool USB_::configured()
|
||||
bool USBDevice_::configured()
|
||||
{
|
||||
return _usbConfiguration;
|
||||
}
|
||||
|
||||
void USB_::poll()
|
||||
void USBDevice_::poll()
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* if defined(USBCON) */
|
||||
#endif /* if defined(USBCON) */
|
||||
|
@ -60,8 +60,4 @@
|
||||
|
||||
#define IMANUFACTURER 1
|
||||
#define IPRODUCT 2
|
||||
#define USB_PID_LEONARDO 0x0034
|
||||
#define USB_PID_MICRO 0x0035
|
||||
#define USB_VID 0x2341 // arduino LLC vid
|
||||
#define USB_PID ARDUINO_MODEL_USB_PID
|
||||
|
||||
|
38
hardware/arduino/avr/cores/arduino/WInterrupts.c
Executable file → Normal file
38
hardware/arduino/avr/cores/arduino/WInterrupts.c
Executable file → Normal file
@ -47,7 +47,19 @@ void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
|
||||
// Enable the interrupt.
|
||||
|
||||
switch (interruptNum) {
|
||||
#if defined(EICRA) && defined(EICRB) && defined(EIMSK)
|
||||
#if defined(__AVR_ATmega32U4__)
|
||||
// I hate doing this, but the register assignment differs between the 1280/2560
|
||||
// and the 32U4. Since avrlib defines registers PCMSK1 and PCMSK2 that aren't
|
||||
// even present on the 32U4 this is the only way to distinguish between them.
|
||||
case 0:
|
||||
EICRA = (EICRA & ~((1<<ISC00) | (1<<ISC01))) | (mode << ISC00);
|
||||
EIMSK |= (1<<INT0);
|
||||
break;
|
||||
case 1:
|
||||
EICRA = (EICRA & ~((1<<ISC10) | (1<<ISC11))) | (mode << ISC10);
|
||||
EIMSK |= (1<<INT1);
|
||||
break;
|
||||
#elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
|
||||
case 2:
|
||||
EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
|
||||
EIMSK |= (1 << INT0);
|
||||
@ -80,7 +92,7 @@ void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
|
||||
EICRB = (EICRB & ~((1 << ISC70) | (1 << ISC71))) | (mode << ISC70);
|
||||
EIMSK |= (1 << INT7);
|
||||
break;
|
||||
#else
|
||||
#else
|
||||
case 0:
|
||||
#if defined(EICRA) && defined(ISC00) && defined(EIMSK)
|
||||
EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
|
||||
@ -134,7 +146,14 @@ void detachInterrupt(uint8_t interruptNum) {
|
||||
// to the number of the EIMSK bit to clear, as this isn't true on the
|
||||
// ATmega8. There, INT0 is 6 and INT1 is 7.)
|
||||
switch (interruptNum) {
|
||||
#if defined(EICRA) && defined(EICRB) && defined(EIMSK)
|
||||
#if defined(__AVR_ATmega32U4__)
|
||||
case 0:
|
||||
EIMSK &= ~(1<<INT0);
|
||||
break;
|
||||
case 1:
|
||||
EIMSK &= ~(1<<INT1);
|
||||
break;
|
||||
#elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
|
||||
case 2:
|
||||
EIMSK &= ~(1 << INT0);
|
||||
break;
|
||||
@ -196,7 +215,18 @@ void attachInterruptTwi(void (*userFunc)(void) ) {
|
||||
}
|
||||
*/
|
||||
|
||||
#if defined(EICRA) && defined(EICRB)
|
||||
#if defined(__AVR_ATmega32U4__)
|
||||
SIGNAL(INT0_vect) {
|
||||
if(intFunc[EXTERNAL_INT_0])
|
||||
intFunc[EXTERNAL_INT_0]();
|
||||
}
|
||||
|
||||
SIGNAL(INT1_vect) {
|
||||
if(intFunc[EXTERNAL_INT_1])
|
||||
intFunc[EXTERNAL_INT_1]();
|
||||
}
|
||||
|
||||
#elif defined(EICRA) && defined(EICRB)
|
||||
|
||||
SIGNAL(INT0_vect) {
|
||||
if(intFunc[EXTERNAL_INT_2])
|
||||
|
2
hardware/arduino/avr/cores/arduino/main.cpp
Executable file → Normal file
2
hardware/arduino/avr/cores/arduino/main.cpp
Executable file → Normal file
@ -5,7 +5,7 @@ int main(void)
|
||||
init();
|
||||
|
||||
#if defined(USBCON)
|
||||
USB.attach();
|
||||
USBDevice.attach();
|
||||
#endif
|
||||
|
||||
setup();
|
||||
|
11
hardware/arduino/avr/cores/arduino/wiring.c
Executable file → Normal file
11
hardware/arduino/avr/cores/arduino/wiring.c
Executable file → Normal file
@ -278,12 +278,21 @@ void init()
|
||||
sbi(TCCR3B, CS30);
|
||||
sbi(TCCR3A, WGM30); // put timer 3 in 8-bit phase correct pwm mode
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(TCCR4A) && defined(TCCR4B) && defined(TCCR4D) /* beginning of timer4 block for 32U4 and similar */
|
||||
sbi(TCCR4B, CS42); // set timer4 prescale factor to 64
|
||||
sbi(TCCR4B, CS41);
|
||||
sbi(TCCR4B, CS40);
|
||||
sbi(TCCR4D, WGM40); // put timer 4 in phase- and frequency-correct PWM mode
|
||||
sbi(TCCR4A, PWM4A); // enable PWM mode for comparator OCR4A
|
||||
sbi(TCCR4C, PWM4D); // enable PWM mode for comparator OCR4D
|
||||
#else /* beginning of timer4 block for ATMEGA1280 and ATMEGA2560 */
|
||||
#if defined(TCCR4B) && defined(CS41) && defined(WGM40)
|
||||
sbi(TCCR4B, CS41); // set timer 4 prescale factor to 64
|
||||
sbi(TCCR4B, CS40);
|
||||
sbi(TCCR4A, WGM40); // put timer 4 in 8-bit phase correct pwm mode
|
||||
#endif
|
||||
#endif /* end timer4 block for ATMEGA1280/2560 and similar */
|
||||
|
||||
#if defined(TCCR5B) && defined(CS51) && defined(WGM50)
|
||||
sbi(TCCR5B, CS51); // set timer 5 prescale factor to 64
|
||||
|
@ -206,14 +206,17 @@ void analogWrite(uint8_t pin, int val)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR4A) && defined(COM4A1)
|
||||
#if defined(TCCR4A)
|
||||
case TIMER4A:
|
||||
// connect pwm to pin on timer 4, channel A
|
||||
//connect pwm to pin on timer 4, channel A
|
||||
sbi(TCCR4A, COM4A1);
|
||||
OCR4A = val; // set pwm duty
|
||||
#if defined(COM4A0) // only used on 32U4
|
||||
cbi(TCCR4A, COM4A0);
|
||||
#endif
|
||||
OCR4A = val; // set pwm duty
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(TCCR4A) && defined(COM4B1)
|
||||
case TIMER4B:
|
||||
// connect pwm to pin on timer 4, channel B
|
||||
@ -230,14 +233,18 @@ void analogWrite(uint8_t pin, int val)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR4A) && defined(COM4D1)
|
||||
case TIMER4D:
|
||||
#if defined(TCCR4C) && defined(COM4D1)
|
||||
case TIMER4D:
|
||||
// connect pwm to pin on timer 4, channel D
|
||||
sbi(TCCR4A, COM4D1);
|
||||
OCR4D = val; // set pwm duty
|
||||
sbi(TCCR4C, COM4D1);
|
||||
#if defined(COM4D0) // only used on 32U4
|
||||
cbi(TCCR4C, COM4D0);
|
||||
#endif
|
||||
OCR4D = val; // set pwm duty
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(TCCR5A) && defined(COM5A1)
|
||||
case TIMER5A:
|
||||
// connect pwm to pin on timer 5, channel A
|
||||
@ -272,3 +279,4 @@ void analogWrite(uint8_t pin, int val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
8
hardware/arduino/avr/cores/arduino/wiring_digital.c
Executable file → Normal file
8
hardware/arduino/avr/cores/arduino/wiring_digital.c
Executable file → Normal file
@ -115,13 +115,17 @@ static void turnOffPWM(uint8_t timer)
|
||||
|
||||
#if defined(TCCR4A) && defined(COM4A1)
|
||||
case TIMER4A: cbi(TCCR4A, COM4A1); break;
|
||||
#endif
|
||||
#endif
|
||||
#if defined(TCCR4A) && defined(COM4B1)
|
||||
case TIMER4B: cbi(TCCR4A, COM4B1); break;
|
||||
#endif
|
||||
#if defined(TCCR4A) && defined(COM4C1)
|
||||
case TIMER4C: cbi(TCCR4A, COM4C1); break;
|
||||
#endif
|
||||
#endif
|
||||
#if defined(TCCR4C) && defined(COM4D1)
|
||||
case TIMER4D: cbi(TCCR4C, COM4D1); break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR5A)
|
||||
case TIMER5A: cbi(TCCR5A, COM5A1); break;
|
||||
case TIMER5B: cbi(TCCR5A, COM5B1); break;
|
||||
|
Reference in New Issue
Block a user