mirror of
https://github.com/arduino/Arduino.git
synced 2025-03-14 11:29:26 +01:00
Remove sam platform from IDE repo
Refer to https://github.com/arduino/ArduinoCore-sam for further development. All the tagged issues will be moved to the new repo PRs which only apply to SAM platform will need to be recreated instead
This commit is contained in:
parent
057419b08b
commit
2e98854703
@ -1,49 +0,0 @@
|
|||||||
|
|
||||||
arduino_due_x_dbg.name=Arduino Due (Programming Port)
|
|
||||||
arduino_due_x_dbg.vid.0=0x2341
|
|
||||||
arduino_due_x_dbg.pid.0=0x003d
|
|
||||||
arduino_due_x_dbg.vid.1=0x2A03
|
|
||||||
arduino_due_x_dbg.pid.1=0x003d
|
|
||||||
arduino_due_x_dbg.upload.tool=bossac
|
|
||||||
arduino_due_x_dbg.upload.protocol=sam-ba
|
|
||||||
arduino_due_x_dbg.upload.maximum_size=524288
|
|
||||||
arduino_due_x_dbg.upload.use_1200bps_touch=true
|
|
||||||
arduino_due_x_dbg.upload.wait_for_upload_port=false
|
|
||||||
arduino_due_x_dbg.upload.native_usb=false
|
|
||||||
arduino_due_x_dbg.build.mcu=cortex-m3
|
|
||||||
arduino_due_x_dbg.build.f_cpu=84000000L
|
|
||||||
arduino_due_x_dbg.build.usb_manufacturer="Arduino LLC"
|
|
||||||
arduino_due_x_dbg.build.usb_product="Arduino Due"
|
|
||||||
arduino_due_x_dbg.build.board=SAM_DUE
|
|
||||||
arduino_due_x_dbg.build.core=arduino
|
|
||||||
arduino_due_x_dbg.build.extra_flags=-D__SAM3X8E__ -mthumb {build.usb_flags}
|
|
||||||
arduino_due_x_dbg.build.ldscript=linker_scripts/gcc/flash.ld
|
|
||||||
arduino_due_x_dbg.build.variant=arduino_due_x
|
|
||||||
arduino_due_x_dbg.build.variant_system_lib=libsam_sam3x8e_gcc_rel.a
|
|
||||||
arduino_due_x_dbg.build.vid=0x2341
|
|
||||||
arduino_due_x_dbg.build.pid=0x003e
|
|
||||||
|
|
||||||
arduino_due_x.name=Arduino Due (Native USB Port)
|
|
||||||
arduino_due_x.vid.0=0x2341
|
|
||||||
arduino_due_x.pid.0=0x003e
|
|
||||||
arduino_due_x.vid.1=0x2A03
|
|
||||||
arduino_due_x.pid.1=0x003e
|
|
||||||
arduino_due_x.upload.tool=bossac
|
|
||||||
arduino_due_x.upload.protocol=sam-ba
|
|
||||||
arduino_due_x.upload.maximum_size=524288
|
|
||||||
arduino_due_x.upload.use_1200bps_touch=true
|
|
||||||
arduino_due_x.upload.wait_for_upload_port=true
|
|
||||||
arduino_due_x.upload.native_usb=true
|
|
||||||
arduino_due_x.build.mcu=cortex-m3
|
|
||||||
arduino_due_x.build.f_cpu=84000000L
|
|
||||||
arduino_due_x.build.usb_manufacturer="Arduino LLC"
|
|
||||||
arduino_due_x.build.usb_product="Arduino Due"
|
|
||||||
arduino_due_x.build.board=SAM_DUE
|
|
||||||
arduino_due_x.build.core=arduino
|
|
||||||
arduino_due_x.build.extra_flags=-D__SAM3X8E__ -mthumb {build.usb_flags}
|
|
||||||
arduino_due_x.build.ldscript=linker_scripts/gcc/flash.ld
|
|
||||||
arduino_due_x.build.variant=arduino_due_x
|
|
||||||
arduino_due_x.build.variant_system_lib=libsam_sam3x8e_gcc_rel.a
|
|
||||||
arduino_due_x.build.vid=0x2341
|
|
||||||
arduino_due_x.build.pid=0x003e
|
|
||||||
|
|
@ -1,224 +0,0 @@
|
|||||||
/*
|
|
||||||
Arduino.h - Main include file for the Arduino SDK
|
|
||||||
Copyright (c) 2005-2013 Arduino Team. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef Arduino_h
|
|
||||||
#define Arduino_h
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
// some libraries and sketches depend on this
|
|
||||||
// AVR stuff, assuming Arduino.h or WProgram.h
|
|
||||||
// automatically includes it...
|
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
#include <avr/interrupt.h>
|
|
||||||
|
|
||||||
#include "binary.h"
|
|
||||||
#include "itoa.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"{
|
|
||||||
#endif // __cplusplus
|
|
||||||
|
|
||||||
// Includes Atmel CMSIS
|
|
||||||
#include <chip.h>
|
|
||||||
|
|
||||||
#include "wiring_constants.h"
|
|
||||||
|
|
||||||
#define clockCyclesPerMicrosecond() ( SystemCoreClock / 1000000L )
|
|
||||||
#define clockCyclesToMicroseconds(a) ( ((a) * 1000L) / (SystemCoreClock / 1000L) )
|
|
||||||
#define microsecondsToClockCycles(a) ( (a) * (SystemCoreClock / 1000000L) )
|
|
||||||
|
|
||||||
void yield(void);
|
|
||||||
|
|
||||||
/* sketch */
|
|
||||||
extern void setup( void ) ;
|
|
||||||
extern void loop( void ) ;
|
|
||||||
|
|
||||||
//#define NOT_A_PIN 0 // defined in pio.h/EPioType
|
|
||||||
#define NOT_A_PORT 0
|
|
||||||
|
|
||||||
#define NOT_AN_INTERRUPT -1
|
|
||||||
|
|
||||||
typedef enum _EExt_Interrupts
|
|
||||||
{
|
|
||||||
EXTERNAL_INT_0=0,
|
|
||||||
EXTERNAL_INT_1=1,
|
|
||||||
EXTERNAL_INT_2=2,
|
|
||||||
EXTERNAL_INT_3=3,
|
|
||||||
EXTERNAL_INT_4=4,
|
|
||||||
EXTERNAL_INT_5=5,
|
|
||||||
EXTERNAL_INT_6=6,
|
|
||||||
EXTERNAL_INT_7=7,
|
|
||||||
EXTERNAL_NUM_INTERRUPTS
|
|
||||||
} EExt_Interrupts ;
|
|
||||||
|
|
||||||
typedef void (*voidFuncPtr)( void ) ;
|
|
||||||
|
|
||||||
/* Define attribute */
|
|
||||||
#if defined ( __CC_ARM ) /* Keil uVision 4 */
|
|
||||||
#define WEAK (__attribute__ ((weak)))
|
|
||||||
#elif defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */
|
|
||||||
#define WEAK __weak
|
|
||||||
#elif defined ( __GNUC__ ) /* GCC CS */
|
|
||||||
#define WEAK __attribute__ ((weak))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Definitions and types for pins */
|
|
||||||
typedef enum _EAnalogChannel
|
|
||||||
{
|
|
||||||
NO_ADC=-1,
|
|
||||||
ADC0=0,
|
|
||||||
ADC1,
|
|
||||||
ADC2,
|
|
||||||
ADC3,
|
|
||||||
ADC4,
|
|
||||||
ADC5,
|
|
||||||
ADC6,
|
|
||||||
ADC7,
|
|
||||||
ADC8,
|
|
||||||
ADC9,
|
|
||||||
ADC10,
|
|
||||||
ADC11,
|
|
||||||
ADC12,
|
|
||||||
ADC13,
|
|
||||||
ADC14,
|
|
||||||
ADC15,
|
|
||||||
DA0,
|
|
||||||
DA1
|
|
||||||
} EAnalogChannel ;
|
|
||||||
|
|
||||||
#define ADC_CHANNEL_NUMBER_NONE 0xffffffff
|
|
||||||
|
|
||||||
// Definitions for PWM channels
|
|
||||||
typedef enum _EPWMChannel
|
|
||||||
{
|
|
||||||
NOT_ON_PWM=-1,
|
|
||||||
PWM_CH0=0,
|
|
||||||
PWM_CH1,
|
|
||||||
PWM_CH2,
|
|
||||||
PWM_CH3,
|
|
||||||
PWM_CH4,
|
|
||||||
PWM_CH5,
|
|
||||||
PWM_CH6,
|
|
||||||
PWM_CH7
|
|
||||||
} EPWMChannel ;
|
|
||||||
|
|
||||||
// Definitions for TC channels
|
|
||||||
typedef enum _ETCChannel
|
|
||||||
{
|
|
||||||
NOT_ON_TIMER=-1,
|
|
||||||
TC0_CHA0=0,
|
|
||||||
TC0_CHB0,
|
|
||||||
TC0_CHA1,
|
|
||||||
TC0_CHB1,
|
|
||||||
TC0_CHA2,
|
|
||||||
TC0_CHB2,
|
|
||||||
TC1_CHA3,
|
|
||||||
TC1_CHB3,
|
|
||||||
TC1_CHA4,
|
|
||||||
TC1_CHB4,
|
|
||||||
TC1_CHA5,
|
|
||||||
TC1_CHB5,
|
|
||||||
TC2_CHA6,
|
|
||||||
TC2_CHB6,
|
|
||||||
TC2_CHA7,
|
|
||||||
TC2_CHB7,
|
|
||||||
TC2_CHA8,
|
|
||||||
TC2_CHB8
|
|
||||||
} ETCChannel ;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pin Attributes to be OR-ed
|
|
||||||
*/
|
|
||||||
#define PIN_ATTR_COMBO (1UL<<0)
|
|
||||||
#define PIN_ATTR_ANALOG (1UL<<1)
|
|
||||||
#define PIN_ATTR_DIGITAL (1UL<<2)
|
|
||||||
#define PIN_ATTR_PWM (1UL<<3)
|
|
||||||
#define PIN_ATTR_TIMER (1UL<<4)
|
|
||||||
|
|
||||||
#define PIN_STATUS_DIGITAL_INPUT_PULLUP (0x01)
|
|
||||||
#define PIN_STATUS_DIGITAL_INPUT (0x02)
|
|
||||||
#define PIN_STATUS_DIGITAL_OUTPUT (0x03)
|
|
||||||
#define PIN_STATUS_ANALOG (0x04)
|
|
||||||
#define PIN_STATUS_PWM (0x05)
|
|
||||||
#define PIN_STATUS_TIMER (0x06)
|
|
||||||
#define PIN_STATUS_SERIAL (0x07)
|
|
||||||
#define PIN_STATUS_DW_LOW (0x10)
|
|
||||||
#define PIN_STATUS_DW_HIGH (0x11)
|
|
||||||
|
|
||||||
/* Types used for the tables below */
|
|
||||||
typedef struct _PinDescription
|
|
||||||
{
|
|
||||||
Pio* pPort ;
|
|
||||||
uint32_t ulPin ;
|
|
||||||
uint32_t ulPeripheralId ;
|
|
||||||
EPioType ulPinType ;
|
|
||||||
uint32_t ulPinConfiguration ;
|
|
||||||
uint32_t ulPinAttribute ;
|
|
||||||
EAnalogChannel ulAnalogChannel ; /* Analog pin in the Arduino context (label on the board) */
|
|
||||||
EAnalogChannel ulADCChannelNumber ; /* ADC Channel number in the SAM device */
|
|
||||||
EPWMChannel ulPWMChannel ;
|
|
||||||
ETCChannel ulTCChannel ;
|
|
||||||
} PinDescription ;
|
|
||||||
|
|
||||||
extern uint8_t g_pinStatus[];
|
|
||||||
|
|
||||||
/* Pins table to be instanciated into variant.cpp */
|
|
||||||
extern const PinDescription g_APinDescription[] ;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} // extern "C"
|
|
||||||
|
|
||||||
#include "WCharacter.h"
|
|
||||||
#include "WString.h"
|
|
||||||
#include "Tone.h"
|
|
||||||
#include "WMath.h"
|
|
||||||
#include "HardwareSerial.h"
|
|
||||||
#include "wiring_pulse.h"
|
|
||||||
|
|
||||||
#endif // __cplusplus
|
|
||||||
|
|
||||||
// Include board variant
|
|
||||||
#include "variant.h"
|
|
||||||
|
|
||||||
#include "wiring.h"
|
|
||||||
#include "wiring_digital.h"
|
|
||||||
#include "wiring_analog.h"
|
|
||||||
#include "wiring_shift.h"
|
|
||||||
#include "WInterrupts.h"
|
|
||||||
|
|
||||||
#include "watchdog.h"
|
|
||||||
|
|
||||||
// USB Device
|
|
||||||
#ifndef USB_VID
|
|
||||||
#define USB_VID 0x2341 // arduino LLC vid
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef USB_PID
|
|
||||||
#define USB_PID 0x003E // arduino Due pid
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "USB/USBDesc.h"
|
|
||||||
#include "USB/USBCore.h"
|
|
||||||
#include "USB/USBAPI.h"
|
|
||||||
|
|
||||||
#endif // Arduino_h
|
|
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
Client.h - Base class that provides Client
|
|
||||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef client_h
|
|
||||||
#define client_h
|
|
||||||
#include "Print.h"
|
|
||||||
#include "Stream.h"
|
|
||||||
#include "IPAddress.h"
|
|
||||||
|
|
||||||
class Client : public Stream {
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual int connect(IPAddress ip, uint16_t port) =0;
|
|
||||||
virtual int connect(const char *host, uint16_t port) =0;
|
|
||||||
virtual size_t write(uint8_t) =0;
|
|
||||||
virtual size_t write(const uint8_t *buf, size_t size) =0;
|
|
||||||
virtual int available() = 0;
|
|
||||||
virtual int read() = 0;
|
|
||||||
virtual int read(uint8_t *buf, size_t size) = 0;
|
|
||||||
virtual int peek() = 0;
|
|
||||||
virtual void flush() = 0;
|
|
||||||
virtual void stop() = 0;
|
|
||||||
virtual uint8_t connected() = 0;
|
|
||||||
virtual operator bool() = 0;
|
|
||||||
protected:
|
|
||||||
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef HardwareSerial_h
|
|
||||||
#define HardwareSerial_h
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
#include "Stream.h"
|
|
||||||
|
|
||||||
class HardwareSerial : public Stream
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual void begin(unsigned long);
|
|
||||||
virtual void end();
|
|
||||||
virtual int available(void) = 0;
|
|
||||||
virtual int peek(void) = 0;
|
|
||||||
virtual int read(void) = 0;
|
|
||||||
virtual void flush(void) = 0;
|
|
||||||
virtual size_t write(uint8_t) = 0;
|
|
||||||
using Print::write; // pull in write(str) and write(buf, size) from Print
|
|
||||||
virtual operator bool() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern void serialEventRun(void) __attribute__((weak));
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,114 +0,0 @@
|
|||||||
/*
|
|
||||||
IPAddress.cpp - Base class that provides IPAddress
|
|
||||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <IPAddress.h>
|
|
||||||
|
|
||||||
IPAddress::IPAddress()
|
|
||||||
{
|
|
||||||
_address.dword = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet)
|
|
||||||
{
|
|
||||||
_address.bytes[0] = first_octet;
|
|
||||||
_address.bytes[1] = second_octet;
|
|
||||||
_address.bytes[2] = third_octet;
|
|
||||||
_address.bytes[3] = fourth_octet;
|
|
||||||
}
|
|
||||||
|
|
||||||
IPAddress::IPAddress(uint32_t address)
|
|
||||||
{
|
|
||||||
_address.dword = address;
|
|
||||||
}
|
|
||||||
|
|
||||||
IPAddress::IPAddress(const uint8_t *address)
|
|
||||||
{
|
|
||||||
memcpy(_address.bytes, address, sizeof(_address.bytes));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IPAddress::fromString(const char *address)
|
|
||||||
{
|
|
||||||
uint16_t acc = 0; // Accumulator
|
|
||||||
uint8_t dots = 0;
|
|
||||||
|
|
||||||
while (*address)
|
|
||||||
{
|
|
||||||
char c = *address++;
|
|
||||||
if (c >= '0' && c <= '9')
|
|
||||||
{
|
|
||||||
acc = acc * 10 + (c - '0');
|
|
||||||
if (acc > 255) {
|
|
||||||
// Value out of [0..255] range
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (c == '.')
|
|
||||||
{
|
|
||||||
if (dots == 3) {
|
|
||||||
// Too much dots (there must be 3 dots)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
_address.bytes[dots++] = acc;
|
|
||||||
acc = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Invalid char
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dots != 3) {
|
|
||||||
// Too few dots (there must be 3 dots)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
_address.bytes[3] = acc;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
IPAddress& IPAddress::operator=(const uint8_t *address)
|
|
||||||
{
|
|
||||||
memcpy(_address.bytes, address, sizeof(_address.bytes));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
IPAddress& IPAddress::operator=(uint32_t address)
|
|
||||||
{
|
|
||||||
_address.dword = address;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IPAddress::operator==(const uint8_t* addr) const
|
|
||||||
{
|
|
||||||
return memcmp(addr, _address.bytes, sizeof(_address.bytes)) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t IPAddress::printTo(Print& p) const
|
|
||||||
{
|
|
||||||
size_t n = 0;
|
|
||||||
for (int i =0; i < 3; i++)
|
|
||||||
{
|
|
||||||
n += p.print(_address.bytes[i], DEC);
|
|
||||||
n += p.print('.');
|
|
||||||
}
|
|
||||||
n += p.print(_address.bytes[3], DEC);
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
IPAddress.h - Base class that provides IPAddress
|
|
||||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef IPAddress_h
|
|
||||||
#define IPAddress_h
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "Printable.h"
|
|
||||||
#include "WString.h"
|
|
||||||
|
|
||||||
// A class to make it easier to handle and pass around IP addresses
|
|
||||||
|
|
||||||
class IPAddress : public Printable {
|
|
||||||
private:
|
|
||||||
union {
|
|
||||||
uint8_t bytes[4]; // IPv4 address
|
|
||||||
uint32_t dword;
|
|
||||||
} _address;
|
|
||||||
|
|
||||||
// Access the raw byte array containing the address. Because this returns a pointer
|
|
||||||
// to the internal structure rather than a copy of the address this function should only
|
|
||||||
// be used when you know that the usage of the returned uint8_t* will be transient and not
|
|
||||||
// stored.
|
|
||||||
uint8_t* raw_address() { return _address.bytes; };
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Constructors
|
|
||||||
IPAddress();
|
|
||||||
IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet);
|
|
||||||
IPAddress(uint32_t address);
|
|
||||||
IPAddress(const uint8_t *address);
|
|
||||||
|
|
||||||
bool fromString(const char *address);
|
|
||||||
bool fromString(const String &address) { return fromString(address.c_str()); }
|
|
||||||
|
|
||||||
// Overloaded cast operator to allow IPAddress objects to be used where a pointer
|
|
||||||
// to a four-byte uint8_t array is expected
|
|
||||||
operator uint32_t() const { return _address.dword; };
|
|
||||||
bool operator==(const IPAddress& addr) const { return _address.dword == addr._address.dword; };
|
|
||||||
bool operator==(const uint8_t* addr) const;
|
|
||||||
|
|
||||||
// Overloaded index operator to allow getting and setting individual octets of the address
|
|
||||||
uint8_t operator[](int index) const { return _address.bytes[index]; };
|
|
||||||
uint8_t& operator[](int index) { return _address.bytes[index]; };
|
|
||||||
|
|
||||||
// Overloaded copy operators to allow initialisation of IPAddress objects from other types
|
|
||||||
IPAddress& operator=(const uint8_t *address);
|
|
||||||
IPAddress& operator=(uint32_t address);
|
|
||||||
|
|
||||||
virtual size_t printTo(Print& p) const;
|
|
||||||
|
|
||||||
friend class EthernetClass;
|
|
||||||
friend class UDP;
|
|
||||||
friend class Client;
|
|
||||||
friend class Server;
|
|
||||||
friend class DhcpClass;
|
|
||||||
friend class DNSClient;
|
|
||||||
};
|
|
||||||
|
|
||||||
const IPAddress INADDR_NONE(0,0,0,0);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,258 +0,0 @@
|
|||||||
/*
|
|
||||||
Print.cpp - Base class that provides print() and println()
|
|
||||||
Copyright (c) 2008 David A. Mellis. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Modified 23 November 2006 by David A. Mellis
|
|
||||||
Modified 03 August 2015 by Chuck Todd
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include "Arduino.h"
|
|
||||||
|
|
||||||
#include "Print.h"
|
|
||||||
|
|
||||||
// Public Methods //////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
/* default implementation: may be overridden */
|
|
||||||
size_t Print::write(const uint8_t *buffer, size_t size)
|
|
||||||
{
|
|
||||||
size_t n = 0;
|
|
||||||
while (size--) {
|
|
||||||
if (write(*buffer++)) n++;
|
|
||||||
else break;
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::print(const __FlashStringHelper *ifsh)
|
|
||||||
{
|
|
||||||
return print(reinterpret_cast<const char *>(ifsh));
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::print(const String &s)
|
|
||||||
{
|
|
||||||
return write(s.c_str(), s.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::print(const char str[])
|
|
||||||
{
|
|
||||||
return write(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::print(char c)
|
|
||||||
{
|
|
||||||
return write(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::print(unsigned char b, int base)
|
|
||||||
{
|
|
||||||
return print((unsigned long) b, base);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::print(int n, int base)
|
|
||||||
{
|
|
||||||
return print((long) n, base);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::print(unsigned int n, int base)
|
|
||||||
{
|
|
||||||
return print((unsigned long) n, base);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::print(long n, int base)
|
|
||||||
{
|
|
||||||
if (base == 0) {
|
|
||||||
return write(n);
|
|
||||||
} else if (base == 10) {
|
|
||||||
if (n < 0) {
|
|
||||||
int t = print('-');
|
|
||||||
n = -n;
|
|
||||||
return printNumber(n, 10) + t;
|
|
||||||
}
|
|
||||||
return printNumber(n, 10);
|
|
||||||
} else {
|
|
||||||
return printNumber(n, base);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::print(unsigned long n, int base)
|
|
||||||
{
|
|
||||||
if (base == 0) return write(n);
|
|
||||||
else return printNumber(n, base);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::print(double n, int digits)
|
|
||||||
{
|
|
||||||
return printFloat(n, digits);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::println(const __FlashStringHelper *ifsh)
|
|
||||||
{
|
|
||||||
size_t n = print(ifsh);
|
|
||||||
n += println();
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::print(const Printable& x)
|
|
||||||
{
|
|
||||||
return x.printTo(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::println(void)
|
|
||||||
{
|
|
||||||
return write("\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::println(const String &s)
|
|
||||||
{
|
|
||||||
size_t n = print(s);
|
|
||||||
n += println();
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::println(const char c[])
|
|
||||||
{
|
|
||||||
size_t n = print(c);
|
|
||||||
n += println();
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::println(char c)
|
|
||||||
{
|
|
||||||
size_t n = print(c);
|
|
||||||
n += println();
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::println(unsigned char b, int base)
|
|
||||||
{
|
|
||||||
size_t n = print(b, base);
|
|
||||||
n += println();
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::println(int num, int base)
|
|
||||||
{
|
|
||||||
size_t n = print(num, base);
|
|
||||||
n += println();
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::println(unsigned int num, int base)
|
|
||||||
{
|
|
||||||
size_t n = print(num, base);
|
|
||||||
n += println();
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::println(long num, int base)
|
|
||||||
{
|
|
||||||
size_t n = print(num, base);
|
|
||||||
n += println();
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::println(unsigned long num, int base)
|
|
||||||
{
|
|
||||||
size_t n = print(num, base);
|
|
||||||
n += println();
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::println(double num, int digits)
|
|
||||||
{
|
|
||||||
size_t n = print(num, digits);
|
|
||||||
n += println();
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::println(const Printable& x)
|
|
||||||
{
|
|
||||||
size_t n = print(x);
|
|
||||||
n += println();
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private Methods /////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
size_t Print::printNumber(unsigned long n, uint8_t base)
|
|
||||||
{
|
|
||||||
char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
|
|
||||||
char *str = &buf[sizeof(buf) - 1];
|
|
||||||
|
|
||||||
*str = '\0';
|
|
||||||
|
|
||||||
// prevent crash if called with base == 1
|
|
||||||
if (base < 2) base = 10;
|
|
||||||
|
|
||||||
do {
|
|
||||||
char c = n % base;
|
|
||||||
n /= base;
|
|
||||||
|
|
||||||
*--str = c < 10 ? c + '0' : c + 'A' - 10;
|
|
||||||
} while(n);
|
|
||||||
|
|
||||||
return write(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::printFloat(double number, uint8_t digits)
|
|
||||||
{
|
|
||||||
size_t n = 0;
|
|
||||||
|
|
||||||
if (isnan(number)) return print("nan");
|
|
||||||
if (isinf(number)) return print("inf");
|
|
||||||
if (number > 4294967040.0) return print ("ovf"); // constant determined empirically
|
|
||||||
if (number <-4294967040.0) return print ("ovf"); // constant determined empirically
|
|
||||||
|
|
||||||
// Handle negative numbers
|
|
||||||
if (number < 0.0)
|
|
||||||
{
|
|
||||||
n += print('-');
|
|
||||||
number = -number;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Round correctly so that print(1.999, 2) prints as "2.00"
|
|
||||||
double rounding = 0.5;
|
|
||||||
for (uint8_t i=0; i<digits; ++i)
|
|
||||||
rounding /= 10.0;
|
|
||||||
|
|
||||||
number += rounding;
|
|
||||||
|
|
||||||
// Extract the integer part of the number and print it
|
|
||||||
unsigned long int_part = (unsigned long)number;
|
|
||||||
double remainder = number - (double)int_part;
|
|
||||||
n += print(int_part);
|
|
||||||
|
|
||||||
// Print the decimal point, but only if there are digits beyond
|
|
||||||
if (digits > 0) {
|
|
||||||
n += print('.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract digits from the remainder one at a time
|
|
||||||
while (digits-- > 0)
|
|
||||||
{
|
|
||||||
remainder *= 10.0;
|
|
||||||
unsigned int toPrint = (unsigned int)remainder;
|
|
||||||
n += print(toPrint);
|
|
||||||
remainder -= toPrint;
|
|
||||||
}
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
Print.h - Base class that provides print() and println()
|
|
||||||
Copyright (c) 2008 David A. Mellis. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef Print_h
|
|
||||||
#define Print_h
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <stdio.h> // for size_t
|
|
||||||
|
|
||||||
#include "WString.h"
|
|
||||||
#include "Printable.h"
|
|
||||||
|
|
||||||
#define DEC 10
|
|
||||||
#define HEX 16
|
|
||||||
#define OCT 8
|
|
||||||
#define BIN 2
|
|
||||||
|
|
||||||
class Print
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
int write_error;
|
|
||||||
size_t printNumber(unsigned long, uint8_t);
|
|
||||||
size_t printFloat(double, uint8_t);
|
|
||||||
protected:
|
|
||||||
void setWriteError(int err = 1) { write_error = err; }
|
|
||||||
public:
|
|
||||||
Print() : write_error(0) {}
|
|
||||||
|
|
||||||
int getWriteError() { return write_error; }
|
|
||||||
void clearWriteError() { setWriteError(0); }
|
|
||||||
|
|
||||||
virtual size_t write(uint8_t) = 0;
|
|
||||||
size_t write(const char *str) {
|
|
||||||
if (str == NULL) return 0;
|
|
||||||
return write((const uint8_t *)str, strlen(str));
|
|
||||||
}
|
|
||||||
virtual size_t write(const uint8_t *buffer, size_t size);
|
|
||||||
size_t write(const char *buffer, size_t size) {
|
|
||||||
return write((const uint8_t *)buffer, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t print(const __FlashStringHelper *);
|
|
||||||
size_t print(const String &);
|
|
||||||
size_t print(const char[]);
|
|
||||||
size_t print(char);
|
|
||||||
size_t print(unsigned char, int = DEC);
|
|
||||||
size_t print(int, int = DEC);
|
|
||||||
size_t print(unsigned int, int = DEC);
|
|
||||||
size_t print(long, int = DEC);
|
|
||||||
size_t print(unsigned long, int = DEC);
|
|
||||||
size_t print(double, int = 2);
|
|
||||||
size_t print(const Printable&);
|
|
||||||
|
|
||||||
size_t println(const __FlashStringHelper *);
|
|
||||||
size_t println(const String &s);
|
|
||||||
size_t println(const char[]);
|
|
||||||
size_t println(char);
|
|
||||||
size_t println(unsigned char, int = DEC);
|
|
||||||
size_t println(int, int = DEC);
|
|
||||||
size_t println(unsigned int, int = DEC);
|
|
||||||
size_t println(long, int = DEC);
|
|
||||||
size_t println(unsigned long, int = DEC);
|
|
||||||
size_t println(double, int = 2);
|
|
||||||
size_t println(const Printable&);
|
|
||||||
size_t println(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
Printable.h - Interface class that allows printing of complex types
|
|
||||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef Printable_h
|
|
||||||
#define Printable_h
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
class Print;
|
|
||||||
|
|
||||||
/** The Printable class provides a way for new classes to allow themselves to be printed.
|
|
||||||
By deriving from Printable and implementing the printTo method, it will then be possible
|
|
||||||
for users to print out instances of this class by passing them into the usual
|
|
||||||
Print::print and Print::println methods.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Printable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual size_t printTo(Print& p) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2012 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include "Reset.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
__attribute__ ((long_call, section (".ramfunc")))
|
|
||||||
void banzai() {
|
|
||||||
// Disable all interrupts
|
|
||||||
__disable_irq();
|
|
||||||
|
|
||||||
// Set bootflag to run SAM-BA bootloader at restart
|
|
||||||
const int EEFC_FCMD_CGPB = 0x0C;
|
|
||||||
const int EEFC_KEY = 0x5A;
|
|
||||||
while ((EFC0->EEFC_FSR & EEFC_FSR_FRDY) == 0);
|
|
||||||
EFC0->EEFC_FCR =
|
|
||||||
EEFC_FCR_FCMD(EEFC_FCMD_CGPB) |
|
|
||||||
EEFC_FCR_FARG(1) |
|
|
||||||
EEFC_FCR_FKEY(EEFC_KEY);
|
|
||||||
while ((EFC0->EEFC_FSR & EEFC_FSR_FRDY) == 0);
|
|
||||||
|
|
||||||
// From here flash memory is no more available.
|
|
||||||
|
|
||||||
// BANZAIIIIIII!!!
|
|
||||||
const int RSTC_KEY = 0xA5;
|
|
||||||
RSTC->RSTC_CR =
|
|
||||||
RSTC_CR_KEY(RSTC_KEY) |
|
|
||||||
RSTC_CR_PROCRST |
|
|
||||||
RSTC_CR_PERRST;
|
|
||||||
|
|
||||||
while (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ticks = -1;
|
|
||||||
|
|
||||||
void initiateReset(int _ticks) {
|
|
||||||
ticks = _ticks;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cancelReset() {
|
|
||||||
ticks = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tickReset() {
|
|
||||||
if (ticks == -1)
|
|
||||||
return;
|
|
||||||
ticks--;
|
|
||||||
if (ticks == 0)
|
|
||||||
banzai();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2012 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef RESET_H
|
|
||||||
#define RESET_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void initiateReset(int ms);
|
|
||||||
void tickReset();
|
|
||||||
void cancelReset();
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "RingBuffer.h"
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
RingBuffer::RingBuffer( void )
|
|
||||||
{
|
|
||||||
memset( (void *)_aucBuffer, 0, SERIAL_BUFFER_SIZE ) ;
|
|
||||||
_iHead=0 ;
|
|
||||||
_iTail=0 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RingBuffer::store_char( uint8_t c )
|
|
||||||
{
|
|
||||||
int i = (uint32_t)(_iHead + 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 != _iTail )
|
|
||||||
{
|
|
||||||
_aucBuffer[_iHead] = c ;
|
|
||||||
_iHead = i ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _RING_BUFFER_
|
|
||||||
#define _RING_BUFFER_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
// Define constants and variables for buffering incoming serial data. We're
|
|
||||||
// using a ring buffer, in which head is the index of the location
|
|
||||||
// to which to write the next incoming character and tail is the index of the
|
|
||||||
// location from which to read.
|
|
||||||
#define SERIAL_BUFFER_SIZE 128
|
|
||||||
|
|
||||||
class RingBuffer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
volatile uint8_t _aucBuffer[SERIAL_BUFFER_SIZE] ;
|
|
||||||
volatile int _iHead ;
|
|
||||||
volatile int _iTail ;
|
|
||||||
|
|
||||||
public:
|
|
||||||
RingBuffer( void ) ;
|
|
||||||
void store_char( uint8_t c ) ;
|
|
||||||
} ;
|
|
||||||
|
|
||||||
#endif /* _RING_BUFFER_ */
|
|
@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
Server.h - Base class that provides Server
|
|
||||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef server_h
|
|
||||||
#define server_h
|
|
||||||
|
|
||||||
#include "Print.h"
|
|
||||||
|
|
||||||
class Server : public Print {
|
|
||||||
public:
|
|
||||||
virtual void begin() =0;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,319 +0,0 @@
|
|||||||
/*
|
|
||||||
Stream.cpp - adds parsing methods to Stream class
|
|
||||||
Copyright (c) 2008 David A. Mellis. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Created July 2011
|
|
||||||
parsing functions based on TextFinder library by Michael Margolis
|
|
||||||
|
|
||||||
findMulti/findUntil routines written by Jim Leonard/Xuth
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
|
||||||
#include "Stream.h"
|
|
||||||
|
|
||||||
#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
|
|
||||||
|
|
||||||
// private method to read stream with timeout
|
|
||||||
int Stream::timedRead()
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
_startMillis = millis();
|
|
||||||
do {
|
|
||||||
c = read();
|
|
||||||
if (c >= 0) return c;
|
|
||||||
} while(millis() - _startMillis < _timeout);
|
|
||||||
return -1; // -1 indicates timeout
|
|
||||||
}
|
|
||||||
|
|
||||||
// private method to peek stream with timeout
|
|
||||||
int Stream::timedPeek()
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
_startMillis = millis();
|
|
||||||
do {
|
|
||||||
c = peek();
|
|
||||||
if (c >= 0) return c;
|
|
||||||
} while(millis() - _startMillis < _timeout);
|
|
||||||
return -1; // -1 indicates timeout
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns peek of the next digit in the stream or -1 if timeout
|
|
||||||
// discards non-numeric characters
|
|
||||||
int Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal )
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
while (1) {
|
|
||||||
c = timedPeek();
|
|
||||||
|
|
||||||
if( c < 0 ||
|
|
||||||
c == '-' ||
|
|
||||||
(c >= '0' && c <= '9') ||
|
|
||||||
(detectDecimal && c == '.')) return c;
|
|
||||||
|
|
||||||
switch( lookahead ){
|
|
||||||
case SKIP_NONE: return -1; // Fail code.
|
|
||||||
case SKIP_WHITESPACE:
|
|
||||||
switch( c ){
|
|
||||||
case ' ':
|
|
||||||
case '\t':
|
|
||||||
case '\r':
|
|
||||||
case '\n': break;
|
|
||||||
default: return -1; // Fail code.
|
|
||||||
}
|
|
||||||
case SKIP_ALL:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
read(); // discard non-numeric
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public Methods
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
|
|
||||||
{
|
|
||||||
_timeout = timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
// find returns true if the target string is found
|
|
||||||
bool Stream::find(char *target)
|
|
||||||
{
|
|
||||||
return findUntil(target, strlen(target), NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// reads data from the stream until the target string of given length is found
|
|
||||||
// returns true if target string is found, false if timed out
|
|
||||||
bool Stream::find(char *target, size_t length)
|
|
||||||
{
|
|
||||||
return findUntil(target, length, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// as find but search ends if the terminator string is found
|
|
||||||
bool Stream::findUntil(char *target, char *terminator)
|
|
||||||
{
|
|
||||||
return findUntil(target, strlen(target), terminator, strlen(terminator));
|
|
||||||
}
|
|
||||||
|
|
||||||
// reads data from the stream until the target string of the given length is found
|
|
||||||
// search terminated if the terminator string is found
|
|
||||||
// returns true if target string is found, false if terminated or timed out
|
|
||||||
bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen)
|
|
||||||
{
|
|
||||||
if (terminator == NULL) {
|
|
||||||
MultiTarget t[1] = {{target, targetLen, 0}};
|
|
||||||
return findMulti(t, 1) == 0 ? true : false;
|
|
||||||
} else {
|
|
||||||
MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}};
|
|
||||||
return findMulti(t, 2) == 0 ? true : false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns the first valid (long) integer value from the current position.
|
|
||||||
// lookahead determines how parseInt looks ahead in the stream.
|
|
||||||
// See LookaheadMode enumeration at the top of the file.
|
|
||||||
// Lookahead is terminated by the first character that is not a valid part of an integer.
|
|
||||||
// Once parsing commences, 'ignore' will be skipped in the stream.
|
|
||||||
long Stream::parseInt(LookaheadMode lookahead, char ignore)
|
|
||||||
{
|
|
||||||
bool isNegative = false;
|
|
||||||
long value = 0;
|
|
||||||
int c;
|
|
||||||
|
|
||||||
c = peekNextDigit(lookahead, false);
|
|
||||||
// ignore non numeric leading characters
|
|
||||||
if(c < 0)
|
|
||||||
return 0; // zero returned if timeout
|
|
||||||
|
|
||||||
do{
|
|
||||||
if(c == ignore)
|
|
||||||
; // ignore this character
|
|
||||||
else if(c == '-')
|
|
||||||
isNegative = true;
|
|
||||||
else if(c >= '0' && c <= '9') // is c a digit?
|
|
||||||
value = value * 10 + c - '0';
|
|
||||||
read(); // consume the character we got with peek
|
|
||||||
c = timedPeek();
|
|
||||||
}
|
|
||||||
while( (c >= '0' && c <= '9') || c == ignore );
|
|
||||||
|
|
||||||
if(isNegative)
|
|
||||||
value = -value;
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// as parseInt but returns a floating point value
|
|
||||||
float Stream::parseFloat(LookaheadMode lookahead, char ignore)
|
|
||||||
{
|
|
||||||
bool isNegative = false;
|
|
||||||
bool isFraction = false;
|
|
||||||
long value = 0;
|
|
||||||
int c;
|
|
||||||
float fraction = 1.0;
|
|
||||||
|
|
||||||
c = peekNextDigit(lookahead, true);
|
|
||||||
// ignore non numeric leading characters
|
|
||||||
if(c < 0)
|
|
||||||
return 0; // zero returned if timeout
|
|
||||||
|
|
||||||
do{
|
|
||||||
if(c == ignore)
|
|
||||||
; // ignore
|
|
||||||
else if(c == '-')
|
|
||||||
isNegative = true;
|
|
||||||
else if (c == '.')
|
|
||||||
isFraction = true;
|
|
||||||
else if(c >= '0' && c <= '9') { // is c a digit?
|
|
||||||
value = value * 10 + c - '0';
|
|
||||||
if(isFraction)
|
|
||||||
fraction *= 0.1;
|
|
||||||
}
|
|
||||||
read(); // consume the character we got with peek
|
|
||||||
c = timedPeek();
|
|
||||||
}
|
|
||||||
while( (c >= '0' && c <= '9') || (c == '.' && !isFraction) || c == ignore );
|
|
||||||
|
|
||||||
if(isNegative)
|
|
||||||
value = -value;
|
|
||||||
if(isFraction)
|
|
||||||
return value * fraction;
|
|
||||||
else
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// read characters from stream into buffer
|
|
||||||
// terminates if length characters have been read, or timeout (see setTimeout)
|
|
||||||
// returns the number of characters placed in the buffer
|
|
||||||
// the buffer is NOT null terminated.
|
|
||||||
//
|
|
||||||
size_t Stream::readBytes(char *buffer, size_t length)
|
|
||||||
{
|
|
||||||
size_t count = 0;
|
|
||||||
while (count < length) {
|
|
||||||
int c = timedRead();
|
|
||||||
if (c < 0) break;
|
|
||||||
*buffer++ = (char)c;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// as readBytes with terminator character
|
|
||||||
// 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)
|
|
||||||
|
|
||||||
size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
|
|
||||||
{
|
|
||||||
if (length < 1) return 0;
|
|
||||||
size_t index = 0;
|
|
||||||
while (index < length) {
|
|
||||||
int c = timedRead();
|
|
||||||
if (c < 0 || c == terminator) break;
|
|
||||||
*buffer++ = (char)c;
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) {
|
|
||||||
// any zero length target string automatically matches and would make
|
|
||||||
// a mess of the rest of the algorithm.
|
|
||||||
for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
|
|
||||||
if (t->len <= 0)
|
|
||||||
return t - targets;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
int c = timedRead();
|
|
||||||
if (c < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
|
|
||||||
// the simple case is if we match, deal with that first.
|
|
||||||
if (c == t->str[t->index]) {
|
|
||||||
if (++t->index == t->len)
|
|
||||||
return t - targets;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if not we need to walk back and see if we could have matched further
|
|
||||||
// down the stream (ie '1112' doesn't match the first position in '11112'
|
|
||||||
// but it will match the second position so we can't just reset the current
|
|
||||||
// index to 0 when we find a mismatch.
|
|
||||||
if (t->index == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int origIndex = t->index;
|
|
||||||
do {
|
|
||||||
--t->index;
|
|
||||||
// first check if current char works against the new current index
|
|
||||||
if (c != t->str[t->index])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// if it's the only char then we're good, nothing more to check
|
|
||||||
if (t->index == 0) {
|
|
||||||
t->index++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise we need to check the rest of the found string
|
|
||||||
int diff = origIndex - t->index;
|
|
||||||
size_t i;
|
|
||||||
for (i = 0; i < t->index; ++i) {
|
|
||||||
if (t->str[i] != t->str[i + diff])
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we successfully got through the previous loop then our current
|
|
||||||
// index is good.
|
|
||||||
if (i == t->index) {
|
|
||||||
t->index++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise we just try the next index
|
|
||||||
} while (t->index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// unreachable
|
|
||||||
return -1;
|
|
||||||
}
|
|
@ -1,130 +0,0 @@
|
|||||||
/*
|
|
||||||
Stream.h - base class for character-based streams.
|
|
||||||
Copyright (c) 2010 David A. Mellis. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
parsing functions based on TextFinder library by Michael Margolis
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef Stream_h
|
|
||||||
#define Stream_h
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include "Print.h"
|
|
||||||
|
|
||||||
// compatability macros for testing
|
|
||||||
/*
|
|
||||||
#define getInt() parseInt()
|
|
||||||
#define getInt(ignore) parseInt(ignore)
|
|
||||||
#define getFloat() parseFloat()
|
|
||||||
#define getFloat(ignore) parseFloat(ignore)
|
|
||||||
#define getString( pre_string, post_string, buffer, length)
|
|
||||||
readBytesBetween( pre_string, terminator, buffer, length)
|
|
||||||
*/
|
|
||||||
|
|
||||||
// This enumeration provides the lookahead options for parseInt(), parseFloat()
|
|
||||||
// The rules set out here are used until either the first valid character is found
|
|
||||||
// or a time out occurs due to lack of input.
|
|
||||||
enum LookaheadMode{
|
|
||||||
SKIP_ALL, // All invalid characters are ignored.
|
|
||||||
SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid.
|
|
||||||
SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped.
|
|
||||||
};
|
|
||||||
|
|
||||||
#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field
|
|
||||||
|
|
||||||
class Stream : public Print
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read
|
|
||||||
unsigned long _startMillis; // used for timeout measurement
|
|
||||||
int timedRead(); // private method to read stream with timeout
|
|
||||||
int timedPeek(); // private method to peek stream with timeout
|
|
||||||
int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual int available() = 0;
|
|
||||||
virtual int read() = 0;
|
|
||||||
virtual int peek() = 0;
|
|
||||||
virtual void flush() = 0;
|
|
||||||
|
|
||||||
Stream() {_timeout=1000;}
|
|
||||||
|
|
||||||
// parsing methods
|
|
||||||
|
|
||||||
void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
|
|
||||||
unsigned long getTimeout(void) { return _timeout; }
|
|
||||||
|
|
||||||
bool find(char *target); // reads data from the stream until the target string is found
|
|
||||||
bool find(uint8_t *target) { return find ((char *)target); }
|
|
||||||
// returns true if target string is found, false if timed out (see setTimeout)
|
|
||||||
|
|
||||||
bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found
|
|
||||||
bool find(uint8_t *target, size_t length) { return find ((char *)target, length); }
|
|
||||||
// returns true if target string is found, false if timed out
|
|
||||||
|
|
||||||
bool find(char target) { return find (&target, 1); }
|
|
||||||
|
|
||||||
bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found
|
|
||||||
bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); }
|
|
||||||
|
|
||||||
bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found
|
|
||||||
bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); }
|
|
||||||
|
|
||||||
long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
|
|
||||||
// returns the first valid (long) integer value from the current position.
|
|
||||||
// lookahead determines how parseInt looks ahead in the stream.
|
|
||||||
// See LookaheadMode enumeration at the top of the file.
|
|
||||||
// Lookahead is terminated by the first character that is not a valid part of an integer.
|
|
||||||
// Once parsing commences, 'ignore' will be skipped in the stream.
|
|
||||||
|
|
||||||
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
|
|
||||||
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
|
|
||||||
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)
|
|
||||||
|
|
||||||
// Arduino String functions to be added here
|
|
||||||
String readString();
|
|
||||||
String readStringUntil(char terminator);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); }
|
|
||||||
float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); }
|
|
||||||
// These overload exists for compatibility with any class that has derived
|
|
||||||
// Stream and used parseFloat/Int with a custom ignore character. To keep
|
|
||||||
// the public API simple, these overload remains protected.
|
|
||||||
|
|
||||||
struct MultiTarget {
|
|
||||||
const char *str; // string you're searching for
|
|
||||||
size_t len; // length of string you're searching for
|
|
||||||
size_t index; // index used by the search routine.
|
|
||||||
};
|
|
||||||
|
|
||||||
// This allows you to search for an arbitrary number of strings.
|
|
||||||
// Returns index of the target that is found first or -1 if timeout occurs.
|
|
||||||
int findMulti(struct MultiTarget *targets, int tCount);
|
|
||||||
};
|
|
||||||
|
|
||||||
#undef NO_IGNORE_CHAR
|
|
||||||
#endif
|
|
@ -1,616 +0,0 @@
|
|||||||
/* Tone.cpp
|
|
||||||
|
|
||||||
A Tone Generator Library
|
|
||||||
|
|
||||||
Written by Brett Hagman
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Version Modified By Date Comments
|
|
||||||
------- ----------- -------- --------
|
|
||||||
0001 B Hagman 09/08/02 Initial coding
|
|
||||||
0002 B Hagman 09/08/18 Multiple pins
|
|
||||||
0003 B Hagman 09/08/18 Moved initialization from constructor to begin()
|
|
||||||
0004 B Hagman 09/09/26 Fixed problems with ATmega8
|
|
||||||
0005 B Hagman 09/11/23 Scanned prescalars for best fit on 8 bit timers
|
|
||||||
09/11/25 Changed pin toggle method to XOR
|
|
||||||
09/11/25 Fixed timer0 from being excluded
|
|
||||||
0006 D Mellis 09/12/29 Replaced objects with functions
|
|
||||||
0007 M Sproul 10/08/29 Changed #ifdefs from cpu to register
|
|
||||||
0008 S Kanemoto 12/06/22 Fixed for Leonardo by @maris_HY
|
|
||||||
*************************************************/
|
|
||||||
|
|
||||||
#include <avr/interrupt.h>
|
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
#include "Arduino.h"
|
|
||||||
#include "pins_arduino.h"
|
|
||||||
|
|
||||||
#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega128__)
|
|
||||||
#define TCCR2A TCCR2
|
|
||||||
#define TCCR2B TCCR2
|
|
||||||
#define COM2A1 COM21
|
|
||||||
#define COM2A0 COM20
|
|
||||||
#define OCR2A OCR2
|
|
||||||
#define TIMSK2 TIMSK
|
|
||||||
#define OCIE2A OCIE2
|
|
||||||
#define TIMER2_COMPA_vect TIMER2_COMP_vect
|
|
||||||
#define TIMSK1 TIMSK
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// timerx_toggle_count:
|
|
||||||
// > 0 - duration specified
|
|
||||||
// = 0 - stopped
|
|
||||||
// < 0 - infinitely (until stop() method called, or new play() called)
|
|
||||||
|
|
||||||
#if !defined(__AVR_ATmega8__)
|
|
||||||
volatile long timer0_toggle_count;
|
|
||||||
volatile uint8_t *timer0_pin_port;
|
|
||||||
volatile uint8_t timer0_pin_mask;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
volatile long timer1_toggle_count;
|
|
||||||
volatile uint8_t *timer1_pin_port;
|
|
||||||
volatile uint8_t timer1_pin_mask;
|
|
||||||
volatile long timer2_toggle_count;
|
|
||||||
volatile uint8_t *timer2_pin_port;
|
|
||||||
volatile uint8_t timer2_pin_mask;
|
|
||||||
|
|
||||||
#if defined(TIMSK3)
|
|
||||||
volatile long timer3_toggle_count;
|
|
||||||
volatile uint8_t *timer3_pin_port;
|
|
||||||
volatile uint8_t timer3_pin_mask;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(TIMSK4)
|
|
||||||
volatile long timer4_toggle_count;
|
|
||||||
volatile uint8_t *timer4_pin_port;
|
|
||||||
volatile uint8_t timer4_pin_mask;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(TIMSK5)
|
|
||||||
volatile long timer5_toggle_count;
|
|
||||||
volatile uint8_t *timer5_pin_port;
|
|
||||||
volatile uint8_t timer5_pin_mask;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
|
||||||
|
|
||||||
#define AVAILABLE_TONE_PINS 1
|
|
||||||
#define USE_TIMER2
|
|
||||||
|
|
||||||
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 3, 4, 5, 1, 0 */ };
|
|
||||||
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255, 255, 255, 255 */ };
|
|
||||||
|
|
||||||
#elif defined(__AVR_ATmega8__)
|
|
||||||
|
|
||||||
#define AVAILABLE_TONE_PINS 1
|
|
||||||
#define USE_TIMER2
|
|
||||||
|
|
||||||
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 1 */ };
|
|
||||||
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255 */ };
|
|
||||||
|
|
||||||
#elif defined(__AVR_ATmega32U4__)
|
|
||||||
|
|
||||||
#define AVAILABLE_TONE_PINS 1
|
|
||||||
#define USE_TIMER3
|
|
||||||
|
|
||||||
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 3 /*, 1 */ };
|
|
||||||
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255 */ };
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define AVAILABLE_TONE_PINS 1
|
|
||||||
#define USE_TIMER2
|
|
||||||
|
|
||||||
// Leave timer 0 to last.
|
|
||||||
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 1, 0 */ };
|
|
||||||
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255 */ };
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int8_t toneBegin(uint8_t _pin)
|
|
||||||
{
|
|
||||||
int8_t _timer = -1;
|
|
||||||
|
|
||||||
// if we're already using the pin, the timer should be configured.
|
|
||||||
for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
|
|
||||||
if (tone_pins[i] == _pin) {
|
|
||||||
return pgm_read_byte(tone_pin_to_timer_PGM + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// search for an unused timer.
|
|
||||||
for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
|
|
||||||
if (tone_pins[i] == 255) {
|
|
||||||
tone_pins[i] = _pin;
|
|
||||||
_timer = pgm_read_byte(tone_pin_to_timer_PGM + i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_timer != -1)
|
|
||||||
{
|
|
||||||
// Set timer specific stuff
|
|
||||||
// All timers in CTC mode
|
|
||||||
// 8 bit timers will require changing prescalar values,
|
|
||||||
// whereas 16 bit timers are set to either ck/1 or ck/64 prescalar
|
|
||||||
switch (_timer)
|
|
||||||
{
|
|
||||||
#if defined(TCCR0A) && defined(TCCR0B)
|
|
||||||
case 0:
|
|
||||||
// 8 bit timer
|
|
||||||
TCCR0A = 0;
|
|
||||||
TCCR0B = 0;
|
|
||||||
bitWrite(TCCR0A, WGM01, 1);
|
|
||||||
bitWrite(TCCR0B, CS00, 1);
|
|
||||||
timer0_pin_port = portOutputRegister(digitalPinToPort(_pin));
|
|
||||||
timer0_pin_mask = digitalPinToBitMask(_pin);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(TCCR1A) && defined(TCCR1B) && defined(WGM12)
|
|
||||||
case 1:
|
|
||||||
// 16 bit timer
|
|
||||||
TCCR1A = 0;
|
|
||||||
TCCR1B = 0;
|
|
||||||
bitWrite(TCCR1B, WGM12, 1);
|
|
||||||
bitWrite(TCCR1B, CS10, 1);
|
|
||||||
timer1_pin_port = portOutputRegister(digitalPinToPort(_pin));
|
|
||||||
timer1_pin_mask = digitalPinToBitMask(_pin);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(TCCR2A) && defined(TCCR2B)
|
|
||||||
case 2:
|
|
||||||
// 8 bit timer
|
|
||||||
TCCR2A = 0;
|
|
||||||
TCCR2B = 0;
|
|
||||||
bitWrite(TCCR2A, WGM21, 1);
|
|
||||||
bitWrite(TCCR2B, CS20, 1);
|
|
||||||
timer2_pin_port = portOutputRegister(digitalPinToPort(_pin));
|
|
||||||
timer2_pin_mask = digitalPinToBitMask(_pin);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(TCCR3A) && defined(TCCR3B) && defined(TIMSK3)
|
|
||||||
case 3:
|
|
||||||
// 16 bit timer
|
|
||||||
TCCR3A = 0;
|
|
||||||
TCCR3B = 0;
|
|
||||||
bitWrite(TCCR3B, WGM32, 1);
|
|
||||||
bitWrite(TCCR3B, CS30, 1);
|
|
||||||
timer3_pin_port = portOutputRegister(digitalPinToPort(_pin));
|
|
||||||
timer3_pin_mask = digitalPinToBitMask(_pin);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(TCCR4A) && defined(TCCR4B) && defined(TIMSK4)
|
|
||||||
case 4:
|
|
||||||
// 16 bit timer
|
|
||||||
TCCR4A = 0;
|
|
||||||
TCCR4B = 0;
|
|
||||||
#if defined(WGM42)
|
|
||||||
bitWrite(TCCR4B, WGM42, 1);
|
|
||||||
#elif defined(CS43)
|
|
||||||
#warning this may not be correct
|
|
||||||
// atmega32u4
|
|
||||||
bitWrite(TCCR4B, CS43, 1);
|
|
||||||
#endif
|
|
||||||
bitWrite(TCCR4B, CS40, 1);
|
|
||||||
timer4_pin_port = portOutputRegister(digitalPinToPort(_pin));
|
|
||||||
timer4_pin_mask = digitalPinToBitMask(_pin);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(TCCR5A) && defined(TCCR5B) && defined(TIMSK5)
|
|
||||||
case 5:
|
|
||||||
// 16 bit timer
|
|
||||||
TCCR5A = 0;
|
|
||||||
TCCR5B = 0;
|
|
||||||
bitWrite(TCCR5B, WGM52, 1);
|
|
||||||
bitWrite(TCCR5B, CS50, 1);
|
|
||||||
timer5_pin_port = portOutputRegister(digitalPinToPort(_pin));
|
|
||||||
timer5_pin_mask = digitalPinToBitMask(_pin);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return _timer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// frequency (in hertz) and duration (in milliseconds).
|
|
||||||
|
|
||||||
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration)
|
|
||||||
{
|
|
||||||
uint8_t prescalarbits = 0b001;
|
|
||||||
long toggle_count = 0;
|
|
||||||
uint32_t ocr = 0;
|
|
||||||
int8_t _timer;
|
|
||||||
|
|
||||||
_timer = toneBegin(_pin);
|
|
||||||
|
|
||||||
if (_timer >= 0)
|
|
||||||
{
|
|
||||||
// Set the pinMode as OUTPUT
|
|
||||||
pinMode(_pin, OUTPUT);
|
|
||||||
|
|
||||||
// if we are using an 8 bit timer, scan through prescalars to find the best fit
|
|
||||||
if (_timer == 0 || _timer == 2)
|
|
||||||
{
|
|
||||||
ocr = F_CPU / frequency / 2 - 1;
|
|
||||||
prescalarbits = 0b001; // ck/1: same for both timers
|
|
||||||
if (ocr > 255)
|
|
||||||
{
|
|
||||||
ocr = F_CPU / frequency / 2 / 8 - 1;
|
|
||||||
prescalarbits = 0b010; // ck/8: same for both timers
|
|
||||||
|
|
||||||
if (_timer == 2 && ocr > 255)
|
|
||||||
{
|
|
||||||
ocr = F_CPU / frequency / 2 / 32 - 1;
|
|
||||||
prescalarbits = 0b011;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ocr > 255)
|
|
||||||
{
|
|
||||||
ocr = F_CPU / frequency / 2 / 64 - 1;
|
|
||||||
prescalarbits = _timer == 0 ? 0b011 : 0b100;
|
|
||||||
|
|
||||||
if (_timer == 2 && ocr > 255)
|
|
||||||
{
|
|
||||||
ocr = F_CPU / frequency / 2 / 128 - 1;
|
|
||||||
prescalarbits = 0b101;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ocr > 255)
|
|
||||||
{
|
|
||||||
ocr = F_CPU / frequency / 2 / 256 - 1;
|
|
||||||
prescalarbits = _timer == 0 ? 0b100 : 0b110;
|
|
||||||
if (ocr > 255)
|
|
||||||
{
|
|
||||||
// can't do any better than /1024
|
|
||||||
ocr = F_CPU / frequency / 2 / 1024 - 1;
|
|
||||||
prescalarbits = _timer == 0 ? 0b101 : 0b111;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(TCCR0B)
|
|
||||||
if (_timer == 0)
|
|
||||||
{
|
|
||||||
TCCR0B = prescalarbits;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
#if defined(TCCR2B)
|
|
||||||
{
|
|
||||||
TCCR2B = prescalarbits;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
// dummy place holder to make the above ifdefs work
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// two choices for the 16 bit timers: ck/1 or ck/64
|
|
||||||
ocr = F_CPU / frequency / 2 - 1;
|
|
||||||
|
|
||||||
prescalarbits = 0b001;
|
|
||||||
if (ocr > 0xffff)
|
|
||||||
{
|
|
||||||
ocr = F_CPU / frequency / 2 / 64 - 1;
|
|
||||||
prescalarbits = 0b011;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_timer == 1)
|
|
||||||
{
|
|
||||||
#if defined(TCCR1B)
|
|
||||||
TCCR1B = (TCCR1B & 0b11111000) | prescalarbits;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#if defined(TCCR3B)
|
|
||||||
else if (_timer == 3)
|
|
||||||
TCCR3B = (TCCR3B & 0b11111000) | prescalarbits;
|
|
||||||
#endif
|
|
||||||
#if defined(TCCR4B)
|
|
||||||
else if (_timer == 4)
|
|
||||||
TCCR4B = (TCCR4B & 0b11111000) | prescalarbits;
|
|
||||||
#endif
|
|
||||||
#if defined(TCCR5B)
|
|
||||||
else if (_timer == 5)
|
|
||||||
TCCR5B = (TCCR5B & 0b11111000) | prescalarbits;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate the toggle count
|
|
||||||
if (duration > 0)
|
|
||||||
{
|
|
||||||
toggle_count = 2 * frequency * duration / 1000;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
toggle_count = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the OCR for the given timer,
|
|
||||||
// set the toggle count,
|
|
||||||
// then turn on the interrupts
|
|
||||||
switch (_timer)
|
|
||||||
{
|
|
||||||
|
|
||||||
#if defined(OCR0A) && defined(TIMSK0) && defined(OCIE0A)
|
|
||||||
case 0:
|
|
||||||
OCR0A = ocr;
|
|
||||||
timer0_toggle_count = toggle_count;
|
|
||||||
bitWrite(TIMSK0, OCIE0A, 1);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
#if defined(OCR1A) && defined(TIMSK1) && defined(OCIE1A)
|
|
||||||
OCR1A = ocr;
|
|
||||||
timer1_toggle_count = toggle_count;
|
|
||||||
bitWrite(TIMSK1, OCIE1A, 1);
|
|
||||||
#elif defined(OCR1A) && defined(TIMSK) && defined(OCIE1A)
|
|
||||||
// this combination is for at least the ATmega32
|
|
||||||
OCR1A = ocr;
|
|
||||||
timer1_toggle_count = toggle_count;
|
|
||||||
bitWrite(TIMSK, OCIE1A, 1);
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
|
|
||||||
#if defined(OCR2A) && defined(TIMSK2) && defined(OCIE2A)
|
|
||||||
case 2:
|
|
||||||
OCR2A = ocr;
|
|
||||||
timer2_toggle_count = toggle_count;
|
|
||||||
bitWrite(TIMSK2, OCIE2A, 1);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(TIMSK3)
|
|
||||||
case 3:
|
|
||||||
OCR3A = ocr;
|
|
||||||
timer3_toggle_count = toggle_count;
|
|
||||||
bitWrite(TIMSK3, OCIE3A, 1);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(TIMSK4)
|
|
||||||
case 4:
|
|
||||||
OCR4A = ocr;
|
|
||||||
timer4_toggle_count = toggle_count;
|
|
||||||
bitWrite(TIMSK4, OCIE4A, 1);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(OCR5A) && defined(TIMSK5) && defined(OCIE5A)
|
|
||||||
case 5:
|
|
||||||
OCR5A = ocr;
|
|
||||||
timer5_toggle_count = toggle_count;
|
|
||||||
bitWrite(TIMSK5, OCIE5A, 1);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// XXX: this function only works properly for timer 2 (the only one we use
|
|
||||||
// currently). for the others, it should end the tone, but won't restore
|
|
||||||
// proper PWM functionality for the timer.
|
|
||||||
void disableTimer(uint8_t _timer)
|
|
||||||
{
|
|
||||||
switch (_timer)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
#if defined(TIMSK0)
|
|
||||||
TIMSK0 = 0;
|
|
||||||
#elif defined(TIMSK)
|
|
||||||
TIMSK = 0; // atmega32
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
|
|
||||||
#if defined(TIMSK1) && defined(OCIE1A)
|
|
||||||
case 1:
|
|
||||||
bitWrite(TIMSK1, OCIE1A, 0);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
#if defined(TIMSK2) && defined(OCIE2A)
|
|
||||||
bitWrite(TIMSK2, OCIE2A, 0); // disable interrupt
|
|
||||||
#endif
|
|
||||||
#if defined(TCCR2A) && defined(WGM20)
|
|
||||||
TCCR2A = (1 << WGM20);
|
|
||||||
#endif
|
|
||||||
#if defined(TCCR2B) && defined(CS22)
|
|
||||||
TCCR2B = (TCCR2B & 0b11111000) | (1 << CS22);
|
|
||||||
#endif
|
|
||||||
#if defined(OCR2A)
|
|
||||||
OCR2A = 0;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
|
|
||||||
#if defined(TIMSK3)
|
|
||||||
case 3:
|
|
||||||
TIMSK3 = 0;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(TIMSK4)
|
|
||||||
case 4:
|
|
||||||
TIMSK4 = 0;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(TIMSK5)
|
|
||||||
case 5:
|
|
||||||
TIMSK5 = 0;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void noTone(uint8_t _pin)
|
|
||||||
{
|
|
||||||
int8_t _timer = -1;
|
|
||||||
|
|
||||||
for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
|
|
||||||
if (tone_pins[i] == _pin) {
|
|
||||||
_timer = pgm_read_byte(tone_pin_to_timer_PGM + i);
|
|
||||||
tone_pins[i] = 255;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
disableTimer(_timer);
|
|
||||||
|
|
||||||
digitalWrite(_pin, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_TIMER0
|
|
||||||
ISR(TIMER0_COMPA_vect)
|
|
||||||
{
|
|
||||||
if (timer0_toggle_count != 0)
|
|
||||||
{
|
|
||||||
// toggle the pin
|
|
||||||
*timer0_pin_port ^= timer0_pin_mask;
|
|
||||||
|
|
||||||
if (timer0_toggle_count > 0)
|
|
||||||
timer0_toggle_count--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
disableTimer(0);
|
|
||||||
*timer0_pin_port &= ~(timer0_pin_mask); // keep pin low after stop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_TIMER1
|
|
||||||
ISR(TIMER1_COMPA_vect)
|
|
||||||
{
|
|
||||||
if (timer1_toggle_count != 0)
|
|
||||||
{
|
|
||||||
// toggle the pin
|
|
||||||
*timer1_pin_port ^= timer1_pin_mask;
|
|
||||||
|
|
||||||
if (timer1_toggle_count > 0)
|
|
||||||
timer1_toggle_count--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
disableTimer(1);
|
|
||||||
*timer1_pin_port &= ~(timer1_pin_mask); // keep pin low after stop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_TIMER2
|
|
||||||
ISR(TIMER2_COMPA_vect)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (timer2_toggle_count != 0)
|
|
||||||
{
|
|
||||||
// toggle the pin
|
|
||||||
*timer2_pin_port ^= timer2_pin_mask;
|
|
||||||
|
|
||||||
if (timer2_toggle_count > 0)
|
|
||||||
timer2_toggle_count--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// need to call noTone() so that the tone_pins[] entry is reset, so the
|
|
||||||
// timer gets initialized next time we call tone().
|
|
||||||
// XXX: this assumes timer 2 is always the first one used.
|
|
||||||
noTone(tone_pins[0]);
|
|
||||||
// disableTimer(2);
|
|
||||||
// *timer2_pin_port &= ~(timer2_pin_mask); // keep pin low after stop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_TIMER3
|
|
||||||
ISR(TIMER3_COMPA_vect)
|
|
||||||
{
|
|
||||||
if (timer3_toggle_count != 0)
|
|
||||||
{
|
|
||||||
// toggle the pin
|
|
||||||
*timer3_pin_port ^= timer3_pin_mask;
|
|
||||||
|
|
||||||
if (timer3_toggle_count > 0)
|
|
||||||
timer3_toggle_count--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
disableTimer(3);
|
|
||||||
*timer3_pin_port &= ~(timer3_pin_mask); // keep pin low after stop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_TIMER4
|
|
||||||
ISR(TIMER4_COMPA_vect)
|
|
||||||
{
|
|
||||||
if (timer4_toggle_count != 0)
|
|
||||||
{
|
|
||||||
// toggle the pin
|
|
||||||
*timer4_pin_port ^= timer4_pin_mask;
|
|
||||||
|
|
||||||
if (timer4_toggle_count > 0)
|
|
||||||
timer4_toggle_count--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
disableTimer(4);
|
|
||||||
*timer4_pin_port &= ~(timer4_pin_mask); // keep pin low after stop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_TIMER5
|
|
||||||
ISR(TIMER5_COMPA_vect)
|
|
||||||
{
|
|
||||||
if (timer5_toggle_count != 0)
|
|
||||||
{
|
|
||||||
// toggle the pin
|
|
||||||
*timer5_pin_port ^= timer5_pin_mask;
|
|
||||||
|
|
||||||
if (timer5_toggle_count > 0)
|
|
||||||
timer5_toggle_count--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
disableTimer(5);
|
|
||||||
*timer5_pin_port &= ~(timer5_pin_mask); // keep pin low after stop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _WIRING_TONE_
|
|
||||||
#define _WIRING_TONE_
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _WIRING_TONE_ */
|
|
@ -1,198 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "UARTClass.h"
|
|
||||||
|
|
||||||
// Constructors ////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
UARTClass::UARTClass( Uart *pUart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer *pRx_buffer, RingBuffer *pTx_buffer )
|
|
||||||
{
|
|
||||||
_rx_buffer = pRx_buffer;
|
|
||||||
_tx_buffer = pTx_buffer;
|
|
||||||
|
|
||||||
_pUart=pUart;
|
|
||||||
_dwIrq=dwIrq;
|
|
||||||
_dwId=dwId;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public Methods //////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void UARTClass::begin(const uint32_t dwBaudRate)
|
|
||||||
{
|
|
||||||
begin(dwBaudRate, Mode_8N1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UARTClass::begin(const uint32_t dwBaudRate, const UARTModes config)
|
|
||||||
{
|
|
||||||
uint32_t modeReg = static_cast<uint32_t>(config) & 0x00000E00;
|
|
||||||
init(dwBaudRate, modeReg | UART_MR_CHMODE_NORMAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UARTClass::init(const uint32_t dwBaudRate, const uint32_t modeReg)
|
|
||||||
{
|
|
||||||
// Configure PMC
|
|
||||||
pmc_enable_periph_clk( _dwId );
|
|
||||||
|
|
||||||
// Disable PDC channel
|
|
||||||
_pUart->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
|
|
||||||
|
|
||||||
// Reset and disable receiver and transmitter
|
|
||||||
_pUart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS;
|
|
||||||
|
|
||||||
// Configure mode
|
|
||||||
_pUart->UART_MR = modeReg;
|
|
||||||
|
|
||||||
// Configure baudrate (asynchronous, no oversampling)
|
|
||||||
_pUart->UART_BRGR = (SystemCoreClock / dwBaudRate) >> 4;
|
|
||||||
|
|
||||||
// Configure interrupts
|
|
||||||
_pUart->UART_IDR = 0xFFFFFFFF;
|
|
||||||
_pUart->UART_IER = UART_IER_RXRDY | UART_IER_OVRE | UART_IER_FRAME;
|
|
||||||
|
|
||||||
// Enable UART interrupt in NVIC
|
|
||||||
NVIC_EnableIRQ(_dwIrq);
|
|
||||||
|
|
||||||
// Make sure both ring buffers are initialized back to empty.
|
|
||||||
_rx_buffer->_iHead = _rx_buffer->_iTail = 0;
|
|
||||||
_tx_buffer->_iHead = _tx_buffer->_iTail = 0;
|
|
||||||
|
|
||||||
// Enable receiver and transmitter
|
|
||||||
_pUart->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UARTClass::end( void )
|
|
||||||
{
|
|
||||||
// Clear any received data
|
|
||||||
_rx_buffer->_iHead = _rx_buffer->_iTail;
|
|
||||||
|
|
||||||
// Wait for any outstanding data to be sent
|
|
||||||
flush();
|
|
||||||
|
|
||||||
// Disable UART interrupt in NVIC
|
|
||||||
NVIC_DisableIRQ( _dwIrq );
|
|
||||||
|
|
||||||
pmc_disable_periph_clk( _dwId );
|
|
||||||
}
|
|
||||||
|
|
||||||
void UARTClass::setInterruptPriority(uint32_t priority)
|
|
||||||
{
|
|
||||||
NVIC_SetPriority(_dwIrq, priority & 0x0F);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t UARTClass::getInterruptPriority()
|
|
||||||
{
|
|
||||||
return NVIC_GetPriority(_dwIrq);
|
|
||||||
}
|
|
||||||
|
|
||||||
int UARTClass::available( void )
|
|
||||||
{
|
|
||||||
return (uint32_t)(SERIAL_BUFFER_SIZE + _rx_buffer->_iHead - _rx_buffer->_iTail) % SERIAL_BUFFER_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int UARTClass::availableForWrite(void)
|
|
||||||
{
|
|
||||||
int head = _tx_buffer->_iHead;
|
|
||||||
int tail = _tx_buffer->_iTail;
|
|
||||||
if (head >= tail) return SERIAL_BUFFER_SIZE - 1 - head + tail;
|
|
||||||
return tail - head - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int UARTClass::peek( void )
|
|
||||||
{
|
|
||||||
if ( _rx_buffer->_iHead == _rx_buffer->_iTail )
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return _rx_buffer->_aucBuffer[_rx_buffer->_iTail];
|
|
||||||
}
|
|
||||||
|
|
||||||
int UARTClass::read( void )
|
|
||||||
{
|
|
||||||
// if the head isn't ahead of the tail, we don't have any characters
|
|
||||||
if ( _rx_buffer->_iHead == _rx_buffer->_iTail )
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
uint8_t uc = _rx_buffer->_aucBuffer[_rx_buffer->_iTail];
|
|
||||||
_rx_buffer->_iTail = (unsigned int)(_rx_buffer->_iTail + 1) % SERIAL_BUFFER_SIZE;
|
|
||||||
return uc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UARTClass::flush( void )
|
|
||||||
{
|
|
||||||
while (_tx_buffer->_iHead != _tx_buffer->_iTail); //wait for transmit data to be sent
|
|
||||||
// Wait for transmission to complete
|
|
||||||
while ((_pUart->UART_SR & UART_SR_TXEMPTY) != UART_SR_TXEMPTY)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t UARTClass::write( const uint8_t uc_data )
|
|
||||||
{
|
|
||||||
// Is the hardware currently busy?
|
|
||||||
if (((_pUart->UART_SR & UART_SR_TXRDY) != UART_SR_TXRDY) |
|
|
||||||
(_tx_buffer->_iTail != _tx_buffer->_iHead))
|
|
||||||
{
|
|
||||||
// If busy we buffer
|
|
||||||
int nextWrite = (_tx_buffer->_iHead + 1) % SERIAL_BUFFER_SIZE;
|
|
||||||
while (_tx_buffer->_iTail == nextWrite)
|
|
||||||
; // Spin locks if we're about to overwrite the buffer. This continues once the data is sent
|
|
||||||
|
|
||||||
_tx_buffer->_aucBuffer[_tx_buffer->_iHead] = uc_data;
|
|
||||||
_tx_buffer->_iHead = nextWrite;
|
|
||||||
// Make sure TX interrupt is enabled
|
|
||||||
_pUart->UART_IER = UART_IER_TXRDY;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Bypass buffering and send character directly
|
|
||||||
_pUart->UART_THR = uc_data;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UARTClass::IrqHandler( void )
|
|
||||||
{
|
|
||||||
uint32_t status = _pUart->UART_SR;
|
|
||||||
|
|
||||||
// Did we receive data?
|
|
||||||
if ((status & UART_SR_RXRDY) == UART_SR_RXRDY)
|
|
||||||
_rx_buffer->store_char(_pUart->UART_RHR);
|
|
||||||
|
|
||||||
// Do we need to keep sending data?
|
|
||||||
if ((status & UART_SR_TXRDY) == UART_SR_TXRDY)
|
|
||||||
{
|
|
||||||
if (_tx_buffer->_iTail != _tx_buffer->_iHead) {
|
|
||||||
_pUart->UART_THR = _tx_buffer->_aucBuffer[_tx_buffer->_iTail];
|
|
||||||
_tx_buffer->_iTail = (unsigned int)(_tx_buffer->_iTail + 1) % SERIAL_BUFFER_SIZE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Mask off transmit interrupt so we don't get it anymore
|
|
||||||
_pUart->UART_IDR = UART_IDR_TXRDY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Acknowledge errors
|
|
||||||
if ((status & UART_SR_OVRE) == UART_SR_OVRE || (status & UART_SR_FRAME) == UART_SR_FRAME)
|
|
||||||
{
|
|
||||||
// TODO: error reporting outside ISR
|
|
||||||
_pUart->UART_CR |= UART_CR_RSTSTA;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _UART_CLASS_
|
|
||||||
#define _UART_CLASS_
|
|
||||||
|
|
||||||
#include "HardwareSerial.h"
|
|
||||||
#include "RingBuffer.h"
|
|
||||||
|
|
||||||
// Includes Atmel CMSIS
|
|
||||||
#include <chip.h>
|
|
||||||
|
|
||||||
#define SERIAL_8N1 UARTClass::Mode_8N1
|
|
||||||
#define SERIAL_8E1 UARTClass::Mode_8E1
|
|
||||||
#define SERIAL_8O1 UARTClass::Mode_8O1
|
|
||||||
#define SERIAL_8M1 UARTClass::Mode_8M1
|
|
||||||
#define SERIAL_8S1 UARTClass::Mode_8S1
|
|
||||||
|
|
||||||
|
|
||||||
class UARTClass : public HardwareSerial
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum UARTModes {
|
|
||||||
Mode_8N1 = US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_NO,
|
|
||||||
Mode_8E1 = US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_EVEN,
|
|
||||||
Mode_8O1 = US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_ODD,
|
|
||||||
Mode_8M1 = US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_MARK,
|
|
||||||
Mode_8S1 = US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_SPACE,
|
|
||||||
};
|
|
||||||
UARTClass(Uart* pUart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, RingBuffer* pTx_buffer);
|
|
||||||
|
|
||||||
void begin(const uint32_t dwBaudRate);
|
|
||||||
void begin(const uint32_t dwBaudRate, const UARTModes config);
|
|
||||||
void end(void);
|
|
||||||
int available(void);
|
|
||||||
int availableForWrite(void);
|
|
||||||
int peek(void);
|
|
||||||
int read(void);
|
|
||||||
void flush(void);
|
|
||||||
size_t write(const uint8_t c);
|
|
||||||
using Print::write; // pull in write(str) and write(buf, size) from Print
|
|
||||||
|
|
||||||
void setInterruptPriority(uint32_t priority);
|
|
||||||
uint32_t getInterruptPriority();
|
|
||||||
|
|
||||||
void IrqHandler(void);
|
|
||||||
|
|
||||||
operator bool() { return true; }; // UART always active
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void init(const uint32_t dwBaudRate, const uint32_t config);
|
|
||||||
|
|
||||||
RingBuffer *_rx_buffer;
|
|
||||||
RingBuffer *_tx_buffer;
|
|
||||||
|
|
||||||
Uart* _pUart;
|
|
||||||
IRQn_Type _dwIrq;
|
|
||||||
uint32_t _dwId;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // _UART_CLASS_
|
|
@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "USARTClass.h"
|
|
||||||
|
|
||||||
// Constructors ////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
USARTClass::USARTClass( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, RingBuffer* pTx_buffer )
|
|
||||||
: UARTClass((Uart*)pUsart, dwIrq, dwId, pRx_buffer, pTx_buffer)
|
|
||||||
{
|
|
||||||
// In case anyone needs USART specific functionality in the future
|
|
||||||
_pUsart=pUsart;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public Methods //////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void USARTClass::begin(const uint32_t dwBaudRate)
|
|
||||||
{
|
|
||||||
begin(dwBaudRate, Mode_8N1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void USARTClass::begin(const uint32_t dwBaudRate, const UARTModes config)
|
|
||||||
{
|
|
||||||
uint32_t modeReg = static_cast<uint32_t>(config);
|
|
||||||
modeReg |= US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHMODE_NORMAL;
|
|
||||||
init(dwBaudRate, modeReg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void USARTClass::begin(const uint32_t dwBaudRate, const USARTModes config)
|
|
||||||
{
|
|
||||||
uint32_t modeReg = static_cast<uint32_t>(config);
|
|
||||||
modeReg |= US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHMODE_NORMAL;
|
|
||||||
init(dwBaudRate, modeReg);
|
|
||||||
}
|
|
||||||
|
|
@ -1,118 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _USART_CLASS_
|
|
||||||
#define _USART_CLASS_
|
|
||||||
|
|
||||||
#include "UARTClass.h"
|
|
||||||
#include "RingBuffer.h"
|
|
||||||
|
|
||||||
// Includes Atmel CMSIS
|
|
||||||
#include <chip.h>
|
|
||||||
|
|
||||||
// Define config for Serial.begin(baud, config);
|
|
||||||
#define SERIAL_5N1 USARTClass::Mode_5N1
|
|
||||||
#define SERIAL_6N1 USARTClass::Mode_6N1
|
|
||||||
#define SERIAL_7N1 USARTClass::Mode_7N1
|
|
||||||
#define SERIAL_5N2 USARTClass::Mode_5N2
|
|
||||||
#define SERIAL_6N2 USARTClass::Mode_6N2
|
|
||||||
#define SERIAL_7N2 USARTClass::Mode_7N2
|
|
||||||
#define SERIAL_8N2 USARTClass::Mode_8N2
|
|
||||||
#define SERIAL_5E1 USARTClass::Mode_5E1
|
|
||||||
#define SERIAL_6E1 USARTClass::Mode_6E1
|
|
||||||
#define SERIAL_7E1 USARTClass::Mode_7E1
|
|
||||||
#define SERIAL_5E2 USARTClass::Mode_5E2
|
|
||||||
#define SERIAL_6E2 USARTClass::Mode_6E2
|
|
||||||
#define SERIAL_7E2 USARTClass::Mode_7E2
|
|
||||||
#define SERIAL_8E2 USARTClass::Mode_8E2
|
|
||||||
#define SERIAL_5O1 USARTClass::Mode_5O1
|
|
||||||
#define SERIAL_6O1 USARTClass::Mode_6O1
|
|
||||||
#define SERIAL_7O1 USARTClass::Mode_7O1
|
|
||||||
#define SERIAL_5O2 USARTClass::Mode_5O2
|
|
||||||
#define SERIAL_6O2 USARTClass::Mode_6O2
|
|
||||||
#define SERIAL_7O2 USARTClass::Mode_7O2
|
|
||||||
#define SERIAL_8O2 USARTClass::Mode_8O2
|
|
||||||
#define SERIAL_5M1 USARTClass::Mode_5M1
|
|
||||||
#define SERIAL_6M1 USARTClass::Mode_6M1
|
|
||||||
#define SERIAL_7M1 USARTClass::Mode_7M1
|
|
||||||
#define SERIAL_5M2 USARTClass::Mode_5M2
|
|
||||||
#define SERIAL_6M2 USARTClass::Mode_6M2
|
|
||||||
#define SERIAL_7M2 USARTClass::Mode_7M2
|
|
||||||
#define SERIAL_8M2 USARTClass::Mode_8M2
|
|
||||||
#define SERIAL_5S1 USARTClass::Mode_5S1
|
|
||||||
#define SERIAL_6S1 USARTClass::Mode_6S1
|
|
||||||
#define SERIAL_7S1 USARTClass::Mode_7S1
|
|
||||||
#define SERIAL_5S2 USARTClass::Mode_5S2
|
|
||||||
#define SERIAL_6S2 USARTClass::Mode_6S2
|
|
||||||
#define SERIAL_7S2 USARTClass::Mode_7S2
|
|
||||||
#define SERIAL_8S2 USARTClass::Mode_8S2
|
|
||||||
|
|
||||||
|
|
||||||
class USARTClass : public UARTClass
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// 8x1 bit modes are inherited from UARTClass
|
|
||||||
enum USARTModes {
|
|
||||||
Mode_5N1 = US_MR_CHRL_5_BIT | US_MR_PAR_NO | US_MR_NBSTOP_1_BIT,
|
|
||||||
Mode_6N1 = US_MR_CHRL_6_BIT | US_MR_PAR_NO | US_MR_NBSTOP_1_BIT,
|
|
||||||
Mode_7N1 = US_MR_CHRL_7_BIT | US_MR_PAR_NO | US_MR_NBSTOP_1_BIT,
|
|
||||||
Mode_5N2 = US_MR_CHRL_5_BIT | US_MR_PAR_NO | US_MR_NBSTOP_2_BIT,
|
|
||||||
Mode_6N2 = US_MR_CHRL_6_BIT | US_MR_PAR_NO | US_MR_NBSTOP_2_BIT,
|
|
||||||
Mode_7N2 = US_MR_CHRL_7_BIT | US_MR_PAR_NO | US_MR_NBSTOP_2_BIT,
|
|
||||||
Mode_8N2 = US_MR_CHRL_8_BIT | US_MR_PAR_NO | US_MR_NBSTOP_2_BIT,
|
|
||||||
Mode_5E1 = US_MR_CHRL_5_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_1_BIT,
|
|
||||||
Mode_6E1 = US_MR_CHRL_6_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_1_BIT,
|
|
||||||
Mode_7E1 = US_MR_CHRL_7_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_1_BIT,
|
|
||||||
Mode_5E2 = US_MR_CHRL_5_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_2_BIT,
|
|
||||||
Mode_6E2 = US_MR_CHRL_6_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_2_BIT,
|
|
||||||
Mode_7E2 = US_MR_CHRL_7_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_2_BIT,
|
|
||||||
Mode_8E2 = US_MR_CHRL_8_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_2_BIT,
|
|
||||||
Mode_5O1 = US_MR_CHRL_5_BIT | US_MR_PAR_ODD | US_MR_NBSTOP_1_BIT,
|
|
||||||
Mode_6O1 = US_MR_CHRL_6_BIT | US_MR_PAR_ODD | US_MR_NBSTOP_1_BIT,
|
|
||||||
Mode_7O1 = US_MR_CHRL_7_BIT | US_MR_PAR_ODD | US_MR_NBSTOP_1_BIT,
|
|
||||||
Mode_5O2 = US_MR_CHRL_5_BIT | US_MR_PAR_ODD | US_MR_NBSTOP_2_BIT,
|
|
||||||
Mode_6O2 = US_MR_CHRL_6_BIT | US_MR_PAR_ODD | US_MR_NBSTOP_2_BIT,
|
|
||||||
Mode_7O2 = US_MR_CHRL_7_BIT | US_MR_PAR_ODD | US_MR_NBSTOP_2_BIT,
|
|
||||||
Mode_8O2 = US_MR_CHRL_8_BIT | US_MR_PAR_ODD | US_MR_NBSTOP_2_BIT,
|
|
||||||
Mode_5M1 = US_MR_CHRL_5_BIT | US_MR_PAR_MARK | US_MR_NBSTOP_1_BIT,
|
|
||||||
Mode_6M1 = US_MR_CHRL_6_BIT | US_MR_PAR_MARK | US_MR_NBSTOP_1_BIT,
|
|
||||||
Mode_7M1 = US_MR_CHRL_7_BIT | US_MR_PAR_MARK | US_MR_NBSTOP_1_BIT,
|
|
||||||
Mode_5M2 = US_MR_CHRL_5_BIT | US_MR_PAR_MARK | US_MR_NBSTOP_2_BIT,
|
|
||||||
Mode_6M2 = US_MR_CHRL_6_BIT | US_MR_PAR_MARK | US_MR_NBSTOP_2_BIT,
|
|
||||||
Mode_7M2 = US_MR_CHRL_7_BIT | US_MR_PAR_MARK | US_MR_NBSTOP_2_BIT,
|
|
||||||
Mode_8M2 = US_MR_CHRL_8_BIT | US_MR_PAR_MARK | US_MR_NBSTOP_2_BIT,
|
|
||||||
Mode_5S1 = US_MR_CHRL_5_BIT | US_MR_PAR_SPACE | US_MR_NBSTOP_1_BIT,
|
|
||||||
Mode_6S1 = US_MR_CHRL_6_BIT | US_MR_PAR_SPACE | US_MR_NBSTOP_1_BIT,
|
|
||||||
Mode_7S1 = US_MR_CHRL_7_BIT | US_MR_PAR_SPACE | US_MR_NBSTOP_1_BIT,
|
|
||||||
Mode_5S2 = US_MR_CHRL_5_BIT | US_MR_PAR_SPACE | US_MR_NBSTOP_2_BIT,
|
|
||||||
Mode_6S2 = US_MR_CHRL_6_BIT | US_MR_PAR_SPACE | US_MR_NBSTOP_2_BIT,
|
|
||||||
Mode_7S2 = US_MR_CHRL_7_BIT | US_MR_PAR_SPACE | US_MR_NBSTOP_2_BIT,
|
|
||||||
Mode_8S2 = US_MR_CHRL_8_BIT | US_MR_PAR_SPACE | US_MR_NBSTOP_2_BIT,
|
|
||||||
};
|
|
||||||
|
|
||||||
USARTClass(Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, RingBuffer* pTx_buffer);
|
|
||||||
|
|
||||||
void begin(const uint32_t dwBaudRate);
|
|
||||||
void begin(const uint32_t dwBaudRate, const USARTModes config);
|
|
||||||
void begin(const uint32_t dwBaudRate, const UARTModes config);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Usart* _pUsart;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // _USART_CLASS_
|
|
@ -1,365 +0,0 @@
|
|||||||
/* Copyright (c) 2011, Peter Barrett
|
|
||||||
**
|
|
||||||
** Permission to use, copy, modify, and/or distribute this software for
|
|
||||||
** any purpose with or without fee is hereby granted, provided that the
|
|
||||||
** above copyright notice and this permission notice appear in all copies.
|
|
||||||
**
|
|
||||||
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
|
||||||
** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
|
||||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
|
||||||
** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
|
||||||
** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
||||||
** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|
||||||
** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|
||||||
** SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
|
||||||
#include "USBAPI.h"
|
|
||||||
#include "Reset.h"
|
|
||||||
#include "Print.h"
|
|
||||||
|
|
||||||
#ifdef CDC_ENABLED
|
|
||||||
|
|
||||||
#define CDC_SERIAL_BUFFER_SIZE 512
|
|
||||||
|
|
||||||
/* For information purpose only since RTS is not always handled by the terminal application */
|
|
||||||
#define CDC_LINESTATE_DTR 0x01 // Data Terminal Ready
|
|
||||||
#define CDC_LINESTATE_RTS 0x02 // Ready to Send
|
|
||||||
|
|
||||||
#define CDC_LINESTATE_READY (CDC_LINESTATE_RTS | CDC_LINESTATE_DTR)
|
|
||||||
|
|
||||||
struct ring_buffer
|
|
||||||
{
|
|
||||||
uint8_t buffer[CDC_SERIAL_BUFFER_SIZE];
|
|
||||||
volatile uint32_t head;
|
|
||||||
volatile uint32_t tail;
|
|
||||||
};
|
|
||||||
|
|
||||||
ring_buffer cdc_rx_buffer = { { 0 }, 0, 0};
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32_t dwDTERate;
|
|
||||||
uint8_t bCharFormat;
|
|
||||||
uint8_t bParityType;
|
|
||||||
uint8_t bDataBits;
|
|
||||||
uint8_t lineState;
|
|
||||||
} LineInfo;
|
|
||||||
|
|
||||||
static volatile LineInfo _usbLineInfo = {
|
|
||||||
57600, // dWDTERate
|
|
||||||
0x00, // bCharFormat
|
|
||||||
0x00, // bParityType
|
|
||||||
0x08, // bDataBits
|
|
||||||
0x00 // lineState
|
|
||||||
};
|
|
||||||
|
|
||||||
static volatile int32_t breakValue = -1;
|
|
||||||
|
|
||||||
_Pragma("pack(1)")
|
|
||||||
static const CDCDescriptor _cdcInterface =
|
|
||||||
{
|
|
||||||
D_IAD(0,2,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,1),
|
|
||||||
|
|
||||||
// CDC communication interface
|
|
||||||
D_INTERFACE(CDC_ACM_INTERFACE,1,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,0),
|
|
||||||
D_CDCCS(CDC_HEADER,0x10,0x01), // Header (1.10 bcd)
|
|
||||||
D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management (not)
|
|
||||||
D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported
|
|
||||||
D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0
|
|
||||||
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10, 0x10),
|
|
||||||
|
|
||||||
// CDC data interface
|
|
||||||
D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0),
|
|
||||||
D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,512,0),
|
|
||||||
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,512,0)
|
|
||||||
};
|
|
||||||
static const CDCDescriptor _cdcOtherInterface =
|
|
||||||
{
|
|
||||||
D_IAD(0,2,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,1),
|
|
||||||
|
|
||||||
// CDC communication interface
|
|
||||||
D_INTERFACE(CDC_ACM_INTERFACE,1,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,0),
|
|
||||||
D_CDCCS(CDC_HEADER,0x10,0x01), // Header (1.10 bcd)
|
|
||||||
D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management (not)
|
|
||||||
D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported
|
|
||||||
D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0
|
|
||||||
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10, 0x10),
|
|
||||||
|
|
||||||
// CDC data interface
|
|
||||||
D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0),
|
|
||||||
D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,64,0),
|
|
||||||
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,64,0)
|
|
||||||
};
|
|
||||||
_Pragma("pack()")
|
|
||||||
|
|
||||||
int WEAK CDC_GetInterface(uint8_t* interfaceNum)
|
|
||||||
{
|
|
||||||
interfaceNum[0] += 2; // uses 2
|
|
||||||
return USBD_SendControl(0,&_cdcInterface,sizeof(_cdcInterface));
|
|
||||||
}
|
|
||||||
|
|
||||||
int WEAK CDC_GetOtherInterface(uint8_t* interfaceNum)
|
|
||||||
{
|
|
||||||
interfaceNum[0] += 2; // uses 2
|
|
||||||
return USBD_SendControl(0,&_cdcOtherInterface,sizeof(_cdcOtherInterface));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WEAK CDC_Setup(USBSetup& setup)
|
|
||||||
{
|
|
||||||
uint8_t r = setup.bRequest;
|
|
||||||
uint8_t requestType = setup.bmRequestType;
|
|
||||||
|
|
||||||
if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
|
|
||||||
{
|
|
||||||
if (CDC_GET_LINE_CODING == r)
|
|
||||||
{
|
|
||||||
USBD_SendControl(0,(void*)&_usbLineInfo,7);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
|
|
||||||
{
|
|
||||||
if (CDC_SET_LINE_CODING == r)
|
|
||||||
{
|
|
||||||
USBD_RecvControl((void*)&_usbLineInfo,7);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CDC_SET_CONTROL_LINE_STATE == r)
|
|
||||||
{
|
|
||||||
_usbLineInfo.lineState = setup.wValueL;
|
|
||||||
// auto-reset into the bootloader is triggered when the port, already
|
|
||||||
// open at 1200 bps, is closed.
|
|
||||||
if (1200 == _usbLineInfo.dwDTERate)
|
|
||||||
{
|
|
||||||
// We check DTR state to determine if host port is open (bit 0 of lineState).
|
|
||||||
if ((_usbLineInfo.lineState & 0x01) == 0)
|
|
||||||
initiateReset(250);
|
|
||||||
else
|
|
||||||
cancelReset();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CDC_SEND_BREAK == r)
|
|
||||||
{
|
|
||||||
breakValue = ((uint16_t)setup.wValueH << 8) | setup.wValueL;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _serialPeek = -1;
|
|
||||||
void Serial_::begin(uint32_t baud_count)
|
|
||||||
{
|
|
||||||
// suppress "unused parameter" warning
|
|
||||||
(void)baud_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Serial_::begin(uint32_t baud_count, uint8_t config)
|
|
||||||
{
|
|
||||||
// suppress "unused parameter" warning
|
|
||||||
(void)baud_count;
|
|
||||||
(void)config;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Serial_::end(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Serial_::accept(void)
|
|
||||||
{
|
|
||||||
static uint32_t guard = 0;
|
|
||||||
|
|
||||||
// synchronized access to guard
|
|
||||||
do {
|
|
||||||
if (__LDREXW(&guard) != 0) {
|
|
||||||
__CLREX();
|
|
||||||
return; // busy
|
|
||||||
}
|
|
||||||
} while (__STREXW(1, &guard) != 0); // retry until write succeed
|
|
||||||
|
|
||||||
ring_buffer *buffer = &cdc_rx_buffer;
|
|
||||||
uint32_t i = (uint32_t)(buffer->head+1) % CDC_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.
|
|
||||||
while (i != buffer->tail) {
|
|
||||||
uint32_t c;
|
|
||||||
if (!USBD_Available(CDC_RX)) {
|
|
||||||
udd_ack_fifocon(CDC_RX);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
c = USBD_Recv(CDC_RX);
|
|
||||||
// c = UDD_Recv8(CDC_RX & 0xF);
|
|
||||||
buffer->buffer[buffer->head] = c;
|
|
||||||
buffer->head = i;
|
|
||||||
|
|
||||||
i = (i + 1) % CDC_SERIAL_BUFFER_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// release the guard
|
|
||||||
guard = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Serial_::available(void)
|
|
||||||
{
|
|
||||||
ring_buffer *buffer = &cdc_rx_buffer;
|
|
||||||
return (unsigned int)(CDC_SERIAL_BUFFER_SIZE + buffer->head - buffer->tail) % CDC_SERIAL_BUFFER_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Serial_::availableForWrite(void)
|
|
||||||
{
|
|
||||||
// return the number of bytes left in the current bank,
|
|
||||||
// always EP size - 1, because bank is flushed on every write
|
|
||||||
return (EPX_SIZE - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Serial_::peek(void)
|
|
||||||
{
|
|
||||||
ring_buffer *buffer = &cdc_rx_buffer;
|
|
||||||
|
|
||||||
if (buffer->head == buffer->tail)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return buffer->buffer[buffer->tail];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int Serial_::read(void)
|
|
||||||
{
|
|
||||||
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
|
|
||||||
{
|
|
||||||
unsigned char c = buffer->buffer[buffer->tail];
|
|
||||||
buffer->tail = (unsigned int)(buffer->tail + 1) % CDC_SERIAL_BUFFER_SIZE;
|
|
||||||
if (USBD_Available(CDC_RX))
|
|
||||||
accept();
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Serial_::flush(void)
|
|
||||||
{
|
|
||||||
USBD_Flush(CDC_TX);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Serial_::write(const uint8_t *buffer, size_t size)
|
|
||||||
{
|
|
||||||
/* only try to send bytes if the high-level CDC connection itself
|
|
||||||
is open (not just the pipe) - the OS should set lineState when the port
|
|
||||||
is opened and clear lineState when the port is closed.
|
|
||||||
bytes sent before the user opens the connection or after
|
|
||||||
the connection is closed are lost - just like with a UART. */
|
|
||||||
|
|
||||||
// TODO - ZE - check behavior on different OSes and test what happens if an
|
|
||||||
// open connection isn't broken cleanly (cable is yanked out, host dies
|
|
||||||
// or locks up, or host virtual serial port hangs)
|
|
||||||
if (_usbLineInfo.lineState > 0)
|
|
||||||
{
|
|
||||||
int r = USBD_Send(CDC_TX, buffer, size);
|
|
||||||
|
|
||||||
if (r > 0)
|
|
||||||
{
|
|
||||||
return r;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
setWriteError();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setWriteError();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Serial_::write(uint8_t c) {
|
|
||||||
return write(&c, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
{
|
|
||||||
// this is here to avoid spurious opening after upload
|
|
||||||
if (millis() < 500)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (_usbLineInfo.lineState > 0)
|
|
||||||
{
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
delay(10);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t Serial_::readBreak() {
|
|
||||||
uint8_t enableInterrupts = ((__get_PRIMASK() & 0x1) == 0 && (__get_FAULTMASK() & 0x1) == 0);
|
|
||||||
|
|
||||||
// disable interrupts,
|
|
||||||
// to avoid clearing a breakValue that might occur
|
|
||||||
// while processing the current break value
|
|
||||||
__disable_irq();
|
|
||||||
|
|
||||||
int ret = breakValue;
|
|
||||||
|
|
||||||
breakValue = -1;
|
|
||||||
|
|
||||||
if (enableInterrupts)
|
|
||||||
{
|
|
||||||
// re-enable the interrupts
|
|
||||||
__enable_irq();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
@ -1,116 +0,0 @@
|
|||||||
/*
|
|
||||||
PluggableUSB.cpp
|
|
||||||
Copyright (c) 2015 Arduino LLC
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "USBAPI.h"
|
|
||||||
#include "USBDesc.h"
|
|
||||||
#include "USBCore.h"
|
|
||||||
#include "PluggableUSB.h"
|
|
||||||
|
|
||||||
#if defined(USBCON)
|
|
||||||
#ifdef PLUGGABLE_USB_ENABLED
|
|
||||||
|
|
||||||
extern uint32_t EndPoints[];
|
|
||||||
|
|
||||||
int PluggableUSB_::getInterface(uint8_t* interfaceCount)
|
|
||||||
{
|
|
||||||
int sent = 0;
|
|
||||||
PluggableUSBModule* node;
|
|
||||||
for (node = rootNode; node; node = node->next) {
|
|
||||||
int res = node->getInterface(interfaceCount);
|
|
||||||
if (res < 0)
|
|
||||||
return -1;
|
|
||||||
sent += res;
|
|
||||||
}
|
|
||||||
return sent;
|
|
||||||
}
|
|
||||||
|
|
||||||
int PluggableUSB_::getDescriptor(USBSetup& setup)
|
|
||||||
{
|
|
||||||
PluggableUSBModule* node;
|
|
||||||
for (node = rootNode; node; node = node->next) {
|
|
||||||
int ret = node->getDescriptor(setup);
|
|
||||||
// ret!=0 -> request has been processed
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PluggableUSB_::getShortName(char *iSerialNum)
|
|
||||||
{
|
|
||||||
PluggableUSBModule* node;
|
|
||||||
for (node = rootNode; node; node = node->next) {
|
|
||||||
iSerialNum += node->getShortName(iSerialNum);
|
|
||||||
}
|
|
||||||
*iSerialNum = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PluggableUSB_::setup(USBSetup& setup)
|
|
||||||
{
|
|
||||||
PluggableUSBModule* node;
|
|
||||||
for (node = rootNode; node; node = node->next) {
|
|
||||||
if (node->setup(setup)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PluggableUSB_::plug(PluggableUSBModule *node)
|
|
||||||
{
|
|
||||||
if ((lastEp + node->numEndpoints) > USB_ENDPOINTS) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rootNode) {
|
|
||||||
rootNode = node;
|
|
||||||
} else {
|
|
||||||
PluggableUSBModule *current = rootNode;
|
|
||||||
while (current->next) {
|
|
||||||
current = current->next;
|
|
||||||
}
|
|
||||||
current->next = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
node->pluggedInterface = lastIf;
|
|
||||||
node->pluggedEndpoint = lastEp;
|
|
||||||
lastIf += node->numInterfaces;
|
|
||||||
for (uint8_t i = 0; i < node->numEndpoints; i++) {
|
|
||||||
EndPoints[lastEp] = node->endpointType[i];
|
|
||||||
lastEp++;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
// restart USB layer???
|
|
||||||
}
|
|
||||||
|
|
||||||
PluggableUSB_& PluggableUSB()
|
|
||||||
{
|
|
||||||
static PluggableUSB_ obj;
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
PluggableUSB_::PluggableUSB_() : lastIf(CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT),
|
|
||||||
lastEp(CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT),
|
|
||||||
rootNode(NULL)
|
|
||||||
{
|
|
||||||
// Empty
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
PluggableUSB.h
|
|
||||||
Copyright (c) 2015 Arduino LLC
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PUSB_h
|
|
||||||
#define PUSB_h
|
|
||||||
|
|
||||||
#include "USBAPI.h"
|
|
||||||
|
|
||||||
#if defined(USBCON)
|
|
||||||
|
|
||||||
class PluggableUSBModule {
|
|
||||||
public:
|
|
||||||
PluggableUSBModule(uint8_t numEps, uint8_t numIfs, uint32_t *epType) :
|
|
||||||
numEndpoints(numEps), numInterfaces(numIfs), endpointType(epType)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual bool setup(USBSetup& setup) = 0;
|
|
||||||
virtual int getInterface(uint8_t* interfaceCount) = 0;
|
|
||||||
virtual int getDescriptor(USBSetup& setup) = 0;
|
|
||||||
virtual uint8_t getShortName(char *name) { name[0] = 'A'+pluggedInterface; return 1; }
|
|
||||||
|
|
||||||
uint8_t pluggedInterface;
|
|
||||||
uint8_t pluggedEndpoint;
|
|
||||||
|
|
||||||
const uint8_t numEndpoints;
|
|
||||||
const uint8_t numInterfaces;
|
|
||||||
const uint32_t *endpointType;
|
|
||||||
|
|
||||||
PluggableUSBModule *next = NULL;
|
|
||||||
|
|
||||||
friend class PluggableUSB_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class PluggableUSB_ {
|
|
||||||
public:
|
|
||||||
PluggableUSB_();
|
|
||||||
bool plug(PluggableUSBModule *node);
|
|
||||||
int getInterface(uint8_t* interfaceCount);
|
|
||||||
int getDescriptor(USBSetup& setup);
|
|
||||||
bool setup(USBSetup& setup);
|
|
||||||
void getShortName(char *iSerialNum);
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint8_t lastIf;
|
|
||||||
uint8_t lastEp;
|
|
||||||
PluggableUSBModule* rootNode;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Replacement for global singleton.
|
|
||||||
// This function prevents static-initialization-order-fiasco
|
|
||||||
// https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use
|
|
||||||
PluggableUSB_& PluggableUSB();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,162 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2012 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __USBAPI__
|
|
||||||
#define __USBAPI__
|
|
||||||
|
|
||||||
#if defined __cplusplus
|
|
||||||
|
|
||||||
#include "RingBuffer.h"
|
|
||||||
#include "Stream.h"
|
|
||||||
|
|
||||||
//================================================================================
|
|
||||||
//================================================================================
|
|
||||||
// USB
|
|
||||||
|
|
||||||
class USBDevice_
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
USBDevice_();
|
|
||||||
bool configured();
|
|
||||||
|
|
||||||
bool attach();
|
|
||||||
bool detach(); // Serial port goes down too...
|
|
||||||
void poll();
|
|
||||||
};
|
|
||||||
extern USBDevice_ USBDevice;
|
|
||||||
|
|
||||||
//================================================================================
|
|
||||||
//================================================================================
|
|
||||||
// Serial over CDC (Serial1 is the physical port)
|
|
||||||
|
|
||||||
class Serial_ : public Stream
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
RingBuffer *_cdc_rx_buffer;
|
|
||||||
public:
|
|
||||||
void begin(uint32_t baud_count);
|
|
||||||
void begin(uint32_t baud_count, uint8_t config);
|
|
||||||
void end(void);
|
|
||||||
|
|
||||||
virtual int available(void);
|
|
||||||
virtual int availableForWrite(void);
|
|
||||||
virtual void accept(void);
|
|
||||||
virtual int peek(void);
|
|
||||||
virtual int read(void);
|
|
||||||
virtual void flush(void);
|
|
||||||
virtual size_t write(uint8_t);
|
|
||||||
virtual size_t write(const uint8_t *buffer, size_t size);
|
|
||||||
using Print::write; // pull in write(str) from Print
|
|
||||||
operator bool();
|
|
||||||
|
|
||||||
// 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_ SerialUSB;
|
|
||||||
|
|
||||||
//================================================================================
|
|
||||||
//================================================================================
|
|
||||||
// Low level API
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t bmRequestType;
|
|
||||||
uint8_t bRequest;
|
|
||||||
uint8_t wValueL;
|
|
||||||
uint8_t wValueH;
|
|
||||||
uint16_t wIndex;
|
|
||||||
uint16_t wLength;
|
|
||||||
} USBSetup;
|
|
||||||
|
|
||||||
//================================================================================
|
|
||||||
//================================================================================
|
|
||||||
// MSC 'Driver'
|
|
||||||
|
|
||||||
int MSC_GetInterface(uint8_t* interfaceNum);
|
|
||||||
int MSC_GetDescriptor(int i);
|
|
||||||
bool MSC_Setup(USBSetup& setup);
|
|
||||||
bool MSC_Data(uint8_t rx,uint8_t tx);
|
|
||||||
|
|
||||||
//================================================================================
|
|
||||||
//================================================================================
|
|
||||||
// CSC 'Driver'
|
|
||||||
|
|
||||||
int CDC_GetInterface(uint8_t* interfaceNum);
|
|
||||||
int CDC_GetOtherInterface(uint8_t* interfaceNum);
|
|
||||||
int CDC_GetDescriptor(int i);
|
|
||||||
bool CDC_Setup(USBSetup& setup);
|
|
||||||
|
|
||||||
//================================================================================
|
|
||||||
//================================================================================
|
|
||||||
|
|
||||||
#define TRANSFER_RELEASE 0x40
|
|
||||||
#define TRANSFER_ZERO 0x20
|
|
||||||
|
|
||||||
void USBD_InitControl(int end);
|
|
||||||
int USBD_SendControl(uint8_t flags, const void* d, uint32_t len);
|
|
||||||
int USBD_RecvControl(void* d, uint32_t len);
|
|
||||||
uint8_t USBD_SendInterfaces(void);
|
|
||||||
bool USBD_ClassInterfaceRequest(USBSetup& setup);
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t USBD_Available(uint32_t ep);
|
|
||||||
uint32_t USBD_SendSpace(uint32_t ep);
|
|
||||||
uint32_t USBD_Send(uint32_t ep, const void* d, uint32_t len);
|
|
||||||
uint32_t USBD_Recv(uint32_t ep, void* data, uint32_t len); // non-blocking
|
|
||||||
uint32_t USBD_Recv(uint32_t ep); // non-blocking
|
|
||||||
void USBD_Flush(uint32_t ep);
|
|
||||||
uint32_t USBD_Connected(void);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
@ -1,894 +0,0 @@
|
|||||||
// Copyright (c) 2010, Peter Barrett
|
|
||||||
/*
|
|
||||||
** Permission to use, copy, modify, and/or distribute this software for
|
|
||||||
** any purpose with or without fee is hereby granted, provided that the
|
|
||||||
** above copyright notice and this permission notice appear in all copies.
|
|
||||||
**
|
|
||||||
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
|
||||||
** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
|
||||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
|
||||||
** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
|
||||||
** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
||||||
** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|
||||||
** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|
||||||
** SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
|
||||||
#include "USBAPI.h"
|
|
||||||
#include "Reset.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "PluggableUSB.h"
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
//#define TRACE_CORE(x) x
|
|
||||||
#define TRACE_CORE(x)
|
|
||||||
|
|
||||||
uint32_t EndPoints[] =
|
|
||||||
{
|
|
||||||
EP_TYPE_CONTROL,
|
|
||||||
|
|
||||||
#ifdef CDC_ENABLED
|
|
||||||
EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM
|
|
||||||
EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT
|
|
||||||
EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PLUGGABLE_USB_ENABLED
|
|
||||||
//allocate 6 endpoints and remove const so they can be changed by the user
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */
|
|
||||||
#define TX_RX_LED_PULSE_MS 100
|
|
||||||
volatile uint8_t TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */
|
|
||||||
volatile uint8_t RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */
|
|
||||||
static char isRemoteWakeUpEnabled = 0;
|
|
||||||
static char isEndpointHalt = 0;
|
|
||||||
//==================================================================
|
|
||||||
//==================================================================
|
|
||||||
|
|
||||||
extern const uint16_t STRING_LANGUAGE[];
|
|
||||||
extern const uint8_t STRING_PRODUCT[];
|
|
||||||
extern const uint8_t STRING_MANUFACTURER[];
|
|
||||||
extern const DeviceDescriptor USB_DeviceDescriptor;
|
|
||||||
extern const DeviceDescriptor USB_DeviceDescriptorA;
|
|
||||||
|
|
||||||
const uint16_t STRING_LANGUAGE[2] = {
|
|
||||||
(3<<8) | (2+2),
|
|
||||||
0x0409 // English
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifndef USB_PRODUCT
|
|
||||||
#define USB_PRODUCT "Arduino Due"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const uint8_t STRING_PRODUCT[] = USB_PRODUCT;
|
|
||||||
|
|
||||||
#ifndef USB_MANUFACTURER
|
|
||||||
#define USB_MANUFACTURER "Arduino LLC"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const uint8_t STRING_MANUFACTURER[] = USB_MANUFACTURER;
|
|
||||||
|
|
||||||
#ifdef CDC_ENABLED
|
|
||||||
#define DEVICE_CLASS 0x02
|
|
||||||
#else
|
|
||||||
#define DEVICE_CLASS 0x00
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// DEVICE DESCRIPTOR
|
|
||||||
const DeviceDescriptor USB_DeviceDescriptor =
|
|
||||||
D_DEVICE(0x00,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,ISERIAL,1);
|
|
||||||
|
|
||||||
const DeviceDescriptor USB_DeviceDescriptorA =
|
|
||||||
D_DEVICE(0xEF,0x02,0x01,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,ISERIAL,1);
|
|
||||||
|
|
||||||
const QualifierDescriptor USB_DeviceQualifier =
|
|
||||||
D_QUALIFIER(0x00,0x00,0x00,64,1);
|
|
||||||
|
|
||||||
//! 7.1.20 Test Mode Support
|
|
||||||
static const unsigned char test_packet_buffer[] = {
|
|
||||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // JKJKJKJK * 9
|
|
||||||
0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, // JJKKJJKK * 8
|
|
||||||
0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE, // JJJJKKKK * 8
|
|
||||||
0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // JJJJJJJKKKKKKK * 8
|
|
||||||
0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD, // JJJJJJJK * 8
|
|
||||||
0xFC,0x7E,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0x7E // {JKKKKKKK * 10}, JK
|
|
||||||
};
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
//==================================================================
|
|
||||||
|
|
||||||
volatile uint32_t _usbConfiguration = 0;
|
|
||||||
volatile uint32_t _usbInitialized = 0;
|
|
||||||
uint32_t _usbSetInterface = 0;
|
|
||||||
uint32_t _cdcComposite = 0;
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
//==================================================================
|
|
||||||
|
|
||||||
#define USB_RECV_TIMEOUT
|
|
||||||
class LockEP
|
|
||||||
{
|
|
||||||
irqflags_t flags;
|
|
||||||
public:
|
|
||||||
LockEP(uint32_t ep __attribute__ ((unused))) : flags(cpu_irq_save())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
~LockEP()
|
|
||||||
{
|
|
||||||
cpu_irq_restore(flags);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Number of bytes, assumes a rx endpoint
|
|
||||||
uint32_t USBD_Available(uint32_t ep)
|
|
||||||
{
|
|
||||||
LockEP lock(ep);
|
|
||||||
return UDD_FifoByteCount(ep & 0xF);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Non Blocking receive
|
|
||||||
// Return number of bytes read
|
|
||||||
uint32_t USBD_Recv(uint32_t ep, void* d, uint32_t len)
|
|
||||||
{
|
|
||||||
if (!_usbConfiguration)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
LockEP lock(ep);
|
|
||||||
uint32_t n = UDD_FifoByteCount(ep & 0xF);
|
|
||||||
len = min(n,len);
|
|
||||||
n = len;
|
|
||||||
uint8_t* dst = (uint8_t*)d;
|
|
||||||
while (n--)
|
|
||||||
*dst++ = UDD_Recv8(ep & 0xF);
|
|
||||||
if (len && !UDD_FifoByteCount(ep & 0xF)) // release empty buffer
|
|
||||||
UDD_ReleaseRX(ep & 0xF);
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recv 1 byte if ready
|
|
||||||
uint32_t USBD_Recv(uint32_t ep)
|
|
||||||
{
|
|
||||||
uint8_t c;
|
|
||||||
if (USBD_Recv(ep & 0xF, &c, 1) != 1)
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Space in send EP
|
|
||||||
//uint32_t USBD_SendSpace(uint32_t ep)
|
|
||||||
//{
|
|
||||||
//LockEP lock(ep);
|
|
||||||
//// if (!UDD_ReadWriteAllowed(ep & 0xF))
|
|
||||||
////{
|
|
||||||
////printf("pb "); // UOTGHS->UOTGHS_DEVEPTISR[%d]=0x%X\n\r", ep, UOTGHS->UOTGHS_DEVEPTISR[ep]);
|
|
||||||
////return 0;
|
|
||||||
////}
|
|
||||||
|
|
||||||
//if(ep==0) return 64 - UDD_FifoByteCount(ep & 0xF); // EP0_SIZE jcb
|
|
||||||
//else return 512 - UDD_FifoByteCount(ep & 0xF); // EPX_SIZE jcb
|
|
||||||
//}
|
|
||||||
|
|
||||||
// Blocking Send of data to an endpoint
|
|
||||||
uint32_t USBD_Send(uint32_t ep, const void* d, uint32_t len)
|
|
||||||
{
|
|
||||||
uint32_t n;
|
|
||||||
int r = len;
|
|
||||||
const uint8_t* data = (const uint8_t*)d;
|
|
||||||
|
|
||||||
if (!_usbConfiguration)
|
|
||||||
{
|
|
||||||
TRACE_CORE(printf("pb conf\n\r");)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (len)
|
|
||||||
{
|
|
||||||
if(ep==0) n = EP0_SIZE;
|
|
||||||
else n = EPX_SIZE;
|
|
||||||
if (n > len)
|
|
||||||
n = len;
|
|
||||||
len -= n;
|
|
||||||
|
|
||||||
UDD_Send(ep & 0xF, data, n);
|
|
||||||
data += n;
|
|
||||||
}
|
|
||||||
//TXLED1; // light the TX LED
|
|
||||||
//TxLEDPulse = TX_RX_LED_PULSE_MS;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t _cmark;
|
|
||||||
uint16_t _cend;
|
|
||||||
|
|
||||||
void USBD_InitControl(int end)
|
|
||||||
{
|
|
||||||
_cmark = 0;
|
|
||||||
_cend = end;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clipped by _cmark/_cend
|
|
||||||
int USBD_SendControl(uint8_t flags __attribute__ ((unused)), const void* d, uint32_t len)
|
|
||||||
{
|
|
||||||
const uint8_t* data = (const uint8_t*)d;
|
|
||||||
uint32_t length = len;
|
|
||||||
uint32_t sent = 0;
|
|
||||||
uint32_t pos = 0;
|
|
||||||
|
|
||||||
TRACE_CORE(printf("=> USBD_SendControl TOTAL len=%lu\r\n", len);)
|
|
||||||
|
|
||||||
if (_cmark < _cend)
|
|
||||||
{
|
|
||||||
while (len > 0)
|
|
||||||
{
|
|
||||||
sent = UDD_Send(EP0, data + pos, len);
|
|
||||||
TRACE_CORE(printf("=> USBD_SendControl sent=%lu\r\n", sent);)
|
|
||||||
pos += sent;
|
|
||||||
len -= sent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_cmark += length;
|
|
||||||
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send a USB descriptor string. The string is stored as a
|
|
||||||
// plain ASCII string but is sent out as UTF-16 with the
|
|
||||||
// correct 2-byte prefix
|
|
||||||
static bool USB_SendStringDescriptor(const uint8_t *string, int wLength) {
|
|
||||||
if (wLength < 2)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
uint8_t buffer[wLength];
|
|
||||||
buffer[0] = strlen((const char*)string) * 2 + 2;
|
|
||||||
buffer[1] = 0x03;
|
|
||||||
|
|
||||||
uint8_t i;
|
|
||||||
for (i = 2; i < wLength && *string; i++) {
|
|
||||||
buffer[i++] = *string++;
|
|
||||||
if (i == wLength) break;
|
|
||||||
buffer[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return USBD_SendControl(0, (uint8_t*)buffer, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Does not timeout or cross fifo boundaries
|
|
||||||
// Will only work for transfers <= 64 bytes
|
|
||||||
// TODO
|
|
||||||
int USBD_RecvControl(void* d, uint32_t len)
|
|
||||||
{
|
|
||||||
UDD_WaitOUT();
|
|
||||||
UDD_Recv(EP0, (uint8_t*)d, len);
|
|
||||||
UDD_ClearOUT();
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle CLASS_INTERFACE requests
|
|
||||||
bool USBD_ClassInterfaceRequest(USBSetup& setup)
|
|
||||||
{
|
|
||||||
uint8_t i = setup.wIndex;
|
|
||||||
|
|
||||||
TRACE_CORE(printf("=> USBD_ClassInterfaceRequest\r\n");)
|
|
||||||
|
|
||||||
#ifdef CDC_ENABLED
|
|
||||||
if (CDC_ACM_INTERFACE == i)
|
|
||||||
{
|
|
||||||
return CDC_Setup(setup);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PLUGGABLE_USB_ENABLED
|
|
||||||
return PluggableUSB().setup(setup);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t USBD_SendInterfaces(void)
|
|
||||||
{
|
|
||||||
uint8_t interfaces = 0;
|
|
||||||
|
|
||||||
#ifdef CDC_ENABLED
|
|
||||||
CDC_GetInterface(&interfaces);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PLUGGABLE_USB_ENABLED
|
|
||||||
PluggableUSB().getInterface(&interfaces);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
TRACE_CORE(printf("=> USBD_SendInterfaces, interfaces=%d\r\n", interfaces);)
|
|
||||||
return interfaces;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t USBD_SendOtherInterfaces(void)
|
|
||||||
{
|
|
||||||
uint8_t interfaces = 0;
|
|
||||||
|
|
||||||
#ifdef CDC_ENABLED
|
|
||||||
CDC_GetOtherInterface(&interfaces);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PLUGGABLE_USB_ENABLED
|
|
||||||
PluggableUSB().getInterface(&interfaces);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
TRACE_CORE(printf("=> USBD_SendInterfaces, interfaces=%d\r\n", interfaces);)
|
|
||||||
return interfaces;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct a dynamic configuration descriptor
|
|
||||||
// This really needs dynamic endpoint allocation etc
|
|
||||||
// TODO
|
|
||||||
static bool USBD_SendConfiguration(int maxlen)
|
|
||||||
{
|
|
||||||
// Count and measure interfaces
|
|
||||||
USBD_InitControl(0);
|
|
||||||
//TRACE_CORE(printf("=> USBD_SendConfiguration _cmark1=%d\r\n", _cmark);)
|
|
||||||
uint8_t interfaces = USBD_SendInterfaces();
|
|
||||||
//TRACE_CORE(printf("=> USBD_SendConfiguration _cmark2=%d\r\n", _cmark);)
|
|
||||||
//TRACE_CORE(printf("=> USBD_SendConfiguration sizeof=%d\r\n", sizeof(ConfigDescriptor));)
|
|
||||||
|
|
||||||
_Pragma("pack(1)")
|
|
||||||
ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor),interfaces);
|
|
||||||
_Pragma("pack()")
|
|
||||||
//TRACE_CORE(printf("=> USBD_SendConfiguration clen=%d\r\n", config.clen);)
|
|
||||||
|
|
||||||
//TRACE_CORE(printf("=> USBD_SendConfiguration maxlen=%d\r\n", maxlen);)
|
|
||||||
|
|
||||||
// Now send them
|
|
||||||
USBD_InitControl(maxlen);
|
|
||||||
USBD_SendControl(0,&config,sizeof(ConfigDescriptor));
|
|
||||||
USBD_SendInterfaces();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool USBD_SendOtherConfiguration(int maxlen)
|
|
||||||
{
|
|
||||||
// Count and measure interfaces
|
|
||||||
USBD_InitControl(0);
|
|
||||||
//TRACE_CORE(printf("=> USBD_SendConfiguration _cmark1=%d\r\n", _cmark);)
|
|
||||||
uint8_t interfaces = USBD_SendOtherInterfaces();
|
|
||||||
//TRACE_CORE(printf("=> USBD_SendConfiguration _cmark2=%d\r\n", _cmark);)
|
|
||||||
//TRACE_CORE(printf("=> USBD_SendConfiguration sizeof=%d\r\n", sizeof(ConfigDescriptor));)
|
|
||||||
|
|
||||||
_Pragma("pack(1)")
|
|
||||||
ConfigDescriptor config = D_OTHERCONFIG(_cmark + sizeof(ConfigDescriptor),interfaces);
|
|
||||||
_Pragma("pack()")
|
|
||||||
//TRACE_CORE(printf("=> USBD_SendConfiguration clen=%d\r\n", config.clen);)
|
|
||||||
|
|
||||||
//TRACE_CORE(printf("=> USBD_SendConfiguration maxlen=%d\r\n", maxlen);)
|
|
||||||
|
|
||||||
// Now send them
|
|
||||||
USBD_InitControl(maxlen);
|
|
||||||
USBD_SendControl(0,&config,sizeof(ConfigDescriptor));
|
|
||||||
USBD_SendOtherInterfaces();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool USBD_SendDescriptor(USBSetup& setup)
|
|
||||||
{
|
|
||||||
uint8_t t = setup.wValueH;
|
|
||||||
uint8_t desc_length = 0;
|
|
||||||
int ret = 0;
|
|
||||||
const uint8_t* desc_addr = 0;
|
|
||||||
|
|
||||||
if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t)
|
|
||||||
{
|
|
||||||
TRACE_CORE(printf("=> USBD_SendDescriptor : USB_CONFIGURATION_DESCRIPTOR_TYPE length=%d\r\n", setup.wLength);)
|
|
||||||
return USBD_SendConfiguration(setup.wLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
USBD_InitControl(setup.wLength);
|
|
||||||
|
|
||||||
#ifdef PLUGGABLE_USB_ENABLED
|
|
||||||
ret = PluggableUSB().getDescriptor(setup);
|
|
||||||
if (ret != 0) {
|
|
||||||
return (ret > 0 ? true : false);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (USB_DEVICE_DESCRIPTOR_TYPE == t)
|
|
||||||
{
|
|
||||||
TRACE_CORE(puts("=> USBD_SendDescriptor : USB_DEVICE_DESCRIPTOR_TYPE\r\n");)
|
|
||||||
if (setup.wLength == 8)
|
|
||||||
{
|
|
||||||
_cdcComposite = 1;
|
|
||||||
}
|
|
||||||
desc_addr = _cdcComposite ? (const uint8_t*)&USB_DeviceDescriptorA : (const uint8_t*)&USB_DeviceDescriptor;
|
|
||||||
if( *desc_addr > setup.wLength ) {
|
|
||||||
desc_length = setup.wLength;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (USB_STRING_DESCRIPTOR_TYPE == t)
|
|
||||||
{
|
|
||||||
TRACE_CORE(puts("=> USBD_SendDescriptor : USB_STRING_DESCRIPTOR_TYPE\r\n");)
|
|
||||||
if (setup.wValueL == 0) {
|
|
||||||
desc_addr = (const uint8_t*)&STRING_LANGUAGE;
|
|
||||||
}
|
|
||||||
else if (setup.wValueL == IPRODUCT) {
|
|
||||||
return USB_SendStringDescriptor(STRING_PRODUCT, setup.wLength);
|
|
||||||
}
|
|
||||||
else if (setup.wValueL == IMANUFACTURER) {
|
|
||||||
return USB_SendStringDescriptor(STRING_MANUFACTURER, setup.wLength);
|
|
||||||
}
|
|
||||||
else if (setup.wValueL == ISERIAL) {
|
|
||||||
#ifdef PLUGGABLE_USB_ENABLED
|
|
||||||
char name[ISERIAL_MAX_LEN];
|
|
||||||
PluggableUSB().getShortName(name);
|
|
||||||
return USB_SendStringDescriptor((uint8_t*)name, setup.wLength);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if( *desc_addr > setup.wLength ) {
|
|
||||||
desc_length = setup.wLength;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (USB_DEVICE_QUALIFIER == t)
|
|
||||||
{
|
|
||||||
// Device qualifier descriptor requested
|
|
||||||
desc_addr = (const uint8_t*)&USB_DeviceQualifier;
|
|
||||||
if( *desc_addr > setup.wLength ) {
|
|
||||||
desc_length = setup.wLength;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (USB_OTHER_SPEED_CONFIGURATION == t)
|
|
||||||
{
|
|
||||||
// Other configuration descriptor requested
|
|
||||||
return USBD_SendOtherConfiguration(setup.wLength);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//printf("Device ERROR");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desc_addr == 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desc_length == 0)
|
|
||||||
{
|
|
||||||
desc_length = *desc_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE_CORE(printf("=> USBD_SendDescriptor : desc_addr=%p desc_length=%d\r\n", desc_addr, desc_length);)
|
|
||||||
USBD_SendControl(0, desc_addr, desc_length);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void USB_SendZlp( void )
|
|
||||||
{
|
|
||||||
while( UOTGHS_DEVEPTISR_TXINI != (UOTGHS->UOTGHS_DEVEPTISR[0] & UOTGHS_DEVEPTISR_TXINI ) )
|
|
||||||
{
|
|
||||||
if((UOTGHS->UOTGHS_DEVISR & UOTGHS_DEVISR_SUSP) == UOTGHS_DEVISR_SUSP)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UOTGHS->UOTGHS_DEVEPTICR[0] = UOTGHS_DEVEPTICR_TXINIC;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void Test_Mode_Support( uint8_t wIndex )
|
|
||||||
{
|
|
||||||
uint8_t i;
|
|
||||||
uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(2);
|
|
||||||
|
|
||||||
switch( wIndex )
|
|
||||||
{
|
|
||||||
case 4:
|
|
||||||
//Test mode Test_Packet:
|
|
||||||
//Upon command, a port must repetitively transmit the following test packet until
|
|
||||||
//the exit action is taken. This enables the testing of rise and fall times, eye
|
|
||||||
//patterns, jitter, and any other dynamic waveform specifications.
|
|
||||||
//The test packet is made up by concatenating the following strings.
|
|
||||||
//(Note: For J/K NRZI data, and for NRZ data, the bit on the left is the first one
|
|
||||||
//transmitted. "S" indicates that a bit stuff occurs, which inserts an "extra" NRZI data bit.
|
|
||||||
//"* N" is used to indicate N occurrences of a string of bits or symbols.)
|
|
||||||
//A port in Test_Packet mode must send this packet repetitively. The inter-packet timing
|
|
||||||
//must be no less than the minimum allowable inter-packet gap as defined in Section 7.1.18 and
|
|
||||||
//no greater than 125 us.
|
|
||||||
|
|
||||||
// Send ZLP
|
|
||||||
USB_SendZlp();
|
|
||||||
|
|
||||||
UOTGHS->UOTGHS_DEVDMA[0].UOTGHS_DEVDMACONTROL = 0; // raz
|
|
||||||
UOTGHS->UOTGHS_DEVDMA[1].UOTGHS_DEVDMACONTROL = 0; // raz
|
|
||||||
|
|
||||||
// Configure endpoint 2, 64 bytes, direction IN, type BULK, 1 bank
|
|
||||||
UOTGHS->UOTGHS_DEVEPTCFG[2] = UOTGHS_DEVEPTCFG_EPSIZE_64_BYTE
|
|
||||||
| UOTGHS_DEVEPTCFG_EPDIR_IN
|
|
||||||
| UOTGHS_DEVEPTCFG_EPTYPE_BLK
|
|
||||||
| UOTGHS_DEVEPTCFG_EPBK_1_BANK;
|
|
||||||
// Check if the configuration is ok
|
|
||||||
UOTGHS->UOTGHS_DEVEPTCFG[2] |= UOTGHS_DEVEPTCFG_ALLOC;
|
|
||||||
while((UOTGHS->UOTGHS_DEVEPTISR[2]&UOTGHS_DEVEPTISR_CFGOK)==0) {}
|
|
||||||
UOTGHS->UOTGHS_DEVEPT |= UOTGHS_DEVEPT_EPEN2;
|
|
||||||
// Write FIFO
|
|
||||||
for( i=0; i<sizeof(test_packet_buffer); i++)
|
|
||||||
{
|
|
||||||
ptr_dest[i] = test_packet_buffer[i];;
|
|
||||||
}
|
|
||||||
// Tst PACKET
|
|
||||||
UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_TSTPCKT;
|
|
||||||
// Send packet
|
|
||||||
UOTGHS->UOTGHS_DEVEPTICR[2] = UOTGHS_DEVEPTICR_TXINIC;
|
|
||||||
UOTGHS->UOTGHS_DEVEPTIDR[2] = UOTGHS_DEVEPTIDR_FIFOCONC;
|
|
||||||
for(;;);
|
|
||||||
// break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
//Test mode Test_J:
|
|
||||||
//Upon command, a port's transceiver must enter the high-speed J state and remain in that
|
|
||||||
//state until the exit action is taken. This enables the testing of the high output drive
|
|
||||||
//level on the D+ line.
|
|
||||||
// Send a ZLP
|
|
||||||
USB_SendZlp();
|
|
||||||
UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_TSTJ;
|
|
||||||
for(;;);
|
|
||||||
// break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
//Test mode Test_K:
|
|
||||||
//Upon command, a port's transceiver must enter the high-speed K state and remain in
|
|
||||||
//that state until the exit action is taken. This enables the testing of the high output drive
|
|
||||||
//level on the D- line.
|
|
||||||
// Send a ZLP
|
|
||||||
USB_SendZlp();
|
|
||||||
UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_TSTK;
|
|
||||||
for(;;);
|
|
||||||
// break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
//Test mode Test_SE0_NAK:
|
|
||||||
//Upon command, a port's transceiver must enter the high-speed receive mode
|
|
||||||
//and remain in that mode until the exit action is taken. This enables the testing
|
|
||||||
//of output impedance, low level output voltage, and loading characteristics.
|
|
||||||
//In addition, while in this mode, upstream facing ports (and only upstream facing ports)
|
|
||||||
//must respond to any IN token packet with a NAK handshake (only if the packet CRC is
|
|
||||||
//determined to be correct) within the normal allowed device response time. This enables testing of
|
|
||||||
//the device squelch level circuitry and, additionally, provides a general purpose stimulus/response
|
|
||||||
//test for basic functional testing.
|
|
||||||
|
|
||||||
// Send a ZLP
|
|
||||||
USB_SendZlp();
|
|
||||||
UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_SUSPEC
|
|
||||||
| UOTGHS_DEVIDR_MSOFEC
|
|
||||||
| UOTGHS_DEVIDR_SOFEC
|
|
||||||
| UOTGHS_DEVIDR_EORSTEC
|
|
||||||
| UOTGHS_DEVIDR_WAKEUPEC
|
|
||||||
| UOTGHS_DEVIDR_EORSMEC
|
|
||||||
| UOTGHS_DEVIDR_UPRSMEC
|
|
||||||
| UOTGHS_DEVIDR_PEP_0
|
|
||||||
| UOTGHS_DEVIDR_PEP_1
|
|
||||||
| UOTGHS_DEVIDR_PEP_2
|
|
||||||
| UOTGHS_DEVIDR_PEP_3
|
|
||||||
| UOTGHS_DEVIDR_PEP_4
|
|
||||||
| UOTGHS_DEVIDR_PEP_5
|
|
||||||
| UOTGHS_DEVIDR_PEP_6
|
|
||||||
| UOTGHS_DEVIDR_DMA_1
|
|
||||||
| UOTGHS_DEVIDR_DMA_2
|
|
||||||
| UOTGHS_DEVIDR_DMA_3
|
|
||||||
| UOTGHS_DEVIDR_DMA_4
|
|
||||||
| UOTGHS_DEVIDR_DMA_5
|
|
||||||
| UOTGHS_DEVIDR_DMA_6;
|
|
||||||
for(;;);
|
|
||||||
// break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//unsigned int iii=0;
|
|
||||||
// Endpoint 0 interrupt
|
|
||||||
static void USB_ISR(void)
|
|
||||||
{
|
|
||||||
// printf("ISR=0x%X\n\r", UOTGHS->UOTGHS_DEVISR); // jcb
|
|
||||||
// if( iii++ > 1500 ) while(1); // jcb
|
|
||||||
// End of bus reset
|
|
||||||
if (Is_udd_reset())
|
|
||||||
{
|
|
||||||
TRACE_CORE(printf(">>> End of Reset\r\n");)
|
|
||||||
|
|
||||||
// Reset USB address to 0
|
|
||||||
udd_configure_address(0);
|
|
||||||
udd_enable_address();
|
|
||||||
|
|
||||||
// Configure EP 0
|
|
||||||
UDD_InitEP(0, EP_TYPE_CONTROL);
|
|
||||||
udd_enable_setup_received_interrupt(0);
|
|
||||||
udd_enable_endpoint_interrupt(0);
|
|
||||||
|
|
||||||
_usbConfiguration = 0;
|
|
||||||
udd_ack_reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CDC_ENABLED
|
|
||||||
if (Is_udd_endpoint_interrupt(CDC_RX))
|
|
||||||
{
|
|
||||||
udd_ack_out_received(CDC_RX);
|
|
||||||
|
|
||||||
// Handle received bytes
|
|
||||||
if (USBD_Available(CDC_RX))
|
|
||||||
SerialUSB.accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Is_udd_sof())
|
|
||||||
{
|
|
||||||
udd_ack_sof();
|
|
||||||
// USBD_Flush(CDC_TX); // jcb
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// EP 0 Interrupt
|
|
||||||
if (Is_udd_endpoint_interrupt(0) )
|
|
||||||
{
|
|
||||||
if (!UDD_ReceivedSetupInt())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
USBSetup setup;
|
|
||||||
UDD_Recv(EP0, (uint8_t*)&setup, 8);
|
|
||||||
UDD_ClearSetupInt();
|
|
||||||
|
|
||||||
uint8_t requestType = setup.bmRequestType;
|
|
||||||
if (requestType & REQUEST_DEVICETOHOST)
|
|
||||||
{
|
|
||||||
TRACE_CORE(puts(">>> EP0 Int: IN Request\r\n");)
|
|
||||||
UDD_WaitIN();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TRACE_CORE(puts(">>> EP0 Int: OUT Request\r\n");)
|
|
||||||
UDD_ClearIN();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ok = true;
|
|
||||||
if (REQUEST_STANDARD == (requestType & REQUEST_TYPE))
|
|
||||||
{
|
|
||||||
// Standard Requests
|
|
||||||
uint8_t r = setup.bRequest;
|
|
||||||
if (GET_STATUS == r)
|
|
||||||
{
|
|
||||||
if( setup.bmRequestType == 0 ) // device
|
|
||||||
{
|
|
||||||
// Send the device status
|
|
||||||
TRACE_CORE(puts(">>> EP0 Int: GET_STATUS\r\n");)
|
|
||||||
// Check current configuration for power mode (if device is configured)
|
|
||||||
// TODO
|
|
||||||
// Check if remote wake-up is enabled
|
|
||||||
// TODO
|
|
||||||
UDD_Send8(EP0, 0); // TODO
|
|
||||||
UDD_Send8(EP0, 0);
|
|
||||||
}
|
|
||||||
// if( setup.bmRequestType == 2 ) // Endpoint:
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Send the endpoint status
|
|
||||||
// Check if the endpoint if currently halted
|
|
||||||
if( isEndpointHalt == 1 )
|
|
||||||
UDD_Send8(EP0, 1); // TODO
|
|
||||||
else
|
|
||||||
UDD_Send8(EP0, 0); // TODO
|
|
||||||
UDD_Send8(EP0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (CLEAR_FEATURE == r)
|
|
||||||
{
|
|
||||||
// Check which is the selected feature
|
|
||||||
if( setup.wValueL == 1) // DEVICEREMOTEWAKEUP
|
|
||||||
{
|
|
||||||
// Enable remote wake-up and send a ZLP
|
|
||||||
if( isRemoteWakeUpEnabled == 1 )
|
|
||||||
UDD_Send8(EP0, 1);
|
|
||||||
else
|
|
||||||
UDD_Send8(EP0, 0);
|
|
||||||
UDD_Send8(EP0, 0);
|
|
||||||
}
|
|
||||||
else // if( setup.wValueL == 0) // ENDPOINTHALT
|
|
||||||
{
|
|
||||||
isEndpointHalt = 0; // TODO
|
|
||||||
UDD_Send8(EP0, 0);
|
|
||||||
UDD_Send8(EP0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (SET_FEATURE == r)
|
|
||||||
{
|
|
||||||
// Check which is the selected feature
|
|
||||||
if( setup.wValueL == 1) // DEVICEREMOTEWAKEUP
|
|
||||||
{
|
|
||||||
// Enable remote wake-up and send a ZLP
|
|
||||||
isRemoteWakeUpEnabled = 1;
|
|
||||||
UDD_Send8(EP0, 0);
|
|
||||||
}
|
|
||||||
if( setup.wValueL == 0) // ENDPOINTHALT
|
|
||||||
{
|
|
||||||
// Halt endpoint
|
|
||||||
isEndpointHalt = 1;
|
|
||||||
//USBD_Halt(USBGenericRequest_GetEndpointNumber(pRequest));
|
|
||||||
UDD_Send8(EP0, 0);
|
|
||||||
}
|
|
||||||
if( setup.wValueL == 2) // TEST_MODE
|
|
||||||
{
|
|
||||||
// 7.1.20 Test Mode Support, 9.4.9 SetFeature
|
|
||||||
if( (setup.bmRequestType == 0 /*USBGenericRequest_DEVICE*/) &&
|
|
||||||
((setup.wIndex & 0x000F) == 0) )
|
|
||||||
{
|
|
||||||
// the lower byte of wIndex must be zero
|
|
||||||
// the most significant byte of wIndex is used to specify the specific test mode
|
|
||||||
|
|
||||||
UOTGHS->UOTGHS_DEVIDR &= ~UOTGHS_DEVIDR_SUSPEC;
|
|
||||||
UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_SPDCONF_HIGH_SPEED; // remove suspend ?
|
|
||||||
|
|
||||||
Test_Mode_Support( (setup.wIndex & 0xFF00)>>8 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (SET_ADDRESS == r)
|
|
||||||
{
|
|
||||||
TRACE_CORE(puts(">>> EP0 Int: SET_ADDRESS\r\n");)
|
|
||||||
UDD_WaitIN();
|
|
||||||
UDD_SetAddress(setup.wValueL);
|
|
||||||
}
|
|
||||||
else if (GET_DESCRIPTOR == r)
|
|
||||||
{
|
|
||||||
TRACE_CORE(puts(">>> EP0 Int: GET_DESCRIPTOR\r\n");)
|
|
||||||
ok = USBD_SendDescriptor(setup);
|
|
||||||
}
|
|
||||||
else if (SET_DESCRIPTOR == r)
|
|
||||||
{
|
|
||||||
TRACE_CORE(puts(">>> EP0 Int: SET_DESCRIPTOR\r\n");)
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
else if (GET_CONFIGURATION == r)
|
|
||||||
{
|
|
||||||
TRACE_CORE(puts(">>> EP0 Int: GET_CONFIGURATION\r\n");)
|
|
||||||
UDD_Send8(EP0, _usbConfiguration);
|
|
||||||
}
|
|
||||||
else if (SET_CONFIGURATION == r)
|
|
||||||
{
|
|
||||||
if (REQUEST_DEVICE == (requestType & REQUEST_RECIPIENT))
|
|
||||||
{
|
|
||||||
TRACE_CORE(printf(">>> EP0 Int: SET_CONFIGURATION REQUEST_DEVICE %d\r\n", setup.wValueL);)
|
|
||||||
|
|
||||||
uint32_t num_endpoints = 0;
|
|
||||||
while (EndPoints[num_endpoints] != 0) {
|
|
||||||
num_endpoints++;
|
|
||||||
}
|
|
||||||
UDD_InitEndpoints(EndPoints, num_endpoints);
|
|
||||||
_usbConfiguration = setup.wValueL;
|
|
||||||
|
|
||||||
#ifdef CDC_ENABLED
|
|
||||||
// Enable interrupt for CDC reception from host (OUT packet)
|
|
||||||
udd_enable_out_received_interrupt(CDC_RX);
|
|
||||||
udd_enable_endpoint_interrupt(CDC_RX);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TRACE_CORE(puts(">>> EP0 Int: SET_CONFIGURATION failed!\r\n");)
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (GET_INTERFACE == r)
|
|
||||||
{
|
|
||||||
TRACE_CORE(puts(">>> EP0 Int: GET_INTERFACE\r\n");)
|
|
||||||
UDD_Send8(EP0, _usbSetInterface);
|
|
||||||
}
|
|
||||||
else if (SET_INTERFACE == r)
|
|
||||||
{
|
|
||||||
_usbSetInterface = setup.wValueL;
|
|
||||||
TRACE_CORE(puts(">>> EP0 Int: SET_INTERFACE\r\n");)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TRACE_CORE(puts(">>> EP0 Int: ClassInterfaceRequest\r\n");)
|
|
||||||
|
|
||||||
UDD_WaitIN(); // Workaround: need tempo here, else CDC serial won't open correctly
|
|
||||||
|
|
||||||
USBD_InitControl(setup.wLength); // Max length of transfer
|
|
||||||
ok = USBD_ClassInterfaceRequest(setup);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ok)
|
|
||||||
{
|
|
||||||
TRACE_CORE(puts(">>> EP0 Int: Send packet\r\n");)
|
|
||||||
UDD_ClearIN();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TRACE_CORE(puts(">>> EP0 Int: Stall\r\n");)
|
|
||||||
UDD_Stall();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void USBD_Flush(uint32_t ep)
|
|
||||||
{
|
|
||||||
if (UDD_FifoByteCount(ep))
|
|
||||||
UDD_ReleaseTX(ep);
|
|
||||||
}
|
|
||||||
|
|
||||||
// VBUS or counting frames
|
|
||||||
// Any frame counting?
|
|
||||||
uint32_t USBD_Connected(void)
|
|
||||||
{
|
|
||||||
uint8_t f = UDD_GetFrameNumber();
|
|
||||||
|
|
||||||
delay(3);
|
|
||||||
|
|
||||||
return f != UDD_GetFrameNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//=======================================================================
|
|
||||||
//=======================================================================
|
|
||||||
|
|
||||||
USBDevice_ USBDevice;
|
|
||||||
|
|
||||||
USBDevice_::USBDevice_()
|
|
||||||
{
|
|
||||||
UDD_SetStack(&USB_ISR);
|
|
||||||
|
|
||||||
if (UDD_Init() == 0UL)
|
|
||||||
{
|
|
||||||
_usbInitialized=1UL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool USBDevice_::attach(void)
|
|
||||||
{
|
|
||||||
if (_usbInitialized != 0UL)
|
|
||||||
{
|
|
||||||
UDD_Attach();
|
|
||||||
_usbConfiguration = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool USBDevice_::detach(void)
|
|
||||||
{
|
|
||||||
if (_usbInitialized != 0UL)
|
|
||||||
{
|
|
||||||
UDD_Detach();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for interrupts
|
|
||||||
// TODO: VBUS detection
|
|
||||||
bool USBDevice_::configured()
|
|
||||||
{
|
|
||||||
return _usbConfiguration;
|
|
||||||
}
|
|
||||||
|
|
||||||
void USBDevice_::poll()
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,293 +0,0 @@
|
|||||||
// Copyright (c) 2010, Peter Barrett
|
|
||||||
/*
|
|
||||||
** Permission to use, copy, modify, and/or distribute this software for
|
|
||||||
** any purpose with or without fee is hereby granted, provided that the
|
|
||||||
** above copyright notice and this permission notice appear in all copies.
|
|
||||||
**
|
|
||||||
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
|
||||||
** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
|
||||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
|
||||||
** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
|
||||||
** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
||||||
** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|
||||||
** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|
||||||
** SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __USBCORE_H__
|
|
||||||
#define __USBCORE_H__
|
|
||||||
|
|
||||||
// Standard requests
|
|
||||||
#define GET_STATUS 0
|
|
||||||
#define CLEAR_FEATURE 1
|
|
||||||
#define SET_FEATURE 3
|
|
||||||
#define SET_ADDRESS 5
|
|
||||||
#define GET_DESCRIPTOR 6
|
|
||||||
#define SET_DESCRIPTOR 7
|
|
||||||
#define GET_CONFIGURATION 8
|
|
||||||
#define SET_CONFIGURATION 9
|
|
||||||
#define GET_INTERFACE 10
|
|
||||||
#define SET_INTERFACE 11
|
|
||||||
|
|
||||||
|
|
||||||
// bmRequestType
|
|
||||||
#define REQUEST_HOSTTODEVICE 0x00
|
|
||||||
#define REQUEST_DEVICETOHOST 0x80
|
|
||||||
#define REQUEST_DIRECTION 0x80
|
|
||||||
|
|
||||||
#define REQUEST_STANDARD 0x00
|
|
||||||
#define REQUEST_CLASS 0x20
|
|
||||||
#define REQUEST_VENDOR 0x40
|
|
||||||
#define REQUEST_TYPE 0x60
|
|
||||||
|
|
||||||
#define REQUEST_DEVICE 0x00
|
|
||||||
#define REQUEST_INTERFACE 0x01
|
|
||||||
#define REQUEST_ENDPOINT 0x02
|
|
||||||
#define REQUEST_OTHER 0x03
|
|
||||||
#define REQUEST_RECIPIENT 0x1F
|
|
||||||
|
|
||||||
#define REQUEST_DEVICETOHOST_CLASS_INTERFACE (REQUEST_DEVICETOHOST | REQUEST_CLASS | REQUEST_INTERFACE)
|
|
||||||
#define REQUEST_HOSTTODEVICE_CLASS_INTERFACE (REQUEST_HOSTTODEVICE | REQUEST_CLASS | REQUEST_INTERFACE)
|
|
||||||
#define REQUEST_DEVICETOHOST_STANDARD_INTERFACE (REQUEST_DEVICETOHOST | REQUEST_STANDARD | REQUEST_INTERFACE)
|
|
||||||
|
|
||||||
// Class requests
|
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
||||||
// Descriptors
|
|
||||||
|
|
||||||
#define USB_DEVICE_DESC_SIZE 18
|
|
||||||
#define USB_CONFIGUARTION_DESC_SIZE 9
|
|
||||||
#define USB_INTERFACE_DESC_SIZE 9
|
|
||||||
#define USB_ENDPOINT_DESC_SIZE 7
|
|
||||||
|
|
||||||
#define USB_DEVICE_DESCRIPTOR_TYPE 1
|
|
||||||
#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2
|
|
||||||
#define USB_STRING_DESCRIPTOR_TYPE 3
|
|
||||||
#define USB_INTERFACE_DESCRIPTOR_TYPE 4
|
|
||||||
#define USB_ENDPOINT_DESCRIPTOR_TYPE 5
|
|
||||||
#define USB_DEVICE_QUALIFIER 6
|
|
||||||
#define USB_OTHER_SPEED_CONFIGURATION 7
|
|
||||||
|
|
||||||
#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02
|
|
||||||
#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03
|
|
||||||
#define USB_DEVICE_CLASS_STORAGE 0x08
|
|
||||||
#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF
|
|
||||||
|
|
||||||
#define USB_CONFIG_POWERED_MASK 0x40
|
|
||||||
#define USB_CONFIG_BUS_POWERED 0x80
|
|
||||||
#define USB_CONFIG_SELF_POWERED 0xC0
|
|
||||||
#define USB_CONFIG_REMOTE_WAKEUP 0x20
|
|
||||||
|
|
||||||
// bMaxPower in Configuration Descriptor
|
|
||||||
#define USB_CONFIG_POWER_MA(mA) ((mA)/2)
|
|
||||||
|
|
||||||
// bEndpointAddress in Endpoint Descriptor
|
|
||||||
#define USB_ENDPOINT_DIRECTION_MASK 0x80
|
|
||||||
#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00)
|
|
||||||
#define USB_ENDPOINT_IN(addr) ((addr) | 0x80)
|
|
||||||
|
|
||||||
#define USB_ENDPOINTS 7
|
|
||||||
|
|
||||||
#define USB_ENDPOINT_TYPE_MASK 0x03
|
|
||||||
#define USB_ENDPOINT_TYPE_CONTROL 0x00
|
|
||||||
#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
|
|
||||||
#define USB_ENDPOINT_TYPE_BULK 0x02
|
|
||||||
#define USB_ENDPOINT_TYPE_INTERRUPT 0x03
|
|
||||||
|
|
||||||
#define TOBYTES(x) ((x) & 0xFF),(((x) >> 8) & 0xFF)
|
|
||||||
|
|
||||||
#define CDC_V1_10 0x0110
|
|
||||||
#define CDC_COMMUNICATION_INTERFACE_CLASS 0x02
|
|
||||||
|
|
||||||
#define CDC_CALL_MANAGEMENT 0x01
|
|
||||||
#define CDC_ABSTRACT_CONTROL_MODEL 0x02
|
|
||||||
#define CDC_HEADER 0x00
|
|
||||||
#define CDC_ABSTRACT_CONTROL_MANAGEMENT 0x02
|
|
||||||
#define CDC_UNION 0x06
|
|
||||||
#define CDC_CS_INTERFACE 0x24
|
|
||||||
#define CDC_CS_ENDPOINT 0x25
|
|
||||||
#define CDC_DATA_INTERFACE_CLASS 0x0A
|
|
||||||
|
|
||||||
#define MSC_SUBCLASS_SCSI 0x06
|
|
||||||
#define MSC_PROTOCOL_BULK_ONLY 0x50
|
|
||||||
|
|
||||||
_Pragma("pack(1)")
|
|
||||||
|
|
||||||
// Device
|
|
||||||
typedef struct {
|
|
||||||
uint8_t len; // 18
|
|
||||||
uint8_t dtype; // 1 USB_DEVICE_DESCRIPTOR_TYPE
|
|
||||||
uint16_t usbVersion; // 0x200
|
|
||||||
uint8_t deviceClass;
|
|
||||||
uint8_t deviceSubClass;
|
|
||||||
uint8_t deviceProtocol;
|
|
||||||
uint8_t packetSize0; // Packet 0
|
|
||||||
uint16_t idVendor;
|
|
||||||
uint16_t idProduct;
|
|
||||||
uint16_t deviceVersion; // 0x100
|
|
||||||
uint8_t iManufacturer;
|
|
||||||
uint8_t iProduct;
|
|
||||||
uint8_t iSerialNumber;
|
|
||||||
uint8_t bNumConfigurations;
|
|
||||||
} DeviceDescriptor;
|
|
||||||
|
|
||||||
// Config
|
|
||||||
typedef struct {
|
|
||||||
uint8_t len; // 9
|
|
||||||
uint8_t dtype; // 2
|
|
||||||
uint16_t clen; // total length
|
|
||||||
uint8_t numInterfaces;
|
|
||||||
uint8_t config;
|
|
||||||
uint8_t iconfig;
|
|
||||||
uint8_t attributes;
|
|
||||||
uint8_t maxPower;
|
|
||||||
} ConfigDescriptor;
|
|
||||||
|
|
||||||
// Device Qualifier (only needed for USB2.0 devices)
|
|
||||||
typedef struct {
|
|
||||||
uint8_t bLength;
|
|
||||||
uint8_t dtype;
|
|
||||||
uint16_t bDescriptorType;
|
|
||||||
uint8_t bDeviceClass;
|
|
||||||
uint8_t bDeviceSubClass;
|
|
||||||
uint8_t bDeviceProtocol;
|
|
||||||
uint8_t bMaxPacketSize0;
|
|
||||||
uint8_t bNumConfigurations;
|
|
||||||
} QualifierDescriptor;
|
|
||||||
|
|
||||||
// String
|
|
||||||
|
|
||||||
// Interface
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t len; // 9
|
|
||||||
uint8_t dtype; // 4
|
|
||||||
uint8_t number;
|
|
||||||
uint8_t alternate;
|
|
||||||
uint8_t numEndpoints;
|
|
||||||
uint8_t interfaceClass;
|
|
||||||
uint8_t interfaceSubClass;
|
|
||||||
uint8_t protocol;
|
|
||||||
uint8_t iInterface;
|
|
||||||
} InterfaceDescriptor;
|
|
||||||
|
|
||||||
// Endpoint
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t len; // 7
|
|
||||||
uint8_t dtype; // 5
|
|
||||||
uint8_t addr;
|
|
||||||
uint8_t attr;
|
|
||||||
uint16_t packetSize;
|
|
||||||
uint8_t interval;
|
|
||||||
} EndpointDescriptor;
|
|
||||||
|
|
||||||
// Interface Association Descriptor
|
|
||||||
// Used to bind 2 interfaces together in CDC compostite device
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t len; // 8
|
|
||||||
uint8_t dtype; // 11
|
|
||||||
uint8_t firstInterface;
|
|
||||||
uint8_t interfaceCount;
|
|
||||||
uint8_t functionClass;
|
|
||||||
uint8_t funtionSubClass;
|
|
||||||
uint8_t functionProtocol;
|
|
||||||
uint8_t iInterface;
|
|
||||||
} IADDescriptor;
|
|
||||||
|
|
||||||
// CDC CS interface descriptor
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t len; // 5
|
|
||||||
uint8_t dtype; // 0x24
|
|
||||||
uint8_t subtype;
|
|
||||||
uint8_t d0;
|
|
||||||
uint8_t d1;
|
|
||||||
} CDCCSInterfaceDescriptor;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t len; // 4
|
|
||||||
uint8_t dtype; // 0x24
|
|
||||||
uint8_t subtype;
|
|
||||||
uint8_t d0;
|
|
||||||
} CDCCSInterfaceDescriptor4;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t len;
|
|
||||||
uint8_t dtype; // 0x24
|
|
||||||
uint8_t subtype; // 1
|
|
||||||
uint8_t bmCapabilities;
|
|
||||||
uint8_t bDataInterface;
|
|
||||||
} CMFunctionalDescriptor;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t len;
|
|
||||||
uint8_t dtype; // 0x24
|
|
||||||
uint8_t subtype; // 1
|
|
||||||
uint8_t bmCapabilities;
|
|
||||||
} ACMFunctionalDescriptor;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
// IAD
|
|
||||||
IADDescriptor iad; // Only needed on compound device
|
|
||||||
|
|
||||||
// Control
|
|
||||||
InterfaceDescriptor cif;
|
|
||||||
CDCCSInterfaceDescriptor header;
|
|
||||||
CMFunctionalDescriptor callManagement; // Call Management
|
|
||||||
ACMFunctionalDescriptor controlManagement; // ACM
|
|
||||||
CDCCSInterfaceDescriptor functionalDescriptor; // CDC_UNION
|
|
||||||
EndpointDescriptor cifin;
|
|
||||||
|
|
||||||
// Data
|
|
||||||
InterfaceDescriptor dif;
|
|
||||||
EndpointDescriptor in;
|
|
||||||
EndpointDescriptor out;
|
|
||||||
} CDCDescriptor;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
InterfaceDescriptor msc;
|
|
||||||
EndpointDescriptor in;
|
|
||||||
EndpointDescriptor out;
|
|
||||||
} MSCDescriptor;
|
|
||||||
|
|
||||||
_Pragma("pack()")
|
|
||||||
|
|
||||||
#define D_DEVICE(_class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs) \
|
|
||||||
{ 18, 1, 0x200, _class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs }
|
|
||||||
|
|
||||||
#define D_CONFIG(_totalLength,_interfaces) \
|
|
||||||
{ 9, 2, (uint16_t)(_totalLength),_interfaces, 1, 0, USB_CONFIG_SELF_POWERED, USB_CONFIG_POWER_MA(500) }
|
|
||||||
|
|
||||||
#define D_OTHERCONFIG(_totalLength,_interfaces) \
|
|
||||||
{ 9, 7, (uint16_t)(_totalLength),_interfaces, 1, 0, USB_CONFIG_SELF_POWERED, USB_CONFIG_POWER_MA(500) }
|
|
||||||
|
|
||||||
#define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \
|
|
||||||
{ 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 }
|
|
||||||
|
|
||||||
#define D_ENDPOINT(_addr,_attr,_packetSize, _interval) \
|
|
||||||
{ 7, 5, (uint8_t)(_addr),_attr,_packetSize, _interval }
|
|
||||||
|
|
||||||
#define D_QUALIFIER(_class,_subClass,_proto,_packetSize0,_configs) \
|
|
||||||
{ 10, 6, 0x200, _class,_subClass,_proto,_packetSize0,_configs }
|
|
||||||
|
|
||||||
#define D_IAD(_firstInterface, _count, _class, _subClass, _protocol) \
|
|
||||||
{ 8, 11, _firstInterface, _count, _class, _subClass, _protocol, 0 }
|
|
||||||
|
|
||||||
#define D_CDCCS(_subtype,_d0,_d1) { 5, 0x24, _subtype, _d0, _d1 }
|
|
||||||
#define D_CDCCS4(_subtype,_d0) { 4, 0x24, _subtype, _d0 }
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,51 +0,0 @@
|
|||||||
// Copyright (c) 2010, Peter Barrett
|
|
||||||
/*
|
|
||||||
** Permission to use, copy, modify, and/or distribute this software for
|
|
||||||
** any purpose with or without fee is hereby granted, provided that the
|
|
||||||
** above copyright notice and this permission notice appear in all copies.
|
|
||||||
**
|
|
||||||
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
|
||||||
** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
|
||||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
|
||||||
** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
|
||||||
** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
||||||
** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|
||||||
** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|
||||||
** SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __USBDESC_H__
|
|
||||||
#define __USBDESC_H__
|
|
||||||
|
|
||||||
#define CDC_ENABLED
|
|
||||||
#define PLUGGABLE_USB_ENABLED
|
|
||||||
|
|
||||||
#ifdef CDC_ENABLED
|
|
||||||
#define CDC_INTERFACE_COUNT 2
|
|
||||||
#define CDC_ENPOINT_COUNT 3
|
|
||||||
#else
|
|
||||||
#define CDC_INTERFACE_COUNT 0
|
|
||||||
#define CDC_ENPOINT_COUNT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CDC_ACM_INTERFACE 0 // CDC ACM
|
|
||||||
#define CDC_DATA_INTERFACE 1 // CDC Data
|
|
||||||
#define CDC_FIRST_ENDPOINT 1
|
|
||||||
#define CDC_ENDPOINT_ACM (CDC_FIRST_ENDPOINT) // CDC First
|
|
||||||
#define CDC_ENDPOINT_OUT (CDC_FIRST_ENDPOINT+1)
|
|
||||||
#define CDC_ENDPOINT_IN (CDC_FIRST_ENDPOINT+2)
|
|
||||||
|
|
||||||
#define INTERFACE_COUNT (MSC_INTERFACE + MSC_INTERFACE_COUNT)
|
|
||||||
|
|
||||||
#ifdef CDC_ENABLED
|
|
||||||
#define CDC_RX CDC_ENDPOINT_OUT
|
|
||||||
#define CDC_TX CDC_ENDPOINT_IN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ISERIAL_MAX_LEN 20
|
|
||||||
|
|
||||||
#define IMANUFACTURER 1
|
|
||||||
#define IPRODUCT 2
|
|
||||||
#define ISERIAL 3
|
|
||||||
|
|
||||||
#endif /* __USBDESC_H__ */
|
|
@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
* Udp.cpp: Library to send/receive UDP packets.
|
|
||||||
*
|
|
||||||
* NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
|
|
||||||
* 1) UDP does not guarantee the order in which assembled UDP packets are received. This
|
|
||||||
* might not happen often in practice, but in larger network topologies, a UDP
|
|
||||||
* packet can be received out of sequence.
|
|
||||||
* 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
|
|
||||||
* aware of it. Again, this may not be a concern in practice on small local networks.
|
|
||||||
* For more information, see http://www.cafeaulait.org/course/week12/35.html
|
|
||||||
*
|
|
||||||
* MIT License:
|
|
||||||
* Copyright (c) 2008 Bjoern Hartmann
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* bjoern@cs.stanford.edu 12/30/2008
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef udp_h
|
|
||||||
#define udp_h
|
|
||||||
|
|
||||||
#include <Stream.h>
|
|
||||||
#include <IPAddress.h>
|
|
||||||
|
|
||||||
class UDP : public Stream {
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
|
|
||||||
virtual void stop() =0; // Finish with the UDP socket
|
|
||||||
|
|
||||||
// Sending UDP packets
|
|
||||||
|
|
||||||
// Start building up a packet to send to the remote host specific in ip and port
|
|
||||||
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
|
|
||||||
virtual int beginPacket(IPAddress ip, uint16_t port) =0;
|
|
||||||
// Start building up a packet to send to the remote host specific in host and port
|
|
||||||
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
|
|
||||||
virtual int beginPacket(const char *host, uint16_t port) =0;
|
|
||||||
// Finish off this packet and send it
|
|
||||||
// Returns 1 if the packet was sent successfully, 0 if there was an error
|
|
||||||
virtual int endPacket() =0;
|
|
||||||
// Write a single byte into the packet
|
|
||||||
virtual size_t write(uint8_t) =0;
|
|
||||||
// Write size bytes from buffer into the packet
|
|
||||||
virtual size_t write(const uint8_t *buffer, size_t size) =0;
|
|
||||||
|
|
||||||
// Start processing the next available incoming packet
|
|
||||||
// Returns the size of the packet in bytes, or 0 if no packets are available
|
|
||||||
virtual int parsePacket() =0;
|
|
||||||
// Number of bytes remaining in the current packet
|
|
||||||
virtual int available() =0;
|
|
||||||
// Read a single byte from the current packet
|
|
||||||
virtual int read() =0;
|
|
||||||
// Read up to len bytes from the current packet and place them into buffer
|
|
||||||
// Returns the number of bytes read, or 0 if none are available
|
|
||||||
virtual int read(unsigned char* buffer, size_t len) =0;
|
|
||||||
// Read up to len characters from the current packet and place them into buffer
|
|
||||||
// Returns the number of characters read, or 0 if none are available
|
|
||||||
virtual int read(char* buffer, size_t len) =0;
|
|
||||||
// Return the next byte from the current packet without moving on to the next byte
|
|
||||||
virtual int peek() =0;
|
|
||||||
virtual void flush() =0; // Finish reading the current packet
|
|
||||||
|
|
||||||
// Return the IP address of the host who sent the current incoming packet
|
|
||||||
virtual IPAddress remoteIP() =0;
|
|
||||||
// Return the port of the host who sent the current incoming packet
|
|
||||||
virtual uint16_t remotePort() =0;
|
|
||||||
protected:
|
|
||||||
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,180 +0,0 @@
|
|||||||
/*
|
|
||||||
WCharacter.h - Character utility functions for Wiring & Arduino
|
|
||||||
Copyright (c) 2010 Hernando Barragan. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef Character_h
|
|
||||||
#define Character_h
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// WCharacter.h prototypes
|
|
||||||
#if defined ( __GNUC__ )
|
|
||||||
inline boolean isAlphaNumeric(int c) __attribute__((always_inline));
|
|
||||||
inline boolean isAlpha(int c) __attribute__((always_inline));
|
|
||||||
inline boolean isAscii(int c) __attribute__((always_inline));
|
|
||||||
inline boolean isWhitespace(int c) __attribute__((always_inline));
|
|
||||||
inline boolean isControl(int c) __attribute__((always_inline));
|
|
||||||
inline boolean isDigit(int c) __attribute__((always_inline));
|
|
||||||
inline boolean isGraph(int c) __attribute__((always_inline));
|
|
||||||
inline boolean isLowerCase(int c) __attribute__((always_inline));
|
|
||||||
inline boolean isPrintable(int c) __attribute__((always_inline));
|
|
||||||
inline boolean isPunct(int c) __attribute__((always_inline));
|
|
||||||
inline boolean isSpace(int c) __attribute__((always_inline));
|
|
||||||
inline boolean isUpperCase(int c) __attribute__((always_inline));
|
|
||||||
inline boolean isHexadecimalDigit(int c) __attribute__((always_inline));
|
|
||||||
inline int toAscii(int c) __attribute__((always_inline));
|
|
||||||
inline int toLowerCase(int c) __attribute__((always_inline));
|
|
||||||
inline int toUpperCase(int c)__attribute__((always_inline));
|
|
||||||
#elif defined ( __ICCARM__ )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Checks for an alphanumeric character.
|
|
||||||
// It is equivalent to (isalpha(c) || isdigit(c)).
|
|
||||||
inline boolean isAlphaNumeric(int c)
|
|
||||||
{
|
|
||||||
return ( isalnum(c) == 0 ? false : true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Checks for an alphabetic character.
|
|
||||||
// It is equivalent to (isupper(c) || islower(c)).
|
|
||||||
inline boolean isAlpha(int c)
|
|
||||||
{
|
|
||||||
return ( isalpha(c) == 0 ? false : true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Checks whether c is a 7-bit unsigned char value
|
|
||||||
// that fits into the ASCII character set.
|
|
||||||
inline boolean isAscii(int c)
|
|
||||||
{
|
|
||||||
/* return ( isascii(c) == 0 ? false : true); */
|
|
||||||
return ( (c & ~0x7f) != 0 ? false : true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Checks for a blank character, that is, a space or a tab.
|
|
||||||
inline boolean isWhitespace(int c)
|
|
||||||
{
|
|
||||||
return ( isblank (c) == 0 ? false : true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Checks for a control character.
|
|
||||||
inline boolean isControl(int c)
|
|
||||||
{
|
|
||||||
return ( iscntrl (c) == 0 ? false : true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Checks for a digit (0 through 9).
|
|
||||||
inline boolean isDigit(int c)
|
|
||||||
{
|
|
||||||
return ( isdigit (c) == 0 ? false : true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Checks for any printable character except space.
|
|
||||||
inline boolean isGraph(int c)
|
|
||||||
{
|
|
||||||
return ( isgraph (c) == 0 ? false : true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Checks for a lower-case character.
|
|
||||||
inline boolean isLowerCase(int c)
|
|
||||||
{
|
|
||||||
return (islower (c) == 0 ? false : true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Checks for any printable character including space.
|
|
||||||
inline boolean isPrintable(int c)
|
|
||||||
{
|
|
||||||
return ( isprint (c) == 0 ? false : true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Checks for any printable character which is not a space
|
|
||||||
// or an alphanumeric character.
|
|
||||||
inline boolean isPunct(int c)
|
|
||||||
{
|
|
||||||
return ( ispunct (c) == 0 ? false : true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Checks for white-space characters. For the avr-libc library,
|
|
||||||
// these are: space, formfeed ('\f'), newline ('\n'), carriage
|
|
||||||
// return ('\r'), horizontal tab ('\t'), and vertical tab ('\v').
|
|
||||||
inline boolean isSpace(int c)
|
|
||||||
{
|
|
||||||
return ( isspace (c) == 0 ? false : true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Checks for an uppercase letter.
|
|
||||||
inline boolean isUpperCase(int c)
|
|
||||||
{
|
|
||||||
return ( isupper (c) == 0 ? false : true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7
|
|
||||||
// 8 9 a b c d e f A B C D E F.
|
|
||||||
inline boolean isHexadecimalDigit(int c)
|
|
||||||
{
|
|
||||||
return ( isxdigit (c) == 0 ? false : true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Converts c to a 7-bit unsigned char value that fits into the
|
|
||||||
// ASCII character set, by clearing the high-order bits.
|
|
||||||
inline int toAscii(int c)
|
|
||||||
{
|
|
||||||
/* return toascii (c); */
|
|
||||||
return (c & 0x7f);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Warning:
|
|
||||||
// Many people will be unhappy if you use this function.
|
|
||||||
// This function will convert accented letters into random
|
|
||||||
// characters.
|
|
||||||
|
|
||||||
// Converts the letter c to lower case, if possible.
|
|
||||||
inline int toLowerCase(int c)
|
|
||||||
{
|
|
||||||
return tolower (c);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Converts the letter c to upper case, if possible.
|
|
||||||
inline int toUpperCase(int c)
|
|
||||||
{
|
|
||||||
return toupper (c);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,182 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011-2012 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "WInterrupts.h"
|
|
||||||
|
|
||||||
typedef void (*interruptCB)(void);
|
|
||||||
|
|
||||||
static interruptCB callbacksPioA[32];
|
|
||||||
static interruptCB callbacksPioB[32];
|
|
||||||
static interruptCB callbacksPioC[32];
|
|
||||||
static interruptCB callbacksPioD[32];
|
|
||||||
|
|
||||||
/* Configure PIO interrupt sources */
|
|
||||||
static void __initialize() {
|
|
||||||
int i;
|
|
||||||
for (i=0; i<32; i++) {
|
|
||||||
callbacksPioA[i] = NULL;
|
|
||||||
callbacksPioB[i] = NULL;
|
|
||||||
callbacksPioC[i] = NULL;
|
|
||||||
callbacksPioD[i] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pmc_enable_periph_clk(ID_PIOA);
|
|
||||||
NVIC_DisableIRQ(PIOA_IRQn);
|
|
||||||
NVIC_ClearPendingIRQ(PIOA_IRQn);
|
|
||||||
NVIC_SetPriority(PIOA_IRQn, 0);
|
|
||||||
NVIC_EnableIRQ(PIOA_IRQn);
|
|
||||||
|
|
||||||
pmc_enable_periph_clk(ID_PIOB);
|
|
||||||
NVIC_DisableIRQ(PIOB_IRQn);
|
|
||||||
NVIC_ClearPendingIRQ(PIOB_IRQn);
|
|
||||||
NVIC_SetPriority(PIOB_IRQn, 0);
|
|
||||||
NVIC_EnableIRQ(PIOB_IRQn);
|
|
||||||
|
|
||||||
pmc_enable_periph_clk(ID_PIOC);
|
|
||||||
NVIC_DisableIRQ(PIOC_IRQn);
|
|
||||||
NVIC_ClearPendingIRQ(PIOC_IRQn);
|
|
||||||
NVIC_SetPriority(PIOC_IRQn, 0);
|
|
||||||
NVIC_EnableIRQ(PIOC_IRQn);
|
|
||||||
|
|
||||||
pmc_enable_periph_clk(ID_PIOD);
|
|
||||||
NVIC_DisableIRQ(PIOD_IRQn);
|
|
||||||
NVIC_ClearPendingIRQ(PIOD_IRQn);
|
|
||||||
NVIC_SetPriority(PIOD_IRQn, 0);
|
|
||||||
NVIC_EnableIRQ(PIOD_IRQn);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void attachInterrupt(uint32_t pin, void (*callback)(void), uint32_t mode)
|
|
||||||
{
|
|
||||||
static int enabled = 0;
|
|
||||||
if (!enabled) {
|
|
||||||
__initialize();
|
|
||||||
enabled = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve pin information
|
|
||||||
Pio *pio = g_APinDescription[pin].pPort;
|
|
||||||
uint32_t mask = g_APinDescription[pin].ulPin;
|
|
||||||
uint32_t pos = 0;
|
|
||||||
|
|
||||||
uint32_t t;
|
|
||||||
for (t = mask; t>1; t>>=1, pos++)
|
|
||||||
;
|
|
||||||
|
|
||||||
// Set callback function
|
|
||||||
if (pio == PIOA)
|
|
||||||
callbacksPioA[pos] = callback;
|
|
||||||
if (pio == PIOB)
|
|
||||||
callbacksPioB[pos] = callback;
|
|
||||||
if (pio == PIOC)
|
|
||||||
callbacksPioC[pos] = callback;
|
|
||||||
if (pio == PIOD)
|
|
||||||
callbacksPioD[pos] = callback;
|
|
||||||
|
|
||||||
// Configure the interrupt mode
|
|
||||||
if (mode == CHANGE) {
|
|
||||||
// Disable additional interrupt mode (detects both rising and falling edges)
|
|
||||||
pio->PIO_AIMDR = mask;
|
|
||||||
} else {
|
|
||||||
// Enable additional interrupt mode
|
|
||||||
pio->PIO_AIMER = mask;
|
|
||||||
|
|
||||||
// Select mode of operation
|
|
||||||
if (mode == LOW) {
|
|
||||||
pio->PIO_LSR = mask; // "Level" Select Register
|
|
||||||
pio->PIO_FELLSR = mask; // "Falling Edge / Low Level" Select Register
|
|
||||||
}
|
|
||||||
if (mode == HIGH) {
|
|
||||||
pio->PIO_LSR = mask; // "Level" Select Register
|
|
||||||
pio->PIO_REHLSR = mask; // "Rising Edge / High Level" Select Register
|
|
||||||
}
|
|
||||||
if (mode == FALLING) {
|
|
||||||
pio->PIO_ESR = mask; // "Edge" Select Register
|
|
||||||
pio->PIO_FELLSR = mask; // "Falling Edge / Low Level" Select Register
|
|
||||||
}
|
|
||||||
if (mode == RISING) {
|
|
||||||
pio->PIO_ESR = mask; // "Edge" Select Register
|
|
||||||
pio->PIO_REHLSR = mask; // "Rising Edge / High Level" Select Register
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enable interrupt
|
|
||||||
pio->PIO_IER = mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
void detachInterrupt(uint32_t pin)
|
|
||||||
{
|
|
||||||
// Retrieve pin information
|
|
||||||
Pio *pio = g_APinDescription[pin].pPort;
|
|
||||||
uint32_t mask = g_APinDescription[pin].ulPin;
|
|
||||||
|
|
||||||
// Disable interrupt
|
|
||||||
pio->PIO_IDR = mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void PIOA_Handler(void) {
|
|
||||||
uint32_t isr = PIOA->PIO_ISR;
|
|
||||||
uint8_t leading_zeros;
|
|
||||||
while((leading_zeros=__CLZ(isr))<32)
|
|
||||||
{
|
|
||||||
uint8_t pin=32-leading_zeros-1;
|
|
||||||
if(callbacksPioA[pin]) callbacksPioA[pin]();
|
|
||||||
isr=isr&(~(1<<pin));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PIOB_Handler(void) {
|
|
||||||
uint32_t isr = PIOB->PIO_ISR;
|
|
||||||
uint8_t leading_zeros;
|
|
||||||
while((leading_zeros=__CLZ(isr))<32)
|
|
||||||
{
|
|
||||||
uint8_t pin=32-leading_zeros-1;
|
|
||||||
if(callbacksPioB[pin]) callbacksPioB[pin]();
|
|
||||||
isr=isr&(~(1<<pin));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PIOC_Handler(void) {
|
|
||||||
uint32_t isr = PIOC->PIO_ISR;
|
|
||||||
uint8_t leading_zeros;
|
|
||||||
while((leading_zeros=__CLZ(isr))<32)
|
|
||||||
{
|
|
||||||
uint8_t pin=32-leading_zeros-1;
|
|
||||||
if(callbacksPioC[pin]) callbacksPioC[pin]();
|
|
||||||
isr=isr&(~(1<<pin));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PIOD_Handler(void) {
|
|
||||||
uint32_t isr = PIOD->PIO_ISR;
|
|
||||||
uint8_t leading_zeros;
|
|
||||||
while((leading_zeros=__CLZ(isr))<32)
|
|
||||||
{
|
|
||||||
uint8_t pin=32-leading_zeros-1;
|
|
||||||
if(callbacksPioD[pin]) callbacksPioD[pin]();
|
|
||||||
isr=isr&(~(1<<pin));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011-2012 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _WIRING_INTERRUPTS_
|
|
||||||
#define _WIRING_INTERRUPTS_
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void attachInterrupt(uint32_t pin, void (*callback)(void), uint32_t mode);
|
|
||||||
|
|
||||||
void detachInterrupt(uint32_t pin);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _WIRING_INTERRUPTS_ */
|
|
@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include "stdlib.h"
|
|
||||||
#include "stdint.h"
|
|
||||||
}
|
|
||||||
#include "WMath.h"
|
|
||||||
|
|
||||||
extern void randomSeed( uint32_t dwSeed )
|
|
||||||
{
|
|
||||||
if ( dwSeed != 0 )
|
|
||||||
{
|
|
||||||
srand( dwSeed ) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern long random( long howbig )
|
|
||||||
{
|
|
||||||
if ( howbig == 0 )
|
|
||||||
{
|
|
||||||
return 0 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rand() % howbig;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern long random( long howsmall, long howbig )
|
|
||||||
{
|
|
||||||
if (howsmall >= howbig)
|
|
||||||
{
|
|
||||||
return howsmall;
|
|
||||||
}
|
|
||||||
|
|
||||||
long diff = howbig - howsmall;
|
|
||||||
|
|
||||||
return random(diff) + howsmall;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern long map(long x, long in_min, long in_max, long out_min, long out_max)
|
|
||||||
{
|
|
||||||
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern uint16_t makeWord( uint16_t w )
|
|
||||||
{
|
|
||||||
return w ;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern uint16_t makeWord( uint8_t h, uint8_t l )
|
|
||||||
{
|
|
||||||
return (h << 8) | l ;
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _WIRING_MATH_
|
|
||||||
#define _WIRING_MATH_
|
|
||||||
|
|
||||||
extern long random( long ) ;
|
|
||||||
extern long random( long, long ) ;
|
|
||||||
extern void randomSeed( uint32_t dwSeed ) ;
|
|
||||||
extern long map( long, long, long, long, long ) ;
|
|
||||||
|
|
||||||
extern uint16_t makeWord( uint16_t w ) ;
|
|
||||||
extern uint16_t makeWord( uint8_t h, uint8_t l ) ;
|
|
||||||
|
|
||||||
#define word(...) makeWord(__VA_ARGS__)
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _WIRING_MATH_ */
|
|
@ -1,752 +0,0 @@
|
|||||||
/*
|
|
||||||
WString.cpp - String library for Wiring & Arduino
|
|
||||||
...mostly rewritten by Paul Stoffregen...
|
|
||||||
Copyright (c) 2009-10 Hernando Barragan. All rights reserved.
|
|
||||||
Copyright 2011, Paul Stoffregen, paul@pjrc.com
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "WString.h"
|
|
||||||
#include "itoa.h"
|
|
||||||
#include "avr/dtostrf.h"
|
|
||||||
|
|
||||||
/*********************************************/
|
|
||||||
/* Constructors */
|
|
||||||
/*********************************************/
|
|
||||||
|
|
||||||
String::String(const char *cstr)
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
if (cstr) copy(cstr, strlen(cstr));
|
|
||||||
}
|
|
||||||
|
|
||||||
String::String(const String &value)
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
*this = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
String::String(const __FlashStringHelper *pstr)
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
*this = pstr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
|
||||||
String::String(String &&rval)
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
move(rval);
|
|
||||||
}
|
|
||||||
String::String(StringSumHelper &&rval)
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
move(rval);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
String::String(char c)
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
char buf[2];
|
|
||||||
buf[0] = c;
|
|
||||||
buf[1] = 0;
|
|
||||||
*this = buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
String::String(unsigned char value, unsigned char base)
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
char buf[1 + 8 * sizeof(unsigned char)];
|
|
||||||
utoa(value, buf, base);
|
|
||||||
*this = buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
String::String(int value, unsigned char base)
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
char buf[2 + 8 * sizeof(int)];
|
|
||||||
itoa(value, buf, base);
|
|
||||||
*this = buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
String::String(unsigned int value, unsigned char base)
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
char buf[1 + 8 * sizeof(unsigned int)];
|
|
||||||
utoa(value, buf, base);
|
|
||||||
*this = buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
String::String(long value, unsigned char base)
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
char buf[2 + 8 * sizeof(long)];
|
|
||||||
ltoa(value, buf, base);
|
|
||||||
*this = buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
String::String(unsigned long value, unsigned char base)
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
char buf[1 + 8 * sizeof(unsigned long)];
|
|
||||||
ultoa(value, buf, base);
|
|
||||||
*this = buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
String::String(float value, unsigned char decimalPlaces)
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
char buf[33];
|
|
||||||
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
String::String(double value, unsigned char decimalPlaces)
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
char buf[33];
|
|
||||||
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
String::~String()
|
|
||||||
{
|
|
||||||
free(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************/
|
|
||||||
/* Memory Management */
|
|
||||||
/*********************************************/
|
|
||||||
|
|
||||||
inline void String::init(void)
|
|
||||||
{
|
|
||||||
buffer = NULL;
|
|
||||||
capacity = 0;
|
|
||||||
len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void String::invalidate(void)
|
|
||||||
{
|
|
||||||
if (buffer) free(buffer);
|
|
||||||
buffer = NULL;
|
|
||||||
capacity = len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::reserve(unsigned int size)
|
|
||||||
{
|
|
||||||
if (buffer && capacity >= size) return 1;
|
|
||||||
if (changeBuffer(size)) {
|
|
||||||
if (len == 0) buffer[0] = 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::changeBuffer(unsigned int maxStrLen)
|
|
||||||
{
|
|
||||||
char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
|
|
||||||
if (newbuffer) {
|
|
||||||
buffer = newbuffer;
|
|
||||||
capacity = maxStrLen;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************/
|
|
||||||
/* Copy and Move */
|
|
||||||
/*********************************************/
|
|
||||||
|
|
||||||
String & String::copy(const char *cstr, unsigned int length)
|
|
||||||
{
|
|
||||||
if (!reserve(length)) {
|
|
||||||
invalidate();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
len = length;
|
|
||||||
strcpy(buffer, cstr);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
|
|
||||||
{
|
|
||||||
if (!reserve(length)) {
|
|
||||||
invalidate();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
len = length;
|
|
||||||
strcpy_P(buffer, (PGM_P)pstr);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
|
||||||
void String::move(String &rhs)
|
|
||||||
{
|
|
||||||
if (buffer) {
|
|
||||||
if (rhs && capacity >= rhs.len) {
|
|
||||||
strcpy(buffer, rhs.buffer);
|
|
||||||
len = rhs.len;
|
|
||||||
rhs.len = 0;
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
free(buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buffer = rhs.buffer;
|
|
||||||
capacity = rhs.capacity;
|
|
||||||
len = rhs.len;
|
|
||||||
rhs.buffer = NULL;
|
|
||||||
rhs.capacity = 0;
|
|
||||||
rhs.len = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
String & String::operator = (const String &rhs)
|
|
||||||
{
|
|
||||||
if (this == &rhs) return *this;
|
|
||||||
|
|
||||||
if (rhs.buffer) copy(rhs.buffer, rhs.len);
|
|
||||||
else invalidate();
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
|
||||||
String & String::operator = (String &&rval)
|
|
||||||
{
|
|
||||||
if (this != &rval) move(rval);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
String & String::operator = (StringSumHelper &&rval)
|
|
||||||
{
|
|
||||||
if (this != &rval) move(rval);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
String & String::operator = (const char *cstr)
|
|
||||||
{
|
|
||||||
if (cstr) copy(cstr, strlen(cstr));
|
|
||||||
else invalidate();
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
String & String::operator = (const __FlashStringHelper *pstr)
|
|
||||||
{
|
|
||||||
if (pstr) copy(pstr, strlen_P((PGM_P)pstr));
|
|
||||||
else invalidate();
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************/
|
|
||||||
/* concat */
|
|
||||||
/*********************************************/
|
|
||||||
|
|
||||||
unsigned char String::concat(const String &s)
|
|
||||||
{
|
|
||||||
return concat(s.buffer, s.len);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::concat(const char *cstr, unsigned int length)
|
|
||||||
{
|
|
||||||
unsigned int newlen = len + length;
|
|
||||||
if (!cstr) return 0;
|
|
||||||
if (length == 0) return 1;
|
|
||||||
if (!reserve(newlen)) return 0;
|
|
||||||
strcpy(buffer + len, cstr);
|
|
||||||
len = newlen;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::concat(const char *cstr)
|
|
||||||
{
|
|
||||||
if (!cstr) return 0;
|
|
||||||
return concat(cstr, strlen(cstr));
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::concat(char c)
|
|
||||||
{
|
|
||||||
char buf[2];
|
|
||||||
buf[0] = c;
|
|
||||||
buf[1] = 0;
|
|
||||||
return concat(buf, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::concat(unsigned char num)
|
|
||||||
{
|
|
||||||
char buf[1 + 3 * sizeof(unsigned char)];
|
|
||||||
itoa(num, buf, 10);
|
|
||||||
return concat(buf, strlen(buf));
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::concat(int num)
|
|
||||||
{
|
|
||||||
char buf[2 + 3 * sizeof(int)];
|
|
||||||
itoa(num, buf, 10);
|
|
||||||
return concat(buf, strlen(buf));
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::concat(unsigned int num)
|
|
||||||
{
|
|
||||||
char buf[1 + 3 * sizeof(unsigned int)];
|
|
||||||
utoa(num, buf, 10);
|
|
||||||
return concat(buf, strlen(buf));
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::concat(long num)
|
|
||||||
{
|
|
||||||
char buf[2 + 3 * sizeof(long)];
|
|
||||||
ltoa(num, buf, 10);
|
|
||||||
return concat(buf, strlen(buf));
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::concat(unsigned long num)
|
|
||||||
{
|
|
||||||
char buf[1 + 3 * sizeof(unsigned long)];
|
|
||||||
ultoa(num, buf, 10);
|
|
||||||
return concat(buf, strlen(buf));
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::concat(float num)
|
|
||||||
{
|
|
||||||
char buf[20];
|
|
||||||
char* string = dtostrf(num, 4, 2, buf);
|
|
||||||
return concat(string, strlen(string));
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::concat(double num)
|
|
||||||
{
|
|
||||||
char buf[20];
|
|
||||||
char* string = dtostrf(num, 4, 2, buf);
|
|
||||||
return concat(string, strlen(string));
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::concat(const __FlashStringHelper * str)
|
|
||||||
{
|
|
||||||
if (!str) return 0;
|
|
||||||
int length = strlen_P((const char *) str);
|
|
||||||
if (length == 0) return 1;
|
|
||||||
unsigned int newlen = len + length;
|
|
||||||
if (!reserve(newlen)) return 0;
|
|
||||||
strcpy_P(buffer + len, (const char *) str);
|
|
||||||
len = newlen;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************/
|
|
||||||
/* Concatenate */
|
|
||||||
/*********************************************/
|
|
||||||
|
|
||||||
StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs)
|
|
||||||
{
|
|
||||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
|
||||||
if (!a.concat(rhs.buffer, rhs.len)) a.invalidate();
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
|
|
||||||
{
|
|
||||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
|
||||||
if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate();
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringSumHelper & operator + (const StringSumHelper &lhs, char c)
|
|
||||||
{
|
|
||||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
|
||||||
if (!a.concat(c)) a.invalidate();
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num)
|
|
||||||
{
|
|
||||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
|
||||||
if (!a.concat(num)) a.invalidate();
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringSumHelper & operator + (const StringSumHelper &lhs, int num)
|
|
||||||
{
|
|
||||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
|
||||||
if (!a.concat(num)) a.invalidate();
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
|
|
||||||
{
|
|
||||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
|
||||||
if (!a.concat(num)) a.invalidate();
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringSumHelper & operator + (const StringSumHelper &lhs, long num)
|
|
||||||
{
|
|
||||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
|
||||||
if (!a.concat(num)) a.invalidate();
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
|
|
||||||
{
|
|
||||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
|
||||||
if (!a.concat(num)) a.invalidate();
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringSumHelper & operator + (const StringSumHelper &lhs, float num)
|
|
||||||
{
|
|
||||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
|
||||||
if (!a.concat(num)) a.invalidate();
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringSumHelper & operator + (const StringSumHelper &lhs, double num)
|
|
||||||
{
|
|
||||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
|
||||||
if (!a.concat(num)) a.invalidate();
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
|
|
||||||
{
|
|
||||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
|
||||||
if (!a.concat(rhs)) a.invalidate();
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************/
|
|
||||||
/* Comparison */
|
|
||||||
/*********************************************/
|
|
||||||
|
|
||||||
int String::compareTo(const String &s) const
|
|
||||||
{
|
|
||||||
if (!buffer || !s.buffer) {
|
|
||||||
if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
|
|
||||||
if (buffer && len > 0) return *(unsigned char *)buffer;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return strcmp(buffer, s.buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::equals(const String &s2) const
|
|
||||||
{
|
|
||||||
return (len == s2.len && compareTo(s2) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::equals(const char *cstr) const
|
|
||||||
{
|
|
||||||
if (len == 0) return (cstr == NULL || *cstr == 0);
|
|
||||||
if (cstr == NULL) return buffer[0] == 0;
|
|
||||||
return strcmp(buffer, cstr) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::operator<(const String &rhs) const
|
|
||||||
{
|
|
||||||
return compareTo(rhs) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::operator>(const String &rhs) const
|
|
||||||
{
|
|
||||||
return compareTo(rhs) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::operator<=(const String &rhs) const
|
|
||||||
{
|
|
||||||
return compareTo(rhs) <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::operator>=(const String &rhs) const
|
|
||||||
{
|
|
||||||
return compareTo(rhs) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::equalsIgnoreCase( const String &s2 ) const
|
|
||||||
{
|
|
||||||
if (this == &s2) return 1;
|
|
||||||
if (len != s2.len) return 0;
|
|
||||||
if (len == 0) return 1;
|
|
||||||
const char *p1 = buffer;
|
|
||||||
const char *p2 = s2.buffer;
|
|
||||||
while (*p1) {
|
|
||||||
if (tolower(*p1++) != tolower(*p2++)) return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::startsWith( const String &s2 ) const
|
|
||||||
{
|
|
||||||
if (len < s2.len) return 0;
|
|
||||||
return startsWith(s2, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::startsWith( const String &s2, unsigned int offset ) const
|
|
||||||
{
|
|
||||||
if (offset > len - s2.len || !buffer || !s2.buffer) return 0;
|
|
||||||
return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char String::endsWith( const String &s2 ) const
|
|
||||||
{
|
|
||||||
if ( len < s2.len || !buffer || !s2.buffer) return 0;
|
|
||||||
return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************/
|
|
||||||
/* Character Access */
|
|
||||||
/*********************************************/
|
|
||||||
|
|
||||||
char String::charAt(unsigned int loc) const
|
|
||||||
{
|
|
||||||
return operator[](loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void String::setCharAt(unsigned int loc, char c)
|
|
||||||
{
|
|
||||||
if (loc < len) buffer[loc] = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
char & String::operator[](unsigned int index)
|
|
||||||
{
|
|
||||||
static char dummy_writable_char;
|
|
||||||
if (index >= len || !buffer) {
|
|
||||||
dummy_writable_char = 0;
|
|
||||||
return dummy_writable_char;
|
|
||||||
}
|
|
||||||
return buffer[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
char String::operator[]( unsigned int index ) const
|
|
||||||
{
|
|
||||||
if (index >= len || !buffer) return 0;
|
|
||||||
return buffer[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const
|
|
||||||
{
|
|
||||||
if (!bufsize || !buf) return;
|
|
||||||
if (index >= len) {
|
|
||||||
buf[0] = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
unsigned int n = bufsize - 1;
|
|
||||||
if (n > len - index) n = len - index;
|
|
||||||
strncpy((char *)buf, buffer + index, n);
|
|
||||||
buf[n] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************/
|
|
||||||
/* Search */
|
|
||||||
/*********************************************/
|
|
||||||
|
|
||||||
int String::indexOf(char c) const
|
|
||||||
{
|
|
||||||
return indexOf(c, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int String::indexOf( char ch, unsigned int fromIndex ) const
|
|
||||||
{
|
|
||||||
if (fromIndex >= len) return -1;
|
|
||||||
const char* temp = strchr(buffer + fromIndex, ch);
|
|
||||||
if (temp == NULL) return -1;
|
|
||||||
return temp - buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
int String::indexOf(const String &s2) const
|
|
||||||
{
|
|
||||||
return indexOf(s2, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int String::indexOf(const String &s2, unsigned int fromIndex) const
|
|
||||||
{
|
|
||||||
if (fromIndex >= len) return -1;
|
|
||||||
const char *found = strstr(buffer + fromIndex, s2.buffer);
|
|
||||||
if (found == NULL) return -1;
|
|
||||||
return found - buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
int String::lastIndexOf( char theChar ) const
|
|
||||||
{
|
|
||||||
return lastIndexOf(theChar, len - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int String::lastIndexOf(char ch, unsigned int fromIndex) const
|
|
||||||
{
|
|
||||||
if (fromIndex >= len) return -1;
|
|
||||||
char tempchar = buffer[fromIndex + 1];
|
|
||||||
buffer[fromIndex + 1] = '\0';
|
|
||||||
char* temp = strrchr( buffer, ch );
|
|
||||||
buffer[fromIndex + 1] = tempchar;
|
|
||||||
if (temp == NULL) return -1;
|
|
||||||
return temp - buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
int String::lastIndexOf(const String &s2) const
|
|
||||||
{
|
|
||||||
return lastIndexOf(s2, len - s2.len);
|
|
||||||
}
|
|
||||||
|
|
||||||
int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
|
|
||||||
{
|
|
||||||
if (s2.len == 0 || len == 0 || s2.len > len) return -1;
|
|
||||||
if (fromIndex >= len) fromIndex = len - 1;
|
|
||||||
int found = -1;
|
|
||||||
for (char *p = buffer; p <= buffer + fromIndex; p++) {
|
|
||||||
p = strstr(p, s2.buffer);
|
|
||||||
if (!p) break;
|
|
||||||
if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer;
|
|
||||||
}
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
String String::substring(unsigned int left, unsigned int right) const
|
|
||||||
{
|
|
||||||
if (left > right) {
|
|
||||||
unsigned int temp = right;
|
|
||||||
right = left;
|
|
||||||
left = temp;
|
|
||||||
}
|
|
||||||
String out;
|
|
||||||
if (left >= len) return out;
|
|
||||||
if (right > len) right = len;
|
|
||||||
char temp = buffer[right]; // save the replaced character
|
|
||||||
buffer[right] = '\0';
|
|
||||||
out = buffer + left; // pointer arithmetic
|
|
||||||
buffer[right] = temp; //restore character
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************/
|
|
||||||
/* Modification */
|
|
||||||
/*********************************************/
|
|
||||||
|
|
||||||
void String::replace(char find, char replace)
|
|
||||||
{
|
|
||||||
if (!buffer) return;
|
|
||||||
for (char *p = buffer; *p; p++) {
|
|
||||||
if (*p == find) *p = replace;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void String::replace(const String& find, const String& replace)
|
|
||||||
{
|
|
||||||
if (len == 0 || find.len == 0) return;
|
|
||||||
int diff = replace.len - find.len;
|
|
||||||
char *readFrom = buffer;
|
|
||||||
char *foundAt;
|
|
||||||
if (diff == 0) {
|
|
||||||
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
|
|
||||||
memcpy(foundAt, replace.buffer, replace.len);
|
|
||||||
readFrom = foundAt + replace.len;
|
|
||||||
}
|
|
||||||
} else if (diff < 0) {
|
|
||||||
char *writeTo = buffer;
|
|
||||||
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
|
|
||||||
unsigned int n = foundAt - readFrom;
|
|
||||||
memcpy(writeTo, readFrom, n);
|
|
||||||
writeTo += n;
|
|
||||||
memcpy(writeTo, replace.buffer, replace.len);
|
|
||||||
writeTo += replace.len;
|
|
||||||
readFrom = foundAt + find.len;
|
|
||||||
len += diff;
|
|
||||||
}
|
|
||||||
strcpy(writeTo, readFrom);
|
|
||||||
} else {
|
|
||||||
unsigned int size = len; // compute size needed for result
|
|
||||||
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
|
|
||||||
readFrom = foundAt + find.len;
|
|
||||||
size += diff;
|
|
||||||
}
|
|
||||||
if (size == len) return;
|
|
||||||
if (size > capacity && !changeBuffer(size)) return; // XXX: tell user!
|
|
||||||
int index = len - 1;
|
|
||||||
while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
|
|
||||||
readFrom = buffer + index + find.len;
|
|
||||||
memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
|
|
||||||
len += diff;
|
|
||||||
buffer[len] = 0;
|
|
||||||
memcpy(buffer + index, replace.buffer, replace.len);
|
|
||||||
index--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void String::remove(unsigned int index){
|
|
||||||
// Pass the biggest integer as the count. The remove method
|
|
||||||
// below will take care of truncating it at the end of the
|
|
||||||
// string.
|
|
||||||
remove(index, (unsigned int)-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void String::remove(unsigned int index, unsigned int count){
|
|
||||||
if (index >= len) { return; }
|
|
||||||
if (count <= 0) { return; }
|
|
||||||
if (count > len - index) { count = len - index; }
|
|
||||||
char *writeTo = buffer + index;
|
|
||||||
len = len - count;
|
|
||||||
strncpy(writeTo, buffer + index + count,len - index);
|
|
||||||
buffer[len] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void String::toLowerCase(void)
|
|
||||||
{
|
|
||||||
if (!buffer) return;
|
|
||||||
for (char *p = buffer; *p; p++) {
|
|
||||||
*p = tolower(*p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void String::toUpperCase(void)
|
|
||||||
{
|
|
||||||
if (!buffer) return;
|
|
||||||
for (char *p = buffer; *p; p++) {
|
|
||||||
*p = toupper(*p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void String::trim(void)
|
|
||||||
{
|
|
||||||
if (!buffer || len == 0) return;
|
|
||||||
char *begin = buffer;
|
|
||||||
while (isspace(*begin)) begin++;
|
|
||||||
char *end = buffer + len - 1;
|
|
||||||
while (isspace(*end) && end >= begin) end--;
|
|
||||||
len = end + 1 - begin;
|
|
||||||
if (begin > buffer) memcpy(buffer, begin, len);
|
|
||||||
buffer[len] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************/
|
|
||||||
/* Parsing / Conversion */
|
|
||||||
/*********************************************/
|
|
||||||
|
|
||||||
long String::toInt(void) const
|
|
||||||
{
|
|
||||||
if (buffer) return atol(buffer);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
float String::toFloat(void) const
|
|
||||||
{
|
|
||||||
return float(toDouble());
|
|
||||||
}
|
|
||||||
|
|
||||||
double String::toDouble(void) const
|
|
||||||
{
|
|
||||||
if (buffer) return atof(buffer);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,229 +0,0 @@
|
|||||||
/*
|
|
||||||
WString.h - String library for Wiring & Arduino
|
|
||||||
...mostly rewritten by Paul Stoffregen...
|
|
||||||
Copyright (c) 2009-10 Hernando Barragan. All right reserved.
|
|
||||||
Copyright 2011, Paul Stoffregen, paul@pjrc.com
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef String_class_h
|
|
||||||
#define String_class_h
|
|
||||||
#ifdef __cplusplus
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
|
|
||||||
// When compiling programs with this class, the following gcc parameters
|
|
||||||
// dramatically increase performance and memory (RAM) efficiency, typically
|
|
||||||
// with little or no increase in code size.
|
|
||||||
// -felide-constructors
|
|
||||||
// -std=c++0x
|
|
||||||
|
|
||||||
class __FlashStringHelper;
|
|
||||||
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
|
|
||||||
|
|
||||||
// An inherited class for holding the result of a concatenation. These
|
|
||||||
// result objects are assumed to be writable by subsequent concatenations.
|
|
||||||
class StringSumHelper;
|
|
||||||
|
|
||||||
// The string class
|
|
||||||
class String
|
|
||||||
{
|
|
||||||
// use a function pointer to allow for "if (s)" without the
|
|
||||||
// complications of an operator bool(). for more information, see:
|
|
||||||
// http://www.artima.com/cppsource/safebool.html
|
|
||||||
typedef void (String::*StringIfHelperType)() const;
|
|
||||||
void StringIfHelper() const {}
|
|
||||||
|
|
||||||
public:
|
|
||||||
// constructors
|
|
||||||
// creates a copy of the initial value.
|
|
||||||
// if the initial value is null or invalid, or if memory allocation
|
|
||||||
// fails, the string will be marked as invalid (i.e. "if (s)" will
|
|
||||||
// be false).
|
|
||||||
String(const char *cstr = "");
|
|
||||||
String(const String &str);
|
|
||||||
String(const __FlashStringHelper *str);
|
|
||||||
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
|
||||||
String(String &&rval);
|
|
||||||
String(StringSumHelper &&rval);
|
|
||||||
#endif
|
|
||||||
explicit String(char c);
|
|
||||||
explicit String(unsigned char, unsigned char base=10);
|
|
||||||
explicit String(int, unsigned char base=10);
|
|
||||||
explicit String(unsigned int, unsigned char base=10);
|
|
||||||
explicit String(long, unsigned char base=10);
|
|
||||||
explicit String(unsigned long, unsigned char base=10);
|
|
||||||
explicit String(float, unsigned char decimalPlaces=2);
|
|
||||||
explicit String(double, unsigned char decimalPlaces=2);
|
|
||||||
~String(void);
|
|
||||||
|
|
||||||
// memory management
|
|
||||||
// return true on success, false on failure (in which case, the string
|
|
||||||
// is left unchanged). reserve(0), if successful, will validate an
|
|
||||||
// invalid string (i.e., "if (s)" will be true afterwards)
|
|
||||||
unsigned char reserve(unsigned int size);
|
|
||||||
inline unsigned int length(void) const {return len;}
|
|
||||||
|
|
||||||
// creates a copy of the assigned value. if the value is null or
|
|
||||||
// invalid, or if the memory allocation fails, the string will be
|
|
||||||
// marked as invalid ("if (s)" will be false).
|
|
||||||
String & operator = (const String &rhs);
|
|
||||||
String & operator = (const char *cstr);
|
|
||||||
String & operator = (const __FlashStringHelper *str);
|
|
||||||
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
|
||||||
String & operator = (String &&rval);
|
|
||||||
String & operator = (StringSumHelper &&rval);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// concatenate (works w/ built-in types)
|
|
||||||
|
|
||||||
// returns true on success, false on failure (in which case, the string
|
|
||||||
// is left unchanged). if the argument is null or invalid, the
|
|
||||||
// concatenation is considered unsucessful.
|
|
||||||
unsigned char concat(const String &str);
|
|
||||||
unsigned char concat(const char *cstr);
|
|
||||||
unsigned char concat(char c);
|
|
||||||
unsigned char concat(unsigned char c);
|
|
||||||
unsigned char concat(int num);
|
|
||||||
unsigned char concat(unsigned int num);
|
|
||||||
unsigned char concat(long num);
|
|
||||||
unsigned char concat(unsigned long num);
|
|
||||||
unsigned char concat(float num);
|
|
||||||
unsigned char concat(double num);
|
|
||||||
unsigned char concat(const __FlashStringHelper * str);
|
|
||||||
|
|
||||||
// if there's not enough memory for the concatenated value, the string
|
|
||||||
// will be left unchanged (but this isn't signalled in any way)
|
|
||||||
String & operator += (const String &rhs) {concat(rhs); return (*this);}
|
|
||||||
String & operator += (const char *cstr) {concat(cstr); return (*this);}
|
|
||||||
String & operator += (char c) {concat(c); return (*this);}
|
|
||||||
String & operator += (unsigned char num) {concat(num); return (*this);}
|
|
||||||
String & operator += (int num) {concat(num); return (*this);}
|
|
||||||
String & operator += (unsigned int num) {concat(num); return (*this);}
|
|
||||||
String & operator += (long num) {concat(num); return (*this);}
|
|
||||||
String & operator += (unsigned long num) {concat(num); return (*this);}
|
|
||||||
String & operator += (float num) {concat(num); return (*this);}
|
|
||||||
String & operator += (double num) {concat(num); return (*this);}
|
|
||||||
String & operator += (const __FlashStringHelper *str){concat(str); return (*this);}
|
|
||||||
|
|
||||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
|
|
||||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
|
|
||||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, char c);
|
|
||||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num);
|
|
||||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, int num);
|
|
||||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
|
|
||||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
|
|
||||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
|
|
||||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, float num);
|
|
||||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, double num);
|
|
||||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs);
|
|
||||||
|
|
||||||
// comparison (only works w/ Strings and "strings")
|
|
||||||
operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
|
|
||||||
int compareTo(const String &s) const;
|
|
||||||
unsigned char equals(const String &s) const;
|
|
||||||
unsigned char equals(const char *cstr) const;
|
|
||||||
unsigned char operator == (const String &rhs) const {return equals(rhs);}
|
|
||||||
unsigned char operator == (const char *cstr) const {return equals(cstr);}
|
|
||||||
unsigned char operator != (const String &rhs) const {return !equals(rhs);}
|
|
||||||
unsigned char operator != (const char *cstr) const {return !equals(cstr);}
|
|
||||||
unsigned char operator < (const String &rhs) const;
|
|
||||||
unsigned char operator > (const String &rhs) const;
|
|
||||||
unsigned char operator <= (const String &rhs) const;
|
|
||||||
unsigned char operator >= (const String &rhs) const;
|
|
||||||
unsigned char equalsIgnoreCase(const String &s) const;
|
|
||||||
unsigned char startsWith( const String &prefix) const;
|
|
||||||
unsigned char startsWith(const String &prefix, unsigned int offset) const;
|
|
||||||
unsigned char endsWith(const String &suffix) const;
|
|
||||||
|
|
||||||
// character acccess
|
|
||||||
char charAt(unsigned int index) const;
|
|
||||||
void setCharAt(unsigned int index, char c);
|
|
||||||
char operator [] (unsigned int index) const;
|
|
||||||
char& operator [] (unsigned int index);
|
|
||||||
void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const;
|
|
||||||
void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
|
|
||||||
{ getBytes((unsigned char *)buf, bufsize, index); }
|
|
||||||
const char* c_str() const { return buffer; }
|
|
||||||
char* begin() { return buffer; }
|
|
||||||
char* end() { return buffer + length(); }
|
|
||||||
const char* begin() const { return c_str(); }
|
|
||||||
const char* end() const { return c_str() + length(); }
|
|
||||||
|
|
||||||
// search
|
|
||||||
int indexOf( char ch ) const;
|
|
||||||
int indexOf( char ch, unsigned int fromIndex ) const;
|
|
||||||
int indexOf( const String &str ) const;
|
|
||||||
int indexOf( const String &str, unsigned int fromIndex ) const;
|
|
||||||
int lastIndexOf( char ch ) const;
|
|
||||||
int lastIndexOf( char ch, unsigned int fromIndex ) const;
|
|
||||||
int lastIndexOf( const String &str ) const;
|
|
||||||
int lastIndexOf( const String &str, unsigned int fromIndex ) const;
|
|
||||||
String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); };
|
|
||||||
String substring( unsigned int beginIndex, unsigned int endIndex ) const;
|
|
||||||
|
|
||||||
// modification
|
|
||||||
void replace(char find, char replace);
|
|
||||||
void replace(const String& find, const String& replace);
|
|
||||||
void remove(unsigned int index);
|
|
||||||
void remove(unsigned int index, unsigned int count);
|
|
||||||
void toLowerCase(void);
|
|
||||||
void toUpperCase(void);
|
|
||||||
void trim(void);
|
|
||||||
|
|
||||||
// parsing/conversion
|
|
||||||
long toInt(void) const;
|
|
||||||
float toFloat(void) const;
|
|
||||||
double toDouble(void) const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
char *buffer; // the actual char array
|
|
||||||
unsigned int capacity; // the array length minus one (for the '\0')
|
|
||||||
unsigned int len; // the String length (not counting the '\0')
|
|
||||||
protected:
|
|
||||||
void init(void);
|
|
||||||
void invalidate(void);
|
|
||||||
unsigned char changeBuffer(unsigned int maxStrLen);
|
|
||||||
unsigned char concat(const char *cstr, unsigned int length);
|
|
||||||
|
|
||||||
// copy and move
|
|
||||||
String & copy(const char *cstr, unsigned int length);
|
|
||||||
String & copy(const __FlashStringHelper *pstr, unsigned int length);
|
|
||||||
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
|
||||||
void move(String &rhs);
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
class StringSumHelper : public String
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
StringSumHelper(const String &s) : String(s) {}
|
|
||||||
StringSumHelper(const char *p) : String(p) {}
|
|
||||||
StringSumHelper(char c) : String(c) {}
|
|
||||||
StringSumHelper(unsigned char num) : String(num) {}
|
|
||||||
StringSumHelper(int num) : String(num) {}
|
|
||||||
StringSumHelper(unsigned int num) : String(num) {}
|
|
||||||
StringSumHelper(long num) : String(num) {}
|
|
||||||
StringSumHelper(unsigned long num) : String(num) {}
|
|
||||||
StringSumHelper(float num) : String(num) {}
|
|
||||||
StringSumHelper(double num) : String(num) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // __cplusplus
|
|
||||||
#endif // String_class_h
|
|
@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2014 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
extern "C" void __cxa_pure_virtual(void) __attribute__ ((__noreturn__));
|
|
||||||
extern "C" void __cxa_deleted_virtual(void) __attribute__ ((__noreturn__));
|
|
||||||
|
|
||||||
void __cxa_pure_virtual(void) {
|
|
||||||
// We might want to write some diagnostics to uart in this case
|
|
||||||
//std::terminate();
|
|
||||||
while (1)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
void __cxa_deleted_virtual(void) {
|
|
||||||
// We might want to write some diagnostics to uart in this case
|
|
||||||
//std::terminate();
|
|
||||||
while (1)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
dtostrf - Emulation for dtostrf function from avr-libc
|
|
||||||
Copyright (c) 2013 Arduino. All rights reserved.
|
|
||||||
Written by Cristian Maglie <c.maglie@arduino.cc>
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
char *dtostrf (double val, signed char width, unsigned char prec, char *sout) {
|
|
||||||
char fmt[20];
|
|
||||||
sprintf(fmt, "%%%d.%df", width, prec);
|
|
||||||
sprintf(sout, fmt, val);
|
|
||||||
return sout;
|
|
||||||
}
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
dtostrf - Emulation for dtostrf function from avr-libc
|
|
||||||
Copyright (c) 2013 Arduino. All rights reserved.
|
|
||||||
Written by Cristian Maglie <c.maglie@arduino.cc>
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char *dtostrf (double val, signed char width, unsigned char prec, char *sout);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,122 +0,0 @@
|
|||||||
/*
|
|
||||||
pgmspace.h - Definitions for compatibility with AVR pgmspace macros
|
|
||||||
|
|
||||||
Copyright (c) 2015 Arduino LLC
|
|
||||||
|
|
||||||
Based on work of Paul Stoffregen on Teensy 3 (http://pjrc.com)
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __PGMSPACE_H_
|
|
||||||
#define __PGMSPACE_H_ 1
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
#define PROGMEM
|
|
||||||
#define PGM_P const char *
|
|
||||||
#define PSTR(str) (str)
|
|
||||||
|
|
||||||
#define _SFR_BYTE(n) (n)
|
|
||||||
|
|
||||||
typedef void prog_void;
|
|
||||||
typedef char prog_char;
|
|
||||||
typedef unsigned char prog_uchar;
|
|
||||||
typedef int8_t prog_int8_t;
|
|
||||||
typedef uint8_t prog_uint8_t;
|
|
||||||
typedef int16_t prog_int16_t;
|
|
||||||
typedef uint16_t prog_uint16_t;
|
|
||||||
typedef int32_t prog_int32_t;
|
|
||||||
typedef uint32_t prog_uint32_t;
|
|
||||||
typedef int64_t prog_int64_t;
|
|
||||||
typedef uint64_t prog_uint64_t;
|
|
||||||
|
|
||||||
typedef const void* int_farptr_t;
|
|
||||||
typedef const void* uint_farptr_t;
|
|
||||||
|
|
||||||
#define memchr_P(s, c, n) memchr((s), (c), (n))
|
|
||||||
#define memcmp_P(s1, s2, n) memcmp((s1), (s2), (n))
|
|
||||||
#define memccpy_P(dest, src, c, n) memccpy((dest), (src), (c), (n))
|
|
||||||
#define memcpy_P(dest, src, n) memcpy((dest), (src), (n))
|
|
||||||
#define memmem_P(haystack, haystacklen, needle, needlelen) memmem((haystack), (haystacklen), (needle), (needlelen))
|
|
||||||
#define memrchr_P(s, c, n) memrchr((s), (c), (n))
|
|
||||||
#define strcat_P(dest, src) strcat((dest), (src))
|
|
||||||
#define strchr_P(s, c) strchr((s), (c))
|
|
||||||
#define strchrnul_P(s, c) strchrnul((s), (c))
|
|
||||||
#define strcmp_P(a, b) strcmp((a), (b))
|
|
||||||
#define strcpy_P(dest, src) strcpy((dest), (src))
|
|
||||||
#define strcasecmp_P(s1, s2) strcasecmp((s1), (s2))
|
|
||||||
#define strcasestr_P(haystack, needle) strcasestr((haystack), (needle))
|
|
||||||
#define strcspn_P(s, accept) strcspn((s), (accept))
|
|
||||||
#define strlcat_P(s1, s2, n) strlcat((s1), (s2), (n))
|
|
||||||
#define strlcpy_P(s1, s2, n) strlcpy((s1), (s2), (n))
|
|
||||||
#define strlen_P(a) strlen((a))
|
|
||||||
#define strnlen_P(s, n) strnlen((s), (n))
|
|
||||||
#define strncmp_P(s1, s2, n) strncmp((s1), (s2), (n))
|
|
||||||
#define strncasecmp_P(s1, s2, n) strncasecmp((s1), (s2), (n))
|
|
||||||
#define strncat_P(s1, s2, n) strncat((s1), (s2), (n))
|
|
||||||
#define strncpy_P(s1, s2, n) strncpy((s1), (s2), (n))
|
|
||||||
#define strpbrk_P(s, accept) strpbrk((s), (accept))
|
|
||||||
#define strrchr_P(s, c) strrchr((s), (c))
|
|
||||||
#define strsep_P(sp, delim) strsep((sp), (delim))
|
|
||||||
#define strspn_P(s, accept) strspn((s), (accept))
|
|
||||||
#define strstr_P(a, b) strstr((a), (b))
|
|
||||||
#define strtok_P(s, delim) strtok((s), (delim))
|
|
||||||
#define strtok_rP(s, delim, last) strtok((s), (delim), (last))
|
|
||||||
|
|
||||||
#define strlen_PF(a) strlen((a))
|
|
||||||
#define strnlen_PF(src, len) strnlen((src), (len))
|
|
||||||
#define memcpy_PF(dest, src, len) memcpy((dest), (src), (len))
|
|
||||||
#define strcpy_PF(dest, src) strcpy((dest), (src))
|
|
||||||
#define strncpy_PF(dest, src, len) strncpy((dest), (src), (len))
|
|
||||||
#define strcat_PF(dest, src) strcat((dest), (src))
|
|
||||||
#define strlcat_PF(dest, src, len) strlcat((dest), (src), (len))
|
|
||||||
#define strncat_PF(dest, src, len) strncat((dest), (src), (len))
|
|
||||||
#define strcmp_PF(s1, s2) strcmp((s1), (s2))
|
|
||||||
#define strncmp_PF(s1, s2, n) strncmp((s1), (s2), (n))
|
|
||||||
#define strcasecmp_PF(s1, s2) strcasecmp((s1), (s2))
|
|
||||||
#define strncasecmp_PF(s1, s2, n) strncasecmp((s1), (s2), (n))
|
|
||||||
#define strstr_PF(s1, s2) strstr((s1), (s2))
|
|
||||||
#define strlcpy_PF(dest, src, n) strlcpy((dest), (src), (n))
|
|
||||||
#define memcmp_PF(s1, s2, n) memcmp((s1), (s2), (n))
|
|
||||||
|
|
||||||
#define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__)
|
|
||||||
#define snprintf_P(s, f, ...) snprintf((s), (f), __VA_ARGS__)
|
|
||||||
|
|
||||||
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
|
|
||||||
#define pgm_read_word(addr) (*(const unsigned short *)(addr))
|
|
||||||
#define pgm_read_dword(addr) (*(const unsigned long *)(addr))
|
|
||||||
#define pgm_read_float(addr) (*(const float *)(addr))
|
|
||||||
#define pgm_read_ptr(addr) (*(const void *)(addr))
|
|
||||||
|
|
||||||
#define pgm_read_byte_near(addr) pgm_read_byte(addr)
|
|
||||||
#define pgm_read_word_near(addr) pgm_read_word(addr)
|
|
||||||
#define pgm_read_dword_near(addr) pgm_read_dword(addr)
|
|
||||||
#define pgm_read_float_near(addr) pgm_read_float(addr)
|
|
||||||
#define pgm_read_ptr_near(addr) pgm_read_ptr(addr)
|
|
||||||
|
|
||||||
#define pgm_read_byte_far(addr) pgm_read_byte(addr)
|
|
||||||
#define pgm_read_word_far(addr) pgm_read_word(addr)
|
|
||||||
#define pgm_read_dword_far(addr) pgm_read_dword(addr)
|
|
||||||
#define pgm_read_float_far(addr) pgm_read_float(addr)
|
|
||||||
#define pgm_read_ptr_far(addr) pgm_read_ptr(addr)
|
|
||||||
|
|
||||||
#define pgm_get_far_address(addr) (&(addr))
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,534 +0,0 @@
|
|||||||
/*
|
|
||||||
binary.h - Definitions for binary constants
|
|
||||||
Copyright (c) 2006 David A. Mellis. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef Binary_h
|
|
||||||
#define Binary_h
|
|
||||||
|
|
||||||
#define B0 0
|
|
||||||
#define B00 0
|
|
||||||
#define B000 0
|
|
||||||
#define B0000 0
|
|
||||||
#define B00000 0
|
|
||||||
#define B000000 0
|
|
||||||
#define B0000000 0
|
|
||||||
#define B00000000 0
|
|
||||||
#define B1 1
|
|
||||||
#define B01 1
|
|
||||||
#define B001 1
|
|
||||||
#define B0001 1
|
|
||||||
#define B00001 1
|
|
||||||
#define B000001 1
|
|
||||||
#define B0000001 1
|
|
||||||
#define B00000001 1
|
|
||||||
#define B10 2
|
|
||||||
#define B010 2
|
|
||||||
#define B0010 2
|
|
||||||
#define B00010 2
|
|
||||||
#define B000010 2
|
|
||||||
#define B0000010 2
|
|
||||||
#define B00000010 2
|
|
||||||
#define B11 3
|
|
||||||
#define B011 3
|
|
||||||
#define B0011 3
|
|
||||||
#define B00011 3
|
|
||||||
#define B000011 3
|
|
||||||
#define B0000011 3
|
|
||||||
#define B00000011 3
|
|
||||||
#define B100 4
|
|
||||||
#define B0100 4
|
|
||||||
#define B00100 4
|
|
||||||
#define B000100 4
|
|
||||||
#define B0000100 4
|
|
||||||
#define B00000100 4
|
|
||||||
#define B101 5
|
|
||||||
#define B0101 5
|
|
||||||
#define B00101 5
|
|
||||||
#define B000101 5
|
|
||||||
#define B0000101 5
|
|
||||||
#define B00000101 5
|
|
||||||
#define B110 6
|
|
||||||
#define B0110 6
|
|
||||||
#define B00110 6
|
|
||||||
#define B000110 6
|
|
||||||
#define B0000110 6
|
|
||||||
#define B00000110 6
|
|
||||||
#define B111 7
|
|
||||||
#define B0111 7
|
|
||||||
#define B00111 7
|
|
||||||
#define B000111 7
|
|
||||||
#define B0000111 7
|
|
||||||
#define B00000111 7
|
|
||||||
#define B1000 8
|
|
||||||
#define B01000 8
|
|
||||||
#define B001000 8
|
|
||||||
#define B0001000 8
|
|
||||||
#define B00001000 8
|
|
||||||
#define B1001 9
|
|
||||||
#define B01001 9
|
|
||||||
#define B001001 9
|
|
||||||
#define B0001001 9
|
|
||||||
#define B00001001 9
|
|
||||||
#define B1010 10
|
|
||||||
#define B01010 10
|
|
||||||
#define B001010 10
|
|
||||||
#define B0001010 10
|
|
||||||
#define B00001010 10
|
|
||||||
#define B1011 11
|
|
||||||
#define B01011 11
|
|
||||||
#define B001011 11
|
|
||||||
#define B0001011 11
|
|
||||||
#define B00001011 11
|
|
||||||
#define B1100 12
|
|
||||||
#define B01100 12
|
|
||||||
#define B001100 12
|
|
||||||
#define B0001100 12
|
|
||||||
#define B00001100 12
|
|
||||||
#define B1101 13
|
|
||||||
#define B01101 13
|
|
||||||
#define B001101 13
|
|
||||||
#define B0001101 13
|
|
||||||
#define B00001101 13
|
|
||||||
#define B1110 14
|
|
||||||
#define B01110 14
|
|
||||||
#define B001110 14
|
|
||||||
#define B0001110 14
|
|
||||||
#define B00001110 14
|
|
||||||
#define B1111 15
|
|
||||||
#define B01111 15
|
|
||||||
#define B001111 15
|
|
||||||
#define B0001111 15
|
|
||||||
#define B00001111 15
|
|
||||||
#define B10000 16
|
|
||||||
#define B010000 16
|
|
||||||
#define B0010000 16
|
|
||||||
#define B00010000 16
|
|
||||||
#define B10001 17
|
|
||||||
#define B010001 17
|
|
||||||
#define B0010001 17
|
|
||||||
#define B00010001 17
|
|
||||||
#define B10010 18
|
|
||||||
#define B010010 18
|
|
||||||
#define B0010010 18
|
|
||||||
#define B00010010 18
|
|
||||||
#define B10011 19
|
|
||||||
#define B010011 19
|
|
||||||
#define B0010011 19
|
|
||||||
#define B00010011 19
|
|
||||||
#define B10100 20
|
|
||||||
#define B010100 20
|
|
||||||
#define B0010100 20
|
|
||||||
#define B00010100 20
|
|
||||||
#define B10101 21
|
|
||||||
#define B010101 21
|
|
||||||
#define B0010101 21
|
|
||||||
#define B00010101 21
|
|
||||||
#define B10110 22
|
|
||||||
#define B010110 22
|
|
||||||
#define B0010110 22
|
|
||||||
#define B00010110 22
|
|
||||||
#define B10111 23
|
|
||||||
#define B010111 23
|
|
||||||
#define B0010111 23
|
|
||||||
#define B00010111 23
|
|
||||||
#define B11000 24
|
|
||||||
#define B011000 24
|
|
||||||
#define B0011000 24
|
|
||||||
#define B00011000 24
|
|
||||||
#define B11001 25
|
|
||||||
#define B011001 25
|
|
||||||
#define B0011001 25
|
|
||||||
#define B00011001 25
|
|
||||||
#define B11010 26
|
|
||||||
#define B011010 26
|
|
||||||
#define B0011010 26
|
|
||||||
#define B00011010 26
|
|
||||||
#define B11011 27
|
|
||||||
#define B011011 27
|
|
||||||
#define B0011011 27
|
|
||||||
#define B00011011 27
|
|
||||||
#define B11100 28
|
|
||||||
#define B011100 28
|
|
||||||
#define B0011100 28
|
|
||||||
#define B00011100 28
|
|
||||||
#define B11101 29
|
|
||||||
#define B011101 29
|
|
||||||
#define B0011101 29
|
|
||||||
#define B00011101 29
|
|
||||||
#define B11110 30
|
|
||||||
#define B011110 30
|
|
||||||
#define B0011110 30
|
|
||||||
#define B00011110 30
|
|
||||||
#define B11111 31
|
|
||||||
#define B011111 31
|
|
||||||
#define B0011111 31
|
|
||||||
#define B00011111 31
|
|
||||||
#define B100000 32
|
|
||||||
#define B0100000 32
|
|
||||||
#define B00100000 32
|
|
||||||
#define B100001 33
|
|
||||||
#define B0100001 33
|
|
||||||
#define B00100001 33
|
|
||||||
#define B100010 34
|
|
||||||
#define B0100010 34
|
|
||||||
#define B00100010 34
|
|
||||||
#define B100011 35
|
|
||||||
#define B0100011 35
|
|
||||||
#define B00100011 35
|
|
||||||
#define B100100 36
|
|
||||||
#define B0100100 36
|
|
||||||
#define B00100100 36
|
|
||||||
#define B100101 37
|
|
||||||
#define B0100101 37
|
|
||||||
#define B00100101 37
|
|
||||||
#define B100110 38
|
|
||||||
#define B0100110 38
|
|
||||||
#define B00100110 38
|
|
||||||
#define B100111 39
|
|
||||||
#define B0100111 39
|
|
||||||
#define B00100111 39
|
|
||||||
#define B101000 40
|
|
||||||
#define B0101000 40
|
|
||||||
#define B00101000 40
|
|
||||||
#define B101001 41
|
|
||||||
#define B0101001 41
|
|
||||||
#define B00101001 41
|
|
||||||
#define B101010 42
|
|
||||||
#define B0101010 42
|
|
||||||
#define B00101010 42
|
|
||||||
#define B101011 43
|
|
||||||
#define B0101011 43
|
|
||||||
#define B00101011 43
|
|
||||||
#define B101100 44
|
|
||||||
#define B0101100 44
|
|
||||||
#define B00101100 44
|
|
||||||
#define B101101 45
|
|
||||||
#define B0101101 45
|
|
||||||
#define B00101101 45
|
|
||||||
#define B101110 46
|
|
||||||
#define B0101110 46
|
|
||||||
#define B00101110 46
|
|
||||||
#define B101111 47
|
|
||||||
#define B0101111 47
|
|
||||||
#define B00101111 47
|
|
||||||
#define B110000 48
|
|
||||||
#define B0110000 48
|
|
||||||
#define B00110000 48
|
|
||||||
#define B110001 49
|
|
||||||
#define B0110001 49
|
|
||||||
#define B00110001 49
|
|
||||||
#define B110010 50
|
|
||||||
#define B0110010 50
|
|
||||||
#define B00110010 50
|
|
||||||
#define B110011 51
|
|
||||||
#define B0110011 51
|
|
||||||
#define B00110011 51
|
|
||||||
#define B110100 52
|
|
||||||
#define B0110100 52
|
|
||||||
#define B00110100 52
|
|
||||||
#define B110101 53
|
|
||||||
#define B0110101 53
|
|
||||||
#define B00110101 53
|
|
||||||
#define B110110 54
|
|
||||||
#define B0110110 54
|
|
||||||
#define B00110110 54
|
|
||||||
#define B110111 55
|
|
||||||
#define B0110111 55
|
|
||||||
#define B00110111 55
|
|
||||||
#define B111000 56
|
|
||||||
#define B0111000 56
|
|
||||||
#define B00111000 56
|
|
||||||
#define B111001 57
|
|
||||||
#define B0111001 57
|
|
||||||
#define B00111001 57
|
|
||||||
#define B111010 58
|
|
||||||
#define B0111010 58
|
|
||||||
#define B00111010 58
|
|
||||||
#define B111011 59
|
|
||||||
#define B0111011 59
|
|
||||||
#define B00111011 59
|
|
||||||
#define B111100 60
|
|
||||||
#define B0111100 60
|
|
||||||
#define B00111100 60
|
|
||||||
#define B111101 61
|
|
||||||
#define B0111101 61
|
|
||||||
#define B00111101 61
|
|
||||||
#define B111110 62
|
|
||||||
#define B0111110 62
|
|
||||||
#define B00111110 62
|
|
||||||
#define B111111 63
|
|
||||||
#define B0111111 63
|
|
||||||
#define B00111111 63
|
|
||||||
#define B1000000 64
|
|
||||||
#define B01000000 64
|
|
||||||
#define B1000001 65
|
|
||||||
#define B01000001 65
|
|
||||||
#define B1000010 66
|
|
||||||
#define B01000010 66
|
|
||||||
#define B1000011 67
|
|
||||||
#define B01000011 67
|
|
||||||
#define B1000100 68
|
|
||||||
#define B01000100 68
|
|
||||||
#define B1000101 69
|
|
||||||
#define B01000101 69
|
|
||||||
#define B1000110 70
|
|
||||||
#define B01000110 70
|
|
||||||
#define B1000111 71
|
|
||||||
#define B01000111 71
|
|
||||||
#define B1001000 72
|
|
||||||
#define B01001000 72
|
|
||||||
#define B1001001 73
|
|
||||||
#define B01001001 73
|
|
||||||
#define B1001010 74
|
|
||||||
#define B01001010 74
|
|
||||||
#define B1001011 75
|
|
||||||
#define B01001011 75
|
|
||||||
#define B1001100 76
|
|
||||||
#define B01001100 76
|
|
||||||
#define B1001101 77
|
|
||||||
#define B01001101 77
|
|
||||||
#define B1001110 78
|
|
||||||
#define B01001110 78
|
|
||||||
#define B1001111 79
|
|
||||||
#define B01001111 79
|
|
||||||
#define B1010000 80
|
|
||||||
#define B01010000 80
|
|
||||||
#define B1010001 81
|
|
||||||
#define B01010001 81
|
|
||||||
#define B1010010 82
|
|
||||||
#define B01010010 82
|
|
||||||
#define B1010011 83
|
|
||||||
#define B01010011 83
|
|
||||||
#define B1010100 84
|
|
||||||
#define B01010100 84
|
|
||||||
#define B1010101 85
|
|
||||||
#define B01010101 85
|
|
||||||
#define B1010110 86
|
|
||||||
#define B01010110 86
|
|
||||||
#define B1010111 87
|
|
||||||
#define B01010111 87
|
|
||||||
#define B1011000 88
|
|
||||||
#define B01011000 88
|
|
||||||
#define B1011001 89
|
|
||||||
#define B01011001 89
|
|
||||||
#define B1011010 90
|
|
||||||
#define B01011010 90
|
|
||||||
#define B1011011 91
|
|
||||||
#define B01011011 91
|
|
||||||
#define B1011100 92
|
|
||||||
#define B01011100 92
|
|
||||||
#define B1011101 93
|
|
||||||
#define B01011101 93
|
|
||||||
#define B1011110 94
|
|
||||||
#define B01011110 94
|
|
||||||
#define B1011111 95
|
|
||||||
#define B01011111 95
|
|
||||||
#define B1100000 96
|
|
||||||
#define B01100000 96
|
|
||||||
#define B1100001 97
|
|
||||||
#define B01100001 97
|
|
||||||
#define B1100010 98
|
|
||||||
#define B01100010 98
|
|
||||||
#define B1100011 99
|
|
||||||
#define B01100011 99
|
|
||||||
#define B1100100 100
|
|
||||||
#define B01100100 100
|
|
||||||
#define B1100101 101
|
|
||||||
#define B01100101 101
|
|
||||||
#define B1100110 102
|
|
||||||
#define B01100110 102
|
|
||||||
#define B1100111 103
|
|
||||||
#define B01100111 103
|
|
||||||
#define B1101000 104
|
|
||||||
#define B01101000 104
|
|
||||||
#define B1101001 105
|
|
||||||
#define B01101001 105
|
|
||||||
#define B1101010 106
|
|
||||||
#define B01101010 106
|
|
||||||
#define B1101011 107
|
|
||||||
#define B01101011 107
|
|
||||||
#define B1101100 108
|
|
||||||
#define B01101100 108
|
|
||||||
#define B1101101 109
|
|
||||||
#define B01101101 109
|
|
||||||
#define B1101110 110
|
|
||||||
#define B01101110 110
|
|
||||||
#define B1101111 111
|
|
||||||
#define B01101111 111
|
|
||||||
#define B1110000 112
|
|
||||||
#define B01110000 112
|
|
||||||
#define B1110001 113
|
|
||||||
#define B01110001 113
|
|
||||||
#define B1110010 114
|
|
||||||
#define B01110010 114
|
|
||||||
#define B1110011 115
|
|
||||||
#define B01110011 115
|
|
||||||
#define B1110100 116
|
|
||||||
#define B01110100 116
|
|
||||||
#define B1110101 117
|
|
||||||
#define B01110101 117
|
|
||||||
#define B1110110 118
|
|
||||||
#define B01110110 118
|
|
||||||
#define B1110111 119
|
|
||||||
#define B01110111 119
|
|
||||||
#define B1111000 120
|
|
||||||
#define B01111000 120
|
|
||||||
#define B1111001 121
|
|
||||||
#define B01111001 121
|
|
||||||
#define B1111010 122
|
|
||||||
#define B01111010 122
|
|
||||||
#define B1111011 123
|
|
||||||
#define B01111011 123
|
|
||||||
#define B1111100 124
|
|
||||||
#define B01111100 124
|
|
||||||
#define B1111101 125
|
|
||||||
#define B01111101 125
|
|
||||||
#define B1111110 126
|
|
||||||
#define B01111110 126
|
|
||||||
#define B1111111 127
|
|
||||||
#define B01111111 127
|
|
||||||
#define B10000000 128
|
|
||||||
#define B10000001 129
|
|
||||||
#define B10000010 130
|
|
||||||
#define B10000011 131
|
|
||||||
#define B10000100 132
|
|
||||||
#define B10000101 133
|
|
||||||
#define B10000110 134
|
|
||||||
#define B10000111 135
|
|
||||||
#define B10001000 136
|
|
||||||
#define B10001001 137
|
|
||||||
#define B10001010 138
|
|
||||||
#define B10001011 139
|
|
||||||
#define B10001100 140
|
|
||||||
#define B10001101 141
|
|
||||||
#define B10001110 142
|
|
||||||
#define B10001111 143
|
|
||||||
#define B10010000 144
|
|
||||||
#define B10010001 145
|
|
||||||
#define B10010010 146
|
|
||||||
#define B10010011 147
|
|
||||||
#define B10010100 148
|
|
||||||
#define B10010101 149
|
|
||||||
#define B10010110 150
|
|
||||||
#define B10010111 151
|
|
||||||
#define B10011000 152
|
|
||||||
#define B10011001 153
|
|
||||||
#define B10011010 154
|
|
||||||
#define B10011011 155
|
|
||||||
#define B10011100 156
|
|
||||||
#define B10011101 157
|
|
||||||
#define B10011110 158
|
|
||||||
#define B10011111 159
|
|
||||||
#define B10100000 160
|
|
||||||
#define B10100001 161
|
|
||||||
#define B10100010 162
|
|
||||||
#define B10100011 163
|
|
||||||
#define B10100100 164
|
|
||||||
#define B10100101 165
|
|
||||||
#define B10100110 166
|
|
||||||
#define B10100111 167
|
|
||||||
#define B10101000 168
|
|
||||||
#define B10101001 169
|
|
||||||
#define B10101010 170
|
|
||||||
#define B10101011 171
|
|
||||||
#define B10101100 172
|
|
||||||
#define B10101101 173
|
|
||||||
#define B10101110 174
|
|
||||||
#define B10101111 175
|
|
||||||
#define B10110000 176
|
|
||||||
#define B10110001 177
|
|
||||||
#define B10110010 178
|
|
||||||
#define B10110011 179
|
|
||||||
#define B10110100 180
|
|
||||||
#define B10110101 181
|
|
||||||
#define B10110110 182
|
|
||||||
#define B10110111 183
|
|
||||||
#define B10111000 184
|
|
||||||
#define B10111001 185
|
|
||||||
#define B10111010 186
|
|
||||||
#define B10111011 187
|
|
||||||
#define B10111100 188
|
|
||||||
#define B10111101 189
|
|
||||||
#define B10111110 190
|
|
||||||
#define B10111111 191
|
|
||||||
#define B11000000 192
|
|
||||||
#define B11000001 193
|
|
||||||
#define B11000010 194
|
|
||||||
#define B11000011 195
|
|
||||||
#define B11000100 196
|
|
||||||
#define B11000101 197
|
|
||||||
#define B11000110 198
|
|
||||||
#define B11000111 199
|
|
||||||
#define B11001000 200
|
|
||||||
#define B11001001 201
|
|
||||||
#define B11001010 202
|
|
||||||
#define B11001011 203
|
|
||||||
#define B11001100 204
|
|
||||||
#define B11001101 205
|
|
||||||
#define B11001110 206
|
|
||||||
#define B11001111 207
|
|
||||||
#define B11010000 208
|
|
||||||
#define B11010001 209
|
|
||||||
#define B11010010 210
|
|
||||||
#define B11010011 211
|
|
||||||
#define B11010100 212
|
|
||||||
#define B11010101 213
|
|
||||||
#define B11010110 214
|
|
||||||
#define B11010111 215
|
|
||||||
#define B11011000 216
|
|
||||||
#define B11011001 217
|
|
||||||
#define B11011010 218
|
|
||||||
#define B11011011 219
|
|
||||||
#define B11011100 220
|
|
||||||
#define B11011101 221
|
|
||||||
#define B11011110 222
|
|
||||||
#define B11011111 223
|
|
||||||
#define B11100000 224
|
|
||||||
#define B11100001 225
|
|
||||||
#define B11100010 226
|
|
||||||
#define B11100011 227
|
|
||||||
#define B11100100 228
|
|
||||||
#define B11100101 229
|
|
||||||
#define B11100110 230
|
|
||||||
#define B11100111 231
|
|
||||||
#define B11101000 232
|
|
||||||
#define B11101001 233
|
|
||||||
#define B11101010 234
|
|
||||||
#define B11101011 235
|
|
||||||
#define B11101100 236
|
|
||||||
#define B11101101 237
|
|
||||||
#define B11101110 238
|
|
||||||
#define B11101111 239
|
|
||||||
#define B11110000 240
|
|
||||||
#define B11110001 241
|
|
||||||
#define B11110010 242
|
|
||||||
#define B11110011 243
|
|
||||||
#define B11110100 244
|
|
||||||
#define B11110101 245
|
|
||||||
#define B11110110 246
|
|
||||||
#define B11110111 247
|
|
||||||
#define B11111000 248
|
|
||||||
#define B11111001 249
|
|
||||||
#define B11111010 250
|
|
||||||
#define B11111011 251
|
|
||||||
#define B11111100 252
|
|
||||||
#define B11111101 253
|
|
||||||
#define B11111110 254
|
|
||||||
#define B11111111 255
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,127 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2012 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
|
||||||
#include "Reset.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void __halt() {
|
|
||||||
// Halts
|
|
||||||
while (1)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void svcHook(void);
|
|
||||||
extern void pendSVHook(void);
|
|
||||||
extern int sysTickHook(void);
|
|
||||||
|
|
||||||
/* Cortex-M3 core handlers */
|
|
||||||
void NMI_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void HardFault_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void MemManage_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void BusFault_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void UsageFault_Handler(void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void DebugMon_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void SVC_Handler (void) { svcHook(); }
|
|
||||||
void PendSV_Handler (void) { pendSVHook(); }
|
|
||||||
|
|
||||||
void SysTick_Handler(void)
|
|
||||||
{
|
|
||||||
if (sysTickHook())
|
|
||||||
return;
|
|
||||||
|
|
||||||
tickReset();
|
|
||||||
|
|
||||||
// Increment tick count each ms
|
|
||||||
TimeTick_Increment();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Peripherals handlers */
|
|
||||||
void SUPC_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void RSTC_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void RTC_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void RTT_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void WDT_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void PMC_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void EFC0_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void EFC1_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void UART_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
#ifdef _SAM3XA_SMC_INSTANCE_
|
|
||||||
void SMC_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
#endif
|
|
||||||
#ifdef _SAM3XA_SDRAMC_INSTANCE_
|
|
||||||
void SDRAMC_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
#endif
|
|
||||||
void PIOA_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void PIOB_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
#ifdef _SAM3XA_PIOC_INSTANCE_
|
|
||||||
void PIOC_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
#endif
|
|
||||||
#ifdef _SAM3XA_PIOD_INSTANCE_
|
|
||||||
void PIOD_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
#endif
|
|
||||||
#ifdef _SAM3XA_PIOE_INSTANCE_
|
|
||||||
void PIOE_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
#endif
|
|
||||||
#ifdef _SAM3XA_PIOF_INSTANCE_
|
|
||||||
void PIOF_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
#endif
|
|
||||||
void USART0_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void USART1_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void USART2_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
#ifdef _SAM3XA_USART3_INSTANCE_
|
|
||||||
void USART3_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
#endif
|
|
||||||
void HSMCI_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void TWI0_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void TWI1_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void SPI0_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
#ifdef _SAM3XA_SPI1_INSTANCE_
|
|
||||||
void SPI1_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
#endif
|
|
||||||
void SSC_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void TC0_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void TC1_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void TC2_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void TC3_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void TC4_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void TC5_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
#ifdef _SAM3XA_TC2_INSTANCE_
|
|
||||||
void TC6_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void TC7_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void TC8_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
#endif
|
|
||||||
void PWM_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void ADC_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void DACC_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void DMAC_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void UOTGHS_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void TRNG_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
#ifdef _SAM3XA_EMAC_INSTANCE_
|
|
||||||
void EMAC_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
#endif
|
|
||||||
void CAN0_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void CAN1_Handler (void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2012 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Empty yield() hook.
|
|
||||||
*
|
|
||||||
* This function is intended to be used by library writers to build
|
|
||||||
* libraries or sketches that supports cooperative threads.
|
|
||||||
*
|
|
||||||
* Its defined as a weak symbol and it can be redefined to implement a
|
|
||||||
* real cooperative scheduler.
|
|
||||||
*/
|
|
||||||
static void __empty() {
|
|
||||||
// Empty
|
|
||||||
}
|
|
||||||
void yield(void) __attribute__ ((weak, alias("__empty")));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SysTick hook
|
|
||||||
*
|
|
||||||
* This function is called from SysTick handler, before the default
|
|
||||||
* handler provided by Arduino.
|
|
||||||
*/
|
|
||||||
static int __false() {
|
|
||||||
// Return false
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int sysTickHook(void) __attribute__ ((weak, alias("__false")));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SVC hook
|
|
||||||
* PendSV hook
|
|
||||||
*
|
|
||||||
* These functions are called from SVC handler, and PensSV handler.
|
|
||||||
* Default action is halting.
|
|
||||||
*/
|
|
||||||
static void __halt() {
|
|
||||||
// Halts
|
|
||||||
while (1)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
void svcHook(void) __attribute__ ((weak, alias("__halt")));
|
|
||||||
void pendSVHook(void) __attribute__ ((weak, alias("__halt")));
|
|
@ -1,109 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
*
|
|
||||||
* Implementation of low level library.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined __ICCARM__ /* IAR Ewarm 5.41+ */
|
|
||||||
|
|
||||||
#include "board.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <yfuns.h>
|
|
||||||
#include <uart.h>
|
|
||||||
|
|
||||||
extern __weak size_t __write( int handle, const unsigned char *buf, size_t bufSize )
|
|
||||||
{
|
|
||||||
size_t nChars = 0 ;
|
|
||||||
|
|
||||||
/* Check for the command to flush all handles */
|
|
||||||
if ( handle == -1 )
|
|
||||||
{
|
|
||||||
return 0 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for stdout and stderr (only necessary if FILE descriptors are enabled.) */
|
|
||||||
if ( handle != 1 && handle != 2 )
|
|
||||||
{
|
|
||||||
/* remove warnings */
|
|
||||||
return 0xfffffff ;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( /* Empty */ ; bufSize > 0 ; --bufSize )
|
|
||||||
{
|
|
||||||
while ( !uart_is_tx_ready(CONSOLE_UART) )
|
|
||||||
;
|
|
||||||
uart_write( CONSOLE_UART, *buf ) ;
|
|
||||||
++buf ;
|
|
||||||
++nChars ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nChars ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern __weak size_t __read( int handle, unsigned char *buf, size_t bufSize )
|
|
||||||
{
|
|
||||||
size_t nChars = 0 ;
|
|
||||||
|
|
||||||
/* Check for stdin (only necessary if FILE descriptors are enabled) */
|
|
||||||
if ( handle != 0 )
|
|
||||||
{
|
|
||||||
/* remove warnings */
|
|
||||||
return 0xfffffff ;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( /*Empty*/; bufSize > 0 ; --bufSize )
|
|
||||||
{
|
|
||||||
uint8_t c;
|
|
||||||
while (uart_read( CONSOLE_UART, &c ))
|
|
||||||
;
|
|
||||||
|
|
||||||
if ( c == 0 )
|
|
||||||
{
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
*buf++ = c ;
|
|
||||||
++nChars ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nChars ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Outputs a character on the UART.
|
|
||||||
*
|
|
||||||
* \param c Character to output.
|
|
||||||
*
|
|
||||||
* \return The character that was output.
|
|
||||||
*/
|
|
||||||
extern __weak signed int putchar( signed int c )
|
|
||||||
{
|
|
||||||
while ( !uart_is_tx_ready(CONSOLE_UART) )
|
|
||||||
;
|
|
||||||
uart_write( CONSOLE_UART, c ) ;
|
|
||||||
|
|
||||||
return c ;
|
|
||||||
}
|
|
||||||
#endif // defined __ICCARM__
|
|
@ -1,170 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "itoa.h"
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"{
|
|
||||||
#endif // __cplusplus
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* reverse: reverse string s in place */
|
|
||||||
static void reverse( char s[] )
|
|
||||||
{
|
|
||||||
int i, j ;
|
|
||||||
char c ;
|
|
||||||
|
|
||||||
for ( i = 0, j = strlen(s)-1 ; i < j ; i++, j-- )
|
|
||||||
{
|
|
||||||
c = s[i] ;
|
|
||||||
s[i] = s[j] ;
|
|
||||||
s[j] = c ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* itoa: convert n to characters in s */
|
|
||||||
extern void itoa( int n, char s[] )
|
|
||||||
{
|
|
||||||
int i, sign ;
|
|
||||||
|
|
||||||
if ( (sign = n) < 0 ) /* record sign */
|
|
||||||
{
|
|
||||||
n = -n; /* make n positive */
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
do
|
|
||||||
{ /* generate digits in reverse order */
|
|
||||||
s[i++] = n % 10 + '0'; /* get next digit */
|
|
||||||
} while ((n /= 10) > 0) ; /* delete it */
|
|
||||||
|
|
||||||
if (sign < 0 )
|
|
||||||
{
|
|
||||||
s[i++] = '-';
|
|
||||||
}
|
|
||||||
|
|
||||||
s[i] = '\0';
|
|
||||||
|
|
||||||
reverse( s ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
extern char* itoa( int value, char *string, int radix )
|
|
||||||
{
|
|
||||||
return ltoa( value, string, radix ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern char* ltoa( long value, char *string, int radix )
|
|
||||||
{
|
|
||||||
char tmp[33];
|
|
||||||
char *tp = tmp;
|
|
||||||
long i;
|
|
||||||
unsigned long v;
|
|
||||||
int sign;
|
|
||||||
char *sp;
|
|
||||||
|
|
||||||
if ( string == NULL )
|
|
||||||
{
|
|
||||||
return 0 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (radix > 36 || radix <= 1)
|
|
||||||
{
|
|
||||||
return 0 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
sign = (radix == 10 && value < 0);
|
|
||||||
if (sign)
|
|
||||||
{
|
|
||||||
v = -value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
v = (unsigned long)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (v || tp == tmp)
|
|
||||||
{
|
|
||||||
i = v % radix;
|
|
||||||
v = v / radix;
|
|
||||||
if (i < 10)
|
|
||||||
*tp++ = i+'0';
|
|
||||||
else
|
|
||||||
*tp++ = i + 'a' - 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
sp = string;
|
|
||||||
|
|
||||||
if (sign)
|
|
||||||
*sp++ = '-';
|
|
||||||
while (tp > tmp)
|
|
||||||
*sp++ = *--tp;
|
|
||||||
*sp = 0;
|
|
||||||
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern char* utoa( unsigned int value, char *string, int radix )
|
|
||||||
{
|
|
||||||
return ultoa( value, string, radix ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern char* ultoa( unsigned long value, char *string, int radix )
|
|
||||||
{
|
|
||||||
char tmp[33];
|
|
||||||
char *tp = tmp;
|
|
||||||
long i;
|
|
||||||
unsigned long v = value;
|
|
||||||
char *sp;
|
|
||||||
|
|
||||||
if ( string == NULL )
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (radix > 36 || radix <= 1)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (v || tp == tmp)
|
|
||||||
{
|
|
||||||
i = v % radix;
|
|
||||||
v = v / radix;
|
|
||||||
if (i < 10)
|
|
||||||
*tp++ = i+'0';
|
|
||||||
else
|
|
||||||
*tp++ = i + 'a' - 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
sp = string;
|
|
||||||
|
|
||||||
|
|
||||||
while (tp > tmp)
|
|
||||||
*sp++ = *--tp;
|
|
||||||
*sp = 0;
|
|
||||||
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
#endif /* 0 */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} // extern "C"
|
|
||||||
#endif // __cplusplus
|
|
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _ITOA_
|
|
||||||
#define _ITOA_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"{
|
|
||||||
#endif // __cplusplus
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
extern void itoa( int n, char s[] ) ;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
extern char* itoa( int value, char *string, int radix ) ;
|
|
||||||
extern char* ltoa( long value, char *string, int radix ) ;
|
|
||||||
extern char* utoa( unsigned int value, char *string, int radix ) ;
|
|
||||||
extern char* ultoa( unsigned long value, char *string, int radix ) ;
|
|
||||||
#endif /* 0 */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} // extern "C"
|
|
||||||
#endif // __cplusplus
|
|
||||||
|
|
||||||
#endif // _ITOA_
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
main.cpp - Main loop for Arduino sketches
|
|
||||||
Copyright (c) 2005-2013 Arduino Team. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define ARDUINO_MAIN
|
|
||||||
#include "Arduino.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Cortex-M3 Systick IT handler
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
extern void SysTick_Handler( void )
|
|
||||||
{
|
|
||||||
// Increment tick count each ms
|
|
||||||
TimeTick_Increment() ;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Weak empty variant initialization function.
|
|
||||||
// May be redefined by variant files.
|
|
||||||
void initVariant() __attribute__((weak));
|
|
||||||
void initVariant() { }
|
|
||||||
|
|
||||||
/*
|
|
||||||
* \brief Main entry point of Arduino application
|
|
||||||
*/
|
|
||||||
int main( void )
|
|
||||||
{
|
|
||||||
// Initialize watchdog
|
|
||||||
watchdogSetup();
|
|
||||||
|
|
||||||
init();
|
|
||||||
|
|
||||||
initVariant();
|
|
||||||
|
|
||||||
delay(1);
|
|
||||||
|
|
||||||
#if defined(USBCON)
|
|
||||||
USBDevice.attach();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
setup();
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
loop();
|
|
||||||
if (serialEventRun) serialEventRun();
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2014 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
void *operator new(size_t size) {
|
|
||||||
return malloc(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *operator new[](size_t size) {
|
|
||||||
return malloc(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator delete(void * ptr) {
|
|
||||||
free(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator delete[](void * ptr) {
|
|
||||||
free(ptr);
|
|
||||||
}
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file syscalls.h
|
|
||||||
*
|
|
||||||
* Implementation of newlib syscall.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
* Headers
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
* Exported functions
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern caddr_t _sbrk( int incr ) ;
|
|
||||||
|
|
||||||
extern int link( char *cOld, char *cNew ) ;
|
|
||||||
|
|
||||||
extern int _close( int file ) ;
|
|
||||||
|
|
||||||
extern int _fstat( int file, struct stat *st ) ;
|
|
||||||
|
|
||||||
extern int _isatty( int file ) ;
|
|
||||||
|
|
||||||
extern int _lseek( int file, int ptr, int dir ) ;
|
|
||||||
|
|
||||||
extern int _read(int file, char *ptr, int len) ;
|
|
||||||
|
|
||||||
extern int _write( int file, char *ptr, int len ) ;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,148 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file syscalls_sam3.c
|
|
||||||
*
|
|
||||||
* Implementation of newlib syscall.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
* Headers
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "syscalls.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include "sam.h"
|
|
||||||
#if defined ( __GNUC__ ) /* GCC CS3 */
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Helper macro to mark unused parameters and prevent compiler warnings.
|
|
||||||
// Appends _UNUSED to the variable name to prevent accidentally using them.
|
|
||||||
#ifdef __GNUC__
|
|
||||||
# define UNUSED(x) x ## _UNUSED __attribute__((__unused__))
|
|
||||||
#else
|
|
||||||
# define UNUSED(x) x ## _UNUSED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
* Exported variables
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#undef errno
|
|
||||||
extern int errno ;
|
|
||||||
extern int _end ;
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
* Exported functions
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
extern void _exit( int status ) ;
|
|
||||||
extern void _kill( int pid, int sig ) ;
|
|
||||||
extern int _getpid ( void ) ;
|
|
||||||
|
|
||||||
extern caddr_t _sbrk ( int incr )
|
|
||||||
{
|
|
||||||
static unsigned char *heap = NULL ;
|
|
||||||
unsigned char *prev_heap ;
|
|
||||||
|
|
||||||
if ( heap == NULL )
|
|
||||||
{
|
|
||||||
heap = (unsigned char *)&_end ;
|
|
||||||
}
|
|
||||||
prev_heap = heap;
|
|
||||||
|
|
||||||
heap += incr ;
|
|
||||||
|
|
||||||
return (caddr_t) prev_heap ;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int link( UNUSED(char *cOld), UNUSED(char *cNew) )
|
|
||||||
{
|
|
||||||
return -1 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int _close( UNUSED(int file) )
|
|
||||||
{
|
|
||||||
return -1 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int _fstat( UNUSED(int file), struct stat *st )
|
|
||||||
{
|
|
||||||
st->st_mode = S_IFCHR ;
|
|
||||||
|
|
||||||
return 0 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int _isatty( UNUSED(int file) )
|
|
||||||
{
|
|
||||||
return 1 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int _lseek( UNUSED(int file), UNUSED(int ptr), UNUSED(int dir) )
|
|
||||||
{
|
|
||||||
return 0 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int _read(UNUSED(int file), UNUSED(char *ptr), UNUSED(int len) )
|
|
||||||
{
|
|
||||||
return 0 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int _write( UNUSED(int file), char *ptr, int len )
|
|
||||||
{
|
|
||||||
int iIndex ;
|
|
||||||
|
|
||||||
|
|
||||||
// for ( ; *ptr != 0 ; ptr++ )
|
|
||||||
for ( iIndex=0 ; iIndex < len ; iIndex++, ptr++ )
|
|
||||||
{
|
|
||||||
// UART_PutChar( *ptr ) ;
|
|
||||||
|
|
||||||
// Check if the transmitter is ready
|
|
||||||
while ((UART->UART_SR & UART_SR_TXRDY) != UART_SR_TXRDY)
|
|
||||||
;
|
|
||||||
|
|
||||||
// Send character
|
|
||||||
UART->UART_THR = *ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return iIndex ;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void _exit( int status )
|
|
||||||
{
|
|
||||||
printf( "Exiting with status %d.\n", status ) ;
|
|
||||||
|
|
||||||
for ( ; ; ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void _kill( UNUSED(int pid), UNUSED(int sig) )
|
|
||||||
{
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int _getpid ( void )
|
|
||||||
{
|
|
||||||
return -1 ;
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2014 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <chip.h>
|
|
||||||
|
|
||||||
#include "watchdog.h"
|
|
||||||
|
|
||||||
|
|
||||||
void watchdogEnable (uint32_t timeout)
|
|
||||||
{
|
|
||||||
/* this assumes the slow clock is running at 32.768 kHz
|
|
||||||
watchdog frequency is therefore 32768 / 128 = 256 Hz */
|
|
||||||
timeout = timeout * 256 / 1000;
|
|
||||||
if (timeout == 0)
|
|
||||||
timeout = 1;
|
|
||||||
else if (timeout > 0xFFF)
|
|
||||||
timeout = 0xFFF;
|
|
||||||
timeout = WDT_MR_WDRSTEN | WDT_MR_WDV(timeout) | WDT_MR_WDD(timeout);
|
|
||||||
WDT_Enable (WDT, timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
void watchdogDisable(void)
|
|
||||||
{
|
|
||||||
WDT_Disable (WDT);
|
|
||||||
}
|
|
||||||
|
|
||||||
void watchdogReset(void)
|
|
||||||
{
|
|
||||||
WDT_Restart (WDT);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
void _watchdogDefaultSetup (void)
|
|
||||||
{
|
|
||||||
WDT_Disable (WDT);
|
|
||||||
}
|
|
||||||
void watchdogSetup (void) __attribute__ ((weak, alias("_watchdogDefaultSetup")));
|
|
||||||
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2014 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _WATCHDOG_
|
|
||||||
#define _WATCHDOG_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
// Watchdog functions
|
|
||||||
|
|
||||||
/*
|
|
||||||
* \brief Enable the watchdog with the specified timeout. Should only be called once.
|
|
||||||
*
|
|
||||||
* \param timeount in milliseconds.
|
|
||||||
*/
|
|
||||||
void watchdogEnable (uint32_t timeout);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* \brief Disable the watchdog timer. Should only be called once.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void watchdogDisable (void);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* \brief Reset the watchdog counter.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void watchdogReset (void);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* \brief Watchdog initialize hook. This function is called from init(). If the user does not provide
|
|
||||||
* this function, then the default action is to disable watchdog.
|
|
||||||
*/
|
|
||||||
void watchdogSetup (void);
|
|
||||||
|
|
||||||
#endif /* _WATCHDOG_ */
|
|
||||||
|
|
@ -1,102 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint32_t millis( void )
|
|
||||||
{
|
|
||||||
// todo: ensure no interrupts
|
|
||||||
return GetTickCount() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Interrupt-compatible version of micros
|
|
||||||
// Theory: repeatedly take readings of SysTick counter, millis counter and SysTick interrupt pending flag.
|
|
||||||
// When it appears that millis counter and pending is stable and SysTick hasn't rolled over, use these
|
|
||||||
// values to calculate micros. If there is a pending SysTick, add one to the millis counter in the calculation.
|
|
||||||
uint32_t micros( void )
|
|
||||||
{
|
|
||||||
uint32_t ticks, ticks2;
|
|
||||||
uint32_t pend, pend2;
|
|
||||||
uint32_t count, count2;
|
|
||||||
|
|
||||||
ticks2 = SysTick->VAL;
|
|
||||||
pend2 = !!((SCB->ICSR & SCB_ICSR_PENDSTSET_Msk)||((SCB->SHCSR & SCB_SHCSR_SYSTICKACT_Msk))) ;
|
|
||||||
count2 = GetTickCount();
|
|
||||||
|
|
||||||
do {
|
|
||||||
ticks=ticks2;
|
|
||||||
pend=pend2;
|
|
||||||
count=count2;
|
|
||||||
ticks2 = SysTick->VAL;
|
|
||||||
pend2 = !!((SCB->ICSR & SCB_ICSR_PENDSTSET_Msk)||((SCB->SHCSR & SCB_SHCSR_SYSTICKACT_Msk))) ;
|
|
||||||
count2 = GetTickCount();
|
|
||||||
} while ((pend != pend2) || (count != count2) || (ticks < ticks2));
|
|
||||||
|
|
||||||
return ((count+pend) * 1000) + (((SysTick->LOAD - ticks)*(1048576/(F_CPU/1000000)))>>20) ;
|
|
||||||
// this is an optimization to turn a runtime division into two compile-time divisions and
|
|
||||||
// a runtime multiplication and shift, saving a few cycles
|
|
||||||
}
|
|
||||||
|
|
||||||
// original function:
|
|
||||||
// uint32_t micros( void )
|
|
||||||
// {
|
|
||||||
// uint32_t ticks ;
|
|
||||||
// uint32_t count ;
|
|
||||||
//
|
|
||||||
// SysTick->CTRL;
|
|
||||||
// do {
|
|
||||||
// ticks = SysTick->VAL;
|
|
||||||
// count = GetTickCount();
|
|
||||||
// } while (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk);
|
|
||||||
//
|
|
||||||
// return count * 1000 + (SysTick->LOAD + 1 - ticks) / (SystemCoreClock/1000000) ;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
void delay( uint32_t ms )
|
|
||||||
{
|
|
||||||
if (ms == 0)
|
|
||||||
return;
|
|
||||||
uint32_t start = GetTickCount();
|
|
||||||
do {
|
|
||||||
yield();
|
|
||||||
} while (GetTickCount() - start < ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */
|
|
||||||
extern signed int putchar( signed int c ) ;
|
|
||||||
/**
|
|
||||||
* \brief
|
|
||||||
*
|
|
||||||
* \param c Character to output.
|
|
||||||
*
|
|
||||||
* \return The character that was output.
|
|
||||||
*/
|
|
||||||
extern WEAK signed int putchar( signed int c )
|
|
||||||
{
|
|
||||||
return c ;
|
|
||||||
}
|
|
||||||
#endif /* __ICCARM__ */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
Copyright (c) 2013 by Paul Stoffregen <paul@pjrc.com> (delayMicroseconds)
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _WIRING_
|
|
||||||
#define _WIRING_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
extern void initVariant( void ) ;
|
|
||||||
extern void init( void ) ;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Returns the number of milliseconds since the Arduino board began running the current program.
|
|
||||||
*
|
|
||||||
* This number will overflow (go back to zero), after approximately 50 days.
|
|
||||||
*
|
|
||||||
* \return Number of milliseconds since the program started (uint32_t)
|
|
||||||
*/
|
|
||||||
extern uint32_t millis( void ) ;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Returns the number of microseconds since the Arduino board began running the current program.
|
|
||||||
*
|
|
||||||
* This number will overflow (go back to zero), after approximately 70 minutes. On 16 MHz Arduino boards
|
|
||||||
* (e.g. Duemilanove and Nano), this function has a resolution of four microseconds (i.e. the value returned is
|
|
||||||
* always a multiple of four). On 8 MHz Arduino boards (e.g. the LilyPad), this function has a resolution
|
|
||||||
* of eight microseconds.
|
|
||||||
*
|
|
||||||
* \note There are 1,000 microseconds in a millisecond and 1,000,000 microseconds in a second.
|
|
||||||
*/
|
|
||||||
extern uint32_t micros( void ) ;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Pauses the program for the amount of time (in miliseconds) specified as parameter.
|
|
||||||
* (There are 1000 milliseconds in a second.)
|
|
||||||
*
|
|
||||||
* \param dwMs the number of milliseconds to pause (uint32_t)
|
|
||||||
*/
|
|
||||||
extern void delay( uint32_t dwMs ) ;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Pauses the program for the amount of time (in microseconds) specified as parameter.
|
|
||||||
*
|
|
||||||
* \param dwUs the number of microseconds to pause (uint32_t)
|
|
||||||
*/
|
|
||||||
static inline void delayMicroseconds(uint32_t) __attribute__((always_inline, unused));
|
|
||||||
static inline void delayMicroseconds(uint32_t usec){
|
|
||||||
/*
|
|
||||||
* Based on Paul Stoffregen's implementation
|
|
||||||
* for Teensy 3.0 (http://www.pjrc.com/)
|
|
||||||
*/
|
|
||||||
if (usec == 0) return;
|
|
||||||
uint32_t n = usec * (VARIANT_MCK / 3000000);
|
|
||||||
asm volatile(
|
|
||||||
"L_%=_delayMicroseconds:" "\n\t"
|
|
||||||
"subs %0, #1" "\n\t"
|
|
||||||
"bne L_%=_delayMicroseconds" "\n"
|
|
||||||
: "+r" (n) :
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _WIRING_ */
|
|
@ -1,353 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int _readResolution = 10;
|
|
||||||
static int _writeResolution = 8;
|
|
||||||
|
|
||||||
void analogReadResolution(int res) {
|
|
||||||
_readResolution = res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void analogWriteResolution(int res) {
|
|
||||||
_writeResolution = res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t mapResolution(uint32_t value, uint32_t from, uint32_t to) {
|
|
||||||
if (from == to)
|
|
||||||
return value;
|
|
||||||
if (from > to)
|
|
||||||
return value >> (from-to);
|
|
||||||
else
|
|
||||||
return value << (to-from);
|
|
||||||
}
|
|
||||||
|
|
||||||
eAnalogReference analog_reference = AR_DEFAULT;
|
|
||||||
|
|
||||||
void analogReference(eAnalogReference ulMode)
|
|
||||||
{
|
|
||||||
analog_reference = ulMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t analogRead(uint32_t ulPin)
|
|
||||||
{
|
|
||||||
uint32_t ulValue = 0;
|
|
||||||
uint32_t ulChannel;
|
|
||||||
|
|
||||||
if (ulPin < A0)
|
|
||||||
ulPin += A0;
|
|
||||||
|
|
||||||
ulChannel = g_APinDescription[ulPin].ulADCChannelNumber ;
|
|
||||||
|
|
||||||
#if defined __SAM3U4E__
|
|
||||||
switch ( g_APinDescription[ulPin].ulAnalogChannel )
|
|
||||||
{
|
|
||||||
// Handling ADC 10 bits channels
|
|
||||||
case ADC0 :
|
|
||||||
case ADC1 :
|
|
||||||
case ADC2 :
|
|
||||||
case ADC3 :
|
|
||||||
case ADC4 :
|
|
||||||
case ADC5 :
|
|
||||||
case ADC6 :
|
|
||||||
case ADC7 :
|
|
||||||
// Enable the corresponding channel
|
|
||||||
adc_enable_channel( ADC, ulChannel );
|
|
||||||
|
|
||||||
// Start the ADC
|
|
||||||
adc_start( ADC );
|
|
||||||
|
|
||||||
// Wait for end of conversion
|
|
||||||
while ((adc_get_status(ADC) & ADC_SR_DRDY) != ADC_SR_DRDY)
|
|
||||||
;
|
|
||||||
|
|
||||||
// Read the value
|
|
||||||
ulValue = adc_get_latest_value(ADC);
|
|
||||||
ulValue = mapResolution(ulValue, 10, _readResolution);
|
|
||||||
|
|
||||||
// Disable the corresponding channel
|
|
||||||
adc_disable_channel( ADC, ulChannel );
|
|
||||||
|
|
||||||
// Stop the ADC
|
|
||||||
// adc_stop( ADC ) ; // never do adc_stop() else we have to reconfigure the ADC each time
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Handling ADC 12 bits channels
|
|
||||||
case ADC8 :
|
|
||||||
case ADC9 :
|
|
||||||
case ADC10 :
|
|
||||||
case ADC11 :
|
|
||||||
case ADC12 :
|
|
||||||
case ADC13 :
|
|
||||||
case ADC14 :
|
|
||||||
case ADC15 :
|
|
||||||
// Enable the corresponding channel
|
|
||||||
adc12b_enable_channel( ADC12B, ulChannel );
|
|
||||||
|
|
||||||
// Start the ADC12B
|
|
||||||
adc12b_start( ADC12B );
|
|
||||||
|
|
||||||
// Wait for end of conversion
|
|
||||||
while ((adc12b_get_status(ADC12B) & ADC12B_SR_DRDY) != ADC12B_SR_DRDY)
|
|
||||||
;
|
|
||||||
|
|
||||||
// Read the value
|
|
||||||
ulValue = adc12b_get_latest_value(ADC12B) >> 2;
|
|
||||||
ulValue = mapResolution(ulValue, 12, _readResolution);
|
|
||||||
|
|
||||||
// Stop the ADC12B
|
|
||||||
// adc12_stop( ADC12B ) ; // never do adc12_stop() else we have to reconfigure the ADC12B each time
|
|
||||||
|
|
||||||
// Disable the corresponding channel
|
|
||||||
adc12b_disable_channel( ADC12B, ulChannel );
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Compiler could yell because we don't handle DAC pins
|
|
||||||
default :
|
|
||||||
ulValue=0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined __SAM3X8E__ || defined __SAM3X8H__
|
|
||||||
static uint32_t latestSelectedChannel = -1;
|
|
||||||
switch ( g_APinDescription[ulPin].ulAnalogChannel )
|
|
||||||
{
|
|
||||||
// Handling ADC 12 bits channels
|
|
||||||
case ADC0 :
|
|
||||||
case ADC1 :
|
|
||||||
case ADC2 :
|
|
||||||
case ADC3 :
|
|
||||||
case ADC4 :
|
|
||||||
case ADC5 :
|
|
||||||
case ADC6 :
|
|
||||||
case ADC7 :
|
|
||||||
case ADC8 :
|
|
||||||
case ADC9 :
|
|
||||||
case ADC10 :
|
|
||||||
case ADC11 :
|
|
||||||
|
|
||||||
// Enable the corresponding channel
|
|
||||||
if (adc_get_channel_status(ADC, ulChannel) != 1) {
|
|
||||||
adc_enable_channel( ADC, ulChannel );
|
|
||||||
if ( latestSelectedChannel != (uint32_t)-1 && ulChannel != latestSelectedChannel)
|
|
||||||
adc_disable_channel( ADC, latestSelectedChannel );
|
|
||||||
latestSelectedChannel = ulChannel;
|
|
||||||
g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_ANALOG;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the ADC
|
|
||||||
adc_start( ADC );
|
|
||||||
|
|
||||||
// Wait for end of conversion
|
|
||||||
while ((adc_get_status(ADC) & ADC_ISR_DRDY) != ADC_ISR_DRDY)
|
|
||||||
;
|
|
||||||
|
|
||||||
// Read the value
|
|
||||||
ulValue = adc_get_latest_value(ADC);
|
|
||||||
ulValue = mapResolution(ulValue, ADC_RESOLUTION, _readResolution);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Compiler could yell because we don't handle DAC pins
|
|
||||||
default :
|
|
||||||
ulValue=0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return ulValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void TC_SetCMR_ChannelA(Tc *tc, uint32_t chan, uint32_t v)
|
|
||||||
{
|
|
||||||
tc->TC_CHANNEL[chan].TC_CMR = (tc->TC_CHANNEL[chan].TC_CMR & 0xFFF0FFFF) | v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void TC_SetCMR_ChannelB(Tc *tc, uint32_t chan, uint32_t v)
|
|
||||||
{
|
|
||||||
tc->TC_CHANNEL[chan].TC_CMR = (tc->TC_CHANNEL[chan].TC_CMR & 0xF0FFFFFF) | v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t PWMEnabled = 0;
|
|
||||||
static uint8_t TCChanEnabled[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
|
|
||||||
|
|
||||||
void analogOutputInit(void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Right now, PWM output only works on the pins with
|
|
||||||
// hardware support. These are defined in the appropriate
|
|
||||||
// pins_*.c file. For the rest of the pins, we default
|
|
||||||
// to digital output.
|
|
||||||
void analogWrite(uint32_t ulPin, uint32_t ulValue) {
|
|
||||||
uint32_t attr = g_APinDescription[ulPin].ulPinAttribute;
|
|
||||||
|
|
||||||
if ((attr & PIN_ATTR_ANALOG) == PIN_ATTR_ANALOG) {
|
|
||||||
EAnalogChannel channel = g_APinDescription[ulPin].ulADCChannelNumber;
|
|
||||||
if (channel == DA0 || channel == DA1) {
|
|
||||||
uint32_t chDACC = ((channel == DA0) ? 0 : 1);
|
|
||||||
if (dacc_get_channel_status(DACC_INTERFACE) == 0) {
|
|
||||||
/* Enable clock for DACC_INTERFACE */
|
|
||||||
pmc_enable_periph_clk(DACC_INTERFACE_ID);
|
|
||||||
|
|
||||||
/* Reset DACC registers */
|
|
||||||
dacc_reset(DACC_INTERFACE);
|
|
||||||
|
|
||||||
/* Half word transfer mode */
|
|
||||||
dacc_set_transfer_mode(DACC_INTERFACE, 0);
|
|
||||||
|
|
||||||
/* Power save:
|
|
||||||
* sleep mode - 0 (disabled)
|
|
||||||
* fast wakeup - 0 (disabled)
|
|
||||||
*/
|
|
||||||
dacc_set_power_save(DACC_INTERFACE, 0, 0);
|
|
||||||
/* Timing:
|
|
||||||
* refresh - 0x08 (1024*8 dacc clocks)
|
|
||||||
* max speed mode - 0 (disabled)
|
|
||||||
* startup time - 0x10 (1024 dacc clocks)
|
|
||||||
*/
|
|
||||||
dacc_set_timing(DACC_INTERFACE, 0x08, 0, 0x10);
|
|
||||||
|
|
||||||
/* Set up analog current */
|
|
||||||
dacc_set_analog_control(DACC_INTERFACE, DACC_ACR_IBCTLCH0(0x02) |
|
|
||||||
DACC_ACR_IBCTLCH1(0x02) |
|
|
||||||
DACC_ACR_IBCTLDACCORE(0x01));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable TAG and select output channel chDACC */
|
|
||||||
dacc_set_channel_selection(DACC_INTERFACE, chDACC);
|
|
||||||
|
|
||||||
if ((dacc_get_channel_status(DACC_INTERFACE) & (1 << chDACC)) == 0) {
|
|
||||||
dacc_enable_channel(DACC_INTERFACE, chDACC);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write user value
|
|
||||||
ulValue = mapResolution(ulValue, _writeResolution, DACC_RESOLUTION);
|
|
||||||
dacc_write_conversion_data(DACC_INTERFACE, ulValue);
|
|
||||||
while ((dacc_get_interrupt_status(DACC_INTERFACE) & DACC_ISR_EOC) == 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((attr & PIN_ATTR_PWM) == PIN_ATTR_PWM) {
|
|
||||||
ulValue = mapResolution(ulValue, _writeResolution, PWM_RESOLUTION);
|
|
||||||
|
|
||||||
if (!PWMEnabled) {
|
|
||||||
// PWM Startup code
|
|
||||||
pmc_enable_periph_clk(PWM_INTERFACE_ID);
|
|
||||||
PWMC_ConfigureClocks(PWM_FREQUENCY * PWM_MAX_DUTY_CYCLE, 0, VARIANT_MCK);
|
|
||||||
PWMEnabled = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t chan = g_APinDescription[ulPin].ulPWMChannel;
|
|
||||||
if ((g_pinStatus[ulPin] & 0xF) != PIN_STATUS_PWM) {
|
|
||||||
// Setup PWM for this pin
|
|
||||||
PIO_Configure(g_APinDescription[ulPin].pPort,
|
|
||||||
g_APinDescription[ulPin].ulPinType,
|
|
||||||
g_APinDescription[ulPin].ulPin,
|
|
||||||
g_APinDescription[ulPin].ulPinConfiguration);
|
|
||||||
PWMC_ConfigureChannel(PWM_INTERFACE, chan, PWM_CMR_CPRE_CLKA, 0, 0);
|
|
||||||
PWMC_SetPeriod(PWM_INTERFACE, chan, PWM_MAX_DUTY_CYCLE);
|
|
||||||
PWMC_SetDutyCycle(PWM_INTERFACE, chan, ulValue);
|
|
||||||
PWMC_EnableChannel(PWM_INTERFACE, chan);
|
|
||||||
g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_PWM;
|
|
||||||
}
|
|
||||||
|
|
||||||
PWMC_SetDutyCycle(PWM_INTERFACE, chan, ulValue);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((attr & PIN_ATTR_TIMER) == PIN_ATTR_TIMER) {
|
|
||||||
// We use MCLK/2 as clock.
|
|
||||||
const uint32_t TC = VARIANT_MCK / 2 / TC_FREQUENCY;
|
|
||||||
|
|
||||||
// Map value to Timer ranges 0..255 => 0..TC
|
|
||||||
ulValue = mapResolution(ulValue, _writeResolution, TC_RESOLUTION);
|
|
||||||
ulValue = ulValue * TC;
|
|
||||||
ulValue = ulValue / TC_MAX_DUTY_CYCLE;
|
|
||||||
|
|
||||||
// Setup Timer for this pin
|
|
||||||
ETCChannel channel = g_APinDescription[ulPin].ulTCChannel;
|
|
||||||
static const uint32_t channelToChNo[] = { 0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2 };
|
|
||||||
static const uint32_t channelToAB[] = { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 };
|
|
||||||
static Tc *channelToTC[] = {
|
|
||||||
TC0, TC0, TC0, TC0, TC0, TC0,
|
|
||||||
TC1, TC1, TC1, TC1, TC1, TC1,
|
|
||||||
TC2, TC2, TC2, TC2, TC2, TC2 };
|
|
||||||
static const uint32_t channelToId[] = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8 };
|
|
||||||
uint32_t chNo = channelToChNo[channel];
|
|
||||||
uint32_t chA = channelToAB[channel];
|
|
||||||
Tc *chTC = channelToTC[channel];
|
|
||||||
uint32_t interfaceID = channelToId[channel];
|
|
||||||
|
|
||||||
if (!TCChanEnabled[interfaceID]) {
|
|
||||||
pmc_enable_periph_clk(TC_INTERFACE_ID + interfaceID);
|
|
||||||
TC_Configure(chTC, chNo,
|
|
||||||
TC_CMR_TCCLKS_TIMER_CLOCK1 |
|
|
||||||
TC_CMR_WAVE | // Waveform mode
|
|
||||||
TC_CMR_WAVSEL_UP_RC | // Counter running up and reset when equals to RC
|
|
||||||
TC_CMR_EEVT_XC0 | // Set external events from XC0 (this setup TIOB as output)
|
|
||||||
TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_CLEAR |
|
|
||||||
TC_CMR_BCPB_CLEAR | TC_CMR_BCPC_CLEAR);
|
|
||||||
TC_SetRC(chTC, chNo, TC);
|
|
||||||
}
|
|
||||||
if (ulValue == 0) {
|
|
||||||
if (chA)
|
|
||||||
TC_SetCMR_ChannelA(chTC, chNo, TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_CLEAR);
|
|
||||||
else
|
|
||||||
TC_SetCMR_ChannelB(chTC, chNo, TC_CMR_BCPB_CLEAR | TC_CMR_BCPC_CLEAR);
|
|
||||||
} else {
|
|
||||||
if (chA) {
|
|
||||||
TC_SetRA(chTC, chNo, ulValue);
|
|
||||||
TC_SetCMR_ChannelA(chTC, chNo, TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_SET);
|
|
||||||
} else {
|
|
||||||
TC_SetRB(chTC, chNo, ulValue);
|
|
||||||
TC_SetCMR_ChannelB(chTC, chNo, TC_CMR_BCPB_CLEAR | TC_CMR_BCPC_SET);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((g_pinStatus[ulPin] & 0xF) != PIN_STATUS_PWM) {
|
|
||||||
PIO_Configure(g_APinDescription[ulPin].pPort,
|
|
||||||
g_APinDescription[ulPin].ulPinType,
|
|
||||||
g_APinDescription[ulPin].ulPin,
|
|
||||||
g_APinDescription[ulPin].ulPinConfiguration);
|
|
||||||
g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_PWM;
|
|
||||||
}
|
|
||||||
if (!TCChanEnabled[interfaceID]) {
|
|
||||||
TC_Start(chTC, chNo);
|
|
||||||
TCChanEnabled[interfaceID] = 1;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Defaults to digital write
|
|
||||||
pinMode(ulPin, OUTPUT);
|
|
||||||
ulValue = mapResolution(ulValue, _writeResolution, 8);
|
|
||||||
if (ulValue < 128)
|
|
||||||
digitalWrite(ulPin, LOW);
|
|
||||||
else
|
|
||||||
digitalWrite(ulPin, HIGH);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,79 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _WIRING_ANALOG_
|
|
||||||
#define _WIRING_ANALOG_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* \brief SAM3 products have only one reference for ADC
|
|
||||||
*/
|
|
||||||
typedef enum _eAnalogReference
|
|
||||||
{
|
|
||||||
AR_DEFAULT,
|
|
||||||
} eAnalogReference ;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* \brief Configures the reference voltage used for analog input (i.e. the value used as the top of the input range).
|
|
||||||
* This function is kept only for compatibility with existing AVR based API.
|
|
||||||
*
|
|
||||||
* \param ulMmode Should be set to AR_DEFAULT.
|
|
||||||
*/
|
|
||||||
extern void analogReference( eAnalogReference ulMode ) ;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* \brief Writes an analog value (PWM wave) to a pin.
|
|
||||||
*
|
|
||||||
* \param ulPin
|
|
||||||
* \param ulValue
|
|
||||||
*/
|
|
||||||
extern void analogWrite( uint32_t ulPin, uint32_t ulValue ) ;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* \brief Reads the value from the specified analog pin.
|
|
||||||
*
|
|
||||||
* \param ulPin
|
|
||||||
*
|
|
||||||
* \return Read value from selected pin, if no error.
|
|
||||||
*/
|
|
||||||
extern uint32_t analogRead( uint32_t ulPin ) ;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* \brief Set the resolution of analogRead return values. Default is 10 bits (range from 0 to 1023).
|
|
||||||
*
|
|
||||||
* \param res
|
|
||||||
*/
|
|
||||||
extern void analogReadResolution(int res);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* \brief Set the resolution of analogWrite parameters. Default is 8 bits (range from 0 to 255).
|
|
||||||
*
|
|
||||||
* \param res
|
|
||||||
*/
|
|
||||||
extern void analogWriteResolution(int res);
|
|
||||||
|
|
||||||
extern void analogOutputInit( void ) ;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _WIRING_ANALOG_ */
|
|
@ -1,102 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _WIRING_CONSTANTS_
|
|
||||||
#define _WIRING_CONSTANTS_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"{
|
|
||||||
#endif // __cplusplus
|
|
||||||
|
|
||||||
#define HIGH 0x1
|
|
||||||
#define LOW 0x0
|
|
||||||
|
|
||||||
#define INPUT 0x0
|
|
||||||
#define OUTPUT 0x1
|
|
||||||
#define INPUT_PULLUP 0x2
|
|
||||||
|
|
||||||
#define true 0x1
|
|
||||||
#define false 0x0
|
|
||||||
|
|
||||||
#define PI 3.1415926535897932384626433832795
|
|
||||||
#define HALF_PI 1.5707963267948966192313216916398
|
|
||||||
#define TWO_PI 6.283185307179586476925286766559
|
|
||||||
#define DEG_TO_RAD 0.017453292519943295769236907684886
|
|
||||||
#define RAD_TO_DEG 57.295779513082320876798154814105
|
|
||||||
#define EULER 2.718281828459045235360287471352
|
|
||||||
|
|
||||||
#define SERIAL 0x0
|
|
||||||
#define DISPLAY 0x1
|
|
||||||
|
|
||||||
enum BitOrder {
|
|
||||||
LSBFIRST = 0,
|
|
||||||
MSBFIRST = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
// LOW 0
|
|
||||||
// HIGH 1
|
|
||||||
#define CHANGE 2
|
|
||||||
#define FALLING 3
|
|
||||||
#define RISING 4
|
|
||||||
|
|
||||||
#define DEFAULT 1
|
|
||||||
#define EXTERNAL 0
|
|
||||||
|
|
||||||
// undefine stdlib's abs if encountered
|
|
||||||
#ifdef abs
|
|
||||||
#undef abs
|
|
||||||
#endif // abs
|
|
||||||
|
|
||||||
#ifndef min
|
|
||||||
#define min(a,b) ((a)<(b)?(a):(b))
|
|
||||||
#endif // min
|
|
||||||
|
|
||||||
#ifndef max
|
|
||||||
#define max(a,b) ((a)>(b)?(a):(b))
|
|
||||||
#endif // max
|
|
||||||
|
|
||||||
#define abs(x) ((x)>0?(x):-(x))
|
|
||||||
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
|
|
||||||
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
|
|
||||||
#define radians(deg) ((deg)*DEG_TO_RAD)
|
|
||||||
#define degrees(rad) ((rad)*RAD_TO_DEG)
|
|
||||||
#define sq(x) ((x)*(x))
|
|
||||||
|
|
||||||
#define interrupts() __enable_irq()
|
|
||||||
#define noInterrupts() __disable_irq()
|
|
||||||
|
|
||||||
#define lowByte(w) ((uint8_t) ((w) & 0xff))
|
|
||||||
#define highByte(w) ((uint8_t) ((w) >> 8))
|
|
||||||
|
|
||||||
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
|
|
||||||
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
|
|
||||||
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
|
|
||||||
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
|
|
||||||
|
|
||||||
typedef unsigned int word;
|
|
||||||
|
|
||||||
#define bit(b) (1UL << (b))
|
|
||||||
|
|
||||||
typedef bool boolean ;
|
|
||||||
typedef uint8_t byte ;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} // extern "C"
|
|
||||||
#endif // __cplusplus
|
|
||||||
|
|
||||||
#endif /* _WIRING_CONSTANTS_ */
|
|
@ -1,141 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern void pinMode( uint32_t ulPin, uint32_t ulMode )
|
|
||||||
{
|
|
||||||
if ( g_APinDescription[ulPin].ulPinType == PIO_NOT_A_PIN )
|
|
||||||
{
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_ANALOG)
|
|
||||||
{
|
|
||||||
adc_disable_channel( ADC, g_APinDescription[ulPin].ulADCChannelNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((g_pinStatus[ulPin] & 0xF) < PIN_STATUS_DIGITAL_OUTPUT && g_pinStatus[ulPin] != 0)
|
|
||||||
{
|
|
||||||
// return if already configured in the right way
|
|
||||||
if (((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_DIGITAL_INPUT && ulMode == INPUT) ||
|
|
||||||
((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_DIGITAL_INPUT_PULLUP && ulMode == INPUT_PULLUP) ||
|
|
||||||
((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_DIGITAL_OUTPUT && ulMode == OUTPUT))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ( ulMode )
|
|
||||||
{
|
|
||||||
case INPUT:
|
|
||||||
/* Enable peripheral for clocking input */
|
|
||||||
pmc_enable_periph_clk( g_APinDescription[ulPin].ulPeripheralId ) ;
|
|
||||||
PIO_Configure(
|
|
||||||
g_APinDescription[ulPin].pPort,
|
|
||||||
PIO_INPUT,
|
|
||||||
g_APinDescription[ulPin].ulPin,
|
|
||||||
0 ) ;
|
|
||||||
g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_DIGITAL_INPUT;
|
|
||||||
break ;
|
|
||||||
|
|
||||||
case INPUT_PULLUP:
|
|
||||||
/* Enable peripheral for clocking input */
|
|
||||||
pmc_enable_periph_clk( g_APinDescription[ulPin].ulPeripheralId ) ;
|
|
||||||
PIO_Configure(
|
|
||||||
g_APinDescription[ulPin].pPort,
|
|
||||||
PIO_INPUT,
|
|
||||||
g_APinDescription[ulPin].ulPin,
|
|
||||||
PIO_PULLUP ) ;
|
|
||||||
g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_DIGITAL_INPUT_PULLUP;
|
|
||||||
break ;
|
|
||||||
|
|
||||||
case OUTPUT:
|
|
||||||
PIO_Configure(
|
|
||||||
g_APinDescription[ulPin].pPort,
|
|
||||||
(g_pinStatus[ulPin] & 0xF0) >> 4 ? PIO_OUTPUT_1 : PIO_OUTPUT_0,
|
|
||||||
g_APinDescription[ulPin].ulPin,
|
|
||||||
g_APinDescription[ulPin].ulPinConfiguration ) ;
|
|
||||||
|
|
||||||
g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_DIGITAL_OUTPUT;
|
|
||||||
|
|
||||||
/* if all pins are output, disable PIO Controller clocking, reduce power consumption */
|
|
||||||
if ( g_APinDescription[ulPin].pPort->PIO_OSR == 0xffffffff )
|
|
||||||
{
|
|
||||||
pmc_disable_periph_clk( g_APinDescription[ulPin].ulPeripheralId ) ;
|
|
||||||
}
|
|
||||||
break ;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void digitalWrite( uint32_t ulPin, uint32_t ulVal )
|
|
||||||
{
|
|
||||||
/* Handle */
|
|
||||||
if ( g_APinDescription[ulPin].ulPinType == PIO_NOT_A_PIN )
|
|
||||||
{
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_PWM) {
|
|
||||||
pinMode(ulPin, OUTPUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0x0F) | (ulVal << 4) ;
|
|
||||||
|
|
||||||
if ( PIO_GetOutputDataStatus( g_APinDescription[ulPin].pPort, g_APinDescription[ulPin].ulPin ) == 0 )
|
|
||||||
{
|
|
||||||
PIO_PullUp( g_APinDescription[ulPin].pPort, g_APinDescription[ulPin].ulPin, ulVal ) ;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PIO_SetOutput( g_APinDescription[ulPin].pPort, g_APinDescription[ulPin].ulPin, ulVal, 0, PIO_PULLUP ) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int digitalRead( uint32_t ulPin )
|
|
||||||
{
|
|
||||||
if ((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_DIGITAL_OUTPUT) {
|
|
||||||
return (g_pinStatus[ulPin] & 0xF0) >> 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_ANALOG) {
|
|
||||||
pinMode(ulPin, INPUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( g_APinDescription[ulPin].ulPinType == PIO_NOT_A_PIN )
|
|
||||||
{
|
|
||||||
return LOW ;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( PIO_Get( g_APinDescription[ulPin].pPort, PIO_INPUT, g_APinDescription[ulPin].ulPin ) == 1 )
|
|
||||||
{
|
|
||||||
return HIGH ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return LOW ;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _WIRING_DIGITAL_
|
|
||||||
#define _WIRING_DIGITAL_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Configures the specified pin to behave either as an input or an output. See the description of digital pins for details.
|
|
||||||
*
|
|
||||||
* \param ulPin The number of the pin whose mode you wish to set
|
|
||||||
* \param ulMode Either INPUT or OUTPUT
|
|
||||||
*/
|
|
||||||
extern void pinMode( uint32_t dwPin, uint32_t dwMode ) ;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Write a HIGH or a LOW value to a digital pin.
|
|
||||||
*
|
|
||||||
* If the pin has been configured as an OUTPUT with pinMode(), its voltage will be set to the
|
|
||||||
* corresponding value: 5V (or 3.3V on 3.3V boards) for HIGH, 0V (ground) for LOW.
|
|
||||||
*
|
|
||||||
* If the pin is configured as an INPUT, writing a HIGH value with digitalWrite() will enable an internal
|
|
||||||
* 20K pullup resistor (see the tutorial on digital pins). Writing LOW will disable the pullup. The pullup
|
|
||||||
* resistor is enough to light an LED dimly, so if LEDs appear to work, but very dimly, this is a likely
|
|
||||||
* cause. The remedy is to set the pin to an output with the pinMode() function.
|
|
||||||
*
|
|
||||||
* \note Digital pin PIN_LED is harder to use as a digital input than the other digital pins because it has an LED
|
|
||||||
* and resistor attached to it that's soldered to the board on most boards. If you enable its internal 20k pull-up
|
|
||||||
* resistor, it will hang at around 1.7 V instead of the expected 5V because the onboard LED and series resistor
|
|
||||||
* pull the voltage level down, meaning it always returns LOW. If you must use pin PIN_LED as a digital input, use an
|
|
||||||
* external pull down resistor.
|
|
||||||
*
|
|
||||||
* \param dwPin the pin number
|
|
||||||
* \param dwVal HIGH or LOW
|
|
||||||
*/
|
|
||||||
extern void digitalWrite( uint32_t dwPin, uint32_t dwVal ) ;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Reads the value from a specified digital pin, either HIGH or LOW.
|
|
||||||
*
|
|
||||||
* \param ulPin The number of the digital pin you want to read (int)
|
|
||||||
*
|
|
||||||
* \return HIGH or LOW
|
|
||||||
*/
|
|
||||||
extern int digitalRead( uint32_t ulPin ) ;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _WIRING_DIGITAL_ */
|
|
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef WiringPrivate_h
|
|
||||||
#define WiringPrivate_h
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"{
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Includes Atmel CMSIS
|
|
||||||
#include <chip.h>
|
|
||||||
|
|
||||||
#include "wiring_constants.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} // extern "C"
|
|
||||||
|
|
||||||
#include "HardwareSerial.h"
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,93 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
|
||||||
#include "wiring_private.h"
|
|
||||||
|
|
||||||
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
|
|
||||||
* or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
|
|
||||||
* to 3 minutes in length, but must be called at least a few dozen microseconds
|
|
||||||
* before the start of the pulse.
|
|
||||||
*
|
|
||||||
* ATTENTION:
|
|
||||||
* This function performs better with short pulses in noInterrupt() context
|
|
||||||
*/
|
|
||||||
uint32_t pulseIn( uint32_t pin, uint32_t state, uint32_t timeout )
|
|
||||||
{
|
|
||||||
// cache the port and bit of the pin in order to speed up the
|
|
||||||
// pulse width measuring loop and achieve finer resolution. calling
|
|
||||||
// digitalRead() instead yields much coarser resolution.
|
|
||||||
PinDescription p = g_APinDescription[pin];
|
|
||||||
uint32_t bit = p.ulPin;
|
|
||||||
uint32_t stateMask = state ? bit : 0;
|
|
||||||
|
|
||||||
// convert the timeout from microseconds to a number of times through
|
|
||||||
// the initial loop; it takes (roughly) 18 clock cycles per iteration.
|
|
||||||
uint32_t maxloops = microsecondsToClockCycles(timeout) / 18;
|
|
||||||
|
|
||||||
uint32_t width = countPulseASM(&(p.pPort->PIO_PDSR), bit, stateMask, maxloops);
|
|
||||||
|
|
||||||
// convert the reading to microseconds. The loop has been determined
|
|
||||||
// to be 18 clock cycles long and have about 16 clocks between the edge
|
|
||||||
// and the start of the loop. There will be some error introduced by
|
|
||||||
// the interrupt handlers.
|
|
||||||
if (width)
|
|
||||||
return clockCyclesToMicroseconds(width * 18 + 16);
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
|
|
||||||
* or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
|
|
||||||
* to 3 minutes in length, but must be called at least a few dozen microseconds
|
|
||||||
* before the start of the pulse.
|
|
||||||
*
|
|
||||||
* ATTENTION:
|
|
||||||
* this function relies on micros() so cannot be used in noInterrupt() context
|
|
||||||
*/
|
|
||||||
uint32_t pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout)
|
|
||||||
{
|
|
||||||
// cache the port and bit of the pin in order to speed up the
|
|
||||||
// pulse width measuring loop and achieve finer resolution. calling
|
|
||||||
// digitalRead() instead yields much coarser resolution.
|
|
||||||
PinDescription p = g_APinDescription[pin];
|
|
||||||
uint32_t bit = p.ulPin;
|
|
||||||
uint32_t stateMask = state ? bit : 0;
|
|
||||||
|
|
||||||
unsigned long startMicros = micros();
|
|
||||||
|
|
||||||
// wait for any previous pulse to end
|
|
||||||
while ((p.pPort->PIO_PDSR & bit) == stateMask) {
|
|
||||||
if (micros() - startMicros > timeout)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// wait for the pulse to start
|
|
||||||
while ((p.pPort->PIO_PDSR & bit) != stateMask) {
|
|
||||||
if (micros() - startMicros > timeout)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long start = micros();
|
|
||||||
// wait for the pulse to stop
|
|
||||||
while ((p.pPort->PIO_PDSR & bit) == stateMask) {
|
|
||||||
if (micros() - startMicros > timeout)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return micros() - start;
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _WIRING_PULSE_
|
|
||||||
#define _WIRING_PULSE_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
unsigned long countPulseASM(const volatile uint32_t *port, uint32_t bit, uint32_t stateMask, unsigned long maxloops);
|
|
||||||
/*
|
|
||||||
* \brief Measures the length (in microseconds) of a pulse on the pin; state is HIGH
|
|
||||||
* or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
|
|
||||||
* to 3 minutes in length, but must be called at least a few dozen microseconds
|
|
||||||
* before the start of the pulse.
|
|
||||||
*/
|
|
||||||
extern uint32_t pulseIn( uint32_t ulPin, uint32_t ulState, uint32_t ulTimeout = 1000000L ) ;
|
|
||||||
extern uint32_t pulseInLong( uint8_t pin, uint8_t state, unsigned long timeout = 1000000L ) ;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _WIRING_PULSE_ */
|
|
@ -1,166 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2015 Arduino LLC. All right reserved.
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
The following function has been compiled to ASM with gcc
|
|
||||||
unsigned long countPulseASM(const volatile uint32_t *port, uint32_t bit, uint32_t stateMask, unsigned long maxloops)
|
|
||||||
{
|
|
||||||
unsigned long width = 0;
|
|
||||||
// wait for any previous pulse to end
|
|
||||||
while ((*port & bit) == stateMask)
|
|
||||||
if (--maxloops == 0)
|
|
||||||
return 0;
|
|
||||||
// wait for the pulse to start
|
|
||||||
while ((*port & bit) != stateMask)
|
|
||||||
if (--maxloops == 0)
|
|
||||||
return 0;
|
|
||||||
// wait for the pulse to stop
|
|
||||||
while ((*port & bit) == stateMask) {
|
|
||||||
if (++width == maxloops)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
using the command line:
|
|
||||||
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -c -O2 -W -ffunction-sections -fdata-sections -nostdlib \
|
|
||||||
countPulseASM.c -Wa,-ahlmsd=output.lst -dp -fverbose-asm -S \
|
|
||||||
-I.arduino15/packages/arduino/hardware/sam/1.6.3/cores/arduino \
|
|
||||||
-I.arduino15/packages/arduino/hardware/sam/1.6.3/system/CMSIS/CMSIS/Include \
|
|
||||||
-I.arduino15/packages/arduino/hardware/sam/1.6.3/system/CMSIS/Device/ATMEL \
|
|
||||||
-I.arduino15/packages/arduino/hardware/sam/1.6.3/system/libsam/include \
|
|
||||||
-I.arduino15/packages/arduino/hardware/sam/1.6.3/variants/arduino_due_x
|
|
||||||
|
|
||||||
The result has been slightly edited to increase readability.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.syntax unified
|
|
||||||
.cpu cortex-m3
|
|
||||||
.fpu softvfp
|
|
||||||
.eabi_attribute 20, 1 @ Tag_ABI_FP_denormal
|
|
||||||
.eabi_attribute 21, 1 @ Tag_ABI_FP_exceptions
|
|
||||||
.eabi_attribute 23, 3 @ Tag_ABI_FP_number_model
|
|
||||||
.eabi_attribute 24, 1 @ Tag_ABI_align8_needed
|
|
||||||
.eabi_attribute 25, 1 @ Tag_ABI_align8_preserved
|
|
||||||
.eabi_attribute 26, 1 @ Tag_ABI_enum_size
|
|
||||||
.eabi_attribute 30, 2 @ Tag_ABI_optimization_goals
|
|
||||||
.eabi_attribute 34, 1 @ Tag_CPU_unaligned_access
|
|
||||||
.eabi_attribute 18, 4 @ Tag_ABI_PCS_wchar_t
|
|
||||||
.file "countPulseASM.c"
|
|
||||||
@ GNU C (GNU Tools for ARM Embedded Processors) version 4.9.3 20150303 (release) [ARM/embedded-4_9-branch revision 221220] (arm-none-eabi)
|
|
||||||
@ compiled by GNU C version 4.7.4, GMP version 4.3.2, MPFR version 2.4.2, MPC version 0.8.1
|
|
||||||
@ GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
|
|
||||||
@ options passed:
|
|
||||||
@ -I .arduino15/packages/arduino/hardware/sam/1.6.3/cores/arduino
|
|
||||||
@ -I .arduino15/packages/arduino/hardware/sam/1.6.3/system/CMSIS/CMSIS/Include
|
|
||||||
@ -I .arduino15/packages/arduino/hardware/sam/1.6.3/system/CMSIS/Device/ATMEL
|
|
||||||
@ -I .arduino15/packages/arduino/hardware/sam/1.6.3/system/libsam/include
|
|
||||||
@ -I .arduino15/packages/arduino/hardware/sam/1.6.3/variants/arduino_due_x
|
|
||||||
@ -imultilib armv7-m -iprefix /usr/bin/../lib/gcc/arm-none-eabi/4.9.3/
|
|
||||||
@ -isysroot /usr/bin/../arm-none-eabi -D__USES_INITFINI__ countPulseASM.c
|
|
||||||
@ -mcpu=cortex-m3 -mthumb -O2 -Wextra -ffunction-sections -fdata-sections
|
|
||||||
@ -fverbose-asm
|
|
||||||
@ options enabled: -faggressive-loop-optimizations -fauto-inc-dec
|
|
||||||
@ -fbranch-count-reg -fcaller-saves -fcombine-stack-adjustments -fcommon
|
|
||||||
@ -fcompare-elim -fcprop-registers -fcrossjumping -fcse-follow-jumps
|
|
||||||
@ -fdata-sections -fdefer-pop -fdelete-null-pointer-checks -fdevirtualize
|
|
||||||
@ -fdevirtualize-speculatively -fdwarf2-cfi-asm -fearly-inlining
|
|
||||||
@ -feliminate-unused-debug-types -fexpensive-optimizations
|
|
||||||
@ -fforward-propagate -ffunction-cse -ffunction-sections -fgcse -fgcse-lm
|
|
||||||
@ -fgnu-runtime -fgnu-unique -fguess-branch-probability
|
|
||||||
@ -fhoist-adjacent-loads -fident -fif-conversion -fif-conversion2
|
|
||||||
@ -findirect-inlining -finline -finline-atomics
|
|
||||||
@ -finline-functions-called-once -finline-small-functions -fipa-cp
|
|
||||||
@ -fipa-profile -fipa-pure-const -fipa-reference -fipa-sra
|
|
||||||
@ -fira-hoist-pressure -fira-share-save-slots -fira-share-spill-slots
|
|
||||||
@ -fisolate-erroneous-paths-dereference -fivopts -fkeep-static-consts
|
|
||||||
@ -fleading-underscore -flifetime-dse -fmath-errno -fmerge-constants
|
|
||||||
@ -fmerge-debug-strings -fmove-loop-invariants -fomit-frame-pointer
|
|
||||||
@ -foptimize-sibling-calls -foptimize-strlen -fpartial-inlining -fpeephole
|
|
||||||
@ -fpeephole2 -fprefetch-loop-arrays -freg-struct-return -freorder-blocks
|
|
||||||
@ -freorder-functions -frerun-cse-after-loop
|
|
||||||
@ -fsched-critical-path-heuristic -fsched-dep-count-heuristic
|
|
||||||
@ -fsched-group-heuristic -fsched-interblock -fsched-last-insn-heuristic
|
|
||||||
@ -fsched-pressure -fsched-rank-heuristic -fsched-spec
|
|
||||||
@ -fsched-spec-insn-heuristic -fsched-stalled-insns-dep -fschedule-insns
|
|
||||||
@ -fschedule-insns2 -fsection-anchors -fshow-column -fshrink-wrap
|
|
||||||
@ -fsigned-zeros -fsplit-ivs-in-unroller -fsplit-wide-types
|
|
||||||
@ -fstrict-aliasing -fstrict-overflow -fstrict-volatile-bitfields
|
|
||||||
@ -fsync-libcalls -fthread-jumps -ftoplevel-reorder -ftrapping-math
|
|
||||||
@ -ftree-bit-ccp -ftree-builtin-call-dce -ftree-ccp -ftree-ch
|
|
||||||
@ -ftree-coalesce-vars -ftree-copy-prop -ftree-copyrename -ftree-cselim
|
|
||||||
@ -ftree-dce -ftree-dominator-opts -ftree-dse -ftree-forwprop -ftree-fre
|
|
||||||
@ -ftree-loop-if-convert -ftree-loop-im -ftree-loop-ivcanon
|
|
||||||
@ -ftree-loop-optimize -ftree-parallelize-loops= -ftree-phiprop -ftree-pre
|
|
||||||
@ -ftree-pta -ftree-reassoc -ftree-scev-cprop -ftree-sink -ftree-slsr
|
|
||||||
@ -ftree-sra -ftree-switch-conversion -ftree-tail-merge -ftree-ter
|
|
||||||
@ -ftree-vrp -funit-at-a-time -fverbose-asm -fzero-initialized-in-bss
|
|
||||||
@ -mfix-cortex-m3-ldrd -mlittle-endian -mlra -mpic-data-is-text-relative
|
|
||||||
@ -msched-prolog -mthumb -munaligned-access -mvectorize-with-neon-quad
|
|
||||||
|
|
||||||
.section .text.countPulseASM,"ax",%progbits
|
|
||||||
.align 2
|
|
||||||
.global countPulseASM
|
|
||||||
.thumb
|
|
||||||
.thumb_func
|
|
||||||
.type countPulseASM, %function
|
|
||||||
countPulseASM:
|
|
||||||
@ args = 0, pretend = 0, frame = 0
|
|
||||||
@ frame_needed = 0, uses_anonymous_args = 0
|
|
||||||
@ link register save eliminated.
|
|
||||||
push {r4, r5} @ @ 132 *push_multi [length = 2]
|
|
||||||
b .L2 @ @ 178 *arm_jump [length = 2]
|
|
||||||
.L4:
|
|
||||||
subs r3, r3, #1 @ maxloops, maxloops, @ 18 thumb2_addsi3_compare0/1 [length = 2]
|
|
||||||
beq .L12 @, @ 19 arm_cond_branch [length = 2]
|
|
||||||
.L2:
|
|
||||||
ldr r4, [r0] @ D.4169, *port_7(D) @ 22 *thumb2_movsi_insn/6 [length = 4]
|
|
||||||
ands r4, r4, r1 @, D.4169, D.4169, bit @ 24 *thumb2_alusi3_short [length = 2]
|
|
||||||
cmp r4, r2 @ D.4169, stateMask @ 25 *arm_cmpsi_insn/2 [length = 2]
|
|
||||||
beq .L4 @, @ 26 arm_cond_branch [length = 2]
|
|
||||||
b .L6 @ @ 181 *arm_jump [length = 2]
|
|
||||||
.L7:
|
|
||||||
subs r3, r3, #1 @ maxloops, maxloops, @ 32 thumb2_addsi3_compare0/1 [length = 2]
|
|
||||||
beq .L12 @, @ 33 arm_cond_branch [length = 2]
|
|
||||||
.L6:
|
|
||||||
ldr r4, [r0] @ D.4169, *port_7(D) @ 41 *thumb2_movsi_insn/6 [length = 4]
|
|
||||||
ands r4, r4, r1 @, D.4169, D.4169, bit @ 43 *thumb2_alusi3_short [length = 2]
|
|
||||||
cmp r4, r2 @ D.4169, stateMask @ 44 *arm_cmpsi_insn/2 [length = 2]
|
|
||||||
bne .L7 @, @ 45 arm_cond_branch [length = 2]
|
|
||||||
movs r5, #0 @ width, @ 7 *thumb2_movsi_shortim [length = 2]
|
|
||||||
b .L9 @ @ 183 *arm_jump [length = 2]
|
|
||||||
.L10:
|
|
||||||
adds r5, r5, #1 @ width, width, @ 50 *thumb2_addsi_short/1 [length = 2]
|
|
||||||
cmp r3, r5 @ maxloops, width @ 51 *arm_cmpsi_insn/2 [length = 2]
|
|
||||||
beq .L22 @, @ 52 arm_cond_branch [length = 2]
|
|
||||||
.L9:
|
|
||||||
ldr r4, [r0] @ D.4169, *port_7(D) @ 60 *thumb2_movsi_insn/6 [length = 4]
|
|
||||||
ands r4, r4, r1 @, D.4169, D.4169, bit @ 62 *thumb2_alusi3_short [length = 2]
|
|
||||||
cmp r4, r2 @ D.4169, stateMask @ 63 *arm_cmpsi_insn/2 [length = 2]
|
|
||||||
beq .L10 @, @ 64 arm_cond_branch [length = 2]
|
|
||||||
mov r0, r5 @ D.4169, width @ 9 *thumb2_movsi_insn/1 [length = 2]
|
|
||||||
pop {r4, r5} @ @ 165 *load_multiple_with_writeback [length = 4]
|
|
||||||
bx lr @ @ 166 *thumb2_return [length = 4]
|
|
||||||
.L12:
|
|
||||||
mov r0, r3 @ D.4169, maxloops @ 8 *thumb2_movsi_insn/1 [length = 2]
|
|
||||||
pop {r4, r5} @ @ 137 *load_multiple_with_writeback [length = 4]
|
|
||||||
bx lr @ @ 138 *thumb2_return [length = 4]
|
|
||||||
.L22:
|
|
||||||
movs r0, #0 @ D.4169, @ 11 *thumb2_movsi_shortim [length = 2]
|
|
||||||
pop {r4, r5} @ @ 173 *load_multiple_with_writeback [length = 4]
|
|
||||||
bx lr @ @ 174 *thumb2_return [length = 4]
|
|
||||||
.size countPulseASM, .-countPulseASM
|
|
||||||
.ident "GCC: (GNU Tools for ARM Embedded Processors) 4.9.3 20150303 (release) [ARM/embedded-4_9-branch revision 221220]"
|
|
@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"{
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint32_t shiftIn( uint32_t ulDataPin, uint32_t ulClockPin, uint32_t ulBitOrder )
|
|
||||||
{
|
|
||||||
uint8_t value = 0 ;
|
|
||||||
uint8_t i ;
|
|
||||||
|
|
||||||
for ( i=0 ; i < 8 ; ++i )
|
|
||||||
{
|
|
||||||
digitalWrite( ulClockPin, HIGH ) ;
|
|
||||||
|
|
||||||
if ( ulBitOrder == LSBFIRST )
|
|
||||||
{
|
|
||||||
value |= digitalRead( ulDataPin ) << i ;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
value |= digitalRead( ulDataPin ) << (7 - i) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
digitalWrite( ulClockPin, LOW ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value ;
|
|
||||||
}
|
|
||||||
|
|
||||||
void shiftOut( uint32_t ulDataPin, uint32_t ulClockPin, uint32_t ulBitOrder, uint32_t ulVal )
|
|
||||||
{
|
|
||||||
uint8_t i ;
|
|
||||||
|
|
||||||
for ( i=0 ; i < 8 ; i++ )
|
|
||||||
{
|
|
||||||
if ( ulBitOrder == LSBFIRST )
|
|
||||||
{
|
|
||||||
digitalWrite( ulDataPin, !!(ulVal & (1 << i)) ) ;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
digitalWrite( ulDataPin, !!(ulVal & (1 << (7 - i))) ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
digitalWrite( ulClockPin, HIGH ) ;
|
|
||||||
digitalWrite( ulClockPin, LOW ) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} // extern "C"
|
|
||||||
#endif
|
|
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _WIRING_SHIFT_
|
|
||||||
#define _WIRING_SHIFT_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* \brief
|
|
||||||
*/
|
|
||||||
extern uint32_t shiftIn( uint32_t ulDataPin, uint32_t ulClockPin, uint32_t ulBitOrder ) ;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* \brief
|
|
||||||
*/
|
|
||||||
extern void shiftOut( uint32_t ulDataPin, uint32_t ulClockPin, uint32_t ulBitOrder, uint32_t ulVal ) ;
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _WIRING_SHIFT_ */
|
|
@ -1,274 +0,0 @@
|
|||||||
:10000000A7C00000C0C00000BEC00000BCC000000F
|
|
||||||
:10001000BAC00000B8C00000B6C00000B4C0000004
|
|
||||||
:10002000B2C00000B0C00000AEC00000CBC40000F1
|
|
||||||
:100030008FC40000A8C00000A6C00000A4C000003B
|
|
||||||
:10004000A2C00000A0C000009EC000009CC0000034
|
|
||||||
:100050009AC0000098C0000096C0000021C10000B6
|
|
||||||
:1000600092C0000090C000008EC000008CC0000054
|
|
||||||
:100070008AC0000088C0000086C0000084C0000064
|
|
||||||
:1000800082C0000080C000007EC000007CC0000074
|
|
||||||
:100090007AC0000078C000001201100102000008C0
|
|
||||||
:1000A00041233D0001000102DC0109023E00020182
|
|
||||||
:1000B00000C0320904000001020201000524000111
|
|
||||||
:1000C0001004240206052406000107058203080027
|
|
||||||
:1000D000FF09040100020A000000070504024000B5
|
|
||||||
:1000E00001070583024000010403090432034100B3
|
|
||||||
:1000F00072006400750069006E006F002000280027
|
|
||||||
:100100007700770077002E006100720064007500B0
|
|
||||||
:1001100069006E006F002E0063006300290000007C
|
|
||||||
:100120002E03410072006400750069006E006F00CC
|
|
||||||
:1001300020004400750065002000500072006F0030
|
|
||||||
:1001400067002E00200050006F0072007400000055
|
|
||||||
:1001500011241FBECFEFD2E0DEBFCDBF11E0A0E083
|
|
||||||
:10016000B1E0E8EEF0E102C005900D92A831B107D0
|
|
||||||
:10017000D9F712E0A8E1B1E001C01D92A833B107A0
|
|
||||||
:10018000E1F722D1AFC73CCF9C01DC01AE57BF4F96
|
|
||||||
:10019000ED91FC91119741911196FC93EE9380584B
|
|
||||||
:1001A0009F4FE817F90711F42D933C939FB7F894EC
|
|
||||||
:1001B000F901EC57FF4F8081815080839FBF842FCE
|
|
||||||
:1001C0000895882311F03F9A01C03F9847980895F9
|
|
||||||
:1001D000882311F046980895469A0895DF92EF9289
|
|
||||||
:1001E000FF920F931F93FC018489813019F08230B4
|
|
||||||
:1001F00019F404C010E303C010E001C010E28389C9
|
|
||||||
:10020000823009F418608589873031F0883031F008
|
|
||||||
:10021000863029F4126003C0146001C01660109289
|
|
||||||
:10022000C9001092C8001092CA000785F088E188C2
|
|
||||||
:10023000D288202F3F2D4E2D5D2D10921E01203B88
|
|
||||||
:1002400084E0380780E0480780E0580719F481E02F
|
|
||||||
:1002500080931E01CA01B90122E030E040E050E085
|
|
||||||
:1002600026D720583B47414E5F4FCA01B901202F86
|
|
||||||
:100270003F2D4E2D5D2DF9D6215030403093CD00CD
|
|
||||||
:100280002093CC001093CA0082E08093C80088E9D4
|
|
||||||
:100290008093C9001F910F91FF90EF90DF90089518
|
|
||||||
:1002A0001F920F920FB60F9211242F938F939F934B
|
|
||||||
:1002B000EF93FF939091CE008EB38430F1F4E091F0
|
|
||||||
:1002C000A201F091A3019083E091A201F091A3011A
|
|
||||||
:1002D000CF0101969093A3018093A201825A91408D
|
|
||||||
:1002E00021F482E291E0928381839FB7F894809118
|
|
||||||
:1002F000A6018F5F8093A6019FBFFF91EF919F9111
|
|
||||||
:100300008F912F910F900FBE0F901F901895FC01A9
|
|
||||||
:1003100040911A0140931B0180911C0180931D01A3
|
|
||||||
:100320008585282F30E02170307020931A01858553
|
|
||||||
:1003300090E096958795817080931C0180911E01B5
|
|
||||||
:10034000882339F08FE590E090931901809318018C
|
|
||||||
:100350000895442341F4222331F08EE190E09093FC
|
|
||||||
:10036000190180931801089580E091E014C680E09F
|
|
||||||
:1003700091E0C7C51F9384B7877F84BF18E10FB68C
|
|
||||||
:10038000F89410936000109260000FBE80E019DFB7
|
|
||||||
:10039000469A3E9A87E690E09093CD008093CC00F9
|
|
||||||
:1003A00086E08093CA001092C8001093C900539A47
|
|
||||||
:1003B0005A9A8AB180638AB98BB180638BB9BDD2F6
|
|
||||||
:1003C00084E085BD1F9108950F931F93CF93DF9312
|
|
||||||
:1003D000D1DF2FB7F89487EA91E0909328028093B9
|
|
||||||
:1003E000270290932A02809329022FBF2FB7F894F7
|
|
||||||
:1003F00082E291E09093A3018093A2019093A501E2
|
|
||||||
:100400008093A4012FBF7894C7EAD1E003E08FB7AF
|
|
||||||
:10041000F89490912B028FBF903809F180E091E021
|
|
||||||
:10042000E6D497FD1CC0E0912702F091280280835A
|
|
||||||
:10043000E0912702F0912802CF01019690932802C3
|
|
||||||
:10044000809327028752924011F4D283C1839FB7D1
|
|
||||||
:10045000F89480912B028F5F80932B029FBF8FB700
|
|
||||||
:10046000F8941091A6018FBFA89903C0113608F423
|
|
||||||
:1004700069C0A89A8091A601882361F05D980093D5
|
|
||||||
:100480001F0108C082E291E07FDE682F80E091E0EA
|
|
||||||
:1004900014D511501123B1F780911F01882351F019
|
|
||||||
:1004A00080911F01815080931F0180911F0188233B
|
|
||||||
:1004B00009F45D9A80912001882351F080912001F8
|
|
||||||
:1004C00081508093200180912001882309F45C9A57
|
|
||||||
:1004D0008091180190911901181619067CF58F3535
|
|
||||||
:1004E000910521F481E074DE80E06BDE80911801DB
|
|
||||||
:1004F00090911901839721F480E06ADE80E061DE4B
|
|
||||||
:100500008091180190911901499721F480E060DEF3
|
|
||||||
:1005100081E057DE8091180190911901019721F433
|
|
||||||
:1005200080E056DE80E04DDE809118019091190147
|
|
||||||
:100530000197909319018093180104C080E048DE70
|
|
||||||
:1005400080E03FDE8FB7F89490912B028FBF992304
|
|
||||||
:1005500069F087EA91E018DE982F8091C80085FF46
|
|
||||||
:10056000FCCF9093CE005C980093200180E091E056
|
|
||||||
:1005700095D42AD44CCFDA01923049F0933061F00F
|
|
||||||
:100580009130F9F4E8E9F0E022E130E01EC0EAEA57
|
|
||||||
:10059000F0E02EE330E019C0813049F0813018F0EE
|
|
||||||
:1005A000823079F408C0E8EEF0E0849107C0ECEE08
|
|
||||||
:1005B000F0E0849103C0E0E2F1E08491282F30E084
|
|
||||||
:1005C00004C0E0E0F0E020E030E0ED93FC93C901EE
|
|
||||||
:1005D000089528E030E040E003C04F5F220F331F52
|
|
||||||
:1005E00028173907D0F3842F8295807F0895809350
|
|
||||||
:1005F000E9008091EB0081608093EB001092ED00A8
|
|
||||||
:100600006093EC004093ED008091EE00881F8827F6
|
|
||||||
:10061000881F08951092F40090E09093E9001092E2
|
|
||||||
:10062000F0001092E8001092ED008091EB008E7FB8
|
|
||||||
:100630008093EB009F5F953081F7089580913002A1
|
|
||||||
:1006400088238CF403C08EB38823B1F08091E80036
|
|
||||||
:1006500082FFF9CF8091E8008B778093E8000895BE
|
|
||||||
:100660008EB3882349F08091E80080FFF9CF809114
|
|
||||||
:10067000E8008E778093E800089594E68091EC007E
|
|
||||||
:1006800080FF05C08091E80080FF05C023C08091F5
|
|
||||||
:10069000E80082FD1FC08EB3882311F482E0089524
|
|
||||||
:1006A0008EB3853011F483E008958091EB0085FFCF
|
|
||||||
:1006B00002C081E008958091E10082FFDFCF809148
|
|
||||||
:1006C000E1008B7F8093E100992311F484E0089589
|
|
||||||
:1006D0009150D4CF80E008959C0140913602509112
|
|
||||||
:1006E00037024617570718F4F90120E038C06115A2
|
|
||||||
:1006F000710511F0AB01F8CF8091E8008E778093FF
|
|
||||||
:10070000E80040E050E0F0CF8091E80083FF02C0B5
|
|
||||||
:1007100081E008958091E80082FD2DC08EB388238A
|
|
||||||
:1007200081F18EB3853079F18091E80080FF17C0A8
|
|
||||||
:100730009091F20006C081918093F10041505040A9
|
|
||||||
:100740009F5F4115510511F09830A8F320E09830D3
|
|
||||||
:1007500009F421E08091E8008E778093E80041154C
|
|
||||||
:10076000510591F6222381F606C08EB3882349F005
|
|
||||||
:100770008EB3853041F08091E80082FFF6CF80E0B3
|
|
||||||
:10078000089582E0089583E008959C014091360227
|
|
||||||
:10079000509137024617570710F490E03BC061159F
|
|
||||||
:1007A000710511F0AB01F9CF8091E8008E7780934D
|
|
||||||
:1007B000E80040E050E0F1CF8091E80083FF02C004
|
|
||||||
:1007C00081E008958091E80082FD30C08EB38823D7
|
|
||||||
:1007D00099F18EB3853091F18091E80080FF1AC0C5
|
|
||||||
:1007E0008091F20009C0F9012F5F3F4FE491E0933F
|
|
||||||
:1007F000F100415050408F5F4115510511F0883094
|
|
||||||
:1008000090F390E0883009F491E08091E8008E77D1
|
|
||||||
:100810008093E8004115510579F6992369F606C0E1
|
|
||||||
:100820008EB3882349F08EB3853041F08091E80083
|
|
||||||
:1008300082FFF6CF80E0089582E0089583E0089576
|
|
||||||
:100840009C016115710529F48091E8008B778093F4
|
|
||||||
:10085000E800F90120C08091E80083FF02C081E038
|
|
||||||
:1008600008958EB3882339F18EB3853031F18091AC
|
|
||||||
:10087000E80082FFF0CF06C08091F10081936150C3
|
|
||||||
:10088000704021F08091F2008823B1F78091E80058
|
|
||||||
:100890008B778093E80061157105E9F606C08EB389
|
|
||||||
:1008A000882349F08EB3853041F08091E80080FFC5
|
|
||||||
:1008B000F6CF80E0089582E0089583E0089542D065
|
|
||||||
:1008C00044D01EBA10922E0210922D0210922C02C9
|
|
||||||
:1008D00084E089BD89B5826089BD09B400FEFDCF81
|
|
||||||
:1008E0008091D800982F9F779093D800806880934C
|
|
||||||
:1008F000D800809163008E7F809363008091D80040
|
|
||||||
:100900008F7D8093D8008091E0008E7F8093E000FF
|
|
||||||
:100910008091E1008E7F8093E1008091E200816010
|
|
||||||
:100920008093E2008091E100877F8093E1008091D5
|
|
||||||
:10093000E20088608093E2000895C1DF81E0809347
|
|
||||||
:100940002F0208951092E20008951092E100089598
|
|
||||||
:100950001F920F920FB60F9211241F932F933F9364
|
|
||||||
:100960004F935F936F937F938F939F93AF93BF93B7
|
|
||||||
:10097000EF93FF93E9EEF0E0108117701082E0EF43
|
|
||||||
:10098000F0E08081877F80837894C3D0F894A9EECB
|
|
||||||
:10099000B0E01C92E0EFF0E08081886080831C93DF
|
|
||||||
:1009A000FF91EF91BF91AF919F918F917F916F9147
|
|
||||||
:1009B0005F914F913F912F911F910F900FBE0F901C
|
|
||||||
:1009C0001F9018951F920F920FB60F9211242F931C
|
|
||||||
:1009D0003F934F935F936F937F938F939F93AF93C7
|
|
||||||
:1009E000BF93EF93FF938091E10080FF1BC0809144
|
|
||||||
:1009F000E20080FF17C08091E1008E7F8093E100CC
|
|
||||||
:100A00008091E2008E7F8093E2008091E20080611D
|
|
||||||
:100A10008093E2008091D80080628093D80019BC56
|
|
||||||
:100A20001EBAD1D18091E10084FF29C08091E200FB
|
|
||||||
:100A300084FF25C084E089BD89B5826089BD09B481
|
|
||||||
:100A400000FEFDCF8091D8008F7D8093D8008091EB
|
|
||||||
:100A5000E1008F7E8093E1008091E2008F7E8093A1
|
|
||||||
:100A6000E2008091E20081608093E20080912E029A
|
|
||||||
:100A7000882311F481E001C084E08EBBA4D1809171
|
|
||||||
:100A8000E10083FF27C08091E20083FF23C08091B3
|
|
||||||
:100A9000E100877F8093E10082E08EBB10922E02FE
|
|
||||||
:100AA0008091E1008E7F8093E1008091E2008E7F53
|
|
||||||
:100AB0008093E2008091E20080618093E200AADDF1
|
|
||||||
:100AC00080E060E042E093DD8091F00088608093F8
|
|
||||||
:100AD000F00079D18091E10082FF0AC08091E200AC
|
|
||||||
:100AE00082FF06C08091E1008B7F8093E1006BD193
|
|
||||||
:100AF000FF91EF91BF91AF919F918F917F916F91F6
|
|
||||||
:100B00005F914F913F912F910F900FBE0F901F90CB
|
|
||||||
:100B100018951F93DF93CF93CDB7DEB7AC970FB681
|
|
||||||
:100B2000F894DEBF0FBECDBFE0E3F2E08091F100AC
|
|
||||||
:100B3000819322E0E833F207C9F7809130023091C7
|
|
||||||
:100B40003102353009F487C0363040F43130C9F114
|
|
||||||
:100B5000313070F0333009F01DC133C0383009F442
|
|
||||||
:100B6000EFC0393009F4FEC0363009F013C192C02D
|
|
||||||
:100B7000803821F0823809F00DC108C090912C0214
|
|
||||||
:100B800080912D02882399F0926011C080913402E7
|
|
||||||
:100B900087708093E9008091EB0090E025E09695C6
|
|
||||||
:100BA00087952A95E1F7982F91701092E90080912E
|
|
||||||
:100BB000E800877F8093E8009093F1001092F100A5
|
|
||||||
:100BC000CAC0882319F0823009F0E4C090E08F7128
|
|
||||||
:100BD0009070009721F0029709F0DDC00CC0809161
|
|
||||||
:100BE0003202813009F0D7C010922D02333069F5FE
|
|
||||||
:100BF00080932D022AC080913202882331F5209102
|
|
||||||
:100C00003402277009F4C7C02093E9008091EB00FB
|
|
||||||
:100C100080FFC1C0333021F48091EB00806213C0AB
|
|
||||||
:100C20008091EB0080618093EB0081E090E002C056
|
|
||||||
:100C3000880F991F2A95E2F78093EA001092EA0044
|
|
||||||
:100C40008091EB0088608093EB001092E900809126
|
|
||||||
:100C5000E800877F83C0882309F09CC0109132028E
|
|
||||||
:100C60008091E800877F8093E800E8DC04C08EB3C1
|
|
||||||
:100C7000882309F490C08091E80080FFF8CF812F8D
|
|
||||||
:100C80008F7711F492E001C093E09EBB806880935F
|
|
||||||
:100C9000E30081C08058823008F07CC0809132022D
|
|
||||||
:100CA0009091330223E08C3D920799F55FB7F89459
|
|
||||||
:100CB000DE0115964EE020E030E061E2E42FF0E046
|
|
||||||
:100CC00060935700849120FF03C082958F704F5F1F
|
|
||||||
:100CD000982F9F70892F805D8A3308F0895F8C93ED
|
|
||||||
:100CE00011961C9211972F5F3F4F129624313105B8
|
|
||||||
:100CF00029F75FBF8AE28B8383E08C838091E800D1
|
|
||||||
:100D0000877F8093E800CE0103966AE270E0E4DC1E
|
|
||||||
:100D100011C060913402AE014F5F5F4F2CDCBC010B
|
|
||||||
:100D20000097C9F18091E800877F8093E80089816E
|
|
||||||
:100D30009A812BDD8091E8008B778093E8002BC0AF
|
|
||||||
:100D4000803841F58091E800877F8093E8008091AA
|
|
||||||
:100D50002E028093F1008091E8008E778093E80066
|
|
||||||
:100D60006DDC19C08823B1F490913202923098F46E
|
|
||||||
:100D70008091E800877F8093E80090932E025EDCEC
|
|
||||||
:100D800080912E02882311F483E001C084E08EBBA1
|
|
||||||
:100D9000EEDA01C0E9DA8091E80083FF0AC08091B1
|
|
||||||
:100DA000EB0080628093EB008091E800877F809366
|
|
||||||
:100DB000E800AC960FB6F894DEBF0FBECDBFCF9162
|
|
||||||
:100DC000DF911F91089508951F938EB3882361F0DA
|
|
||||||
:100DD0001091E9001092E9008091E80083FF01C0C2
|
|
||||||
:100DE00098DE17701093E9001F9108950895FC0193
|
|
||||||
:100DF0008EB3843021F587859089A189B2890097C7
|
|
||||||
:100E0000A105B105E1F085818093E9008091E800BA
|
|
||||||
:100E100082FF15C08091F200882319F42FEF3FEF75
|
|
||||||
:100E200004C08091F100282F30E08091F2008823E7
|
|
||||||
:100E300041F48091E8008B778093E80002C02FEFA7
|
|
||||||
:100E40003FEFC9010895FC018EB3843011F5878509
|
|
||||||
:100E50009089A189B2890097A105B105D1F081815E
|
|
||||||
:100E60008093E9008091F2008823A9F09091E80036
|
|
||||||
:100E70008091E8008E778093E80095FD0CC0FDDB43
|
|
||||||
:100E8000982F882349F48091E8008E778093E800BA
|
|
||||||
:100E900003C092E001C090E0892F0895FC018EB359
|
|
||||||
:100EA000843051F487859089A189B2890097A10582
|
|
||||||
:100EB000B10511F0CF01C7CF08951F93FC01162F84
|
|
||||||
:100EC0008EB38430D9F487859089A189B28900973F
|
|
||||||
:100ED000A105B10599F081818093E9008091E80036
|
|
||||||
:100EE00085FD08C08091E8008E778093E800C5DB1F
|
|
||||||
:100EF000882329F41093F10080E001C082E01F9163
|
|
||||||
:100F000008950F931F93CF93DF93EC010D96FC018F
|
|
||||||
:100F100089E0DF011D928A95E9F72A813B810981E9
|
|
||||||
:100F20008C81882311F410E001C014E0C90151DB69
|
|
||||||
:100F3000182B1260802F61E8412F59DB882329F19B
|
|
||||||
:100F40002E813F810D818885882311F410E001C036
|
|
||||||
:100F500014E0C9013EDB182B1260802F60E8412F9E
|
|
||||||
:100F600046DB882391F02A853B8509858C8588237B
|
|
||||||
:100F700011F410E001C014E0C9012BDB182B126042
|
|
||||||
:100F8000802F61EC412F33DB01C080E0DF91CF91F6
|
|
||||||
:100F90001F910F910895CF93DF93EC018091E800AA
|
|
||||||
:100FA00083FF60C0888190E0209134023091350247
|
|
||||||
:100FB0002817390709F056C080913102813261F05B
|
|
||||||
:100FC000823220F4803209F04DC019C0823269F1BA
|
|
||||||
:100FD000833209F047C038C080913002813A09F06D
|
|
||||||
:100FE00041C08091E800877F8093E800CE010F9692
|
|
||||||
:100FF00067E070E071DB8091E8008B7713C080912F
|
|
||||||
:101000003002813279F58091E800877F8093E80093
|
|
||||||
:10101000CE010F9667E070E013DCCE01DFD880913F
|
|
||||||
:10102000E8008E778093E8001DC080913002813205
|
|
||||||
:10103000C9F48091E800877F8093E80080913202B4
|
|
||||||
:101040008D87CE0164D90DC080913002813251F478
|
|
||||||
:101050008091E800877F8093E800CE0160913202A2
|
|
||||||
:10106000C5DEECDADF91CF910895A1E21A2EAA1B1A
|
|
||||||
:10107000BB1BFD010DC0AA1FBB1FEE1FFF1FA21748
|
|
||||||
:10108000B307E407F50720F0A21BB30BE40BF50B45
|
|
||||||
:10109000661F771F881F991F1A9469F760957095CE
|
|
||||||
:1010A000809590959B01AC01BD01CF01089597FB00
|
|
||||||
:1010B000092E05260ED057FD04D0D7DF0AD0001C1C
|
|
||||||
:1010C00038F450954095309521953F4F4F4F5F4FE5
|
|
||||||
:1010D0000895F6F790958095709561957F4F8F4FA5
|
|
||||||
:0810E0009F4F0895F894FFCF23
|
|
||||||
:1010E8000003400000044000000208000000000067
|
|
||||||
:0810F8000000000000001400DC
|
|
||||||
:00000001FF
|
|
@ -1,272 +0,0 @@
|
|||||||
:10000000A7C00000C0C00000BEC00000BCC000000F
|
|
||||||
:10001000BAC00000B8C00000B6C00000B4C0000004
|
|
||||||
:10002000B2C00000B0C00000AEC00000B8C4000004
|
|
||||||
:100030007CC40000A8C00000A6C00000A4C000004E
|
|
||||||
:10004000A2C00000A0C000009EC000009CC0000034
|
|
||||||
:100050009AC0000098C0000096C0000021C10000B6
|
|
||||||
:1000600092C0000090C000008EC000008CC0000054
|
|
||||||
:100070008AC0000088C0000086C0000084C0000064
|
|
||||||
:1000800082C0000080C000007EC000007CC0000074
|
|
||||||
:100090007AC0000078C000001201100102000008C0
|
|
||||||
:1000A00041233D0001000102DC0109023E00020182
|
|
||||||
:1000B00000C0320904000001020201000524000111
|
|
||||||
:1000C0001004240206052406000107058203080027
|
|
||||||
:1000D000FF09040100020A000000070504024000B5
|
|
||||||
:1000E00001070583024000010403090432034100B3
|
|
||||||
:1000F00072006400750069006E006F002000280027
|
|
||||||
:100100007700770077002E006100720064007500B0
|
|
||||||
:1001100069006E006F002E0063006300290000007C
|
|
||||||
:100120002E03410072006400750069006E006F00CC
|
|
||||||
:1001300020004400750065002000500072006F0030
|
|
||||||
:1001400067002E00200050006F0072007400000055
|
|
||||||
:1001500011241FBECFEFD2E0DEBFCDBF11E0A0E083
|
|
||||||
:10016000B1E0E2ECF0E102C005900D92A831B107D8
|
|
||||||
:10017000D9F712E0A8E1B1E001C01D92A833B107A0
|
|
||||||
:10018000E1F722D19CC73CCF9C01DC01AE57BF4FA9
|
|
||||||
:10019000ED91FC91119741911196FC93EE9380584B
|
|
||||||
:1001A0009F4FE817F90711F42D933C939FB7F894EC
|
|
||||||
:1001B000F901EC57FF4F8081815080839FBF842FCE
|
|
||||||
:1001C0000895882311F03F9A01C03F9847980895F9
|
|
||||||
:1001D000882311F046980895469A0895DF92EF9289
|
|
||||||
:1001E000FF920F931F93FC018489813019F08230B4
|
|
||||||
:1001F00019F404C010E303C010E001C010E28389C9
|
|
||||||
:10020000823009F418608589873031F0883031F008
|
|
||||||
:10021000863029F4126003C0146001C01660109289
|
|
||||||
:10022000C9001092C8001092CA000785F088E188C2
|
|
||||||
:10023000D288202F3F2D4E2D5D2D10921E01203B88
|
|
||||||
:1002400084E0380780E0480780E0580719F481E02F
|
|
||||||
:1002500080931E01CA01B90122E030E040E050E085
|
|
||||||
:1002600013D720583B47414E5F4FCA01B901202F99
|
|
||||||
:100270003F2D4E2D5D2DE6D6215030403093CD00E0
|
|
||||||
:100280002093CC001093CA0082E08093C80088E9D4
|
|
||||||
:100290008093C9001F910F91FF90EF90DF90089518
|
|
||||||
:1002A0001F920F920FB60F9211242F938F939F934B
|
|
||||||
:1002B000EF93FF939091CE008EB38430F1F4E091F0
|
|
||||||
:1002C000A201F091A3019083E091A201F091A3011A
|
|
||||||
:1002D000CF0101969093A3018093A201825A91408D
|
|
||||||
:1002E00021F482E291E0928381839FB7F894809118
|
|
||||||
:1002F000A6018F5F8093A6019FBFFF91EF919F9111
|
|
||||||
:100300008F912F910F900FBE0F901F901895FC01A9
|
|
||||||
:1003100040911A0140931B0180911C0180931D01A3
|
|
||||||
:100320008585282F30E02170307020931A01858553
|
|
||||||
:1003300090E096958795817080931C0180911E01B5
|
|
||||||
:10034000882339F088E790E0909319018093180191
|
|
||||||
:100350000895442341F4222331F082E390E0909306
|
|
||||||
:10036000190180931801089580E091E001C680E0B2
|
|
||||||
:1003700091E0B4C51F9384B7877F84BF18E10FB69F
|
|
||||||
:10038000F89410936000109260000FBE80E019DFB7
|
|
||||||
:10039000469A3E9A87E690E09093CD008093CC00F9
|
|
||||||
:1003A00086E08093CA001092C8001093C900539A47
|
|
||||||
:1003B0005A9A8AB180638AB98BB180638BB9AAD209
|
|
||||||
:1003C00084E085BD1F9108950F931F93CF93DF9312
|
|
||||||
:1003D000D1DF2FB7F89487EA91E0909328028093B9
|
|
||||||
:1003E000270290932A02809329022FBF2FB7F894F7
|
|
||||||
:1003F00082E291E09093A3018093A2019093A501E2
|
|
||||||
:100400008093A4012FBF7894C7EAD1E003E08FB7AF
|
|
||||||
:10041000F89490912B028FBF903809F180E091E021
|
|
||||||
:10042000D3D497FD1CC0E0912702F091280280836D
|
|
||||||
:10043000E0912702F0912802CF01019690932802C3
|
|
||||||
:10044000809327028752924011F4D283C1839FB7D1
|
|
||||||
:10045000F89480912B028F5F80932B029FBF8FB700
|
|
||||||
:10046000F8941091A6018FBFA89903C0113608F423
|
|
||||||
:1004700056C0A89A8091A601882361F05D980093E8
|
|
||||||
:100480001F0108C082E291E07FDE682F80E091E0EA
|
|
||||||
:1004900001D511501123B1F780911F01882351F02C
|
|
||||||
:1004A00080911F01815080931F0180911F0188233B
|
|
||||||
:1004B00009F45D9A80912001882351F080912001F8
|
|
||||||
:1004C00081508093200180912001882309F45C9A57
|
|
||||||
:1004D000809118019091190118161906E4F4CC972F
|
|
||||||
:1004E000CD9710F481E001C080E072DE80911801A8
|
|
||||||
:1004F000909119010197C29710F481E001C080E04A
|
|
||||||
:1005000060DE809118019091190101979093190173
|
|
||||||
:100510008093180104C080E05BDE80E052DE8FB77C
|
|
||||||
:10052000F89490912B028FBF992369F087EA91E0AC
|
|
||||||
:100530002BDE982F8091C80085FFFCCF9093CE00D2
|
|
||||||
:100540005C980093200180E091E095D42AD45FCF9D
|
|
||||||
:10055000DA01923049F0933061F09130F9F4E8E932
|
|
||||||
:10056000F0E022E130E01EC0EAEAF0E02EE330E005
|
|
||||||
:1005700019C0813049F0813018F0823079F408C018
|
|
||||||
:10058000E8EEF0E0849107C0ECEEF0E0849103C067
|
|
||||||
:10059000E0E2F1E08491282F30E004C0E0E0F0E0F8
|
|
||||||
:1005A00020E030E0ED93FC93C901089528E030E0AD
|
|
||||||
:1005B00040E003C04F5F220F331F28173907D0F3E5
|
|
||||||
:1005C000842F8295807F08958093E9008091EB00CD
|
|
||||||
:1005D00081608093EB001092ED006093EC004093FB
|
|
||||||
:1005E000ED008091EE00881F8827881F08951092E3
|
|
||||||
:1005F000F40090E09093E9001092F0001092E8006F
|
|
||||||
:100600001092ED008091EB008E7F8093EB009F5F56
|
|
||||||
:10061000953081F708958091300288238CF403C0CF
|
|
||||||
:100620008EB38823B1F08091E80082FFF9CF8091EA
|
|
||||||
:10063000E8008B778093E80008958EB3882349F013
|
|
||||||
:100640008091E80080FFF9CF8091E8008E77809359
|
|
||||||
:10065000E800089594E68091EC0080FF05C0809149
|
|
||||||
:10066000E80080FF05C023C08091E80082FD1FC024
|
|
||||||
:100670008EB3882311F482E008958EB3853011F48F
|
|
||||||
:1006800083E008958091EB0085FF02C081E008952A
|
|
||||||
:100690008091E10082FFDFCF8091E1008B7F80932A
|
|
||||||
:1006A000E100992311F484E008959150D4CF80E0C3
|
|
||||||
:1006B00008959C0140913602509137024617570722
|
|
||||||
:1006C00018F4F90120E038C06115710511F0AB0193
|
|
||||||
:1006D000F8CF8091E8008E778093E80040E050E00A
|
|
||||||
:1006E000F0CF8091E80083FF02C081E008958091FF
|
|
||||||
:1006F000E80082FD2DC08EB3882381F18EB3853052
|
|
||||||
:1007000079F18091E80080FF17C09091F20006C057
|
|
||||||
:1007100081918093F100415050409F5F41155105F8
|
|
||||||
:1007200011F09830A8F320E0983009F421E080918E
|
|
||||||
:10073000E8008E778093E8004115510591F6222359
|
|
||||||
:1007400081F606C08EB3882349F08EB3853041F020
|
|
||||||
:100750008091E80082FFF6CF80E0089582E008955E
|
|
||||||
:1007600083E008959C01409136025091370246176C
|
|
||||||
:10077000570710F490E03BC06115710511F0AB0113
|
|
||||||
:10078000F9CF8091E8008E778093E80040E050E058
|
|
||||||
:10079000F1CF8091E80083FF02C081E0089580914D
|
|
||||||
:1007A000E80082FD30C08EB3882399F18EB3853086
|
|
||||||
:1007B00091F18091E80080FF1AC08091F20009C099
|
|
||||||
:1007C000F9012F5F3F4FE491E093F1004150504019
|
|
||||||
:1007D0008F5F4115510511F0883090F390E088301B
|
|
||||||
:1007E00009F491E08091E8008E778093E80041154C
|
|
||||||
:1007F000510579F6992369F606C08EB3882349F02E
|
|
||||||
:100800008EB3853041F08091E80082FFF6CF80E022
|
|
||||||
:10081000089582E0089583E008959C0161157105B3
|
|
||||||
:1008200029F48091E8008B778093E800F90120C0DB
|
|
||||||
:100830008091E80083FF02C081E008958EB3882391
|
|
||||||
:1008400039F18EB3853031F18091E80082FFF0CF2D
|
|
||||||
:1008500006C08091F10081936150704021F0809139
|
|
||||||
:10086000F2008823B1F78091E8008B778093E8004D
|
|
||||||
:1008700061157105E9F606C08EB3882349F08EB381
|
|
||||||
:10088000853041F08091E80080FFF6CF80E0089548
|
|
||||||
:1008900082E0089583E0089542D044D01EBA1092B9
|
|
||||||
:1008A0002E0210922D0210922C0284E089BD89B58F
|
|
||||||
:1008B000826089BD09B400FEFDCF8091D800982FD9
|
|
||||||
:1008C0009F779093D80080688093D80080916300D0
|
|
||||||
:1008D0008E7F809363008091D8008F7D8093D800B5
|
|
||||||
:1008E0008091E0008E7F8093E0008091E1008E7F18
|
|
||||||
:1008F0008093E1008091E20081608093E20080912A
|
|
||||||
:10090000E100877F8093E1008091E200886080931E
|
|
||||||
:10091000E2000895C1DF81E080932F0208951092D4
|
|
||||||
:10092000E20008951092E10008951F920F920FB611
|
|
||||||
:100930000F9211241F932F933F934F935F936F93C5
|
|
||||||
:100940007F938F939F93AF93BF93EF93FF93E9EEC2
|
|
||||||
:10095000F0E0108117701082E0EFF0E08081877F77
|
|
||||||
:1009600080837894C3D0F894A9EEB0E01C92E0EFB5
|
|
||||||
:10097000F0E08081886080831C93FF91EF91BF91AC
|
|
||||||
:10098000AF919F918F917F916F915F914F913F9127
|
|
||||||
:100990002F911F910F900FBE0F901F9018951F92CF
|
|
||||||
:1009A0000F920FB60F9211242F933F934F935F93A3
|
|
||||||
:1009B0006F937F938F939F93AF93BF93EF93FF9327
|
|
||||||
:1009C0008091E10080FF1BC08091E20080FF17C092
|
|
||||||
:1009D0008091E1008E7F8093E1008091E2008E7F24
|
|
||||||
:1009E0008093E2008091E20080618093E200809138
|
|
||||||
:1009F000D80080628093D80019BC1EBAD1D18091F2
|
|
||||||
:100A0000E10084FF29C08091E20084FF25C084E0DA
|
|
||||||
:100A100089BD89B5826089BD09B400FEFDCF809192
|
|
||||||
:100A2000D8008F7D8093D8008091E1008F7E8093E5
|
|
||||||
:100A3000E1008091E2008F7E8093E2008091E200ED
|
|
||||||
:100A400081608093E20080912E02882311F481E07E
|
|
||||||
:100A500001C084E08EBBA4D18091E10083FF27C058
|
|
||||||
:100A60008091E20083FF23C08091E100877F809323
|
|
||||||
:100A7000E10082E08EBB10922E028091E1008E7F19
|
|
||||||
:100A80008093E1008091E2008E7F8093E20080916C
|
|
||||||
:100A9000E20080618093E200AADD80E060E042E055
|
|
||||||
:100AA00093DD8091F00088608093F00079D180918F
|
|
||||||
:100AB000E10082FF0AC08091E20082FF06C08091BF
|
|
||||||
:100AC000E1008B7F8093E1006BD1FF91EF91BF91AB
|
|
||||||
:100AD000AF919F918F917F916F915F914F913F91D6
|
|
||||||
:100AE0002F910F900FBE0F901F9018951F93DF93BB
|
|
||||||
:100AF000CF93CDB7DEB7AC970FB6F894DEBF0FBE7D
|
|
||||||
:100B0000CDBFE0E3F2E08091F100819322E0E83391
|
|
||||||
:100B1000F207C9F78091300230913102353009F483
|
|
||||||
:100B200087C0363040F43130C9F1313070F03330A5
|
|
||||||
:100B300009F01DC133C0383009F4EFC0393009F471
|
|
||||||
:100B4000FEC0363009F013C192C0803821F08238DF
|
|
||||||
:100B500009F00DC108C090912C0280912D028823CC
|
|
||||||
:100B600099F0926011C08091340287708093E900FF
|
|
||||||
:100B70008091EB0090E025E0969587952A95E1F726
|
|
||||||
:100B8000982F91701092E9008091E800877F809300
|
|
||||||
:100B9000E8009093F1001092F100CAC0882319F088
|
|
||||||
:100BA000823009F0E4C090E08F719070009721F0DE
|
|
||||||
:100BB000029709F0DDC00CC080913202813009F04B
|
|
||||||
:100BC000D7C010922D02333069F580932D022AC0D0
|
|
||||||
:100BD00080913202882331F520913402277009F484
|
|
||||||
:100BE000C7C02093E9008091EB0080FFC1C0333083
|
|
||||||
:100BF00021F48091EB00806213C08091EB00806152
|
|
||||||
:100C00008093EB0081E090E002C0880F991F2A9545
|
|
||||||
:100C1000E2F78093EA001092EA008091EB0088608E
|
|
||||||
:100C20008093EB001092E9008091E800877F83C0F9
|
|
||||||
:100C3000882309F09CC0109132028091E800877FE0
|
|
||||||
:100C40008093E800E8DC04C08EB3882309F490C0E8
|
|
||||||
:100C50008091E80080FFF8CF812F8F7711F492E028
|
|
||||||
:100C600001C093E09EBB80688093E30081C0805800
|
|
||||||
:100C7000823008F07CC0809132029091330223E0F0
|
|
||||||
:100C80008C3D920799F55FB7F894DE0115964EE01A
|
|
||||||
:100C900020E030E061E2E42FF0E0609357008491BF
|
|
||||||
:100CA00020FF03C082958F704F5F982F9F70892F10
|
|
||||||
:100CB000805D8A3308F0895F8C9311961C9211979E
|
|
||||||
:100CC0002F5F3F4F12962431310529F75FBF8AE22B
|
|
||||||
:100CD0008B8383E08C838091E800877F8093E8009A
|
|
||||||
:100CE000CE0103966AE270E0E4DC11C06091340248
|
|
||||||
:100CF000AE014F5F5F4F2CDCBC010097C9F18091C2
|
|
||||||
:100D0000E800877F8093E80089819A812BDD8091BC
|
|
||||||
:100D1000E8008B778093E8002BC0803841F5809104
|
|
||||||
:100D2000E800877F8093E80080912E028093F10095
|
|
||||||
:100D30008091E8008E778093E8006DDC19C08823ED
|
|
||||||
:100D4000B1F490913202923098F48091E800877F5C
|
|
||||||
:100D50008093E80090932E025EDC80912E0288231F
|
|
||||||
:100D600011F483E001C084E08EBB01DB01C0FCDA3A
|
|
||||||
:100D70008091E80083FF0AC08091EB00806280933D
|
|
||||||
:100D8000EB008091E800877F8093E800AC960FB677
|
|
||||||
:100D9000F894DEBF0FBECDBFCF91DF911F910895B4
|
|
||||||
:100DA00008951F938EB3882361F01091E90010928B
|
|
||||||
:100DB000E9008091E80083FF01C098DE177010936E
|
|
||||||
:100DC000E9001F9108950895FC018EB3843021F548
|
|
||||||
:100DD00087859089A189B2890097A105B105E1F0C5
|
|
||||||
:100DE00085818093E9008091E80082FF15C08091A1
|
|
||||||
:100DF000F200882319F42FEF3FEF04C08091F10037
|
|
||||||
:100E0000282F30E08091F200882341F48091E8009F
|
|
||||||
:100E10008B778093E80002C02FEF3FEFC901089560
|
|
||||||
:100E2000FC018EB3843011F587859089A189B28940
|
|
||||||
:100E30000097A105B105D1F081818093E9008091EF
|
|
||||||
:100E4000F2008823A9F09091E8008091E8008E7765
|
|
||||||
:100E50008093E80095FD0CC0FDDB982F882349F4B2
|
|
||||||
:100E60008091E8008E778093E80003C092E001C093
|
|
||||||
:100E700090E0892F0895FC018EB3843051F487856A
|
|
||||||
:100E80009089A189B2890097A105B10511F0CF0120
|
|
||||||
:100E9000C7CF08951F93FC01162F8EB38430D9F469
|
|
||||||
:100EA00087859089A189B2890097A105B10599F03C
|
|
||||||
:100EB00081818093E9008091E80085FD08C08091E0
|
|
||||||
:100EC000E8008E778093E800C5DB882329F410932F
|
|
||||||
:100ED000F10080E001C082E01F9108950F931F93FD
|
|
||||||
:100EE000CF93DF93EC010D96FC0189E0DF011D92A9
|
|
||||||
:100EF0008A95E9F72A813B8109818C81882311F445
|
|
||||||
:100F000010E001C014E0C90151DB182B1260802FE2
|
|
||||||
:100F100061E8412F59DB882329F12E813F810D8122
|
|
||||||
:100F20008885882311F410E001C014E0C9013EDB7C
|
|
||||||
:100F3000182B1260802F60E8412F46DB882391F048
|
|
||||||
:100F40002A853B8509858C85882311F410E001C032
|
|
||||||
:100F500014E0C9012BDB182B1260802F61EC412FAC
|
|
||||||
:100F600033DB01C080E0DF91CF911F910F91089595
|
|
||||||
:100F7000CF93DF93EC018091E80083FF60C088810C
|
|
||||||
:100F800090E020913402309135022817390709F09A
|
|
||||||
:100F900056C080913102813261F0823220F4803279
|
|
||||||
:100FA00009F04DC019C0823269F1833209F047C09F
|
|
||||||
:100FB00038C080913002813A09F041C08091E80048
|
|
||||||
:100FC000877F8093E800CE010F9667E070E071DBC9
|
|
||||||
:100FD0008091E8008B7713C080913002813279F5DF
|
|
||||||
:100FE0008091E800877F8093E800CE010F9667E04C
|
|
||||||
:100FF00070E013DCCE01F2D88091E8008E77809308
|
|
||||||
:10100000E8001DC0809130028132C9F48091E8006F
|
|
||||||
:10101000877F8093E800809132028D87CE0177D957
|
|
||||||
:101020000DC080913002813251F48091E800877FB9
|
|
||||||
:101030008093E800CE0160913202C5DEECDADF91E8
|
|
||||||
:10104000CF910895A1E21A2EAA1BBB1BFD010DC072
|
|
||||||
:10105000AA1FBB1FEE1FFF1FA217B307E407F50768
|
|
||||||
:1010600020F0A21BB30BE40BF50B661F771F881F44
|
|
||||||
:10107000991F1A9469F760957095809590959B01DA
|
|
||||||
:10108000AC01BD01CF01089597FB092E05260ED0B6
|
|
||||||
:1010900057FD04D0D7DF0AD0001C38F45095409596
|
|
||||||
:1010A000309521953F4F4F4F5F4F0895F6F790953C
|
|
||||||
:1010B0008095709561957F4F8F4F9F4F0895F8945D
|
|
||||||
:0210C000FFCF60
|
|
||||||
:1010C200000340000004400000020800000000008D
|
|
||||||
:0810D200000000000000140002
|
|
||||||
:00000001FF
|
|
@ -1,309 +0,0 @@
|
|||||||
/*
|
|
||||||
LUFA Library
|
|
||||||
Copyright (C) Dean Camera, 2010.
|
|
||||||
|
|
||||||
dean [at] fourwalledcubicle [dot] com
|
|
||||||
www.fourwalledcubicle.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
|
||||||
|
|
||||||
Permission to use, copy, modify, distribute, and sell this
|
|
||||||
software and its documentation for any purpose is hereby granted
|
|
||||||
without fee, provided that the above copyright notice appear in
|
|
||||||
all copies and that both that the copyright notice and this
|
|
||||||
permission notice and warranty disclaimer appear in supporting
|
|
||||||
documentation, and that the name of the author not be used in
|
|
||||||
advertising or publicity pertaining to distribution of the
|
|
||||||
software without specific, written prior permission.
|
|
||||||
|
|
||||||
The author disclaim all warranties with regard to this
|
|
||||||
software, including all implied warranties of merchantability
|
|
||||||
and fitness. In no event shall the author be liable for any
|
|
||||||
special, indirect or consequential damages or any damages
|
|
||||||
whatsoever resulting from loss of use, data or profits, whether
|
|
||||||
in an action of contract, negligence or other tortious action,
|
|
||||||
arising out of or in connection with the use or performance of
|
|
||||||
this software.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** \file
|
|
||||||
*
|
|
||||||
* Main source file for the Arduino-usbserial project. This file contains the main tasks of
|
|
||||||
* the project and is responsible for the initial application hardware configuration.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Arduino-usbserial.h"
|
|
||||||
|
|
||||||
/** Circular buffer to hold data from the host before it is sent to the device via the serial port. */
|
|
||||||
RingBuff_t USBtoUSART_Buffer;
|
|
||||||
|
|
||||||
/** Circular buffer to hold data from the serial port before it is sent to the host. */
|
|
||||||
RingBuff_t USARTtoUSB_Buffer;
|
|
||||||
|
|
||||||
/** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */
|
|
||||||
volatile struct
|
|
||||||
{
|
|
||||||
uint8_t TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */
|
|
||||||
uint8_t RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */
|
|
||||||
uint8_t PingPongLEDPulse; /**< Milliseconds remaining for enumeration Tx/Rx ping-pong LED pulse */
|
|
||||||
} PulseMSRemaining;
|
|
||||||
|
|
||||||
/** LUFA CDC Class driver interface configuration and state information. This structure is
|
|
||||||
* passed to all CDC Class driver functions, so that multiple instances of the same class
|
|
||||||
* within a device can be differentiated from one another.
|
|
||||||
*/
|
|
||||||
USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface =
|
|
||||||
{
|
|
||||||
.Config =
|
|
||||||
{
|
|
||||||
.ControlInterfaceNumber = 0,
|
|
||||||
|
|
||||||
.DataINEndpointNumber = CDC_TX_EPNUM,
|
|
||||||
.DataINEndpointSize = CDC_TXRX_EPSIZE,
|
|
||||||
.DataINEndpointDoubleBank = false,
|
|
||||||
|
|
||||||
.DataOUTEndpointNumber = CDC_RX_EPNUM,
|
|
||||||
.DataOUTEndpointSize = CDC_TXRX_EPSIZE,
|
|
||||||
.DataOUTEndpointDoubleBank = false,
|
|
||||||
|
|
||||||
.NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,
|
|
||||||
.NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
|
|
||||||
.NotificationEndpointDoubleBank = false,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
int ResetTimer = 0;
|
|
||||||
int tries = 20;
|
|
||||||
bool CurrentDTRState = false;
|
|
||||||
bool PreviousDTRState = false;
|
|
||||||
bool CurrentRTSState = false;
|
|
||||||
bool PreviousRTSState = false;
|
|
||||||
bool Selected1200BPS = false;
|
|
||||||
|
|
||||||
void setResetPin(bool v) {
|
|
||||||
/* Target /RESET line */
|
|
||||||
if (v) {
|
|
||||||
/* ACTIVE => OUTPUT LOW (0v on target /RESET) */
|
|
||||||
AVR_RESET_LINE_DDR |= AVR_RESET_LINE_MASK;
|
|
||||||
AVR_RESET_LINE_PORT &= ~AVR_RESET_LINE_MASK;
|
|
||||||
//LEDs_TurnOnLEDs(LEDMASK_RX);
|
|
||||||
} else {
|
|
||||||
/* INACTIVE => set as INPUT (internal pullup on target /RESET keep it at 3.3v) */
|
|
||||||
AVR_RESET_LINE_DDR &= ~AVR_RESET_LINE_MASK;
|
|
||||||
AVR_RESET_LINE_PORT &= ~AVR_RESET_LINE_MASK;
|
|
||||||
//LEDs_TurnOffLEDs(LEDMASK_RX);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setErasePin(bool v) {
|
|
||||||
if (v) {
|
|
||||||
AVR_ERASE_LINE_PORT &= ~AVR_ERASE_LINE_MASK;
|
|
||||||
//LEDs_TurnOnLEDs(LEDMASK_TX);
|
|
||||||
} else {
|
|
||||||
AVR_ERASE_LINE_PORT |= AVR_ERASE_LINE_MASK;
|
|
||||||
//LEDs_TurnOffLEDs(LEDMASK_TX);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
|
||||||
* setup of all components and the main program loop.
|
|
||||||
*/
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
SetupHardware();
|
|
||||||
|
|
||||||
RingBuffer_InitBuffer(&USBtoUSART_Buffer);
|
|
||||||
RingBuffer_InitBuffer(&USARTtoUSB_Buffer);
|
|
||||||
|
|
||||||
sei();
|
|
||||||
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
|
|
||||||
// Only try to read in bytes from the CDC interface if the transmit buffer is not full
|
|
||||||
if (!(RingBuffer_IsFull(&USBtoUSART_Buffer)))
|
|
||||||
{
|
|
||||||
int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);
|
|
||||||
|
|
||||||
// Read bytes from the USB OUT endpoint into the USART transmit buffer
|
|
||||||
if (!(ReceivedByte < 0))
|
|
||||||
RingBuffer_Insert(&USBtoUSART_Buffer, ReceivedByte);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the UART receive buffer flush timer has expired or the buffer is nearly full
|
|
||||||
RingBuff_Count_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer);
|
|
||||||
if ((TIFR0 & (1 << TOV0)) || (BufferCount > BUFFER_NEARLY_FULL))
|
|
||||||
{
|
|
||||||
TIFR0 |= (1 << TOV0);
|
|
||||||
|
|
||||||
if (USARTtoUSB_Buffer.Count) {
|
|
||||||
LEDs_TurnOnLEDs(LEDMASK_TX);
|
|
||||||
PulseMSRemaining.TxLEDPulse = TX_RX_LED_PULSE_MS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read bytes from the USART receive buffer into the USB IN endpoint
|
|
||||||
while (BufferCount--)
|
|
||||||
CDC_Device_SendByte(&VirtualSerial_CDC_Interface, RingBuffer_Remove(&USARTtoUSB_Buffer));
|
|
||||||
|
|
||||||
// Turn off TX LED(s) once the TX pulse period has elapsed
|
|
||||||
if (PulseMSRemaining.TxLEDPulse && !(--PulseMSRemaining.TxLEDPulse))
|
|
||||||
LEDs_TurnOffLEDs(LEDMASK_TX);
|
|
||||||
|
|
||||||
// Turn off RX LED(s) once the RX pulse period has elapsed
|
|
||||||
if (PulseMSRemaining.RxLEDPulse && !(--PulseMSRemaining.RxLEDPulse))
|
|
||||||
LEDs_TurnOffLEDs(LEDMASK_RX);
|
|
||||||
|
|
||||||
if (ResetTimer > 0)
|
|
||||||
{
|
|
||||||
// SAM3X RESET/ERASE Sequence
|
|
||||||
// --------------------------
|
|
||||||
// Between 60 and 120: do erase
|
|
||||||
if (ResetTimer >= 60 && ResetTimer <= 120) {
|
|
||||||
setErasePin(true);
|
|
||||||
} else {
|
|
||||||
setErasePin(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Between 1 and 50: do reset
|
|
||||||
if (ResetTimer >= 1 && ResetTimer <= 50) {
|
|
||||||
setResetPin(true);
|
|
||||||
} else {
|
|
||||||
setResetPin(false);
|
|
||||||
}
|
|
||||||
ResetTimer--;
|
|
||||||
} else {
|
|
||||||
setErasePin(false);
|
|
||||||
setResetPin(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load the next byte from the USART transmit buffer into the USART
|
|
||||||
if (!(RingBuffer_IsEmpty(&USBtoUSART_Buffer))) {
|
|
||||||
Serial_TxByte(RingBuffer_Remove(&USBtoUSART_Buffer));
|
|
||||||
LEDs_TurnOnLEDs(LEDMASK_RX);
|
|
||||||
PulseMSRemaining.RxLEDPulse = TX_RX_LED_PULSE_MS;
|
|
||||||
}
|
|
||||||
|
|
||||||
CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
|
|
||||||
USB_USBTask();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
|
||||||
void SetupHardware(void)
|
|
||||||
{
|
|
||||||
/* Disable watchdog if enabled by bootloader/fuses */
|
|
||||||
MCUSR &= ~(1 << WDRF);
|
|
||||||
wdt_disable();
|
|
||||||
|
|
||||||
setResetPin(false);
|
|
||||||
|
|
||||||
/* Target /ERASE line is active HIGH: there is a mosfet that inverts logic */
|
|
||||||
AVR_ERASE_LINE_PORT |= AVR_ERASE_LINE_MASK;
|
|
||||||
AVR_ERASE_LINE_DDR |= AVR_ERASE_LINE_MASK;
|
|
||||||
|
|
||||||
/* Hardware Initialization */
|
|
||||||
Serial_Init(9600, false);
|
|
||||||
LEDs_Init();
|
|
||||||
USB_Init();
|
|
||||||
|
|
||||||
/* Start the flush timer so that overflows occur rapidly to push received bytes to the USB interface */
|
|
||||||
TCCR0B = (1 << CS02);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Event handler for the library USB Configuration Changed event. */
|
|
||||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
|
||||||
{
|
|
||||||
CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Event handler for the library USB Unhandled Control Request event. */
|
|
||||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
|
||||||
{
|
|
||||||
CDC_Device_ProcessControlRequest(&VirtualSerial_CDC_Interface);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Event handler for the CDC Class driver Line Encoding Changed event.
|
|
||||||
*
|
|
||||||
* \param[in] CDCInterfaceInfo Pointer to the CDC class interface configuration structure being referenced
|
|
||||||
*/
|
|
||||||
void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
|
|
||||||
{
|
|
||||||
uint8_t ConfigMask = 0;
|
|
||||||
|
|
||||||
switch (CDCInterfaceInfo->State.LineEncoding.ParityType)
|
|
||||||
{
|
|
||||||
case CDC_PARITY_Odd:
|
|
||||||
ConfigMask = ((1 << UPM11) | (1 << UPM10));
|
|
||||||
break;
|
|
||||||
case CDC_PARITY_Even:
|
|
||||||
ConfigMask = (1 << UPM11);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CDCInterfaceInfo->State.LineEncoding.CharFormat == CDC_LINEENCODING_TwoStopBits)
|
|
||||||
ConfigMask |= (1 << USBS1);
|
|
||||||
|
|
||||||
switch (CDCInterfaceInfo->State.LineEncoding.DataBits)
|
|
||||||
{
|
|
||||||
case 6:
|
|
||||||
ConfigMask |= (1 << UCSZ10);
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
ConfigMask |= (1 << UCSZ11);
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
ConfigMask |= ((1 << UCSZ11) | (1 << UCSZ10));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Must turn off USART before reconfiguring it, otherwise incorrect operation may occur */
|
|
||||||
UCSR1B = 0;
|
|
||||||
UCSR1A = 0;
|
|
||||||
UCSR1C = 0;
|
|
||||||
|
|
||||||
long bps = CDCInterfaceInfo->State.LineEncoding.BaudRateBPS;
|
|
||||||
Selected1200BPS = (bps == 1200);
|
|
||||||
|
|
||||||
UBRR1 = SERIAL_2X_UBBRVAL(bps);
|
|
||||||
UCSR1C = ConfigMask;
|
|
||||||
UCSR1A = (1 << U2X1);
|
|
||||||
UCSR1B = (1 << RXCIE1) | (1 << TXEN1) | (1 << RXEN1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** ISR to manage the reception of data from the serial port, placing received bytes into a circular buffer
|
|
||||||
* for later transmission to the host.
|
|
||||||
*/
|
|
||||||
ISR(USART1_RX_vect, ISR_BLOCK)
|
|
||||||
{
|
|
||||||
uint8_t ReceivedByte = UDR1;
|
|
||||||
|
|
||||||
if (USB_DeviceState == DEVICE_STATE_Configured)
|
|
||||||
RingBuffer_Insert(&USARTtoUSB_Buffer, ReceivedByte);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Event handler for the CDC Class driver Host-to-Device Line Encoding Changed event.
|
|
||||||
*
|
|
||||||
* \param[in] CDCInterfaceInfo Pointer to the CDC class interface configuration structure being referenced
|
|
||||||
*/
|
|
||||||
void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
|
|
||||||
{
|
|
||||||
PreviousDTRState = CurrentDTRState;
|
|
||||||
PreviousRTSState = CurrentRTSState;
|
|
||||||
CurrentDTRState = (CDCInterfaceInfo->State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR);
|
|
||||||
CurrentRTSState = (CDCInterfaceInfo->State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_RTS);
|
|
||||||
|
|
||||||
if (Selected1200BPS) {
|
|
||||||
/* Start Erase / Reset procedure when receiving the magic "1200" baudrate */
|
|
||||||
ResetTimer = 120;
|
|
||||||
} else if (!PreviousDTRState && CurrentDTRState) {
|
|
||||||
/* Reset on rising edge of DTR */
|
|
||||||
ResetTimer = 50;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
|||||||
/*
|
|
||||||
LUFA Library
|
|
||||||
Copyright (C) Dean Camera, 2010.
|
|
||||||
|
|
||||||
dean [at] fourwalledcubicle [dot] com
|
|
||||||
www.fourwalledcubicle.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
|
||||||
|
|
||||||
Permission to use, copy, modify, distribute, and sell this
|
|
||||||
software and its documentation for any purpose is hereby granted
|
|
||||||
without fee, provided that the above copyright notice appear in
|
|
||||||
all copies and that both that the copyright notice and this
|
|
||||||
permission notice and warranty disclaimer appear in supporting
|
|
||||||
documentation, and that the name of the author not be used in
|
|
||||||
advertising or publicity pertaining to distribution of the
|
|
||||||
software without specific, written prior permission.
|
|
||||||
|
|
||||||
The author disclaim all warranties with regard to this
|
|
||||||
software, including all implied warranties of merchantability
|
|
||||||
and fitness. In no event shall the author be liable for any
|
|
||||||
special, indirect or consequential damages or any damages
|
|
||||||
whatsoever resulting from loss of use, data or profits, whether
|
|
||||||
in an action of contract, negligence or other tortious action,
|
|
||||||
arising out of or in connection with the use or performance of
|
|
||||||
this software.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** \file
|
|
||||||
*
|
|
||||||
* Header file for Arduino-usbserial.c.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _ARDUINO_USBSERIAL_H_
|
|
||||||
#define _ARDUINO_USBSERIAL_H_
|
|
||||||
|
|
||||||
/* Includes: */
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include <avr/wdt.h>
|
|
||||||
#include <avr/interrupt.h>
|
|
||||||
#include <avr/power.h>
|
|
||||||
|
|
||||||
#include "Descriptors.h"
|
|
||||||
|
|
||||||
#include "Lib/LightweightRingBuff.h"
|
|
||||||
|
|
||||||
#include <LUFA/Version.h>
|
|
||||||
#include <LUFA/Drivers/Board/LEDs.h>
|
|
||||||
#include <LUFA/Drivers/Peripheral/Serial.h>
|
|
||||||
#include <LUFA/Drivers/USB/USB.h>
|
|
||||||
#include <LUFA/Drivers/USB/Class/CDC.h>
|
|
||||||
|
|
||||||
/* Macros: */
|
|
||||||
/** LED mask for the library LED driver, to indicate TX activity. */
|
|
||||||
#define LEDMASK_TX LEDS_LED1
|
|
||||||
|
|
||||||
/** LED mask for the library LED driver, to indicate RX activity. */
|
|
||||||
#define LEDMASK_RX LEDS_LED2
|
|
||||||
|
|
||||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
|
||||||
#define LEDMASK_ERROR (LEDS_LED1 | LEDS_LED2)
|
|
||||||
|
|
||||||
/** LED mask for the library LED driver, to indicate that the USB interface is busy. */
|
|
||||||
#define LEDMASK_BUSY (LEDS_LED1 | LEDS_LED2)
|
|
||||||
|
|
||||||
/* Function Prototypes: */
|
|
||||||
void SetupHardware(void);
|
|
||||||
|
|
||||||
void EVENT_USB_Device_Connect(void);
|
|
||||||
void EVENT_USB_Device_Disconnect(void);
|
|
||||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
|
||||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
|
||||||
|
|
||||||
void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo);
|
|
||||||
void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo);
|
|
||||||
|
|
||||||
#endif /* _ARDUINO_USBSERIAL_H_ */
|
|
@ -1,110 +0,0 @@
|
|||||||
/*
|
|
||||||
LUFA Library
|
|
||||||
Copyright (C) Dean Camera, 2010.
|
|
||||||
|
|
||||||
dean [at] fourwalledcubicle [dot] com
|
|
||||||
www.fourwalledcubicle.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
|
||||||
|
|
||||||
Permission to use, copy, modify, distribute, and sell this
|
|
||||||
software and its documentation for any purpose is hereby granted
|
|
||||||
without fee, provided that the above copyright notice appear in
|
|
||||||
all copies and that both that the copyright notice and this
|
|
||||||
permission notice and warranty disclaimer appear in supporting
|
|
||||||
documentation, and that the name of the author not be used in
|
|
||||||
advertising or publicity pertaining to distribution of the
|
|
||||||
software without specific, written prior permission.
|
|
||||||
|
|
||||||
The author disclaim all warranties with regard to this
|
|
||||||
software, including all implied warranties of merchantability
|
|
||||||
and fitness. In no event shall the author be liable for any
|
|
||||||
special, indirect or consequential damages or any damages
|
|
||||||
whatsoever resulting from loss of use, data or profits, whether
|
|
||||||
in an action of contract, negligence or other tortious action,
|
|
||||||
arising out of or in connection with the use or performance of
|
|
||||||
this software.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Board LEDs driver for the Benito board, from www.dorkbotpdx.org.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LEDS_ARDUINOUNO_H__
|
|
||||||
#define __LEDS_ARDUINOUNO_H__
|
|
||||||
|
|
||||||
/* Includes: */
|
|
||||||
#include <avr/io.h>
|
|
||||||
|
|
||||||
/* Enable C linkage for C++ Compilers: */
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Preprocessor Checks: */
|
|
||||||
#if !defined(INCLUDE_FROM_LEDS_H)
|
|
||||||
#error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Public Interface - May be used in end-application: */
|
|
||||||
/* Macros: */
|
|
||||||
/** LED mask for the first LED on the board. */
|
|
||||||
#define LEDS_LED1 (1 << 5)
|
|
||||||
|
|
||||||
/** LED mask for the second LED on the board. */
|
|
||||||
#define LEDS_LED2 (1 << 4)
|
|
||||||
|
|
||||||
/** LED mask for all the LEDs on the board. */
|
|
||||||
#define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2)
|
|
||||||
|
|
||||||
/** LED mask for the none of the board LEDs */
|
|
||||||
#define LEDS_NO_LEDS 0
|
|
||||||
|
|
||||||
/* Inline Functions: */
|
|
||||||
#if !defined(__DOXYGEN__)
|
|
||||||
static inline void LEDs_Init(void)
|
|
||||||
{
|
|
||||||
DDRD |= LEDS_ALL_LEDS;
|
|
||||||
PORTD |= LEDS_ALL_LEDS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask)
|
|
||||||
{
|
|
||||||
PORTD &= ~LEDMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask)
|
|
||||||
{
|
|
||||||
PORTD |= LEDMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void LEDs_SetAllLEDs(const uint8_t LEDMask)
|
|
||||||
{
|
|
||||||
PORTD = ((PORTD | LEDS_ALL_LEDS) & ~LEDMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, const uint8_t ActiveMask)
|
|
||||||
{
|
|
||||||
PORTD = ((PORTD | ActiveMask) & ~LEDMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void LEDs_ToggleLEDs(const uint8_t LEDMask)
|
|
||||||
{
|
|
||||||
PORTD ^= LEDMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT;
|
|
||||||
static inline uint8_t LEDs_GetLEDs(void)
|
|
||||||
{
|
|
||||||
return (PORTD & LEDS_ALL_LEDS);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Disable C linkage for C++ Compilers: */
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,281 +0,0 @@
|
|||||||
/*
|
|
||||||
LUFA Library
|
|
||||||
Copyright (C) Dean Camera, 2010.
|
|
||||||
|
|
||||||
dean [at] fourwalledcubicle [dot] com
|
|
||||||
www.fourwalledcubicle.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
|
||||||
|
|
||||||
Permission to use, copy, modify, distribute, and sell this
|
|
||||||
software and its documentation for any purpose is hereby granted
|
|
||||||
without fee, provided that the above copyright notice appear in
|
|
||||||
all copies and that both that the copyright notice and this
|
|
||||||
permission notice and warranty disclaimer appear in supporting
|
|
||||||
documentation, and that the name of the author not be used in
|
|
||||||
advertising or publicity pertaining to distribution of the
|
|
||||||
software without specific, written prior permission.
|
|
||||||
|
|
||||||
The author disclaim all warranties with regard to this
|
|
||||||
software, including all implied warranties of merchantability
|
|
||||||
and fitness. In no event shall the author be liable for any
|
|
||||||
special, indirect or consequential damages or any damages
|
|
||||||
whatsoever resulting from loss of use, data or profits, whether
|
|
||||||
in an action of contract, negligence or other tortious action,
|
|
||||||
arising out of or in connection with the use or performance of
|
|
||||||
this software.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** \file
|
|
||||||
*
|
|
||||||
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special
|
|
||||||
* computer-readable structures which the host requests upon device enumeration, to determine
|
|
||||||
* the device's capabilities and functions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Descriptors.h"
|
|
||||||
|
|
||||||
/* On some devices, there is a factory set internal serial number which can be automatically sent to the host as
|
|
||||||
* the device's serial number when the Device Descriptor's .SerialNumStrIndex entry is set to USE_INTERNAL_SERIAL.
|
|
||||||
* This allows the host to track a device across insertions on different ports, allowing them to retain allocated
|
|
||||||
* resources like COM port numbers and drivers. On demos using this feature, give a warning on unsupported devices
|
|
||||||
* so that the user can supply their own serial number descriptor instead or remove the USE_INTERNAL_SERIAL value
|
|
||||||
* from the Device Descriptor (forcing the host to generate a serial number for each device from the VID, PID and
|
|
||||||
* port location).
|
|
||||||
*/
|
|
||||||
#if (USE_INTERNAL_SERIAL == NO_DESCRIPTOR)
|
|
||||||
#warning USE_INTERNAL_SERIAL is not available on this AVR - please manually construct a device serial descriptor.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
|
||||||
* device characteristics, including the supported USB version, control endpoint size and the
|
|
||||||
* number of device configurations. The descriptor is read out by the USB host when the enumeration
|
|
||||||
* process begins.
|
|
||||||
*/
|
|
||||||
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
|
||||||
{
|
|
||||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
|
||||||
|
|
||||||
.USBSpecification = VERSION_BCD(01.10),
|
|
||||||
.Class = 0x02,
|
|
||||||
.SubClass = 0x00,
|
|
||||||
.Protocol = 0x00,
|
|
||||||
|
|
||||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
|
||||||
|
|
||||||
.VendorID = 0x2341, // Arduino
|
|
||||||
.ProductID = 0x003D, // Arduino Due on board USB2Serial
|
|
||||||
|
|
||||||
.ReleaseNumber = 0x0001,
|
|
||||||
|
|
||||||
.ManufacturerStrIndex = 0x01,
|
|
||||||
.ProductStrIndex = 0x02,
|
|
||||||
.SerialNumStrIndex = USE_INTERNAL_SERIAL,
|
|
||||||
|
|
||||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
|
|
||||||
* of the device in one of its supported configurations, including information about any device interfaces
|
|
||||||
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
|
|
||||||
* a configuration so that the host may correctly communicate with the USB device.
|
|
||||||
*/
|
|
||||||
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
|
||||||
{
|
|
||||||
.Config =
|
|
||||||
{
|
|
||||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
|
||||||
|
|
||||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
|
||||||
.TotalInterfaces = 2,
|
|
||||||
|
|
||||||
.ConfigurationNumber = 1,
|
|
||||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
|
||||||
|
|
||||||
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
|
|
||||||
|
|
||||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
|
||||||
},
|
|
||||||
|
|
||||||
.CDC_CCI_Interface =
|
|
||||||
{
|
|
||||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
|
||||||
|
|
||||||
.InterfaceNumber = 0,
|
|
||||||
.AlternateSetting = 0,
|
|
||||||
|
|
||||||
.TotalEndpoints = 1,
|
|
||||||
|
|
||||||
.Class = 0x02,
|
|
||||||
.SubClass = 0x02,
|
|
||||||
.Protocol = 0x01,
|
|
||||||
|
|
||||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
|
||||||
},
|
|
||||||
|
|
||||||
.CDC_Functional_IntHeader =
|
|
||||||
{
|
|
||||||
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
|
|
||||||
.SubType = 0x00,
|
|
||||||
|
|
||||||
.Data = {0x01, 0x10}
|
|
||||||
},
|
|
||||||
|
|
||||||
.CDC_Functional_AbstractControlManagement =
|
|
||||||
{
|
|
||||||
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(1)), .Type = 0x24},
|
|
||||||
.SubType = 0x02,
|
|
||||||
|
|
||||||
.Data = {0x06}
|
|
||||||
},
|
|
||||||
|
|
||||||
.CDC_Functional_Union =
|
|
||||||
{
|
|
||||||
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
|
|
||||||
.SubType = 0x06,
|
|
||||||
|
|
||||||
.Data = {0x00, 0x01}
|
|
||||||
},
|
|
||||||
|
|
||||||
.CDC_NotificationEndpoint =
|
|
||||||
{
|
|
||||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
|
||||||
|
|
||||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC_NOTIFICATION_EPNUM),
|
|
||||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
|
||||||
.EndpointSize = CDC_NOTIFICATION_EPSIZE,
|
|
||||||
.PollingIntervalMS = 0xFF
|
|
||||||
},
|
|
||||||
|
|
||||||
.CDC_DCI_Interface =
|
|
||||||
{
|
|
||||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
|
||||||
|
|
||||||
.InterfaceNumber = 1,
|
|
||||||
.AlternateSetting = 0,
|
|
||||||
|
|
||||||
.TotalEndpoints = 2,
|
|
||||||
|
|
||||||
.Class = 0x0A,
|
|
||||||
.SubClass = 0x00,
|
|
||||||
.Protocol = 0x00,
|
|
||||||
|
|
||||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
|
||||||
},
|
|
||||||
|
|
||||||
.CDC_DataOutEndpoint =
|
|
||||||
{
|
|
||||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
|
||||||
|
|
||||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | CDC_RX_EPNUM),
|
|
||||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
|
||||||
.EndpointSize = CDC_TXRX_EPSIZE,
|
|
||||||
.PollingIntervalMS = 0x01
|
|
||||||
},
|
|
||||||
|
|
||||||
.CDC_DataInEndpoint =
|
|
||||||
{
|
|
||||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
|
||||||
|
|
||||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC_TX_EPNUM),
|
|
||||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
|
||||||
.EndpointSize = CDC_TXRX_EPSIZE,
|
|
||||||
.PollingIntervalMS = 0x01
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
|
|
||||||
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
|
|
||||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
|
||||||
*/
|
|
||||||
USB_Descriptor_String_t PROGMEM LanguageString =
|
|
||||||
{
|
|
||||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
|
||||||
|
|
||||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
|
|
||||||
* form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
|
|
||||||
* Descriptor.
|
|
||||||
*/
|
|
||||||
USB_Descriptor_String_t PROGMEM ManufacturerString =
|
|
||||||
{
|
|
||||||
.Header = {.Size = USB_STRING_LEN(24), .Type = DTYPE_String},
|
|
||||||
|
|
||||||
.UnicodeString = L"Arduino (www.arduino.cc)"
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
|
|
||||||
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
|
|
||||||
* Descriptor.
|
|
||||||
*/
|
|
||||||
USB_Descriptor_String_t PROGMEM ProductString =
|
|
||||||
{
|
|
||||||
#if (ARDUINO_MODEL_PID == ARDUINO_UNO_PID)
|
|
||||||
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
|
|
||||||
|
|
||||||
.UnicodeString = L"Arduino Uno"
|
|
||||||
#elif (ARDUINO_MODEL_PID == ARDUINO_DUE_PID)
|
|
||||||
.Header = {.Size = USB_STRING_LEN(22), .Type = DTYPE_String},
|
|
||||||
|
|
||||||
.UnicodeString = L"Arduino Due Prog. Port"
|
|
||||||
#elif (ARDUINO_MODEL_PID == ARDUINO_MEGA2560_PID)
|
|
||||||
.Header = {.Size = USB_STRING_LEN(17), .Type = DTYPE_String},
|
|
||||||
|
|
||||||
.UnicodeString = L"Arduino Mega 2560"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
|
|
||||||
* documentation) by the application code so that the address and size of a requested descriptor can be given
|
|
||||||
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
|
|
||||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
|
||||||
* USB host.
|
|
||||||
*/
|
|
||||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
|
|
||||||
const uint8_t wIndex,
|
|
||||||
void** const DescriptorAddress)
|
|
||||||
{
|
|
||||||
const uint8_t DescriptorType = (wValue >> 8);
|
|
||||||
const uint8_t DescriptorNumber = (wValue & 0xFF);
|
|
||||||
|
|
||||||
void* Address = NULL;
|
|
||||||
uint16_t Size = NO_DESCRIPTOR;
|
|
||||||
|
|
||||||
switch (DescriptorType)
|
|
||||||
{
|
|
||||||
case DTYPE_Device:
|
|
||||||
Address = (void*)&DeviceDescriptor;
|
|
||||||
Size = sizeof(USB_Descriptor_Device_t);
|
|
||||||
break;
|
|
||||||
case DTYPE_Configuration:
|
|
||||||
Address = (void*)&ConfigurationDescriptor;
|
|
||||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
|
||||||
break;
|
|
||||||
case DTYPE_String:
|
|
||||||
switch (DescriptorNumber)
|
|
||||||
{
|
|
||||||
case 0x00:
|
|
||||||
Address = (void*)&LanguageString;
|
|
||||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
|
||||||
break;
|
|
||||||
case 0x01:
|
|
||||||
Address = (void*)&ManufacturerString;
|
|
||||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
|
||||||
break;
|
|
||||||
case 0x02:
|
|
||||||
Address = (void*)&ProductString;
|
|
||||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
*DescriptorAddress = Address;
|
|
||||||
return Size;
|
|
||||||
}
|
|
@ -1,89 +0,0 @@
|
|||||||
/*
|
|
||||||
LUFA Library
|
|
||||||
Copyright (C) Dean Camera, 2010.
|
|
||||||
|
|
||||||
dean [at] fourwalledcubicle [dot] com
|
|
||||||
www.fourwalledcubicle.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
|
||||||
|
|
||||||
Permission to use, copy, modify, distribute, and sell this
|
|
||||||
software and its documentation for any purpose is hereby granted
|
|
||||||
without fee, provided that the above copyright notice appear in
|
|
||||||
all copies and that both that the copyright notice and this
|
|
||||||
permission notice and warranty disclaimer appear in supporting
|
|
||||||
documentation, and that the name of the author not be used in
|
|
||||||
advertising or publicity pertaining to distribution of the
|
|
||||||
software without specific, written prior permission.
|
|
||||||
|
|
||||||
The author disclaim all warranties with regard to this
|
|
||||||
software, including all implied warranties of merchantability
|
|
||||||
and fitness. In no event shall the author be liable for any
|
|
||||||
special, indirect or consequential damages or any damages
|
|
||||||
whatsoever resulting from loss of use, data or profits, whether
|
|
||||||
in an action of contract, negligence or other tortious action,
|
|
||||||
arising out of or in connection with the use or performance of
|
|
||||||
this software.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** \file
|
|
||||||
*
|
|
||||||
* Header file for Descriptors.c.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _DESCRIPTORS_H_
|
|
||||||
#define _DESCRIPTORS_H_
|
|
||||||
|
|
||||||
/* Includes: */
|
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
|
|
||||||
#include <LUFA/Drivers/USB/USB.h>
|
|
||||||
#include <LUFA/Drivers/USB/Class/CDC.h>
|
|
||||||
|
|
||||||
/* Product-specific definitions: */
|
|
||||||
#define ARDUINO_UNO_PID 0x0001
|
|
||||||
#define ARDUINO_DUE_PID 0x003D
|
|
||||||
#define ARDUINO_MEGA2560_PID 0x0010
|
|
||||||
|
|
||||||
/* Macros: */
|
|
||||||
/** Endpoint number of the CDC device-to-host notification IN endpoint. */
|
|
||||||
#define CDC_NOTIFICATION_EPNUM 2
|
|
||||||
|
|
||||||
/** Endpoint number of the CDC device-to-host data IN endpoint. */
|
|
||||||
#define CDC_TX_EPNUM 3
|
|
||||||
|
|
||||||
/** Endpoint number of the CDC host-to-device data OUT endpoint. */
|
|
||||||
#define CDC_RX_EPNUM 4
|
|
||||||
|
|
||||||
/** Size in bytes of the CDC device-to-host notification IN endpoint. */
|
|
||||||
#define CDC_NOTIFICATION_EPSIZE 8
|
|
||||||
|
|
||||||
/** Size in bytes of the CDC data IN and OUT endpoints. */
|
|
||||||
#define CDC_TXRX_EPSIZE 64
|
|
||||||
|
|
||||||
/* Type Defines: */
|
|
||||||
/** Type define for the device configuration descriptor structure. This must be defined in the
|
|
||||||
* application code, as the configuration descriptor contains several sub-descriptors which
|
|
||||||
* vary between devices, and which describe the device's usage to the host.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
USB_Descriptor_Configuration_Header_t Config;
|
|
||||||
USB_Descriptor_Interface_t CDC_CCI_Interface;
|
|
||||||
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_IntHeader;
|
|
||||||
CDC_FUNCTIONAL_DESCRIPTOR(1) CDC_Functional_AbstractControlManagement;
|
|
||||||
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_Union;
|
|
||||||
USB_Descriptor_Endpoint_t CDC_NotificationEndpoint;
|
|
||||||
USB_Descriptor_Interface_t CDC_DCI_Interface;
|
|
||||||
USB_Descriptor_Endpoint_t CDC_DataOutEndpoint;
|
|
||||||
USB_Descriptor_Endpoint_t CDC_DataInEndpoint;
|
|
||||||
} USB_Descriptor_Configuration_t;
|
|
||||||
|
|
||||||
/* Function Prototypes: */
|
|
||||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
|
|
||||||
const uint8_t wIndex,
|
|
||||||
void** const DescriptorAddress) ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,197 +0,0 @@
|
|||||||
/*
|
|
||||||
LUFA Library
|
|
||||||
Copyright (C) Dean Camera, 2010.
|
|
||||||
|
|
||||||
dean [at] fourwalledcubicle [dot] com
|
|
||||||
www.fourwalledcubicle.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
|
||||||
|
|
||||||
Permission to use, copy, modify, distribute, and sell this
|
|
||||||
software and its documentation for any purpose is hereby granted
|
|
||||||
without fee, provided that the above copyright notice appear in
|
|
||||||
all copies and that both that the copyright notice and this
|
|
||||||
permission notice and warranty disclaimer appear in supporting
|
|
||||||
documentation, and that the name of the author not be used in
|
|
||||||
advertising or publicity pertaining to distribution of the
|
|
||||||
software without specific, written prior permission.
|
|
||||||
|
|
||||||
The author disclaim all warranties with regard to this
|
|
||||||
software, including all implied warranties of merchantability
|
|
||||||
and fitness. In no event shall the author be liable for any
|
|
||||||
special, indirect or consequential damages or any damages
|
|
||||||
whatsoever resulting from loss of use, data or profits, whether
|
|
||||||
in an action of contract, negligence or other tortious action,
|
|
||||||
arising out of or in connection with the use or performance of
|
|
||||||
this software.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** \file
|
|
||||||
*
|
|
||||||
* Ultra lightweight ring buffer, for fast insertion/deletion.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _ULW_RING_BUFF_H_
|
|
||||||
#define _ULW_RING_BUFF_H_
|
|
||||||
|
|
||||||
/* Includes: */
|
|
||||||
#include <util/atomic.h>
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
/* Defines: */
|
|
||||||
/** Size of each ring buffer, in data elements - must be between 1 and 255. */
|
|
||||||
#define BUFFER_SIZE 128
|
|
||||||
|
|
||||||
/** Maximum number of data elements to buffer before forcing a flush.
|
|
||||||
* Must be less than BUFFER_SIZE
|
|
||||||
*/
|
|
||||||
#define BUFFER_NEARLY_FULL 96
|
|
||||||
|
|
||||||
/** Type of data to store into the buffer. */
|
|
||||||
#define RingBuff_Data_t uint8_t
|
|
||||||
|
|
||||||
/** Datatype which may be used to store the count of data stored in a buffer, retrieved
|
|
||||||
* via a call to \ref RingBuffer_GetCount().
|
|
||||||
*/
|
|
||||||
#if (BUFFER_SIZE <= 0xFF)
|
|
||||||
#define RingBuff_Count_t uint8_t
|
|
||||||
#else
|
|
||||||
#define RingBuff_Count_t uint16_t
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Type Defines: */
|
|
||||||
/** Type define for a new ring buffer object. Buffers should be initialized via a call to
|
|
||||||
* \ref RingBuffer_InitBuffer() before use.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
RingBuff_Data_t Buffer[BUFFER_SIZE]; /**< Internal ring buffer data, referenced by the buffer pointers. */
|
|
||||||
RingBuff_Data_t* In; /**< Current storage location in the circular buffer */
|
|
||||||
RingBuff_Data_t* Out; /**< Current retrieval location in the circular buffer */
|
|
||||||
RingBuff_Count_t Count;
|
|
||||||
} RingBuff_t;
|
|
||||||
|
|
||||||
/* Inline Functions: */
|
|
||||||
/** Initializes a ring buffer ready for use. Buffers must be initialized via this function
|
|
||||||
* before any operations are called upon them. Already initialized buffers may be reset
|
|
||||||
* by re-initializing them using this function.
|
|
||||||
*
|
|
||||||
* \param[out] Buffer Pointer to a ring buffer structure to initialize
|
|
||||||
*/
|
|
||||||
static inline void RingBuffer_InitBuffer(RingBuff_t* const Buffer)
|
|
||||||
{
|
|
||||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
|
|
||||||
{
|
|
||||||
Buffer->In = Buffer->Buffer;
|
|
||||||
Buffer->Out = Buffer->Buffer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Retrieves the minimum number of bytes stored in a particular buffer. This value is computed
|
|
||||||
* by entering an atomic lock on the buffer while the IN and OUT locations are fetched, so that
|
|
||||||
* the buffer cannot be modified while the computation takes place. This value should be cached
|
|
||||||
* when reading out the contents of the buffer, so that as small a time as possible is spent
|
|
||||||
* in an atomic lock.
|
|
||||||
*
|
|
||||||
* \note The value returned by this function is guaranteed to only be the minimum number of bytes
|
|
||||||
* stored in the given buffer; this value may change as other threads write new data and so
|
|
||||||
* the returned number should be used only to determine how many successive reads may safely
|
|
||||||
* be performed on the buffer.
|
|
||||||
*
|
|
||||||
* \param[in] Buffer Pointer to a ring buffer structure whose count is to be computed
|
|
||||||
*/
|
|
||||||
static inline RingBuff_Count_t RingBuffer_GetCount(RingBuff_t* const Buffer)
|
|
||||||
{
|
|
||||||
RingBuff_Count_t Count;
|
|
||||||
|
|
||||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
|
|
||||||
{
|
|
||||||
Count = Buffer->Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Atomically determines if the specified ring buffer contains any free space. This should
|
|
||||||
* be tested before storing data to the buffer, to ensure that no data is lost due to a
|
|
||||||
* buffer overrun.
|
|
||||||
*
|
|
||||||
* \param[in,out] Buffer Pointer to a ring buffer structure to insert into
|
|
||||||
*
|
|
||||||
* \return Boolean true if the buffer contains no free space, false otherwise
|
|
||||||
*/
|
|
||||||
static inline bool RingBuffer_IsFull(RingBuff_t* const Buffer)
|
|
||||||
{
|
|
||||||
return (RingBuffer_GetCount(Buffer) == BUFFER_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Atomically determines if the specified ring buffer contains any data. This should
|
|
||||||
* be tested before removing data from the buffer, to ensure that the buffer does not
|
|
||||||
* underflow.
|
|
||||||
*
|
|
||||||
* If the data is to be removed in a loop, store the total number of bytes stored in the
|
|
||||||
* buffer (via a call to the \ref RingBuffer_GetCount() function) in a temporary variable
|
|
||||||
* to reduce the time spent in atomicity locks.
|
|
||||||
*
|
|
||||||
* \param[in,out] Buffer Pointer to a ring buffer structure to insert into
|
|
||||||
*
|
|
||||||
* \return Boolean true if the buffer contains no free space, false otherwise
|
|
||||||
*/
|
|
||||||
static inline bool RingBuffer_IsEmpty(RingBuff_t* const Buffer)
|
|
||||||
{
|
|
||||||
return (RingBuffer_GetCount(Buffer) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Inserts an element into the ring buffer.
|
|
||||||
*
|
|
||||||
* \note Only one execution thread (main program thread or an ISR) may insert into a single buffer
|
|
||||||
* otherwise data corruption may occur. Insertion and removal may occur from different execution
|
|
||||||
* threads.
|
|
||||||
*
|
|
||||||
* \param[in,out] Buffer Pointer to a ring buffer structure to insert into
|
|
||||||
* \param[in] Data Data element to insert into the buffer
|
|
||||||
*/
|
|
||||||
static inline void RingBuffer_Insert(RingBuff_t* const Buffer,
|
|
||||||
const RingBuff_Data_t Data)
|
|
||||||
{
|
|
||||||
*Buffer->In = Data;
|
|
||||||
|
|
||||||
if (++Buffer->In == &Buffer->Buffer[BUFFER_SIZE])
|
|
||||||
Buffer->In = Buffer->Buffer;
|
|
||||||
|
|
||||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
|
|
||||||
{
|
|
||||||
Buffer->Count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Removes an element from the ring buffer.
|
|
||||||
*
|
|
||||||
* \note Only one execution thread (main program thread or an ISR) may remove from a single buffer
|
|
||||||
* otherwise data corruption may occur. Insertion and removal may occur from different execution
|
|
||||||
* threads.
|
|
||||||
*
|
|
||||||
* \param[in,out] Buffer Pointer to a ring buffer structure to retrieve from
|
|
||||||
*
|
|
||||||
* \return Next data element stored in the buffer
|
|
||||||
*/
|
|
||||||
static inline RingBuff_Data_t RingBuffer_Remove(RingBuff_t* const Buffer)
|
|
||||||
{
|
|
||||||
RingBuff_Data_t Data = *Buffer->Out;
|
|
||||||
|
|
||||||
if (++Buffer->Out == &Buffer->Buffer[BUFFER_SIZE])
|
|
||||||
Buffer->Out = Buffer->Buffer;
|
|
||||||
|
|
||||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
|
|
||||||
{
|
|
||||||
Buffer->Count--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,792 +0,0 @@
|
|||||||
# Hey Emacs, this is a -*- makefile -*-
|
|
||||||
#----------------------------------------------------------------------------
|
|
||||||
# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
|
|
||||||
# >> Modified for use with the LUFA project. <<
|
|
||||||
#
|
|
||||||
# Released to the Public Domain
|
|
||||||
#
|
|
||||||
# Additional material for this makefile was written by:
|
|
||||||
# Peter Fleury
|
|
||||||
# Tim Henigan
|
|
||||||
# Colin O'Flynn
|
|
||||||
# Reiner Patommel
|
|
||||||
# Markus Pfaff
|
|
||||||
# Sander Pool
|
|
||||||
# Frederik Rouleau
|
|
||||||
# Carlos Lamas
|
|
||||||
# Dean Camera
|
|
||||||
# Opendous Inc.
|
|
||||||
# Denver Gingerich
|
|
||||||
#
|
|
||||||
#----------------------------------------------------------------------------
|
|
||||||
# On command line:
|
|
||||||
#
|
|
||||||
# make all = Make software.
|
|
||||||
#
|
|
||||||
# make clean = Clean out built project files.
|
|
||||||
#
|
|
||||||
# make coff = Convert ELF to AVR COFF.
|
|
||||||
#
|
|
||||||
# make extcoff = Convert ELF to AVR Extended COFF.
|
|
||||||
#
|
|
||||||
# make program = Download the hex file to the device, using avrdude.
|
|
||||||
# Please customize the avrdude settings below first!
|
|
||||||
#
|
|
||||||
# make dfu = Download the hex file to the device, using dfu-programmer (must
|
|
||||||
# have dfu-programmer installed).
|
|
||||||
#
|
|
||||||
# make flip = Download the hex file to the device, using Atmel FLIP (must
|
|
||||||
# have Atmel FLIP installed).
|
|
||||||
#
|
|
||||||
# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
|
|
||||||
# (must have dfu-programmer installed).
|
|
||||||
#
|
|
||||||
# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
|
|
||||||
# (must have Atmel FLIP installed).
|
|
||||||
#
|
|
||||||
# make doxygen = Generate DoxyGen documentation for the project (must have
|
|
||||||
# DoxyGen installed)
|
|
||||||
#
|
|
||||||
# make debug = Start either simulavr or avarice as specified for debugging,
|
|
||||||
# with avr-gdb or avr-insight as the front end for debugging.
|
|
||||||
#
|
|
||||||
# make filename.s = Just compile filename.c into the assembler code only.
|
|
||||||
#
|
|
||||||
# make filename.i = Create a preprocessed source file for use in submitting
|
|
||||||
# bug reports to the GCC project.
|
|
||||||
#
|
|
||||||
# To rebuild project do "make clean" then "make all".
|
|
||||||
#----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# MCU name(s)
|
|
||||||
# Since the ATMEGA8U2 part is not directly supported by the current
|
|
||||||
# versions of either avrdude or dfu-programmer, we specify a dummy
|
|
||||||
# part; AT90USB82 which is close enough in memory size and organization
|
|
||||||
|
|
||||||
#MCU = atmega8u2
|
|
||||||
MCU = atmega16u2
|
|
||||||
#MCU = atmega32u2
|
|
||||||
|
|
||||||
# MCU_AVRDUDE = at90usb82
|
|
||||||
# MCU_DFU = at90usb82
|
|
||||||
MCU_AVRDUDE = $(MCU)
|
|
||||||
MCU_DFU = $(MCU)
|
|
||||||
|
|
||||||
# Specify the Arduino model using the assigned PID. This is used by Descriptors.c
|
|
||||||
# to set PID and product descriptor string
|
|
||||||
# Uno PID:
|
|
||||||
#ARDUINO_MODEL_PID = 0x0001
|
|
||||||
# Mega 2560 PID:
|
|
||||||
#ARDUINO_MODEL_PID = 0x0010
|
|
||||||
# Due PID:
|
|
||||||
ARDUINO_MODEL_PID = 0x003D
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Target board (see library "Board Types" documentation, NONE for projects not requiring
|
|
||||||
# LUFA board drivers). If USER is selected, put custom board drivers in a directory called
|
|
||||||
# "Board" inside the application directory.
|
|
||||||
BOARD = USER
|
|
||||||
|
|
||||||
|
|
||||||
# Processor frequency.
|
|
||||||
# This will define a symbol, F_CPU, in all source code files equal to the
|
|
||||||
# processor frequency in Hz. You can then use this symbol in your source code to
|
|
||||||
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
|
|
||||||
# automatically to create a 32-bit value in your source code.
|
|
||||||
#
|
|
||||||
# This will be an integer division of F_CLOCK below, as it is sourced by
|
|
||||||
# F_CLOCK after it has run through any CPU prescalers. Note that this value
|
|
||||||
# does not *change* the processor frequency - it should merely be updated to
|
|
||||||
# reflect the processor speed set externally so that the code can use accurate
|
|
||||||
# software delays.
|
|
||||||
#F_CPU = 8000000
|
|
||||||
F_CPU = 16000000
|
|
||||||
|
|
||||||
|
|
||||||
# Input clock frequency.
|
|
||||||
# This will define a symbol, F_CLOCK, in all source code files equal to the
|
|
||||||
# input clock frequency (before any prescaling is performed) in Hz. This value may
|
|
||||||
# differ from F_CPU if prescaling is used on the latter, and is required as the
|
|
||||||
# raw input clock is fed directly to the PLL sections of the AVR for high speed
|
|
||||||
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
|
|
||||||
# at the end, this will be done automatically to create a 32-bit value in your
|
|
||||||
# source code.
|
|
||||||
#
|
|
||||||
# If no clock division is performed on the input clock inside the AVR (via the
|
|
||||||
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
|
|
||||||
F_CLOCK = $(F_CPU)
|
|
||||||
|
|
||||||
|
|
||||||
# Output format. (can be srec, ihex, binary)
|
|
||||||
FORMAT = ihex
|
|
||||||
|
|
||||||
|
|
||||||
# Target file name (without extension).
|
|
||||||
TARGET = Arduino-usbserial
|
|
||||||
|
|
||||||
|
|
||||||
# Object files directory
|
|
||||||
# To put object files in current directory, use a dot (.), do NOT make
|
|
||||||
# this an empty or blank macro!
|
|
||||||
OBJDIR = .
|
|
||||||
|
|
||||||
|
|
||||||
# Path to the LUFA library
|
|
||||||
LUFA_PATH = ../..
|
|
||||||
|
|
||||||
|
|
||||||
# LUFA library compile-time options
|
|
||||||
LUFA_OPTS = -D USB_DEVICE_ONLY
|
|
||||||
LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8
|
|
||||||
LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
|
|
||||||
LUFA_OPTS += -D USE_FLASH_DESCRIPTORS
|
|
||||||
LUFA_OPTS += -D INTERRUPT_CONTROL_ENDPOINT
|
|
||||||
LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0
|
|
||||||
LUFA_OPTS += -D USE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
|
|
||||||
|
|
||||||
|
|
||||||
# Create the LUFA source path variables by including the LUFA root makefile
|
|
||||||
include $(LUFA_PATH)/LUFA/makefile
|
|
||||||
|
|
||||||
|
|
||||||
# List C source files here. (C dependencies are automatically generated.)
|
|
||||||
SRC = $(TARGET).c \
|
|
||||||
Descriptors.c \
|
|
||||||
$(LUFA_SRC_USB) \
|
|
||||||
$(LUFA_SRC_USBCLASS) \
|
|
||||||
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Device.c \
|
|
||||||
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c \
|
|
||||||
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/HostStandardReq.c \
|
|
||||||
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c \
|
|
||||||
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Pipe.c \
|
|
||||||
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/USBController.c \
|
|
||||||
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/Events.c \
|
|
||||||
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/USBInterrupt.c \
|
|
||||||
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c \
|
|
||||||
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/DeviceStandardReq.c \
|
|
||||||
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c \
|
|
||||||
$(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/CDC.c \
|
|
||||||
$(LUFA_PATH)/LUFA/Drivers/USB/Class/Host/CDC.c
|
|
||||||
|
|
||||||
|
|
||||||
# List C++ source files here. (C dependencies are automatically generated.)
|
|
||||||
CPPSRC =
|
|
||||||
|
|
||||||
|
|
||||||
# List Assembler source files here.
|
|
||||||
# Make them always end in a capital .S. Files ending in a lowercase .s
|
|
||||||
# will not be considered source files but generated files (assembler
|
|
||||||
# output from the compiler), and will be deleted upon "make clean"!
|
|
||||||
# Even though the DOS/Win* filesystem matches both .s and .S the same,
|
|
||||||
# it will preserve the spelling of the filenames, and gcc itself does
|
|
||||||
# care about how the name is spelled on its command-line.
|
|
||||||
ASRC =
|
|
||||||
|
|
||||||
|
|
||||||
# Optimization level, can be [0, 1, 2, 3, s].
|
|
||||||
# 0 = turn off optimization. s = optimize for size.
|
|
||||||
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
|
|
||||||
OPT = s
|
|
||||||
|
|
||||||
|
|
||||||
# Debugging format.
|
|
||||||
# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
|
|
||||||
# AVR Studio 4.10 requires dwarf-2.
|
|
||||||
# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
|
|
||||||
DEBUG = dwarf-2
|
|
||||||
|
|
||||||
|
|
||||||
# List any extra directories to look for include files here.
|
|
||||||
# Each directory must be seperated by a space.
|
|
||||||
# Use forward slashes for directory separators.
|
|
||||||
# For a directory that has spaces, enclose it in quotes.
|
|
||||||
EXTRAINCDIRS = $(LUFA_PATH)/
|
|
||||||
|
|
||||||
|
|
||||||
# Compiler flag to set the C Standard level.
|
|
||||||
# c89 = "ANSI" C
|
|
||||||
# gnu89 = c89 plus GCC extensions
|
|
||||||
# c99 = ISO C99 standard (not yet fully implemented)
|
|
||||||
# gnu99 = c99 plus GCC extensions
|
|
||||||
CSTANDARD = -std=gnu99
|
|
||||||
|
|
||||||
|
|
||||||
# Place -D or -U options here for C sources
|
|
||||||
CDEFS = -DF_CPU=$(F_CPU)UL
|
|
||||||
CDEFS += -DF_CLOCK=$(F_CLOCK)UL
|
|
||||||
CDEFS += -DARDUINO_MODEL_PID=$(ARDUINO_MODEL_PID)
|
|
||||||
CDEFS += -DBOARD=BOARD_$(BOARD)
|
|
||||||
CDEFS += $(LUFA_OPTS)
|
|
||||||
|
|
||||||
CDEFS += -DAVR_RESET_LINE_PORT="PORTC"
|
|
||||||
CDEFS += -DAVR_RESET_LINE_DDR="DDRC"
|
|
||||||
CDEFS += -DAVR_RESET_LINE_MASK="(1 << 7)"
|
|
||||||
|
|
||||||
CDEFS += -DAVR_ERASE_LINE_PORT="PORTC"
|
|
||||||
CDEFS += -DAVR_ERASE_LINE_DDR="DDRC"
|
|
||||||
CDEFS += -DAVR_ERASE_LINE_MASK="(1 << 6)"
|
|
||||||
|
|
||||||
CDEFS += -DTX_RX_LED_PULSE_MS=3
|
|
||||||
CDEFS += -DPING_PONG_LED_PULSE_MS=100
|
|
||||||
|
|
||||||
# Place -D or -U options here for ASM sources
|
|
||||||
ADEFS = -DF_CPU=$(F_CPU)
|
|
||||||
ADEFS += -DF_CLOCK=$(F_CLOCK)UL
|
|
||||||
ADEFS += -DBOARD=BOARD_$(BOARD)
|
|
||||||
ADEFS += $(LUFA_OPTS)
|
|
||||||
|
|
||||||
# Place -D or -U options here for C++ sources
|
|
||||||
CPPDEFS = -DF_CPU=$(F_CPU)UL
|
|
||||||
CPPDEFS += -DF_CLOCK=$(F_CLOCK)UL
|
|
||||||
CPPDEFS += -DBOARD=BOARD_$(BOARD)
|
|
||||||
CPPDEFS += $(LUFA_OPTS)
|
|
||||||
#CPPDEFS += -D__STDC_LIMIT_MACROS
|
|
||||||
#CPPDEFS += -D__STDC_CONSTANT_MACROS
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#---------------- Compiler Options C ----------------
|
|
||||||
# -g*: generate debugging information
|
|
||||||
# -O*: optimization level
|
|
||||||
# -f...: tuning, see GCC manual and avr-libc documentation
|
|
||||||
# -Wall...: warning level
|
|
||||||
# -Wa,...: tell GCC to pass this to the assembler.
|
|
||||||
# -adhlns...: create assembler listing
|
|
||||||
CFLAGS = -g$(DEBUG)
|
|
||||||
CFLAGS += $(CDEFS)
|
|
||||||
CFLAGS += -O$(OPT)
|
|
||||||
CFLAGS += -funsigned-char
|
|
||||||
CFLAGS += -funsigned-bitfields
|
|
||||||
CFLAGS += -ffunction-sections
|
|
||||||
CFLAGS += -fno-inline-small-functions
|
|
||||||
CFLAGS += -fpack-struct
|
|
||||||
CFLAGS += -fshort-enums
|
|
||||||
CFLAGS += -fno-strict-aliasing
|
|
||||||
CFLAGS += -Wall
|
|
||||||
CFLAGS += -Wstrict-prototypes
|
|
||||||
#CFLAGS += -mshort-calls
|
|
||||||
#CFLAGS += -fno-unit-at-a-time
|
|
||||||
#CFLAGS += -Wundef
|
|
||||||
#CFLAGS += -Wunreachable-code
|
|
||||||
#CFLAGS += -Wsign-compare
|
|
||||||
CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
|
|
||||||
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
|
||||||
CFLAGS += $(CSTANDARD)
|
|
||||||
|
|
||||||
|
|
||||||
#---------------- Compiler Options C++ ----------------
|
|
||||||
# -g*: generate debugging information
|
|
||||||
# -O*: optimization level
|
|
||||||
# -f...: tuning, see GCC manual and avr-libc documentation
|
|
||||||
# -Wall...: warning level
|
|
||||||
# -Wa,...: tell GCC to pass this to the assembler.
|
|
||||||
# -adhlns...: create assembler listing
|
|
||||||
CPPFLAGS = -g$(DEBUG)
|
|
||||||
CPPFLAGS += $(CPPDEFS)
|
|
||||||
CPPFLAGS += -O$(OPT)
|
|
||||||
CPPFLAGS += -funsigned-char
|
|
||||||
CPPFLAGS += -funsigned-bitfields
|
|
||||||
CPPFLAGS += -fpack-struct
|
|
||||||
CPPFLAGS += -fshort-enums
|
|
||||||
CPPFLAGS += -fno-exceptions
|
|
||||||
CPPFLAGS += -Wall
|
|
||||||
CPPFLAGS += -Wundef
|
|
||||||
CFLAGS += -Wundef
|
|
||||||
#CPPFLAGS += -mshort-calls
|
|
||||||
#CPPFLAGS += -fno-unit-at-a-time
|
|
||||||
#CPPFLAGS += -Wstrict-prototypes
|
|
||||||
#CPPFLAGS += -Wunreachable-code
|
|
||||||
#CPPFLAGS += -Wsign-compare
|
|
||||||
CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
|
|
||||||
CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
|
||||||
#CPPFLAGS += $(CSTANDARD)
|
|
||||||
|
|
||||||
|
|
||||||
#---------------- Assembler Options ----------------
|
|
||||||
# -Wa,...: tell GCC to pass this to the assembler.
|
|
||||||
# -adhlns: create listing
|
|
||||||
# -gstabs: have the assembler create line number information; note that
|
|
||||||
# for use in COFF files, additional information about filenames
|
|
||||||
# and function names needs to be present in the assembler source
|
|
||||||
# files -- see avr-libc docs [FIXME: not yet described there]
|
|
||||||
# -listing-cont-lines: Sets the maximum number of continuation lines of hex
|
|
||||||
# dump that will be displayed for a given single line of source input.
|
|
||||||
ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100
|
|
||||||
|
|
||||||
|
|
||||||
#---------------- Library Options ----------------
|
|
||||||
# Minimalistic printf version
|
|
||||||
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
|
|
||||||
|
|
||||||
# Floating point printf version (requires MATH_LIB = -lm below)
|
|
||||||
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
|
|
||||||
|
|
||||||
# If this is left blank, then it will use the Standard printf version.
|
|
||||||
PRINTF_LIB =
|
|
||||||
#PRINTF_LIB = $(PRINTF_LIB_MIN)
|
|
||||||
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
|
|
||||||
|
|
||||||
|
|
||||||
# Minimalistic scanf version
|
|
||||||
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
|
|
||||||
|
|
||||||
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
|
|
||||||
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
|
|
||||||
|
|
||||||
# If this is left blank, then it will use the Standard scanf version.
|
|
||||||
SCANF_LIB =
|
|
||||||
#SCANF_LIB = $(SCANF_LIB_MIN)
|
|
||||||
#SCANF_LIB = $(SCANF_LIB_FLOAT)
|
|
||||||
|
|
||||||
|
|
||||||
MATH_LIB = -lm
|
|
||||||
|
|
||||||
|
|
||||||
# List any extra directories to look for libraries here.
|
|
||||||
# Each directory must be seperated by a space.
|
|
||||||
# Use forward slashes for directory separators.
|
|
||||||
# For a directory that has spaces, enclose it in quotes.
|
|
||||||
EXTRALIBDIRS =
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#---------------- External Memory Options ----------------
|
|
||||||
|
|
||||||
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
|
|
||||||
# used for variables (.data/.bss) and heap (malloc()).
|
|
||||||
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
|
|
||||||
|
|
||||||
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
|
|
||||||
# only used for heap (malloc()).
|
|
||||||
#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff
|
|
||||||
|
|
||||||
EXTMEMOPTS =
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#---------------- Linker Options ----------------
|
|
||||||
# -Wl,...: tell GCC to pass this to linker.
|
|
||||||
# -Map: create map file
|
|
||||||
# --cref: add cross reference to map file
|
|
||||||
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
|
|
||||||
LDFLAGS += -Wl,--relax
|
|
||||||
LDFLAGS += -Wl,--gc-sections
|
|
||||||
LDFLAGS += $(EXTMEMOPTS)
|
|
||||||
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
|
|
||||||
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
|
|
||||||
#LDFLAGS += -T linker_script.x
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#---------------- Programming Options (avrdude) ----------------
|
|
||||||
|
|
||||||
# Programming hardware
|
|
||||||
# Type: avrdude -c ?
|
|
||||||
# to get a full listing.
|
|
||||||
#
|
|
||||||
AVRDUDE_PROGRAMMER = avrispmkii
|
|
||||||
|
|
||||||
# com1 = serial port. Use lpt1 to connect to parallel port.
|
|
||||||
AVRDUDE_PORT = usb
|
|
||||||
|
|
||||||
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
|
|
||||||
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
|
|
||||||
|
|
||||||
|
|
||||||
# Uncomment the following if you want avrdude's erase cycle counter.
|
|
||||||
# Note that this counter needs to be initialized first using -Yn,
|
|
||||||
# see avrdude manual.
|
|
||||||
#AVRDUDE_ERASE_COUNTER = -y
|
|
||||||
|
|
||||||
# Uncomment the following if you do /not/ wish a verification to be
|
|
||||||
# performed after programming the device.
|
|
||||||
#AVRDUDE_NO_VERIFY = -V
|
|
||||||
|
|
||||||
# Increase verbosity level. Please use this when submitting bug
|
|
||||||
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
|
|
||||||
# to submit bug reports.
|
|
||||||
#AVRDUDE_VERBOSE = -v -v
|
|
||||||
|
|
||||||
AVRDUDE_FORCE = -F
|
|
||||||
|
|
||||||
AVRDUDE_FLAGS = -p $(MCU_AVRDUDE) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
|
|
||||||
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
|
|
||||||
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
|
|
||||||
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
|
|
||||||
AVRDUDE_FLAGS += $(AVRDUDE_FORCE)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#---------------- Debugging Options ----------------
|
|
||||||
|
|
||||||
# For simulavr only - target MCU frequency.
|
|
||||||
DEBUG_MFREQ = $(F_CPU)
|
|
||||||
|
|
||||||
# Set the DEBUG_UI to either gdb or insight.
|
|
||||||
# DEBUG_UI = gdb
|
|
||||||
DEBUG_UI = insight
|
|
||||||
|
|
||||||
# Set the debugging back-end to either avarice, simulavr.
|
|
||||||
DEBUG_BACKEND = avarice
|
|
||||||
#DEBUG_BACKEND = simulavr
|
|
||||||
|
|
||||||
# GDB Init Filename.
|
|
||||||
GDBINIT_FILE = __avr_gdbinit
|
|
||||||
|
|
||||||
# When using avarice settings for the JTAG
|
|
||||||
JTAG_DEV = /dev/com1
|
|
||||||
|
|
||||||
# Debugging port used to communicate between GDB / avarice / simulavr.
|
|
||||||
DEBUG_PORT = 4242
|
|
||||||
|
|
||||||
# Debugging host used to communicate between GDB / avarice / simulavr, normally
|
|
||||||
# just set to localhost unless doing some sort of crazy debugging when
|
|
||||||
# avarice is running on a different computer.
|
|
||||||
DEBUG_HOST = localhost
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#============================================================================
|
|
||||||
|
|
||||||
|
|
||||||
# Define programs and commands.
|
|
||||||
SHELL = sh
|
|
||||||
CC = avr-gcc
|
|
||||||
OBJCOPY = avr-objcopy
|
|
||||||
OBJDUMP = avr-objdump
|
|
||||||
SIZE = avr-size
|
|
||||||
AR = avr-ar rcs
|
|
||||||
NM = avr-nm
|
|
||||||
AVRDUDE = avrdude
|
|
||||||
REMOVE = rm -f
|
|
||||||
REMOVEDIR = rm -rf
|
|
||||||
COPY = cp
|
|
||||||
WINSHELL = cmd
|
|
||||||
|
|
||||||
# Define Messages
|
|
||||||
# English
|
|
||||||
MSG_ERRORS_NONE = Errors: none
|
|
||||||
MSG_BEGIN = -------- begin --------
|
|
||||||
MSG_END = -------- end --------
|
|
||||||
MSG_SIZE_BEFORE = Size before:
|
|
||||||
MSG_SIZE_AFTER = Size after:
|
|
||||||
MSG_COFF = Converting to AVR COFF:
|
|
||||||
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
|
|
||||||
MSG_FLASH = Creating load file for Flash:
|
|
||||||
MSG_EEPROM = Creating load file for EEPROM:
|
|
||||||
MSG_EXTENDED_LISTING = Creating Extended Listing:
|
|
||||||
MSG_SYMBOL_TABLE = Creating Symbol Table:
|
|
||||||
MSG_LINKING = Linking:
|
|
||||||
MSG_COMPILING = Compiling C:
|
|
||||||
MSG_COMPILING_CPP = Compiling C++:
|
|
||||||
MSG_ASSEMBLING = Assembling:
|
|
||||||
MSG_CLEANING = Cleaning project:
|
|
||||||
MSG_CREATING_LIBRARY = Creating library:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Define all object files.
|
|
||||||
OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
|
|
||||||
|
|
||||||
# Define all listing files.
|
|
||||||
LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
|
|
||||||
|
|
||||||
|
|
||||||
# Compiler flags to generate dependency files.
|
|
||||||
GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
|
|
||||||
|
|
||||||
|
|
||||||
# Combine all necessary flags and optional flags.
|
|
||||||
# Add target processor to flags.
|
|
||||||
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
|
|
||||||
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
|
|
||||||
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Default target.
|
|
||||||
#all: begin gccversion sizebefore build checkinvalidevents showliboptions showtarget sizeafter end
|
|
||||||
all: begin gccversion sizebefore build showliboptions showtarget sizeafter end
|
|
||||||
|
|
||||||
# Change the build target to build a HEX file or a library.
|
|
||||||
build: elf hex eep lss sym asm
|
|
||||||
#build: lib
|
|
||||||
|
|
||||||
|
|
||||||
elf: $(TARGET).elf
|
|
||||||
hex: $(TARGET).hex
|
|
||||||
eep: $(TARGET).eep
|
|
||||||
lss: $(TARGET).lss
|
|
||||||
sym: $(TARGET).sym
|
|
||||||
asm: $(TARGET).s
|
|
||||||
LIBNAME=lib$(TARGET).a
|
|
||||||
lib: $(LIBNAME)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Eye candy.
|
|
||||||
# AVR Studio 3.x does not check make's exit code but relies on
|
|
||||||
# the following magic strings to be generated by the compile job.
|
|
||||||
begin:
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_BEGIN)
|
|
||||||
|
|
||||||
end:
|
|
||||||
@echo $(MSG_END)
|
|
||||||
@echo
|
|
||||||
|
|
||||||
|
|
||||||
# Display size of file.
|
|
||||||
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
|
|
||||||
ELFSIZE = $(SIZE) $(MCU_FLAG) $(FORMAT_FLAG) $(TARGET).elf
|
|
||||||
MCU_FLAG = $(shell $(SIZE) --help | grep -- --mcu > /dev/null && echo --mcu=$(MCU) )
|
|
||||||
FORMAT_FLAG = $(shell $(SIZE) --help | grep -- --format=.*avr > /dev/null && echo --format=avr )
|
|
||||||
|
|
||||||
sizebefore:
|
|
||||||
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
|
|
||||||
2>/dev/null; echo; fi
|
|
||||||
|
|
||||||
sizeafter:
|
|
||||||
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
|
|
||||||
2>/dev/null; echo; fi
|
|
||||||
|
|
||||||
#$(LUFA_PATH)/LUFA/LUFA_Events.lst:
|
|
||||||
# @make -C $(LUFA_PATH)/LUFA/ LUFA_Events.lst
|
|
||||||
|
|
||||||
#checkinvalidevents: $(LUFA_PATH)/LUFA/LUFA_Events.lst
|
|
||||||
# @echo
|
|
||||||
# @echo Checking for invalid events...
|
|
||||||
# @$(shell) avr-nm $(OBJ) | sed -n -e 's/^.*EVENT_/EVENT_/p' | \
|
|
||||||
# grep -F -v --file=$(LUFA_PATH)/LUFA/LUFA_Events.lst > InvalidEvents.tmp || true
|
|
||||||
# @sed -n -e 's/^/ WARNING - INVALID EVENT NAME: /p' InvalidEvents.tmp
|
|
||||||
# @if test -s InvalidEvents.tmp; then exit 1; fi
|
|
||||||
|
|
||||||
showliboptions:
|
|
||||||
@echo
|
|
||||||
@echo ---- Compile Time Library Options ----
|
|
||||||
@for i in $(LUFA_OPTS:-D%=%); do \
|
|
||||||
echo $$i; \
|
|
||||||
done
|
|
||||||
@echo --------------------------------------
|
|
||||||
|
|
||||||
showtarget:
|
|
||||||
@echo
|
|
||||||
@echo --------- Target Information ---------
|
|
||||||
@echo AVR Model: $(MCU)
|
|
||||||
@echo Board: $(BOARD)
|
|
||||||
@echo Clock: $(F_CPU)Hz CPU, $(F_CLOCK)Hz Master
|
|
||||||
@echo --------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
# Display compiler version information.
|
|
||||||
gccversion :
|
|
||||||
@$(CC) --version
|
|
||||||
|
|
||||||
|
|
||||||
# Program the device.
|
|
||||||
program: $(TARGET).hex $(TARGET).eep
|
|
||||||
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
|
|
||||||
|
|
||||||
flip: $(TARGET).hex
|
|
||||||
batchisp -hardware usb -device $(MCU_DFU) -operation erase f
|
|
||||||
batchisp -hardware usb -device $(MCU_DFU) -operation loadbuffer $(TARGET).hex program
|
|
||||||
batchisp -hardware usb -device $(MCU_DFU) -operation start reset 0
|
|
||||||
|
|
||||||
dfu: $(TARGET).hex
|
|
||||||
dfu-programmer $(MCU_DFU) erase
|
|
||||||
dfu-programmer $(MCU_DFU) flash --debug 1 $(TARGET).hex
|
|
||||||
dfu-programmer $(MCU_DFU) reset
|
|
||||||
|
|
||||||
|
|
||||||
flip-ee: $(TARGET).hex $(TARGET).eep
|
|
||||||
$(COPY) $(TARGET).eep $(TARGET)eep.hex
|
|
||||||
batchisp -hardware usb -device $(MCU_DFU) -operation memory EEPROM erase
|
|
||||||
batchisp -hardware usb -device $(MCU_DFU) -operation memory EEPROM loadbuffer $(TARGET)eep.hex program
|
|
||||||
batchisp -hardware usb -device $(MCU_DFU) -operation start reset 0
|
|
||||||
$(REMOVE) $(TARGET)eep.hex
|
|
||||||
|
|
||||||
dfu-ee: $(TARGET).hex $(TARGET).eep
|
|
||||||
dfu-programmer $(MCU_DFU) flash-eeprom --debug 1 --suppress-bootloader-mem $(TARGET).eep
|
|
||||||
dfu-programmer $(MCU_DFU) reset
|
|
||||||
|
|
||||||
|
|
||||||
# Generate avr-gdb config/init file which does the following:
|
|
||||||
# define the reset signal, load the target file, connect to target, and set
|
|
||||||
# a breakpoint at main().
|
|
||||||
gdb-config:
|
|
||||||
@$(REMOVE) $(GDBINIT_FILE)
|
|
||||||
@echo define reset >> $(GDBINIT_FILE)
|
|
||||||
@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
|
|
||||||
@echo end >> $(GDBINIT_FILE)
|
|
||||||
@echo file $(TARGET).elf >> $(GDBINIT_FILE)
|
|
||||||
@echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)
|
|
||||||
ifeq ($(DEBUG_BACKEND),simulavr)
|
|
||||||
@echo load >> $(GDBINIT_FILE)
|
|
||||||
endif
|
|
||||||
@echo break main >> $(GDBINIT_FILE)
|
|
||||||
|
|
||||||
debug: gdb-config $(TARGET).elf
|
|
||||||
ifeq ($(DEBUG_BACKEND), avarice)
|
|
||||||
@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
|
|
||||||
@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
|
|
||||||
$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
|
|
||||||
@$(WINSHELL) /c pause
|
|
||||||
|
|
||||||
else
|
|
||||||
@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
|
|
||||||
$(DEBUG_MFREQ) --port $(DEBUG_PORT)
|
|
||||||
endif
|
|
||||||
@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
|
|
||||||
COFFCONVERT = $(OBJCOPY) --debugging
|
|
||||||
COFFCONVERT += --change-section-address .data-0x800000
|
|
||||||
COFFCONVERT += --change-section-address .bss-0x800000
|
|
||||||
COFFCONVERT += --change-section-address .noinit-0x800000
|
|
||||||
COFFCONVERT += --change-section-address .eeprom-0x810000
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
coff: $(TARGET).elf
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_COFF) $(TARGET).cof
|
|
||||||
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
|
|
||||||
|
|
||||||
|
|
||||||
extcoff: $(TARGET).elf
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
|
|
||||||
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Create final output files (.hex, .eep) from ELF output file.
|
|
||||||
%.hex: %.elf
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_FLASH) $@
|
|
||||||
$(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock $< $@
|
|
||||||
|
|
||||||
%.eep: %.elf
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_EEPROM) $@
|
|
||||||
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
|
|
||||||
--change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0
|
|
||||||
|
|
||||||
# Create extended listing file from ELF output file.
|
|
||||||
%.lss: %.elf
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_EXTENDED_LISTING) $@
|
|
||||||
$(OBJDUMP) -h -S -z $< > $@
|
|
||||||
|
|
||||||
# Create a symbol table from ELF output file.
|
|
||||||
%.sym: %.elf
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_SYMBOL_TABLE) $@
|
|
||||||
$(NM) -n $< > $@
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Create library from object files.
|
|
||||||
.SECONDARY : $(TARGET).a
|
|
||||||
.PRECIOUS : $(OBJ)
|
|
||||||
%.a: $(OBJ)
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_CREATING_LIBRARY) $@
|
|
||||||
$(AR) $@ $(OBJ)
|
|
||||||
|
|
||||||
|
|
||||||
# Link: create ELF output file from object files.
|
|
||||||
.SECONDARY : $(TARGET).elf
|
|
||||||
.PRECIOUS : $(OBJ)
|
|
||||||
%.elf: $(OBJ)
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_LINKING) $@
|
|
||||||
$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
|
|
||||||
|
|
||||||
|
|
||||||
# Compile: create object files from C source files.
|
|
||||||
$(OBJDIR)/%.o : %.c
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_COMPILING) $<
|
|
||||||
$(CC) -c $(ALL_CFLAGS) $< -o $@
|
|
||||||
|
|
||||||
|
|
||||||
# Compile: create object files from C++ source files.
|
|
||||||
$(OBJDIR)/%.o : %.cpp
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_COMPILING_CPP) $<
|
|
||||||
$(CC) -c $(ALL_CPPFLAGS) $< -o $@
|
|
||||||
|
|
||||||
|
|
||||||
# Compile: create assembler files from C source files.
|
|
||||||
%.s : %.c
|
|
||||||
$(CC) -S $(ALL_CFLAGS) $< -o $@
|
|
||||||
|
|
||||||
|
|
||||||
# Compile: create assembler files from C++ source files.
|
|
||||||
%.s : %.cpp
|
|
||||||
$(CC) -S $(ALL_CPPFLAGS) $< -o $@
|
|
||||||
|
|
||||||
|
|
||||||
# Assemble: create object files from assembler source files.
|
|
||||||
$(OBJDIR)/%.o : %.S
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_ASSEMBLING) $<
|
|
||||||
$(CC) -c $(ALL_ASFLAGS) $< -o $@
|
|
||||||
|
|
||||||
|
|
||||||
# Create preprocessed source for use in sending a bug report.
|
|
||||||
%.i : %.c
|
|
||||||
$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@
|
|
||||||
|
|
||||||
|
|
||||||
# Target: clean project.
|
|
||||||
clean: begin clean_list clean_binary end
|
|
||||||
|
|
||||||
clean_binary:
|
|
||||||
$(REMOVE) $(TARGET).hex
|
|
||||||
|
|
||||||
clean_list:
|
|
||||||
@echo $(MSG_CLEANING)
|
|
||||||
$(REMOVE) $(TARGET).hex
|
|
||||||
$(REMOVE) $(TARGET).eep
|
|
||||||
$(REMOVE) $(TARGET).cof
|
|
||||||
$(REMOVE) $(TARGET).elf
|
|
||||||
$(REMOVE) $(TARGET).map
|
|
||||||
$(REMOVE) $(TARGET).sym
|
|
||||||
$(REMOVE) $(TARGET).lss
|
|
||||||
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o)
|
|
||||||
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst)
|
|
||||||
$(REMOVE) $(SRC:.c=.s)
|
|
||||||
$(REMOVE) $(SRC:.c=.d)
|
|
||||||
$(REMOVE) $(SRC:.c=.i)
|
|
||||||
$(REMOVEDIR) .dep
|
|
||||||
|
|
||||||
doxygen:
|
|
||||||
@echo Generating Project Documentation...
|
|
||||||
@doxygen Doxygen.conf
|
|
||||||
@echo Documentation Generation Complete.
|
|
||||||
|
|
||||||
clean_doxygen:
|
|
||||||
rm -rf Documentation
|
|
||||||
|
|
||||||
# Create object files directory
|
|
||||||
$(shell mkdir $(OBJDIR) 2>/dev/null)
|
|
||||||
|
|
||||||
|
|
||||||
# Include the dependency files.
|
|
||||||
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
|
|
||||||
|
|
||||||
|
|
||||||
# Listing of phony targets.
|
|
||||||
.PHONY : all begin finish end sizebefore sizeafter gccversion \
|
|
||||||
build elf hex eep lss sym coff extcoff doxygen clean \
|
|
||||||
clean_list clean_doxygen program dfu flip flip-ee dfu-ee \
|
|
||||||
debug gdb-config
|
|
@ -1,14 +0,0 @@
|
|||||||
To setup the project and upload the Arduino usbserial application firmware to an ATMEGA32U2 using the Arduino USB DFU bootloader:
|
|
||||||
1. unpack the source into LUFA's Projects directory
|
|
||||||
2. set ARDUINO_MODEL_PID in the makefile as appropriate
|
|
||||||
3. do "make clean; make"
|
|
||||||
4. put the 32U2 into USB DFU mode:
|
|
||||||
4.a. assert and hold the 32U2's RESET line
|
|
||||||
4.b. assert and hold the 32U2's HWB line
|
|
||||||
4.c. release the 32U2's RESET line
|
|
||||||
4.d. release the 32U2's HWB line
|
|
||||||
5. confirm that the board enumerates as "ATmega32u2"
|
|
||||||
6. do "make dfu" (OS X or Linux - dfu-programmer must be installed first) or "make flip" (Windows - Flip must be installed first)
|
|
||||||
|
|
||||||
Check that the board enumerates as "Arduino Mega 2560".
|
|
||||||
Test by uploading a new Arduino sketch from the Arduino IDE.
|
|
@ -1,21 +0,0 @@
|
|||||||
#######################################
|
|
||||||
# Syntax Coloring Map HID
|
|
||||||
#######################################
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Datatypes (KEYWORD1)
|
|
||||||
#######################################
|
|
||||||
|
|
||||||
HID KEYWORD1
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Methods and Functions (KEYWORD2)
|
|
||||||
#######################################
|
|
||||||
begin KEYWORD2
|
|
||||||
SendReport KEYWORD2
|
|
||||||
AppendDescriptor KEYWORD2
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Constants (LITERAL1)
|
|
||||||
#######################################
|
|
||||||
HID_TX LITERAL1
|
|
@ -1,9 +0,0 @@
|
|||||||
name=HID
|
|
||||||
version=1.0
|
|
||||||
author=Arduino
|
|
||||||
maintainer=Arduino <info@arduino.cc>
|
|
||||||
sentence=Module for PluggableUSB infrastructure. Exposes an API for devices like Keyboards, Mice and Gamepads.
|
|
||||||
paragraph=
|
|
||||||
category=Communication
|
|
||||||
url=http://www.arduino.cc/en/Reference/HID
|
|
||||||
architectures=sam
|
|
@ -1,156 +0,0 @@
|
|||||||
/* Copyright (c) 2015, Arduino LLC
|
|
||||||
**
|
|
||||||
** Original code (pre-library): Copyright (c) 2011, Peter Barrett
|
|
||||||
**
|
|
||||||
** Permission to use, copy, modify, and/or distribute this software for
|
|
||||||
** any purpose with or without fee is hereby granted, provided that the
|
|
||||||
** above copyright notice and this permission notice appear in all copies.
|
|
||||||
**
|
|
||||||
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
|
||||||
** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
|
||||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
|
||||||
** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
|
||||||
** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
||||||
** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|
||||||
** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|
||||||
** SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "HID.h"
|
|
||||||
|
|
||||||
#if defined(USBCON)
|
|
||||||
|
|
||||||
HID_& HID()
|
|
||||||
{
|
|
||||||
static HID_ obj;
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
int HID_::getInterface(uint8_t* interfaceCount)
|
|
||||||
{
|
|
||||||
*interfaceCount += 1; // uses 1
|
|
||||||
HIDDescriptor hidInterface = {
|
|
||||||
D_INTERFACE(pluggedInterface, 1, USB_DEVICE_CLASS_HUMAN_INTERFACE, HID_SUBCLASS_NONE, HID_PROTOCOL_NONE),
|
|
||||||
D_HIDREPORT(descriptorSize),
|
|
||||||
D_ENDPOINT(USB_ENDPOINT_IN(pluggedEndpoint), USB_ENDPOINT_TYPE_INTERRUPT, 0x40, 0x01)
|
|
||||||
};
|
|
||||||
return USBD_SendControl(0, &hidInterface, sizeof(hidInterface));
|
|
||||||
}
|
|
||||||
|
|
||||||
int HID_::getDescriptor(USBSetup& setup)
|
|
||||||
{
|
|
||||||
// Check if this is a HID Class Descriptor request
|
|
||||||
if (setup.bmRequestType != REQUEST_DEVICETOHOST_STANDARD_INTERFACE) { return 0; }
|
|
||||||
if (setup.wValueH != HID_REPORT_DESCRIPTOR_TYPE) { return 0; }
|
|
||||||
|
|
||||||
// In a HID Class Descriptor wIndex cointains the interface number
|
|
||||||
if (setup.wIndex != pluggedInterface) { return 0; }
|
|
||||||
|
|
||||||
int total = 0;
|
|
||||||
HIDSubDescriptor* node;
|
|
||||||
for (node = rootNode; node; node = node->next) {
|
|
||||||
int res = USBD_SendControl(0, node->data, node->length);
|
|
||||||
if (res == -1)
|
|
||||||
return -1;
|
|
||||||
total += res;
|
|
||||||
}
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t HID_::getShortName(char *name)
|
|
||||||
{
|
|
||||||
name[0] = 'H';
|
|
||||||
name[1] = 'I';
|
|
||||||
name[2] = 'D';
|
|
||||||
name[3] = 'A' + (descriptorSize & 0x0F);
|
|
||||||
name[4] = 'A' + ((descriptorSize >> 4) & 0x0F);
|
|
||||||
return 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HID_::AppendDescriptor(HIDSubDescriptor *node)
|
|
||||||
{
|
|
||||||
if (!rootNode) {
|
|
||||||
rootNode = node;
|
|
||||||
} else {
|
|
||||||
HIDSubDescriptor *current = rootNode;
|
|
||||||
while (current->next) {
|
|
||||||
current = current->next;
|
|
||||||
}
|
|
||||||
current->next = node;
|
|
||||||
}
|
|
||||||
descriptorSize += node->length;
|
|
||||||
}
|
|
||||||
|
|
||||||
int HID_::SendReport(uint8_t id, const void* data, int len)
|
|
||||||
{
|
|
||||||
uint8_t p[64];
|
|
||||||
p[0] = id;
|
|
||||||
memcpy(&p[1], data, len);
|
|
||||||
return USBD_Send(pluggedEndpoint, p, len+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HID_::setup(USBSetup& setup)
|
|
||||||
{
|
|
||||||
if (pluggedInterface != setup.wIndex) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t request = setup.bRequest;
|
|
||||||
uint8_t requestType = setup.bmRequestType;
|
|
||||||
|
|
||||||
if (requestType == REQUEST_DEVICETOHOST_CLASS_INTERFACE)
|
|
||||||
{
|
|
||||||
if (request == HID_GET_REPORT) {
|
|
||||||
// TODO: HID_GetReport();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (request == HID_GET_PROTOCOL) {
|
|
||||||
// TODO: Send8(protocol);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (request == HID_GET_IDLE) {
|
|
||||||
// TODO: Send8(idle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (requestType == REQUEST_HOSTTODEVICE_CLASS_INTERFACE)
|
|
||||||
{
|
|
||||||
if (request == HID_SET_PROTOCOL) {
|
|
||||||
// The USB Host tells us if we are in boot or report mode.
|
|
||||||
// This only works with a real boot compatible device.
|
|
||||||
protocol = setup.wValueL;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (request == HID_SET_IDLE) {
|
|
||||||
idle = setup.wValueL;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (request == HID_SET_REPORT)
|
|
||||||
{
|
|
||||||
//uint8_t reportID = setup.wValueL;
|
|
||||||
//uint16_t length = setup.wLength;
|
|
||||||
//uint8_t data[length];
|
|
||||||
// Make sure to not read more data than USB_EP_SIZE.
|
|
||||||
// You can read multiple times through a loop.
|
|
||||||
// The first byte (may!) contain the reportID on a multreport.
|
|
||||||
//USB_RecvControl(data, length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
HID_::HID_(void) : PluggableUSBModule(1, 1, epType),
|
|
||||||
rootNode(NULL), descriptorSize(0),
|
|
||||||
protocol(1), idle(1)
|
|
||||||
{
|
|
||||||
epType[0] = EP_TYPE_INTERRUPT_IN;
|
|
||||||
PluggableUSB().plug(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
int HID_::begin(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* if defined(USBCON) */
|
|
@ -1,120 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2015, Arduino LLC
|
|
||||||
Original code (pre-library): Copyright (c) 2011, Peter Barrett
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for
|
|
||||||
any purpose with or without fee is hereby granted, provided that the
|
|
||||||
above copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
|
||||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
|
||||||
BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
|
||||||
OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
||||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|
||||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|
||||||
SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef HID_h
|
|
||||||
#define HID_h
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include "USB/PluggableUSB.h"
|
|
||||||
|
|
||||||
#if defined(USBCON)
|
|
||||||
|
|
||||||
#define _USING_HID
|
|
||||||
|
|
||||||
// HID 'Driver'
|
|
||||||
// ------------
|
|
||||||
#define HID_GET_REPORT 0x01
|
|
||||||
#define HID_GET_IDLE 0x02
|
|
||||||
#define HID_GET_PROTOCOL 0x03
|
|
||||||
#define HID_SET_REPORT 0x09
|
|
||||||
#define HID_SET_IDLE 0x0A
|
|
||||||
#define HID_SET_PROTOCOL 0x0B
|
|
||||||
|
|
||||||
#define HID_HID_DESCRIPTOR_TYPE 0x21
|
|
||||||
#define HID_REPORT_DESCRIPTOR_TYPE 0x22
|
|
||||||
#define HID_PHYSICAL_DESCRIPTOR_TYPE 0x23
|
|
||||||
|
|
||||||
// HID subclass HID1.11 Page 8 4.2 Subclass
|
|
||||||
#define HID_SUBCLASS_NONE 0
|
|
||||||
#define HID_SUBCLASS_BOOT_INTERFACE 1
|
|
||||||
|
|
||||||
// HID Keyboard/Mouse bios compatible protocols HID1.11 Page 9 4.3 Protocols
|
|
||||||
#define HID_PROTOCOL_NONE 0
|
|
||||||
#define HID_PROTOCOL_KEYBOARD 1
|
|
||||||
#define HID_PROTOCOL_MOUSE 2
|
|
||||||
|
|
||||||
// Normal or bios protocol (Keyboard/Mouse) HID1.11 Page 54 7.2.5 Get_Protocol Request
|
|
||||||
// "protocol" variable is used for this purpose.
|
|
||||||
#define HID_BOOT_PROTOCOL 0
|
|
||||||
#define HID_REPORT_PROTOCOL 1
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t len; // 9
|
|
||||||
uint8_t dtype; // 0x21
|
|
||||||
uint8_t addr;
|
|
||||||
uint8_t versionL; // 0x101
|
|
||||||
uint8_t versionH; // 0x101
|
|
||||||
uint8_t country;
|
|
||||||
uint8_t desctype; // 0x22 report
|
|
||||||
uint8_t descLenL;
|
|
||||||
uint8_t descLenH;
|
|
||||||
} HIDDescDescriptor;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
InterfaceDescriptor hid;
|
|
||||||
HIDDescDescriptor desc;
|
|
||||||
EndpointDescriptor in;
|
|
||||||
} HIDDescriptor;
|
|
||||||
|
|
||||||
class HIDSubDescriptor {
|
|
||||||
public:
|
|
||||||
HIDSubDescriptor *next = NULL;
|
|
||||||
HIDSubDescriptor(const void *d, const uint16_t l) : data(d), length(l) { }
|
|
||||||
|
|
||||||
const void* data;
|
|
||||||
const uint16_t length;
|
|
||||||
};
|
|
||||||
|
|
||||||
class HID_ : public PluggableUSBModule
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
HID_(void);
|
|
||||||
int begin(void);
|
|
||||||
int SendReport(uint8_t id, const void* data, int len);
|
|
||||||
void AppendDescriptor(HIDSubDescriptor* node);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Implementation of the PluggableUSBModule
|
|
||||||
int getInterface(uint8_t* interfaceCount);
|
|
||||||
int getDescriptor(USBSetup& setup);
|
|
||||||
bool setup(USBSetup& setup);
|
|
||||||
uint8_t getShortName(char* name);
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint32_t epType[1];
|
|
||||||
|
|
||||||
HIDSubDescriptor* rootNode;
|
|
||||||
uint16_t descriptorSize;
|
|
||||||
|
|
||||||
uint8_t protocol;
|
|
||||||
uint8_t idle;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Replacement for global singleton.
|
|
||||||
// This function prevents static-initialization-order-fiasco
|
|
||||||
// https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use
|
|
||||||
HID_& HID();
|
|
||||||
|
|
||||||
#define D_HIDREPORT(length) { 9, 0x21, 0x01, 0x01, 0, 1, 0x22, lowByte(length), highByte(length) }
|
|
||||||
|
|
||||||
#endif // USBCON
|
|
||||||
|
|
||||||
#endif // HID_h
|
|
@ -1,143 +0,0 @@
|
|||||||
/*
|
|
||||||
SCP1000 Barometric Pressure Sensor Display
|
|
||||||
|
|
||||||
Shows the output of a Barometric Pressure Sensor on a
|
|
||||||
Uses the SPI library. For details on the sensor, see:
|
|
||||||
http://www.sparkfun.com/commerce/product_info.php?products_id=8161
|
|
||||||
http://www.vti.fi/en/support/obsolete_products/pressure_sensors/
|
|
||||||
|
|
||||||
This sketch adapted from Nathan Seidle's SCP1000 example for PIC:
|
|
||||||
http://www.sparkfun.com/datasheets/Sensors/SCP1000-Testing.zip
|
|
||||||
|
|
||||||
Circuit:
|
|
||||||
SCP1000 sensor attached to pins 6, 7, 10 - 13:
|
|
||||||
DRDY: pin 6
|
|
||||||
CSB: pin 7
|
|
||||||
MOSI: pin 11
|
|
||||||
MISO: pin 12
|
|
||||||
SCK: pin 13
|
|
||||||
|
|
||||||
created 31 July 2010
|
|
||||||
modified 14 August 2010
|
|
||||||
by Tom Igoe
|
|
||||||
*/
|
|
||||||
|
|
||||||
// the sensor communicates using SPI, so include the library:
|
|
||||||
#include <SPI.h>
|
|
||||||
|
|
||||||
//Sensor's memory register addresses:
|
|
||||||
const int PRESSURE = 0x1F; //3 most significant bits of pressure
|
|
||||||
const int PRESSURE_LSB = 0x20; //16 least significant bits of pressure
|
|
||||||
const int TEMPERATURE = 0x21; //16 bit temperature reading
|
|
||||||
const byte READ = 0b11111100; // SCP1000's read command
|
|
||||||
const byte WRITE = 0b00000010; // SCP1000's write command
|
|
||||||
|
|
||||||
// pins used for the connection with the sensor
|
|
||||||
// the other you need are controlled by the SPI library):
|
|
||||||
const int dataReadyPin = 6;
|
|
||||||
const int chipSelectPin = 7;
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(9600);
|
|
||||||
|
|
||||||
// start the SPI library:
|
|
||||||
SPI.begin();
|
|
||||||
|
|
||||||
// initalize the data ready and chip select pins:
|
|
||||||
pinMode(dataReadyPin, INPUT);
|
|
||||||
pinMode(chipSelectPin, OUTPUT);
|
|
||||||
|
|
||||||
//Configure SCP1000 for low noise configuration:
|
|
||||||
writeRegister(0x02, 0x2D);
|
|
||||||
writeRegister(0x01, 0x03);
|
|
||||||
writeRegister(0x03, 0x02);
|
|
||||||
// give the sensor time to set up:
|
|
||||||
delay(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
//Select High Resolution Mode
|
|
||||||
writeRegister(0x03, 0x0A);
|
|
||||||
|
|
||||||
// don't do anything until the data ready pin is high:
|
|
||||||
if (digitalRead(dataReadyPin) == HIGH) {
|
|
||||||
//Read the temperature data
|
|
||||||
int tempData = readRegister(0x21, 2);
|
|
||||||
|
|
||||||
// convert the temperature to celsius and display it:
|
|
||||||
float realTemp = (float)tempData / 20.0;
|
|
||||||
Serial.print("Temp[C]=");
|
|
||||||
Serial.print(realTemp);
|
|
||||||
|
|
||||||
|
|
||||||
//Read the pressure data highest 3 bits:
|
|
||||||
byte pressure_data_high = readRegister(0x1F, 1);
|
|
||||||
pressure_data_high &= 0b00000111; //you only needs bits 2 to 0
|
|
||||||
|
|
||||||
//Read the pressure data lower 16 bits:
|
|
||||||
unsigned int pressure_data_low = readRegister(0x20, 2);
|
|
||||||
//combine the two parts into one 19-bit number:
|
|
||||||
long pressure = ((pressure_data_high << 16) | pressure_data_low) / 4;
|
|
||||||
|
|
||||||
// display the temperature:
|
|
||||||
Serial.println("\tPressure [Pa]=" + String(pressure));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Read from or write to register from the SCP1000:
|
|
||||||
unsigned int readRegister(byte thisRegister, int bytesToRead) {
|
|
||||||
byte inByte = 0; // incoming byte from the SPI
|
|
||||||
unsigned int result = 0; // result to return
|
|
||||||
Serial.print(thisRegister, BIN);
|
|
||||||
Serial.print("\t");
|
|
||||||
// SCP1000 expects the register name in the upper 6 bits
|
|
||||||
// of the byte. So shift the bits left by two bits:
|
|
||||||
thisRegister = thisRegister << 2;
|
|
||||||
// now combine the address and the command into one byte
|
|
||||||
byte dataToSend = thisRegister & READ;
|
|
||||||
Serial.println(thisRegister, BIN);
|
|
||||||
// take the chip select low to select the device:
|
|
||||||
digitalWrite(chipSelectPin, LOW);
|
|
||||||
// send the device the register you want to read:
|
|
||||||
SPI.transfer(dataToSend);
|
|
||||||
// send a value of 0 to read the first byte returned:
|
|
||||||
result = SPI.transfer(0x00);
|
|
||||||
// decrement the number of bytes left to read:
|
|
||||||
bytesToRead--;
|
|
||||||
// if you still have another byte to read:
|
|
||||||
if (bytesToRead > 0) {
|
|
||||||
// shift the first byte left, then get the second byte:
|
|
||||||
result = result << 8;
|
|
||||||
inByte = SPI.transfer(0x00);
|
|
||||||
// combine the byte you just got with the previous one:
|
|
||||||
result = result | inByte;
|
|
||||||
// decrement the number of bytes left to read:
|
|
||||||
bytesToRead--;
|
|
||||||
}
|
|
||||||
// take the chip select high to de-select:
|
|
||||||
digitalWrite(chipSelectPin, HIGH);
|
|
||||||
// return the result:
|
|
||||||
return (result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//Sends a write command to SCP1000
|
|
||||||
|
|
||||||
void writeRegister(byte thisRegister, byte thisValue) {
|
|
||||||
|
|
||||||
// SCP1000 expects the register address in the upper 6 bits
|
|
||||||
// of the byte. So shift the bits left by two bits:
|
|
||||||
thisRegister = thisRegister << 2;
|
|
||||||
// now combine the register address and the command into one byte:
|
|
||||||
byte dataToSend = thisRegister | WRITE;
|
|
||||||
|
|
||||||
// take the chip select low to select the device:
|
|
||||||
digitalWrite(chipSelectPin, LOW);
|
|
||||||
|
|
||||||
SPI.transfer(dataToSend); //Send register location
|
|
||||||
SPI.transfer(thisValue); //Send value to record into register
|
|
||||||
|
|
||||||
// take the chip select high to de-select:
|
|
||||||
digitalWrite(chipSelectPin, HIGH);
|
|
||||||
}
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
Digital Pot Control
|
|
||||||
|
|
||||||
This example controls an Analog Devices AD5206 digital potentiometer.
|
|
||||||
The AD5206 has 6 potentiometer channels. Each channel's pins are labeled
|
|
||||||
A - connect this to voltage
|
|
||||||
W - this is the pot's wiper, which changes when you set it
|
|
||||||
B - connect this to ground.
|
|
||||||
|
|
||||||
The AD5206 is SPI-compatible,and to command it, you send two bytes,
|
|
||||||
one with the channel number (0 - 5) and one with the resistance value for the
|
|
||||||
channel (0 - 255).
|
|
||||||
|
|
||||||
The circuit:
|
|
||||||
* All A pins of AD5206 connected to +5V
|
|
||||||
* All B pins of AD5206 connected to ground
|
|
||||||
* An LED and a 220-ohm resisor in series connected from each W pin to ground
|
|
||||||
* CS - to digital pin 10 (SS pin)
|
|
||||||
* SDI - to digital pin 11 (MOSI pin)
|
|
||||||
* CLK - to digital pin 13 (SCK pin)
|
|
||||||
|
|
||||||
created 10 Aug 2010
|
|
||||||
by Tom Igoe
|
|
||||||
|
|
||||||
Thanks to Heather Dewey-Hagborg for the original tutorial, 2005
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
// inslude the SPI library:
|
|
||||||
#include <SPI.h>
|
|
||||||
|
|
||||||
|
|
||||||
// set pin 10 as the slave select for the digital pot:
|
|
||||||
const int slaveSelectPin = 10;
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
// set the slaveSelectPin as an output:
|
|
||||||
pinMode(slaveSelectPin, OUTPUT);
|
|
||||||
// initialize SPI:
|
|
||||||
SPI.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
// go through the six channels of the digital pot:
|
|
||||||
for (int channel = 0; channel < 6; channel++) {
|
|
||||||
// change the resistance on this channel from min to max:
|
|
||||||
for (int level = 0; level < 255; level++) {
|
|
||||||
digitalPotWrite(channel, level);
|
|
||||||
delay(10);
|
|
||||||
}
|
|
||||||
// wait a second at the top:
|
|
||||||
delay(100);
|
|
||||||
// change the resistance on this channel from max to min:
|
|
||||||
for (int level = 0; level < 255; level++) {
|
|
||||||
digitalPotWrite(channel, 255 - level);
|
|
||||||
delay(10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void digitalPotWrite(int address, int value) {
|
|
||||||
// take the SS pin low to select the chip:
|
|
||||||
digitalWrite(slaveSelectPin, LOW);
|
|
||||||
// send in the address and value via SPI:
|
|
||||||
SPI.transfer(address);
|
|
||||||
SPI.transfer(value);
|
|
||||||
// take the SS pin high to de-select the chip:
|
|
||||||
digitalWrite(slaveSelectPin, HIGH);
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
#######################################
|
|
||||||
# Syntax Coloring Map SPI
|
|
||||||
#######################################
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Datatypes (KEYWORD1)
|
|
||||||
#######################################
|
|
||||||
|
|
||||||
SPI KEYWORD1
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Methods and Functions (KEYWORD2)
|
|
||||||
#######################################
|
|
||||||
begin KEYWORD2
|
|
||||||
end KEYWORD2
|
|
||||||
transfer KEYWORD2
|
|
||||||
#setBitOrder KEYWORD2
|
|
||||||
setDataMode KEYWORD2
|
|
||||||
setClockDivider KEYWORD2
|
|
||||||
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Constants (LITERAL1)
|
|
||||||
#######################################
|
|
||||||
SPI_MODE0 LITERAL1
|
|
||||||
SPI_MODE1 LITERAL1
|
|
||||||
SPI_MODE2 LITERAL1
|
|
||||||
SPI_MODE3 LITERAL1
|
|
||||||
|
|
||||||
SPI_CONTINUE LITERAL1
|
|
||||||
SPI_LAST LITERAL1
|
|
@ -1,10 +0,0 @@
|
|||||||
name=SPI
|
|
||||||
version=1.0
|
|
||||||
author=Arduino
|
|
||||||
maintainer=Arduino <info@arduino.cc>
|
|
||||||
sentence=Enables the communication with devices that use the Serial Peripheral Interface (SPI) Bus.
|
|
||||||
paragraph=
|
|
||||||
category=Communication
|
|
||||||
url=http://www.arduino.cc/en/Reference/SPI
|
|
||||||
architectures=sam
|
|
||||||
|
|
@ -1,297 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2010 by Cristian Maglie <c.maglie@arduino.cc>
|
|
||||||
* Copyright (c) 2014 by Paul Stoffregen <paul@pjrc.com> (Transaction API)
|
|
||||||
* SPI Master library for arduino.
|
|
||||||
*
|
|
||||||
* This file is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of either the GNU General Public License version 2
|
|
||||||
* or the GNU Lesser General Public License version 2.1, both as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "SPI.h"
|
|
||||||
|
|
||||||
SPIClass::SPIClass(Spi *_spi, uint32_t _id, void(*_initCb)(void)) :
|
|
||||||
spi(_spi), id(_id), initCb(_initCb), initialized(false)
|
|
||||||
{
|
|
||||||
// Empty
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPIClass::begin() {
|
|
||||||
init();
|
|
||||||
// NPCS control is left to the user
|
|
||||||
|
|
||||||
// Default speed set to 4Mhz
|
|
||||||
setClockDivider(BOARD_SPI_DEFAULT_SS, 21);
|
|
||||||
setDataMode(BOARD_SPI_DEFAULT_SS, SPI_MODE0);
|
|
||||||
setBitOrder(BOARD_SPI_DEFAULT_SS, MSBFIRST);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPIClass::begin(uint8_t _pin) {
|
|
||||||
init();
|
|
||||||
|
|
||||||
uint32_t spiPin = BOARD_PIN_TO_SPI_PIN(_pin);
|
|
||||||
PIO_Configure(
|
|
||||||
g_APinDescription[spiPin].pPort,
|
|
||||||
g_APinDescription[spiPin].ulPinType,
|
|
||||||
g_APinDescription[spiPin].ulPin,
|
|
||||||
g_APinDescription[spiPin].ulPinConfiguration);
|
|
||||||
|
|
||||||
// Default speed set to 4Mhz
|
|
||||||
setClockDivider(_pin, 21);
|
|
||||||
setDataMode(_pin, SPI_MODE0);
|
|
||||||
setBitOrder(_pin, MSBFIRST);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPIClass::init() {
|
|
||||||
if (initialized)
|
|
||||||
return;
|
|
||||||
interruptMode = 0;
|
|
||||||
interruptSave = 0;
|
|
||||||
interruptMask[0] = 0;
|
|
||||||
interruptMask[1] = 0;
|
|
||||||
interruptMask[2] = 0;
|
|
||||||
interruptMask[3] = 0;
|
|
||||||
initCb();
|
|
||||||
SPI_Configure(spi, id, SPI_MR_MSTR | SPI_MR_PS | SPI_MR_MODFDIS);
|
|
||||||
SPI_Enable(spi);
|
|
||||||
initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef interruptsStatus
|
|
||||||
#define interruptsStatus() __interruptsStatus()
|
|
||||||
static inline unsigned char __interruptsStatus(void) __attribute__((always_inline, unused));
|
|
||||||
static inline unsigned char __interruptsStatus(void) {
|
|
||||||
unsigned int primask, faultmask;
|
|
||||||
asm volatile ("mrs %0, primask" : "=r" (primask));
|
|
||||||
if (primask) return 0;
|
|
||||||
asm volatile ("mrs %0, faultmask" : "=r" (faultmask));
|
|
||||||
if (faultmask) return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void SPIClass::usingInterrupt(uint8_t interruptNumber)
|
|
||||||
{
|
|
||||||
uint8_t irestore;
|
|
||||||
|
|
||||||
irestore = interruptsStatus();
|
|
||||||
noInterrupts();
|
|
||||||
if (interruptMode < 16) {
|
|
||||||
if (interruptNumber > NUM_DIGITAL_PINS) {
|
|
||||||
interruptMode = 16;
|
|
||||||
} else {
|
|
||||||
Pio *pio = g_APinDescription[interruptNumber].pPort;
|
|
||||||
uint32_t mask = g_APinDescription[interruptNumber].ulPin;
|
|
||||||
if (pio == PIOA) {
|
|
||||||
interruptMode |= 1;
|
|
||||||
interruptMask[0] |= mask;
|
|
||||||
} else if (pio == PIOB) {
|
|
||||||
interruptMode |= 2;
|
|
||||||
interruptMask[1] |= mask;
|
|
||||||
} else if (pio == PIOC) {
|
|
||||||
interruptMode |= 4;
|
|
||||||
interruptMask[2] |= mask;
|
|
||||||
} else if (pio == PIOD) {
|
|
||||||
interruptMode |= 8;
|
|
||||||
interruptMask[3] |= mask;
|
|
||||||
} else {
|
|
||||||
interruptMode = 16;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (irestore) interrupts();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPIClass::beginTransaction(uint8_t pin, SPISettings settings)
|
|
||||||
{
|
|
||||||
uint8_t mode = interruptMode;
|
|
||||||
if (mode > 0) {
|
|
||||||
if (mode < 16) {
|
|
||||||
if (mode & 1) PIOA->PIO_IDR = interruptMask[0];
|
|
||||||
if (mode & 2) PIOB->PIO_IDR = interruptMask[1];
|
|
||||||
if (mode & 4) PIOC->PIO_IDR = interruptMask[2];
|
|
||||||
if (mode & 8) PIOD->PIO_IDR = interruptMask[3];
|
|
||||||
} else {
|
|
||||||
interruptSave = interruptsStatus();
|
|
||||||
noInterrupts();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(pin);
|
|
||||||
bitOrder[ch] = settings.border;
|
|
||||||
SPI_ConfigureNPCS(spi, ch, settings.config);
|
|
||||||
//setBitOrder(pin, settings.border);
|
|
||||||
//setDataMode(pin, settings.datamode);
|
|
||||||
//setClockDivider(pin, settings.clockdiv);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPIClass::endTransaction(void)
|
|
||||||
{
|
|
||||||
uint8_t mode = interruptMode;
|
|
||||||
if (mode > 0) {
|
|
||||||
if (mode < 16) {
|
|
||||||
if (mode & 1) PIOA->PIO_IER = interruptMask[0];
|
|
||||||
if (mode & 2) PIOB->PIO_IER = interruptMask[1];
|
|
||||||
if (mode & 4) PIOC->PIO_IER = interruptMask[2];
|
|
||||||
if (mode & 8) PIOD->PIO_IER = interruptMask[3];
|
|
||||||
} else {
|
|
||||||
if (interruptSave) interrupts();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPIClass::end(uint8_t _pin) {
|
|
||||||
uint32_t spiPin = BOARD_PIN_TO_SPI_PIN(_pin);
|
|
||||||
// Setting the pin as INPUT will disconnect it from SPI peripheral
|
|
||||||
pinMode(spiPin, INPUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPIClass::end() {
|
|
||||||
SPI_Disable(spi);
|
|
||||||
initialized = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPIClass::setBitOrder(uint8_t _pin, BitOrder _bitOrder) {
|
|
||||||
uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
|
|
||||||
bitOrder[ch] = _bitOrder;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPIClass::setDataMode(uint8_t _pin, uint8_t _mode) {
|
|
||||||
uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
|
|
||||||
mode[ch] = _mode | SPI_CSR_CSAAT;
|
|
||||||
// SPI_CSR_DLYBCT(1) keeps CS enabled for 32 MCLK after a completed
|
|
||||||
// transfer. Some device needs that for working properly.
|
|
||||||
SPI_ConfigureNPCS(spi, ch, mode[ch] | SPI_CSR_SCBR(divider[ch]) | SPI_CSR_DLYBCT(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPIClass::setClockDivider(uint8_t _pin, uint8_t _divider) {
|
|
||||||
uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
|
|
||||||
divider[ch] = _divider;
|
|
||||||
// SPI_CSR_DLYBCT(1) keeps CS enabled for 32 MCLK after a completed
|
|
||||||
// transfer. Some device needs that for working properly.
|
|
||||||
SPI_ConfigureNPCS(spi, ch, mode[ch] | SPI_CSR_SCBR(divider[ch]) | SPI_CSR_DLYBCT(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
byte SPIClass::transfer(byte _pin, uint8_t _data, SPITransferMode _mode) {
|
|
||||||
uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
|
|
||||||
// Reverse bit order
|
|
||||||
if (bitOrder[ch] == LSBFIRST)
|
|
||||||
_data = __REV(__RBIT(_data));
|
|
||||||
uint32_t d = _data | SPI_PCS(ch);
|
|
||||||
if (_mode == SPI_LAST)
|
|
||||||
d |= SPI_TDR_LASTXFER;
|
|
||||||
|
|
||||||
// SPI_Write(spi, _channel, _data);
|
|
||||||
while ((spi->SPI_SR & SPI_SR_TDRE) == 0)
|
|
||||||
;
|
|
||||||
spi->SPI_TDR = d;
|
|
||||||
|
|
||||||
// return SPI_Read(spi);
|
|
||||||
while ((spi->SPI_SR & SPI_SR_RDRF) == 0)
|
|
||||||
;
|
|
||||||
d = spi->SPI_RDR;
|
|
||||||
// Reverse bit order
|
|
||||||
if (bitOrder[ch] == LSBFIRST)
|
|
||||||
d = __REV(__RBIT(d));
|
|
||||||
return d & 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t SPIClass::transfer16(byte _pin, uint16_t _data, SPITransferMode _mode) {
|
|
||||||
union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } t;
|
|
||||||
uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
|
|
||||||
|
|
||||||
t.val = _data;
|
|
||||||
|
|
||||||
if (bitOrder[ch] == LSBFIRST) {
|
|
||||||
t.lsb = transfer(_pin, t.lsb, SPI_CONTINUE);
|
|
||||||
t.msb = transfer(_pin, t.msb, _mode);
|
|
||||||
} else {
|
|
||||||
t.msb = transfer(_pin, t.msb, SPI_CONTINUE);
|
|
||||||
t.lsb = transfer(_pin, t.lsb, _mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
return t.val;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPIClass::transfer(byte _pin, void *_buf, size_t _count, SPITransferMode _mode) {
|
|
||||||
if (_count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
uint8_t *buffer = (uint8_t *)_buf;
|
|
||||||
if (_count == 1) {
|
|
||||||
*buffer = transfer(_pin, *buffer, _mode);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
|
|
||||||
bool reverse = (bitOrder[ch] == LSBFIRST);
|
|
||||||
|
|
||||||
// Send the first byte
|
|
||||||
uint32_t d = *buffer;
|
|
||||||
if (reverse)
|
|
||||||
d = __REV(__RBIT(d));
|
|
||||||
while ((spi->SPI_SR & SPI_SR_TDRE) == 0)
|
|
||||||
;
|
|
||||||
spi->SPI_TDR = d | SPI_PCS(ch);
|
|
||||||
|
|
||||||
while (_count > 1) {
|
|
||||||
// Prepare next byte
|
|
||||||
d = *(buffer+1);
|
|
||||||
if (reverse)
|
|
||||||
d = __REV(__RBIT(d));
|
|
||||||
if (_count == 2 && _mode == SPI_LAST)
|
|
||||||
d |= SPI_TDR_LASTXFER;
|
|
||||||
|
|
||||||
// Read transferred byte and send next one straight away
|
|
||||||
while ((spi->SPI_SR & SPI_SR_RDRF) == 0)
|
|
||||||
;
|
|
||||||
uint8_t r = spi->SPI_RDR;
|
|
||||||
spi->SPI_TDR = d | SPI_PCS(ch);
|
|
||||||
|
|
||||||
// Save read byte
|
|
||||||
if (reverse)
|
|
||||||
r = __REV(__RBIT(r));
|
|
||||||
*buffer = r;
|
|
||||||
buffer++;
|
|
||||||
_count--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Receive the last transferred byte
|
|
||||||
while ((spi->SPI_SR & SPI_SR_RDRF) == 0)
|
|
||||||
;
|
|
||||||
uint8_t r = spi->SPI_RDR;
|
|
||||||
if (reverse)
|
|
||||||
r = __REV(__RBIT(r));
|
|
||||||
*buffer = r;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPIClass::attachInterrupt(void) {
|
|
||||||
// Should be enableInterrupt()
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPIClass::detachInterrupt(void) {
|
|
||||||
// Should be disableInterrupt()
|
|
||||||
}
|
|
||||||
|
|
||||||
#if SPI_INTERFACES_COUNT > 0
|
|
||||||
static void SPI_0_Init(void) {
|
|
||||||
PIO_Configure(
|
|
||||||
g_APinDescription[PIN_SPI_MOSI].pPort,
|
|
||||||
g_APinDescription[PIN_SPI_MOSI].ulPinType,
|
|
||||||
g_APinDescription[PIN_SPI_MOSI].ulPin,
|
|
||||||
g_APinDescription[PIN_SPI_MOSI].ulPinConfiguration);
|
|
||||||
PIO_Configure(
|
|
||||||
g_APinDescription[PIN_SPI_MISO].pPort,
|
|
||||||
g_APinDescription[PIN_SPI_MISO].ulPinType,
|
|
||||||
g_APinDescription[PIN_SPI_MISO].ulPin,
|
|
||||||
g_APinDescription[PIN_SPI_MISO].ulPinConfiguration);
|
|
||||||
PIO_Configure(
|
|
||||||
g_APinDescription[PIN_SPI_SCK].pPort,
|
|
||||||
g_APinDescription[PIN_SPI_SCK].ulPinType,
|
|
||||||
g_APinDescription[PIN_SPI_SCK].ulPin,
|
|
||||||
g_APinDescription[PIN_SPI_SCK].ulPinConfiguration);
|
|
||||||
}
|
|
||||||
|
|
||||||
SPIClass SPI(SPI_INTERFACE, SPI_INTERFACE_ID, SPI_0_Init);
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,148 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2010 by Cristian Maglie <c.maglie@arduino.cc>
|
|
||||||
* Copyright (c) 2014 by Paul Stoffregen <paul@pjrc.com> (Transaction API)
|
|
||||||
* SPI Master library for arduino.
|
|
||||||
*
|
|
||||||
* This file is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of either the GNU General Public License version 2
|
|
||||||
* or the GNU Lesser General Public License version 2.1, both as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _SPI_H_INCLUDED
|
|
||||||
#define _SPI_H_INCLUDED
|
|
||||||
|
|
||||||
#include "variant.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
// SPI_HAS_TRANSACTION means SPI has
|
|
||||||
// - beginTransaction()
|
|
||||||
// - endTransaction()
|
|
||||||
// - usingInterrupt()
|
|
||||||
// - SPISetting(clock, bitOrder, dataMode)
|
|
||||||
#define SPI_HAS_TRANSACTION 1
|
|
||||||
|
|
||||||
// SPI_HAS_EXTENDED_CS_PIN_HANDLING means SPI has automatic
|
|
||||||
// CS pin handling and provides the following methods:
|
|
||||||
// - begin(pin)
|
|
||||||
// - end(pin)
|
|
||||||
// - setBitOrder(pin, bitorder)
|
|
||||||
// - setDataMode(pin, datamode)
|
|
||||||
// - setClockDivider(pin, clockdiv)
|
|
||||||
// - transfer(pin, data, SPI_LAST/SPI_CONTINUE)
|
|
||||||
// - beginTransaction(pin, SPISettings settings) (if transactions are available)
|
|
||||||
#define SPI_HAS_EXTENDED_CS_PIN_HANDLING 1
|
|
||||||
|
|
||||||
#define SPI_MODE0 0x02
|
|
||||||
#define SPI_MODE1 0x00
|
|
||||||
#define SPI_MODE2 0x03
|
|
||||||
#define SPI_MODE3 0x01
|
|
||||||
|
|
||||||
enum SPITransferMode {
|
|
||||||
SPI_CONTINUE,
|
|
||||||
SPI_LAST
|
|
||||||
};
|
|
||||||
|
|
||||||
class SPISettings {
|
|
||||||
public:
|
|
||||||
SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
|
|
||||||
if (__builtin_constant_p(clock)) {
|
|
||||||
init_AlwaysInline(clock, bitOrder, dataMode);
|
|
||||||
} else {
|
|
||||||
init_MightInline(clock, bitOrder, dataMode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SPISettings() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); }
|
|
||||||
private:
|
|
||||||
void init_MightInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
|
|
||||||
init_AlwaysInline(clock, bitOrder, dataMode);
|
|
||||||
}
|
|
||||||
void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) __attribute__((__always_inline__)) {
|
|
||||||
border = bitOrder;
|
|
||||||
uint8_t div;
|
|
||||||
if (clock < (F_CPU / 255)) {
|
|
||||||
div = 255;
|
|
||||||
} else if (clock >= (F_CPU / 2)) {
|
|
||||||
div = 2;
|
|
||||||
} else {
|
|
||||||
div = (F_CPU / (clock + 1)) + 1;
|
|
||||||
}
|
|
||||||
config = (dataMode & 3) | SPI_CSR_CSAAT | SPI_CSR_SCBR(div) | SPI_CSR_DLYBCT(1);
|
|
||||||
}
|
|
||||||
uint32_t config;
|
|
||||||
BitOrder border;
|
|
||||||
friend class SPIClass;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SPIClass {
|
|
||||||
public:
|
|
||||||
SPIClass(Spi *_spi, uint32_t _id, void(*_initCb)(void));
|
|
||||||
|
|
||||||
// Transfer functions
|
|
||||||
byte transfer(byte _pin, uint8_t _data, SPITransferMode _mode = SPI_LAST);
|
|
||||||
uint16_t transfer16(byte _pin, uint16_t _data, SPITransferMode _mode = SPI_LAST);
|
|
||||||
void transfer(byte _pin, void *_buf, size_t _count, SPITransferMode _mode = SPI_LAST);
|
|
||||||
// Transfer functions on default pin BOARD_SPI_DEFAULT_SS
|
|
||||||
byte transfer(uint8_t _data, SPITransferMode _mode = SPI_LAST) { return transfer(BOARD_SPI_DEFAULT_SS, _data, _mode); }
|
|
||||||
uint16_t transfer16(uint16_t _data, SPITransferMode _mode = SPI_LAST) { return transfer16(BOARD_SPI_DEFAULT_SS, _data, _mode); }
|
|
||||||
void transfer(void *_buf, size_t _count, SPITransferMode _mode = SPI_LAST) { transfer(BOARD_SPI_DEFAULT_SS, _buf, _count, _mode); }
|
|
||||||
|
|
||||||
// Transaction Functions
|
|
||||||
void usingInterrupt(uint8_t interruptNumber);
|
|
||||||
void beginTransaction(SPISettings settings) { beginTransaction(BOARD_SPI_DEFAULT_SS, settings); }
|
|
||||||
void beginTransaction(uint8_t pin, SPISettings settings);
|
|
||||||
void endTransaction(void);
|
|
||||||
|
|
||||||
// SPI Configuration methods
|
|
||||||
void attachInterrupt(void);
|
|
||||||
void detachInterrupt(void);
|
|
||||||
|
|
||||||
void begin(void);
|
|
||||||
void end(void);
|
|
||||||
|
|
||||||
// Attach/Detach pin to/from SPI controller
|
|
||||||
void begin(uint8_t _pin);
|
|
||||||
void end(uint8_t _pin);
|
|
||||||
|
|
||||||
// These methods sets a parameter on a single pin
|
|
||||||
void setBitOrder(uint8_t _pin, BitOrder);
|
|
||||||
void setDataMode(uint8_t _pin, uint8_t);
|
|
||||||
void setClockDivider(uint8_t _pin, uint8_t);
|
|
||||||
|
|
||||||
// These methods sets the same parameters but on default pin BOARD_SPI_DEFAULT_SS
|
|
||||||
void setBitOrder(BitOrder _order) { setBitOrder(BOARD_SPI_DEFAULT_SS, _order); };
|
|
||||||
void setDataMode(uint8_t _mode) { setDataMode(BOARD_SPI_DEFAULT_SS, _mode); };
|
|
||||||
void setClockDivider(uint8_t _div) { setClockDivider(BOARD_SPI_DEFAULT_SS, _div); };
|
|
||||||
|
|
||||||
private:
|
|
||||||
void init();
|
|
||||||
|
|
||||||
Spi *spi;
|
|
||||||
uint32_t id;
|
|
||||||
BitOrder bitOrder[SPI_CHANNELS_NUM];
|
|
||||||
uint32_t divider[SPI_CHANNELS_NUM];
|
|
||||||
uint32_t mode[SPI_CHANNELS_NUM];
|
|
||||||
void (*initCb)(void);
|
|
||||||
bool initialized;
|
|
||||||
uint8_t interruptMode; // 0=none, 1-15=mask, 16=global
|
|
||||||
uint8_t interruptSave; // temp storage, to restore state
|
|
||||||
uint32_t interruptMask[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
#if SPI_INTERFACES_COUNT > 0
|
|
||||||
extern SPIClass SPI;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// For compatibility with sketches designed for AVR @ 16 MHz
|
|
||||||
// New programs should use SPI.beginTransaction to set the SPI clock
|
|
||||||
#define SPI_CLOCK_DIV2 11
|
|
||||||
#define SPI_CLOCK_DIV4 21
|
|
||||||
#define SPI_CLOCK_DIV8 42
|
|
||||||
#define SPI_CLOCK_DIV16 84
|
|
||||||
#define SPI_CLOCK_DIV32 168
|
|
||||||
#define SPI_CLOCK_DIV64 255
|
|
||||||
#define SPI_CLOCK_DIV128 255
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,87 +0,0 @@
|
|||||||
// I2C SRF10 or SRF08 Devantech Ultrasonic Ranger Finder
|
|
||||||
// by Nicholas Zambetti <http://www.zambetti.com>
|
|
||||||
// and James Tichenor <http://www.jamestichenor.net>
|
|
||||||
|
|
||||||
// Demonstrates use of the Wire library reading data from the
|
|
||||||
// Devantech Utrasonic Rangers SFR08 and SFR10
|
|
||||||
|
|
||||||
// Created 29 April 2006
|
|
||||||
|
|
||||||
// This example code is in the public domain.
|
|
||||||
|
|
||||||
|
|
||||||
#include <Wire.h>
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
Wire.begin(); // join i2c bus (address optional for master)
|
|
||||||
Serial.begin(9600); // start serial communication at 9600bps
|
|
||||||
}
|
|
||||||
|
|
||||||
int reading = 0;
|
|
||||||
|
|
||||||
void loop()
|
|
||||||
{
|
|
||||||
// step 1: instruct sensor to read echoes
|
|
||||||
Wire.beginTransmission(112); // transmit to device #112 (0x70)
|
|
||||||
// the address specified in the datasheet is 224 (0xE0)
|
|
||||||
// but i2c adressing uses the high 7 bits so it's 112
|
|
||||||
Wire.write(byte(0x00)); // sets register pointer to the command register (0x00)
|
|
||||||
Wire.write(byte(0x50)); // command sensor to measure in "inches" (0x50)
|
|
||||||
// use 0x51 for centimeters
|
|
||||||
// use 0x52 for ping microseconds
|
|
||||||
Wire.endTransmission(); // stop transmitting
|
|
||||||
|
|
||||||
// step 2: wait for readings to happen
|
|
||||||
delay(70); // datasheet suggests at least 65 milliseconds
|
|
||||||
|
|
||||||
// step 3: instruct sensor to return a particular echo reading
|
|
||||||
Wire.beginTransmission(112); // transmit to device #112
|
|
||||||
Wire.write(byte(0x02)); // sets register pointer to echo #1 register (0x02)
|
|
||||||
Wire.endTransmission(); // stop transmitting
|
|
||||||
|
|
||||||
// step 4: request reading from sensor
|
|
||||||
Wire.requestFrom(112, 2); // request 2 bytes from slave device #112
|
|
||||||
|
|
||||||
// step 5: receive reading from sensor
|
|
||||||
if(2 <= Wire.available()) // if two bytes were received
|
|
||||||
{
|
|
||||||
reading = Wire.read(); // receive high byte (overwrites previous reading)
|
|
||||||
reading = reading << 8; // shift high byte to be high 8 bits
|
|
||||||
reading |= Wire.read(); // receive low byte as lower 8 bits
|
|
||||||
Serial.println(reading); // print the reading
|
|
||||||
}
|
|
||||||
|
|
||||||
delay(250); // wait a bit since people have to read the output :)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
// The following code changes the address of a Devantech Ultrasonic Range Finder (SRF10 or SRF08)
|
|
||||||
// usage: changeAddress(0x70, 0xE6);
|
|
||||||
|
|
||||||
void changeAddress(byte oldAddress, byte newAddress)
|
|
||||||
{
|
|
||||||
Wire.beginTransmission(oldAddress);
|
|
||||||
Wire.write(byte(0x00));
|
|
||||||
Wire.write(byte(0xA0));
|
|
||||||
Wire.endTransmission();
|
|
||||||
|
|
||||||
Wire.beginTransmission(oldAddress);
|
|
||||||
Wire.write(byte(0x00));
|
|
||||||
Wire.write(byte(0xAA));
|
|
||||||
Wire.endTransmission();
|
|
||||||
|
|
||||||
Wire.beginTransmission(oldAddress);
|
|
||||||
Wire.write(byte(0x00));
|
|
||||||
Wire.write(byte(0xA5));
|
|
||||||
Wire.endTransmission();
|
|
||||||
|
|
||||||
Wire.beginTransmission(oldAddress);
|
|
||||||
Wire.write(byte(0x00));
|
|
||||||
Wire.write(newAddress);
|
|
||||||
Wire.endTransmission();
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
@ -1,39 +0,0 @@
|
|||||||
// I2C Digital Potentiometer
|
|
||||||
// by Nicholas Zambetti <http://www.zambetti.com>
|
|
||||||
// and Shawn Bonkowski <http://people.interaction-ivrea.it/s.bonkowski/>
|
|
||||||
|
|
||||||
// Demonstrates use of the Wire library
|
|
||||||
// Controls AD5171 digital potentiometer via I2C/TWI
|
|
||||||
|
|
||||||
// Created 31 March 2006
|
|
||||||
|
|
||||||
// This example code is in the public domain.
|
|
||||||
|
|
||||||
// This example code is in the public domain.
|
|
||||||
|
|
||||||
|
|
||||||
#include <Wire.h>
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
Wire.begin(); // join i2c bus (address optional for master)
|
|
||||||
}
|
|
||||||
|
|
||||||
byte val = 0;
|
|
||||||
|
|
||||||
void loop()
|
|
||||||
{
|
|
||||||
Wire.beginTransmission(44); // transmit to device #44 (0x2c)
|
|
||||||
// device address is specified in datasheet
|
|
||||||
Wire.write(byte(0x00)); // sends instruction byte
|
|
||||||
Wire.write(val); // sends potentiometer value byte
|
|
||||||
Wire.endTransmission(); // stop transmitting
|
|
||||||
|
|
||||||
val++; // increment value
|
|
||||||
if(val == 64) // if reached 64th position (max)
|
|
||||||
{
|
|
||||||
val = 0; // start over from lowest value
|
|
||||||
}
|
|
||||||
delay(500);
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
|||||||
// Wire Master Reader
|
|
||||||
// by Nicholas Zambetti <http://www.zambetti.com>
|
|
||||||
|
|
||||||
// Demonstrates use of the Wire library
|
|
||||||
// Reads data from an I2C/TWI slave device
|
|
||||||
// Refer to the "Wire Slave Sender" example for use with this
|
|
||||||
|
|
||||||
// Created 29 March 2006
|
|
||||||
|
|
||||||
// This example code is in the public domain.
|
|
||||||
|
|
||||||
|
|
||||||
#include <Wire.h>
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
Wire.begin(); // join i2c bus (address optional for master)
|
|
||||||
Serial.begin(9600); // start serial for output
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop()
|
|
||||||
{
|
|
||||||
Wire.requestFrom(2, 6); // request 6 bytes from slave device #2
|
|
||||||
|
|
||||||
while(Wire.available()) // slave may send less than requested
|
|
||||||
{
|
|
||||||
char c = Wire.read(); // receive a byte as character
|
|
||||||
Serial.print(c); // print the character
|
|
||||||
}
|
|
||||||
|
|
||||||
delay(500);
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
// Wire Master Writer
|
|
||||||
// by Nicholas Zambetti <http://www.zambetti.com>
|
|
||||||
|
|
||||||
// Demonstrates use of the Wire library
|
|
||||||
// Writes data to an I2C/TWI slave device
|
|
||||||
// Refer to the "Wire Slave Receiver" example for use with this
|
|
||||||
|
|
||||||
// Created 29 March 2006
|
|
||||||
|
|
||||||
// This example code is in the public domain.
|
|
||||||
|
|
||||||
|
|
||||||
#include <Wire.h>
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
Wire.begin(); // join i2c bus (address optional for master)
|
|
||||||
}
|
|
||||||
|
|
||||||
byte x = 0;
|
|
||||||
|
|
||||||
void loop()
|
|
||||||
{
|
|
||||||
Wire.beginTransmission(4); // transmit to device #4
|
|
||||||
Wire.write("x is "); // sends five bytes
|
|
||||||
Wire.write(x); // sends one byte
|
|
||||||
Wire.endTransmission(); // stop transmitting
|
|
||||||
|
|
||||||
x++;
|
|
||||||
delay(500);
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
// Wire Slave Receiver
|
|
||||||
// by Nicholas Zambetti <http://www.zambetti.com>
|
|
||||||
|
|
||||||
// Demonstrates use of the Wire library
|
|
||||||
// Receives data as an I2C/TWI slave device
|
|
||||||
// Refer to the "Wire Master Writer" example for use with this
|
|
||||||
|
|
||||||
// Created 29 March 2006
|
|
||||||
|
|
||||||
// This example code is in the public domain.
|
|
||||||
|
|
||||||
|
|
||||||
#include <Wire.h>
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
Wire.begin(4); // join i2c bus with address #4
|
|
||||||
Wire.onReceive(receiveEvent); // register event
|
|
||||||
Serial.begin(9600); // start serial for output
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop()
|
|
||||||
{
|
|
||||||
delay(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
// function that executes whenever data is received from master
|
|
||||||
// this function is registered as an event, see setup()
|
|
||||||
void receiveEvent(int howMany)
|
|
||||||
{
|
|
||||||
while(1 < Wire.available()) // loop through all but the last
|
|
||||||
{
|
|
||||||
char c = Wire.read(); // receive byte as a character
|
|
||||||
Serial.print(c); // print the character
|
|
||||||
}
|
|
||||||
int x = Wire.read(); // receive byte as an integer
|
|
||||||
Serial.println(x); // print the integer
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
// Wire Slave Sender
|
|
||||||
// by Nicholas Zambetti <http://www.zambetti.com>
|
|
||||||
|
|
||||||
// Demonstrates use of the Wire library
|
|
||||||
// Sends data as an I2C/TWI slave device
|
|
||||||
// Refer to the "Wire Master Reader" example for use with this
|
|
||||||
|
|
||||||
// Created 29 March 2006
|
|
||||||
|
|
||||||
// This example code is in the public domain.
|
|
||||||
|
|
||||||
|
|
||||||
#include <Wire.h>
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
Wire.begin(2); // join i2c bus with address #2
|
|
||||||
Wire.onRequest(requestEvent); // register event
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop()
|
|
||||||
{
|
|
||||||
delay(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
// function that executes whenever data is requested by master
|
|
||||||
// this function is registered as an event, see setup()
|
|
||||||
void requestEvent()
|
|
||||||
{
|
|
||||||
Wire.write("hello "); // respond with message of 6 bytes
|
|
||||||
// as expected by master
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
#######################################
|
|
||||||
# Syntax Coloring Map For Wire
|
|
||||||
#######################################
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Datatypes (KEYWORD1)
|
|
||||||
#######################################
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Methods and Functions (KEYWORD2)
|
|
||||||
#######################################
|
|
||||||
|
|
||||||
begin KEYWORD2
|
|
||||||
setClock KEYWORD2
|
|
||||||
beginTransmission KEYWORD2
|
|
||||||
endTransmission KEYWORD2
|
|
||||||
requestFrom KEYWORD2
|
|
||||||
onReceive KEYWORD2
|
|
||||||
onRequest KEYWORD2
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Instances (KEYWORD2)
|
|
||||||
#######################################
|
|
||||||
|
|
||||||
Wire KEYWORD2
|
|
||||||
Wire1 KEYWORD2
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Constants (LITERAL1)
|
|
||||||
#######################################
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
|||||||
name=Wire
|
|
||||||
version=1.0
|
|
||||||
author=Arduino
|
|
||||||
maintainer=Arduino <info@arduino.cc>
|
|
||||||
sentence=Allows the communication between devices or sensors connected via Two Wire Interface Bus.
|
|
||||||
paragraph=
|
|
||||||
category=Communication
|
|
||||||
url=http://www.arduino.cc/en/Reference/Wire
|
|
||||||
architectures=sam
|
|
||||||
|
|
@ -1,447 +0,0 @@
|
|||||||
/*
|
|
||||||
* TwoWire.h - TWI/I2C library for Arduino Due
|
|
||||||
* Copyright (c) 2011 Cristian Maglie <c.maglie@arduino.cc>
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include <string.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "Wire.h"
|
|
||||||
|
|
||||||
static inline bool TWI_FailedAcknowledge(Twi *pTwi) {
|
|
||||||
return pTwi->TWI_SR & TWI_SR_NACK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool TWI_WaitTransferComplete(Twi *_twi, uint32_t _timeout) {
|
|
||||||
uint32_t _status_reg = 0;
|
|
||||||
while ((_status_reg & TWI_SR_TXCOMP) != TWI_SR_TXCOMP) {
|
|
||||||
_status_reg = TWI_GetStatus(_twi);
|
|
||||||
|
|
||||||
if (_status_reg & TWI_SR_NACK)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (--_timeout == 0)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool TWI_WaitByteSent(Twi *_twi, uint32_t _timeout) {
|
|
||||||
uint32_t _status_reg = 0;
|
|
||||||
while ((_status_reg & TWI_SR_TXRDY) != TWI_SR_TXRDY) {
|
|
||||||
_status_reg = TWI_GetStatus(_twi);
|
|
||||||
|
|
||||||
if (_status_reg & TWI_SR_NACK)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (--_timeout == 0)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool TWI_WaitByteReceived(Twi *_twi, uint32_t _timeout) {
|
|
||||||
uint32_t _status_reg = 0;
|
|
||||||
while ((_status_reg & TWI_SR_RXRDY) != TWI_SR_RXRDY) {
|
|
||||||
_status_reg = TWI_GetStatus(_twi);
|
|
||||||
|
|
||||||
if (_status_reg & TWI_SR_NACK)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (--_timeout == 0)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool TWI_STATUS_SVREAD(uint32_t status) {
|
|
||||||
return (status & TWI_SR_SVREAD) == TWI_SR_SVREAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool TWI_STATUS_SVACC(uint32_t status) {
|
|
||||||
return (status & TWI_SR_SVACC) == TWI_SR_SVACC;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool TWI_STATUS_GACC(uint32_t status) {
|
|
||||||
return (status & TWI_SR_GACC) == TWI_SR_GACC;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool TWI_STATUS_EOSACC(uint32_t status) {
|
|
||||||
return (status & TWI_SR_EOSACC) == TWI_SR_EOSACC;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool TWI_STATUS_NACK(uint32_t status) {
|
|
||||||
return (status & TWI_SR_NACK) == TWI_SR_NACK;
|
|
||||||
}
|
|
||||||
|
|
||||||
TwoWire::TwoWire(Twi *_twi, void(*_beginCb)(void), void(*_endCb)(void)) :
|
|
||||||
twi(_twi), rxBufferIndex(0), rxBufferLength(0), txAddress(0),
|
|
||||||
txBufferLength(0), srvBufferIndex(0), srvBufferLength(0), status(
|
|
||||||
UNINITIALIZED), onBeginCallback(_beginCb),
|
|
||||||
onEndCallback(_endCb), twiClock(TWI_CLOCK) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void TwoWire::begin(void) {
|
|
||||||
if (onBeginCallback)
|
|
||||||
onBeginCallback();
|
|
||||||
|
|
||||||
// Disable PDC channel
|
|
||||||
twi->TWI_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
|
|
||||||
|
|
||||||
TWI_ConfigureMaster(twi, twiClock, VARIANT_MCK);
|
|
||||||
status = MASTER_IDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TwoWire::begin(uint8_t address) {
|
|
||||||
if (onBeginCallback)
|
|
||||||
onBeginCallback();
|
|
||||||
|
|
||||||
// Disable PDC channel
|
|
||||||
twi->TWI_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
|
|
||||||
|
|
||||||
TWI_ConfigureSlave(twi, address);
|
|
||||||
status = SLAVE_IDLE;
|
|
||||||
TWI_EnableIt(twi, TWI_IER_SVACC);
|
|
||||||
//| TWI_IER_RXRDY | TWI_IER_TXRDY | TWI_IER_TXCOMP);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TwoWire::begin(int address) {
|
|
||||||
begin((uint8_t) address);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TwoWire::end(void) {
|
|
||||||
TWI_Disable(twi);
|
|
||||||
|
|
||||||
// Enable PDC channel
|
|
||||||
twi->TWI_PTCR &= ~(UART_PTCR_RXTDIS | UART_PTCR_TXTDIS);
|
|
||||||
|
|
||||||
if (onEndCallback)
|
|
||||||
onEndCallback();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TwoWire::setClock(uint32_t frequency) {
|
|
||||||
twiClock = frequency;
|
|
||||||
TWI_SetClock(twi, twiClock, VARIANT_MCK);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddress, uint8_t isize, uint8_t sendStop) {
|
|
||||||
if (quantity > BUFFER_LENGTH)
|
|
||||||
quantity = BUFFER_LENGTH;
|
|
||||||
|
|
||||||
// perform blocking read into buffer
|
|
||||||
int readed = 0;
|
|
||||||
TWI_StartRead(twi, address, iaddress, isize);
|
|
||||||
do {
|
|
||||||
// Stop condition must be set during the reception of last byte
|
|
||||||
if (readed + 1 == quantity)
|
|
||||||
TWI_SendSTOPCondition( twi);
|
|
||||||
|
|
||||||
if (TWI_WaitByteReceived(twi, RECV_TIMEOUT))
|
|
||||||
rxBuffer[readed++] = TWI_ReadByte(twi);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
} while (readed < quantity);
|
|
||||||
TWI_WaitTransferComplete(twi, RECV_TIMEOUT);
|
|
||||||
|
|
||||||
// set rx buffer iterator vars
|
|
||||||
rxBufferIndex = 0;
|
|
||||||
rxBufferLength = readed;
|
|
||||||
|
|
||||||
return readed;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) {
|
|
||||||
return requestFrom((uint8_t) address, (uint8_t) quantity, (uint32_t) 0, (uint8_t) 0, (uint8_t) sendStop);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity) {
|
|
||||||
return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) true);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t TwoWire::requestFrom(int address, int quantity) {
|
|
||||||
return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) true);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop) {
|
|
||||||
return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) sendStop);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TwoWire::beginTransmission(uint8_t address) {
|
|
||||||
status = MASTER_SEND;
|
|
||||||
|
|
||||||
// save address of target and empty buffer
|
|
||||||
txAddress = address;
|
|
||||||
txBufferLength = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TwoWire::beginTransmission(int address) {
|
|
||||||
beginTransmission((uint8_t) address);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Originally, 'endTransmission' was an f(void) function.
|
|
||||||
// It has been modified to take one parameter indicating
|
|
||||||
// whether or not a STOP should be performed on the bus.
|
|
||||||
// Calling endTransmission(false) allows a sketch to
|
|
||||||
// perform a repeated start.
|
|
||||||
//
|
|
||||||
// WARNING: Nothing in the library keeps track of whether
|
|
||||||
// the bus tenure has been properly ended with a STOP. It
|
|
||||||
// is very possible to leave the bus in a hung state if
|
|
||||||
// no call to endTransmission(true) is made. Some I2C
|
|
||||||
// devices will behave oddly if they do not see a STOP.
|
|
||||||
//
|
|
||||||
uint8_t TwoWire::endTransmission(uint8_t sendStop) {
|
|
||||||
uint8_t error = 0;
|
|
||||||
// transmit buffer (blocking)
|
|
||||||
TWI_StartWrite(twi, txAddress, 0, 0, txBuffer[0]);
|
|
||||||
if (!TWI_WaitByteSent(twi, XMIT_TIMEOUT))
|
|
||||||
error = 2; // error, got NACK on address transmit
|
|
||||||
|
|
||||||
if (error == 0) {
|
|
||||||
uint16_t sent = 1;
|
|
||||||
while (sent < txBufferLength) {
|
|
||||||
TWI_WriteByte(twi, txBuffer[sent++]);
|
|
||||||
if (!TWI_WaitByteSent(twi, XMIT_TIMEOUT))
|
|
||||||
error = 3; // error, got NACK during data transmmit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error == 0) {
|
|
||||||
TWI_Stop(twi);
|
|
||||||
if (!TWI_WaitTransferComplete(twi, XMIT_TIMEOUT))
|
|
||||||
error = 4; // error, finishing up
|
|
||||||
}
|
|
||||||
|
|
||||||
txBufferLength = 0; // empty buffer
|
|
||||||
status = MASTER_IDLE;
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This provides backwards compatibility with the original
|
|
||||||
// definition, and expected behaviour, of endTransmission
|
|
||||||
//
|
|
||||||
uint8_t TwoWire::endTransmission(void)
|
|
||||||
{
|
|
||||||
return endTransmission(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t TwoWire::write(uint8_t data) {
|
|
||||||
if (status == MASTER_SEND) {
|
|
||||||
if (txBufferLength >= BUFFER_LENGTH)
|
|
||||||
return 0;
|
|
||||||
txBuffer[txBufferLength++] = data;
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
if (srvBufferLength >= BUFFER_LENGTH)
|
|
||||||
return 0;
|
|
||||||
srvBuffer[srvBufferLength++] = data;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t TwoWire::write(const uint8_t *data, size_t quantity) {
|
|
||||||
if (status == MASTER_SEND) {
|
|
||||||
for (size_t i = 0; i < quantity; ++i) {
|
|
||||||
if (txBufferLength >= BUFFER_LENGTH)
|
|
||||||
return i;
|
|
||||||
txBuffer[txBufferLength++] = data[i];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (size_t i = 0; i < quantity; ++i) {
|
|
||||||
if (srvBufferLength >= BUFFER_LENGTH)
|
|
||||||
return i;
|
|
||||||
srvBuffer[srvBufferLength++] = data[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return quantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
int TwoWire::available(void) {
|
|
||||||
return rxBufferLength - rxBufferIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
int TwoWire::read(void) {
|
|
||||||
if (rxBufferIndex < rxBufferLength)
|
|
||||||
return rxBuffer[rxBufferIndex++];
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int TwoWire::peek(void) {
|
|
||||||
if (rxBufferIndex < rxBufferLength)
|
|
||||||
return rxBuffer[rxBufferIndex];
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TwoWire::flush(void) {
|
|
||||||
// Do nothing, use endTransmission(..) to force
|
|
||||||
// data transfer.
|
|
||||||
}
|
|
||||||
|
|
||||||
void TwoWire::onReceive(void(*function)(int)) {
|
|
||||||
onReceiveCallback = function;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TwoWire::onRequest(void(*function)(void)) {
|
|
||||||
onRequestCallback = function;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TwoWire::onService(void) {
|
|
||||||
// Retrieve interrupt status
|
|
||||||
uint32_t sr = TWI_GetStatus(twi);
|
|
||||||
|
|
||||||
if (status == SLAVE_IDLE && TWI_STATUS_SVACC(sr)) {
|
|
||||||
TWI_DisableIt(twi, TWI_IDR_SVACC);
|
|
||||||
TWI_EnableIt(twi, TWI_IER_RXRDY | TWI_IER_GACC | TWI_IER_NACK
|
|
||||||
| TWI_IER_EOSACC | TWI_IER_SCL_WS | TWI_IER_TXCOMP);
|
|
||||||
|
|
||||||
srvBufferLength = 0;
|
|
||||||
srvBufferIndex = 0;
|
|
||||||
|
|
||||||
// Detect if we should go into RECV or SEND status
|
|
||||||
// SVREAD==1 means *master* reading -> SLAVE_SEND
|
|
||||||
if (!TWI_STATUS_SVREAD(sr)) {
|
|
||||||
status = SLAVE_RECV;
|
|
||||||
} else {
|
|
||||||
status = SLAVE_SEND;
|
|
||||||
|
|
||||||
// Alert calling program to generate a response ASAP
|
|
||||||
if (onRequestCallback)
|
|
||||||
onRequestCallback();
|
|
||||||
else
|
|
||||||
// create a default 1-byte response
|
|
||||||
write((uint8_t) 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status != SLAVE_IDLE && TWI_STATUS_EOSACC(sr)) {
|
|
||||||
if (status == SLAVE_RECV && onReceiveCallback) {
|
|
||||||
// Copy data into rxBuffer
|
|
||||||
// (allows to receive another packet while the
|
|
||||||
// user program reads actual data)
|
|
||||||
for (uint8_t i = 0; i < srvBufferLength; ++i)
|
|
||||||
rxBuffer[i] = srvBuffer[i];
|
|
||||||
rxBufferIndex = 0;
|
|
||||||
rxBufferLength = srvBufferLength;
|
|
||||||
|
|
||||||
// Alert calling program
|
|
||||||
onReceiveCallback( rxBufferLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transfer completed
|
|
||||||
TWI_EnableIt(twi, TWI_SR_SVACC);
|
|
||||||
TWI_DisableIt(twi, TWI_IDR_RXRDY | TWI_IDR_GACC | TWI_IDR_NACK
|
|
||||||
| TWI_IDR_EOSACC | TWI_IDR_SCL_WS | TWI_IER_TXCOMP);
|
|
||||||
status = SLAVE_IDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status == SLAVE_RECV) {
|
|
||||||
if (TWI_STATUS_RXRDY(sr)) {
|
|
||||||
if (srvBufferLength < BUFFER_LENGTH)
|
|
||||||
srvBuffer[srvBufferLength++] = TWI_ReadByte(twi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status == SLAVE_SEND) {
|
|
||||||
if (TWI_STATUS_TXRDY(sr) && !TWI_STATUS_NACK(sr)) {
|
|
||||||
uint8_t c = 'x';
|
|
||||||
if (srvBufferIndex < srvBufferLength)
|
|
||||||
c = srvBuffer[srvBufferIndex++];
|
|
||||||
TWI_WriteByte(twi, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if WIRE_INTERFACES_COUNT > 0
|
|
||||||
static void Wire_Init(void) {
|
|
||||||
pmc_enable_periph_clk(WIRE_INTERFACE_ID);
|
|
||||||
PIO_Configure(
|
|
||||||
g_APinDescription[PIN_WIRE_SDA].pPort,
|
|
||||||
g_APinDescription[PIN_WIRE_SDA].ulPinType,
|
|
||||||
g_APinDescription[PIN_WIRE_SDA].ulPin,
|
|
||||||
g_APinDescription[PIN_WIRE_SDA].ulPinConfiguration);
|
|
||||||
PIO_Configure(
|
|
||||||
g_APinDescription[PIN_WIRE_SCL].pPort,
|
|
||||||
g_APinDescription[PIN_WIRE_SCL].ulPinType,
|
|
||||||
g_APinDescription[PIN_WIRE_SCL].ulPin,
|
|
||||||
g_APinDescription[PIN_WIRE_SCL].ulPinConfiguration);
|
|
||||||
|
|
||||||
NVIC_DisableIRQ(WIRE_ISR_ID);
|
|
||||||
NVIC_ClearPendingIRQ(WIRE_ISR_ID);
|
|
||||||
NVIC_SetPriority(WIRE_ISR_ID, 0);
|
|
||||||
NVIC_EnableIRQ(WIRE_ISR_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Wire_Deinit(void) {
|
|
||||||
NVIC_DisableIRQ(WIRE_ISR_ID);
|
|
||||||
NVIC_ClearPendingIRQ(WIRE_ISR_ID);
|
|
||||||
|
|
||||||
pmc_disable_periph_clk(WIRE_INTERFACE_ID);
|
|
||||||
|
|
||||||
// no need to undo PIO_Configure,
|
|
||||||
// as Peripheral A was enable by default before,
|
|
||||||
// and pullups were not enabled
|
|
||||||
}
|
|
||||||
|
|
||||||
TwoWire Wire = TwoWire(WIRE_INTERFACE, Wire_Init, Wire_Deinit);
|
|
||||||
|
|
||||||
void WIRE_ISR_HANDLER(void) {
|
|
||||||
Wire.onService();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if WIRE_INTERFACES_COUNT > 1
|
|
||||||
static void Wire1_Init(void) {
|
|
||||||
pmc_enable_periph_clk(WIRE1_INTERFACE_ID);
|
|
||||||
PIO_Configure(
|
|
||||||
g_APinDescription[PIN_WIRE1_SDA].pPort,
|
|
||||||
g_APinDescription[PIN_WIRE1_SDA].ulPinType,
|
|
||||||
g_APinDescription[PIN_WIRE1_SDA].ulPin,
|
|
||||||
g_APinDescription[PIN_WIRE1_SDA].ulPinConfiguration);
|
|
||||||
PIO_Configure(
|
|
||||||
g_APinDescription[PIN_WIRE1_SCL].pPort,
|
|
||||||
g_APinDescription[PIN_WIRE1_SCL].ulPinType,
|
|
||||||
g_APinDescription[PIN_WIRE1_SCL].ulPin,
|
|
||||||
g_APinDescription[PIN_WIRE1_SCL].ulPinConfiguration);
|
|
||||||
|
|
||||||
NVIC_DisableIRQ(WIRE1_ISR_ID);
|
|
||||||
NVIC_ClearPendingIRQ(WIRE1_ISR_ID);
|
|
||||||
NVIC_SetPriority(WIRE1_ISR_ID, 0);
|
|
||||||
NVIC_EnableIRQ(WIRE1_ISR_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Wire1_Deinit(void) {
|
|
||||||
NVIC_DisableIRQ(WIRE1_ISR_ID);
|
|
||||||
NVIC_ClearPendingIRQ(WIRE1_ISR_ID);
|
|
||||||
|
|
||||||
pmc_disable_periph_clk(WIRE1_INTERFACE_ID);
|
|
||||||
|
|
||||||
// no need to undo PIO_Configure,
|
|
||||||
// as Peripheral A was enable by default before,
|
|
||||||
// and pullups were not enabled
|
|
||||||
}
|
|
||||||
|
|
||||||
TwoWire Wire1 = TwoWire(WIRE1_INTERFACE, Wire1_Init, Wire1_Deinit);
|
|
||||||
|
|
||||||
void WIRE1_ISR_HANDLER(void) {
|
|
||||||
Wire1.onService();
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,127 +0,0 @@
|
|||||||
/*
|
|
||||||
* TwoWire.h - TWI/I2C library for Arduino Due
|
|
||||||
* Copyright (c) 2011 Cristian Maglie <c.maglie@arduino.cc>
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef TwoWire_h
|
|
||||||
#define TwoWire_h
|
|
||||||
|
|
||||||
// Include Atmel CMSIS driver
|
|
||||||
#include <include/twi.h>
|
|
||||||
|
|
||||||
#include "Stream.h"
|
|
||||||
#include "variant.h"
|
|
||||||
|
|
||||||
#define BUFFER_LENGTH 32
|
|
||||||
|
|
||||||
// WIRE_HAS_END means Wire has end()
|
|
||||||
#define WIRE_HAS_END 1
|
|
||||||
|
|
||||||
class TwoWire : public Stream {
|
|
||||||
public:
|
|
||||||
TwoWire(Twi *twi, void(*begin_cb)(void), void(*end_cb)(void));
|
|
||||||
void begin();
|
|
||||||
void begin(uint8_t);
|
|
||||||
void begin(int);
|
|
||||||
void end();
|
|
||||||
void setClock(uint32_t);
|
|
||||||
void beginTransmission(uint8_t);
|
|
||||||
void beginTransmission(int);
|
|
||||||
uint8_t endTransmission(void);
|
|
||||||
uint8_t endTransmission(uint8_t);
|
|
||||||
uint8_t requestFrom(uint8_t, uint8_t);
|
|
||||||
uint8_t requestFrom(uint8_t, uint8_t, uint8_t);
|
|
||||||
uint8_t requestFrom(uint8_t, uint8_t, uint32_t, uint8_t, uint8_t);
|
|
||||||
uint8_t requestFrom(int, int);
|
|
||||||
uint8_t requestFrom(int, int, int);
|
|
||||||
virtual size_t write(uint8_t);
|
|
||||||
virtual size_t write(const uint8_t *, size_t);
|
|
||||||
virtual int available(void);
|
|
||||||
virtual int read(void);
|
|
||||||
virtual int peek(void);
|
|
||||||
virtual void flush(void);
|
|
||||||
void onReceive(void(*)(int));
|
|
||||||
void onRequest(void(*)(void));
|
|
||||||
|
|
||||||
inline size_t write(unsigned long n) { return write((uint8_t)n); }
|
|
||||||
inline size_t write(long n) { return write((uint8_t)n); }
|
|
||||||
inline size_t write(unsigned int n) { return write((uint8_t)n); }
|
|
||||||
inline size_t write(int n) { return write((uint8_t)n); }
|
|
||||||
using Print::write;
|
|
||||||
|
|
||||||
void onService(void);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// RX Buffer
|
|
||||||
uint8_t rxBuffer[BUFFER_LENGTH];
|
|
||||||
uint8_t rxBufferIndex;
|
|
||||||
uint8_t rxBufferLength;
|
|
||||||
|
|
||||||
// TX Buffer
|
|
||||||
uint8_t txAddress;
|
|
||||||
uint8_t txBuffer[BUFFER_LENGTH];
|
|
||||||
uint8_t txBufferLength;
|
|
||||||
|
|
||||||
// Service buffer
|
|
||||||
uint8_t srvBuffer[BUFFER_LENGTH];
|
|
||||||
uint8_t srvBufferIndex;
|
|
||||||
uint8_t srvBufferLength;
|
|
||||||
|
|
||||||
// Callback user functions
|
|
||||||
void (*onRequestCallback)(void);
|
|
||||||
void (*onReceiveCallback)(int);
|
|
||||||
|
|
||||||
// Called before initialization
|
|
||||||
void (*onBeginCallback)(void);
|
|
||||||
|
|
||||||
// Called after deinitialization
|
|
||||||
void (*onEndCallback)(void);
|
|
||||||
|
|
||||||
// TWI instance
|
|
||||||
Twi *twi;
|
|
||||||
|
|
||||||
// TWI state
|
|
||||||
enum TwoWireStatus {
|
|
||||||
UNINITIALIZED,
|
|
||||||
MASTER_IDLE,
|
|
||||||
MASTER_SEND,
|
|
||||||
MASTER_RECV,
|
|
||||||
SLAVE_IDLE,
|
|
||||||
SLAVE_RECV,
|
|
||||||
SLAVE_SEND
|
|
||||||
};
|
|
||||||
TwoWireStatus status;
|
|
||||||
|
|
||||||
// TWI clock frequency
|
|
||||||
static const uint32_t TWI_CLOCK = 100000;
|
|
||||||
uint32_t twiClock;
|
|
||||||
|
|
||||||
// Timeouts (
|
|
||||||
static const uint32_t RECV_TIMEOUT = 100000;
|
|
||||||
static const uint32_t XMIT_TIMEOUT = 100000;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if WIRE_INTERFACES_COUNT > 0
|
|
||||||
extern TwoWire Wire;
|
|
||||||
#endif
|
|
||||||
#if WIRE_INTERFACES_COUNT > 1
|
|
||||||
extern TwoWire Wire1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,108 +0,0 @@
|
|||||||
|
|
||||||
# Arduino SAM Core and platform.
|
|
||||||
# ------------------------------
|
|
||||||
#
|
|
||||||
# For more info:
|
|
||||||
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification
|
|
||||||
|
|
||||||
name=Arduino ARM (32-bits) Boards
|
|
||||||
version=1.6.11
|
|
||||||
|
|
||||||
# SAM3 compile variables
|
|
||||||
# ----------------------
|
|
||||||
|
|
||||||
compiler.warning_flags=-w
|
|
||||||
compiler.warning_flags.none=-w
|
|
||||||
compiler.warning_flags.default=
|
|
||||||
compiler.warning_flags.more=-Wall
|
|
||||||
compiler.warning_flags.all=-Wall -Wextra
|
|
||||||
|
|
||||||
compiler.path={runtime.tools.arm-none-eabi-gcc.path}/bin/
|
|
||||||
compiler.c.cmd=arm-none-eabi-gcc
|
|
||||||
compiler.c.flags=-c -g -Os {compiler.warning_flags} -std=gnu11 -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -Dprintf=iprintf -MMD
|
|
||||||
compiler.c.elf.cmd=arm-none-eabi-gcc
|
|
||||||
compiler.c.elf.flags=-Os -Wl,--gc-sections
|
|
||||||
compiler.S.cmd=arm-none-eabi-gcc
|
|
||||||
compiler.S.flags=-c -g -x assembler-with-cpp -MMD
|
|
||||||
compiler.cpp.cmd=arm-none-eabi-g++
|
|
||||||
compiler.cpp.flags=-c -g -Os {compiler.warning_flags} -std=gnu++11 -ffunction-sections -fdata-sections -nostdlib -fno-threadsafe-statics --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -Dprintf=iprintf -MMD
|
|
||||||
compiler.ar.cmd=arm-none-eabi-ar
|
|
||||||
compiler.ar.flags=rcs
|
|
||||||
compiler.objcopy.cmd=arm-none-eabi-objcopy
|
|
||||||
compiler.objcopy.eep.flags=-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0
|
|
||||||
compiler.elf2hex.flags=-O binary
|
|
||||||
compiler.elf2hex.cmd=arm-none-eabi-objcopy
|
|
||||||
compiler.ldflags=
|
|
||||||
compiler.size.cmd=arm-none-eabi-size
|
|
||||||
compiler.define=-DARDUINO=
|
|
||||||
compiler.combine.flags=-u _sbrk -u link -u _close -u _fstat -u _isatty -u _lseek -u _read -u _write -u _exit -u kill -u _getpid
|
|
||||||
|
|
||||||
# This can be overridden in boards.txt
|
|
||||||
build.extra_flags=
|
|
||||||
|
|
||||||
# These can be overridden in platform.local.txt
|
|
||||||
compiler.c.extra_flags=
|
|
||||||
compiler.c.elf.extra_flags=
|
|
||||||
compiler.cpp.extra_flags=
|
|
||||||
compiler.S.extra_flags=
|
|
||||||
compiler.ar.extra_flags=
|
|
||||||
compiler.elf2hex.extra_flags=
|
|
||||||
|
|
||||||
|
|
||||||
compiler.libsam.c.flags="-I{build.system.path}/libsam" "-I{build.system.path}/CMSIS/CMSIS/Include/" "-I{build.system.path}/CMSIS/Device/ATMEL/"
|
|
||||||
|
|
||||||
# USB Flags
|
|
||||||
# ---------
|
|
||||||
build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} -DUSBCON '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}'
|
|
||||||
|
|
||||||
# Default usb manufacturer will be replaced at compile time using
|
|
||||||
# numeric vendor ID if available or by board's specific value.
|
|
||||||
build.usb_manufacturer="Unknown"
|
|
||||||
|
|
||||||
|
|
||||||
# SAM3 compile patterns
|
|
||||||
# ---------------------
|
|
||||||
|
|
||||||
## Compile c files
|
|
||||||
recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -mcpu={build.mcu} -mthumb -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {compiler.libsam.c.flags} {includes} "{source_file}" -o "{object_file}"
|
|
||||||
|
|
||||||
## Compile c++ files
|
|
||||||
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mcpu={build.mcu} -mthumb -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {compiler.libsam.c.flags} {includes} "{source_file}" -o "{object_file}"
|
|
||||||
|
|
||||||
## Compile S files
|
|
||||||
recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} -mcpu={build.mcu} -mthumb -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {compiler.libsam.c.flags} {includes} "{source_file}" -o "{object_file}"
|
|
||||||
|
|
||||||
## Create archives
|
|
||||||
# archive_file_path is needed for backwards compatibility with IDE 1.6.5 or older, IDE 1.6.6 or newer overrides this value
|
|
||||||
archive_file_path={build.path}/{archive_file}
|
|
||||||
recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}"
|
|
||||||
|
|
||||||
## Combine gc-sections, archives, and objects
|
|
||||||
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" -mcpu={build.mcu} -mthumb {compiler.c.elf.flags} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--start-group {compiler.combine.flags} {object_files} "{build.variant.path}/{build.variant_system_lib}" "{build.path}/{archive_file}" -Wl,--end-group -lm -gcc
|
|
||||||
|
|
||||||
## Create output (.bin file)
|
|
||||||
recipe.objcopy.bin.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin"
|
|
||||||
|
|
||||||
## Save hex
|
|
||||||
recipe.output.tmp_file={build.project_name}.bin
|
|
||||||
recipe.output.save_file={build.project_name}.{build.variant}.bin
|
|
||||||
|
|
||||||
## Compute size
|
|
||||||
recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf"
|
|
||||||
recipe.size.regex=\.text\s+([0-9]+).*
|
|
||||||
|
|
||||||
|
|
||||||
# SAM3 Uploader tools
|
|
||||||
# -------------------
|
|
||||||
|
|
||||||
# BOSSA
|
|
||||||
tools.bossac.path={runtime.tools.bossac.path}
|
|
||||||
tools.bossac.cmd=bossac
|
|
||||||
tools.bossac.cmd.windows=bossac.exe
|
|
||||||
|
|
||||||
tools.bossac.upload.params.verbose=-i -d
|
|
||||||
tools.bossac.upload.params.quiet=
|
|
||||||
tools.bossac.upload.params.verify=-v
|
|
||||||
tools.bossac.upload.pattern="{path}/{cmd}" {upload.verbose} --port={serial.port.file} -U {upload.native_usb} -e -w {upload.verify} -b "{build.path}/{build.project_name}.bin" -R
|
|
||||||
|
|
||||||
tools.bossac_remote.upload.pattern=/usr/bin/run-bossac {upload.verbose} --port=ttyATH0 -U {upload.native_usb} -e -w -v -b /tmp/sketch.bin -R
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user