initial
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<CodeBlocks_project_file>
|
||||
<FileVersion major="1" minor="6" />
|
||||
<Project>
|
||||
<Option title="UltiLCD2_Sim" />
|
||||
<Option pch_mode="2" />
|
||||
<Option compiler="gcc" />
|
||||
<Build>
|
||||
<Target title="Debug">
|
||||
<Option output=".bin/Debug/UltiLCD2_Sim" prefix_auto="1" extension_auto="1" />
|
||||
<Option object_output=".obj/Debug/" />
|
||||
<Option type="1" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-g" />
|
||||
</Compiler>
|
||||
</Target>
|
||||
<Target title="Release">
|
||||
<Option output=".bin/Release/UltiLCD2_Sim" prefix_auto="1" extension_auto="1" />
|
||||
<Option object_output=".obj/Release/" />
|
||||
<Option type="1" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-O2" />
|
||||
<Add option="-Wno-strict-aliasing" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-s" />
|
||||
</Linker>
|
||||
</Target>
|
||||
</Build>
|
||||
<Compiler>
|
||||
<Add option="-Wall" />
|
||||
<Add option="-D__AVR_ATmega2560__=1" />
|
||||
<Add option="-DARDUINO=100" />
|
||||
<Add option="-DF_CPU=16000000" />
|
||||
<Add directory="arduino_sim" />
|
||||
<Add directory="avr_sim" />
|
||||
<Add directory="C:/Software/SecretMarlin/UltiLCD2_Sim/" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add library="SDLmain" />
|
||||
<Add library="SDL" />
|
||||
</Linker>
|
||||
<Unit filename="../Marlin/Configuration.h" />
|
||||
<Unit filename="../Marlin/ConfigurationStore.cpp" />
|
||||
<Unit filename="../Marlin/ConfigurationStore.h" />
|
||||
<Unit filename="../Marlin/Configuration_adv.h" />
|
||||
<Unit filename="../Marlin/Marlin.h" />
|
||||
<Unit filename="../Marlin/MarlinSerial.cpp" />
|
||||
<Unit filename="../Marlin/MarlinSerial.h" />
|
||||
<Unit filename="../Marlin/Marlin_main.cpp" />
|
||||
<Unit filename="../Marlin/Sd2Card.cpp" />
|
||||
<Unit filename="../Marlin/Sd2Card.h" />
|
||||
<Unit filename="../Marlin/Sd2PinMap.h" />
|
||||
<Unit filename="../Marlin/SdBaseFile.cpp" />
|
||||
<Unit filename="../Marlin/SdBaseFile.h" />
|
||||
<Unit filename="../Marlin/SdFatConfig.h" />
|
||||
<Unit filename="../Marlin/SdFatStructs.h" />
|
||||
<Unit filename="../Marlin/SdFatUtil.cpp" />
|
||||
<Unit filename="../Marlin/SdFatUtil.h" />
|
||||
<Unit filename="../Marlin/SdFile.cpp" />
|
||||
<Unit filename="../Marlin/SdFile.h" />
|
||||
<Unit filename="../Marlin/SdInfo.h" />
|
||||
<Unit filename="../Marlin/SdVolume.cpp" />
|
||||
<Unit filename="../Marlin/SdVolume.h" />
|
||||
<Unit filename="../Marlin/UltiLCD2.cpp" />
|
||||
<Unit filename="../Marlin/UltiLCD2.h" />
|
||||
<Unit filename="../Marlin/UltiLCD2_gfx.cpp" />
|
||||
<Unit filename="../Marlin/UltiLCD2_gfx.h" />
|
||||
<Unit filename="../Marlin/UltiLCD2_hi_lib.cpp" />
|
||||
<Unit filename="../Marlin/UltiLCD2_hi_lib.h" />
|
||||
<Unit filename="../Marlin/UltiLCD2_low_lib.cpp" />
|
||||
<Unit filename="../Marlin/UltiLCD2_low_lib.h" />
|
||||
<Unit filename="../Marlin/UltiLCD2_menu_first_run.cpp" />
|
||||
<Unit filename="../Marlin/UltiLCD2_menu_first_run.h" />
|
||||
<Unit filename="../Marlin/UltiLCD2_menu_maintenance.cpp" />
|
||||
<Unit filename="../Marlin/UltiLCD2_menu_maintenance.h" />
|
||||
<Unit filename="../Marlin/UltiLCD2_menu_material.cpp" />
|
||||
<Unit filename="../Marlin/UltiLCD2_menu_material.h" />
|
||||
<Unit filename="../Marlin/UltiLCD2_menu_print.cpp" />
|
||||
<Unit filename="../Marlin/UltiLCD2_menu_print.h" />
|
||||
<Unit filename="../Marlin/cardreader.cpp" />
|
||||
<Unit filename="../Marlin/cardreader.h" />
|
||||
<Unit filename="../Marlin/electronics_test.cpp" />
|
||||
<Unit filename="../Marlin/electronics_test.h" />
|
||||
<Unit filename="../Marlin/fastio.h" />
|
||||
<Unit filename="../Marlin/lifetime_stats.cpp" />
|
||||
<Unit filename="../Marlin/lifetime_stats.h" />
|
||||
<Unit filename="../Marlin/motion_control.cpp" />
|
||||
<Unit filename="../Marlin/motion_control.h" />
|
||||
<Unit filename="../Marlin/pins.h" />
|
||||
<Unit filename="../Marlin/planner.cpp" />
|
||||
<Unit filename="../Marlin/planner.h" />
|
||||
<Unit filename="../Marlin/speed_lookuptable.h" />
|
||||
<Unit filename="../Marlin/stepper.cpp" />
|
||||
<Unit filename="../Marlin/stepper.h" />
|
||||
<Unit filename="../Marlin/temperature.cpp" />
|
||||
<Unit filename="../Marlin/temperature.h" />
|
||||
<Unit filename="../Marlin/thermistortables.h" />
|
||||
<Unit filename="../Marlin/ultralcd.cpp" />
|
||||
<Unit filename="../Marlin/ultralcd.h" />
|
||||
<Unit filename="../Marlin/ultralcd_implementation_hitachi_HD44780.h" />
|
||||
<Unit filename="../Marlin/ultralcd_implementation_ultiboard_v2.h" />
|
||||
<Unit filename="../Marlin/ultralcd_st7920_u8glib_rrd.h" />
|
||||
<Unit filename="../Marlin/watchdog.cpp" />
|
||||
<Unit filename="../Marlin/watchdog.h" />
|
||||
<Unit filename="arduino_sim/Arduino.h" />
|
||||
<Unit filename="arduino_sim/HardwareSerial.cpp" />
|
||||
<Unit filename="arduino_sim/HardwareSerial.h" />
|
||||
<Unit filename="arduino_sim/LiquidCrystal.cpp" />
|
||||
<Unit filename="arduino_sim/LiquidCrystal.h" />
|
||||
<Unit filename="arduino_sim/Print.cpp" />
|
||||
<Unit filename="arduino_sim/Print.h" />
|
||||
<Unit filename="arduino_sim/Printable.h" />
|
||||
<Unit filename="arduino_sim/Stream.cpp" />
|
||||
<Unit filename="arduino_sim/Stream.h" />
|
||||
<Unit filename="arduino_sim/Tone.cpp" />
|
||||
<Unit filename="arduino_sim/WCharacter.h" />
|
||||
<Unit filename="arduino_sim/WString.cpp" />
|
||||
<Unit filename="arduino_sim/WString.h" />
|
||||
<Unit filename="arduino_sim/binary.h" />
|
||||
<Unit filename="arduino_sim/main.cpp" />
|
||||
<Unit filename="arduino_sim/new.cpp" />
|
||||
<Unit filename="arduino_sim/new.h" />
|
||||
<Unit filename="arduino_sim/pins_arduino.h" />
|
||||
<Unit filename="arduino_sim/wiring.cpp">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="arduino_sim/wiring_analog.cpp">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="arduino_sim/wiring_digital.cpp">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="arduino_sim/wiring_private.h" />
|
||||
<Unit filename="arduino_sim/wiring_pulse.cpp">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="arduino_sim/wiring_shift.cpp">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="avr_sim/avr/eeprom.h" />
|
||||
<Unit filename="avr_sim/avr/interrupt.h" />
|
||||
<Unit filename="avr_sim/avr/io.h" />
|
||||
<Unit filename="avr_sim/avr/iom2560.h" />
|
||||
<Unit filename="avr_sim/avr/iomxx0_1.h" />
|
||||
<Unit filename="avr_sim/avr/pgmspace.h" />
|
||||
<Unit filename="avr_sim/avr/sim_io.cpp" />
|
||||
<Unit filename="avr_sim/avr/wdt.h" />
|
||||
<Unit filename="avr_sim/util/delay.h" />
|
||||
<Unit filename="component/adc.cpp" />
|
||||
<Unit filename="component/adc.h" />
|
||||
<Unit filename="component/arduinoIO.cpp" />
|
||||
<Unit filename="component/arduinoIO.h" />
|
||||
<Unit filename="component/base.cpp" />
|
||||
<Unit filename="component/base.h" />
|
||||
<Unit filename="component/delegate.h" />
|
||||
<Unit filename="component/display_HD44780.cpp" />
|
||||
<Unit filename="component/display_HD44780.h" />
|
||||
<Unit filename="component/display_SSD1309.cpp" />
|
||||
<Unit filename="component/display_SSD1309.h" />
|
||||
<Unit filename="component/heater.cpp" />
|
||||
<Unit filename="component/heater.h" />
|
||||
<Unit filename="component/i2c.cpp" />
|
||||
<Unit filename="component/i2c.h" />
|
||||
<Unit filename="component/led_PCA9632.cpp" />
|
||||
<Unit filename="component/led_PCA9632.h" />
|
||||
<Unit filename="component/sdcard.cpp" />
|
||||
<Unit filename="component/sdcard.h" />
|
||||
<Unit filename="component/serial.cpp" />
|
||||
<Unit filename="component/serial.h" />
|
||||
<Unit filename="component/stepper.cpp" />
|
||||
<Unit filename="component/stepper.h" />
|
||||
<Unit filename="sim_main.cpp" />
|
||||
<Extensions>
|
||||
<code_completion />
|
||||
<envvars />
|
||||
<debugger />
|
||||
<lib_finder disable_auto="1" />
|
||||
<DoxyBlocks>
|
||||
<comment_style block="0" line="0" />
|
||||
<doxyfile_project />
|
||||
<doxyfile_build />
|
||||
<doxyfile_warnings />
|
||||
<doxyfile_output />
|
||||
<doxyfile_dot />
|
||||
<general />
|
||||
</DoxyBlocks>
|
||||
</Extensions>
|
||||
</Project>
|
||||
</CodeBlocks_project_file>
|
||||
@@ -0,0 +1,215 @@
|
||||
#ifndef Arduino_h
|
||||
#define Arduino_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#include "binary.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#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 SERIAL 0x0
|
||||
#define DISPLAY 0x1
|
||||
|
||||
#define LSBFIRST 0
|
||||
#define MSBFIRST 1
|
||||
|
||||
#define CHANGE 1
|
||||
#define FALLING 2
|
||||
#define RISING 3
|
||||
|
||||
#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
|
||||
#define DEFAULT 0
|
||||
#define EXTERNAL 1
|
||||
#define INTERNAL 2
|
||||
#else
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284P__)
|
||||
#define INTERNAL1V1 2
|
||||
#define INTERNAL2V56 3
|
||||
#else
|
||||
#define INTERNAL 3
|
||||
#endif
|
||||
#define DEFAULT 1
|
||||
#define EXTERNAL 0
|
||||
#endif
|
||||
|
||||
// undefine stdlib's abs if encountered
|
||||
#ifdef abs
|
||||
#undef abs
|
||||
#endif
|
||||
|
||||
#define min(a,b) ((a)<(b)?(a):(b))
|
||||
#define max(a,b) ((a)>(b)?(a):(b))
|
||||
#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() sei()
|
||||
#define noInterrupts() cli()
|
||||
|
||||
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
|
||||
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
|
||||
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
|
||||
|
||||
#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 uint8_t boolean;
|
||||
typedef uint8_t byte;
|
||||
|
||||
void init(void);
|
||||
|
||||
void pinMode(uint8_t, uint8_t);
|
||||
void digitalWrite(uint8_t, uint8_t);
|
||||
int digitalRead(uint8_t);
|
||||
int analogRead(uint8_t);
|
||||
void analogReference(uint8_t mode);
|
||||
void analogWrite(uint8_t, int);
|
||||
|
||||
unsigned long millis(void);
|
||||
unsigned long micros(void);
|
||||
void delay(unsigned long);
|
||||
void delayMicroseconds(unsigned int us);
|
||||
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);
|
||||
|
||||
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
|
||||
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder);
|
||||
|
||||
void attachInterrupt(uint8_t, void (*)(void), int mode);
|
||||
void detachInterrupt(uint8_t);
|
||||
|
||||
void setup(void);
|
||||
void loop(void);
|
||||
|
||||
// Get the bit location within the hardware port of the given virtual pin.
|
||||
// This comes from the pins_*.c file for the active board configuration.
|
||||
|
||||
#define analogInPinToBit(P) (P)
|
||||
|
||||
// On the ATmega1280, the addresses of some of the port registers are
|
||||
// greater than 255, so we can't store them in uint8_t's.
|
||||
extern const AVRRegistor* PROGMEM port_to_mode_PGM[];
|
||||
extern const AVRRegistor* PROGMEM port_to_input_PGM[];
|
||||
extern const AVRRegistor* PROGMEM port_to_output_PGM[];
|
||||
|
||||
extern const uint8_t PROGMEM digital_pin_to_port_PGM[];
|
||||
// extern const uint8_t PROGMEM digital_pin_to_bit_PGM[];
|
||||
extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[];
|
||||
extern const uint8_t PROGMEM digital_pin_to_timer_PGM[];
|
||||
|
||||
// Get the bit location within the hardware port of the given virtual pin.
|
||||
// This comes from the pins_*.c file for the active board configuration.
|
||||
//
|
||||
// These perform slightly better as macros compared to inline functions
|
||||
//
|
||||
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
|
||||
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
|
||||
#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) )
|
||||
#define analogInPinToBit(P) (P)
|
||||
#define portOutputRegister(P) ( (AVRRegistor *)( port_to_output_PGM[P]))
|
||||
#define portInputRegister(P) ( (AVRRegistor *)( port_to_input_PGM[P]))
|
||||
#define portModeRegister(P) ( (AVRRegistor *)( port_to_mode_PGM[P]))
|
||||
|
||||
#define NOT_A_PIN 0
|
||||
#define NOT_A_PORT 0
|
||||
|
||||
#ifdef ARDUINO_MAIN
|
||||
#define PA 1
|
||||
#define PB 2
|
||||
#define PC 3
|
||||
#define PD 4
|
||||
#define PE 5
|
||||
#define PF 6
|
||||
#define PG 7
|
||||
#define PH 8
|
||||
#define PJ 10
|
||||
#define PK 11
|
||||
#define PL 12
|
||||
#endif
|
||||
|
||||
#define NOT_ON_TIMER 0
|
||||
#define TIMER0A 1
|
||||
#define TIMER0B 2
|
||||
#define TIMER1A 3
|
||||
#define TIMER1B 4
|
||||
#define TIMER2 5
|
||||
#define TIMER2A 6
|
||||
#define TIMER2B 7
|
||||
|
||||
#define TIMER3A 8
|
||||
#define TIMER3B 9
|
||||
#define TIMER3C 10
|
||||
#define TIMER4A 11
|
||||
#define TIMER4B 12
|
||||
#define TIMER4C 13
|
||||
#define TIMER4D 14
|
||||
#define TIMER5A 15
|
||||
#define TIMER5B 16
|
||||
#define TIMER5C 17
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "WCharacter.h"
|
||||
#include "WString.h"
|
||||
#include "HardwareSerial.h"
|
||||
|
||||
uint16_t makeWord(uint16_t w);
|
||||
uint16_t makeWord(byte h, byte l);
|
||||
|
||||
#define word(...) makeWord(__VA_ARGS__)
|
||||
|
||||
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
|
||||
|
||||
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0);
|
||||
void noTone(uint8_t _pin);
|
||||
|
||||
// WMath prototypes
|
||||
long random(long);
|
||||
long random(long, long);
|
||||
void randomSeed(unsigned int);
|
||||
long map(long, long, long, long, long);
|
||||
|
||||
#endif
|
||||
|
||||
#include "pins_arduino.h"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,430 @@
|
||||
/*
|
||||
HardwareSerial.cpp - Hardware serial library for Wiring
|
||||
Copyright (c) 2006 Nicholas Zambetti. 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 28 September 2010 by Mark Sproul
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include "Arduino.h"
|
||||
#include "wiring_private.h"
|
||||
|
||||
#if 0
|
||||
// this next line disables the entire HardwareSerial.cpp,
|
||||
// this is so I can support Attiny series and any other chip without a uart
|
||||
#if defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H)
|
||||
|
||||
#include "HardwareSerial.h"
|
||||
|
||||
// Define constants and variables for buffering incoming serial data. We're
|
||||
// using a ring buffer (I think), 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.
|
||||
#if (RAMEND < 1000)
|
||||
#define SERIAL_BUFFER_SIZE 16
|
||||
#else
|
||||
#define SERIAL_BUFFER_SIZE 64
|
||||
#endif
|
||||
|
||||
struct ring_buffer
|
||||
{
|
||||
unsigned char buffer[SERIAL_BUFFER_SIZE];
|
||||
volatile unsigned int head;
|
||||
volatile unsigned int tail;
|
||||
};
|
||||
|
||||
#if defined(USBCON)
|
||||
ring_buffer rx_buffer = { { 0 }, 0, 0};
|
||||
ring_buffer tx_buffer = { { 0 }, 0, 0};
|
||||
#endif
|
||||
#if defined(UBRRH) || defined(UBRR0H)
|
||||
ring_buffer rx_buffer = { { 0 }, 0, 0 };
|
||||
ring_buffer tx_buffer = { { 0 }, 0, 0 };
|
||||
#endif
|
||||
#if defined(UBRR1H)
|
||||
ring_buffer rx_buffer1 = { { 0 }, 0, 0 };
|
||||
ring_buffer tx_buffer1 = { { 0 }, 0, 0 };
|
||||
#endif
|
||||
#if defined(UBRR2H)
|
||||
ring_buffer rx_buffer2 = { { 0 }, 0, 0 };
|
||||
ring_buffer tx_buffer2 = { { 0 }, 0, 0 };
|
||||
#endif
|
||||
#if defined(UBRR3H)
|
||||
ring_buffer rx_buffer3 = { { 0 }, 0, 0 };
|
||||
ring_buffer tx_buffer3 = { { 0 }, 0, 0 };
|
||||
#endif
|
||||
|
||||
inline void store_char(unsigned char c, ring_buffer *buffer)
|
||||
{
|
||||
int i = (unsigned int)(buffer->head + 1) % SERIAL_BUFFER_SIZE;
|
||||
|
||||
// if we should be storing the received character into the location
|
||||
// just before the tail (meaning that the head would advance to the
|
||||
// current location of the tail), we're about to overflow the buffer
|
||||
// and so we don't write the character or advance the head.
|
||||
if (i != buffer->tail) {
|
||||
buffer->buffer[buffer->head] = c;
|
||||
buffer->head = i;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(USART0_RX_vect) && defined(USART1_RX_vect)
|
||||
// do nothing - on the 32u4 the first USART is USART1
|
||||
#else
|
||||
#if !defined(USART_RX_vect) && !defined(SIG_USART0_RECV) && \
|
||||
!defined(SIG_UART0_RECV) && !defined(USART0_RX_vect) && \
|
||||
!defined(SIG_UART_RECV)
|
||||
#error "Don't know what the Data Received vector is called for the first UART"
|
||||
#else
|
||||
void serialEvent() __attribute__((weak));
|
||||
void serialEvent() {}
|
||||
#define serialEvent_implemented
|
||||
#if defined(USART_RX_vect)
|
||||
SIGNAL(USART_RX_vect)
|
||||
#elif defined(SIG_USART0_RECV)
|
||||
SIGNAL(SIG_USART0_RECV)
|
||||
#elif defined(SIG_UART0_RECV)
|
||||
SIGNAL(SIG_UART0_RECV)
|
||||
#elif defined(USART0_RX_vect)
|
||||
SIGNAL(USART0_RX_vect)
|
||||
#elif defined(SIG_UART_RECV)
|
||||
SIGNAL(SIG_UART_RECV)
|
||||
#endif
|
||||
{
|
||||
#if defined(UDR0)
|
||||
unsigned char c = UDR0;
|
||||
#elif defined(UDR)
|
||||
unsigned char c = UDR;
|
||||
#else
|
||||
#error UDR not defined
|
||||
#endif
|
||||
store_char(c, &rx_buffer);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(USART1_RX_vect)
|
||||
void serialEvent1() __attribute__((weak));
|
||||
void serialEvent1() {}
|
||||
#define serialEvent1_implemented
|
||||
SIGNAL(USART1_RX_vect)
|
||||
{
|
||||
unsigned char c = UDR1;
|
||||
store_char(c, &rx_buffer1);
|
||||
}
|
||||
#elif defined(SIG_USART1_RECV)
|
||||
#error SIG_USART1_RECV
|
||||
#endif
|
||||
|
||||
#if defined(USART2_RX_vect) && defined(UDR2)
|
||||
void serialEvent2() __attribute__((weak));
|
||||
void serialEvent2() {}
|
||||
#define serialEvent2_implemented
|
||||
SIGNAL(USART2_RX_vect)
|
||||
{
|
||||
unsigned char c = UDR2;
|
||||
store_char(c, &rx_buffer2);
|
||||
}
|
||||
#elif defined(SIG_USART2_RECV)
|
||||
#error SIG_USART2_RECV
|
||||
#endif
|
||||
|
||||
#if defined(USART3_RX_vect) && defined(UDR3)
|
||||
void serialEvent3() __attribute__((weak));
|
||||
void serialEvent3() {}
|
||||
#define serialEvent3_implemented
|
||||
SIGNAL(USART3_RX_vect)
|
||||
{
|
||||
unsigned char c = UDR3;
|
||||
store_char(c, &rx_buffer3);
|
||||
}
|
||||
#elif defined(SIG_USART3_RECV)
|
||||
#error SIG_USART3_RECV
|
||||
#endif
|
||||
|
||||
void serialEventRun(void)
|
||||
{
|
||||
#ifdef serialEvent_implemented
|
||||
if (Serial.available()) serialEvent();
|
||||
#endif
|
||||
#ifdef serialEvent1_implemented
|
||||
if (Serial1.available()) serialEvent1();
|
||||
#endif
|
||||
#ifdef serialEvent2_implemented
|
||||
if (Serial2.available()) serialEvent2();
|
||||
#endif
|
||||
#ifdef serialEvent3_implemented
|
||||
if (Serial3.available()) serialEvent3();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if !defined(USART0_UDRE_vect) && defined(USART1_UDRE_vect)
|
||||
// do nothing - on the 32u4 the first USART is USART1
|
||||
#else
|
||||
#if !defined(UART0_UDRE_vect) && !defined(UART_UDRE_vect) && !defined(USART0_UDRE_vect) && !defined(USART_UDRE_vect)
|
||||
#error "Don't know what the Data Register Empty vector is called for the first UART"
|
||||
#else
|
||||
#if defined(UART0_UDRE_vect)
|
||||
ISR(UART0_UDRE_vect)
|
||||
#elif defined(UART_UDRE_vect)
|
||||
ISR(UART_UDRE_vect)
|
||||
#elif defined(USART0_UDRE_vect)
|
||||
ISR(USART0_UDRE_vect)
|
||||
#elif defined(USART_UDRE_vect)
|
||||
ISR(USART_UDRE_vect)
|
||||
#endif
|
||||
{
|
||||
if (tx_buffer.head == tx_buffer.tail) {
|
||||
// Buffer empty, so disable interrupts
|
||||
#if defined(UCSR0B)
|
||||
cbi(UCSR0B, UDRIE0);
|
||||
#else
|
||||
cbi(UCSRB, UDRIE);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
// There is more data in the output buffer. Send the next byte
|
||||
unsigned char c = tx_buffer.buffer[tx_buffer.tail];
|
||||
tx_buffer.tail = (tx_buffer.tail + 1) % SERIAL_BUFFER_SIZE;
|
||||
|
||||
#if defined(UDR0)
|
||||
UDR0 = c;
|
||||
#elif defined(UDR)
|
||||
UDR = c;
|
||||
#else
|
||||
#error UDR not defined
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USART1_UDRE_vect
|
||||
ISR(USART1_UDRE_vect)
|
||||
{
|
||||
if (tx_buffer1.head == tx_buffer1.tail) {
|
||||
// Buffer empty, so disable interrupts
|
||||
cbi(UCSR1B, UDRIE1);
|
||||
}
|
||||
else {
|
||||
// There is more data in the output buffer. Send the next byte
|
||||
unsigned char c = tx_buffer1.buffer[tx_buffer1.tail];
|
||||
tx_buffer1.tail = (tx_buffer1.tail + 1) % SERIAL_BUFFER_SIZE;
|
||||
|
||||
UDR1 = c;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USART2_UDRE_vect
|
||||
ISR(USART2_UDRE_vect)
|
||||
{
|
||||
if (tx_buffer2.head == tx_buffer2.tail) {
|
||||
// Buffer empty, so disable interrupts
|
||||
cbi(UCSR2B, UDRIE2);
|
||||
}
|
||||
else {
|
||||
// There is more data in the output buffer. Send the next byte
|
||||
unsigned char c = tx_buffer2.buffer[tx_buffer2.tail];
|
||||
tx_buffer2.tail = (tx_buffer2.tail + 1) % SERIAL_BUFFER_SIZE;
|
||||
|
||||
UDR2 = c;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USART3_UDRE_vect
|
||||
ISR(USART3_UDRE_vect)
|
||||
{
|
||||
if (tx_buffer3.head == tx_buffer3.tail) {
|
||||
// Buffer empty, so disable interrupts
|
||||
cbi(UCSR3B, UDRIE3);
|
||||
}
|
||||
else {
|
||||
// There is more data in the output buffer. Send the next byte
|
||||
unsigned char c = tx_buffer3.buffer[tx_buffer3.tail];
|
||||
tx_buffer3.tail = (tx_buffer3.tail + 1) % SERIAL_BUFFER_SIZE;
|
||||
|
||||
UDR3 = c;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Constructors ////////////////////////////////////////////////////////////////
|
||||
|
||||
HardwareSerial::HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer,
|
||||
volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
|
||||
volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
|
||||
volatile uint8_t *udr,
|
||||
uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x)
|
||||
{
|
||||
_rx_buffer = rx_buffer;
|
||||
_tx_buffer = tx_buffer;
|
||||
_ubrrh = ubrrh;
|
||||
_ubrrl = ubrrl;
|
||||
_ucsra = ucsra;
|
||||
_ucsrb = ucsrb;
|
||||
_udr = udr;
|
||||
_rxen = rxen;
|
||||
_txen = txen;
|
||||
_rxcie = rxcie;
|
||||
_udrie = udrie;
|
||||
_u2x = u2x;
|
||||
}
|
||||
|
||||
// Public Methods //////////////////////////////////////////////////////////////
|
||||
|
||||
void HardwareSerial::begin(unsigned long baud)
|
||||
{
|
||||
uint16_t baud_setting;
|
||||
bool use_u2x = true;
|
||||
|
||||
#if F_CPU == 16000000UL
|
||||
// hardcoded exception for compatibility with the bootloader shipped
|
||||
// with the Duemilanove and previous boards and the firmware on the 8U2
|
||||
// on the Uno and Mega 2560.
|
||||
if (baud == 57600) {
|
||||
use_u2x = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
try_again:
|
||||
|
||||
if (use_u2x) {
|
||||
*_ucsra = 1 << _u2x;
|
||||
baud_setting = (F_CPU / 4 / baud - 1) / 2;
|
||||
} else {
|
||||
*_ucsra = 0;
|
||||
baud_setting = (F_CPU / 8 / baud - 1) / 2;
|
||||
}
|
||||
|
||||
if ((baud_setting > 4095) && use_u2x)
|
||||
{
|
||||
use_u2x = false;
|
||||
goto try_again;
|
||||
}
|
||||
|
||||
// assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)
|
||||
*_ubrrh = baud_setting >> 8;
|
||||
*_ubrrl = baud_setting;
|
||||
|
||||
sbi(*_ucsrb, _rxen);
|
||||
sbi(*_ucsrb, _txen);
|
||||
sbi(*_ucsrb, _rxcie);
|
||||
cbi(*_ucsrb, _udrie);
|
||||
}
|
||||
|
||||
void HardwareSerial::end()
|
||||
{
|
||||
// wait for transmission of outgoing data
|
||||
while (_tx_buffer->head != _tx_buffer->tail)
|
||||
;
|
||||
|
||||
cbi(*_ucsrb, _rxen);
|
||||
cbi(*_ucsrb, _txen);
|
||||
cbi(*_ucsrb, _rxcie);
|
||||
cbi(*_ucsrb, _udrie);
|
||||
|
||||
// clear any received data
|
||||
_rx_buffer->head = _rx_buffer->tail;
|
||||
}
|
||||
|
||||
int HardwareSerial::available(void)
|
||||
{
|
||||
return (unsigned int)(SERIAL_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % SERIAL_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
int HardwareSerial::peek(void)
|
||||
{
|
||||
if (_rx_buffer->head == _rx_buffer->tail) {
|
||||
return -1;
|
||||
} else {
|
||||
return _rx_buffer->buffer[_rx_buffer->tail];
|
||||
}
|
||||
}
|
||||
|
||||
int HardwareSerial::read(void)
|
||||
{
|
||||
// if the head isn't ahead of the tail, we don't have any characters
|
||||
if (_rx_buffer->head == _rx_buffer->tail) {
|
||||
return -1;
|
||||
} else {
|
||||
unsigned char c = _rx_buffer->buffer[_rx_buffer->tail];
|
||||
_rx_buffer->tail = (unsigned int)(_rx_buffer->tail + 1) % SERIAL_BUFFER_SIZE;
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
void HardwareSerial::flush()
|
||||
{
|
||||
while (_tx_buffer->head != _tx_buffer->tail)
|
||||
;
|
||||
}
|
||||
|
||||
size_t HardwareSerial::write(uint8_t c)
|
||||
{
|
||||
int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE;
|
||||
|
||||
// If the output buffer is full, there's nothing for it other than to
|
||||
// wait for the interrupt handler to empty it a bit
|
||||
// ???: return 0 here instead?
|
||||
while (i == _tx_buffer->tail)
|
||||
;
|
||||
|
||||
_tx_buffer->buffer[_tx_buffer->head] = c;
|
||||
_tx_buffer->head = i;
|
||||
|
||||
sbi(*_ucsrb, _udrie);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
HardwareSerial::operator bool() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Preinstantiate Objects //////////////////////////////////////////////////////
|
||||
|
||||
#if defined(UBRRH) && defined(UBRRL)
|
||||
HardwareSerial Serial(&rx_buffer, &tx_buffer, &UBRRH, &UBRRL, &UCSRA, &UCSRB, &UDR, RXEN, TXEN, RXCIE, UDRIE, U2X);
|
||||
#elif defined(UBRR0H) && defined(UBRR0L)
|
||||
HardwareSerial Serial(&rx_buffer, &tx_buffer, &UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UDR0, RXEN0, TXEN0, RXCIE0, UDRIE0, U2X0);
|
||||
#elif defined(USBCON)
|
||||
// do nothing - Serial object and buffers are initialized in CDC code
|
||||
#else
|
||||
#error no serial port defined (port 0)
|
||||
#endif
|
||||
|
||||
#if defined(UBRR1H)
|
||||
HardwareSerial Serial1(&rx_buffer1, &tx_buffer1, &UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UDR1, RXEN1, TXEN1, RXCIE1, UDRIE1, U2X1);
|
||||
#endif
|
||||
#if defined(UBRR2H)
|
||||
HardwareSerial Serial2(&rx_buffer2, &tx_buffer2, &UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UDR2, RXEN2, TXEN2, RXCIE2, UDRIE2, U2X2);
|
||||
#endif
|
||||
#if defined(UBRR3H)
|
||||
HardwareSerial Serial3(&rx_buffer3, &tx_buffer3, &UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UDR3, RXEN3, TXEN3, RXCIE3, UDRIE3, U2X3);
|
||||
#endif
|
||||
|
||||
#endif // whole file
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
HardwareSerial.h - Hardware serial library for Wiring
|
||||
Copyright (c) 2006 Nicholas Zambetti. 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 28 September 2010 by Mark Sproul
|
||||
*/
|
||||
|
||||
#ifndef HardwareSerial_h
|
||||
#define HardwareSerial_h
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "Stream.h"
|
||||
|
||||
struct ring_buffer;
|
||||
|
||||
class HardwareSerial : public Stream
|
||||
{
|
||||
private:
|
||||
ring_buffer *_rx_buffer;
|
||||
ring_buffer *_tx_buffer;
|
||||
volatile uint8_t *_ubrrh;
|
||||
volatile uint8_t *_ubrrl;
|
||||
volatile uint8_t *_ucsra;
|
||||
volatile uint8_t *_ucsrb;
|
||||
volatile uint8_t *_udr;
|
||||
uint8_t _rxen;
|
||||
uint8_t _txen;
|
||||
uint8_t _rxcie;
|
||||
uint8_t _udrie;
|
||||
uint8_t _u2x;
|
||||
public:
|
||||
HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer,
|
||||
volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
|
||||
volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
|
||||
volatile uint8_t *udr,
|
||||
uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x);
|
||||
void begin(unsigned long);
|
||||
void end();
|
||||
virtual int available(void);
|
||||
virtual int peek(void);
|
||||
virtual int read(void);
|
||||
virtual void flush(void);
|
||||
virtual size_t write(uint8_t);
|
||||
using Print::write; // pull in write(str) and write(buf, size) from Print
|
||||
operator bool();
|
||||
};
|
||||
|
||||
#if defined(UBRRH) || defined(UBRR0H)
|
||||
extern HardwareSerial Serial;
|
||||
#elif defined(USBCON)
|
||||
#include "USBAPI.h"
|
||||
// extern HardwareSerial Serial_;
|
||||
#endif
|
||||
#if defined(UBRR1H)
|
||||
extern HardwareSerial Serial1;
|
||||
#endif
|
||||
#if defined(UBRR2H)
|
||||
extern HardwareSerial Serial2;
|
||||
#endif
|
||||
#if defined(UBRR3H)
|
||||
extern HardwareSerial Serial3;
|
||||
#endif
|
||||
|
||||
extern void serialEventRun(void) __attribute__((weak));
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,310 @@
|
||||
#include "LiquidCrystal.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include "Arduino.h"
|
||||
|
||||
// When the display powers up, it is configured as follows:
|
||||
//
|
||||
// 1. Display clear
|
||||
// 2. Function set:
|
||||
// DL = 1; 8-bit interface data
|
||||
// N = 0; 1-line display
|
||||
// F = 0; 5x8 dot character font
|
||||
// 3. Display on/off control:
|
||||
// D = 0; Display off
|
||||
// C = 0; Cursor off
|
||||
// B = 0; Blinking off
|
||||
// 4. Entry mode set:
|
||||
// I/D = 1; Increment by 1
|
||||
// S = 0; No shift
|
||||
//
|
||||
// Note, however, that resetting the Arduino doesn't reset the LCD, so we
|
||||
// can't assume that its in that state when a sketch starts (and the
|
||||
// LiquidCrystal constructor is called).
|
||||
|
||||
LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
|
||||
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
|
||||
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
|
||||
{
|
||||
init(0, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7);
|
||||
}
|
||||
|
||||
LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable,
|
||||
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
|
||||
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
|
||||
{
|
||||
init(0, rs, 255, enable, d0, d1, d2, d3, d4, d5, d6, d7);
|
||||
}
|
||||
|
||||
LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
|
||||
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3)
|
||||
{
|
||||
init(1, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable,
|
||||
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3)
|
||||
{
|
||||
init(1, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void LiquidCrystal::init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable,
|
||||
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
|
||||
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
|
||||
{
|
||||
_rs_pin = rs;
|
||||
_rw_pin = rw;
|
||||
_enable_pin = enable;
|
||||
|
||||
_data_pins[0] = d0;
|
||||
_data_pins[1] = d1;
|
||||
_data_pins[2] = d2;
|
||||
_data_pins[3] = d3;
|
||||
_data_pins[4] = d4;
|
||||
_data_pins[5] = d5;
|
||||
_data_pins[6] = d6;
|
||||
_data_pins[7] = d7;
|
||||
|
||||
pinMode(_rs_pin, OUTPUT);
|
||||
// we can save 1 pin by not using RW. Indicate by passing 255 instead of pin#
|
||||
if (_rw_pin != 255) {
|
||||
pinMode(_rw_pin, OUTPUT);
|
||||
}
|
||||
pinMode(_enable_pin, OUTPUT);
|
||||
|
||||
if (fourbitmode)
|
||||
_displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
|
||||
else
|
||||
_displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS;
|
||||
|
||||
begin(16, 1);
|
||||
}
|
||||
|
||||
void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
|
||||
if (lines > 1) {
|
||||
_displayfunction |= LCD_2LINE;
|
||||
}
|
||||
_numlines = lines;
|
||||
_currline = 0;
|
||||
|
||||
// for some 1 line displays you can select a 10 pixel high font
|
||||
if ((dotsize != 0) && (lines == 1)) {
|
||||
_displayfunction |= LCD_5x10DOTS;
|
||||
}
|
||||
|
||||
// SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
|
||||
// according to datasheet, we need at least 40ms after power rises above 2.7V
|
||||
// before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
|
||||
delayMicroseconds(50000);
|
||||
// Now we pull both RS and R/W low to begin commands
|
||||
digitalWrite(_rs_pin, LOW);
|
||||
digitalWrite(_enable_pin, LOW);
|
||||
if (_rw_pin != 255) {
|
||||
digitalWrite(_rw_pin, LOW);
|
||||
}
|
||||
|
||||
//put the LCD into 4 bit or 8 bit mode
|
||||
if (! (_displayfunction & LCD_8BITMODE)) {
|
||||
// this is according to the hitachi HD44780 datasheet
|
||||
// figure 24, pg 46
|
||||
|
||||
// we start in 8bit mode, try to set 4 bit mode
|
||||
write4bits(0x03);
|
||||
delayMicroseconds(4500); // wait min 4.1ms
|
||||
|
||||
// second try
|
||||
write4bits(0x03);
|
||||
delayMicroseconds(4500); // wait min 4.1ms
|
||||
|
||||
// third go!
|
||||
write4bits(0x03);
|
||||
delayMicroseconds(150);
|
||||
|
||||
// finally, set to 4-bit interface
|
||||
write4bits(0x02);
|
||||
} else {
|
||||
// this is according to the hitachi HD44780 datasheet
|
||||
// page 45 figure 23
|
||||
|
||||
// Send function set command sequence
|
||||
command(LCD_FUNCTIONSET | _displayfunction);
|
||||
delayMicroseconds(4500); // wait more than 4.1ms
|
||||
|
||||
// second try
|
||||
command(LCD_FUNCTIONSET | _displayfunction);
|
||||
delayMicroseconds(150);
|
||||
|
||||
// third go
|
||||
command(LCD_FUNCTIONSET | _displayfunction);
|
||||
}
|
||||
|
||||
// finally, set # lines, font size, etc.
|
||||
command(LCD_FUNCTIONSET | _displayfunction);
|
||||
|
||||
// turn the display on with no cursor or blinking default
|
||||
_displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
|
||||
display();
|
||||
|
||||
// clear it off
|
||||
clear();
|
||||
|
||||
// Initialize to default text direction (for romance languages)
|
||||
_displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
|
||||
// set the entry mode
|
||||
command(LCD_ENTRYMODESET | _displaymode);
|
||||
|
||||
}
|
||||
|
||||
/********** high level commands, for the user! */
|
||||
void LiquidCrystal::clear()
|
||||
{
|
||||
command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero
|
||||
delayMicroseconds(2000); // this command takes a long time!
|
||||
}
|
||||
|
||||
void LiquidCrystal::home()
|
||||
{
|
||||
command(LCD_RETURNHOME); // set cursor position to zero
|
||||
delayMicroseconds(2000); // this command takes a long time!
|
||||
}
|
||||
|
||||
void LiquidCrystal::setCursor(uint8_t col, uint8_t row)
|
||||
{
|
||||
int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
|
||||
if ( row >= _numlines ) {
|
||||
row = _numlines-1; // we count rows starting w/0
|
||||
}
|
||||
|
||||
command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
|
||||
}
|
||||
|
||||
// Turn the display on/off (quickly)
|
||||
void LiquidCrystal::noDisplay() {
|
||||
_displaycontrol &= ~LCD_DISPLAYON;
|
||||
command(LCD_DISPLAYCONTROL | _displaycontrol);
|
||||
}
|
||||
void LiquidCrystal::display() {
|
||||
_displaycontrol |= LCD_DISPLAYON;
|
||||
command(LCD_DISPLAYCONTROL | _displaycontrol);
|
||||
}
|
||||
|
||||
// Turns the underline cursor on/off
|
||||
void LiquidCrystal::noCursor() {
|
||||
_displaycontrol &= ~LCD_CURSORON;
|
||||
command(LCD_DISPLAYCONTROL | _displaycontrol);
|
||||
}
|
||||
void LiquidCrystal::cursor() {
|
||||
_displaycontrol |= LCD_CURSORON;
|
||||
command(LCD_DISPLAYCONTROL | _displaycontrol);
|
||||
}
|
||||
|
||||
// Turn on and off the blinking cursor
|
||||
void LiquidCrystal::noBlink() {
|
||||
_displaycontrol &= ~LCD_BLINKON;
|
||||
command(LCD_DISPLAYCONTROL | _displaycontrol);
|
||||
}
|
||||
void LiquidCrystal::blink() {
|
||||
_displaycontrol |= LCD_BLINKON;
|
||||
command(LCD_DISPLAYCONTROL | _displaycontrol);
|
||||
}
|
||||
|
||||
// These commands scroll the display without changing the RAM
|
||||
void LiquidCrystal::scrollDisplayLeft(void) {
|
||||
command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
|
||||
}
|
||||
void LiquidCrystal::scrollDisplayRight(void) {
|
||||
command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
|
||||
}
|
||||
|
||||
// This is for text that flows Left to Right
|
||||
void LiquidCrystal::leftToRight(void) {
|
||||
_displaymode |= LCD_ENTRYLEFT;
|
||||
command(LCD_ENTRYMODESET | _displaymode);
|
||||
}
|
||||
|
||||
// This is for text that flows Right to Left
|
||||
void LiquidCrystal::rightToLeft(void) {
|
||||
_displaymode &= ~LCD_ENTRYLEFT;
|
||||
command(LCD_ENTRYMODESET | _displaymode);
|
||||
}
|
||||
|
||||
// This will 'right justify' text from the cursor
|
||||
void LiquidCrystal::autoscroll(void) {
|
||||
_displaymode |= LCD_ENTRYSHIFTINCREMENT;
|
||||
command(LCD_ENTRYMODESET | _displaymode);
|
||||
}
|
||||
|
||||
// This will 'left justify' text from the cursor
|
||||
void LiquidCrystal::noAutoscroll(void) {
|
||||
_displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
|
||||
command(LCD_ENTRYMODESET | _displaymode);
|
||||
}
|
||||
|
||||
// Allows us to fill the first 8 CGRAM locations
|
||||
// with custom characters
|
||||
void LiquidCrystal::createChar(uint8_t location, uint8_t charmap[]) {
|
||||
location &= 0x7; // we only have 8 locations 0-7
|
||||
command(LCD_SETCGRAMADDR | (location << 3));
|
||||
for (int i=0; i<8; i++) {
|
||||
write(charmap[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*********** mid level commands, for sending data/cmds */
|
||||
|
||||
inline void LiquidCrystal::command(uint8_t value) {
|
||||
send(value, LOW);
|
||||
}
|
||||
|
||||
inline size_t LiquidCrystal::write(uint8_t value) {
|
||||
send(value, HIGH);
|
||||
return 1; // assume sucess
|
||||
}
|
||||
|
||||
/************ low level data pushing commands **********/
|
||||
|
||||
// write either command or data, with automatic 4/8-bit selection
|
||||
void LiquidCrystal::send(uint8_t value, uint8_t mode) {
|
||||
digitalWrite(_rs_pin, mode);
|
||||
|
||||
// if there is a RW pin indicated, set it low to Write
|
||||
if (_rw_pin != 255) {
|
||||
digitalWrite(_rw_pin, LOW);
|
||||
}
|
||||
|
||||
if (_displayfunction & LCD_8BITMODE) {
|
||||
write8bits(value);
|
||||
} else {
|
||||
write4bits(value>>4);
|
||||
write4bits(value);
|
||||
}
|
||||
}
|
||||
|
||||
void LiquidCrystal::pulseEnable(void) {
|
||||
digitalWrite(_enable_pin, LOW);
|
||||
delayMicroseconds(1);
|
||||
digitalWrite(_enable_pin, HIGH);
|
||||
delayMicroseconds(1); // enable pulse must be >450ns
|
||||
digitalWrite(_enable_pin, LOW);
|
||||
delayMicroseconds(100); // commands need > 37us to settle
|
||||
}
|
||||
|
||||
void LiquidCrystal::write4bits(uint8_t value) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
pinMode(_data_pins[i], OUTPUT);
|
||||
digitalWrite(_data_pins[i], (value >> i) & 0x01);
|
||||
}
|
||||
|
||||
pulseEnable();
|
||||
}
|
||||
|
||||
void LiquidCrystal::write8bits(uint8_t value) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
pinMode(_data_pins[i], OUTPUT);
|
||||
digitalWrite(_data_pins[i], (value >> i) & 0x01);
|
||||
}
|
||||
|
||||
pulseEnable();
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
#ifndef LiquidCrystal_h
|
||||
#define LiquidCrystal_h
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "Print.h"
|
||||
|
||||
// commands
|
||||
#define LCD_CLEARDISPLAY 0x01
|
||||
#define LCD_RETURNHOME 0x02
|
||||
#define LCD_ENTRYMODESET 0x04
|
||||
#define LCD_DISPLAYCONTROL 0x08
|
||||
#define LCD_CURSORSHIFT 0x10
|
||||
#define LCD_FUNCTIONSET 0x20
|
||||
#define LCD_SETCGRAMADDR 0x40
|
||||
#define LCD_SETDDRAMADDR 0x80
|
||||
|
||||
// flags for display entry mode
|
||||
#define LCD_ENTRYRIGHT 0x00
|
||||
#define LCD_ENTRYLEFT 0x02
|
||||
#define LCD_ENTRYSHIFTINCREMENT 0x01
|
||||
#define LCD_ENTRYSHIFTDECREMENT 0x00
|
||||
|
||||
// flags for display on/off control
|
||||
#define LCD_DISPLAYON 0x04
|
||||
#define LCD_DISPLAYOFF 0x00
|
||||
#define LCD_CURSORON 0x02
|
||||
#define LCD_CURSOROFF 0x00
|
||||
#define LCD_BLINKON 0x01
|
||||
#define LCD_BLINKOFF 0x00
|
||||
|
||||
// flags for display/cursor shift
|
||||
#define LCD_DISPLAYMOVE 0x08
|
||||
#define LCD_CURSORMOVE 0x00
|
||||
#define LCD_MOVERIGHT 0x04
|
||||
#define LCD_MOVELEFT 0x00
|
||||
|
||||
// flags for function set
|
||||
#define LCD_8BITMODE 0x10
|
||||
#define LCD_4BITMODE 0x00
|
||||
#define LCD_2LINE 0x08
|
||||
#define LCD_1LINE 0x00
|
||||
#define LCD_5x10DOTS 0x04
|
||||
#define LCD_5x8DOTS 0x00
|
||||
|
||||
class LiquidCrystal : public Print {
|
||||
public:
|
||||
LiquidCrystal(uint8_t rs, uint8_t enable,
|
||||
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
|
||||
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
|
||||
LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
|
||||
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
|
||||
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
|
||||
LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
|
||||
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);
|
||||
LiquidCrystal(uint8_t rs, uint8_t enable,
|
||||
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);
|
||||
|
||||
void init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable,
|
||||
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
|
||||
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
|
||||
|
||||
void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS);
|
||||
|
||||
void clear();
|
||||
void home();
|
||||
|
||||
void noDisplay();
|
||||
void display();
|
||||
void noBlink();
|
||||
void blink();
|
||||
void noCursor();
|
||||
void cursor();
|
||||
void scrollDisplayLeft();
|
||||
void scrollDisplayRight();
|
||||
void leftToRight();
|
||||
void rightToLeft();
|
||||
void autoscroll();
|
||||
void noAutoscroll();
|
||||
|
||||
void createChar(uint8_t, uint8_t[]);
|
||||
void setCursor(uint8_t, uint8_t);
|
||||
virtual size_t write(uint8_t);
|
||||
void command(uint8_t);
|
||||
|
||||
using Print::write;
|
||||
private:
|
||||
void send(uint8_t, uint8_t);
|
||||
void write4bits(uint8_t);
|
||||
void write8bits(uint8_t);
|
||||
void pulseEnable();
|
||||
|
||||
uint8_t _rs_pin; // LOW: command. HIGH: character.
|
||||
uint8_t _rw_pin; // LOW: write to LCD. HIGH: read from LCD.
|
||||
uint8_t _enable_pin; // activated by a HIGH pulse.
|
||||
uint8_t _data_pins[8];
|
||||
|
||||
uint8_t _displayfunction;
|
||||
uint8_t _displaycontrol;
|
||||
uint8_t _displaymode;
|
||||
|
||||
uint8_t _initialized;
|
||||
|
||||
uint8_t _numlines,_currline;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
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
|
||||
*/
|
||||
|
||||
#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--) {
|
||||
n += write(*buffer++);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::print(const __FlashStringHelper *ifsh)
|
||||
{
|
||||
const char *p = (const char *)ifsh;
|
||||
size_t n = 0;
|
||||
while (1) {
|
||||
unsigned char c = pgm_read_byte(p++);
|
||||
if (c == 0) break;
|
||||
n += write(c);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::print(const String &s)
|
||||
{
|
||||
size_t n = 0;
|
||||
for (uint16_t i = 0; i < s.length(); i++) {
|
||||
n += write(s[i]);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
size_t n = print('\r');
|
||||
n += print('\n');
|
||||
return 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 {
|
||||
unsigned long m = n;
|
||||
n /= base;
|
||||
char c = m - base * n;
|
||||
*--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;
|
||||
|
||||
// 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;
|
||||
int toPrint = int(remainder);
|
||||
n += print(toPrint);
|
||||
remainder -= toPrint;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
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) { return write((const uint8_t *)str, strlen(str)); }
|
||||
virtual size_t write(const uint8_t *buffer, size_t 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
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
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 <new.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
|
||||
|
||||
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
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
|
||||
*/
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Stream.h"
|
||||
|
||||
#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
|
||||
#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field
|
||||
|
||||
// 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()
|
||||
{
|
||||
int c;
|
||||
while (1) {
|
||||
c = timedPeek();
|
||||
if (c < 0) return c; // timeout
|
||||
if (c == '-') return c;
|
||||
if (c >= '0' && c <= '9') return c;
|
||||
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, NULL);
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
size_t index = 0; // maximum target string length is 64k bytes!
|
||||
size_t termIndex = 0;
|
||||
int c;
|
||||
|
||||
if( *target == 0)
|
||||
return true; // return true if target is a null string
|
||||
while( (c = timedRead()) > 0){
|
||||
|
||||
if(c != target[index])
|
||||
index = 0; // reset index if any char does not match
|
||||
|
||||
if( c == target[index]){
|
||||
//////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
|
||||
if(++index >= targetLen){ // return true if all chars in the target match
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(termLen > 0 && c == terminator[termIndex]){
|
||||
if(++termIndex >= termLen)
|
||||
return false; // return false if terminate string found before target string
|
||||
}
|
||||
else
|
||||
termIndex = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// returns the first valid (long) integer value from the current position.
|
||||
// initial characters that are not digits (or the minus sign) are skipped
|
||||
// function is terminated by the first character that is not a digit.
|
||||
long Stream::parseInt()
|
||||
{
|
||||
return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
|
||||
}
|
||||
|
||||
// as above but a given skipChar is ignored
|
||||
// this allows format characters (typically commas) in values to be ignored
|
||||
long Stream::parseInt(char skipChar)
|
||||
{
|
||||
boolean isNegative = false;
|
||||
long value = 0;
|
||||
int c;
|
||||
|
||||
c = peekNextDigit();
|
||||
// ignore non numeric leading characters
|
||||
if(c < 0)
|
||||
return 0; // zero returned if timeout
|
||||
|
||||
do{
|
||||
if(c == skipChar)
|
||||
; // ignore this charactor
|
||||
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 == skipChar );
|
||||
|
||||
if(isNegative)
|
||||
value = -value;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
// as parseInt but returns a floating point value
|
||||
float Stream::parseFloat()
|
||||
{
|
||||
return parseFloat(NO_SKIP_CHAR);
|
||||
}
|
||||
|
||||
// as above but the given skipChar is ignored
|
||||
// this allows format characters (typically commas) in values to be ignored
|
||||
float Stream::parseFloat(char skipChar){
|
||||
boolean isNegative = false;
|
||||
boolean isFraction = false;
|
||||
long value = 0;
|
||||
char c;
|
||||
float fraction = 1.0;
|
||||
|
||||
c = peekNextDigit();
|
||||
// ignore non numeric leading characters
|
||||
if(c < 0)
|
||||
return 0; // zero returned if timeout
|
||||
|
||||
do{
|
||||
if(c == skipChar)
|
||||
; // 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 == '.' || c == skipChar );
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
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(skipChar) parseInt(skipchar)
|
||||
#define getFloat() parseFloat()
|
||||
#define getFloat(skipChar) parseFloat(skipChar)
|
||||
#define getString( pre_string, post_string, buffer, length)
|
||||
readBytesBetween( pre_string, terminator, buffer, length)
|
||||
*/
|
||||
|
||||
class Stream : public Print
|
||||
{
|
||||
private:
|
||||
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(); // 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
|
||||
|
||||
bool find(char *target); // reads data from the stream until the target string is found
|
||||
// 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
|
||||
// returns true if target string is found, false if timed out
|
||||
|
||||
bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found
|
||||
|
||||
bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found
|
||||
|
||||
|
||||
long parseInt(); // returns the first valid (long) integer value from the current position.
|
||||
// initial characters that are not digits (or the minus sign) are skipped
|
||||
// integer is terminated by the first character that is not a digit.
|
||||
|
||||
float parseFloat(); // float version of parseInt
|
||||
|
||||
size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
|
||||
// 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
|
||||
// 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 skipChar); // as above but the given skipChar is ignored
|
||||
// as above but the given skipChar is ignored
|
||||
// this allows format characters (typically commas) in values to be ignored
|
||||
|
||||
float parseFloat(char skipChar); // as above but the given skipChar is ignored
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,593 @@
|
||||
/* 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
|
||||
*************************************************/
|
||||
|
||||
#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
|
||||
|
||||
|
||||
// MLS: This does not make sense, the 3 options are the same
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
|
||||
#define AVAILABLE_TONE_PINS 1
|
||||
|
||||
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
|
||||
|
||||
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 1 */ };
|
||||
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255 */ };
|
||||
|
||||
#else
|
||||
|
||||
#define AVAILABLE_TONE_PINS 1
|
||||
|
||||
// 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);
|
||||
|
||||
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);
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR2A) && defined(TCCR2B)
|
||||
case 2:
|
||||
// 8 bit timer
|
||||
TCCR2A = 0;
|
||||
TCCR2B = 0;
|
||||
bitWrite(TCCR2A, WGM21, 1);
|
||||
bitWrite(TCCR2B, CS20, 1);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if !defined(__AVR_ATmega8__)
|
||||
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
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#if 0
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
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>
|
||||
|
||||
// WCharacter.h prototypes
|
||||
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));
|
||||
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,645 @@
|
||||
/*
|
||||
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"
|
||||
|
||||
|
||||
/*********************************************/
|
||||
/* Constructors */
|
||||
/*********************************************/
|
||||
|
||||
String::String(const char *cstr)
|
||||
{
|
||||
init();
|
||||
if (cstr) copy(cstr, strlen(cstr));
|
||||
}
|
||||
|
||||
String::String(const String &value)
|
||||
{
|
||||
init();
|
||||
*this = value;
|
||||
}
|
||||
|
||||
#ifdef __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[9];
|
||||
utoa(value, buf, base);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(int value, unsigned char base)
|
||||
{
|
||||
init();
|
||||
char buf[18];
|
||||
itoa(value, buf, base);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(unsigned int value, unsigned char base)
|
||||
{
|
||||
init();
|
||||
char buf[17];
|
||||
utoa(value, buf, base);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(long value, unsigned char base)
|
||||
{
|
||||
init();
|
||||
char buf[34];
|
||||
ltoa(value, buf, base);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(unsigned long value, unsigned char base)
|
||||
{
|
||||
init();
|
||||
char buf[33];
|
||||
ultoa(value, buf, base);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::~String()
|
||||
{
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Memory Management */
|
||||
/*********************************************/
|
||||
|
||||
inline void String::init(void)
|
||||
{
|
||||
buffer = NULL;
|
||||
capacity = 0;
|
||||
len = 0;
|
||||
flags = 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;
|
||||
}
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
void String::move(String &rhs)
|
||||
{
|
||||
if (buffer) {
|
||||
if (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;
|
||||
}
|
||||
|
||||
#ifdef __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;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* 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[4];
|
||||
itoa(num, buf, 10);
|
||||
return concat(buf, strlen(buf));
|
||||
}
|
||||
|
||||
unsigned char String::concat(int num)
|
||||
{
|
||||
char buf[7];
|
||||
itoa(num, buf, 10);
|
||||
return concat(buf, strlen(buf));
|
||||
}
|
||||
|
||||
unsigned char String::concat(unsigned int num)
|
||||
{
|
||||
char buf[6];
|
||||
utoa(num, buf, 10);
|
||||
return concat(buf, strlen(buf));
|
||||
}
|
||||
|
||||
unsigned char String::concat(long num)
|
||||
{
|
||||
char buf[12];
|
||||
ltoa(num, buf, 10);
|
||||
return concat(buf, strlen(buf));
|
||||
}
|
||||
|
||||
unsigned char String::concat(unsigned long num)
|
||||
{
|
||||
char buf[11];
|
||||
ultoa(num, buf, 10);
|
||||
return concat(buf, strlen(buf));
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* 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 ) const
|
||||
{
|
||||
return substring(left, len);
|
||||
}
|
||||
|
||||
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::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;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
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<__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);
|
||||
#ifdef __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);
|
||||
~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);
|
||||
#ifdef __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);
|
||||
|
||||
// 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);}
|
||||
|
||||
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);
|
||||
|
||||
// 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);}
|
||||
|
||||
// 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;
|
||||
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 toLowerCase(void);
|
||||
void toUpperCase(void);
|
||||
void trim(void);
|
||||
|
||||
// parsing/conversion
|
||||
long toInt(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')
|
||||
unsigned char flags; // unused, for future features
|
||||
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);
|
||||
#ifdef __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) {}
|
||||
};
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // String_class_h
|
||||
@@ -0,0 +1,515 @@
|
||||
#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
|
||||
@@ -0,0 +1,20 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
init();
|
||||
|
||||
#if defined(USBCON)
|
||||
USBDevice.attach();
|
||||
#endif
|
||||
|
||||
setup();
|
||||
|
||||
for (;;) {
|
||||
loop();
|
||||
if (serialEventRun) serialEventRun();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#include <new.h>
|
||||
|
||||
void * operator new(size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void operator delete(void * ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
int __cxa_guard_acquire(__guard *g) {return !*(char *)(g);};
|
||||
void __cxa_guard_release (__guard *g) {*(char *)g = 1;};
|
||||
void __cxa_guard_abort (__guard *) {};
|
||||
|
||||
void __cxa_pure_virtual(void) {};
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/* Header to define new/delete operators as they aren't provided by avr-gcc by default
|
||||
Taken from http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=59453
|
||||
*/
|
||||
|
||||
#ifndef NEW_H
|
||||
#define NEW_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
//void * operator new(size_t size);
|
||||
//void operator delete(void * ptr);
|
||||
|
||||
__extension__ typedef int __guard __attribute__((mode (__DI__)));
|
||||
|
||||
extern "C" int __cxa_guard_acquire(__guard *);
|
||||
extern "C" void __cxa_guard_release (__guard *);
|
||||
extern "C" void __cxa_guard_abort (__guard *);
|
||||
|
||||
extern "C" void __cxa_pure_virtual(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
pins_arduino.h - Pin definition functions for Arduino
|
||||
Part of Arduino - http://www.arduino.cc/
|
||||
|
||||
Copyright (c) 2007 David A. Mellis
|
||||
|
||||
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., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
$Id: wiring.h 249 2007-02-03 16:52:51Z mellis $
|
||||
*/
|
||||
|
||||
#ifndef Pins_Arduino_h
|
||||
#define Pins_Arduino_h
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#define NUM_DIGITAL_PINS 70
|
||||
#define NUM_ANALOG_INPUTS 16
|
||||
#define analogInputToDigitalPin(p) ((p < 16) ? (p) + 54 : -1)
|
||||
#define digitalPinHasPWM(p) (((p) >= 2 && (p) <= 13) || ((p) >= 44 && (p)<= 46))
|
||||
|
||||
static const uint8_t SS = 53;
|
||||
static const uint8_t MOSI = 51;
|
||||
static const uint8_t MISO = 50;
|
||||
static const uint8_t SCK = 52;
|
||||
|
||||
static const uint8_t SDA = 20;
|
||||
static const uint8_t SCL = 21;
|
||||
static const uint8_t LED_BUILTIN = 13;
|
||||
|
||||
static const uint8_t A0 = 54;
|
||||
static const uint8_t A1 = 55;
|
||||
static const uint8_t A2 = 56;
|
||||
static const uint8_t A3 = 57;
|
||||
static const uint8_t A4 = 58;
|
||||
static const uint8_t A5 = 59;
|
||||
static const uint8_t A6 = 60;
|
||||
static const uint8_t A7 = 61;
|
||||
static const uint8_t A8 = 62;
|
||||
static const uint8_t A9 = 63;
|
||||
static const uint8_t A10 = 64;
|
||||
static const uint8_t A11 = 65;
|
||||
static const uint8_t A12 = 66;
|
||||
static const uint8_t A13 = 67;
|
||||
static const uint8_t A14 = 68;
|
||||
static const uint8_t A15 = 69;
|
||||
|
||||
// A majority of the pins are NOT PCINTs, SO BE WARNED (i.e. you cannot use them as receive pins)
|
||||
// Only pins available for RECEIVE (TRANSMIT can be on any pin):
|
||||
// (I've deliberately left out pin mapping to the Hardware USARTs - seems senseless to me)
|
||||
// Pins: 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69
|
||||
|
||||
#define digitalPinToPCICR(p) ( (((p) >= 10) && ((p) <= 13)) || \
|
||||
(((p) >= 50) && ((p) <= 53)) || \
|
||||
(((p) >= 62) && ((p) <= 69)) ? (&PCICR) : ((uint8_t *)0) )
|
||||
|
||||
#define digitalPinToPCICRbit(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? 0 : \
|
||||
( (((p) >= 62) && ((p) <= 69)) ? 2 : \
|
||||
0 ) )
|
||||
|
||||
#define digitalPinToPCMSK(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? (&PCMSK0) : \
|
||||
( (((p) >= 62) && ((p) <= 69)) ? (&PCMSK2) : \
|
||||
((uint8_t *)0) ) )
|
||||
|
||||
#define digitalPinToPCMSKbit(p) ( (((p) >= 10) && ((p) <= 13)) ? ((p) - 6) : \
|
||||
( ((p) == 50) ? 3 : \
|
||||
( ((p) == 51) ? 2 : \
|
||||
( ((p) == 52) ? 1 : \
|
||||
( ((p) == 53) ? 0 : \
|
||||
( (((p) >= 62) && ((p) <= 69)) ? ((p) - 62) : \
|
||||
0 ) ) ) ) ) )
|
||||
|
||||
#ifdef ARDUINO_MAIN
|
||||
|
||||
const AVRRegistor* PROGMEM port_to_mode_PGM[] = {
|
||||
NOT_A_PORT,
|
||||
&DDRA,
|
||||
&DDRB,
|
||||
&DDRC,
|
||||
&DDRD,
|
||||
&DDRE,
|
||||
&DDRF,
|
||||
&DDRG,
|
||||
&DDRH,
|
||||
NOT_A_PORT,
|
||||
&DDRJ,
|
||||
&DDRK,
|
||||
&DDRL,
|
||||
};
|
||||
|
||||
const AVRRegistor* PROGMEM port_to_output_PGM[] = {
|
||||
NOT_A_PORT,
|
||||
&PORTA,
|
||||
&PORTB,
|
||||
&PORTC,
|
||||
&PORTD,
|
||||
&PORTE,
|
||||
&PORTF,
|
||||
&PORTG,
|
||||
&PORTH,
|
||||
NOT_A_PORT,
|
||||
&PORTJ,
|
||||
&PORTK,
|
||||
&PORTL,
|
||||
};
|
||||
|
||||
const AVRRegistor* PROGMEM port_to_input_PGM[] = {
|
||||
NOT_A_PIN,
|
||||
&PINA,
|
||||
&PINB,
|
||||
&PINC,
|
||||
&PIND,
|
||||
&PINE,
|
||||
&PINF,
|
||||
&PING,
|
||||
&PINH,
|
||||
NOT_A_PIN,
|
||||
&PINJ,
|
||||
&PINK,
|
||||
&PINL,
|
||||
};
|
||||
|
||||
const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
|
||||
// PORTLIST
|
||||
// -------------------------------------------
|
||||
PE , // PE 0 ** 0 ** USART0_RX
|
||||
PE , // PE 1 ** 1 ** USART0_TX
|
||||
PE , // PE 4 ** 2 ** PWM2
|
||||
PE , // PE 5 ** 3 ** PWM3
|
||||
PG , // PG 5 ** 4 ** PWM4
|
||||
PE , // PE 3 ** 5 ** PWM5
|
||||
PH , // PH 3 ** 6 ** PWM6
|
||||
PH , // PH 4 ** 7 ** PWM7
|
||||
PH , // PH 5 ** 8 ** PWM8
|
||||
PH , // PH 6 ** 9 ** PWM9
|
||||
PB , // PB 4 ** 10 ** PWM10
|
||||
PB , // PB 5 ** 11 ** PWM11
|
||||
PB , // PB 6 ** 12 ** PWM12
|
||||
PB , // PB 7 ** 13 ** PWM13
|
||||
PJ , // PJ 1 ** 14 ** USART3_TX
|
||||
PJ , // PJ 0 ** 15 ** USART3_RX
|
||||
PH , // PH 1 ** 16 ** USART2_TX
|
||||
PH , // PH 0 ** 17 ** USART2_RX
|
||||
PD , // PD 3 ** 18 ** USART1_TX
|
||||
PD , // PD 2 ** 19 ** USART1_RX
|
||||
PD , // PD 1 ** 20 ** I2C_SDA
|
||||
PD , // PD 0 ** 21 ** I2C_SCL
|
||||
PA , // PA 0 ** 22 ** D22
|
||||
PA , // PA 1 ** 23 ** D23
|
||||
PA , // PA 2 ** 24 ** D24
|
||||
PA , // PA 3 ** 25 ** D25
|
||||
PA , // PA 4 ** 26 ** D26
|
||||
PA , // PA 5 ** 27 ** D27
|
||||
PA , // PA 6 ** 28 ** D28
|
||||
PA , // PA 7 ** 29 ** D29
|
||||
PC , // PC 7 ** 30 ** D30
|
||||
PC , // PC 6 ** 31 ** D31
|
||||
PC , // PC 5 ** 32 ** D32
|
||||
PC , // PC 4 ** 33 ** D33
|
||||
PC , // PC 3 ** 34 ** D34
|
||||
PC , // PC 2 ** 35 ** D35
|
||||
PC , // PC 1 ** 36 ** D36
|
||||
PC , // PC 0 ** 37 ** D37
|
||||
PD , // PD 7 ** 38 ** D38
|
||||
PG , // PG 2 ** 39 ** D39
|
||||
PG , // PG 1 ** 40 ** D40
|
||||
PG , // PG 0 ** 41 ** D41
|
||||
PL , // PL 7 ** 42 ** D42
|
||||
PL , // PL 6 ** 43 ** D43
|
||||
PL , // PL 5 ** 44 ** D44
|
||||
PL , // PL 4 ** 45 ** D45
|
||||
PL , // PL 3 ** 46 ** D46
|
||||
PL , // PL 2 ** 47 ** D47
|
||||
PL , // PL 1 ** 48 ** D48
|
||||
PL , // PL 0 ** 49 ** D49
|
||||
PB , // PB 3 ** 50 ** SPI_MISO
|
||||
PB , // PB 2 ** 51 ** SPI_MOSI
|
||||
PB , // PB 1 ** 52 ** SPI_SCK
|
||||
PB , // PB 0 ** 53 ** SPI_SS
|
||||
PF , // PF 0 ** 54 ** A0
|
||||
PF , // PF 1 ** 55 ** A1
|
||||
PF , // PF 2 ** 56 ** A2
|
||||
PF , // PF 3 ** 57 ** A3
|
||||
PF , // PF 4 ** 58 ** A4
|
||||
PF , // PF 5 ** 59 ** A5
|
||||
PF , // PF 6 ** 60 ** A6
|
||||
PF , // PF 7 ** 61 ** A7
|
||||
PK , // PK 0 ** 62 ** A8
|
||||
PK , // PK 1 ** 63 ** A9
|
||||
PK , // PK 2 ** 64 ** A10
|
||||
PK , // PK 3 ** 65 ** A11
|
||||
PK , // PK 4 ** 66 ** A12
|
||||
PK , // PK 5 ** 67 ** A13
|
||||
PK , // PK 6 ** 68 ** A14
|
||||
PK , // PK 7 ** 69 ** A15
|
||||
};
|
||||
|
||||
const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
|
||||
// PIN IN PORT
|
||||
// -------------------------------------------
|
||||
_BV( 0 ) , // PE 0 ** 0 ** USART0_RX
|
||||
_BV( 1 ) , // PE 1 ** 1 ** USART0_TX
|
||||
_BV( 4 ) , // PE 4 ** 2 ** PWM2
|
||||
_BV( 5 ) , // PE 5 ** 3 ** PWM3
|
||||
_BV( 5 ) , // PG 5 ** 4 ** PWM4
|
||||
_BV( 3 ) , // PE 3 ** 5 ** PWM5
|
||||
_BV( 3 ) , // PH 3 ** 6 ** PWM6
|
||||
_BV( 4 ) , // PH 4 ** 7 ** PWM7
|
||||
_BV( 5 ) , // PH 5 ** 8 ** PWM8
|
||||
_BV( 6 ) , // PH 6 ** 9 ** PWM9
|
||||
_BV( 4 ) , // PB 4 ** 10 ** PWM10
|
||||
_BV( 5 ) , // PB 5 ** 11 ** PWM11
|
||||
_BV( 6 ) , // PB 6 ** 12 ** PWM12
|
||||
_BV( 7 ) , // PB 7 ** 13 ** PWM13
|
||||
_BV( 1 ) , // PJ 1 ** 14 ** USART3_TX
|
||||
_BV( 0 ) , // PJ 0 ** 15 ** USART3_RX
|
||||
_BV( 1 ) , // PH 1 ** 16 ** USART2_TX
|
||||
_BV( 0 ) , // PH 0 ** 17 ** USART2_RX
|
||||
_BV( 3 ) , // PD 3 ** 18 ** USART1_TX
|
||||
_BV( 2 ) , // PD 2 ** 19 ** USART1_RX
|
||||
_BV( 1 ) , // PD 1 ** 20 ** I2C_SDA
|
||||
_BV( 0 ) , // PD 0 ** 21 ** I2C_SCL
|
||||
_BV( 0 ) , // PA 0 ** 22 ** D22
|
||||
_BV( 1 ) , // PA 1 ** 23 ** D23
|
||||
_BV( 2 ) , // PA 2 ** 24 ** D24
|
||||
_BV( 3 ) , // PA 3 ** 25 ** D25
|
||||
_BV( 4 ) , // PA 4 ** 26 ** D26
|
||||
_BV( 5 ) , // PA 5 ** 27 ** D27
|
||||
_BV( 6 ) , // PA 6 ** 28 ** D28
|
||||
_BV( 7 ) , // PA 7 ** 29 ** D29
|
||||
_BV( 7 ) , // PC 7 ** 30 ** D30
|
||||
_BV( 6 ) , // PC 6 ** 31 ** D31
|
||||
_BV( 5 ) , // PC 5 ** 32 ** D32
|
||||
_BV( 4 ) , // PC 4 ** 33 ** D33
|
||||
_BV( 3 ) , // PC 3 ** 34 ** D34
|
||||
_BV( 2 ) , // PC 2 ** 35 ** D35
|
||||
_BV( 1 ) , // PC 1 ** 36 ** D36
|
||||
_BV( 0 ) , // PC 0 ** 37 ** D37
|
||||
_BV( 7 ) , // PD 7 ** 38 ** D38
|
||||
_BV( 2 ) , // PG 2 ** 39 ** D39
|
||||
_BV( 1 ) , // PG 1 ** 40 ** D40
|
||||
_BV( 0 ) , // PG 0 ** 41 ** D41
|
||||
_BV( 7 ) , // PL 7 ** 42 ** D42
|
||||
_BV( 6 ) , // PL 6 ** 43 ** D43
|
||||
_BV( 5 ) , // PL 5 ** 44 ** D44
|
||||
_BV( 4 ) , // PL 4 ** 45 ** D45
|
||||
_BV( 3 ) , // PL 3 ** 46 ** D46
|
||||
_BV( 2 ) , // PL 2 ** 47 ** D47
|
||||
_BV( 1 ) , // PL 1 ** 48 ** D48
|
||||
_BV( 0 ) , // PL 0 ** 49 ** D49
|
||||
_BV( 3 ) , // PB 3 ** 50 ** SPI_MISO
|
||||
_BV( 2 ) , // PB 2 ** 51 ** SPI_MOSI
|
||||
_BV( 1 ) , // PB 1 ** 52 ** SPI_SCK
|
||||
_BV( 0 ) , // PB 0 ** 53 ** SPI_SS
|
||||
_BV( 0 ) , // PF 0 ** 54 ** A0
|
||||
_BV( 1 ) , // PF 1 ** 55 ** A1
|
||||
_BV( 2 ) , // PF 2 ** 56 ** A2
|
||||
_BV( 3 ) , // PF 3 ** 57 ** A3
|
||||
_BV( 4 ) , // PF 4 ** 58 ** A4
|
||||
_BV( 5 ) , // PF 5 ** 59 ** A5
|
||||
_BV( 6 ) , // PF 6 ** 60 ** A6
|
||||
_BV( 7 ) , // PF 7 ** 61 ** A7
|
||||
_BV( 0 ) , // PK 0 ** 62 ** A8
|
||||
_BV( 1 ) , // PK 1 ** 63 ** A9
|
||||
_BV( 2 ) , // PK 2 ** 64 ** A10
|
||||
_BV( 3 ) , // PK 3 ** 65 ** A11
|
||||
_BV( 4 ) , // PK 4 ** 66 ** A12
|
||||
_BV( 5 ) , // PK 5 ** 67 ** A13
|
||||
_BV( 6 ) , // PK 6 ** 68 ** A14
|
||||
_BV( 7 ) , // PK 7 ** 69 ** A15
|
||||
};
|
||||
|
||||
const uint8_t PROGMEM digital_pin_to_timer_PGM[] = {
|
||||
// TIMERS
|
||||
// -------------------------------------------
|
||||
NOT_ON_TIMER , // PE 0 ** 0 ** USART0_RX
|
||||
NOT_ON_TIMER , // PE 1 ** 1 ** USART0_TX
|
||||
TIMER3B , // PE 4 ** 2 ** PWM2
|
||||
TIMER3C , // PE 5 ** 3 ** PWM3
|
||||
TIMER0B , // PG 5 ** 4 ** PWM4
|
||||
TIMER3A , // PE 3 ** 5 ** PWM5
|
||||
TIMER4A , // PH 3 ** 6 ** PWM6
|
||||
TIMER4B , // PH 4 ** 7 ** PWM7
|
||||
TIMER4C , // PH 5 ** 8 ** PWM8
|
||||
TIMER2B , // PH 6 ** 9 ** PWM9
|
||||
TIMER2A , // PB 4 ** 10 ** PWM10
|
||||
TIMER1A , // PB 5 ** 11 ** PWM11
|
||||
TIMER1B , // PB 6 ** 12 ** PWM12
|
||||
TIMER0A , // PB 7 ** 13 ** PWM13
|
||||
NOT_ON_TIMER , // PJ 1 ** 14 ** USART3_TX
|
||||
NOT_ON_TIMER , // PJ 0 ** 15 ** USART3_RX
|
||||
NOT_ON_TIMER , // PH 1 ** 16 ** USART2_TX
|
||||
NOT_ON_TIMER , // PH 0 ** 17 ** USART2_RX
|
||||
NOT_ON_TIMER , // PD 3 ** 18 ** USART1_TX
|
||||
NOT_ON_TIMER , // PD 2 ** 19 ** USART1_RX
|
||||
NOT_ON_TIMER , // PD 1 ** 20 ** I2C_SDA
|
||||
NOT_ON_TIMER , // PD 0 ** 21 ** I2C_SCL
|
||||
NOT_ON_TIMER , // PA 0 ** 22 ** D22
|
||||
NOT_ON_TIMER , // PA 1 ** 23 ** D23
|
||||
NOT_ON_TIMER , // PA 2 ** 24 ** D24
|
||||
NOT_ON_TIMER , // PA 3 ** 25 ** D25
|
||||
NOT_ON_TIMER , // PA 4 ** 26 ** D26
|
||||
NOT_ON_TIMER , // PA 5 ** 27 ** D27
|
||||
NOT_ON_TIMER , // PA 6 ** 28 ** D28
|
||||
NOT_ON_TIMER , // PA 7 ** 29 ** D29
|
||||
NOT_ON_TIMER , // PC 7 ** 30 ** D30
|
||||
NOT_ON_TIMER , // PC 6 ** 31 ** D31
|
||||
NOT_ON_TIMER , // PC 5 ** 32 ** D32
|
||||
NOT_ON_TIMER , // PC 4 ** 33 ** D33
|
||||
NOT_ON_TIMER , // PC 3 ** 34 ** D34
|
||||
NOT_ON_TIMER , // PC 2 ** 35 ** D35
|
||||
NOT_ON_TIMER , // PC 1 ** 36 ** D36
|
||||
NOT_ON_TIMER , // PC 0 ** 37 ** D37
|
||||
NOT_ON_TIMER , // PD 7 ** 38 ** D38
|
||||
NOT_ON_TIMER , // PG 2 ** 39 ** D39
|
||||
NOT_ON_TIMER , // PG 1 ** 40 ** D40
|
||||
NOT_ON_TIMER , // PG 0 ** 41 ** D41
|
||||
NOT_ON_TIMER , // PL 7 ** 42 ** D42
|
||||
NOT_ON_TIMER , // PL 6 ** 43 ** D43
|
||||
TIMER5C , // PL 5 ** 44 ** D44
|
||||
TIMER5B , // PL 4 ** 45 ** D45
|
||||
TIMER5A , // PL 3 ** 46 ** D46
|
||||
NOT_ON_TIMER , // PL 2 ** 47 ** D47
|
||||
NOT_ON_TIMER , // PL 1 ** 48 ** D48
|
||||
NOT_ON_TIMER , // PL 0 ** 49 ** D49
|
||||
NOT_ON_TIMER , // PB 3 ** 50 ** SPI_MISO
|
||||
NOT_ON_TIMER , // PB 2 ** 51 ** SPI_MOSI
|
||||
NOT_ON_TIMER , // PB 1 ** 52 ** SPI_SCK
|
||||
NOT_ON_TIMER , // PB 0 ** 53 ** SPI_SS
|
||||
NOT_ON_TIMER , // PF 0 ** 54 ** A0
|
||||
NOT_ON_TIMER , // PF 1 ** 55 ** A1
|
||||
NOT_ON_TIMER , // PF 2 ** 56 ** A2
|
||||
NOT_ON_TIMER , // PF 3 ** 57 ** A3
|
||||
NOT_ON_TIMER , // PF 4 ** 58 ** A4
|
||||
NOT_ON_TIMER , // PF 5 ** 59 ** A5
|
||||
NOT_ON_TIMER , // PF 6 ** 60 ** A6
|
||||
NOT_ON_TIMER , // PF 7 ** 61 ** A7
|
||||
NOT_ON_TIMER , // PK 0 ** 62 ** A8
|
||||
NOT_ON_TIMER , // PK 1 ** 63 ** A9
|
||||
NOT_ON_TIMER , // PK 2 ** 64 ** A10
|
||||
NOT_ON_TIMER , // PK 3 ** 65 ** A11
|
||||
NOT_ON_TIMER , // PK 4 ** 66 ** A12
|
||||
NOT_ON_TIMER , // PK 5 ** 67 ** A13
|
||||
NOT_ON_TIMER , // PK 6 ** 68 ** A14
|
||||
NOT_ON_TIMER , // PK 7 ** 69 ** A15
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,326 @@
|
||||
/*
|
||||
wiring.c - Partial implementation of the Wiring API for the ATmega8.
|
||||
Part of Arduino - http://www.arduino.cc/
|
||||
|
||||
Copyright (c) 2005-2006 David A. Mellis
|
||||
|
||||
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., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#include "wiring_private.h"
|
||||
|
||||
// the prescaler is set so that timer0 ticks every 64 clock cycles, and the
|
||||
// the overflow handler is called every 256 ticks.
|
||||
#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))
|
||||
|
||||
// the whole number of milliseconds per timer0 overflow
|
||||
#define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)
|
||||
|
||||
// the fractional number of milliseconds per timer0 overflow. we shift right
|
||||
// by three to fit these numbers into a byte. (for the clock speeds we care
|
||||
// about - 8 and 16 MHz - this doesn't lose precision.)
|
||||
#define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
|
||||
#define FRACT_MAX (1000 >> 3)
|
||||
|
||||
volatile unsigned long timer0_overflow_count = 0;
|
||||
volatile unsigned long timer0_millis = 0;
|
||||
static unsigned char timer0_fract = 0;
|
||||
|
||||
#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
|
||||
SIGNAL(TIM0_OVF_vect)
|
||||
#else
|
||||
SIGNAL(TIMER0_OVF_vect)
|
||||
#endif
|
||||
{
|
||||
// copy these to local variables so they can be stored in registers
|
||||
// (volatile variables must be read from memory on every access)
|
||||
unsigned long m = timer0_millis;
|
||||
unsigned char f = timer0_fract;
|
||||
|
||||
m += MILLIS_INC;
|
||||
f += FRACT_INC;
|
||||
if (f >= FRACT_MAX) {
|
||||
f -= FRACT_MAX;
|
||||
m += 1;
|
||||
}
|
||||
|
||||
timer0_fract = f;
|
||||
timer0_millis = m;
|
||||
timer0_overflow_count++;
|
||||
}
|
||||
|
||||
unsigned long millis()
|
||||
{
|
||||
unsigned long m;
|
||||
uint8_t oldSREG = SREG;
|
||||
|
||||
// disable interrupts while we read timer0_millis or we might get an
|
||||
// inconsistent value (e.g. in the middle of a write to timer0_millis)
|
||||
cli();
|
||||
m = timer0_millis;
|
||||
SREG = oldSREG;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
unsigned long micros() {
|
||||
unsigned long m;
|
||||
uint8_t oldSREG = SREG, t;
|
||||
|
||||
cli();
|
||||
m = timer0_overflow_count;
|
||||
#if defined(TCNT0)
|
||||
t = TCNT0;
|
||||
#elif defined(TCNT0L)
|
||||
t = TCNT0L;
|
||||
#else
|
||||
#error TIMER 0 not defined
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef TIFR0
|
||||
if ((TIFR0 & _BV(TOV0)) && (t < 255))
|
||||
m++;
|
||||
#else
|
||||
if ((TIFR & _BV(TOV0)) && (t < 255))
|
||||
m++;
|
||||
#endif
|
||||
|
||||
SREG = oldSREG;
|
||||
|
||||
return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
|
||||
}
|
||||
|
||||
void delay(unsigned long ms)
|
||||
{
|
||||
uint16_t start = (uint16_t)micros();
|
||||
|
||||
while (ms > 0) {
|
||||
if (((uint16_t)micros() - start) >= 1000) {
|
||||
ms--;
|
||||
start += 1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Delay for the given number of microseconds. Assumes a 8 or 16 MHz clock. */
|
||||
void delayMicroseconds(unsigned int us)
|
||||
{
|
||||
// calling avrlib's delay_us() function with low values (e.g. 1 or
|
||||
// 2 microseconds) gives delays longer than desired.
|
||||
//delay_us(us);
|
||||
#if F_CPU >= 20000000L
|
||||
// for the 20 MHz clock on rare Arduino boards
|
||||
|
||||
// for a one-microsecond delay, simply wait 2 cycle and return. The overhead
|
||||
// of the function call yields a delay of exactly a one microsecond.
|
||||
__asm__ __volatile__ (
|
||||
"nop" "\n\t"
|
||||
"nop"); //just waiting 2 cycle
|
||||
if (--us == 0)
|
||||
return;
|
||||
|
||||
// the following loop takes a 1/5 of a microsecond (4 cycles)
|
||||
// per iteration, so execute it five times for each microsecond of
|
||||
// delay requested.
|
||||
us = (us<<2) + us; // x5 us
|
||||
|
||||
// account for the time taken in the preceeding commands.
|
||||
us -= 2;
|
||||
|
||||
#elif F_CPU >= 16000000L
|
||||
// for the 16 MHz clock on most Arduino boards
|
||||
|
||||
// for a one-microsecond delay, simply return. the overhead
|
||||
// of the function call yields a delay of approximately 1 1/8 us.
|
||||
if (--us == 0)
|
||||
return;
|
||||
|
||||
// the following loop takes a quarter of a microsecond (4 cycles)
|
||||
// per iteration, so execute it four times for each microsecond of
|
||||
// delay requested.
|
||||
us <<= 2;
|
||||
|
||||
// account for the time taken in the preceeding commands.
|
||||
us -= 2;
|
||||
#else
|
||||
// for the 8 MHz internal clock on the ATmega168
|
||||
|
||||
// for a one- or two-microsecond delay, simply return. the overhead of
|
||||
// the function calls takes more than two microseconds. can't just
|
||||
// subtract two, since us is unsigned; we'd overflow.
|
||||
if (--us == 0)
|
||||
return;
|
||||
if (--us == 0)
|
||||
return;
|
||||
|
||||
// the following loop takes half of a microsecond (4 cycles)
|
||||
// per iteration, so execute it twice for each microsecond of
|
||||
// delay requested.
|
||||
us <<= 1;
|
||||
|
||||
// partially compensate for the time taken by the preceeding commands.
|
||||
// we can't subtract any more than this or we'd overflow w/ small delays.
|
||||
us--;
|
||||
#endif
|
||||
|
||||
// busy wait
|
||||
#ifdef __AVR
|
||||
__asm__ __volatile__ (
|
||||
"1: sbiw %0,1" "\n\t" // 2 cycles
|
||||
"brne 1b" : "=w" (us) : "0" (us) // 2 cycles
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
// this needs to be called before setup() or some functions won't
|
||||
// work there
|
||||
sei();
|
||||
|
||||
// on the ATmega168, timer 0 is also used for fast hardware pwm
|
||||
// (using phase-correct PWM would mean that timer 0 overflowed half as often
|
||||
// resulting in different millis() behavior on the ATmega8 and ATmega168)
|
||||
#if defined(TCCR0A) && defined(WGM01)
|
||||
sbi(TCCR0A, WGM01);
|
||||
sbi(TCCR0A, WGM00);
|
||||
#endif
|
||||
|
||||
// set timer 0 prescale factor to 64
|
||||
#if defined(__AVR_ATmega128__)
|
||||
// CPU specific: different values for the ATmega128
|
||||
sbi(TCCR0, CS02);
|
||||
#elif defined(TCCR0) && defined(CS01) && defined(CS00)
|
||||
// this combination is for the standard atmega8
|
||||
sbi(TCCR0, CS01);
|
||||
sbi(TCCR0, CS00);
|
||||
#elif defined(TCCR0B) && defined(CS01) && defined(CS00)
|
||||
// this combination is for the standard 168/328/1280/2560
|
||||
sbi(TCCR0B, CS01);
|
||||
sbi(TCCR0B, CS00);
|
||||
#elif defined(TCCR0A) && defined(CS01) && defined(CS00)
|
||||
// this combination is for the __AVR_ATmega645__ series
|
||||
sbi(TCCR0A, CS01);
|
||||
sbi(TCCR0A, CS00);
|
||||
#else
|
||||
#error Timer 0 prescale factor 64 not set correctly
|
||||
#endif
|
||||
|
||||
// enable timer 0 overflow interrupt
|
||||
#if defined(TIMSK) && defined(TOIE0)
|
||||
sbi(TIMSK, TOIE0);
|
||||
#elif defined(TIMSK0) && defined(TOIE0)
|
||||
sbi(TIMSK0, TOIE0);
|
||||
#else
|
||||
#error Timer 0 overflow interrupt not set correctly
|
||||
#endif
|
||||
|
||||
// timers 1 and 2 are used for phase-correct hardware pwm
|
||||
// this is better for motors as it ensures an even waveform
|
||||
// note, however, that fast pwm mode can achieve a frequency of up
|
||||
// 8 MHz (with a 16 MHz clock) at 50% duty cycle
|
||||
|
||||
#if defined(TCCR1B) && defined(CS11) && defined(CS10)
|
||||
TCCR1B = 0;
|
||||
|
||||
// set timer 1 prescale factor to 64
|
||||
sbi(TCCR1B, CS11);
|
||||
#if F_CPU >= 8000000L
|
||||
sbi(TCCR1B, CS10);
|
||||
#endif
|
||||
#elif defined(TCCR1) && defined(CS11) && defined(CS10)
|
||||
sbi(TCCR1, CS11);
|
||||
#if F_CPU >= 8000000L
|
||||
sbi(TCCR1, CS10);
|
||||
#endif
|
||||
#endif
|
||||
// put timer 1 in 8-bit phase correct pwm mode
|
||||
#if defined(TCCR1A) && defined(WGM10)
|
||||
sbi(TCCR1A, WGM10);
|
||||
#elif defined(TCCR1)
|
||||
#warning this needs to be finished
|
||||
#endif
|
||||
|
||||
// set timer 2 prescale factor to 64
|
||||
#if defined(TCCR2) && defined(CS22)
|
||||
sbi(TCCR2, CS22);
|
||||
#elif defined(TCCR2B) && defined(CS22)
|
||||
sbi(TCCR2B, CS22);
|
||||
#else
|
||||
#warning Timer 2 not finished (may not be present on this CPU)
|
||||
#endif
|
||||
|
||||
// configure timer 2 for phase correct pwm (8-bit)
|
||||
#if defined(TCCR2) && defined(WGM20)
|
||||
sbi(TCCR2, WGM20);
|
||||
#elif defined(TCCR2A) && defined(WGM20)
|
||||
sbi(TCCR2A, WGM20);
|
||||
#else
|
||||
#warning Timer 2 not finished (may not be present on this CPU)
|
||||
#endif
|
||||
|
||||
#if defined(TCCR3B) && defined(CS31) && defined(WGM30)
|
||||
sbi(TCCR3B, CS31); // set timer 3 prescale factor to 64
|
||||
sbi(TCCR3B, CS30);
|
||||
sbi(TCCR3A, WGM30); // put timer 3 in 8-bit phase correct pwm mode
|
||||
#endif
|
||||
|
||||
#if defined(TCCR4A) && defined(TCCR4B) && defined(TCCR4D) /* beginning of timer4 block for 32U4 and similar */
|
||||
sbi(TCCR4B, CS42); // set timer4 prescale factor to 64
|
||||
sbi(TCCR4B, CS41);
|
||||
sbi(TCCR4B, CS40);
|
||||
sbi(TCCR4D, WGM40); // put timer 4 in phase- and frequency-correct PWM mode
|
||||
sbi(TCCR4A, PWM4A); // enable PWM mode for comparator OCR4A
|
||||
sbi(TCCR4C, PWM4D); // enable PWM mode for comparator OCR4D
|
||||
#else /* beginning of timer4 block for ATMEGA1280 and ATMEGA2560 */
|
||||
#if defined(TCCR4B) && defined(CS41) && defined(WGM40)
|
||||
sbi(TCCR4B, CS41); // set timer 4 prescale factor to 64
|
||||
sbi(TCCR4B, CS40);
|
||||
sbi(TCCR4A, WGM40); // put timer 4 in 8-bit phase correct pwm mode
|
||||
#endif
|
||||
#endif /* end timer4 block for ATMEGA1280/2560 and similar */
|
||||
|
||||
#if defined(TCCR5B) && defined(CS51) && defined(WGM50)
|
||||
sbi(TCCR5B, CS51); // set timer 5 prescale factor to 64
|
||||
sbi(TCCR5B, CS50);
|
||||
sbi(TCCR5A, WGM50); // put timer 5 in 8-bit phase correct pwm mode
|
||||
#endif
|
||||
|
||||
#if defined(ADCSRA)
|
||||
// set a2d prescale factor to 128
|
||||
// 16 MHz / 128 = 125 KHz, inside the desired 50-200 KHz range.
|
||||
// XXX: this will not work properly for other clock speeds, and
|
||||
// this code should use F_CPU to determine the prescale factor.
|
||||
sbi(ADCSRA, ADPS2);
|
||||
sbi(ADCSRA, ADPS1);
|
||||
sbi(ADCSRA, ADPS0);
|
||||
|
||||
// enable a2d conversions
|
||||
sbi(ADCSRA, ADEN);
|
||||
#endif
|
||||
|
||||
// the bootloader connects pins 0 and 1 to the USART; disconnect them
|
||||
// here so they can be used as normal digital i/o; they will be
|
||||
// reconnected in Serial.begin()
|
||||
#if defined(UCSRB)
|
||||
UCSRB = 0;
|
||||
#elif defined(UCSR0B)
|
||||
UCSR0B = 0;
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
wiring_analog.c - analog input and output
|
||||
Part of Arduino - http://www.arduino.cc/
|
||||
|
||||
Copyright (c) 2005-2006 David A. Mellis
|
||||
|
||||
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., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
Modified 28 September 2010 by Mark Sproul
|
||||
|
||||
$Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
|
||||
*/
|
||||
|
||||
#include "wiring_private.h"
|
||||
#include "pins_arduino.h"
|
||||
|
||||
uint8_t analog_reference = DEFAULT;
|
||||
|
||||
void analogReference(uint8_t mode)
|
||||
{
|
||||
// can't actually set the register here because the default setting
|
||||
// will connect AVCC and the AREF pin, which would cause a short if
|
||||
// there's something connected to AREF.
|
||||
analog_reference = mode;
|
||||
}
|
||||
|
||||
int analogRead(uint8_t pin)
|
||||
{
|
||||
uint8_t low, high;
|
||||
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
if (pin >= 54) pin -= 54; // allow for channel or pin numbers
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
if (pin >= 18) pin -= 18; // allow for channel or pin numbers
|
||||
#elif defined(__AVR_ATmega1284__)
|
||||
if (pin >= 24) pin -= 24; // allow for channel or pin numbers
|
||||
#else
|
||||
if (pin >= 14) pin -= 14; // allow for channel or pin numbers
|
||||
#endif
|
||||
|
||||
#if defined(__AVR_ATmega32U4__)
|
||||
pin = analogPinToChannel(pin);
|
||||
ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
|
||||
#elif defined(ADCSRB) && defined(MUX5)
|
||||
// the MUX5 bit of ADCSRB selects whether we're reading from channels
|
||||
// 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
|
||||
ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
|
||||
#endif
|
||||
|
||||
// set the analog reference (high two bits of ADMUX) and select the
|
||||
// channel (low 4 bits). this also sets ADLAR (left-adjust result)
|
||||
// to 0 (the default).
|
||||
#if defined(ADMUX)
|
||||
ADMUX = (analog_reference << 6) | (pin & 0x07);
|
||||
#endif
|
||||
|
||||
// without a delay, we seem to read from the wrong channel
|
||||
//delay(1);
|
||||
|
||||
#if defined(ADCSRA) && defined(ADCL)
|
||||
// start the conversion
|
||||
sbi(ADCSRA, ADSC);
|
||||
|
||||
// ADSC is cleared when the conversion finishes
|
||||
while (bit_is_set(ADCSRA, ADSC));
|
||||
|
||||
// we have to read ADCL first; doing so locks both ADCL
|
||||
// and ADCH until ADCH is read. reading ADCL second would
|
||||
// cause the results of each conversion to be discarded,
|
||||
// as ADCL and ADCH would be locked when it completed.
|
||||
low = ADCL;
|
||||
high = ADCH;
|
||||
#else
|
||||
// we dont have an ADC, return 0
|
||||
low = 0;
|
||||
high = 0;
|
||||
#endif
|
||||
|
||||
// combine the two bytes
|
||||
return (high << 8) | low;
|
||||
}
|
||||
|
||||
// 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(uint8_t pin, int val)
|
||||
{
|
||||
// We need to make sure the PWM output is enabled for those pins
|
||||
// that support it, as we turn it off when digitally reading or
|
||||
// writing with them. Also, make sure the pin is in output mode
|
||||
// for consistenty with Wiring, which doesn't require a pinMode
|
||||
// call for the analog output pins.
|
||||
pinMode(pin, OUTPUT);
|
||||
if (val == 0)
|
||||
{
|
||||
digitalWrite(pin, LOW);
|
||||
}
|
||||
else if (val == 255)
|
||||
{
|
||||
digitalWrite(pin, HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(digitalPinToTimer(pin))
|
||||
{
|
||||
// XXX fix needed for atmega8
|
||||
#if defined(TCCR0) && defined(COM00) && !defined(__AVR_ATmega8__)
|
||||
case TIMER0A:
|
||||
// connect pwm to pin on timer 0
|
||||
sbi(TCCR0, COM00);
|
||||
OCR0 = val; // set pwm duty
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR0A) && defined(COM0A1)
|
||||
case TIMER0A:
|
||||
// connect pwm to pin on timer 0, channel A
|
||||
sbi(TCCR0A, COM0A1);
|
||||
OCR0A = val; // set pwm duty
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR0A) && defined(COM0B1)
|
||||
case TIMER0B:
|
||||
// connect pwm to pin on timer 0, channel B
|
||||
sbi(TCCR0A, COM0B1);
|
||||
OCR0B = val; // set pwm duty
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR1A) && defined(COM1A1)
|
||||
case TIMER1A:
|
||||
// connect pwm to pin on timer 1, channel A
|
||||
sbi(TCCR1A, COM1A1);
|
||||
OCR1A = val; // set pwm duty
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR1A) && defined(COM1B1)
|
||||
case TIMER1B:
|
||||
// connect pwm to pin on timer 1, channel B
|
||||
sbi(TCCR1A, COM1B1);
|
||||
OCR1B = val; // set pwm duty
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR2) && defined(COM21)
|
||||
case TIMER2:
|
||||
// connect pwm to pin on timer 2
|
||||
sbi(TCCR2, COM21);
|
||||
OCR2 = val; // set pwm duty
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR2A) && defined(COM2A1)
|
||||
case TIMER2A:
|
||||
// connect pwm to pin on timer 2, channel A
|
||||
sbi(TCCR2A, COM2A1);
|
||||
OCR2A = val; // set pwm duty
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR2A) && defined(COM2B1)
|
||||
case TIMER2B:
|
||||
// connect pwm to pin on timer 2, channel B
|
||||
sbi(TCCR2A, COM2B1);
|
||||
OCR2B = val; // set pwm duty
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR3A) && defined(COM3A1)
|
||||
case TIMER3A:
|
||||
// connect pwm to pin on timer 3, channel A
|
||||
sbi(TCCR3A, COM3A1);
|
||||
OCR3A = val; // set pwm duty
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR3A) && defined(COM3B1)
|
||||
case TIMER3B:
|
||||
// connect pwm to pin on timer 3, channel B
|
||||
sbi(TCCR3A, COM3B1);
|
||||
OCR3B = val; // set pwm duty
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR3A) && defined(COM3C1)
|
||||
case TIMER3C:
|
||||
// connect pwm to pin on timer 3, channel C
|
||||
sbi(TCCR3A, COM3C1);
|
||||
OCR3C = val; // set pwm duty
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR4A)
|
||||
case TIMER4A:
|
||||
//connect pwm to pin on timer 4, channel A
|
||||
sbi(TCCR4A, COM4A1);
|
||||
#if defined(COM4A0) // only used on 32U4
|
||||
cbi(TCCR4A, COM4A0);
|
||||
#endif
|
||||
OCR4A = val; // set pwm duty
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR4A) && defined(COM4B1)
|
||||
case TIMER4B:
|
||||
// connect pwm to pin on timer 4, channel B
|
||||
sbi(TCCR4A, COM4B1);
|
||||
OCR4B = val; // set pwm duty
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR4A) && defined(COM4C1)
|
||||
case TIMER4C:
|
||||
// connect pwm to pin on timer 4, channel C
|
||||
sbi(TCCR4A, COM4C1);
|
||||
OCR4C = val; // set pwm duty
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR4C) && defined(COM4D1)
|
||||
case TIMER4D:
|
||||
// connect pwm to pin on timer 4, channel D
|
||||
sbi(TCCR4C, COM4D1);
|
||||
#if defined(COM4D0) // only used on 32U4
|
||||
cbi(TCCR4C, COM4D0);
|
||||
#endif
|
||||
OCR4D = val; // set pwm duty
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(TCCR5A) && defined(COM5A1)
|
||||
case TIMER5A:
|
||||
// connect pwm to pin on timer 5, channel A
|
||||
sbi(TCCR5A, COM5A1);
|
||||
OCR5A = val; // set pwm duty
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR5A) && defined(COM5B1)
|
||||
case TIMER5B:
|
||||
// connect pwm to pin on timer 5, channel B
|
||||
sbi(TCCR5A, COM5B1);
|
||||
OCR5B = val; // set pwm duty
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR5A) && defined(COM5C1)
|
||||
case TIMER5C:
|
||||
// connect pwm to pin on timer 5, channel C
|
||||
sbi(TCCR5A, COM5C1);
|
||||
OCR5C = val; // set pwm duty
|
||||
break;
|
||||
#endif
|
||||
|
||||
case NOT_ON_TIMER:
|
||||
default:
|
||||
if (val < 128) {
|
||||
digitalWrite(pin, LOW);
|
||||
} else {
|
||||
digitalWrite(pin, HIGH);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
wiring_digital.c - digital input and output functions
|
||||
Part of Arduino - http://www.arduino.cc/
|
||||
|
||||
Copyright (c) 2005-2006 David A. Mellis
|
||||
|
||||
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., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
Modified 28 September 2010 by Mark Sproul
|
||||
|
||||
$Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
|
||||
*/
|
||||
|
||||
#define ARDUINO_MAIN
|
||||
#include "wiring_private.h"
|
||||
#include "pins_arduino.h"
|
||||
|
||||
void pinMode(uint8_t pin, uint8_t mode)
|
||||
{
|
||||
uint8_t bit = digitalPinToBitMask(pin);
|
||||
uint8_t port = digitalPinToPort(pin);
|
||||
AVRRegistor *reg, *out;
|
||||
|
||||
if (port == NOT_A_PIN) return;
|
||||
|
||||
// JWS: can I let the optimizer do this?
|
||||
reg = portModeRegister(port);
|
||||
out = portOutputRegister(port);
|
||||
|
||||
if (mode == INPUT) {
|
||||
uint8_t oldSREG = SREG;
|
||||
cli();
|
||||
*reg &= ~bit;
|
||||
*out &= ~bit;
|
||||
SREG = oldSREG;
|
||||
} else if (mode == INPUT_PULLUP) {
|
||||
uint8_t oldSREG = SREG;
|
||||
cli();
|
||||
*reg &= ~bit;
|
||||
*out |= bit;
|
||||
SREG = oldSREG;
|
||||
} else {
|
||||
uint8_t oldSREG = SREG;
|
||||
cli();
|
||||
*reg |= bit;
|
||||
SREG = oldSREG;
|
||||
}
|
||||
}
|
||||
|
||||
// Forcing this inline keeps the callers from having to push their own stuff
|
||||
// on the stack. It is a good performance win and only takes 1 more byte per
|
||||
// user than calling. (It will take more bytes on the 168.)
|
||||
//
|
||||
// But shouldn't this be moved into pinMode? Seems silly to check and do on
|
||||
// each digitalread or write.
|
||||
//
|
||||
// Mark Sproul:
|
||||
// - Removed inline. Save 170 bytes on atmega1280
|
||||
// - changed to a switch statment; added 32 bytes but much easier to read and maintain.
|
||||
// - Added more #ifdefs, now compiles for atmega645
|
||||
//
|
||||
//static inline void turnOffPWM(uint8_t timer) __attribute__ ((always_inline));
|
||||
//static inline void turnOffPWM(uint8_t timer)
|
||||
static void turnOffPWM(uint8_t timer)
|
||||
{
|
||||
switch (timer)
|
||||
{
|
||||
#if defined(TCCR1A) && defined(COM1A1)
|
||||
case TIMER1A: cbi(TCCR1A, COM1A1); break;
|
||||
#endif
|
||||
#if defined(TCCR1A) && defined(COM1B1)
|
||||
case TIMER1B: cbi(TCCR1A, COM1B1); break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR2) && defined(COM21)
|
||||
case TIMER2: cbi(TCCR2, COM21); break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR0A) && defined(COM0A1)
|
||||
case TIMER0A: cbi(TCCR0A, COM0A1); break;
|
||||
#endif
|
||||
|
||||
#if defined(TIMER0B) && defined(COM0B1)
|
||||
case TIMER0B: cbi(TCCR0A, COM0B1); break;
|
||||
#endif
|
||||
#if defined(TCCR2A) && defined(COM2A1)
|
||||
case TIMER2A: cbi(TCCR2A, COM2A1); break;
|
||||
#endif
|
||||
#if defined(TCCR2A) && defined(COM2B1)
|
||||
case TIMER2B: cbi(TCCR2A, COM2B1); break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR3A) && defined(COM3A1)
|
||||
case TIMER3A: cbi(TCCR3A, COM3A1); break;
|
||||
#endif
|
||||
#if defined(TCCR3A) && defined(COM3B1)
|
||||
case TIMER3B: cbi(TCCR3A, COM3B1); break;
|
||||
#endif
|
||||
#if defined(TCCR3A) && defined(COM3C1)
|
||||
case TIMER3C: cbi(TCCR3A, COM3C1); break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR4A) && defined(COM4A1)
|
||||
case TIMER4A: cbi(TCCR4A, COM4A1); break;
|
||||
#endif
|
||||
#if defined(TCCR4A) && defined(COM4B1)
|
||||
case TIMER4B: cbi(TCCR4A, COM4B1); break;
|
||||
#endif
|
||||
#if defined(TCCR4A) && defined(COM4C1)
|
||||
case TIMER4C: cbi(TCCR4A, COM4C1); break;
|
||||
#endif
|
||||
#if defined(TCCR4C) && defined(COM4D1)
|
||||
case TIMER4D: cbi(TCCR4C, COM4D1); break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR5A)
|
||||
case TIMER5A: cbi(TCCR5A, COM5A1); break;
|
||||
case TIMER5B: cbi(TCCR5A, COM5B1); break;
|
||||
case TIMER5C: cbi(TCCR5A, COM5C1); break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void digitalWrite(uint8_t pin, uint8_t val)
|
||||
{
|
||||
uint8_t timer = digitalPinToTimer(pin);
|
||||
uint8_t bit = digitalPinToBitMask(pin);
|
||||
uint8_t port = digitalPinToPort(pin);
|
||||
AVRRegistor *out;
|
||||
|
||||
if (port == NOT_A_PIN) return;
|
||||
|
||||
// If the pin that support PWM output, we need to turn it off
|
||||
// before doing a digital write.
|
||||
if (timer != NOT_ON_TIMER) turnOffPWM(timer);
|
||||
|
||||
out = portOutputRegister(port);
|
||||
|
||||
uint8_t oldSREG = SREG;
|
||||
cli();
|
||||
|
||||
if (val == LOW) {
|
||||
*out &= ~bit;
|
||||
} else {
|
||||
*out |= bit;
|
||||
}
|
||||
|
||||
SREG = oldSREG;
|
||||
}
|
||||
|
||||
int digitalRead(uint8_t pin)
|
||||
{
|
||||
uint8_t timer = digitalPinToTimer(pin);
|
||||
uint8_t bit = digitalPinToBitMask(pin);
|
||||
uint8_t port = digitalPinToPort(pin);
|
||||
|
||||
if (port == NOT_A_PIN) return LOW;
|
||||
|
||||
// If the pin that support PWM output, we need to turn it off
|
||||
// before getting a digital reading.
|
||||
if (timer != NOT_ON_TIMER) turnOffPWM(timer);
|
||||
|
||||
if (*portInputRegister(port) & bit) return HIGH;
|
||||
return LOW;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
wiring_private.h - Internal header file.
|
||||
Part of Arduino - http://www.arduino.cc/
|
||||
|
||||
Copyright (c) 2005-2006 David A. Mellis
|
||||
|
||||
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., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
$Id: wiring.h 239 2007-01-12 17:58:39Z mellis $
|
||||
*/
|
||||
|
||||
#ifndef WiringPrivate_h
|
||||
#define WiringPrivate_h
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#ifndef cbi
|
||||
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
|
||||
#endif
|
||||
#ifndef sbi
|
||||
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
|
||||
#endif
|
||||
|
||||
#define EXTERNAL_INT_0 0
|
||||
#define EXTERNAL_INT_1 1
|
||||
#define EXTERNAL_INT_2 2
|
||||
#define EXTERNAL_INT_3 3
|
||||
#define EXTERNAL_INT_4 4
|
||||
#define EXTERNAL_INT_5 5
|
||||
#define EXTERNAL_INT_6 6
|
||||
#define EXTERNAL_INT_7 7
|
||||
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define EXTERNAL_NUM_INTERRUPTS 8
|
||||
#elif defined(__AVR_ATmega1284P__)
|
||||
#define EXTERNAL_NUM_INTERRUPTS 3
|
||||
#else
|
||||
#define EXTERNAL_NUM_INTERRUPTS 2
|
||||
#endif
|
||||
|
||||
typedef void (*voidFuncPtr)(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
wiring_pulse.c - pulseIn() function
|
||||
Part of Arduino - http://www.arduino.cc/
|
||||
|
||||
Copyright (c) 2005-2006 David A. Mellis
|
||||
|
||||
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., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
$Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
|
||||
*/
|
||||
|
||||
#include "wiring_private.h"
|
||||
#include "pins_arduino.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. */
|
||||
unsigned long pulseIn(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.
|
||||
uint8_t bit = digitalPinToBitMask(pin);
|
||||
uint8_t port = digitalPinToPort(pin);
|
||||
uint8_t stateMask = (state ? bit : 0);
|
||||
unsigned long width = 0; // keep initialization out of time critical area
|
||||
|
||||
// convert the timeout from microseconds to a number of times through
|
||||
// the initial loop; it takes 16 clock cycles per iteration.
|
||||
unsigned long numloops = 0;
|
||||
unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;
|
||||
|
||||
// wait for any previous pulse to end
|
||||
while ((*portInputRegister(port) & bit) == stateMask)
|
||||
if (numloops++ == maxloops)
|
||||
return 0;
|
||||
|
||||
// wait for the pulse to start
|
||||
while ((*portInputRegister(port) & bit) != stateMask)
|
||||
if (numloops++ == maxloops)
|
||||
return 0;
|
||||
|
||||
// wait for the pulse to stop
|
||||
while ((*portInputRegister(port) & bit) == stateMask) {
|
||||
if (numloops++ == maxloops)
|
||||
return 0;
|
||||
width++;
|
||||
}
|
||||
|
||||
// convert the reading to microseconds. The loop has been determined
|
||||
// to be 20 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.
|
||||
return clockCyclesToMicroseconds(width * 21 + 16);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
wiring_shift.c - shiftOut() function
|
||||
Part of Arduino - http://www.arduino.cc/
|
||||
|
||||
Copyright (c) 2005-2006 David A. Mellis
|
||||
|
||||
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., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
$Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
|
||||
*/
|
||||
|
||||
#include "wiring_private.h"
|
||||
|
||||
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) {
|
||||
uint8_t value = 0;
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
digitalWrite(clockPin, HIGH);
|
||||
if (bitOrder == LSBFIRST)
|
||||
value |= digitalRead(dataPin) << i;
|
||||
else
|
||||
value |= digitalRead(dataPin) << (7 - i);
|
||||
digitalWrite(clockPin, LOW);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (bitOrder == LSBFIRST)
|
||||
digitalWrite(dataPin, !!(val & (1 << i)));
|
||||
else
|
||||
digitalWrite(dataPin, !!(val & (1 << (7 - i))));
|
||||
|
||||
digitalWrite(clockPin, HIGH);
|
||||
digitalWrite(clockPin, LOW);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/* Copyright (c) 2002, 2003, 2004, 2007 Marek Michalkiewicz
|
||||
Copyright (c) 2005, 2006 Bjoern Haase
|
||||
Copyright (c) 2008 Atmel Corporation
|
||||
Copyright (c) 2008 Wouter van Gulik
|
||||
Copyright (c) 2009 Dmitry Xmelkov
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
/* $Id: eeprom.h,v 1.21.2.13 2009/12/03 18:38:59 arcanum Exp $ */
|
||||
|
||||
#ifndef _AVR_EEPROM_H_
|
||||
#define _AVR_EEPROM_H_ 1
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
extern uint8_t __eeprom__storage[4096];
|
||||
|
||||
static inline uint8_t eeprom_read_byte (const uint8_t *__p)
|
||||
{
|
||||
return __eeprom__storage[int(__p)];
|
||||
}
|
||||
static inline uint16_t eeprom_read_word (const uint16_t *__p)
|
||||
{
|
||||
return *(uint16_t*)&__eeprom__storage[int(__p)];
|
||||
}
|
||||
static inline uint32_t eeprom_read_dword (const uint32_t *__p)
|
||||
{
|
||||
return *(uint32_t*)&__eeprom__storage[int(__p)];
|
||||
}
|
||||
#define eeprom_read_float eeprom_read_float_
|
||||
static inline float eeprom_read_float_ (const float *__p)
|
||||
{
|
||||
return *(float*)&__eeprom__storage[int(__p)];
|
||||
}
|
||||
static inline void eeprom_read_block (void *__dst, const void *__src, size_t __n)
|
||||
{
|
||||
memcpy(__dst, &__eeprom__storage[int(__src)], __n);
|
||||
}
|
||||
|
||||
static inline void eeprom_write_byte (uint8_t *__p, uint8_t __value)
|
||||
{
|
||||
__eeprom__storage[int(__p)] = __value;
|
||||
}
|
||||
static inline void eeprom_write_word (uint16_t *__p, uint16_t __value)
|
||||
{
|
||||
*(uint16_t*)&__eeprom__storage[int(__p)] = __value;
|
||||
}
|
||||
|
||||
static inline void eeprom_write_dword (uint32_t *__p, uint32_t __value)
|
||||
{
|
||||
*(uint32_t*)&__eeprom__storage[int(__p)] = __value;
|
||||
}
|
||||
|
||||
#define eeprom_write_float eeprom_write_float_
|
||||
static inline void eeprom_write_float_ (float *__p, float __value)
|
||||
{
|
||||
*(float*)&__eeprom__storage[int(__p)] = __value;
|
||||
}
|
||||
|
||||
static inline void eeprom_write_block (const void *__src, void *__dst, size_t __n)
|
||||
{
|
||||
memcpy(&__eeprom__storage[int(__dst)], __src, __n);
|
||||
}
|
||||
|
||||
static inline void eeprom_update_byte (uint8_t *__p, uint8_t __value) {}
|
||||
static inline void eeprom_update_word (uint16_t *__p, uint16_t __value) {}
|
||||
static inline void eeprom_update_dword (uint32_t *__p, uint32_t __value) {}
|
||||
static inline void eeprom_update_float (float *__p, float __value) {}
|
||||
static inline void eeprom_update_block (const void *__src, void *__dst, size_t __n) {}
|
||||
|
||||
#endif /* !_AVR_EEPROM_H_ */
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef _SIM_INTERRUPT_H
|
||||
#define _SIM_INTERRUPT_H
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
#define SREG _SFR_IO8(0x3F)
|
||||
#define SREG_I (7)
|
||||
|
||||
static inline void cli() { SREG &=~_BV(SREG_I); }
|
||||
static inline void sei() { SREG |= _BV(SREG_I); }
|
||||
|
||||
#define ISR(vector_name) void vector_name ()
|
||||
#define SIGNAL(vector_name) void vector_name (void)
|
||||
|
||||
#endif//_SIM_INTERRUPT_H
|
||||
@@ -0,0 +1,66 @@
|
||||
#ifndef _AVR_IO_H_
|
||||
#define _AVR_IO_H_ 1
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error "No C++ compiler, simulated IO requires C++! Force C++ on all files!"
|
||||
#endif
|
||||
|
||||
#include "../../component/delegate.h"
|
||||
|
||||
typedef delegate<uint8_t, uint8_t&> registerDelegate;
|
||||
typedef void (*sim_ms_callback_t)();
|
||||
|
||||
void sim_check_interrupts();
|
||||
void sim_setup(sim_ms_callback_t callback);
|
||||
|
||||
class AVRRegistor
|
||||
{
|
||||
private:
|
||||
uint8_t value;
|
||||
registerDelegate callback;
|
||||
public:
|
||||
AVRRegistor() : value(0), callback() {}
|
||||
~AVRRegistor() {}
|
||||
|
||||
void setCallback(registerDelegate callback) { this->callback = callback; }
|
||||
void forceValue(uint8_t value) { this->value = value; }
|
||||
|
||||
operator uint8_t() const { return value; }
|
||||
AVRRegistor& operator = (const uint32_t v);
|
||||
AVRRegistor& operator |= (const uint32_t n) { *this = (value | n); return *this; }
|
||||
AVRRegistor& operator &= (const uint32_t n) { *this = (value & n); return *this; }
|
||||
|
||||
//volatile uint8_t* operator & () __attribute__((__deprecated__)) { return &value; }
|
||||
};
|
||||
#define __REG_MAP_SIZE 0x200
|
||||
extern AVRRegistor __reg_map[__REG_MAP_SIZE];
|
||||
|
||||
class AVRRegistor16
|
||||
{
|
||||
private:
|
||||
int index;
|
||||
public:
|
||||
AVRRegistor16(int index) : index(index) {}
|
||||
~AVRRegistor16() {}
|
||||
|
||||
AVRRegistor16& operator = (const uint32_t v) { __reg_map[index] = v & 0xFF; __reg_map[index+1] = (v >> 8) & 0xFF; return *this; }
|
||||
operator uint16_t() const { return uint16_t(__reg_map[index]) | (uint16_t(__reg_map[index+1])<<8); /*TODO*/}
|
||||
};
|
||||
|
||||
#define _SFR_MEM8(__n) (__reg_map[(__n)])
|
||||
#define _SFR_MEM16(__n) (AVRRegistor16(__n))
|
||||
#define _SFR_IO8(__n) (__reg_map[((__n) + 0x20)])
|
||||
#define _VECTOR(__n) __vector_ ## __n
|
||||
#define _SFR_BYTE(__n) __n
|
||||
|
||||
#define _BV(bit) (1 << (bit))
|
||||
|
||||
#define bit_is_set(sfr, bit) (_SFR_BYTE(sfr) & _BV(bit))
|
||||
|
||||
#include "iom2560.h"
|
||||
|
||||
#endif//_AVR_IO_H_
|
||||
@@ -0,0 +1,94 @@
|
||||
/* Copyright (c) 2005 Anatoly Sokolov
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
/* $Id */
|
||||
|
||||
/* avr/iom2560.h - definitions for ATmega2560 */
|
||||
|
||||
#ifndef _AVR_IOM2560_H_
|
||||
#define _AVR_IOM2560_H_ 1
|
||||
|
||||
#include <avr/iomxx0_1.h>
|
||||
|
||||
/* Constants */
|
||||
#define SPM_PAGESIZE 256
|
||||
#define RAMEND 0x21FF
|
||||
#define XRAMEND 0xFFFF
|
||||
#define E2END 0xFFF
|
||||
#define E2PAGESIZE 8
|
||||
#define FLASHEND 0x3FFFF
|
||||
|
||||
|
||||
/* Fuses */
|
||||
|
||||
#define FUSE_MEMORY_SIZE 3
|
||||
|
||||
/* Low Fuse Byte */
|
||||
#define FUSE_CKSEL0 (unsigned char)~_BV(0)
|
||||
#define FUSE_CKSEL1 (unsigned char)~_BV(1)
|
||||
#define FUSE_CKSEL2 (unsigned char)~_BV(2)
|
||||
#define FUSE_CKSEL3 (unsigned char)~_BV(3)
|
||||
#define FUSE_SUT0 (unsigned char)~_BV(4)
|
||||
#define FUSE_SUT1 (unsigned char)~_BV(5)
|
||||
#define FUSE_CKOUT (unsigned char)~_BV(6)
|
||||
#define FUSE_CKDIV8 (unsigned char)~_BV(7)
|
||||
#define LFUSE_DEFAULT (FUSE_CKSEL0 & FUSE_CKSEL2 & FUSE_CKSEL3 & FUSE_SUT0 & FUSE_CKDIV8)
|
||||
|
||||
/* High Fuse Byte */
|
||||
#define FUSE_BOOTRST (unsigned char)~_BV(0)
|
||||
#define FUSE_BOOTSZ0 (unsigned char)~_BV(1)
|
||||
#define FUSE_BOOTSZ1 (unsigned char)~_BV(2)
|
||||
#define FUSE_EESAVE (unsigned char)~_BV(3)
|
||||
#define FUSE_WDTON (unsigned char)~_BV(4)
|
||||
#define FUSE_SPIEN (unsigned char)~_BV(5)
|
||||
#define FUSE_JTAGEN (unsigned char)~_BV(6)
|
||||
#define FUSE_OCDEN (unsigned char)~_BV(7)
|
||||
#define HFUSE_DEFAULT (FUSE_BOOTSZ0 & FUSE_BOOTSZ1 & FUSE_SPIEN & FUSE_JTAGEN)
|
||||
|
||||
/* Extended Fuse Byte */
|
||||
#define FUSE_BODLEVEL0 (unsigned char)~_BV(0)
|
||||
#define FUSE_BODLEVEL1 (unsigned char)~_BV(1)
|
||||
#define FUSE_BODLEVEL2 (unsigned char)~_BV(2)
|
||||
#define EFUSE_DEFAULT (0xFF)
|
||||
|
||||
|
||||
/* Lock Bits */
|
||||
#define __LOCK_BITS_EXIST
|
||||
#define __BOOT_LOCK_BITS_0_EXIST
|
||||
#define __BOOT_LOCK_BITS_1_EXIST
|
||||
|
||||
|
||||
/* Signature */
|
||||
#define SIGNATURE_0 0x1E
|
||||
#define SIGNATURE_1 0x98
|
||||
#define SIGNATURE_2 0x01
|
||||
|
||||
|
||||
#endif /* _AVR_IOM2560_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,69 @@
|
||||
#ifndef AVR_PGMSPACE_H
|
||||
#define AVR_PGMSPACE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef char prog_char;
|
||||
|
||||
#define PROGMEM __attribute__(())
|
||||
#define PGM_P const prog_char *
|
||||
#define PSTR(str) (str)
|
||||
#define strcpy_P strcpy
|
||||
#define strlen_P strlen
|
||||
#define strcmp_P strcmp
|
||||
#define sprintf_P sprintf
|
||||
#define strcat_P strcat
|
||||
#define strstr_P strstr
|
||||
#define strncmp_P strncmp
|
||||
#define strncpy_P strncpy
|
||||
#define strchr_P strchr
|
||||
|
||||
static inline uint8_t pgm_read_byte(const void* ptr)
|
||||
{
|
||||
return *(const uint8_t*)ptr;
|
||||
}
|
||||
|
||||
static inline uint16_t pgm_read_word(const void* ptr)
|
||||
{
|
||||
return *(const uint16_t*)ptr;
|
||||
}
|
||||
|
||||
static inline float pgm_read_float(const void* ptr)
|
||||
{
|
||||
return *(const float*)ptr;
|
||||
}
|
||||
|
||||
#define pgm_read_byte_near(n) pgm_read_byte(n)
|
||||
#define pgm_read_word_near(n) pgm_read_word(n)
|
||||
#define pgm_read_float_near(n) pgm_read_float(n)
|
||||
|
||||
/* Cheating some none-standard C functions in here (normally provided by avr-libc), so WString.h of Arduino sees this function */
|
||||
inline static char * ultoa (unsigned long int __val, char *__s, int __radix)
|
||||
{
|
||||
char* c = __s;
|
||||
unsigned long n = __radix;
|
||||
while(n < __val)
|
||||
n *= __radix;
|
||||
n /= __radix;
|
||||
while(n)
|
||||
{
|
||||
int v = (__val / n) % __radix;
|
||||
if (v < 10)
|
||||
*c++ = '0' + v;
|
||||
else
|
||||
*c++ = 'a' + v - 10;
|
||||
n /= __radix;
|
||||
}
|
||||
*c = '\0';
|
||||
return __s;
|
||||
}
|
||||
|
||||
inline static char * utoa (unsigned int __val, char *__s, int __radix)
|
||||
{
|
||||
return ultoa(__val, __s, __radix);
|
||||
}
|
||||
|
||||
|
||||
inline static double square(double __x) { return __x * __x; }
|
||||
|
||||
#endif//AVR_PGMSPACE_H
|
||||
@@ -0,0 +1,128 @@
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdio.h>
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
#include "../../Marlin/configuration.h"
|
||||
#include "../../Marlin/pins.h"
|
||||
#include "../../Marlin/fastio.h"
|
||||
|
||||
AVRRegistor __reg_map[__REG_MAP_SIZE];
|
||||
uint8_t __eeprom__storage[4096];
|
||||
sim_ms_callback_t ms_callback;
|
||||
|
||||
unsigned int __bss_end;
|
||||
unsigned int __heap_start;
|
||||
void *__brkval;
|
||||
|
||||
extern void TWI_vect();
|
||||
extern void TIMER0_OVF_vect();
|
||||
extern void TIMER0_COMPB_vect();
|
||||
extern void TIMER1_COMPA_vect();
|
||||
|
||||
unsigned int prevTicks = SDL_GetTicks();
|
||||
unsigned int twiIntStart = 0;
|
||||
|
||||
//After an interrupt we need to set the interrupt flag again, but do this without calling sim_check_interrupts so the interrupt does not fire recursively
|
||||
#define _sei() do { SREG.forceValue(SREG | _BV(SREG_I)); } while(0)
|
||||
|
||||
void sim_check_interrupts()
|
||||
{
|
||||
if (!(SREG & _BV(SREG_I)))
|
||||
return;
|
||||
|
||||
unsigned int ticks = SDL_GetTicks();
|
||||
int tickDiff = ticks - prevTicks;
|
||||
prevTicks = ticks;
|
||||
|
||||
#ifdef ENABLE_ULTILCD2
|
||||
if ((TWCR & _BV(TWEN)) && (TWCR & _BV(TWINT)) && (TWCR & _BV(TWIE)))
|
||||
{
|
||||
//Relay the TWI interrupt by 25ms one time till it gets disabled again. This fakes the LCD refresh rate.
|
||||
if (twiIntStart == 0)
|
||||
twiIntStart = SDL_GetTicks();
|
||||
if (SDL_GetTicks() - twiIntStart > 25)
|
||||
{
|
||||
cli();
|
||||
TWI_vect();
|
||||
_sei();
|
||||
}
|
||||
}
|
||||
if (!(TWCR & _BV(TWEN)) || !(TWCR & _BV(TWIE)))
|
||||
{
|
||||
twiIntStart = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
//if (tickDiff > 1)
|
||||
// printf("Ticks slow! %i\n", tickDiff);
|
||||
if (tickDiff > 0)
|
||||
{
|
||||
ms_callback();
|
||||
|
||||
cli();
|
||||
for(int n=0;n<tickDiff;n++)
|
||||
{
|
||||
if (TIMSK0 & _BV(OCIE0B))
|
||||
TIMER0_COMPB_vect();
|
||||
if (TIMSK0 & _BV(TOIE0))
|
||||
TIMER0_OVF_vect();
|
||||
}
|
||||
|
||||
//Timer1 runs at 16Mhz / 8 ticks per second.
|
||||
unsigned int waveformMode = ((TCCR1B & (_BV(WGM13) | _BV(WGM12))) >> 1) | (TCCR1A & (_BV(WGM11) | _BV(WGM10)));
|
||||
unsigned int clockSource = TCCR1B & (_BV(CS12) | _BV(CS11) | _BV(CS10));
|
||||
unsigned int tickCount = F_CPU * tickDiff / 1000;
|
||||
unsigned int ticks = TCNT1;
|
||||
switch(clockSource)
|
||||
{
|
||||
case 0: tickCount = 0; break;
|
||||
case 1: break;
|
||||
case 2: tickCount /= 8; break;
|
||||
case 3: tickCount /= 64; break;
|
||||
case 4: tickCount /= 256; break;
|
||||
case 5: tickCount /= 1024; break;
|
||||
case 6: tickCount = 0; break;
|
||||
case 7: tickCount = 0; break;
|
||||
}
|
||||
|
||||
if (tickCount > 0 && OCR1A > 0)
|
||||
{
|
||||
ticks += tickCount;
|
||||
while(ticks > int(OCR1A))
|
||||
{
|
||||
ticks -= int(OCR1A);
|
||||
if (TIMSK1 & _BV(OCIE1A))
|
||||
TIMER1_COMPA_vect();
|
||||
}
|
||||
TCNT1 = ticks;
|
||||
}
|
||||
_sei();
|
||||
}
|
||||
}
|
||||
|
||||
extern void sim_setup_main();
|
||||
|
||||
//Assignment opperator called on every register write.
|
||||
AVRRegistor& AVRRegistor::operator = (const uint32_t v)
|
||||
{
|
||||
uint8_t n = v;
|
||||
if (!ms_callback) sim_setup_main();
|
||||
callback(value, n);
|
||||
value = n;
|
||||
sim_check_interrupts();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void sim_setup(sim_ms_callback_t callback)
|
||||
{
|
||||
FILE* f = fopen("eeprom.save", "rb");
|
||||
if (f)
|
||||
{
|
||||
fread(__eeprom__storage, sizeof(__eeprom__storage), 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
ms_callback = callback;
|
||||
|
||||
UCSR0A = 0;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef _AVR_WDT_H_
|
||||
#define _AVR_WDT_H_
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define wdt_reset() do {} while(0)
|
||||
#define wdt_enable(value) do {} while(0)
|
||||
#define wdt_disable() do {} while(0)
|
||||
|
||||
#define WDTO_15MS 0
|
||||
#define WDTO_30MS 1
|
||||
#define WDTO_60MS 2
|
||||
#define WDTO_120MS 3
|
||||
#define WDTO_250MS 4
|
||||
#define WDTO_500MS 5
|
||||
#define WDTO_1S 6
|
||||
#define WDTO_2S 7
|
||||
#define WDTO_4S 8
|
||||
#define WDTO_8S 9
|
||||
|
||||
#endif /* _AVR_WDT_H_ */
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
#ifndef _SIM_DELAY_H
|
||||
#define _SIM_DELAY_H
|
||||
|
||||
static inline void _delay_ms(int delay) {}
|
||||
static inline void _delay_us(int delay) {}
|
||||
|
||||
#endif//_SIM_DELAY_H
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "adc.h"
|
||||
|
||||
adcSim::adcSim()
|
||||
{
|
||||
ADCSRA.setCallback(DELEGATE(registerDelegate, adcSim, *this, ADC_ADCSRA_callback));
|
||||
for(unsigned int n=0;n<16;n++)
|
||||
adcValue[n] = 0;
|
||||
}
|
||||
|
||||
adcSim::~adcSim()
|
||||
{
|
||||
}
|
||||
|
||||
void adcSim::ADC_ADCSRA_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
if ((newValue & _BV(ADEN)) && (newValue & _BV(ADSC)))
|
||||
{ //Start ADC conversion
|
||||
int idx = ADMUX & (_BV(MUX4)|_BV(MUX3)|_BV(MUX2)|_BV(MUX1)|_BV(MUX0));
|
||||
if (ADCSRB & _BV(MUX5))
|
||||
idx += 8;
|
||||
|
||||
ADC = adcValue[idx];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef ADC_SIM_H
|
||||
#define ADC_SIM_H
|
||||
|
||||
#include "base.h"
|
||||
|
||||
class adcSim : public simBaseComponent
|
||||
{
|
||||
public:
|
||||
adcSim();
|
||||
virtual ~adcSim();
|
||||
|
||||
int adcValue[16];
|
||||
|
||||
private:
|
||||
void ADC_ADCSRA_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
};
|
||||
|
||||
#endif//I2C_SIM_H
|
||||
@@ -0,0 +1,141 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "arduinoIO.h"
|
||||
|
||||
#define PA 1
|
||||
#define PB 2
|
||||
#define PC 3
|
||||
#define PD 4
|
||||
#define PE 5
|
||||
#define PF 6
|
||||
#define PG 7
|
||||
#define PH 8
|
||||
#define PJ 10
|
||||
#define PK 11
|
||||
#define PL 12
|
||||
|
||||
arduinoIOSim::arduinoIOSim()
|
||||
{
|
||||
PORTA.setCallback(DELEGATE(registerDelegate, arduinoIOSim, *this, IO_PORTA_callback));
|
||||
PORTB.setCallback(DELEGATE(registerDelegate, arduinoIOSim, *this, IO_PORTB_callback));
|
||||
PORTC.setCallback(DELEGATE(registerDelegate, arduinoIOSim, *this, IO_PORTC_callback));
|
||||
PORTD.setCallback(DELEGATE(registerDelegate, arduinoIOSim, *this, IO_PORTD_callback));
|
||||
PORTE.setCallback(DELEGATE(registerDelegate, arduinoIOSim, *this, IO_PORTE_callback));
|
||||
PORTF.setCallback(DELEGATE(registerDelegate, arduinoIOSim, *this, IO_PORTF_callback));
|
||||
PORTG.setCallback(DELEGATE(registerDelegate, arduinoIOSim, *this, IO_PORTG_callback));
|
||||
PORTH.setCallback(DELEGATE(registerDelegate, arduinoIOSim, *this, IO_PORTH_callback));
|
||||
PORTJ.setCallback(DELEGATE(registerDelegate, arduinoIOSim, *this, IO_PORTJ_callback));
|
||||
PORTK.setCallback(DELEGATE(registerDelegate, arduinoIOSim, *this, IO_PORTK_callback));
|
||||
PORTL.setCallback(DELEGATE(registerDelegate, arduinoIOSim, *this, IO_PORTL_callback));
|
||||
|
||||
for(unsigned int n=0; n<11*8; n++)
|
||||
portIdxToPinNr[n] = -1;
|
||||
for(unsigned int n=0; n<NUM_DIGITAL_PINS; n++)
|
||||
{
|
||||
if (digital_pin_to_port_PGM[n] == NOT_A_PORT)
|
||||
continue;
|
||||
int idx = digital_pin_to_port_PGM[n] * 8;
|
||||
int mask = digital_pin_to_bit_mask_PGM[n];
|
||||
for(unsigned int i=0;i<8;i++)
|
||||
if (mask == _BV(i)) idx += i;
|
||||
portIdxToPinNr[idx] = n;
|
||||
}
|
||||
}
|
||||
arduinoIOSim::~arduinoIOSim()
|
||||
{
|
||||
}
|
||||
|
||||
void arduinoIOSim::registerPortCallback(int portNr, ioDelegate func)
|
||||
{
|
||||
if (portNr < 0 || portNr >= NUM_DIGITAL_PINS)
|
||||
return;
|
||||
ioWriteDelegate[portNr] = func;
|
||||
}
|
||||
|
||||
void arduinoIOSim::checkPinChange(int portID, uint8_t oldValue, uint8_t newValue)
|
||||
{
|
||||
uint8_t change = oldValue ^ newValue;
|
||||
if (change)
|
||||
{
|
||||
for(unsigned int i=0;i<8;i++)
|
||||
{
|
||||
if (change & _BV(i))
|
||||
{
|
||||
int pinNr = portIdxToPinNr[portID * 8 + i];
|
||||
if (pinNr >= 0)
|
||||
ioWriteDelegate[pinNr](pinNr, newValue & _BV(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void arduinoIOSim::IO_PORTA_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
checkPinChange(PA, oldValue, newValue);
|
||||
}
|
||||
void arduinoIOSim::IO_PORTB_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
checkPinChange(PB, oldValue, newValue);
|
||||
}
|
||||
void arduinoIOSim::IO_PORTC_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
checkPinChange(PC, oldValue, newValue);
|
||||
}
|
||||
void arduinoIOSim::IO_PORTD_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
checkPinChange(PD, oldValue, newValue);
|
||||
}
|
||||
void arduinoIOSim::IO_PORTE_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
checkPinChange(PE, oldValue, newValue);
|
||||
}
|
||||
void arduinoIOSim::IO_PORTF_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
checkPinChange(PF, oldValue, newValue);
|
||||
}
|
||||
void arduinoIOSim::IO_PORTG_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
checkPinChange(PG, oldValue, newValue);
|
||||
}
|
||||
void arduinoIOSim::IO_PORTH_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
checkPinChange(PH, oldValue, newValue);
|
||||
}
|
||||
void arduinoIOSim::IO_PORTJ_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
checkPinChange(PJ, oldValue, newValue);
|
||||
}
|
||||
void arduinoIOSim::IO_PORTK_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
checkPinChange(PK, oldValue, newValue);
|
||||
}
|
||||
void arduinoIOSim::IO_PORTL_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
checkPinChange(PL, oldValue, newValue);
|
||||
}
|
||||
|
||||
bool readOutput(int arduinoPinNr)
|
||||
{
|
||||
uint8_t bit = digitalPinToBitMask(arduinoPinNr);
|
||||
uint8_t port = digitalPinToPort(arduinoPinNr);
|
||||
|
||||
if (port == NOT_A_PORT) return false;
|
||||
|
||||
AVRRegistor* out = portOutputRegister(port);
|
||||
|
||||
return (*out) & bit;
|
||||
}
|
||||
|
||||
void writeInput(int arduinoPinNr, bool value)
|
||||
{
|
||||
uint8_t bit = digitalPinToBitMask(arduinoPinNr);
|
||||
uint8_t port = digitalPinToPort(arduinoPinNr);
|
||||
|
||||
if (port == NOT_A_PIN) return;
|
||||
|
||||
AVRRegistor* in = portInputRegister(port);
|
||||
if (value)
|
||||
(*in) |= bit;
|
||||
else
|
||||
(*in) &=~bit;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef ARDUINO_IO_SIM_H
|
||||
#define ARDUINO_IO_SIM_H
|
||||
|
||||
#include "base.h"
|
||||
#include "delegate.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
typedef delegate<int, bool> ioDelegate;
|
||||
|
||||
class arduinoIOSim : public simBaseComponent
|
||||
{
|
||||
public:
|
||||
arduinoIOSim();
|
||||
virtual ~arduinoIOSim();
|
||||
|
||||
void registerPortCallback(int portNr, ioDelegate func);
|
||||
private:
|
||||
int portIdxToPinNr[13*8];
|
||||
ioDelegate ioWriteDelegate[NUM_DIGITAL_PINS];
|
||||
|
||||
void IO_PORTA_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void IO_PORTB_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void IO_PORTC_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void IO_PORTD_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void IO_PORTE_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void IO_PORTF_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void IO_PORTG_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void IO_PORTH_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void IO_PORTJ_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void IO_PORTK_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void IO_PORTL_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
|
||||
void checkPinChange(int portID, uint8_t oldValue, uint8_t newValue);
|
||||
};
|
||||
|
||||
bool readOutput(int arduinoPinNr);
|
||||
void writeInput(int arduinoPinNr, bool value);
|
||||
|
||||
#endif//ARDUINO_IO_SIM_H
|
||||
@@ -0,0 +1,209 @@
|
||||
#include <SDL/SDL.h>
|
||||
#include "base.h"
|
||||
|
||||
#define DRAW_SCALE 3
|
||||
|
||||
extern SDL_Surface *screen;
|
||||
std::vector<simBaseComponent*> simComponentList;
|
||||
|
||||
static const uint8_t lcd_font[] = {
|
||||
// font data
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x00'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x01'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x02'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x03'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x04'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x05'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x06'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x07'
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x08'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x09'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x0A'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x0B'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x0C'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x0D'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x0E'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x0F'
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x10'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x11'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x12'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x13'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x14'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x15'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x16'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x17'
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x18'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x19'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x1A'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x1B'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x1C'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x1D'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x1E'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x1F'
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// (space)
|
||||
0x00, 0x00, 0x5F, 0x00, 0x00,// !
|
||||
0x00, 0x07, 0x00, 0x07, 0x00,// "
|
||||
0x14, 0x7F, 0x14, 0x7F, 0x14,// #
|
||||
0x24, 0x2A, 0x7F, 0x2A, 0x12,// $
|
||||
0x23, 0x13, 0x08, 0x64, 0x62,// %
|
||||
0x36, 0x49, 0x55, 0x22, 0x50,// &
|
||||
0x00, 0x05, 0x03, 0x00, 0x00,// '
|
||||
0x00, 0x1C, 0x22, 0x41, 0x00,// (
|
||||
0x00, 0x41, 0x22, 0x1C, 0x00,// )
|
||||
0x08, 0x2A, 0x1C, 0x2A, 0x08,// *
|
||||
0x08, 0x08, 0x3E, 0x08, 0x08,// +
|
||||
0x00, 0x50, 0x30, 0x00, 0x00,// ,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08,// -
|
||||
0x00, 0x60, 0x60, 0x00, 0x00,// .
|
||||
0x20, 0x10, 0x08, 0x04, 0x02,// /
|
||||
0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
|
||||
0x00, 0x42, 0x7F, 0x40, 0x00,// 1
|
||||
0x42, 0x61, 0x51, 0x49, 0x46,// 2
|
||||
0x21, 0x41, 0x45, 0x4B, 0x31,// 3
|
||||
0x18, 0x14, 0x12, 0x7F, 0x10,// 4
|
||||
0x27, 0x45, 0x45, 0x45, 0x39,// 5
|
||||
0x3C, 0x4A, 0x49, 0x49, 0x30,// 6
|
||||
0x01, 0x71, 0x09, 0x05, 0x03,// 7
|
||||
0x36, 0x49, 0x49, 0x49, 0x36,// 8
|
||||
0x06, 0x49, 0x49, 0x29, 0x1E,// 9
|
||||
0x00, 0x36, 0x36, 0x00, 0x00,// :
|
||||
0x00, 0x56, 0x36, 0x00, 0x00,// ;
|
||||
0x00, 0x08, 0x14, 0x22, 0x41,// <
|
||||
0x14, 0x14, 0x14, 0x14, 0x14,// =
|
||||
0x41, 0x22, 0x14, 0x08, 0x00,// >
|
||||
0x02, 0x01, 0x51, 0x09, 0x06,// ?
|
||||
0x32, 0x49, 0x79, 0x41, 0x3E,// @
|
||||
0x7E, 0x11, 0x11, 0x11, 0x7E,// A
|
||||
0x7F, 0x49, 0x49, 0x49, 0x36,// B
|
||||
0x3E, 0x41, 0x41, 0x41, 0x22,// C
|
||||
0x7F, 0x41, 0x41, 0x22, 0x1C,// D
|
||||
0x7F, 0x49, 0x49, 0x49, 0x41,// E
|
||||
0x7F, 0x09, 0x09, 0x01, 0x01,// F
|
||||
0x3E, 0x41, 0x41, 0x51, 0x32,// G
|
||||
0x7F, 0x08, 0x08, 0x08, 0x7F,// H
|
||||
0x00, 0x41, 0x7F, 0x41, 0x00,// I
|
||||
0x20, 0x40, 0x41, 0x3F, 0x01,// J
|
||||
0x7F, 0x08, 0x14, 0x22, 0x41,// K
|
||||
0x7F, 0x40, 0x40, 0x40, 0x40,// L
|
||||
0x7F, 0x02, 0x04, 0x02, 0x7F,// M
|
||||
0x7F, 0x04, 0x08, 0x10, 0x7F,// N
|
||||
0x3E, 0x41, 0x41, 0x41, 0x3E,// O
|
||||
0x7F, 0x09, 0x09, 0x09, 0x06,// P
|
||||
0x3E, 0x41, 0x51, 0x21, 0x5E,// Q
|
||||
0x7F, 0x09, 0x19, 0x29, 0x46,// R
|
||||
0x46, 0x49, 0x49, 0x49, 0x31,// S
|
||||
0x01, 0x01, 0x7F, 0x01, 0x01,// T
|
||||
0x3F, 0x40, 0x40, 0x40, 0x3F,// U
|
||||
0x1F, 0x20, 0x40, 0x20, 0x1F,// V
|
||||
0x7F, 0x20, 0x18, 0x20, 0x7F,// W
|
||||
0x63, 0x14, 0x08, 0x14, 0x63,// X
|
||||
0x03, 0x04, 0x78, 0x04, 0x03,// Y
|
||||
0x61, 0x51, 0x49, 0x45, 0x43,// Z
|
||||
0x00, 0x00, 0x7F, 0x41, 0x41,// [
|
||||
0x02, 0x04, 0x08, 0x10, 0x20,// "\"
|
||||
0x41, 0x41, 0x7F, 0x00, 0x00,// ]
|
||||
0x04, 0x02, 0x01, 0x02, 0x04,// ^
|
||||
0x40, 0x40, 0x40, 0x40, 0x40,// _
|
||||
0x00, 0x01, 0x02, 0x04, 0x00,// `
|
||||
0x20, 0x54, 0x54, 0x54, 0x78,// a
|
||||
0x7F, 0x48, 0x44, 0x44, 0x38,// b
|
||||
0x38, 0x44, 0x44, 0x44, 0x20,// c
|
||||
0x38, 0x44, 0x44, 0x48, 0x7F,// d
|
||||
0x38, 0x54, 0x54, 0x54, 0x18,// e
|
||||
0x08, 0x7E, 0x09, 0x01, 0x02,// f
|
||||
0x08, 0x14, 0x54, 0x54, 0x3C,// g
|
||||
0x7F, 0x08, 0x04, 0x04, 0x78,// h
|
||||
0x00, 0x44, 0x7D, 0x40, 0x00,// i
|
||||
0x20, 0x40, 0x44, 0x3D, 0x00,// j
|
||||
0x00, 0x7F, 0x10, 0x28, 0x44,// k
|
||||
0x00, 0x41, 0x7F, 0x40, 0x00,// l
|
||||
0x7C, 0x04, 0x18, 0x04, 0x78,// m
|
||||
0x7C, 0x08, 0x04, 0x04, 0x78,// n
|
||||
0x38, 0x44, 0x44, 0x44, 0x38,// o
|
||||
0x7C, 0x14, 0x14, 0x14, 0x08,// p
|
||||
0x08, 0x14, 0x14, 0x18, 0x7C,// q
|
||||
0x7C, 0x08, 0x04, 0x04, 0x08,// r
|
||||
0x48, 0x54, 0x54, 0x54, 0x20,// s
|
||||
0x04, 0x3F, 0x44, 0x40, 0x20,// t
|
||||
0x3C, 0x40, 0x40, 0x20, 0x7C,// u
|
||||
0x1C, 0x20, 0x40, 0x20, 0x1C,// v
|
||||
0x3C, 0x40, 0x30, 0x40, 0x3C,// w
|
||||
0x44, 0x28, 0x10, 0x28, 0x44,// x
|
||||
0x0C, 0x50, 0x50, 0x50, 0x3C,// y
|
||||
0x44, 0x64, 0x54, 0x4C, 0x44,// z
|
||||
0x00, 0x08, 0x36, 0x41, 0x00,// {
|
||||
0x00, 0x00, 0x7F, 0x00, 0x00,// |
|
||||
0x00, 0x41, 0x36, 0x08, 0x00,// }
|
||||
0x08, 0x08, 0x2A, 0x1C, 0x08,// ->
|
||||
0x08, 0x1C, 0x2A, 0x08, 0x08 // <-
|
||||
};
|
||||
|
||||
void drawString(const int x, const int y, const char* str, uint32_t color)
|
||||
{
|
||||
int _x = x;
|
||||
while(*str)
|
||||
{
|
||||
drawChar(_x, y, *str, color);
|
||||
str++;
|
||||
_x += 6;
|
||||
}
|
||||
}
|
||||
|
||||
void drawChar(const int x, const int y, const char c, uint32_t color)
|
||||
{
|
||||
SDL_Rect rect;
|
||||
for(unsigned int n=0; n<5; n++)
|
||||
{
|
||||
int bits = lcd_font[c * 5 + n];
|
||||
for(unsigned int m=0; m<8; m++)
|
||||
{
|
||||
rect.x = x * DRAW_SCALE + n * DRAW_SCALE;
|
||||
rect.y = y * DRAW_SCALE + m * DRAW_SCALE;
|
||||
rect.w = DRAW_SCALE;
|
||||
rect.h = DRAW_SCALE;
|
||||
if (bits & (1L << m))
|
||||
SDL_FillRect(screen, &rect, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawStringSmall(const int x, const int y, const char* str, uint32_t color)
|
||||
{
|
||||
int _x = x;
|
||||
while(*str)
|
||||
{
|
||||
drawCharSmall(_x, y, *str, color);
|
||||
str++;
|
||||
_x += 6 / DRAW_SCALE;
|
||||
}
|
||||
}
|
||||
|
||||
void drawCharSmall(const int x, const int y, const char c, uint32_t color)
|
||||
{
|
||||
SDL_Rect rect;
|
||||
for(unsigned int n=0; n<5; n++)
|
||||
{
|
||||
int bits = lcd_font[c * 5 + n];
|
||||
for(unsigned int m=0; m<8; m++)
|
||||
{
|
||||
rect.x = x * DRAW_SCALE + n;
|
||||
rect.y = y * DRAW_SCALE + m;
|
||||
rect.w = 1;
|
||||
rect.h = 1;
|
||||
if (bits & (1L << m))
|
||||
SDL_FillRect(screen, &rect, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawRect(const int x, const int y, const int w, const int h, uint32_t color)
|
||||
{
|
||||
SDL_Rect rect = {x * DRAW_SCALE, y * DRAW_SCALE, w * DRAW_SCALE, h * DRAW_SCALE};
|
||||
if (rect.w == 0) rect.w = 1;
|
||||
if (rect.h == 0) rect.h = 1;
|
||||
SDL_FillRect(screen, &rect, color);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef SIM_BASE_H
|
||||
#define SIM_BASE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
class simBaseComponent;
|
||||
extern std::vector<simBaseComponent*> simComponentList;
|
||||
|
||||
class simBaseComponent
|
||||
{
|
||||
public:
|
||||
simBaseComponent() : drawPosX(-1), drawPosY(-1) {simComponentList.push_back(this);}
|
||||
virtual ~simBaseComponent() {}
|
||||
|
||||
virtual void tick() {}//Called about every ms
|
||||
void doDraw() { if (drawPosX > -1) draw(drawPosX, drawPosY); }
|
||||
virtual void draw(int x, int y) {}//Called every screen draw (~25ms)
|
||||
|
||||
simBaseComponent* setDrawPosition(int x, int y) { drawPosX = x; drawPosY = y; return this; }
|
||||
private:
|
||||
int drawPosX, drawPosY;
|
||||
};
|
||||
|
||||
void drawRect(const int x, const int y, const int w, const int h, uint32_t color);
|
||||
void drawString(const int x, const int y, const char* str, uint32_t color);
|
||||
void drawChar(const int x, const int y, const char c, uint32_t color);
|
||||
void drawStringSmall(const int x, const int y, const char* str, uint32_t color);
|
||||
void drawCharSmall(const int x, const int y, const char c, uint32_t color);
|
||||
|
||||
#endif//SIM_BASE_H
|
||||
@@ -0,0 +1,49 @@
|
||||
#ifndef DELEGATE_H
|
||||
#define DELEGATE_H
|
||||
|
||||
#include <stddef.h>
|
||||
/* Here be dragons... */
|
||||
|
||||
template<typename A0=void, typename A1=void>
|
||||
class delegate
|
||||
{
|
||||
public:
|
||||
delegate() : object_ptr(NULL), stub_ptr(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T, void (T::*TMethod)(A0 a0, A1 a1)>
|
||||
static delegate from_method(T* object_ptr)
|
||||
{
|
||||
delegate d;
|
||||
d.object_ptr = object_ptr;
|
||||
d.stub_ptr = &method_stub<T, TMethod>;
|
||||
return d;
|
||||
}
|
||||
|
||||
void operator()(A0 a0, A1 a1) const
|
||||
{
|
||||
if (!object_ptr)
|
||||
return;
|
||||
return stub_ptr(object_ptr, a0, a1);
|
||||
}
|
||||
|
||||
operator bool() const { return object_ptr != NULL; }
|
||||
|
||||
private:
|
||||
typedef void (*stub_type)(void* object_ptr, A0 a0, A1 a1);
|
||||
|
||||
void* object_ptr;
|
||||
stub_type stub_ptr;
|
||||
|
||||
template <class T, void (T::*TMethod)(A0 a0, A1 a1)>
|
||||
static void method_stub(void* object_ptr, A0 a0, A1 a1)
|
||||
{
|
||||
T* p = static_cast<T*>(object_ptr);
|
||||
return (p->*TMethod)(a0, a1);
|
||||
}
|
||||
};
|
||||
|
||||
#define DELEGATE(DelegateType, Type, Object, Method) (DelegateType::from_method<Type, &Type::Method>(&Object))
|
||||
|
||||
#endif//DELEGATE_H
|
||||
@@ -0,0 +1,114 @@
|
||||
#include "display_HD44780.h"
|
||||
#include "arduinoIO.h"
|
||||
|
||||
displayHD44780Sim::displayHD44780Sim(arduinoIOSim* arduinoIO, int rsPinNr, int enablePinNr, int d4PinNr, int d5PinNr, int d6PinNr, int d7PinNr)
|
||||
{
|
||||
this->rsPin = rsPinNr;
|
||||
this->enablePin = enablePinNr;
|
||||
this->d4Pin = d4PinNr;
|
||||
this->d5Pin = d5PinNr;
|
||||
this->d6Pin = d6PinNr;
|
||||
this->d7Pin = d7PinNr;
|
||||
|
||||
readUpper = true;
|
||||
writeData = true;
|
||||
dataPos = 0;
|
||||
memset(data, ' ', 0x80);
|
||||
arduinoIO->registerPortCallback(enablePinNr, DELEGATE(ioDelegate, displayHD44780Sim, *this, enablePinUpdate));
|
||||
}
|
||||
displayHD44780Sim::~displayHD44780Sim()
|
||||
{
|
||||
}
|
||||
|
||||
void displayHD44780Sim::draw(int x, int y)
|
||||
{
|
||||
int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
|
||||
for(unsigned int y=0; y<4; y++)
|
||||
{
|
||||
for(unsigned int x=0; x<20; x++)
|
||||
{
|
||||
char c = data[x+row_offsets[y]];
|
||||
|
||||
drawRect(x* 6, y * 9, 5, 8, 0x202080);
|
||||
|
||||
if (c < 8)
|
||||
{
|
||||
for(unsigned int m=0; m<8; m++)
|
||||
{
|
||||
int bits = customFontData[c * 8 + m];
|
||||
for(unsigned int n=0; n<5; n++)
|
||||
{
|
||||
if (bits & _BV(4-n))
|
||||
drawRect(x * 6 + n, y * 9 + m, 1, 1, 0xAAAAEE);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
drawChar(x * 6, y * 9, c, 0xAAAAEE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void displayHD44780Sim::enablePinUpdate(int pinNr, bool high)
|
||||
{
|
||||
if (!high) return;
|
||||
|
||||
int n = 0;
|
||||
if (readOutput(d4Pin)) n |= _BV(0);
|
||||
if (readOutput(d5Pin)) n |= _BV(1);
|
||||
if (readOutput(d6Pin)) n |= _BV(2);
|
||||
if (readOutput(d7Pin)) n |= _BV(3);
|
||||
bool rs = readOutput(rsPin);
|
||||
|
||||
if (readUpper || rs != upperRS)
|
||||
{
|
||||
upperBits = n;
|
||||
readUpper = false;
|
||||
upperRS = rs;
|
||||
return;
|
||||
}
|
||||
readUpper = true;
|
||||
|
||||
n |= upperBits << 4;
|
||||
|
||||
if (!rs)
|
||||
{
|
||||
if (n == 0x01)//LCD_CLEARDISPLAY
|
||||
{
|
||||
memset(data, ' ', 0x80);
|
||||
dataPos = 0;
|
||||
writeData = true;
|
||||
}else if (n == 0x02)//LCD_RETURNHOME
|
||||
{
|
||||
dataPos = 0;
|
||||
writeData = true;
|
||||
}else if ((n & 0xFC) == 0x04)//LCD_ENTRYMODESET
|
||||
{
|
||||
}else if ((n & 0xF8) == 0x08)//LCD_DISPLAYCONTROL
|
||||
{
|
||||
}else if ((n & 0xF0) == 0x10)//LCD_CURSORSHIFT
|
||||
{
|
||||
}else if ((n & 0xE0) == 0x20)//LCD_FUNCTIONSET
|
||||
{
|
||||
}else if ((n & 0xC0) == 0x40)//LCD_SETCGRAMADDR
|
||||
{
|
||||
dataPos = (n & 0x3F);
|
||||
writeData = false;
|
||||
}else if (n & 0x80)//LCD_SETDDRAMADDR
|
||||
{
|
||||
dataPos = (n & 0x7F);
|
||||
writeData = true;
|
||||
}else{
|
||||
printf("Unknown HD44780 command: %02x\n", n);
|
||||
}
|
||||
}else{
|
||||
if (writeData)
|
||||
{
|
||||
data[dataPos] = n;
|
||||
dataPos = (dataPos + 1) % 0x80;
|
||||
}else{
|
||||
customFontData[dataPos] = n;
|
||||
dataPos = (dataPos + 1) % 0x40;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef DISPLAY_HD44780_SIM_H
|
||||
#define DISPLAY_HD44780_SIM_H
|
||||
|
||||
#include "base.h"
|
||||
#include "arduinoIO.h"
|
||||
|
||||
class displayHD44780Sim : public simBaseComponent
|
||||
{
|
||||
public:
|
||||
displayHD44780Sim(arduinoIOSim* arduinoIO, int rsPinNr, int enablePinNr, int d4PinNr, int d5PinNr, int d6PinNr, int d7PinNr);
|
||||
virtual ~displayHD44780Sim();
|
||||
|
||||
virtual void draw(int x, int y);
|
||||
private:
|
||||
int rsPin;
|
||||
int enablePin;
|
||||
int d4Pin;
|
||||
int d5Pin;
|
||||
int d6Pin;
|
||||
int d7Pin;
|
||||
|
||||
bool readUpper;
|
||||
bool upperRS;
|
||||
int upperBits;
|
||||
|
||||
bool writeData;
|
||||
int dataPos;
|
||||
char data[0x80];
|
||||
char customFontData[0x40];
|
||||
|
||||
void enablePinUpdate(int pinNr, bool high);
|
||||
};
|
||||
|
||||
#endif//STEPPER_SIM_H
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "display_SSD1309.h"
|
||||
|
||||
displaySDD1309Sim::displaySDD1309Sim(i2cSim* i2c, int id)
|
||||
{
|
||||
i2c->registerDevice(id, DELEGATE(i2cMessageDelegate, displaySDD1309Sim, *this, processMessage));
|
||||
lcd_data_pos = 0;
|
||||
}
|
||||
|
||||
displaySDD1309Sim::~displaySDD1309Sim()
|
||||
{
|
||||
}
|
||||
|
||||
void displaySDD1309Sim::processMessage(uint8_t* message, int length)
|
||||
{
|
||||
if (message[1] == 0x40)
|
||||
{
|
||||
//Data
|
||||
for(int n=2;n<length;n++)
|
||||
{
|
||||
lcd_data[lcd_data_pos] = message[n];
|
||||
lcd_data_pos = (lcd_data_pos + 1) % 1024;
|
||||
}
|
||||
}else if (message[1] == 0x00)
|
||||
{
|
||||
//Command
|
||||
for(int n=2;n<length;n++)
|
||||
{
|
||||
if ((message[n] & 0xF0) == 0x00)
|
||||
{
|
||||
lcd_data_pos = (lcd_data_pos & 0xFF0) | (message[n] & 0x0F);
|
||||
}else if ((message[n] & 0xF0) == 0x10)
|
||||
{
|
||||
lcd_data_pos = (lcd_data_pos & 0xF8F) | ((message[n] & 0x07) << 4);
|
||||
}else if ((message[n] & 0xF0) == 0xB0)
|
||||
{
|
||||
lcd_data_pos = (lcd_data_pos & 0x07F) | ((message[n] & 0x0F) << 7);
|
||||
}else if (message[n] == 0x20) { /*LCD_COMMAND_SET_ADDRESSING_MODE*/
|
||||
}else if (message[n] == 0x40) { /*Set start line*/
|
||||
}else if (message[n] == 0x81) { /*LCD_COMMAND_CONTRAST*/ n++;
|
||||
}else if (message[n] == 0xA1) { /*Segment remap*/
|
||||
}else if (message[n] == 0xA4) { /*LCD_COMMAND_FULL_DISPLAY_ON_DISABLE*/
|
||||
}else if (message[n] == 0xA5) { /*LCD_COMMAND_FULL_DISPLAY_ON_ENABLE*/
|
||||
}else if (message[n] == 0xA8) { /*Multiplex ratio*/ n++;
|
||||
}else if (message[n] == 0xC8) { /*COM scan output direction*/
|
||||
}else if (message[n] == 0xD3) { /*Display offset*/ n++;
|
||||
}else if (message[n] == 0xD5) { /*Display clock divider/freq*/ n++;
|
||||
}else if (message[n] == 0xD9) { /*Precharge period*/ n++;
|
||||
}else if (message[n] == 0xDA) { /*COM pins hardware configuration*/ n++;
|
||||
}else if (message[n] == 0xDB) { /*VCOMH Deslect level*/ n++;
|
||||
}else if (message[n] == 0xDF) { /*LCD_COMMAND_LOCK_COMMANDS*/ n++;
|
||||
}else if (message[n] == 0xAE) { //Display OFF
|
||||
}else if (message[n] == 0xAF) { //Display ON
|
||||
}else{
|
||||
printf("Unknown LCD CMD: %02x\n", message[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define LCD_GFX_WIDTH 128
|
||||
#define LCD_GFX_HEIGHT 64
|
||||
void displaySDD1309Sim::draw(int x, int y)
|
||||
{
|
||||
drawRect(x, y, LCD_GFX_WIDTH + 2, LCD_GFX_HEIGHT + 2, 0xFFFFFF);
|
||||
drawRect(x+1, y+1, LCD_GFX_WIDTH, LCD_GFX_HEIGHT, 0x101010);
|
||||
for(int _y=0;_y<64;_y++)
|
||||
{
|
||||
for(int _x=0;_x<128;_x++)
|
||||
{
|
||||
if (lcd_data[_x + (_y/8) * LCD_GFX_WIDTH] & _BV(_y%8))
|
||||
{
|
||||
drawRect(x+_x+1, y+_y+1, 1, 1, 0x8080FF);
|
||||
drawRect(x+_x+1, y+_y+1, 0, 1, 0x8080AF);
|
||||
drawRect(x+_x+1, y+_y+1, 1, 0, 0x8080AF);
|
||||
}else{
|
||||
drawRect(x+_x+1, y+_y+1, 0, 1, 0x202020);
|
||||
drawRect(x+_x+1, y+_y+1, 1, 0, 0x202020);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
SDL_LockSurface(screen);
|
||||
for(int y=0;y<64;y++)
|
||||
{
|
||||
for(int _y=0;_y<DRAW_SCALE;_y++)
|
||||
{
|
||||
uint32_t* pix = ((uint32_t*)screen->pixels) + screen->pitch / 4 * (y * DRAW_SCALE + _y + DRAW_SCALE);
|
||||
for(int _n=0;_n<DRAW_SCALE;_n++)
|
||||
*pix++ = 0xFFFFFF;
|
||||
for(int x=0;x<128;x++)
|
||||
{
|
||||
for(int _n=0;_n<DRAW_SCALE;_n++)
|
||||
{
|
||||
if (_n == 0 || _y == 0)
|
||||
*pix++ = (lcd_data[x + (y/8) * LCD_GFX_WIDTH] & _BV(y%8)) ? 0x8080AF : 0x101010;
|
||||
else
|
||||
*pix++ = (lcd_data[x + (y/8) * LCD_GFX_WIDTH] & _BV(y%8)) ? 0x8080FF : 0x202020;
|
||||
}
|
||||
}
|
||||
for(int _n=0;_n<DRAW_SCALE;_n++)
|
||||
*pix++ = 0xFFFFFF;
|
||||
}
|
||||
}
|
||||
for(int _y=0;_y<DRAW_SCALE;_y++)
|
||||
{
|
||||
uint32_t* pix = ((uint32_t*)screen->pixels) + screen->pitch / 4 * (_y);
|
||||
uint32_t* pix2 = ((uint32_t*)screen->pixels) + screen->pitch / 4 * (64 * DRAW_SCALE + _y + DRAW_SCALE);
|
||||
for(int x=0;x<130;x++)
|
||||
for(int _n=0;_n<DRAW_SCALE;_n++)
|
||||
{
|
||||
*pix++ = 0xFFFFFF;
|
||||
*pix2++ = 0xFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_UnlockSurface(screen);
|
||||
*/
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef DISPLAY_SSD1309_SIM_H
|
||||
#define DISPLAY_SSD1309_SIM_H
|
||||
|
||||
#include "i2c.h"
|
||||
|
||||
class displaySDD1309Sim : public simBaseComponent
|
||||
{
|
||||
public:
|
||||
displaySDD1309Sim(i2cSim* i2c, int id = 0x78);
|
||||
virtual ~displaySDD1309Sim();
|
||||
|
||||
virtual void draw(int x, int y);
|
||||
private:
|
||||
void processMessage(uint8_t* message, int length);
|
||||
|
||||
int lcd_data_pos;
|
||||
uint8_t lcd_data[1024];
|
||||
};
|
||||
|
||||
#endif//DISPLAY_SSD1309_SIM_H
|
||||
@@ -0,0 +1,32 @@
|
||||
#include "heater.h"
|
||||
#include "arduinoIO.h"
|
||||
|
||||
heaterSim::heaterSim(int heaterPinNr, adcSim* adc, int temperatureADCNr, float heaterStrength)
|
||||
{
|
||||
this->heaterPinNr = heaterPinNr;
|
||||
this->adc = adc;
|
||||
this->temperatureADCNr = temperatureADCNr;
|
||||
this->heaterStrength = heaterStrength;
|
||||
|
||||
this->temperature = 20;
|
||||
}
|
||||
|
||||
heaterSim::~heaterSim()
|
||||
{
|
||||
}
|
||||
|
||||
void heaterSim::tick()
|
||||
{
|
||||
if (readOutput(heaterPinNr))
|
||||
temperature += 0.03 * heaterStrength;
|
||||
else if (temperature > 20)
|
||||
temperature -= 0.03 * heaterStrength;
|
||||
adc->adcValue[temperatureADCNr] = 231 + temperature * 81 / 100;//Not accurate, but accurate enough.
|
||||
}
|
||||
|
||||
void heaterSim::draw(int x, int y)
|
||||
{
|
||||
char buffer[32];
|
||||
sprintf(buffer, "%iC", int(temperature));
|
||||
drawString(x, y, buffer, 0xFFFFFF);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef HEATER_SIM_H
|
||||
#define HEATER_SIM_H
|
||||
|
||||
#include "base.h"
|
||||
#include "adc.h"
|
||||
|
||||
class heaterSim : public simBaseComponent
|
||||
{
|
||||
public:
|
||||
heaterSim(int heaterPinNr, adcSim* adc, int temperatureADCNr, float heaterStrength = 1.0);
|
||||
virtual ~heaterSim();
|
||||
|
||||
virtual void tick();
|
||||
virtual void draw(int x, int y);
|
||||
private:
|
||||
float temperature;
|
||||
float heaterStrength;
|
||||
|
||||
int heaterPinNr;
|
||||
adcSim* adc;
|
||||
int temperatureADCNr;
|
||||
};
|
||||
|
||||
#endif//I2C_SIM_H
|
||||
@@ -0,0 +1,59 @@
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "i2c.h"
|
||||
|
||||
i2cSim::i2cSim()
|
||||
{
|
||||
TWCR.setCallback(DELEGATE(registerDelegate, i2cSim, *this, I2C_TWCR_callback));
|
||||
}
|
||||
|
||||
i2cSim::~i2cSim()
|
||||
{
|
||||
}
|
||||
|
||||
void i2cSim::I2C_TWCR_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
if ((oldValue ^ newValue) == _BV(TWIE) && (newValue & _BV(TWIE)))
|
||||
return;
|
||||
if ((newValue & _BV(TWINT)) && (newValue & _BV(TWEN)))
|
||||
{
|
||||
if (newValue & _BV(TWSTA))
|
||||
{
|
||||
if (i2cMessagePos > 0)
|
||||
{
|
||||
if (i2cDevice[i2cMessage[0]])
|
||||
i2cDevice[i2cMessage[0]](i2cMessage, i2cMessagePos);
|
||||
else
|
||||
printf("i2c message to unknown device ID: %02x\n", i2cMessage[0]);
|
||||
}
|
||||
i2cMessagePos = 0;
|
||||
i2cMessage[0] = 0xFF;
|
||||
TWSR = 0x08;
|
||||
} else if (newValue & _BV(TWSTO))
|
||||
{
|
||||
if (i2cDevice[i2cMessage[0]])
|
||||
i2cDevice[i2cMessage[0]](i2cMessage, i2cMessagePos);
|
||||
else
|
||||
printf("i2c message to unknown device ID: %02x\n", i2cMessage[0]);
|
||||
i2cMessagePos = 0;
|
||||
newValue &=~_BV(TWINT);
|
||||
newValue &=~_BV(TWSTO);
|
||||
TWSR = 0x00;
|
||||
}else{
|
||||
i2cMessage[i2cMessagePos] = TWDR;
|
||||
i2cMessagePos++;
|
||||
TWDR = 0x00;
|
||||
if (TWSR == 0x08)
|
||||
TWSR = 0x18;
|
||||
else if (TWSR == 0x18)
|
||||
TWSR = 0x28;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void i2cSim::registerDevice(int id, i2cMessageDelegate func)
|
||||
{
|
||||
if (id < 0 || id > 255)
|
||||
return;
|
||||
i2cDevice[id] = func;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef I2C_SIM_H
|
||||
#define I2C_SIM_H
|
||||
|
||||
#include "base.h"
|
||||
|
||||
typedef delegate<uint8_t*, int> i2cMessageDelegate;
|
||||
|
||||
class i2cSim : public simBaseComponent
|
||||
{
|
||||
public:
|
||||
i2cSim();
|
||||
virtual ~i2cSim();
|
||||
|
||||
void registerDevice(int id, i2cMessageDelegate func);
|
||||
|
||||
void I2C_TWCR_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
private:
|
||||
int i2cMessagePos;
|
||||
uint8_t i2cMessage[2048];
|
||||
i2cMessageDelegate i2cDevice[256];
|
||||
};
|
||||
|
||||
#endif//I2C_SIM_H
|
||||
@@ -0,0 +1,68 @@
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "led_PCA9632.h"
|
||||
|
||||
ledPCA9632Sim::ledPCA9632Sim(i2cSim* i2c, int id)
|
||||
{
|
||||
i2c->registerDevice(id, DELEGATE(i2cMessageDelegate, ledPCA9632Sim, *this, processMessage));
|
||||
}
|
||||
|
||||
ledPCA9632Sim::~ledPCA9632Sim()
|
||||
{
|
||||
}
|
||||
|
||||
void ledPCA9632Sim::processMessage(uint8_t* message, int length)
|
||||
{
|
||||
int regAddr = message[1] & 0x0F;
|
||||
for(int n=2; n<length; n++)
|
||||
{
|
||||
switch(regAddr)
|
||||
{
|
||||
case 0x00://MODE1
|
||||
break;
|
||||
case 0x01://MODE2
|
||||
break;
|
||||
case 0x02://PWM0
|
||||
pwm[0] = message[n];
|
||||
break;
|
||||
case 0x03://PWM1
|
||||
pwm[1] = message[n];
|
||||
break;
|
||||
case 0x04://PWM2
|
||||
pwm[2] = message[n];
|
||||
break;
|
||||
case 0x05://PWM3
|
||||
pwm[3] = message[n];
|
||||
break;
|
||||
case 0x06://GRPPWM
|
||||
break;
|
||||
case 0x07://GRPFREQ
|
||||
break;
|
||||
case 0x08://LEDOUT
|
||||
ledout = message[n];
|
||||
break;
|
||||
default:
|
||||
printf("LED: %02x: %02x\n", regAddr, message[n]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (message[1] & 0x80)
|
||||
{
|
||||
regAddr++;
|
||||
if (regAddr > 0x0C)
|
||||
regAddr = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ledPCA9632Sim::draw(int x, int y)
|
||||
{
|
||||
int r=0,g=0,b=0;
|
||||
if ((ledout & 0x03) == 1) r = 0xff;
|
||||
if ((ledout & 0x03) == 2) r = pwm[0];
|
||||
if (((ledout >> 2) & 0x03) == 1) g = 0xff;
|
||||
if (((ledout >> 2) & 0x03) == 2) g = pwm[1];
|
||||
if (((ledout >> 4) & 0x03) == 1) b = 0xff;
|
||||
if (((ledout >> 4) & 0x03) == 2) b = pwm[2];
|
||||
drawRect(x, y, 128, 3, r << 16 | g << 8 | b);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef LED_PCA9532_SIM_H
|
||||
#define LED_PCA9532_SIM_H
|
||||
|
||||
#include "i2c.h"
|
||||
|
||||
class ledPCA9632Sim : public simBaseComponent
|
||||
{
|
||||
public:
|
||||
ledPCA9632Sim(i2cSim* i2c, int id = 0xC0);
|
||||
virtual ~ledPCA9632Sim();
|
||||
|
||||
virtual void draw(int x, int y);
|
||||
private:
|
||||
void processMessage(uint8_t* message, int length);
|
||||
|
||||
int pwm[4];
|
||||
int ledout;
|
||||
};
|
||||
|
||||
|
||||
#endif//LED_PCA9532_SIM_H
|
||||
@@ -0,0 +1,270 @@
|
||||
#include <dirent.h>
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "sdcard.h"
|
||||
#include "../../Marlin/SdFatStructs.h"
|
||||
|
||||
sdcardSimulation::sdcardSimulation(const char* basePath, int errorRate)
|
||||
: errorRate(errorRate)
|
||||
{
|
||||
this->basePath = basePath;
|
||||
|
||||
SPDR.setCallback(DELEGATE(registerDelegate, sdcardSimulation, *this, ISP_SPDR_callback));
|
||||
|
||||
sd_state = 0;
|
||||
sd_buffer_pos = 0;
|
||||
}
|
||||
|
||||
sdcardSimulation::~sdcardSimulation()
|
||||
{
|
||||
}
|
||||
|
||||
static const uint16_t crctab[] = {
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
|
||||
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
|
||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
|
||||
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
|
||||
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
|
||||
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
|
||||
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
|
||||
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
|
||||
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
|
||||
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
|
||||
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
|
||||
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
|
||||
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
|
||||
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
|
||||
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
|
||||
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
|
||||
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
|
||||
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
|
||||
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
|
||||
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
|
||||
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
|
||||
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
|
||||
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
|
||||
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
|
||||
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
|
||||
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
|
||||
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
|
||||
};
|
||||
static uint16_t CRC_CCITT(const uint8_t* data, size_t n) {
|
||||
uint16_t crc = 0;
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
crc = crctab[(crc >> 8 ^ data[i]) & 0XFF] ^ (crc << 8);
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
FILE* simFile;
|
||||
//Total crappy fake FAT32 simulation, works for 1 file, sort of.
|
||||
void sdcardSimulation::read_sd_block(int nr)
|
||||
{
|
||||
memset(sd_buffer, 0, 512);
|
||||
switch(nr)
|
||||
{
|
||||
case 0x000:{//MBR
|
||||
mbr_t* mbr = (mbr_t*)sd_buffer;
|
||||
mbr->part[0].boot = 0;
|
||||
mbr->part[0].totalSectors = 0x200000;
|
||||
mbr->part[0].firstSector = 1;
|
||||
}break;
|
||||
case 0x001:{//fat32_boot_t
|
||||
fat32_boot_t* boot = (fat32_boot_t*)sd_buffer;
|
||||
boot->bytesPerSector = 512;
|
||||
boot->fatCount = 1;
|
||||
boot->reservedSectorCount = 1;
|
||||
boot->sectorsPerCluster = 1;
|
||||
boot->sectorsPerFat32 = 0x400;
|
||||
boot->rootDirEntryCount = 0;
|
||||
boot->fat32RootCluster = 1;
|
||||
}break;
|
||||
case 0x002:{//FAT32 for root dir entries
|
||||
uint32_t* fat32 = (uint32_t*)sd_buffer;
|
||||
for(uint8_t n=0;n<128;n++)
|
||||
fat32[n] = 0X0FFFFFF8;
|
||||
for(uint8_t n=0;n<128;n++)
|
||||
fat32[n] = n + 1;
|
||||
fat32[127] = 0X0FFFFFF8;
|
||||
}break;
|
||||
default:
|
||||
if (nr >= 0x401 && nr < 0x500) //root directory: dir_t
|
||||
{
|
||||
dir_t* dir = (dir_t*)sd_buffer;
|
||||
|
||||
DIR* dh = opendir(basePath);
|
||||
struct dirent *entry;
|
||||
int idx = 0;
|
||||
int reqIdx = nr - 0x401;
|
||||
while((entry=readdir(dh))!=NULL)
|
||||
{
|
||||
if (entry->d_name[0] == '.')
|
||||
continue;
|
||||
if (idx == reqIdx)
|
||||
break;
|
||||
idx++;
|
||||
}
|
||||
if (entry == NULL)
|
||||
return;
|
||||
|
||||
const char* namePtr = entry->d_name;
|
||||
|
||||
int fatNr = 0;
|
||||
while(*namePtr)
|
||||
{
|
||||
vfat_t *vfat = (vfat_t*)dir;
|
||||
vfat->firstClusterLow = 0;
|
||||
vfat->sequenceNumber = 0x41 + fatNr;
|
||||
for(unsigned int n=0;n<5&&*namePtr;n++)
|
||||
vfat->name1[n*2] = *namePtr++;
|
||||
for(unsigned int n=0;n<6&&*namePtr;n++)
|
||||
vfat->name2[n*2] = *namePtr++;
|
||||
for(unsigned int n=0;n<2&&*namePtr;n++)
|
||||
vfat->name3[n*2] = *namePtr++;
|
||||
vfat->attributes = DIR_ATT_LONG_NAME;
|
||||
dir++;
|
||||
fatNr++;
|
||||
}
|
||||
|
||||
dir->attributes = 0;
|
||||
memcpy(dir->name, "FAKEFILEXCO", 8+3);
|
||||
if (strrchr(entry->d_name, '.'))
|
||||
dir->name[8] = toupper(strrchr(entry->d_name, '.')[1]);
|
||||
dir->firstClusterHigh = 0;
|
||||
dir->firstClusterLow = 256;
|
||||
if (simFile == NULL)
|
||||
simFile = fopen("c:/models/Box_20x20x10.gcode", "rb");
|
||||
fseek(simFile, 0, SEEK_END);
|
||||
dir->fileSize = ftell(simFile);
|
||||
fseek(simFile, 0, SEEK_SET);
|
||||
|
||||
dir++;
|
||||
fatNr++;
|
||||
|
||||
closedir(dh);
|
||||
|
||||
while(fatNr < 16)
|
||||
{
|
||||
dir->attributes = DIR_ATT_HIDDEN;
|
||||
dir->name[0] = DIR_NAME_DELETED;
|
||||
|
||||
dir++;
|
||||
fatNr++;
|
||||
}
|
||||
}
|
||||
else if (nr >= 4 && nr < 0x400)
|
||||
{
|
||||
//FAT32 tables for file, just link to the next block
|
||||
uint32_t* fat32 = (uint32_t*)sd_buffer;
|
||||
for(uint8_t n=0;n<128;n++)
|
||||
fat32[n] = (nr-2) * 128 + n + 1;
|
||||
}
|
||||
else if (nr >= 0x500 && nr < 0x20000)
|
||||
{
|
||||
//Actual data blocks
|
||||
fseek(simFile, (nr - 0x501) * 512, SEEK_SET);
|
||||
fread(sd_buffer, 512, 1, simFile);
|
||||
}else{
|
||||
memset(sd_buffer, 0xFF, 512);
|
||||
printf("Read SD?: %x\n", nr);
|
||||
//exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t crc = CRC_CCITT(sd_buffer, 512);
|
||||
sd_buffer[512] = crc >> 8;
|
||||
sd_buffer[513] = crc;
|
||||
}
|
||||
|
||||
void sdcardSimulation::ISP_SPDR_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
if (errorRate && (rand() % errorRate) == 0)
|
||||
newValue = rand();
|
||||
if ((PING & _BV(2)))
|
||||
{
|
||||
//No card inserted, return 0xFF
|
||||
newValue = 0xFF;
|
||||
SPSR |= _BV(SPIF);//Mark transfer finished
|
||||
return;
|
||||
}
|
||||
switch(sd_state)
|
||||
{
|
||||
case 0://Read CMD
|
||||
case 2://Read ACMD
|
||||
sd_buffer[sd_buffer_pos++] = newValue;
|
||||
if (sd_buffer_pos == 1 && (sd_buffer[0] & 0xC0) != 0x40)
|
||||
sd_buffer_pos = 0;
|
||||
if (sd_buffer_pos == 6) // 1 cmd, 4 param, 1 crc
|
||||
sd_state += 1;
|
||||
break;
|
||||
case 1://Return status of CMD
|
||||
sd_state = 0;
|
||||
sd_buffer_pos = 0;
|
||||
|
||||
switch(sd_buffer[0] & 0x3F)
|
||||
{
|
||||
case 0x00://CMD0 - GO_IDLE_STATE
|
||||
newValue = 0x01; //Report R1_IDLE_STATE
|
||||
break;
|
||||
case 0x08://CMD8 - SEND_IF_COND
|
||||
newValue = 0x04; //Report R1_ILLEGAL_COMMAND
|
||||
break;
|
||||
case 0x0C://CMD12 - STOP_TRANSMISSION
|
||||
newValue = 0x01; //Report R1_IDLE_STATE
|
||||
break;
|
||||
case 0x11://CMD17 - READ_SINGLE_BLOCK
|
||||
newValue = 0x00;//R1_READY_STATE
|
||||
sd_read_block_nr = (sd_buffer[1] << 24) | (sd_buffer[2] << 16) | (sd_buffer[3] << 8) | (sd_buffer[4] << 0);
|
||||
read_sd_block(sd_read_block_nr >> 9);
|
||||
sd_state = 10;
|
||||
sd_buffer_pos = 0;
|
||||
break;
|
||||
case 0x37://CMD55 - APP_CMD
|
||||
sd_state = 2;
|
||||
break;
|
||||
default:
|
||||
printf("SD CMD: %02x %02x %02x %02x %02x %02x\n", sd_buffer[0] & 0x3F, sd_buffer[1], sd_buffer[2], sd_buffer[3], sd_buffer[4], sd_buffer[5]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 3://Return status of ACMD
|
||||
sd_state = 0;
|
||||
sd_buffer_pos = 0;
|
||||
|
||||
switch(sd_buffer[0] & 0x3F)
|
||||
{
|
||||
case 0x29://ACMD41 - SD_SEND_OP_COMD
|
||||
newValue = 0x00;//R1_READY_STATE
|
||||
break;
|
||||
default:
|
||||
printf("SD ACMD: %02x %02x %02x %02x %02x %02x\n", sd_buffer[0] & 0x3F, sd_buffer[1], sd_buffer[2], sd_buffer[3], sd_buffer[4], sd_buffer[5]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 10://READ BLOCK
|
||||
if (sd_buffer_pos == 0)
|
||||
newValue = 0xFE;//DATA_START_BLOCK
|
||||
else
|
||||
newValue = sd_buffer[sd_buffer_pos-1];
|
||||
|
||||
sd_buffer_pos++;
|
||||
if (sd_buffer_pos == 512 + 1 + 2)
|
||||
{
|
||||
sd_state = 0;
|
||||
sd_buffer_pos = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
//Introduce random errors in SD communication
|
||||
if (errorRate && (rand() % errorRate) == 0)
|
||||
newValue = rand();
|
||||
|
||||
//Mark transfer finished
|
||||
SPSR |= _BV(SPIF);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef SDCARD_SIM_H
|
||||
#define SDCARD_SIM_H
|
||||
|
||||
#include "base.h"
|
||||
|
||||
class sdcardSimulation : public simBaseComponent
|
||||
{
|
||||
private:
|
||||
const char* basePath;
|
||||
public:
|
||||
sdcardSimulation(const char* basePath, int errorRate=0);
|
||||
virtual ~sdcardSimulation();
|
||||
|
||||
void ISP_SPDR_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void read_sd_block(int nr);
|
||||
|
||||
int sd_state;
|
||||
uint8_t sd_buffer[1024];
|
||||
int sd_buffer_pos;
|
||||
int sd_read_block_nr;
|
||||
int errorRate;
|
||||
};
|
||||
|
||||
#endif//SDCARD_SIM_H
|
||||
@@ -0,0 +1,49 @@
|
||||
#include <avr/io.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "serial.h"
|
||||
|
||||
serialSim::serialSim()
|
||||
{
|
||||
UCSR0A.setCallback(DELEGATE(registerDelegate, serialSim, *this, UART_UCSR0A_callback));
|
||||
UDR0.setCallback(DELEGATE(registerDelegate, serialSim, *this, UART_UDR0_callback));
|
||||
|
||||
UCSR0A = 0;
|
||||
|
||||
recvLine = 0;
|
||||
recvPos = 0;
|
||||
memset(recvBuffer, '\0', sizeof(recvBuffer));
|
||||
}
|
||||
|
||||
serialSim::~serialSim()
|
||||
{
|
||||
}
|
||||
|
||||
void serialSim::UART_UCSR0A_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
//Always mark "write ready" flag, so the serial code never waits.
|
||||
newValue |= _BV(UDRE0);
|
||||
}
|
||||
void serialSim::UART_UDR0_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
recvBuffer[recvLine][recvPos] = newValue;
|
||||
recvPos++;
|
||||
if (recvPos == 80 || newValue == '\n')
|
||||
{
|
||||
recvPos = 0;
|
||||
recvLine++;
|
||||
if (recvLine == SERIAL_LINE_COUNT)
|
||||
{
|
||||
for(unsigned int n=0; n<SERIAL_LINE_COUNT-1;n++)
|
||||
memcpy(recvBuffer[n], recvBuffer[n+1], 80);
|
||||
recvLine--;
|
||||
memset(recvBuffer[recvLine], '\0', 80);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void serialSim::draw(int x, int y)
|
||||
{
|
||||
for(unsigned int n=0; n<SERIAL_LINE_COUNT;n++)
|
||||
drawStringSmall(x, y+n*3, recvBuffer[n], 0xFFFFFF);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef SERIAL_SIM_H
|
||||
#define SERIAL_SIM_H
|
||||
|
||||
#include "base.h"
|
||||
|
||||
#define SERIAL_LINE_COUNT 30
|
||||
class serialSim : public simBaseComponent
|
||||
{
|
||||
public:
|
||||
serialSim();
|
||||
virtual ~serialSim();
|
||||
|
||||
virtual void draw(int x, int y);
|
||||
|
||||
private:
|
||||
int recvLine, recvPos;
|
||||
char recvBuffer[SERIAL_LINE_COUNT][80];
|
||||
|
||||
void UART_UCSR0A_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void UART_UDR0_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
};
|
||||
|
||||
#endif//SERIAL_SIM_H
|
||||
@@ -0,0 +1,59 @@
|
||||
#include "stepper.h"
|
||||
#include "arduinoIO.h"
|
||||
|
||||
stepperSim::stepperSim(arduinoIOSim* arduinoIO, int enablePinNr, int stepPinNr, int dirPinNr, bool invertDir)
|
||||
{
|
||||
this->minStepValue = -1;
|
||||
this->maxStepValue = -1;
|
||||
this->stepValue = 0;
|
||||
this->minEndstopPin = -1;
|
||||
this->maxEndstopPin = -1;
|
||||
|
||||
this->invertDir = invertDir;
|
||||
this->enablePin = enablePinNr;
|
||||
this->stepPin = stepPinNr;
|
||||
this->dirPin = dirPinNr;
|
||||
|
||||
arduinoIO->registerPortCallback(stepPinNr, DELEGATE(ioDelegate, stepperSim, *this, stepPinUpdate));
|
||||
}
|
||||
stepperSim::~stepperSim()
|
||||
{
|
||||
}
|
||||
|
||||
void stepperSim::stepPinUpdate(int pinNr, bool high)
|
||||
{
|
||||
if (high)//Only step on high->low transition.
|
||||
return;
|
||||
if (readOutput(enablePin))
|
||||
return;
|
||||
if (readOutput(dirPin) == invertDir)
|
||||
stepValue --;
|
||||
else
|
||||
stepValue ++;
|
||||
if (minStepValue == -1)
|
||||
return;
|
||||
if (stepValue < minStepValue)
|
||||
stepValue = minStepValue;
|
||||
if (stepValue > maxStepValue)
|
||||
stepValue = maxStepValue;
|
||||
if (minEndstopPin > -1)
|
||||
writeInput(minEndstopPin, stepValue != minStepValue);
|
||||
if (maxEndstopPin > -1)
|
||||
writeInput(maxEndstopPin, stepValue != maxStepValue);
|
||||
}
|
||||
|
||||
void stepperSim::setEndstops(int minEndstopPinNr, int maxEndstopPinNr)
|
||||
{
|
||||
minEndstopPin = minEndstopPinNr;
|
||||
maxEndstopPin = maxEndstopPinNr;
|
||||
|
||||
writeInput(minEndstopPin, stepValue != minStepValue);
|
||||
writeInput(maxEndstopPin, stepValue != maxStepValue);
|
||||
}
|
||||
|
||||
void stepperSim::draw(int x, int y)
|
||||
{
|
||||
char buffer[32];
|
||||
sprintf(buffer, "%i steps", int(stepValue));
|
||||
drawString(x, y, buffer, 0xFFFFFF);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef STEPPER_SIM_H
|
||||
#define STEPPER_SIM_H
|
||||
|
||||
#include "base.h"
|
||||
#include "arduinoIO.h"
|
||||
|
||||
class stepperSim : public simBaseComponent
|
||||
{
|
||||
private:
|
||||
int minStepValue;
|
||||
int maxStepValue;
|
||||
int stepValue;
|
||||
bool invertDir;
|
||||
int enablePin, stepPin, dirPin;
|
||||
int minEndstopPin, maxEndstopPin;
|
||||
public:
|
||||
stepperSim(arduinoIOSim* arduinoIO, int enablePinNr, int stepPinNr, int dirPinNr, bool invertDir);
|
||||
virtual ~stepperSim();
|
||||
|
||||
virtual void draw(int x, int y);
|
||||
|
||||
void setRange(int minValue, int maxValue) { minStepValue = minValue; maxStepValue = maxValue; stepValue = (maxValue + minValue) / 2; }
|
||||
void setEndstops(int minEndstopPinNr, int maxEndstopPinNr);
|
||||
int getPosition() { return stepValue; }
|
||||
private:
|
||||
void stepPinUpdate(int pinNr, bool high);
|
||||
};
|
||||
|
||||
#endif//STEPPER_SIM_H
|
||||
@@ -0,0 +1,250 @@
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "component/sdcard.h"
|
||||
#include "component/adc.h"
|
||||
#include "component/heater.h"
|
||||
#include "component/serial.h"
|
||||
#include "component/display_SSD1309.h"
|
||||
#include "component/display_HD44780.h"
|
||||
#include "component/led_PCA9632.h"
|
||||
#include "component/arduinoIO.h"
|
||||
#include "component/stepper.h"
|
||||
|
||||
#include "../Marlin/UltiLCD2.h"
|
||||
#include "../Marlin/temperature.h"
|
||||
#include "../Marlin/stepper.h"
|
||||
|
||||
SDL_Surface *screen;
|
||||
|
||||
extern int8_t lcd_lib_encoder_pos_interrupt;
|
||||
extern int8_t encoderDiff;
|
||||
extern uint8_t __eeprom__storage[4096];
|
||||
|
||||
bool cardInserted = true;
|
||||
int stoppedValue;
|
||||
|
||||
void setupGui()
|
||||
{
|
||||
if ( SDL_Init(SDL_INIT_VIDEO) < 0 )
|
||||
{
|
||||
fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
atexit(SDL_Quit);
|
||||
|
||||
screen = SDL_SetVideoMode(1024, 600, 32, SDL_SWSURFACE);
|
||||
}
|
||||
|
||||
unsigned long lastUpdate = SDL_GetTicks();
|
||||
int key_delay;
|
||||
#define KEY_REPEAT_DELAY 3
|
||||
#define SCALE 3
|
||||
void guiUpdate()
|
||||
{
|
||||
for(unsigned int n=0; n<simComponentList.size(); n++)
|
||||
simComponentList[n]->tick();
|
||||
|
||||
if (SDL_GetTicks() - lastUpdate < 25)
|
||||
return;
|
||||
lastUpdate = SDL_GetTicks();
|
||||
|
||||
int clickX = -1, clickY = -1;
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
switch (event.type)
|
||||
{
|
||||
case SDL_KEYDOWN:
|
||||
key_delay = 0;
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
// If escape is pressed, quit
|
||||
if (event.key.keysym.sym == SDLK_ESCAPE)
|
||||
{
|
||||
FILE* f = fopen("eeprom.save", "wb");
|
||||
fwrite(__eeprom__storage, sizeof(__eeprom__storage), 1, f);
|
||||
fclose(f);
|
||||
exit(0);
|
||||
}
|
||||
if (event.key.keysym.sym == SDLK_p)
|
||||
{
|
||||
SDL_Surface* tmpSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, 128*SCALE,64*SCALE,32, 0, 0, 0, 0);
|
||||
SDL_Rect src = {SCALE, SCALE, 128*SCALE,64*SCALE};
|
||||
SDL_Rect dst = {0, 0, 128*SCALE,64*SCALE};
|
||||
SDL_BlitSurface(screen, &src, tmpSurface, &dst);
|
||||
char filename[128];
|
||||
static int screenshotNr = 0;
|
||||
sprintf(filename, "screen%i.bmp", screenshotNr);
|
||||
screenshotNr++;
|
||||
SDL_SaveBMP(tmpSurface, filename);
|
||||
SDL_FreeSurface(tmpSurface);
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
if (event.motion.state)
|
||||
{
|
||||
#ifdef ENABLE_ULTILCD2
|
||||
lcd_lib_encoder_pos_interrupt += event.motion.xrel / 2;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
clickX = event.button.x;
|
||||
clickY = event.button.y;
|
||||
break;
|
||||
case SDL_QUIT:
|
||||
{
|
||||
FILE* f = fopen("eeprom.save", "wb");
|
||||
fwrite(__eeprom__storage, sizeof(__eeprom__storage), 1, f);
|
||||
fclose(f);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
Uint8* keys = SDL_GetKeyState(NULL);
|
||||
writeInput(BTN_ENC, !keys[SDLK_RETURN]);
|
||||
if (keys[SDLK_RIGHT])
|
||||
{
|
||||
if (key_delay == 0)
|
||||
{
|
||||
#ifdef ENABLE_ULTILCD2
|
||||
lcd_lib_encoder_pos_interrupt+=2;
|
||||
#endif
|
||||
#ifdef ULTIPANEL
|
||||
encoderDiff+=2;
|
||||
#endif
|
||||
key_delay = KEY_REPEAT_DELAY;
|
||||
}else
|
||||
key_delay--;
|
||||
}
|
||||
if (keys[SDLK_LEFT])
|
||||
{
|
||||
if (key_delay == 0)
|
||||
{
|
||||
#ifdef ENABLE_ULTILCD2
|
||||
lcd_lib_encoder_pos_interrupt-=2;
|
||||
#endif
|
||||
#ifdef ULTIPANEL
|
||||
encoderDiff-=2;
|
||||
#endif
|
||||
key_delay = KEY_REPEAT_DELAY;
|
||||
}else
|
||||
key_delay--;
|
||||
}
|
||||
|
||||
SDL_FillRect(screen, NULL, 0x000000);
|
||||
for(unsigned int n=0; n<simComponentList.size(); n++)
|
||||
simComponentList[n]->doDraw();
|
||||
|
||||
SDL_Rect rect;
|
||||
rect.w = 32;
|
||||
rect.h = 32;
|
||||
rect.x = 128 * SCALE + 32;
|
||||
rect.y = 32;
|
||||
|
||||
if (clickX >= rect.x && clickX <= rect.x + rect.w && clickY >= rect.y && clickY <= rect.y + rect.h)
|
||||
cardInserted = !cardInserted;
|
||||
SDL_FillRect(screen, &rect, cardInserted ? 0x00FF00 : 0xFF0000);
|
||||
rect.y += 48;
|
||||
writeInput(SDCARDDETECT, !cardInserted);
|
||||
|
||||
if (clickX >= rect.x && clickX <= rect.x + rect.w && clickY >= rect.y && clickY <= rect.y + rect.h)
|
||||
stoppedValue = !stoppedValue;
|
||||
writeInput(SAFETY_TRIGGERED_PIN, stoppedValue);
|
||||
|
||||
SDL_FillRect(screen, &rect, stoppedValue ? 0x00FF00 : 0xFF0000);
|
||||
rect.y += 48;
|
||||
|
||||
SDL_Flip(screen);
|
||||
}
|
||||
|
||||
#define PRINTER_DOWN_SCALE 2
|
||||
class printerSim : public simBaseComponent
|
||||
{
|
||||
private:
|
||||
stepperSim* x;
|
||||
stepperSim* y;
|
||||
stepperSim* z;
|
||||
stepperSim* e0;
|
||||
stepperSim* e1;
|
||||
int e0stepPos, e1stepPos;
|
||||
int map[X_MAX_LENGTH/PRINTER_DOWN_SCALE+1][Y_MAX_LENGTH/PRINTER_DOWN_SCALE+1];
|
||||
public:
|
||||
printerSim(stepperSim* x, stepperSim* y, stepperSim* z, stepperSim* e0, stepperSim* e1)
|
||||
: x(x), y(y), z(z), e0(e0), e1(e1)
|
||||
{
|
||||
e0stepPos = e0->getPosition();
|
||||
e1stepPos = e1->getPosition();
|
||||
memset(map, 0, sizeof(map));
|
||||
}
|
||||
virtual ~printerSim()
|
||||
{
|
||||
}
|
||||
|
||||
void draw(int _x, int _y)
|
||||
{
|
||||
drawRect(_x, _y, X_MAX_LENGTH / PRINTER_DOWN_SCALE + 1, Y_MAX_LENGTH / PRINTER_DOWN_SCALE + 1, 0x202020);
|
||||
for(unsigned int py=0; py<Y_MAX_LENGTH/PRINTER_DOWN_SCALE; py++)
|
||||
for(unsigned int px=0; px<X_MAX_LENGTH/PRINTER_DOWN_SCALE; px++)
|
||||
drawRect(_x+px, _y+py, 1, 1, map[px][py] + 0x202020);
|
||||
|
||||
drawRect(_x + X_MAX_LENGTH / PRINTER_DOWN_SCALE + 2, _y, 1, Z_MAX_LENGTH / PRINTER_DOWN_SCALE + 1, 0x202020);
|
||||
|
||||
float pos[3];
|
||||
float stepsPerUnit[4] = DEFAULT_AXIS_STEPS_PER_UNIT;
|
||||
pos[0] = x->getPosition() / stepsPerUnit[X_AXIS];
|
||||
pos[1] = Y_MAX_POS - y->getPosition() / stepsPerUnit[Y_AXIS];
|
||||
pos[2] = z->getPosition() / stepsPerUnit[Z_AXIS];
|
||||
|
||||
map[int(pos[0]/PRINTER_DOWN_SCALE)][int(pos[1]/PRINTER_DOWN_SCALE)] += e0->getPosition() - e0stepPos;
|
||||
map[int(pos[0]/PRINTER_DOWN_SCALE)][int(pos[1]/PRINTER_DOWN_SCALE)] += e1->getPosition() - e1stepPos;
|
||||
|
||||
e0stepPos = e0->getPosition();
|
||||
e1stepPos = e1->getPosition();
|
||||
|
||||
drawRect(_x + pos[0] / PRINTER_DOWN_SCALE, _y + pos[1] / PRINTER_DOWN_SCALE, 1, 1, 0xFFFFFF);
|
||||
drawRect(_x + X_MAX_LENGTH / PRINTER_DOWN_SCALE + 2, _y + pos[2] / PRINTER_DOWN_SCALE, 1, 1, 0xFFFFFF);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void sim_setup_main()
|
||||
{
|
||||
setupGui();
|
||||
sim_setup(guiUpdate);
|
||||
adcSim* adc = new adcSim();
|
||||
arduinoIOSim* arduinoIO = new arduinoIOSim();
|
||||
stepperSim* xStep = new stepperSim(arduinoIO, X_ENABLE_PIN, X_STEP_PIN, X_DIR_PIN, INVERT_X_DIR);
|
||||
stepperSim* yStep = new stepperSim(arduinoIO, Y_ENABLE_PIN, Y_STEP_PIN, Y_DIR_PIN, INVERT_Y_DIR);
|
||||
stepperSim* zStep = new stepperSim(arduinoIO, Z_ENABLE_PIN, Z_STEP_PIN, Z_DIR_PIN, INVERT_Z_DIR);
|
||||
stepperSim* e0Step = new stepperSim(arduinoIO, E0_ENABLE_PIN, E0_STEP_PIN, E0_DIR_PIN, INVERT_E0_DIR);
|
||||
stepperSim* e1Step = new stepperSim(arduinoIO, E1_ENABLE_PIN, E1_STEP_PIN, E1_DIR_PIN, INVERT_E1_DIR);
|
||||
float stepsPerUnit[4] = DEFAULT_AXIS_STEPS_PER_UNIT;
|
||||
xStep->setRange(0, X_MAX_POS * stepsPerUnit[X_AXIS]);
|
||||
yStep->setRange(0, Y_MAX_POS * stepsPerUnit[Y_AXIS]);
|
||||
zStep->setRange(0, Z_MAX_POS * stepsPerUnit[Z_AXIS]);
|
||||
xStep->setEndstops(X_MIN_PIN, X_MAX_PIN);
|
||||
yStep->setEndstops(Y_MIN_PIN, Y_MAX_PIN);
|
||||
zStep->setEndstops(Z_MIN_PIN, Z_MAX_PIN);
|
||||
(new printerSim(xStep, yStep, zStep, e0Step, e1Step))->setDrawPosition(5, 70);
|
||||
e0Step->setDrawPosition(130, 100);
|
||||
e1Step->setDrawPosition(130, 110);
|
||||
|
||||
(new heaterSim(HEATER_0_PIN, adc, TEMP_0_PIN))->setDrawPosition(130, 70);
|
||||
(new heaterSim(HEATER_1_PIN, adc, TEMP_1_PIN))->setDrawPosition(130, 80);
|
||||
(new heaterSim(HEATER_BED_PIN, adc, TEMP_BED_PIN, 0.2))->setDrawPosition(130, 90);
|
||||
new sdcardSimulation("c:/models/", 5000);
|
||||
(new serialSim())->setDrawPosition(150, 0);
|
||||
#if defined(ULTIBOARD_V2_CONTROLLER) || defined(ENABLE_ULTILCD2)
|
||||
i2cSim* i2c = new i2cSim();
|
||||
(new displaySDD1309Sim(i2c))->setDrawPosition(0, 0);
|
||||
(new ledPCA9632Sim(i2c))->setDrawPosition(1, 66);
|
||||
#endif
|
||||
#if defined(ULTIPANEL) && !defined(ULTIBOARD_V2_CONTROLLER)
|
||||
(new displayHD44780Sim(arduinoIO, LCD_PINS_RS, LCD_PINS_ENABLE, LCD_PINS_D4, LCD_PINS_D5,LCD_PINS_D6,LCD_PINS_D7))->setDrawPosition(0, 0);
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user