├── .gitattributes ├── LICENSE ├── readme.txt ├── sample.txt ├── src ├── .editorconfig ├── .gitignore ├── Makefile ├── bas.cpp ├── bas.h ├── core │ ├── Arduino.h │ ├── CDC.cpp │ ├── Client.h │ ├── HardwareSerial.cpp │ ├── HardwareSerial.h │ ├── HardwareSerial0.cpp │ ├── HardwareSerial1.cpp │ ├── HardwareSerial2.cpp │ ├── HardwareSerial3.cpp │ ├── HardwareSerial_private.h │ ├── IPAddress.cpp │ ├── IPAddress.h │ ├── PluggableUSB.cpp │ ├── PluggableUSB.h │ ├── Print.cpp │ ├── Print.h │ ├── Printable.h │ ├── SPI.cpp │ ├── SPI.h │ ├── Server.h │ ├── Stream.cpp │ ├── Stream.h │ ├── Tone.cpp │ ├── USBAPI.h │ ├── USBCore.cpp │ ├── USBCore.h │ ├── USBDesc.h │ ├── Udp.h │ ├── WCharacter.h │ ├── WInterrupts.c │ ├── WMath.cpp │ ├── WString.cpp │ ├── WString.h │ ├── abi.cpp │ ├── avr5.xn │ ├── binary.h │ ├── hooks.c │ ├── main.cpp │ ├── new.cpp │ ├── new.h │ ├── pins_arduino.h │ ├── wiring.c │ ├── wiring_analog.c │ ├── wiring_digital.c │ ├── wiring_private.h │ ├── wiring_pulse.S │ ├── wiring_pulse.c │ └── wiring_shift.c ├── ino.cpp ├── ino.h ├── lib │ ├── common.cpp │ ├── common.h │ ├── frame.cpp │ ├── frame.h │ ├── nouse │ │ ├── debug.cpp │ │ ├── debug.h │ │ ├── eep.cpp │ │ ├── eep.h │ │ ├── key.cpp │ │ ├── key.h │ │ ├── math.cpp │ │ ├── math.h │ │ ├── snd.cpp │ │ └── snd.h │ ├── oled.cpp │ ├── oled.h │ ├── rnd.cpp │ ├── rnd.h │ ├── sys.cpp │ ├── sys.h │ ├── tinymt32.c │ └── tinymt32.h ├── make_bin.bat ├── make_clean.bat ├── make_usb.bat └── res │ └── font.h ├── test.bat ├── test.hex ├── test.sh └── tool ├── reset.cs └── reset.exe /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=crlf 2 | *.sh eol=lf 3 | 4 | *.bmp binary 5 | *.exe binary 6 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | TOYOSHIKI Tiny Basic for Arduboy - Interpreter 2 | 3 | ## Description 4 | TOYOSHIKI Tiny Basic is Palo Alto Tiny BASIC(1976) clone. 5 | Interpreter is magic. if you see internal structure, you will become wizard :) 6 | 7 | 8 | ## Installation 9 | Request : Arduino IDE 1.8.x 10 | 11 | 1. download from github 12 | 2. pls edit test.bat(windows) or test.sh(osx) for your computer(must change COM port number) 13 | 3. execute test.bat 14 | 4. this program need Serial Monitor. i tested Tera Term. it is famous in Japan. 15 | 5. after connect, input keyboard. 16 | 17 | 18 | ## Manual(BASIC grammar) 19 | https://en.wikipedia.org/wiki/Tiny_BASIC 20 | 21 | 22 | ## Original 23 | simple source code. thank you! 24 | https://github.com/vintagechips/ttbasic_win 25 | 26 | 27 | ## ToDo 28 | INPUT order. 29 | 30 | 31 | ## Development 32 | compiler : windows Arduino IDE 1.8.13(avr-gcc) + 1.0.6(make.exe) 33 | image converter : python 2.6 + PIL 34 | etc : Visual Studio 2015 C# 35 | 36 | 37 | ## License 38 | GPL v2 39 | 40 | -------------------------------------------------------------------------------- /sample.txt: -------------------------------------------------------------------------------- 1 | +++ hello.bas 2 | 3 | 10 PRINT "HELLO ARDUBOY" 4 | 5 | 6 | 7 | 8 | +++ zundoko.bas 9 | 10 | 10 R=RND(2)-1; IF R PRINT "ZUN ",; GOTO 30 11 | 20 PRINT "DOKO ", 12 | 30 N=16*R+N/2; IF N#15 GOTO 10 13 | 40 PRINT "KI.YO.SHI!" 14 | 15 | 16 | 17 | 18 | ++++ fizzbuzz.bas 19 | 20 | 10 FOR I=1 TO 100 21 | 20 F=I/3*3=I; B=I/5*5=I 22 | 30 IF F PRINT "FIZZ", 23 | 40 IF B PRINT "BUZZ", 24 | 50 IF F+B=0 PRINT I, 25 | 60 PRINT 26 | 70 NEXT I 27 | 28 | 29 | 30 | 31 | ++++ line.bas 32 | 33 | 10 CLS 34 | 20 FOR I=0 TO 63 35 | 30 PSET I,I,1 36 | 40 NEXT I 37 | 38 | 39 | 40 | 41 | ++++ test.bas 42 | 43 | 10 FOR I=2 TO -2 STEP -1; GOSUB 100; NEXT I 44 | 20 STOP 45 | 100 REM SUBROUTINE 46 | 110 PRINT ABS(I); RETURN 47 | 48 | 49 | 50 | 51 | ++++ ball.bas 52 | 53 | 1000 REM SETUP 54 | 1010 U=4 55 | 1020 V=4 56 | 1030 X=30 57 | 1040 Y=30 58 | 59 | 2000 REM UPDATE 60 | 2010 X=X+U 61 | 2020 Y=Y+V 62 | 2110 IF X+U<=0 U=RND(10) 63 | 2120 IF X+U>=127 U=-RND(10) 64 | 2210 IF Y+V<=0 V=RND(10) 65 | 2220 IF Y+V>=63 V=-RND(10) 66 | 67 | 3000 REM DRAW 68 | 3010 CLS 69 | 3020 PSET X,Y,1 70 | 4000 GOTO 2000 71 | 72 | 73 | 74 | 75 | ++++ multball.bas 76 | 77 | 1000 CLS 78 | 1010 B=11 79 | 80 | 2010 FOR I=0 TO B STEP 4 81 | 82 | 2020 @(I)=@(I)+@(I+2) 83 | 2030 @(I+1)=@(I+1)+@(I+3) 84 | 85 | 2050 IF @(I)<=0 @(I+2)=RND(10) 86 | 2060 IF @(I)>=127 @(I+2)=-RND(10) 87 | 88 | 2070 IF @(I+1)<=0 @(I+3)=RND(10) 89 | 2080 IF @(I+1)>=63 @(I+3)=-RND(10) 90 | 91 | 2090 PSET @(I),@(I+1),1 92 | 2100 NEXT I 93 | 94 | 4000 GOTO 2010 95 | -------------------------------------------------------------------------------- /src/.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | indent_style = tab 3 | indent_size = 4 4 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.d 3 | *.a 4 | *.elf 5 | *.hex 6 | *.map 7 | *.nm 8 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | MAKEFLAGS +=--no-print-directory 2 | 3 | BINPATH = "C:/Program Files (x86)/Arduino/hardware/tools/avr/bin/" 4 | CONFFILE = "C:/Program Files (x86)/Arduino/hardware/tools/avr/etc/avrdude.conf" 5 | COM = COM3 6 | 7 | ARDUBOY_MODEL = ARDUBOY_10 8 | #ARDUBOY_MODEL = ARDUBOY_DEVKIT 9 | 10 | #============================================================================= 11 | 12 | PREFIX = $(BINPATH)avr- 13 | CPP = $(PREFIX)g++ 14 | CC = $(PREFIX)gcc 15 | AS = $(PREFIX)gcc 16 | AR = $(PREFIX)ar 17 | LD = $(PREFIX)gcc 18 | OBJCOPY = $(PREFIX)objcopy 19 | NM = $(PREFIX)nm 20 | 21 | SFILES = \ 22 | $(wildcard core/*.s) \ 23 | $(wildcard core/*.S) \ 24 | 25 | CFILES = \ 26 | $(wildcard core/*.c) \ 27 | $(wildcard core/*.cpp) \ 28 | $(wildcard lib/*.c) \ 29 | $(wildcard lib/*.cpp) \ 30 | $(wildcard *.c) \ 31 | $(wildcard *.cpp) \ 32 | 33 | VPATH = $(dir $(CFILES) $(SFILES)) 34 | INCDIR = core/ 35 | 36 | OBJDIR = obj 37 | NAME = test 38 | MAPFILE = $(NAME).map 39 | NMFILE = $(NAME).nm 40 | TARGET_ELF = $(NAME).elf 41 | TARGET_HEX = $(NAME).hex 42 | 43 | #============================================================================= 44 | 45 | DFLAGS = -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_LEONARDO -DARDUINO_ARCH_AVR -DUSB_VID=0x2341 -DUSB_PID=0x8036 -DUSB_MANUFACTURER="Unknown" -D$(ARDUBOY_MODEL) 46 | 47 | GFLAGS = -c -g -Os -Wall -Wextra -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega32u4 $(DFLAGS) $(foreach incdir,$(INCDIR),-I$(incdir)) -x c++ -fpermissive 48 | 49 | CFLAGS = -c -g -Os -Wall -Wextra -std=gnu11 -ffunction-sections -fdata-sections -MMD -mmcu=atmega32u4 $(DFLAGS) -DUSB_PRODUCT="Arduino Leonardo" $(foreach incdir,$(INCDIR),-I$(incdir)) -x c 50 | 51 | ASFLAGS = -c -g -x assembler-with-cpp -mmcu=atmega32u4 $(DFLAGS) -DUSB_PRODUCT="Arduino Leonardo" $(foreach incdir,$(INCDIR),-I$(incdir)) 52 | 53 | LDFLAGS = -Wall -Wextra -Os -Wl,--gc-sections -Wl,-Map=$(MAPFILE) -mmcu=atmega32u4 -T core/avr5.xn 54 | 55 | OFILES = $(addprefix $(OBJDIR)/, $(addsuffix .o, $(notdir $(SFILES) $(CFILES)))) 56 | 57 | DFILES = $(addprefix $(OBJDIR)/, $(addsuffix .d, $(notdir $(CFILES)))) 58 | 59 | #============================================================================= 60 | 61 | .PHONY: all usb 62 | all: 63 | @make $(TARGET_HEX) 64 | 65 | usb: 66 | @$(BINPATH)avrdude -C$(CONFFILE) -v -patmega32u4 -cavr109 -P$(COM) -b57600 -D -Uflash:w:$(TARGET_HEX):i 67 | 68 | #============================================================================= 69 | 70 | $(TARGET_HEX): $(TARGET_ELF) 71 | @$(OBJCOPY) -O ihex -R .eeprom $< $@ 72 | 73 | $(TARGET_ELF): $(OBJDIR) $(OFILES) Makefile 74 | @echo # Linking $@ 75 | @$(AR) rcs $(OBJDIR)/core.a $(OFILES) 76 | @$(LD) $(LDFLAGS) -o $@ $(OBJDIR)/core.a 77 | @$(NM) -n $@ > $(NMFILE) 78 | 79 | $(OBJDIR): 80 | @mkdir $@ 81 | 82 | #============================================================================= 83 | 84 | .SUFFIXES: .S .s .cpp .c .o .a .d 85 | 86 | $(OBJDIR)/%.cpp.o: %.cpp 87 | @echo # compiling $< 88 | @$(CPP) $(GFLAGS) $< -o $@ 89 | 90 | $(OBJDIR)/%.c.o: %.c 91 | @echo # compiling $< 92 | @$(CC) $(CFLAGS) $< -o $@ 93 | 94 | $(OBJDIR)/%.s.o: %.s 95 | @echo # assembling $< 96 | @$(AS) $(ASFLAGS) $< -o $@ 97 | 98 | $(OBJDIR)/%.S.o: %.S 99 | @echo # assembling $< 100 | @$(AS) $(ASFLAGS) $< -o $@ 101 | 102 | 103 | -include $(DFILES) 104 | -------------------------------------------------------------------------------- /src/bas.h: -------------------------------------------------------------------------------- 1 | #ifndef BAS_H 2 | #define BAS_H 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | #include "lib/common.h" 8 | 9 | //--------------------------------------------------------------------------- 10 | #define BAS_CODE_CR 0x0d 11 | #define BAS_CODE_LF 0x0a 12 | #define BAS_CODE_TAB 0x09 13 | #define BAS_CODE_BS 0x08 14 | #define BAS_CODE_DEL 0x7f 15 | #define BAS_CODE_SP 0x20 16 | #define BAS_CODE_ESC 0x1b 17 | 18 | #define BAS_SIZE_LINE 50 19 | #define BAS_SIZE_CODE 50 20 | #define BAS_SIZE_LIST 300 21 | #define BAS_SIZE_ARRAY 20 22 | #define BAS_SIZE_VAR 26 23 | #define BAS_SIZE_GOSUB 6 24 | #define BAS_SIZE_FOR 15 25 | #define BAS_SIZE_CMD (sizeof(BasCmdTable) / sizeof(const char*)) 26 | 27 | enum { 28 | BAS_EXEC_RESET, 29 | BAS_EXEC_RDY, 30 | BAS_EXEC_KEY, 31 | BAS_EXEC_LEX, 32 | BAS_EXEC_ADR, 33 | BAS_EXEC_CMD, 34 | BAS_EXEC_RUN, 35 | BAS_EXEC_OK, 36 | }; 37 | 38 | enum { 39 | BAS_CODE_GOTO, 40 | BAS_CODE_GOSUB, 41 | BAS_CODE_RETURN, 42 | BAS_CODE_FOR, 43 | BAS_CODE_TO, 44 | BAS_CODE_STEP, 45 | BAS_CODE_NEXT, 46 | BAS_CODE_IF, 47 | BAS_CODE_REM, 48 | BAS_CODE_STOP, 49 | BAS_CODE_INPUT, // 0x0a 50 | BAS_CODE_PRINT, 51 | BAS_CODE_LET, 52 | BAS_CODE_COMMA, 53 | BAS_CODE_SEMI, 54 | BAS_CODE_MINUS, 55 | BAS_CODE_PLUS, // 0x10 56 | BAS_CODE_MUL, 57 | BAS_CODE_DIV, 58 | BAS_CODE_MOD, 59 | BAS_CODE_OPEN, 60 | BAS_CODE_CLOSE, 61 | BAS_CODE_GTE, 62 | BAS_CODE_NEQ, 63 | BAS_CODE_GT, 64 | BAS_CODE_EQ, 65 | BAS_CODE_LTE, 66 | BAS_CODE_LT, // 0x1b 67 | BAS_CODE_ARRAY, 68 | BAS_CODE_RND, 69 | BAS_CODE_ABS, 70 | BAS_CODE_SIZE, 71 | BAS_CODE_LIST, 72 | BAS_CODE_RUN, // 0x21 73 | BAS_CODE_NEW, 74 | BAS_CODE_CLS, 75 | BAS_CODE_PSET, 76 | 77 | BAS_CODE_NUM, // 0x25 78 | BAS_CODE_VAR, 79 | BAS_CODE_STR, 80 | BAS_CODE_EOL, // 0x28 81 | }; 82 | 83 | enum { 84 | BAS_ERROR_OK, 85 | BAS_ERROR_DIVBY0, 86 | BAS_ERROR_VOF, 87 | BAS_ERROR_SOR, 88 | BAS_ERROR_IBUFOF, 89 | BAS_ERROR_LBUFOF, 90 | BAS_ERROR_GSTKOF, 91 | BAS_ERROR_GSTKUF, 92 | BAS_ERROR_LSTKOF, 93 | BAS_ERROR_LSTKUF, 94 | BAS_ERROR_NEXTWOV, 95 | BAS_ERROR_NEXTUM, 96 | BAS_ERROR_FORWOV, 97 | BAS_ERROR_FORWOTO, 98 | BAS_ERROR_LETWOV, 99 | BAS_ERROR_IFWOC, 100 | BAS_ERROR_ULN, 101 | BAS_ERROR_PAREN, 102 | BAS_ERROR_VWOEQ, 103 | BAS_ERROR_COM, 104 | BAS_ERROR_SYNTAX, 105 | BAS_ERROR_SYS, 106 | BAS_ERROR_ESC 107 | }; 108 | //--------------------------------------------------------------------------- 109 | 110 | typedef struct { 111 | u8 act; 112 | 113 | s16 lineLen; 114 | u8 lineBuf[BAS_SIZE_LINE]; 115 | 116 | s16 codeLen; 117 | u8 codeBuf[BAS_SIZE_CODE]; 118 | 119 | s16 listLen; 120 | u8 listBuf[BAS_SIZE_LIST]; 121 | 122 | u8* pCur; // Pointer current 123 | u8* pLine; // Pointer current line 124 | 125 | s16 var[BAS_SIZE_VAR]; 126 | s16 array[BAS_SIZE_ARRAY]; 127 | 128 | s8 forIdx; 129 | u8* forStack[BAS_SIZE_FOR]; 130 | 131 | s8 gosubIdx; 132 | u8* gosubStack[BAS_SIZE_GOSUB]; 133 | 134 | u8 error; 135 | 136 | } ST_BAS; 137 | 138 | 139 | //--------------------------------------------------------------------------- 140 | void BasInit(void); 141 | void BasLoop(void); 142 | 143 | void BasExecReset(void); 144 | void BasExecRdy(void); 145 | void BasExecKey(void); 146 | void BasExecLex(void); 147 | void BasExecAdr(void); 148 | void BasExecCmd(void); 149 | void BasExecRun(void); 150 | void BasExecOk(void); 151 | void BasExecError(void); 152 | 153 | void BasCmdGoto(void); 154 | void BasCmdGosub(void); 155 | void BasCmdReturn(void); 156 | void BasCmdFor(void); 157 | void BasCmdNext(void); 158 | void BasCmdIf(void); 159 | void BasCmdRem(void); 160 | void BasCmdStop(void); 161 | void BasCmdVar(void); 162 | void BasCmdArray(void); 163 | void BasCmdLet(void); 164 | void BasCmdPrint(void); 165 | void BasCmdInput(void); 166 | void BasCmdCls(void); 167 | void BasCmdPset(void); 168 | 169 | s16 BasCalcCond(void); 170 | s16 BasCalcExpr(void); 171 | s16 BasCalcTerm(void); 172 | s16 BasCalcFactor(void); 173 | s16 BasCalcParam(void); 174 | s16 BasCalcRnd(s16 val); 175 | 176 | void BasSerialWriteChr(u8 c); 177 | void BasSerialWriteStr(char* s); 178 | void BasSerialWriteStrP(u16 s); 179 | void BasSerialWriteNum(s16 val, s16 d); 180 | void BasSerialWriteList(u8* p); 181 | void BasSerialWriteNewLine(void); 182 | u8 BasSerialRead(void); 183 | bool BasSerialIsAvailable(void); 184 | 185 | bool BasIsNoSpaceAfter(u8 code); 186 | bool BasIsNoSpaceBefore(u8 code); 187 | bool BasIsPrint(u8 c); 188 | bool BasIsSpace(u8 c); 189 | bool BasIsToupper(u8 c); 190 | bool BasIsAlpha(u8 c); 191 | bool BasIsDigit(u8 c); 192 | bool BasIsString(u8 c); 193 | bool BasIsCmd(u8* p); 194 | bool BasIsRunList(void); 195 | bool BasIsError(void); 196 | 197 | void BasAddCode(u8 code); 198 | void BasAddCode2(u8* p, s16 len); 199 | u8* BasAddCodeCmd(u8* p); 200 | u8* BasAddCodeNum(u8* p); 201 | u8* BasAddCodeStr(u8* p); 202 | u8* BasAddCodeVar(u8* p); 203 | 204 | u8* BasGetListPointer(s16 lineno); 205 | s16 BasGetLineNo(u8* p); 206 | u8 BasGetCmdIdx(u8* p); 207 | u8 BasGetCmdLen(u8 idx); 208 | u8* BasSkipSpace(u8* p); 209 | 210 | 211 | #ifdef __cplusplus 212 | } 213 | #endif 214 | #endif 215 | -------------------------------------------------------------------------------- /src/core/Arduino.h: -------------------------------------------------------------------------------- 1 | /* 2 | Arduino.h - Main include file for the Arduino SDK 3 | Copyright (c) 2005-2013 Arduino Team. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef Arduino_h 21 | #define Arduino_h 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include "binary.h" 33 | 34 | #ifdef __cplusplus 35 | extern "C"{ 36 | #endif 37 | 38 | void yield(void); 39 | 40 | #define HIGH 0x1 41 | #define LOW 0x0 42 | 43 | #define INPUT 0x0 44 | #define OUTPUT 0x1 45 | #define INPUT_PULLUP 0x2 46 | 47 | #define PI 3.1415926535897932384626433832795 48 | #define HALF_PI 1.5707963267948966192313216916398 49 | #define TWO_PI 6.283185307179586476925286766559 50 | #define DEG_TO_RAD 0.017453292519943295769236907684886 51 | #define RAD_TO_DEG 57.295779513082320876798154814105 52 | #define EULER 2.718281828459045235360287471352 53 | 54 | #define SERIAL 0x0 55 | #define DISPLAY 0x1 56 | 57 | #define LSBFIRST 0 58 | #define MSBFIRST 1 59 | 60 | #define CHANGE 1 61 | #define FALLING 2 62 | #define RISING 3 63 | 64 | #if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) 65 | #define DEFAULT 0 66 | #define EXTERNAL 1 67 | #define INTERNAL 2 68 | #else 69 | #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) 70 | #define INTERNAL1V1 2 71 | #define INTERNAL2V56 3 72 | #else 73 | #define INTERNAL 3 74 | #endif 75 | #define DEFAULT 1 76 | #define EXTERNAL 0 77 | #endif 78 | 79 | // undefine stdlib's abs if encountered 80 | #ifdef abs 81 | #undef abs 82 | #endif 83 | 84 | #define min(a,b) ((a)<(b)?(a):(b)) 85 | #define max(a,b) ((a)>(b)?(a):(b)) 86 | #define abs(x) ((x)>0?(x):-(x)) 87 | #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) 88 | #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) 89 | #define radians(deg) ((deg)*DEG_TO_RAD) 90 | #define degrees(rad) ((rad)*RAD_TO_DEG) 91 | #define sq(x) ((x)*(x)) 92 | 93 | #define interrupts() sei() 94 | #define noInterrupts() cli() 95 | 96 | #define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) 97 | #define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) 98 | #define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() ) 99 | 100 | #define lowByte(w) ((uint8_t) ((w) & 0xff)) 101 | #define highByte(w) ((uint8_t) ((w) >> 8)) 102 | 103 | #define bitRead(value, bit) (((value) >> (bit)) & 0x01) 104 | #define bitSet(value, bit) ((value) |= (1UL << (bit))) 105 | #define bitClear(value, bit) ((value) &= ~(1UL << (bit))) 106 | #define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) 107 | 108 | // avr-libc defines _NOP() since 1.6.2 109 | #ifndef _NOP 110 | #define _NOP() do { __asm__ volatile ("nop"); } while (0) 111 | #endif 112 | 113 | typedef unsigned int word; 114 | 115 | #define bit(b) (1UL << (b)) 116 | 117 | typedef bool boolean; 118 | typedef uint8_t byte; 119 | 120 | void init(void); 121 | void initVariant(void); 122 | 123 | int atexit(void (*func)()) __attribute__((weak)); 124 | 125 | void pinMode(uint8_t, uint8_t); 126 | void digitalWrite(uint8_t, uint8_t); 127 | int digitalRead(uint8_t); 128 | int analogRead(uint8_t); 129 | void analogReference(uint8_t mode); 130 | void analogWrite(uint8_t, int); 131 | 132 | unsigned long millis(void); 133 | unsigned long micros(void); 134 | void delay(unsigned long); 135 | void delayMicroseconds(unsigned int us); 136 | unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout); 137 | unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout); 138 | 139 | void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val); 140 | uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder); 141 | 142 | void attachInterrupt(uint8_t, void (*)(void), int mode); 143 | void detachInterrupt(uint8_t); 144 | 145 | void setup(void); 146 | void loop(void); 147 | 148 | // Get the bit location within the hardware port of the given virtual pin. 149 | // This comes from the pins_*.c file for the active board configuration. 150 | 151 | #define analogInPinToBit(P) (P) 152 | 153 | // On the ATmega1280, the addresses of some of the port registers are 154 | // greater than 255, so we can't store them in uint8_t's. 155 | extern const uint16_t PROGMEM port_to_mode_PGM[]; 156 | extern const uint16_t PROGMEM port_to_input_PGM[]; 157 | extern const uint16_t PROGMEM port_to_output_PGM[]; 158 | 159 | extern const uint8_t PROGMEM digital_pin_to_port_PGM[]; 160 | // extern const uint8_t PROGMEM digital_pin_to_bit_PGM[]; 161 | extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[]; 162 | extern const uint8_t PROGMEM digital_pin_to_timer_PGM[]; 163 | 164 | // Get the bit location within the hardware port of the given virtual pin. 165 | // This comes from the pins_*.c file for the active board configuration. 166 | // 167 | // These perform slightly better as macros compared to inline functions 168 | // 169 | #define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) ) 170 | #define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) ) 171 | #define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) ) 172 | #define analogInPinToBit(P) (P) 173 | #define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) ) 174 | #define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) ) 175 | #define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) ) 176 | 177 | #define NOT_A_PIN 0 178 | #define NOT_A_PORT 0 179 | 180 | #define NOT_AN_INTERRUPT -1 181 | 182 | #ifdef ARDUINO_MAIN 183 | #define PA 1 184 | #define PB 2 185 | #define PC 3 186 | #define PD 4 187 | #define PE 5 188 | #define PF 6 189 | #define PG 7 190 | #define PH 8 191 | #define PJ 10 192 | #define PK 11 193 | #define PL 12 194 | #endif 195 | 196 | #define NOT_ON_TIMER 0 197 | #define TIMER0A 1 198 | #define TIMER0B 2 199 | #define TIMER1A 3 200 | #define TIMER1B 4 201 | #define TIMER1C 5 202 | #define TIMER2 6 203 | #define TIMER2A 7 204 | #define TIMER2B 8 205 | 206 | #define TIMER3A 9 207 | #define TIMER3B 10 208 | #define TIMER3C 11 209 | #define TIMER4A 12 210 | #define TIMER4B 13 211 | #define TIMER4C 14 212 | #define TIMER4D 15 213 | #define TIMER5A 16 214 | #define TIMER5B 17 215 | #define TIMER5C 18 216 | 217 | #ifdef __cplusplus 218 | } // extern "C" 219 | #endif 220 | 221 | #ifdef __cplusplus 222 | #include "WCharacter.h" 223 | #include "WString.h" 224 | #include "HardwareSerial.h" 225 | #include "USBAPI.h" 226 | #if defined(HAVE_HWSERIAL0) && defined(HAVE_CDCSERIAL) 227 | #error "Targets with both UART0 and CDC serial not supported" 228 | #endif 229 | 230 | uint16_t makeWord(uint16_t w); 231 | uint16_t makeWord(byte h, byte l); 232 | 233 | #define word(...) makeWord(__VA_ARGS__) 234 | 235 | unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); 236 | unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); 237 | 238 | void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0); 239 | void noTone(uint8_t _pin); 240 | 241 | // WMath prototypes 242 | long random(long); 243 | long random(long, long); 244 | void randomSeed(unsigned long); 245 | long map(long, long, long, long, long); 246 | 247 | #endif 248 | 249 | #include "pins_arduino.h" 250 | 251 | #endif 252 | -------------------------------------------------------------------------------- /src/core/Client.h: -------------------------------------------------------------------------------- 1 | /* 2 | Client.h - Base class that provides Client 3 | Copyright (c) 2011 Adrian McEwen. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef client_h 21 | #define client_h 22 | #include "Print.h" 23 | #include "Stream.h" 24 | #include "IPAddress.h" 25 | 26 | class Client : public Stream { 27 | 28 | public: 29 | virtual int connect(IPAddress ip, uint16_t port) =0; 30 | virtual int connect(const char *host, uint16_t port) =0; 31 | virtual size_t write(uint8_t) =0; 32 | virtual size_t write(const uint8_t *buf, size_t size) =0; 33 | virtual int available() = 0; 34 | virtual int read() = 0; 35 | virtual int read(uint8_t *buf, size_t size) = 0; 36 | virtual int peek() = 0; 37 | virtual void flush() = 0; 38 | virtual void stop() = 0; 39 | virtual uint8_t connected() = 0; 40 | virtual operator bool() = 0; 41 | protected: 42 | uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); }; 43 | }; 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/core/HardwareSerial.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | HardwareSerial.cpp - Hardware serial library for Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 23 November 2006 by David A. Mellis 20 | Modified 28 September 2010 by Mark Sproul 21 | Modified 14 August 2012 by Alarus 22 | Modified 3 December 2013 by Matthijs Kooijman 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include "Arduino.h" 30 | 31 | #include "HardwareSerial.h" 32 | #include "HardwareSerial_private.h" 33 | 34 | // this next line disables the entire HardwareSerial.cpp, 35 | // this is so I can support Attiny series and any other chip without a uart 36 | #if defined(HAVE_HWSERIAL0) || defined(HAVE_HWSERIAL1) || defined(HAVE_HWSERIAL2) || defined(HAVE_HWSERIAL3) 37 | 38 | // SerialEvent functions are weak, so when the user doesn't define them, 39 | // the linker just sets their address to 0 (which is checked below). 40 | // The Serialx_available is just a wrapper around Serialx.available(), 41 | // but we can refer to it weakly so we don't pull in the entire 42 | // HardwareSerial instance if the user doesn't also refer to it. 43 | #if defined(HAVE_HWSERIAL0) 44 | void serialEvent() __attribute__((weak)); 45 | bool Serial0_available() __attribute__((weak)); 46 | #endif 47 | 48 | #if defined(HAVE_HWSERIAL1) 49 | void serialEvent1() __attribute__((weak)); 50 | bool Serial1_available() __attribute__((weak)); 51 | #endif 52 | 53 | #if defined(HAVE_HWSERIAL2) 54 | void serialEvent2() __attribute__((weak)); 55 | bool Serial2_available() __attribute__((weak)); 56 | #endif 57 | 58 | #if defined(HAVE_HWSERIAL3) 59 | void serialEvent3() __attribute__((weak)); 60 | bool Serial3_available() __attribute__((weak)); 61 | #endif 62 | 63 | void serialEventRun(void) 64 | { 65 | #if defined(HAVE_HWSERIAL0) 66 | if (Serial0_available && serialEvent && Serial0_available()) serialEvent(); 67 | #endif 68 | #if defined(HAVE_HWSERIAL1) 69 | if (Serial1_available && serialEvent1 && Serial1_available()) serialEvent1(); 70 | #endif 71 | #if defined(HAVE_HWSERIAL2) 72 | if (Serial2_available && serialEvent2 && Serial2_available()) serialEvent2(); 73 | #endif 74 | #if defined(HAVE_HWSERIAL3) 75 | if (Serial3_available && serialEvent3 && Serial3_available()) serialEvent3(); 76 | #endif 77 | } 78 | 79 | // Actual interrupt handlers ////////////////////////////////////////////////////////////// 80 | 81 | void HardwareSerial::_tx_udr_empty_irq(void) 82 | { 83 | // If interrupts are enabled, there must be more data in the output 84 | // buffer. Send the next byte 85 | unsigned char c = _tx_buffer[_tx_buffer_tail]; 86 | _tx_buffer_tail = (_tx_buffer_tail + 1) % SERIAL_TX_BUFFER_SIZE; 87 | 88 | *_udr = c; 89 | 90 | // clear the TXC bit -- "can be cleared by writing a one to its bit 91 | // location". This makes sure flush() won't return until the bytes 92 | // actually got written 93 | sbi(*_ucsra, TXC0); 94 | 95 | if (_tx_buffer_head == _tx_buffer_tail) { 96 | // Buffer empty, so disable interrupts 97 | cbi(*_ucsrb, UDRIE0); 98 | } 99 | } 100 | 101 | // Public Methods ////////////////////////////////////////////////////////////// 102 | 103 | void HardwareSerial::begin(unsigned long baud, byte config) 104 | { 105 | // Try u2x mode first 106 | uint16_t baud_setting = (F_CPU / 4 / baud - 1) / 2; 107 | *_ucsra = 1 << U2X0; 108 | 109 | // hardcoded exception for 57600 for compatibility with the bootloader 110 | // shipped with the Duemilanove and previous boards and the firmware 111 | // on the 8U2 on the Uno and Mega 2560. Also, The baud_setting cannot 112 | // be > 4095, so switch back to non-u2x mode if the baud rate is too 113 | // low. 114 | if (((F_CPU == 16000000UL) && (baud == 57600)) || (baud_setting >4095)) 115 | { 116 | *_ucsra = 0; 117 | baud_setting = (F_CPU / 8 / baud - 1) / 2; 118 | } 119 | 120 | // assign the baud_setting, a.k.a. ubrr (USART Baud Rate Register) 121 | *_ubrrh = baud_setting >> 8; 122 | *_ubrrl = baud_setting; 123 | 124 | _written = false; 125 | 126 | //set the data bits, parity, and stop bits 127 | #if defined(__AVR_ATmega8__) 128 | config |= 0x80; // select UCSRC register (shared with UBRRH) 129 | #endif 130 | *_ucsrc = config; 131 | 132 | sbi(*_ucsrb, RXEN0); 133 | sbi(*_ucsrb, TXEN0); 134 | sbi(*_ucsrb, RXCIE0); 135 | cbi(*_ucsrb, UDRIE0); 136 | } 137 | 138 | void HardwareSerial::end() 139 | { 140 | // wait for transmission of outgoing data 141 | flush(); 142 | 143 | cbi(*_ucsrb, RXEN0); 144 | cbi(*_ucsrb, TXEN0); 145 | cbi(*_ucsrb, RXCIE0); 146 | cbi(*_ucsrb, UDRIE0); 147 | 148 | // clear any received data 149 | _rx_buffer_head = _rx_buffer_tail; 150 | } 151 | 152 | int HardwareSerial::available(void) 153 | { 154 | return ((unsigned int)(SERIAL_RX_BUFFER_SIZE + _rx_buffer_head - _rx_buffer_tail)) % SERIAL_RX_BUFFER_SIZE; 155 | } 156 | 157 | int HardwareSerial::peek(void) 158 | { 159 | if (_rx_buffer_head == _rx_buffer_tail) { 160 | return -1; 161 | } else { 162 | return _rx_buffer[_rx_buffer_tail]; 163 | } 164 | } 165 | 166 | int HardwareSerial::read(void) 167 | { 168 | // if the head isn't ahead of the tail, we don't have any characters 169 | if (_rx_buffer_head == _rx_buffer_tail) { 170 | return -1; 171 | } else { 172 | unsigned char c = _rx_buffer[_rx_buffer_tail]; 173 | _rx_buffer_tail = (rx_buffer_index_t)(_rx_buffer_tail + 1) % SERIAL_RX_BUFFER_SIZE; 174 | return c; 175 | } 176 | } 177 | 178 | int HardwareSerial::availableForWrite(void) 179 | { 180 | #if (SERIAL_TX_BUFFER_SIZE>256) 181 | uint8_t oldSREG = SREG; 182 | cli(); 183 | #endif 184 | tx_buffer_index_t head = _tx_buffer_head; 185 | tx_buffer_index_t tail = _tx_buffer_tail; 186 | #if (SERIAL_TX_BUFFER_SIZE>256) 187 | SREG = oldSREG; 188 | #endif 189 | if (head >= tail) return SERIAL_TX_BUFFER_SIZE - 1 - head + tail; 190 | return tail - head - 1; 191 | } 192 | 193 | void HardwareSerial::flush() 194 | { 195 | // If we have never written a byte, no need to flush. This special 196 | // case is needed since there is no way to force the TXC (transmit 197 | // complete) bit to 1 during initialization 198 | if (!_written) 199 | return; 200 | 201 | while (bit_is_set(*_ucsrb, UDRIE0) || bit_is_clear(*_ucsra, TXC0)) { 202 | if (bit_is_clear(SREG, SREG_I) && bit_is_set(*_ucsrb, UDRIE0)) 203 | // Interrupts are globally disabled, but the DR empty 204 | // interrupt should be enabled, so poll the DR empty flag to 205 | // prevent deadlock 206 | if (bit_is_set(*_ucsra, UDRE0)) 207 | _tx_udr_empty_irq(); 208 | } 209 | // If we get here, nothing is queued anymore (DRIE is disabled) and 210 | // the hardware finished tranmission (TXC is set). 211 | } 212 | 213 | size_t HardwareSerial::write(uint8_t c) 214 | { 215 | _written = true; 216 | // If the buffer and the data register is empty, just write the byte 217 | // to the data register and be done. This shortcut helps 218 | // significantly improve the effective datarate at high (> 219 | // 500kbit/s) bitrates, where interrupt overhead becomes a slowdown. 220 | if (_tx_buffer_head == _tx_buffer_tail && bit_is_set(*_ucsra, UDRE0)) { 221 | *_udr = c; 222 | sbi(*_ucsra, TXC0); 223 | return 1; 224 | } 225 | tx_buffer_index_t i = (_tx_buffer_head + 1) % SERIAL_TX_BUFFER_SIZE; 226 | 227 | // If the output buffer is full, there's nothing for it other than to 228 | // wait for the interrupt handler to empty it a bit 229 | while (i == _tx_buffer_tail) { 230 | if (bit_is_clear(SREG, SREG_I)) { 231 | // Interrupts are disabled, so we'll have to poll the data 232 | // register empty flag ourselves. If it is set, pretend an 233 | // interrupt has happened and call the handler to free up 234 | // space for us. 235 | if(bit_is_set(*_ucsra, UDRE0)) 236 | _tx_udr_empty_irq(); 237 | } else { 238 | // nop, the interrupt handler will free up space for us 239 | } 240 | } 241 | 242 | _tx_buffer[_tx_buffer_head] = c; 243 | _tx_buffer_head = i; 244 | 245 | sbi(*_ucsrb, UDRIE0); 246 | 247 | return 1; 248 | } 249 | 250 | #endif // whole file 251 | -------------------------------------------------------------------------------- /src/core/HardwareSerial.h: -------------------------------------------------------------------------------- 1 | /* 2 | HardwareSerial.h - Hardware serial library for Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 28 September 2010 by Mark Sproul 20 | Modified 14 August 2012 by Alarus 21 | Modified 3 December 2013 by Matthijs Kooijman 22 | */ 23 | 24 | #ifndef HardwareSerial_h 25 | #define HardwareSerial_h 26 | 27 | #include 28 | 29 | #include "Stream.h" 30 | 31 | // Define constants and variables for buffering incoming serial data. We're 32 | // using a ring buffer (I think), in which head is the index of the location 33 | // to which to write the next incoming character and tail is the index of the 34 | // location from which to read. 35 | // NOTE: a "power of 2" buffer size is reccomended to dramatically 36 | // optimize all the modulo operations for ring buffers. 37 | // WARNING: When buffer sizes are increased to > 256, the buffer index 38 | // variables are automatically increased in size, but the extra 39 | // atomicity guards needed for that are not implemented. This will 40 | // often work, but occasionally a race condition can occur that makes 41 | // Serial behave erratically. See https://github.com/arduino/Arduino/issues/2405 42 | #if !defined(SERIAL_TX_BUFFER_SIZE) 43 | #if ((RAMEND - RAMSTART) < 1023) 44 | #define SERIAL_TX_BUFFER_SIZE 16 45 | #else 46 | #define SERIAL_TX_BUFFER_SIZE 64 47 | #endif 48 | #endif 49 | #if !defined(SERIAL_RX_BUFFER_SIZE) 50 | #if ((RAMEND - RAMSTART) < 1023) 51 | #define SERIAL_RX_BUFFER_SIZE 16 52 | #else 53 | #define SERIAL_RX_BUFFER_SIZE 64 54 | #endif 55 | #endif 56 | #if (SERIAL_TX_BUFFER_SIZE>256) 57 | typedef uint16_t tx_buffer_index_t; 58 | #else 59 | typedef uint8_t tx_buffer_index_t; 60 | #endif 61 | #if (SERIAL_RX_BUFFER_SIZE>256) 62 | typedef uint16_t rx_buffer_index_t; 63 | #else 64 | typedef uint8_t rx_buffer_index_t; 65 | #endif 66 | 67 | // Define config for Serial.begin(baud, config); 68 | #define SERIAL_5N1 0x00 69 | #define SERIAL_6N1 0x02 70 | #define SERIAL_7N1 0x04 71 | #define SERIAL_8N1 0x06 72 | #define SERIAL_5N2 0x08 73 | #define SERIAL_6N2 0x0A 74 | #define SERIAL_7N2 0x0C 75 | #define SERIAL_8N2 0x0E 76 | #define SERIAL_5E1 0x20 77 | #define SERIAL_6E1 0x22 78 | #define SERIAL_7E1 0x24 79 | #define SERIAL_8E1 0x26 80 | #define SERIAL_5E2 0x28 81 | #define SERIAL_6E2 0x2A 82 | #define SERIAL_7E2 0x2C 83 | #define SERIAL_8E2 0x2E 84 | #define SERIAL_5O1 0x30 85 | #define SERIAL_6O1 0x32 86 | #define SERIAL_7O1 0x34 87 | #define SERIAL_8O1 0x36 88 | #define SERIAL_5O2 0x38 89 | #define SERIAL_6O2 0x3A 90 | #define SERIAL_7O2 0x3C 91 | #define SERIAL_8O2 0x3E 92 | 93 | class HardwareSerial : public Stream 94 | { 95 | protected: 96 | volatile uint8_t * const _ubrrh; 97 | volatile uint8_t * const _ubrrl; 98 | volatile uint8_t * const _ucsra; 99 | volatile uint8_t * const _ucsrb; 100 | volatile uint8_t * const _ucsrc; 101 | volatile uint8_t * const _udr; 102 | // Has any byte been written to the UART since begin() 103 | bool _written; 104 | 105 | volatile rx_buffer_index_t _rx_buffer_head; 106 | volatile rx_buffer_index_t _rx_buffer_tail; 107 | volatile tx_buffer_index_t _tx_buffer_head; 108 | volatile tx_buffer_index_t _tx_buffer_tail; 109 | 110 | // Don't put any members after these buffers, since only the first 111 | // 32 bytes of this struct can be accessed quickly using the ldd 112 | // instruction. 113 | unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE]; 114 | unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE]; 115 | 116 | public: 117 | inline HardwareSerial( 118 | volatile uint8_t *ubrrh, volatile uint8_t *ubrrl, 119 | volatile uint8_t *ucsra, volatile uint8_t *ucsrb, 120 | volatile uint8_t *ucsrc, volatile uint8_t *udr); 121 | void begin(unsigned long baud) { begin(baud, SERIAL_8N1); } 122 | void begin(unsigned long, uint8_t); 123 | void end(); 124 | virtual int available(void); 125 | virtual int peek(void); 126 | virtual int read(void); 127 | int availableForWrite(void); 128 | virtual void flush(void); 129 | virtual size_t write(uint8_t); 130 | inline size_t write(unsigned long n) { return write((uint8_t)n); } 131 | inline size_t write(long n) { return write((uint8_t)n); } 132 | inline size_t write(unsigned int n) { return write((uint8_t)n); } 133 | inline size_t write(int n) { return write((uint8_t)n); } 134 | using Print::write; // pull in write(str) and write(buf, size) from Print 135 | operator bool() { return true; } 136 | 137 | // Interrupt handlers - Not intended to be called externally 138 | inline void _rx_complete_irq(void); 139 | void _tx_udr_empty_irq(void); 140 | }; 141 | 142 | #if defined(UBRRH) || defined(UBRR0H) 143 | extern HardwareSerial Serial; 144 | #define HAVE_HWSERIAL0 145 | #endif 146 | #if defined(UBRR1H) 147 | extern HardwareSerial Serial1; 148 | #define HAVE_HWSERIAL1 149 | #endif 150 | #if defined(UBRR2H) 151 | extern HardwareSerial Serial2; 152 | #define HAVE_HWSERIAL2 153 | #endif 154 | #if defined(UBRR3H) 155 | extern HardwareSerial Serial3; 156 | #define HAVE_HWSERIAL3 157 | #endif 158 | 159 | extern void serialEventRun(void) __attribute__((weak)); 160 | 161 | #endif 162 | -------------------------------------------------------------------------------- /src/core/HardwareSerial0.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | HardwareSerial0.cpp - Hardware serial library for Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 23 November 2006 by David A. Mellis 20 | Modified 28 September 2010 by Mark Sproul 21 | Modified 14 August 2012 by Alarus 22 | Modified 3 December 2013 by Matthijs Kooijman 23 | */ 24 | 25 | #include "Arduino.h" 26 | #include "HardwareSerial.h" 27 | #include "HardwareSerial_private.h" 28 | 29 | // Each HardwareSerial is defined in its own file, sine the linker pulls 30 | // in the entire file when any element inside is used. --gc-sections can 31 | // additionally cause unused symbols to be dropped, but ISRs have the 32 | // "used" attribute so are never dropped and they keep the 33 | // HardwareSerial instance in as well. Putting each instance in its own 34 | // file prevents the linker from pulling in any unused instances in the 35 | // first place. 36 | 37 | #if defined(HAVE_HWSERIAL0) 38 | 39 | #if defined(USART_RX_vect) 40 | ISR(USART_RX_vect) 41 | #elif defined(USART0_RX_vect) 42 | ISR(USART0_RX_vect) 43 | #elif defined(USART_RXC_vect) 44 | ISR(USART_RXC_vect) // ATmega8 45 | #else 46 | #error "Don't know what the Data Received vector is called for Serial" 47 | #endif 48 | { 49 | Serial._rx_complete_irq(); 50 | } 51 | 52 | #if defined(UART0_UDRE_vect) 53 | ISR(UART0_UDRE_vect) 54 | #elif defined(UART_UDRE_vect) 55 | ISR(UART_UDRE_vect) 56 | #elif defined(USART0_UDRE_vect) 57 | ISR(USART0_UDRE_vect) 58 | #elif defined(USART_UDRE_vect) 59 | ISR(USART_UDRE_vect) 60 | #else 61 | #error "Don't know what the Data Register Empty vector is called for Serial" 62 | #endif 63 | { 64 | Serial._tx_udr_empty_irq(); 65 | } 66 | 67 | #if defined(UBRRH) && defined(UBRRL) 68 | HardwareSerial Serial(&UBRRH, &UBRRL, &UCSRA, &UCSRB, &UCSRC, &UDR); 69 | #else 70 | HardwareSerial Serial(&UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UCSR0C, &UDR0); 71 | #endif 72 | 73 | // Function that can be weakly referenced by serialEventRun to prevent 74 | // pulling in this file if it's not otherwise used. 75 | bool Serial0_available() { 76 | return Serial.available(); 77 | } 78 | 79 | #endif // HAVE_HWSERIAL0 80 | -------------------------------------------------------------------------------- /src/core/HardwareSerial1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | HardwareSerial1.cpp - Hardware serial library for Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 23 November 2006 by David A. Mellis 20 | Modified 28 September 2010 by Mark Sproul 21 | Modified 14 August 2012 by Alarus 22 | Modified 3 December 2013 by Matthijs Kooijman 23 | */ 24 | 25 | #include "Arduino.h" 26 | #include "HardwareSerial.h" 27 | #include "HardwareSerial_private.h" 28 | 29 | // Each HardwareSerial is defined in its own file, sine the linker pulls 30 | // in the entire file when any element inside is used. --gc-sections can 31 | // additionally cause unused symbols to be dropped, but ISRs have the 32 | // "used" attribute so are never dropped and they keep the 33 | // HardwareSerial instance in as well. Putting each instance in its own 34 | // file prevents the linker from pulling in any unused instances in the 35 | // first place. 36 | 37 | #if defined(HAVE_HWSERIAL1) 38 | 39 | #if defined(UART1_RX_vect) 40 | ISR(UART1_RX_vect) 41 | #elif defined(USART1_RX_vect) 42 | ISR(USART1_RX_vect) 43 | #else 44 | #error "Don't know what the Data Register Empty vector is called for Serial1" 45 | #endif 46 | { 47 | Serial1._rx_complete_irq(); 48 | } 49 | 50 | #if defined(UART1_UDRE_vect) 51 | ISR(UART1_UDRE_vect) 52 | #elif defined(USART1_UDRE_vect) 53 | ISR(USART1_UDRE_vect) 54 | #else 55 | #error "Don't know what the Data Register Empty vector is called for Serial1" 56 | #endif 57 | { 58 | Serial1._tx_udr_empty_irq(); 59 | } 60 | 61 | HardwareSerial Serial1(&UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UCSR1C, &UDR1); 62 | 63 | // Function that can be weakly referenced by serialEventRun to prevent 64 | // pulling in this file if it's not otherwise used. 65 | bool Serial1_available() { 66 | return Serial1.available(); 67 | } 68 | 69 | #endif // HAVE_HWSERIAL1 70 | -------------------------------------------------------------------------------- /src/core/HardwareSerial2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | HardwareSerial2.cpp - Hardware serial library for Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 23 November 2006 by David A. Mellis 20 | Modified 28 September 2010 by Mark Sproul 21 | Modified 14 August 2012 by Alarus 22 | Modified 3 December 2013 by Matthijs Kooijman 23 | */ 24 | 25 | #include "Arduino.h" 26 | #include "HardwareSerial.h" 27 | #include "HardwareSerial_private.h" 28 | 29 | // Each HardwareSerial is defined in its own file, sine the linker pulls 30 | // in the entire file when any element inside is used. --gc-sections can 31 | // additionally cause unused symbols to be dropped, but ISRs have the 32 | // "used" attribute so are never dropped and they keep the 33 | // HardwareSerial instance in as well. Putting each instance in its own 34 | // file prevents the linker from pulling in any unused instances in the 35 | // first place. 36 | 37 | #if defined(HAVE_HWSERIAL2) 38 | 39 | ISR(USART2_RX_vect) 40 | { 41 | Serial2._rx_complete_irq(); 42 | } 43 | 44 | ISR(USART2_UDRE_vect) 45 | { 46 | Serial2._tx_udr_empty_irq(); 47 | } 48 | 49 | HardwareSerial Serial2(&UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UCSR2C, &UDR2); 50 | 51 | // Function that can be weakly referenced by serialEventRun to prevent 52 | // pulling in this file if it's not otherwise used. 53 | bool Serial2_available() { 54 | return Serial2.available(); 55 | } 56 | 57 | #endif // HAVE_HWSERIAL2 58 | -------------------------------------------------------------------------------- /src/core/HardwareSerial3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | HardwareSerial3.cpp - Hardware serial library for Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 23 November 2006 by David A. Mellis 20 | Modified 28 September 2010 by Mark Sproul 21 | Modified 14 August 2012 by Alarus 22 | Modified 3 December 2013 by Matthijs Kooijman 23 | */ 24 | 25 | #include "Arduino.h" 26 | #include "HardwareSerial.h" 27 | #include "HardwareSerial_private.h" 28 | 29 | // Each HardwareSerial is defined in its own file, sine the linker pulls 30 | // in the entire file when any element inside is used. --gc-sections can 31 | // additionally cause unused symbols to be dropped, but ISRs have the 32 | // "used" attribute so are never dropped and they keep the 33 | // HardwareSerial instance in as well. Putting each instance in its own 34 | // file prevents the linker from pulling in any unused instances in the 35 | // first place. 36 | 37 | #if defined(HAVE_HWSERIAL3) 38 | 39 | ISR(USART3_RX_vect) 40 | { 41 | Serial3._rx_complete_irq(); 42 | } 43 | 44 | ISR(USART3_UDRE_vect) 45 | { 46 | Serial3._tx_udr_empty_irq(); 47 | } 48 | 49 | HardwareSerial Serial3(&UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UCSR3C, &UDR3); 50 | 51 | // Function that can be weakly referenced by serialEventRun to prevent 52 | // pulling in this file if it's not otherwise used. 53 | bool Serial3_available() { 54 | return Serial3.available(); 55 | } 56 | 57 | #endif // HAVE_HWSERIAL3 58 | -------------------------------------------------------------------------------- /src/core/HardwareSerial_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | HardwareSerial_private.h - Hardware serial library for Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 23 November 2006 by David A. Mellis 20 | Modified 28 September 2010 by Mark Sproul 21 | Modified 14 August 2012 by Alarus 22 | */ 23 | 24 | #include "wiring_private.h" 25 | 26 | // this next line disables the entire HardwareSerial.cpp, 27 | // this is so I can support Attiny series and any other chip without a uart 28 | #if defined(HAVE_HWSERIAL0) || defined(HAVE_HWSERIAL1) || defined(HAVE_HWSERIAL2) || defined(HAVE_HWSERIAL3) 29 | 30 | // Ensure that the various bit positions we use are available with a 0 31 | // postfix, so we can always use the values for UART0 for all UARTs. The 32 | // alternative, passing the various values for each UART to the 33 | // HardwareSerial constructor also works, but makes the code bigger and 34 | // slower. 35 | #if !defined(TXC0) 36 | #if defined(TXC) 37 | // Some chips like ATmega8 don't have UPE, only PE. The other bits are 38 | // named as expected. 39 | #if !defined(UPE) && defined(PE) 40 | #define UPE PE 41 | #endif 42 | // On ATmega8, the uart and its bits are not numbered, so there is no TXC0 etc. 43 | #define TXC0 TXC 44 | #define RXEN0 RXEN 45 | #define TXEN0 TXEN 46 | #define RXCIE0 RXCIE 47 | #define UDRIE0 UDRIE 48 | #define U2X0 U2X 49 | #define UPE0 UPE 50 | #define UDRE0 UDRE 51 | #elif defined(TXC1) 52 | // Some devices have uart1 but no uart0 53 | #define TXC0 TXC1 54 | #define RXEN0 RXEN1 55 | #define TXEN0 TXEN1 56 | #define RXCIE0 RXCIE1 57 | #define UDRIE0 UDRIE1 58 | #define U2X0 U2X1 59 | #define UPE0 UPE1 60 | #define UDRE0 UDRE1 61 | #else 62 | #error No UART found in HardwareSerial.cpp 63 | #endif 64 | #endif // !defined TXC0 65 | 66 | // Check at compiletime that it is really ok to use the bit positions of 67 | // UART0 for the other UARTs as well, in case these values ever get 68 | // changed for future hardware. 69 | #if defined(TXC1) && (TXC1 != TXC0 || RXEN1 != RXEN0 || RXCIE1 != RXCIE0 || \ 70 | UDRIE1 != UDRIE0 || U2X1 != U2X0 || UPE1 != UPE0 || \ 71 | UDRE1 != UDRE0) 72 | #error "Not all bit positions for UART1 are the same as for UART0" 73 | #endif 74 | #if defined(TXC2) && (TXC2 != TXC0 || RXEN2 != RXEN0 || RXCIE2 != RXCIE0 || \ 75 | UDRIE2 != UDRIE0 || U2X2 != U2X0 || UPE2 != UPE0 || \ 76 | UDRE2 != UDRE0) 77 | #error "Not all bit positions for UART2 are the same as for UART0" 78 | #endif 79 | #if defined(TXC3) && (TXC3 != TXC0 || RXEN3 != RXEN0 || RXCIE3 != RXCIE0 || \ 80 | UDRIE3 != UDRIE0 || U3X3 != U3X0 || UPE3 != UPE0 || \ 81 | UDRE3 != UDRE0) 82 | #error "Not all bit positions for UART3 are the same as for UART0" 83 | #endif 84 | 85 | // Constructors //////////////////////////////////////////////////////////////// 86 | 87 | HardwareSerial::HardwareSerial( 88 | volatile uint8_t *ubrrh, volatile uint8_t *ubrrl, 89 | volatile uint8_t *ucsra, volatile uint8_t *ucsrb, 90 | volatile uint8_t *ucsrc, volatile uint8_t *udr) : 91 | _ubrrh(ubrrh), _ubrrl(ubrrl), 92 | _ucsra(ucsra), _ucsrb(ucsrb), _ucsrc(ucsrc), 93 | _udr(udr), 94 | _rx_buffer_head(0), _rx_buffer_tail(0), 95 | _tx_buffer_head(0), _tx_buffer_tail(0) 96 | { 97 | } 98 | 99 | // Actual interrupt handlers ////////////////////////////////////////////////////////////// 100 | 101 | void HardwareSerial::_rx_complete_irq(void) 102 | { 103 | if (bit_is_clear(*_ucsra, UPE0)) { 104 | // No Parity error, read byte and store it in the buffer if there is 105 | // room 106 | unsigned char c = *_udr; 107 | rx_buffer_index_t i = (unsigned int)(_rx_buffer_head + 1) % SERIAL_RX_BUFFER_SIZE; 108 | 109 | // if we should be storing the received character into the location 110 | // just before the tail (meaning that the head would advance to the 111 | // current location of the tail), we're about to overflow the buffer 112 | // and so we don't write the character or advance the head. 113 | if (i != _rx_buffer_tail) { 114 | _rx_buffer[_rx_buffer_head] = c; 115 | _rx_buffer_head = i; 116 | } 117 | } else { 118 | // Parity error, read byte but discard it 119 | *_udr; 120 | }; 121 | } 122 | 123 | #endif // whole file 124 | -------------------------------------------------------------------------------- /src/core/IPAddress.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | IPAddress.cpp - Base class that provides IPAddress 3 | Copyright (c) 2011 Adrian McEwen. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | IPAddress::IPAddress() 24 | { 25 | _address.dword = 0; 26 | } 27 | 28 | IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) 29 | { 30 | _address.bytes[0] = first_octet; 31 | _address.bytes[1] = second_octet; 32 | _address.bytes[2] = third_octet; 33 | _address.bytes[3] = fourth_octet; 34 | } 35 | 36 | IPAddress::IPAddress(uint32_t address) 37 | { 38 | _address.dword = address; 39 | } 40 | 41 | IPAddress::IPAddress(const uint8_t *address) 42 | { 43 | memcpy(_address.bytes, address, sizeof(_address.bytes)); 44 | } 45 | 46 | bool IPAddress::fromString(const char *address) 47 | { 48 | // TODO: add support for "a", "a.b", "a.b.c" formats 49 | 50 | uint16_t acc = 0; // Accumulator 51 | uint8_t dots = 0; 52 | 53 | while (*address) 54 | { 55 | char c = *address++; 56 | if (c >= '0' && c <= '9') 57 | { 58 | acc = acc * 10 + (c - '0'); 59 | if (acc > 255) { 60 | // Value out of [0..255] range 61 | return false; 62 | } 63 | } 64 | else if (c == '.') 65 | { 66 | if (dots == 3) { 67 | // Too much dots (there must be 3 dots) 68 | return false; 69 | } 70 | _address.bytes[dots++] = acc; 71 | acc = 0; 72 | } 73 | else 74 | { 75 | // Invalid char 76 | return false; 77 | } 78 | } 79 | 80 | if (dots != 3) { 81 | // Too few dots (there must be 3 dots) 82 | return false; 83 | } 84 | _address.bytes[3] = acc; 85 | return true; 86 | } 87 | 88 | IPAddress& IPAddress::operator=(const uint8_t *address) 89 | { 90 | memcpy(_address.bytes, address, sizeof(_address.bytes)); 91 | return *this; 92 | } 93 | 94 | IPAddress& IPAddress::operator=(uint32_t address) 95 | { 96 | _address.dword = address; 97 | return *this; 98 | } 99 | 100 | bool IPAddress::operator==(const uint8_t* addr) const 101 | { 102 | return memcmp(addr, _address.bytes, sizeof(_address.bytes)) == 0; 103 | } 104 | 105 | size_t IPAddress::printTo(Print& p) const 106 | { 107 | size_t n = 0; 108 | for (int i =0; i < 3; i++) 109 | { 110 | n += p.print(_address.bytes[i], DEC); 111 | n += p.print('.'); 112 | } 113 | n += p.print(_address.bytes[3], DEC); 114 | return n; 115 | } 116 | 117 | -------------------------------------------------------------------------------- /src/core/IPAddress.h: -------------------------------------------------------------------------------- 1 | /* 2 | IPAddress.h - Base class that provides IPAddress 3 | Copyright (c) 2011 Adrian McEwen. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef IPAddress_h 21 | #define IPAddress_h 22 | 23 | #include 24 | #include "Printable.h" 25 | #include "WString.h" 26 | 27 | // A class to make it easier to handle and pass around IP addresses 28 | 29 | class IPAddress : public Printable { 30 | private: 31 | union { 32 | uint8_t bytes[4]; // IPv4 address 33 | uint32_t dword; 34 | } _address; 35 | 36 | // Access the raw byte array containing the address. Because this returns a pointer 37 | // to the internal structure rather than a copy of the address this function should only 38 | // be used when you know that the usage of the returned uint8_t* will be transient and not 39 | // stored. 40 | uint8_t* raw_address() { return _address.bytes; }; 41 | 42 | public: 43 | // Constructors 44 | IPAddress(); 45 | IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet); 46 | IPAddress(uint32_t address); 47 | IPAddress(const uint8_t *address); 48 | 49 | bool fromString(const char *address); 50 | bool fromString(const String &address) { return fromString(address.c_str()); } 51 | 52 | // Overloaded cast operator to allow IPAddress objects to be used where a pointer 53 | // to a four-byte uint8_t array is expected 54 | operator uint32_t() const { return _address.dword; }; 55 | bool operator==(const IPAddress& addr) const { return _address.dword == addr._address.dword; }; 56 | bool operator==(const uint8_t* addr) const; 57 | 58 | // Overloaded index operator to allow getting and setting individual octets of the address 59 | uint8_t operator[](int index) const { return _address.bytes[index]; }; 60 | uint8_t& operator[](int index) { return _address.bytes[index]; }; 61 | 62 | // Overloaded copy operators to allow initialisation of IPAddress objects from other types 63 | IPAddress& operator=(const uint8_t *address); 64 | IPAddress& operator=(uint32_t address); 65 | 66 | virtual size_t printTo(Print& p) const; 67 | 68 | friend class EthernetClass; 69 | friend class UDP; 70 | friend class Client; 71 | friend class Server; 72 | friend class DhcpClass; 73 | friend class DNSClient; 74 | }; 75 | 76 | const IPAddress INADDR_NONE(0,0,0,0); 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /src/core/PluggableUSB.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | PluggableUSB.cpp 3 | Copyright (c) 2015 Arduino LLC 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include "USBAPI.h" 21 | #include "PluggableUSB.h" 22 | 23 | #if defined(USBCON) 24 | #ifdef PLUGGABLE_USB_ENABLED 25 | 26 | extern uint8_t _initEndpoints[]; 27 | 28 | int PluggableUSB_::getInterface(uint8_t* interfaceCount) 29 | { 30 | int sent = 0; 31 | PluggableUSBModule* node; 32 | for (node = rootNode; node; node = node->next) { 33 | int res = node->getInterface(interfaceCount); 34 | if (res < 0) 35 | return -1; 36 | sent += res; 37 | } 38 | return sent; 39 | } 40 | 41 | int PluggableUSB_::getDescriptor(USBSetup& setup) 42 | { 43 | PluggableUSBModule* node; 44 | for (node = rootNode; node; node = node->next) { 45 | int ret = node->getDescriptor(setup); 46 | // ret!=0 -> request has been processed 47 | if (ret) 48 | return ret; 49 | } 50 | return 0; 51 | } 52 | 53 | void PluggableUSB_::getShortName(char *iSerialNum) 54 | { 55 | PluggableUSBModule* node; 56 | for (node = rootNode; node; node = node->next) { 57 | iSerialNum += node->getShortName(iSerialNum); 58 | } 59 | *iSerialNum = 0; 60 | } 61 | 62 | bool PluggableUSB_::setup(USBSetup& setup) 63 | { 64 | PluggableUSBModule* node; 65 | for (node = rootNode; node; node = node->next) { 66 | if (node->setup(setup)) { 67 | return true; 68 | } 69 | } 70 | return false; 71 | } 72 | 73 | bool PluggableUSB_::plug(PluggableUSBModule *node) 74 | { 75 | if ((lastEp + node->numEndpoints) > USB_ENDPOINTS) { 76 | return false; 77 | } 78 | 79 | if (!rootNode) { 80 | rootNode = node; 81 | } else { 82 | PluggableUSBModule *current = rootNode; 83 | while (current->next) { 84 | current = current->next; 85 | } 86 | current->next = node; 87 | } 88 | 89 | node->pluggedInterface = lastIf; 90 | node->pluggedEndpoint = lastEp; 91 | lastIf += node->numInterfaces; 92 | for (uint8_t i = 0; i < node->numEndpoints; i++) { 93 | _initEndpoints[lastEp] = node->endpointType[i]; 94 | lastEp++; 95 | } 96 | return true; 97 | // restart USB layer??? 98 | } 99 | 100 | PluggableUSB_& PluggableUSB() 101 | { 102 | static PluggableUSB_ obj; 103 | return obj; 104 | } 105 | 106 | PluggableUSB_::PluggableUSB_() : lastIf(CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT), 107 | lastEp(CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT), 108 | rootNode(NULL) 109 | { 110 | // Empty 111 | } 112 | 113 | #endif 114 | 115 | #endif /* if defined(USBCON) */ 116 | -------------------------------------------------------------------------------- /src/core/PluggableUSB.h: -------------------------------------------------------------------------------- 1 | /* 2 | PluggableUSB.h 3 | Copyright (c) 2015 Arduino LLC 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef PUSB_h 21 | #define PUSB_h 22 | 23 | #include "USBAPI.h" 24 | #include 25 | 26 | #if defined(USBCON) 27 | 28 | class PluggableUSBModule { 29 | public: 30 | PluggableUSBModule(uint8_t numEps, uint8_t numIfs, uint8_t *epType) : 31 | numEndpoints(numEps), numInterfaces(numIfs), endpointType(epType) 32 | { } 33 | 34 | protected: 35 | virtual bool setup(USBSetup& setup) = 0; 36 | virtual int getInterface(uint8_t* interfaceCount) = 0; 37 | virtual int getDescriptor(USBSetup& setup) = 0; 38 | virtual uint8_t getShortName(char *name) { name[0] = 'A'+pluggedInterface; return 1; } 39 | 40 | uint8_t pluggedInterface; 41 | uint8_t pluggedEndpoint; 42 | 43 | const uint8_t numEndpoints; 44 | const uint8_t numInterfaces; 45 | const uint8_t *endpointType; 46 | 47 | PluggableUSBModule *next = NULL; 48 | 49 | friend class PluggableUSB_; 50 | }; 51 | 52 | class PluggableUSB_ { 53 | public: 54 | PluggableUSB_(); 55 | bool plug(PluggableUSBModule *node); 56 | int getInterface(uint8_t* interfaceCount); 57 | int getDescriptor(USBSetup& setup); 58 | bool setup(USBSetup& setup); 59 | void getShortName(char *iSerialNum); 60 | 61 | private: 62 | uint8_t lastIf; 63 | uint8_t lastEp; 64 | PluggableUSBModule* rootNode; 65 | }; 66 | 67 | // Replacement for global singleton. 68 | // This function prevents static-initialization-order-fiasco 69 | // https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use 70 | PluggableUSB_& PluggableUSB(); 71 | 72 | #endif 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /src/core/Print.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Print.cpp - Base class that provides print() and println() 3 | Copyright (c) 2008 David A. Mellis. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 23 November 2006 by David A. Mellis 20 | Modified 03 August 2015 by Chuck Todd 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include "Arduino.h" 28 | 29 | #include "Print.h" 30 | 31 | // Public Methods ////////////////////////////////////////////////////////////// 32 | 33 | /* default implementation: may be overridden */ 34 | size_t Print::write(const uint8_t *buffer, size_t size) 35 | { 36 | size_t n = 0; 37 | while (size--) { 38 | if (write(*buffer++)) n++; 39 | else break; 40 | } 41 | return n; 42 | } 43 | 44 | size_t Print::print(const __FlashStringHelper *ifsh) 45 | { 46 | PGM_P p = reinterpret_cast(ifsh); 47 | size_t n = 0; 48 | while (1) { 49 | unsigned char c = pgm_read_byte(p++); 50 | if (c == 0) break; 51 | if (write(c)) n++; 52 | else break; 53 | } 54 | return n; 55 | } 56 | 57 | size_t Print::print(const String &s) 58 | { 59 | return write(s.c_str(), s.length()); 60 | } 61 | 62 | size_t Print::print(const char str[]) 63 | { 64 | return write(str); 65 | } 66 | 67 | size_t Print::print(char c) 68 | { 69 | return write(c); 70 | } 71 | 72 | size_t Print::print(unsigned char b, int base) 73 | { 74 | return print((unsigned long) b, base); 75 | } 76 | 77 | size_t Print::print(int n, int base) 78 | { 79 | return print((long) n, base); 80 | } 81 | 82 | size_t Print::print(unsigned int n, int base) 83 | { 84 | return print((unsigned long) n, base); 85 | } 86 | 87 | size_t Print::print(long n, int base) 88 | { 89 | if (base == 0) { 90 | return write(n); 91 | } else if (base == 10) { 92 | if (n < 0) { 93 | int t = print('-'); 94 | n = -n; 95 | return printNumber(n, 10) + t; 96 | } 97 | return printNumber(n, 10); 98 | } else { 99 | return printNumber(n, base); 100 | } 101 | } 102 | 103 | size_t Print::print(unsigned long n, int base) 104 | { 105 | if (base == 0) return write(n); 106 | else return printNumber(n, base); 107 | } 108 | 109 | size_t Print::print(double n, int digits) 110 | { 111 | return printFloat(n, digits); 112 | } 113 | 114 | size_t Print::println(const __FlashStringHelper *ifsh) 115 | { 116 | size_t n = print(ifsh); 117 | n += println(); 118 | return n; 119 | } 120 | 121 | size_t Print::print(const Printable& x) 122 | { 123 | return x.printTo(*this); 124 | } 125 | 126 | size_t Print::println(void) 127 | { 128 | return write("\r\n"); 129 | } 130 | 131 | size_t Print::println(const String &s) 132 | { 133 | size_t n = print(s); 134 | n += println(); 135 | return n; 136 | } 137 | 138 | size_t Print::println(const char c[]) 139 | { 140 | size_t n = print(c); 141 | n += println(); 142 | return n; 143 | } 144 | 145 | size_t Print::println(char c) 146 | { 147 | size_t n = print(c); 148 | n += println(); 149 | return n; 150 | } 151 | 152 | size_t Print::println(unsigned char b, int base) 153 | { 154 | size_t n = print(b, base); 155 | n += println(); 156 | return n; 157 | } 158 | 159 | size_t Print::println(int num, int base) 160 | { 161 | size_t n = print(num, base); 162 | n += println(); 163 | return n; 164 | } 165 | 166 | size_t Print::println(unsigned int num, int base) 167 | { 168 | size_t n = print(num, base); 169 | n += println(); 170 | return n; 171 | } 172 | 173 | size_t Print::println(long num, int base) 174 | { 175 | size_t n = print(num, base); 176 | n += println(); 177 | return n; 178 | } 179 | 180 | size_t Print::println(unsigned long num, int base) 181 | { 182 | size_t n = print(num, base); 183 | n += println(); 184 | return n; 185 | } 186 | 187 | size_t Print::println(double num, int digits) 188 | { 189 | size_t n = print(num, digits); 190 | n += println(); 191 | return n; 192 | } 193 | 194 | size_t Print::println(const Printable& x) 195 | { 196 | size_t n = print(x); 197 | n += println(); 198 | return n; 199 | } 200 | 201 | // Private Methods ///////////////////////////////////////////////////////////// 202 | 203 | size_t Print::printNumber(unsigned long n, uint8_t base) 204 | { 205 | char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. 206 | char *str = &buf[sizeof(buf) - 1]; 207 | 208 | *str = '\0'; 209 | 210 | // prevent crash if called with base == 1 211 | if (base < 2) base = 10; 212 | 213 | do { 214 | char c = n % base; 215 | n /= base; 216 | 217 | *--str = c < 10 ? c + '0' : c + 'A' - 10; 218 | } while(n); 219 | 220 | return write(str); 221 | } 222 | 223 | size_t Print::printFloat(double number, uint8_t digits) 224 | { 225 | size_t n = 0; 226 | 227 | if (isnan(number)) return print("nan"); 228 | if (isinf(number)) return print("inf"); 229 | if (number > 4294967040.0) return print ("ovf"); // constant determined empirically 230 | if (number <-4294967040.0) return print ("ovf"); // constant determined empirically 231 | 232 | // Handle negative numbers 233 | if (number < 0.0) 234 | { 235 | n += print('-'); 236 | number = -number; 237 | } 238 | 239 | // Round correctly so that print(1.999, 2) prints as "2.00" 240 | double rounding = 0.5; 241 | for (uint8_t i=0; i 0) { 253 | n += print("."); 254 | } 255 | 256 | // Extract digits from the remainder one at a time 257 | while (digits-- > 0) 258 | { 259 | remainder *= 10.0; 260 | int toPrint = int(remainder); 261 | n += print(toPrint); 262 | remainder -= toPrint; 263 | } 264 | 265 | return n; 266 | } 267 | -------------------------------------------------------------------------------- /src/core/Print.h: -------------------------------------------------------------------------------- 1 | /* 2 | Print.h - Base class that provides print() and println() 3 | Copyright (c) 2008 David A. Mellis. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef Print_h 21 | #define Print_h 22 | 23 | #include 24 | #include // for size_t 25 | 26 | #include "WString.h" 27 | #include "Printable.h" 28 | 29 | #define DEC 10 30 | #define HEX 16 31 | #define OCT 8 32 | #define BIN 2 33 | 34 | class Print 35 | { 36 | private: 37 | int write_error; 38 | size_t printNumber(unsigned long, uint8_t); 39 | size_t printFloat(double, uint8_t); 40 | protected: 41 | void setWriteError(int err = 1) { write_error = err; } 42 | public: 43 | Print() : write_error(0) {} 44 | 45 | int getWriteError() { return write_error; } 46 | void clearWriteError() { setWriteError(0); } 47 | 48 | virtual size_t write(uint8_t) = 0; 49 | size_t write(const char *str) { 50 | if (str == NULL) return 0; 51 | return write((const uint8_t *)str, strlen(str)); 52 | } 53 | virtual size_t write(const uint8_t *buffer, size_t size); 54 | size_t write(const char *buffer, size_t size) { 55 | return write((const uint8_t *)buffer, size); 56 | } 57 | 58 | size_t print(const __FlashStringHelper *); 59 | size_t print(const String &); 60 | size_t print(const char[]); 61 | size_t print(char); 62 | size_t print(unsigned char, int = DEC); 63 | size_t print(int, int = DEC); 64 | size_t print(unsigned int, int = DEC); 65 | size_t print(long, int = DEC); 66 | size_t print(unsigned long, int = DEC); 67 | size_t print(double, int = 2); 68 | size_t print(const Printable&); 69 | 70 | size_t println(const __FlashStringHelper *); 71 | size_t println(const String &s); 72 | size_t println(const char[]); 73 | size_t println(char); 74 | size_t println(unsigned char, int = DEC); 75 | size_t println(int, int = DEC); 76 | size_t println(unsigned int, int = DEC); 77 | size_t println(long, int = DEC); 78 | size_t println(unsigned long, int = DEC); 79 | size_t println(double, int = 2); 80 | size_t println(const Printable&); 81 | size_t println(void); 82 | }; 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /src/core/Printable.h: -------------------------------------------------------------------------------- 1 | /* 2 | Printable.h - Interface class that allows printing of complex types 3 | Copyright (c) 2011 Adrian McEwen. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef Printable_h 21 | #define Printable_h 22 | 23 | #include 24 | 25 | class Print; 26 | 27 | /** The Printable class provides a way for new classes to allow themselves to be printed. 28 | By deriving from Printable and implementing the printTo method, it will then be possible 29 | for users to print out instances of this class by passing them into the usual 30 | Print::print and Print::println methods. 31 | */ 32 | 33 | class Printable 34 | { 35 | public: 36 | virtual size_t printTo(Print& p) const = 0; 37 | }; 38 | 39 | #endif 40 | 41 | -------------------------------------------------------------------------------- /src/core/SPI.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 by Cristian Maglie 3 | * Copyright (c) 2014 by Paul Stoffregen (Transaction API) 4 | * Copyright (c) 2014 by Matthijs Kooijman (SPISettings AVR) 5 | * Copyright (c) 2014 by Andrew J. Kroll (atomicity fixes) 6 | * SPI Master library for arduino. 7 | * 8 | * This file is free software; you can redistribute it and/or modify 9 | * it under the terms of either the GNU General Public License version 2 10 | * or the GNU Lesser General Public License version 2.1, both as 11 | * published by the Free Software Foundation. 12 | */ 13 | 14 | #include "SPI.h" 15 | 16 | SPIClass SPI; 17 | 18 | uint8_t SPIClass::initialized = 0; 19 | uint8_t SPIClass::interruptMode = 0; 20 | uint8_t SPIClass::interruptMask = 0; 21 | uint8_t SPIClass::interruptSave = 0; 22 | #ifdef SPI_TRANSACTION_MISMATCH_LED 23 | uint8_t SPIClass::inTransactionFlag = 0; 24 | #endif 25 | 26 | void SPIClass::begin() 27 | { 28 | uint8_t sreg = SREG; 29 | noInterrupts(); // Protect from a scheduler and prevent transactionBegin 30 | if (!initialized) { 31 | // Set SS to high so a connected chip will be "deselected" by default 32 | uint8_t port = digitalPinToPort(SS); 33 | uint8_t bit = digitalPinToBitMask(SS); 34 | volatile uint8_t *reg = portModeRegister(port); 35 | 36 | // if the SS pin is not already configured as an output 37 | // then set it high (to enable the internal pull-up resistor) 38 | if(!(*reg & bit)){ 39 | digitalWrite(SS, HIGH); 40 | } 41 | 42 | // When the SS pin is set as OUTPUT, it can be used as 43 | // a general purpose output port (it doesn't influence 44 | // SPI operations). 45 | pinMode(SS, OUTPUT); 46 | 47 | // Warning: if the SS pin ever becomes a LOW INPUT then SPI 48 | // automatically switches to Slave, so the data direction of 49 | // the SS pin MUST be kept as OUTPUT. 50 | SPCR |= _BV(MSTR); 51 | SPCR |= _BV(SPE); 52 | 53 | // Set direction register for SCK and MOSI pin. 54 | // MISO pin automatically overrides to INPUT. 55 | // By doing this AFTER enabling SPI, we avoid accidentally 56 | // clocking in a single bit since the lines go directly 57 | // from "input" to SPI control. 58 | // http://code.google.com/p/arduino/issues/detail?id=888 59 | pinMode(SCK, OUTPUT); 60 | pinMode(MOSI, OUTPUT); 61 | } 62 | initialized++; // reference count 63 | SREG = sreg; 64 | } 65 | 66 | void SPIClass::end() { 67 | uint8_t sreg = SREG; 68 | noInterrupts(); // Protect from a scheduler and prevent transactionBegin 69 | // Decrease the reference counter 70 | if (initialized) 71 | initialized--; 72 | // If there are no more references disable SPI 73 | if (!initialized) { 74 | SPCR &= ~_BV(SPE); 75 | interruptMode = 0; 76 | #ifdef SPI_TRANSACTION_MISMATCH_LED 77 | inTransactionFlag = 0; 78 | #endif 79 | } 80 | SREG = sreg; 81 | } 82 | 83 | // mapping of interrupt numbers to bits within SPI_AVR_EIMSK 84 | #if defined(__AVR_ATmega32U4__) 85 | #define SPI_INT0_MASK (1< 26 | #include "Print.h" 27 | 28 | // compatability macros for testing 29 | /* 30 | #define getInt() parseInt() 31 | #define getInt(ignore) parseInt(ignore) 32 | #define getFloat() parseFloat() 33 | #define getFloat(ignore) parseFloat(ignore) 34 | #define getString( pre_string, post_string, buffer, length) 35 | readBytesBetween( pre_string, terminator, buffer, length) 36 | */ 37 | 38 | // This enumeration provides the lookahead options for parseInt(), parseFloat() 39 | // The rules set out here are used until either the first valid character is found 40 | // or a time out occurs due to lack of input. 41 | enum LookaheadMode{ 42 | SKIP_ALL, // All invalid characters are ignored. 43 | SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid. 44 | SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped. 45 | }; 46 | 47 | #define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field 48 | 49 | class Stream : public Print 50 | { 51 | protected: 52 | unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read 53 | unsigned long _startMillis; // used for timeout measurement 54 | int timedRead(); // private method to read stream with timeout 55 | int timedPeek(); // private method to peek stream with timeout 56 | int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout 57 | 58 | public: 59 | virtual int available() = 0; 60 | virtual int read() = 0; 61 | virtual int peek() = 0; 62 | virtual void flush() = 0; 63 | 64 | Stream() {_timeout=1000;} 65 | 66 | // parsing methods 67 | 68 | void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second 69 | 70 | bool find(char *target); // reads data from the stream until the target string is found 71 | bool find(uint8_t *target) { return find ((char *)target); } 72 | // returns true if target string is found, false if timed out (see setTimeout) 73 | 74 | bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found 75 | bool find(uint8_t *target, size_t length) { return find ((char *)target, length); } 76 | // returns true if target string is found, false if timed out 77 | 78 | bool find(char target) { return find (&target, 1); } 79 | 80 | bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found 81 | bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); } 82 | 83 | bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found 84 | bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); } 85 | 86 | long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); 87 | // returns the first valid (long) integer value from the current position. 88 | // lookahead determines how parseInt looks ahead in the stream. 89 | // See LookaheadMode enumeration at the top of the file. 90 | // Lookahead is terminated by the first character that is not a valid part of an integer. 91 | // Once parsing commences, 'ignore' will be skipped in the stream. 92 | 93 | float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); 94 | // float version of parseInt 95 | 96 | size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer 97 | size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); } 98 | // terminates if length characters have been read or timeout (see setTimeout) 99 | // returns the number of characters placed in the buffer (0 means no valid data found) 100 | 101 | size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character 102 | size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); } 103 | // terminates if length characters have been read, timeout, or if the terminator character detected 104 | // returns the number of characters placed in the buffer (0 means no valid data found) 105 | 106 | // Arduino String functions to be added here 107 | String readString(); 108 | String readStringUntil(char terminator); 109 | 110 | protected: 111 | long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); } 112 | float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); } 113 | // These overload exists for compatibility with any class that has derived 114 | // Stream and used parseFloat/Int with a custom ignore character. To keep 115 | // the public API simple, these overload remains protected. 116 | 117 | struct MultiTarget { 118 | const char *str; // string you're searching for 119 | size_t len; // length of string you're searching for 120 | size_t index; // index used by the search routine. 121 | }; 122 | 123 | // This allows you to search for an arbitrary number of strings. 124 | // Returns index of the target that is found first or -1 if timeout occurs. 125 | int findMulti(struct MultiTarget *targets, int tCount); 126 | }; 127 | 128 | #undef NO_IGNORE_CHAR 129 | #endif 130 | -------------------------------------------------------------------------------- /src/core/USBAPI.h: -------------------------------------------------------------------------------- 1 | /* 2 | USBAPI.h 3 | Copyright (c) 2005-2014 Arduino. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef __USBAPI__ 21 | #define __USBAPI__ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | typedef unsigned char u8; 30 | typedef unsigned short u16; 31 | typedef unsigned long u32; 32 | 33 | #include "Arduino.h" 34 | 35 | // This definitions is usefull if you want to reduce the EP_SIZE to 16 36 | // at the moment only 64 and 16 as EP_SIZE for all EPs are supported except the control endpoint 37 | #ifndef USB_EP_SIZE 38 | #define USB_EP_SIZE 64 39 | #endif 40 | 41 | #if defined(USBCON) 42 | 43 | #include "USBDesc.h" 44 | #include "USBCore.h" 45 | 46 | //================================================================================ 47 | //================================================================================ 48 | // USB 49 | 50 | #define EP_TYPE_CONTROL (0x00) 51 | #define EP_TYPE_BULK_IN ((1<256) 85 | #error Please lower the CDC Buffer size 86 | #endif 87 | 88 | class Serial_ : public Stream 89 | { 90 | private: 91 | int peek_buffer; 92 | public: 93 | Serial_() { peek_buffer = -1; }; 94 | void begin(unsigned long); 95 | void begin(unsigned long, uint8_t); 96 | void end(void); 97 | 98 | virtual int available(void); 99 | virtual int peek(void); 100 | virtual int read(void); 101 | int availableForWrite(void); 102 | virtual void flush(void); 103 | virtual size_t write(uint8_t); 104 | virtual size_t write(const uint8_t*, size_t); 105 | using Print::write; // pull in write(str) and write(buf, size) from Print 106 | operator bool(); 107 | 108 | volatile uint8_t _rx_buffer_head; 109 | volatile uint8_t _rx_buffer_tail; 110 | unsigned char _rx_buffer[SERIAL_BUFFER_SIZE]; 111 | 112 | // This method allows processing "SEND_BREAK" requests sent by 113 | // the USB host. Those requests indicate that the host wants to 114 | // send a BREAK signal and are accompanied by a single uint16_t 115 | // value, specifying the duration of the break. The value 0 116 | // means to end any current break, while the value 0xffff means 117 | // to start an indefinite break. 118 | // readBreak() will return the value of the most recent break 119 | // request, but will return it at most once, returning -1 when 120 | // readBreak() is called again (until another break request is 121 | // received, which is again returned once). 122 | // This also mean that if two break requests are received 123 | // without readBreak() being called in between, the value of the 124 | // first request is lost. 125 | // Note that the value returned is a long, so it can return 126 | // 0-0xffff as well as -1. 127 | int32_t readBreak(); 128 | 129 | // These return the settings specified by the USB host for the 130 | // serial port. These aren't really used, but are offered here 131 | // in case a sketch wants to act on these settings. 132 | uint32_t baud(); 133 | uint8_t stopbits(); 134 | uint8_t paritytype(); 135 | uint8_t numbits(); 136 | bool dtr(); 137 | bool rts(); 138 | enum { 139 | ONE_STOP_BIT = 0, 140 | ONE_AND_HALF_STOP_BIT = 1, 141 | TWO_STOP_BITS = 2, 142 | }; 143 | enum { 144 | NO_PARITY = 0, 145 | ODD_PARITY = 1, 146 | EVEN_PARITY = 2, 147 | MARK_PARITY = 3, 148 | SPACE_PARITY = 4, 149 | }; 150 | 151 | }; 152 | extern Serial_ Serial; 153 | 154 | #define HAVE_CDCSERIAL 155 | 156 | //================================================================================ 157 | //================================================================================ 158 | // Low level API 159 | 160 | typedef struct 161 | { 162 | uint8_t bmRequestType; 163 | uint8_t bRequest; 164 | uint8_t wValueL; 165 | uint8_t wValueH; 166 | uint16_t wIndex; 167 | uint16_t wLength; 168 | } USBSetup; 169 | 170 | //================================================================================ 171 | //================================================================================ 172 | // MSC 'Driver' 173 | 174 | int MSC_GetInterface(uint8_t* interfaceNum); 175 | int MSC_GetDescriptor(int i); 176 | bool MSC_Setup(USBSetup& setup); 177 | bool MSC_Data(uint8_t rx,uint8_t tx); 178 | 179 | //================================================================================ 180 | //================================================================================ 181 | // CSC 'Driver' 182 | 183 | int CDC_GetInterface(uint8_t* interfaceNum); 184 | int CDC_GetDescriptor(int i); 185 | bool CDC_Setup(USBSetup& setup); 186 | 187 | //================================================================================ 188 | //================================================================================ 189 | 190 | #define TRANSFER_PGM 0x80 191 | #define TRANSFER_RELEASE 0x40 192 | #define TRANSFER_ZERO 0x20 193 | 194 | int USB_SendControl(uint8_t flags, const void* d, int len); 195 | int USB_RecvControl(void* d, int len); 196 | int USB_RecvControlLong(void* d, int len); 197 | 198 | uint8_t USB_Available(uint8_t ep); 199 | uint8_t USB_SendSpace(uint8_t ep); 200 | int USB_Send(uint8_t ep, const void* data, int len); // blocking 201 | int USB_Recv(uint8_t ep, void* data, int len); // non-blocking 202 | int USB_Recv(uint8_t ep); // non-blocking 203 | void USB_Flush(uint8_t ep); 204 | 205 | #endif 206 | 207 | #endif /* if defined(USBCON) */ 208 | -------------------------------------------------------------------------------- /src/core/USBCore.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2010, Peter Barrett 3 | /* 4 | ** Permission to use, copy, modify, and/or distribute this software for 5 | ** any purpose with or without fee is hereby granted, provided that the 6 | ** above copyright notice and this permission notice appear in all copies. 7 | ** 8 | ** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 9 | ** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 10 | ** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 11 | ** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES 12 | ** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 13 | ** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 14 | ** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 15 | ** SOFTWARE. 16 | */ 17 | 18 | #ifndef __USBCORE_H__ 19 | #define __USBCORE_H__ 20 | 21 | #include "USBAPI.h" 22 | 23 | // Standard requests 24 | #define GET_STATUS 0 25 | #define CLEAR_FEATURE 1 26 | #define SET_FEATURE 3 27 | #define SET_ADDRESS 5 28 | #define GET_DESCRIPTOR 6 29 | #define SET_DESCRIPTOR 7 30 | #define GET_CONFIGURATION 8 31 | #define SET_CONFIGURATION 9 32 | #define GET_INTERFACE 10 33 | #define SET_INTERFACE 11 34 | 35 | 36 | // bmRequestType 37 | #define REQUEST_HOSTTODEVICE 0x00 38 | #define REQUEST_DEVICETOHOST 0x80 39 | #define REQUEST_DIRECTION 0x80 40 | 41 | #define REQUEST_STANDARD 0x00 42 | #define REQUEST_CLASS 0x20 43 | #define REQUEST_VENDOR 0x40 44 | #define REQUEST_TYPE 0x60 45 | 46 | #define REQUEST_DEVICE 0x00 47 | #define REQUEST_INTERFACE 0x01 48 | #define REQUEST_ENDPOINT 0x02 49 | #define REQUEST_OTHER 0x03 50 | #define REQUEST_RECIPIENT 0x03 51 | 52 | #define REQUEST_DEVICETOHOST_CLASS_INTERFACE (REQUEST_DEVICETOHOST | REQUEST_CLASS | REQUEST_INTERFACE) 53 | #define REQUEST_HOSTTODEVICE_CLASS_INTERFACE (REQUEST_HOSTTODEVICE | REQUEST_CLASS | REQUEST_INTERFACE) 54 | #define REQUEST_DEVICETOHOST_STANDARD_INTERFACE (REQUEST_DEVICETOHOST | REQUEST_STANDARD | REQUEST_INTERFACE) 55 | 56 | // Class requests 57 | 58 | #define CDC_SET_LINE_CODING 0x20 59 | #define CDC_GET_LINE_CODING 0x21 60 | #define CDC_SET_CONTROL_LINE_STATE 0x22 61 | #define CDC_SEND_BREAK 0x23 62 | 63 | #define MSC_RESET 0xFF 64 | #define MSC_GET_MAX_LUN 0xFE 65 | 66 | // Descriptors 67 | 68 | #define USB_DEVICE_DESC_SIZE 18 69 | #define USB_CONFIGUARTION_DESC_SIZE 9 70 | #define USB_INTERFACE_DESC_SIZE 9 71 | #define USB_ENDPOINT_DESC_SIZE 7 72 | 73 | #define USB_DEVICE_DESCRIPTOR_TYPE 1 74 | #define USB_CONFIGURATION_DESCRIPTOR_TYPE 2 75 | #define USB_STRING_DESCRIPTOR_TYPE 3 76 | #define USB_INTERFACE_DESCRIPTOR_TYPE 4 77 | #define USB_ENDPOINT_DESCRIPTOR_TYPE 5 78 | 79 | // usb_20.pdf Table 9.6 Standard Feature Selectors 80 | #define DEVICE_REMOTE_WAKEUP 1 81 | #define ENDPOINT_HALT 2 82 | #define TEST_MODE 3 83 | 84 | // usb_20.pdf Figure 9-4. Information Returned by a GetStatus() Request to a Device 85 | #define FEATURE_SELFPOWERED_ENABLED (1 << 0) 86 | #define FEATURE_REMOTE_WAKEUP_ENABLED (1 << 1) 87 | 88 | #define USB_DEVICE_CLASS_COMMUNICATIONS 0x02 89 | #define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03 90 | #define USB_DEVICE_CLASS_STORAGE 0x08 91 | #define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF 92 | 93 | #define USB_CONFIG_POWERED_MASK 0x40 94 | #define USB_CONFIG_BUS_POWERED 0x80 95 | #define USB_CONFIG_SELF_POWERED 0xC0 96 | #define USB_CONFIG_REMOTE_WAKEUP 0x20 97 | 98 | // bMaxPower in Configuration Descriptor 99 | #define USB_CONFIG_POWER_MA(mA) ((mA)/2) 100 | 101 | // bEndpointAddress in Endpoint Descriptor 102 | #define USB_ENDPOINT_DIRECTION_MASK 0x80 103 | #define USB_ENDPOINT_OUT(addr) (lowByte((addr) | 0x00)) 104 | #define USB_ENDPOINT_IN(addr) (lowByte((addr) | 0x80)) 105 | 106 | #define USB_ENDPOINT_TYPE_MASK 0x03 107 | #define USB_ENDPOINT_TYPE_CONTROL 0x00 108 | #define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 109 | #define USB_ENDPOINT_TYPE_BULK 0x02 110 | #define USB_ENDPOINT_TYPE_INTERRUPT 0x03 111 | 112 | #define TOBYTES(x) ((x) & 0xFF),(((x) >> 8) & 0xFF) 113 | 114 | #define CDC_V1_10 0x0110 115 | #define CDC_COMMUNICATION_INTERFACE_CLASS 0x02 116 | 117 | #define CDC_CALL_MANAGEMENT 0x01 118 | #define CDC_ABSTRACT_CONTROL_MODEL 0x02 119 | #define CDC_HEADER 0x00 120 | #define CDC_ABSTRACT_CONTROL_MANAGEMENT 0x02 121 | #define CDC_UNION 0x06 122 | #define CDC_CS_INTERFACE 0x24 123 | #define CDC_CS_ENDPOINT 0x25 124 | #define CDC_DATA_INTERFACE_CLASS 0x0A 125 | 126 | #define MSC_SUBCLASS_SCSI 0x06 127 | #define MSC_PROTOCOL_BULK_ONLY 0x50 128 | 129 | // Device 130 | typedef struct { 131 | u8 len; // 18 132 | u8 dtype; // 1 USB_DEVICE_DESCRIPTOR_TYPE 133 | u16 usbVersion; // 0x200 134 | u8 deviceClass; 135 | u8 deviceSubClass; 136 | u8 deviceProtocol; 137 | u8 packetSize0; // Packet 0 138 | u16 idVendor; 139 | u16 idProduct; 140 | u16 deviceVersion; // 0x100 141 | u8 iManufacturer; 142 | u8 iProduct; 143 | u8 iSerialNumber; 144 | u8 bNumConfigurations; 145 | } DeviceDescriptor; 146 | 147 | // Config 148 | typedef struct { 149 | u8 len; // 9 150 | u8 dtype; // 2 151 | u16 clen; // total length 152 | u8 numInterfaces; 153 | u8 config; 154 | u8 iconfig; 155 | u8 attributes; 156 | u8 maxPower; 157 | } ConfigDescriptor; 158 | 159 | // String 160 | 161 | // Interface 162 | typedef struct 163 | { 164 | u8 len; // 9 165 | u8 dtype; // 4 166 | u8 number; 167 | u8 alternate; 168 | u8 numEndpoints; 169 | u8 interfaceClass; 170 | u8 interfaceSubClass; 171 | u8 protocol; 172 | u8 iInterface; 173 | } InterfaceDescriptor; 174 | 175 | // Endpoint 176 | typedef struct 177 | { 178 | u8 len; // 7 179 | u8 dtype; // 5 180 | u8 addr; 181 | u8 attr; 182 | u16 packetSize; 183 | u8 interval; 184 | } EndpointDescriptor; 185 | 186 | // Interface Association Descriptor 187 | // Used to bind 2 interfaces together in CDC compostite device 188 | typedef struct 189 | { 190 | u8 len; // 8 191 | u8 dtype; // 11 192 | u8 firstInterface; 193 | u8 interfaceCount; 194 | u8 functionClass; 195 | u8 funtionSubClass; 196 | u8 functionProtocol; 197 | u8 iInterface; 198 | } IADDescriptor; 199 | 200 | // CDC CS interface descriptor 201 | typedef struct 202 | { 203 | u8 len; // 5 204 | u8 dtype; // 0x24 205 | u8 subtype; 206 | u8 d0; 207 | u8 d1; 208 | } CDCCSInterfaceDescriptor; 209 | 210 | typedef struct 211 | { 212 | u8 len; // 4 213 | u8 dtype; // 0x24 214 | u8 subtype; 215 | u8 d0; 216 | } CDCCSInterfaceDescriptor4; 217 | 218 | typedef struct 219 | { 220 | u8 len; 221 | u8 dtype; // 0x24 222 | u8 subtype; // 1 223 | u8 bmCapabilities; 224 | u8 bDataInterface; 225 | } CMFunctionalDescriptor; 226 | 227 | typedef struct 228 | { 229 | u8 len; 230 | u8 dtype; // 0x24 231 | u8 subtype; // 1 232 | u8 bmCapabilities; 233 | } ACMFunctionalDescriptor; 234 | 235 | typedef struct 236 | { 237 | // IAD 238 | IADDescriptor iad; // Only needed on compound device 239 | 240 | // Control 241 | InterfaceDescriptor cif; // 242 | CDCCSInterfaceDescriptor header; 243 | CMFunctionalDescriptor callManagement; // Call Management 244 | ACMFunctionalDescriptor controlManagement; // ACM 245 | CDCCSInterfaceDescriptor functionalDescriptor; // CDC_UNION 246 | EndpointDescriptor cifin; 247 | 248 | // Data 249 | InterfaceDescriptor dif; 250 | EndpointDescriptor in; 251 | EndpointDescriptor out; 252 | } CDCDescriptor; 253 | 254 | typedef struct 255 | { 256 | InterfaceDescriptor msc; 257 | EndpointDescriptor in; 258 | EndpointDescriptor out; 259 | } MSCDescriptor; 260 | 261 | 262 | #define D_DEVICE(_class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs) \ 263 | { 18, 1, 0x200, _class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs } 264 | 265 | #define D_CONFIG(_totalLength,_interfaces) \ 266 | { 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_BUS_POWERED | USB_CONFIG_REMOTE_WAKEUP, USB_CONFIG_POWER_MA(500) } 267 | 268 | #define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \ 269 | { 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 } 270 | 271 | #define D_ENDPOINT(_addr,_attr,_packetSize, _interval) \ 272 | { 7, 5, _addr,_attr,_packetSize, _interval } 273 | 274 | #define D_IAD(_firstInterface, _count, _class, _subClass, _protocol) \ 275 | { 8, 11, _firstInterface, _count, _class, _subClass, _protocol, 0 } 276 | 277 | #define D_CDCCS(_subtype,_d0,_d1) { 5, 0x24, _subtype, _d0, _d1 } 278 | #define D_CDCCS4(_subtype,_d0) { 4, 0x24, _subtype, _d0 } 279 | 280 | 281 | #endif 282 | -------------------------------------------------------------------------------- /src/core/USBDesc.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2011, Peter Barrett 3 | Copyright (c) 2015, Arduino LLC 4 | 5 | Permission to use, copy, modify, and/or distribute this software for 6 | any purpose with or without fee is hereby granted, provided that the 7 | above copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 12 | BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES 13 | OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 14 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 15 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 16 | SOFTWARE. 17 | */ 18 | 19 | #define PLUGGABLE_USB_ENABLED 20 | 21 | #if defined(EPRST6) 22 | #define USB_ENDPOINTS 7 // AtMegaxxU4 23 | #else 24 | #define USB_ENDPOINTS 5 // AtMegaxxU2 25 | #endif 26 | 27 | #define ISERIAL_MAX_LEN 20 28 | 29 | #define CDC_INTERFACE_COUNT 2 30 | #define CDC_ENPOINT_COUNT 3 31 | 32 | #define CDC_ACM_INTERFACE 0 // CDC ACM 33 | #define CDC_DATA_INTERFACE 1 // CDC Data 34 | #define CDC_FIRST_ENDPOINT 1 35 | #define CDC_ENDPOINT_ACM (CDC_FIRST_ENDPOINT) // CDC First 36 | #define CDC_ENDPOINT_OUT (CDC_FIRST_ENDPOINT+1) 37 | #define CDC_ENDPOINT_IN (CDC_FIRST_ENDPOINT+2) 38 | 39 | #define INTERFACE_COUNT (MSC_INTERFACE + MSC_INTERFACE_COUNT) 40 | 41 | #define CDC_RX CDC_ENDPOINT_OUT 42 | #define CDC_TX CDC_ENDPOINT_IN 43 | 44 | #define IMANUFACTURER 1 45 | #define IPRODUCT 2 46 | #define ISERIAL 3 -------------------------------------------------------------------------------- /src/core/Udp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Udp.cpp: Library to send/receive UDP packets. 3 | * 4 | * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these) 5 | * 1) UDP does not guarantee the order in which assembled UDP packets are received. This 6 | * might not happen often in practice, but in larger network topologies, a UDP 7 | * packet can be received out of sequence. 8 | * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being 9 | * aware of it. Again, this may not be a concern in practice on small local networks. 10 | * For more information, see http://www.cafeaulait.org/course/week12/35.html 11 | * 12 | * MIT License: 13 | * Copyright (c) 2008 Bjoern Hartmann 14 | * Permission is hereby granted, free of charge, to any person obtaining a copy 15 | * of this software and associated documentation files (the "Software"), to deal 16 | * in the Software without restriction, including without limitation the rights 17 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | * copies of the Software, and to permit persons to whom the Software is 19 | * furnished to do so, subject to the following conditions: 20 | * 21 | * The above copyright notice and this permission notice shall be included in 22 | * all copies or substantial portions of the Software. 23 | * 24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 30 | * THE SOFTWARE. 31 | * 32 | * bjoern@cs.stanford.edu 12/30/2008 33 | */ 34 | 35 | #ifndef udp_h 36 | #define udp_h 37 | 38 | #include 39 | #include 40 | 41 | class UDP : public Stream { 42 | 43 | public: 44 | virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use 45 | virtual void stop() =0; // Finish with the UDP socket 46 | 47 | // Sending UDP packets 48 | 49 | // Start building up a packet to send to the remote host specific in ip and port 50 | // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port 51 | virtual int beginPacket(IPAddress ip, uint16_t port) =0; 52 | // Start building up a packet to send to the remote host specific in host and port 53 | // Returns 1 if successful, 0 if there was a problem resolving the hostname or port 54 | virtual int beginPacket(const char *host, uint16_t port) =0; 55 | // Finish off this packet and send it 56 | // Returns 1 if the packet was sent successfully, 0 if there was an error 57 | virtual int endPacket() =0; 58 | // Write a single byte into the packet 59 | virtual size_t write(uint8_t) =0; 60 | // Write size bytes from buffer into the packet 61 | virtual size_t write(const uint8_t *buffer, size_t size) =0; 62 | 63 | // Start processing the next available incoming packet 64 | // Returns the size of the packet in bytes, or 0 if no packets are available 65 | virtual int parsePacket() =0; 66 | // Number of bytes remaining in the current packet 67 | virtual int available() =0; 68 | // Read a single byte from the current packet 69 | virtual int read() =0; 70 | // Read up to len bytes from the current packet and place them into buffer 71 | // Returns the number of bytes read, or 0 if none are available 72 | virtual int read(unsigned char* buffer, size_t len) =0; 73 | // Read up to len characters from the current packet and place them into buffer 74 | // Returns the number of characters read, or 0 if none are available 75 | virtual int read(char* buffer, size_t len) =0; 76 | // Return the next byte from the current packet without moving on to the next byte 77 | virtual int peek() =0; 78 | virtual void flush() =0; // Finish reading the current packet 79 | 80 | // Return the IP address of the host who sent the current incoming packet 81 | virtual IPAddress remoteIP() =0; 82 | // Return the port of the host who sent the current incoming packet 83 | virtual uint16_t remotePort() =0; 84 | protected: 85 | uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); }; 86 | }; 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /src/core/WCharacter.h: -------------------------------------------------------------------------------- 1 | /* 2 | WCharacter.h - Character utility functions for Wiring & Arduino 3 | Copyright (c) 2010 Hernando Barragan. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef Character_h 21 | #define Character_h 22 | 23 | #include 24 | 25 | // WCharacter.h prototypes 26 | inline boolean isAlphaNumeric(int c) __attribute__((always_inline)); 27 | inline boolean isAlpha(int c) __attribute__((always_inline)); 28 | inline boolean isAscii(int c) __attribute__((always_inline)); 29 | inline boolean isWhitespace(int c) __attribute__((always_inline)); 30 | inline boolean isControl(int c) __attribute__((always_inline)); 31 | inline boolean isDigit(int c) __attribute__((always_inline)); 32 | inline boolean isGraph(int c) __attribute__((always_inline)); 33 | inline boolean isLowerCase(int c) __attribute__((always_inline)); 34 | inline boolean isPrintable(int c) __attribute__((always_inline)); 35 | inline boolean isPunct(int c) __attribute__((always_inline)); 36 | inline boolean isSpace(int c) __attribute__((always_inline)); 37 | inline boolean isUpperCase(int c) __attribute__((always_inline)); 38 | inline boolean isHexadecimalDigit(int c) __attribute__((always_inline)); 39 | inline int toAscii(int c) __attribute__((always_inline)); 40 | inline int toLowerCase(int c) __attribute__((always_inline)); 41 | inline int toUpperCase(int c)__attribute__((always_inline)); 42 | 43 | 44 | // Checks for an alphanumeric character. 45 | // It is equivalent to (isalpha(c) || isdigit(c)). 46 | inline boolean isAlphaNumeric(int c) 47 | { 48 | return ( isalnum(c) == 0 ? false : true); 49 | } 50 | 51 | 52 | // Checks for an alphabetic character. 53 | // It is equivalent to (isupper(c) || islower(c)). 54 | inline boolean isAlpha(int c) 55 | { 56 | return ( isalpha(c) == 0 ? false : true); 57 | } 58 | 59 | 60 | // Checks whether c is a 7-bit unsigned char value 61 | // that fits into the ASCII character set. 62 | inline boolean isAscii(int c) 63 | { 64 | return ( isascii (c) == 0 ? false : true); 65 | } 66 | 67 | 68 | // Checks for a blank character, that is, a space or a tab. 69 | inline boolean isWhitespace(int c) 70 | { 71 | return ( isblank (c) == 0 ? false : true); 72 | } 73 | 74 | 75 | // Checks for a control character. 76 | inline boolean isControl(int c) 77 | { 78 | return ( iscntrl (c) == 0 ? false : true); 79 | } 80 | 81 | 82 | // Checks for a digit (0 through 9). 83 | inline boolean isDigit(int c) 84 | { 85 | return ( isdigit (c) == 0 ? false : true); 86 | } 87 | 88 | 89 | // Checks for any printable character except space. 90 | inline boolean isGraph(int c) 91 | { 92 | return ( isgraph (c) == 0 ? false : true); 93 | } 94 | 95 | 96 | // Checks for a lower-case character. 97 | inline boolean isLowerCase(int c) 98 | { 99 | return (islower (c) == 0 ? false : true); 100 | } 101 | 102 | 103 | // Checks for any printable character including space. 104 | inline boolean isPrintable(int c) 105 | { 106 | return ( isprint (c) == 0 ? false : true); 107 | } 108 | 109 | 110 | // Checks for any printable character which is not a space 111 | // or an alphanumeric character. 112 | inline boolean isPunct(int c) 113 | { 114 | return ( ispunct (c) == 0 ? false : true); 115 | } 116 | 117 | 118 | // Checks for white-space characters. For the avr-libc library, 119 | // these are: space, formfeed ('\f'), newline ('\n'), carriage 120 | // return ('\r'), horizontal tab ('\t'), and vertical tab ('\v'). 121 | inline boolean isSpace(int c) 122 | { 123 | return ( isspace (c) == 0 ? false : true); 124 | } 125 | 126 | 127 | // Checks for an uppercase letter. 128 | inline boolean isUpperCase(int c) 129 | { 130 | return ( isupper (c) == 0 ? false : true); 131 | } 132 | 133 | 134 | // Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7 135 | // 8 9 a b c d e f A B C D E F. 136 | inline boolean isHexadecimalDigit(int c) 137 | { 138 | return ( isxdigit (c) == 0 ? false : true); 139 | } 140 | 141 | 142 | // Converts c to a 7-bit unsigned char value that fits into the 143 | // ASCII character set, by clearing the high-order bits. 144 | inline int toAscii(int c) 145 | { 146 | return toascii (c); 147 | } 148 | 149 | 150 | // Warning: 151 | // Many people will be unhappy if you use this function. 152 | // This function will convert accented letters into random 153 | // characters. 154 | 155 | // Converts the letter c to lower case, if possible. 156 | inline int toLowerCase(int c) 157 | { 158 | return tolower (c); 159 | } 160 | 161 | 162 | // Converts the letter c to upper case, if possible. 163 | inline int toUpperCase(int c) 164 | { 165 | return toupper (c); 166 | } 167 | 168 | #endif -------------------------------------------------------------------------------- /src/core/WMath.cpp: -------------------------------------------------------------------------------- 1 | /* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2 | 3 | /* 4 | Part of the Wiring project - http://wiring.org.co 5 | Copyright (c) 2004-06 Hernando Barragan 6 | Modified 13 August 2006, David A. Mellis for Arduino - http://www.arduino.cc/ 7 | 8 | This library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU Lesser General Public 10 | License as published by the Free Software Foundation; either 11 | version 2.1 of the License, or (at your option) any later version. 12 | 13 | This library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General 19 | Public License along with this library; if not, write to the 20 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 21 | Boston, MA 02111-1307 USA 22 | */ 23 | 24 | extern "C" { 25 | #include "stdlib.h" 26 | } 27 | 28 | void randomSeed(unsigned long seed) 29 | { 30 | if (seed != 0) { 31 | srandom(seed); 32 | } 33 | } 34 | 35 | long random(long howbig) 36 | { 37 | if (howbig == 0) { 38 | return 0; 39 | } 40 | return random() % howbig; 41 | } 42 | 43 | long random(long howsmall, long howbig) 44 | { 45 | if (howsmall >= howbig) { 46 | return howsmall; 47 | } 48 | long diff = howbig - howsmall; 49 | return random(diff) + howsmall; 50 | } 51 | 52 | long map(long x, long in_min, long in_max, long out_min, long out_max) 53 | { 54 | return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; 55 | } 56 | 57 | unsigned int makeWord(unsigned int w) { return w; } 58 | unsigned int makeWord(unsigned char h, unsigned char l) { return (h << 8) | l; } 59 | -------------------------------------------------------------------------------- /src/core/abi.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #include 20 | 21 | extern "C" void __cxa_pure_virtual(void) __attribute__ ((__noreturn__)); 22 | extern "C" void __cxa_deleted_virtual(void) __attribute__ ((__noreturn__)); 23 | 24 | void __cxa_pure_virtual(void) { 25 | // We might want to write some diagnostics to uart in this case 26 | //std::terminate(); 27 | abort(); 28 | } 29 | 30 | void __cxa_deleted_virtual(void) { 31 | // We might want to write some diagnostics to uart in this case 32 | //std::terminate(); 33 | abort(); 34 | } 35 | 36 | -------------------------------------------------------------------------------- /src/core/avr5.xn: -------------------------------------------------------------------------------- 1 | /* Script for -n: mix text and data on same page */ 2 | OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr") 3 | OUTPUT_ARCH(avr:5) 4 | MEMORY 5 | { 6 | text (rx) : ORIGIN = 0, LENGTH = 28K /* modified */ 7 | data (rw!x) : ORIGIN = 0x800060, LENGTH = 0xA00 /* modified */ 8 | eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 0x400 /* modified */ 9 | fuse (rw!x) : ORIGIN = 0x820000, LENGTH = 1K 10 | lock (rw!x) : ORIGIN = 0x830000, LENGTH = 1K 11 | signature (rw!x) : ORIGIN = 0x840000, LENGTH = 1K 12 | } 13 | SECTIONS 14 | { 15 | /* Read-only sections, merged into text segment: */ 16 | .hash : { *(.hash) } 17 | .dynsym : { *(.dynsym) } 18 | .dynstr : { *(.dynstr) } 19 | .gnu.version : { *(.gnu.version) } 20 | .gnu.version_d : { *(.gnu.version_d) } 21 | .gnu.version_r : { *(.gnu.version_r) } 22 | .rel.init : { *(.rel.init) } 23 | .rela.init : { *(.rela.init) } 24 | .rel.text : 25 | { 26 | *(.rel.text) 27 | *(.rel.text.*) 28 | *(.rel.gnu.linkonce.t*) 29 | } 30 | .rela.text : 31 | { 32 | *(.rela.text) 33 | *(.rela.text.*) 34 | *(.rela.gnu.linkonce.t*) 35 | } 36 | .rel.fini : { *(.rel.fini) } 37 | .rela.fini : { *(.rela.fini) } 38 | .rel.rodata : 39 | { 40 | *(.rel.rodata) 41 | *(.rel.rodata.*) 42 | *(.rel.gnu.linkonce.r*) 43 | } 44 | .rela.rodata : 45 | { 46 | *(.rela.rodata) 47 | *(.rela.rodata.*) 48 | *(.rela.gnu.linkonce.r*) 49 | } 50 | .rel.data : 51 | { 52 | *(.rel.data) 53 | *(.rel.data.*) 54 | *(.rel.gnu.linkonce.d*) 55 | } 56 | .rela.data : 57 | { 58 | *(.rela.data) 59 | *(.rela.data.*) 60 | *(.rela.gnu.linkonce.d*) 61 | } 62 | .rel.ctors : { *(.rel.ctors) } 63 | .rela.ctors : { *(.rela.ctors) } 64 | .rel.dtors : { *(.rel.dtors) } 65 | .rela.dtors : { *(.rela.dtors) } 66 | .rel.got : { *(.rel.got) } 67 | .rela.got : { *(.rela.got) } 68 | .rel.bss : { *(.rel.bss) } 69 | .rela.bss : { *(.rela.bss) } 70 | .rel.plt : { *(.rel.plt) } 71 | .rela.plt : { *(.rela.plt) } 72 | /* Internal text space or external memory. */ 73 | .text : 74 | { 75 | *(.vectors) 76 | KEEP(*(.vectors)) 77 | /* For data that needs to reside in the lower 64k of progmem. */ 78 | *(.progmem.gcc*) 79 | /* PR 13812: Placing the trampolines here gives a better chance 80 | that they will be in range of the code that uses them. */ 81 | . = ALIGN(2); 82 | __trampolines_start = . ; 83 | /* The jump trampolines for the 16-bit limited relocs will reside here. */ 84 | *(.trampolines) 85 | *(.trampolines*) 86 | __trampolines_end = . ; 87 | *(.progmem*) 88 | . = ALIGN(2); 89 | /* For future tablejump instruction arrays for 3 byte pc devices. 90 | We don't relax jump/call instructions within these sections. */ 91 | *(.jumptables) 92 | *(.jumptables*) 93 | /* For code that needs to reside in the lower 128k progmem. */ 94 | *(.lowtext) 95 | *(.lowtext*) 96 | __ctors_start = . ; 97 | *(.ctors) 98 | __ctors_end = . ; 99 | __dtors_start = . ; 100 | *(.dtors) 101 | __dtors_end = . ; 102 | KEEP(SORT(*)(.ctors)) 103 | KEEP(SORT(*)(.dtors)) 104 | /* From this point on, we don't bother about wether the insns are 105 | below or above the 16 bits boundary. */ 106 | *(.init0) /* Start here after reset. */ 107 | KEEP (*(.init0)) 108 | *(.init1) 109 | KEEP (*(.init1)) 110 | *(.init2) /* Clear __zero_reg__, set up stack pointer. */ 111 | KEEP (*(.init2)) 112 | *(.init3) 113 | KEEP (*(.init3)) 114 | *(.init4) /* Initialize data and BSS. */ 115 | KEEP (*(.init4)) 116 | *(.init5) 117 | KEEP (*(.init5)) 118 | *(.init6) /* C++ constructors. */ 119 | KEEP (*(.init6)) 120 | *(.init7) 121 | KEEP (*(.init7)) 122 | *(.init8) 123 | KEEP (*(.init8)) 124 | *(.init9) /* Call main(). */ 125 | KEEP (*(.init9)) 126 | *(.text) 127 | . = ALIGN(2); 128 | *(.text.*) 129 | . = ALIGN(2); 130 | *(.fini9) /* _exit() starts here. */ 131 | KEEP (*(.fini9)) 132 | *(.fini8) 133 | KEEP (*(.fini8)) 134 | *(.fini7) 135 | KEEP (*(.fini7)) 136 | *(.fini6) /* C++ destructors. */ 137 | KEEP (*(.fini6)) 138 | *(.fini5) 139 | KEEP (*(.fini5)) 140 | *(.fini4) 141 | KEEP (*(.fini4)) 142 | *(.fini3) 143 | KEEP (*(.fini3)) 144 | *(.fini2) 145 | KEEP (*(.fini2)) 146 | *(.fini1) 147 | KEEP (*(.fini1)) 148 | *(.fini0) /* Infinite loop after program termination. */ 149 | KEEP (*(.fini0)) 150 | _etext = . ; 151 | } > text 152 | .data : 153 | { 154 | PROVIDE (__data_start = .) ; 155 | /* --gc-sections will delete empty .data. This leads to wrong start 156 | addresses for subsequent sections because -Tdata= from the command 157 | line will have no effect, see PR13697. Thus, keep .data */ 158 | KEEP (*(.data)) 159 | *(.data*) 160 | *(.rodata) /* We need to include .rodata here if gcc is used */ 161 | *(.rodata*) /* with -fdata-sections. */ 162 | *(.gnu.linkonce.d*) 163 | . = ALIGN(2); 164 | _edata = . ; 165 | PROVIDE (__data_end = .) ; 166 | } > data AT> text 167 | .bss : AT (ADDR (.bss)) 168 | { 169 | PROVIDE (__bss_start = .) ; 170 | *(.bss) 171 | *(.bss*) 172 | *(COMMON) 173 | PROVIDE (__bss_end = .) ; 174 | } > data 175 | __data_load_start = LOADADDR(.data); 176 | __data_load_end = __data_load_start + SIZEOF(.data); 177 | /* Global data not cleared after reset. */ 178 | .noinit : 179 | { 180 | PROVIDE (__noinit_start = .) ; 181 | *(.noinit*) 182 | PROVIDE (__noinit_end = .) ; 183 | _end = . ; 184 | PROVIDE (__heap_start = .) ; 185 | } > data 186 | .eeprom : 187 | { 188 | /* See .data above... */ 189 | KEEP(*(.eeprom*)) 190 | __eeprom_end = . ; 191 | } > eeprom 192 | .fuse : 193 | { 194 | KEEP(*(.fuse)) 195 | KEEP(*(.lfuse)) 196 | KEEP(*(.hfuse)) 197 | KEEP(*(.efuse)) 198 | } > fuse 199 | .lock : 200 | { 201 | KEEP(*(.lock*)) 202 | } > lock 203 | .signature : 204 | { 205 | KEEP(*(.signature*)) 206 | } > signature 207 | /* Stabs debugging sections. */ 208 | .stab 0 : { *(.stab) } 209 | .stabstr 0 : { *(.stabstr) } 210 | .stab.excl 0 : { *(.stab.excl) } 211 | .stab.exclstr 0 : { *(.stab.exclstr) } 212 | .stab.index 0 : { *(.stab.index) } 213 | .stab.indexstr 0 : { *(.stab.indexstr) } 214 | .comment 0 : { *(.comment) } 215 | .note.gnu.build-id : { *(.note.gnu.build-id) } 216 | /* DWARF debug sections. 217 | Symbols in the DWARF debugging sections are relative to the beginning 218 | of the section so we begin them at 0. */ 219 | /* DWARF 1 */ 220 | .debug 0 : { *(.debug) } 221 | .line 0 : { *(.line) } 222 | /* GNU DWARF 1 extensions */ 223 | .debug_srcinfo 0 : { *(.debug_srcinfo) } 224 | .debug_sfnames 0 : { *(.debug_sfnames) } 225 | /* DWARF 1.1 and DWARF 2 */ 226 | .debug_aranges 0 : { *(.debug_aranges) } 227 | .debug_pubnames 0 : { *(.debug_pubnames) } 228 | /* DWARF 2 */ 229 | .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } 230 | .debug_abbrev 0 : { *(.debug_abbrev) } 231 | .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) } 232 | .debug_frame 0 : { *(.debug_frame) } 233 | .debug_str 0 : { *(.debug_str) } 234 | .debug_loc 0 : { *(.debug_loc) } 235 | .debug_macinfo 0 : { *(.debug_macinfo) } 236 | /* SGI/MIPS DWARF 2 extensions */ 237 | .debug_weaknames 0 : { *(.debug_weaknames) } 238 | .debug_funcnames 0 : { *(.debug_funcnames) } 239 | .debug_typenames 0 : { *(.debug_typenames) } 240 | .debug_varnames 0 : { *(.debug_varnames) } 241 | /* DWARF 3 */ 242 | .debug_pubtypes 0 : { *(.debug_pubtypes) } 243 | .debug_ranges 0 : { *(.debug_ranges) } 244 | /* DWARF Extension. */ 245 | .debug_macro 0 : { *(.debug_macro) } 246 | } 247 | -------------------------------------------------------------------------------- /src/core/hooks.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | /** 20 | * Empty yield() hook. 21 | * 22 | * This function is intended to be used by library writers to build 23 | * libraries or sketches that supports cooperative threads. 24 | * 25 | * Its defined as a weak symbol and it can be redefined to implement a 26 | * real cooperative scheduler. 27 | */ 28 | static void __empty() { 29 | // Empty 30 | } 31 | void yield(void) __attribute__ ((weak, alias("__empty"))); 32 | -------------------------------------------------------------------------------- /src/core/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | main.cpp - Main loop for Arduino sketches 3 | Copyright (c) 2005-2013 Arduino Team. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include 21 | 22 | // Declared weak in Arduino.h to allow user redefinitions. 23 | int atexit(void (* /*func*/ )()) { return 0; } 24 | 25 | // Weak empty variant initialization function. 26 | // May be redefined by variant files. 27 | void initVariant() __attribute__((weak)); 28 | void initVariant() { } 29 | 30 | void setupUSB() __attribute__((weak)); 31 | void setupUSB() { } 32 | 33 | int main(void) 34 | { 35 | init(); 36 | 37 | initVariant(); 38 | 39 | #if defined(USBCON) 40 | USBDevice.attach(); 41 | #endif 42 | 43 | setup(); 44 | 45 | for (;;) { 46 | loop(); 47 | if (serialEventRun) serialEventRun(); 48 | } 49 | 50 | return 0; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /src/core/new.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #include 20 | 21 | void *operator new(size_t size) { 22 | return malloc(size); 23 | } 24 | 25 | void *operator new[](size_t size) { 26 | return malloc(size); 27 | } 28 | 29 | void operator delete(void * ptr) { 30 | free(ptr); 31 | } 32 | 33 | void operator delete[](void * ptr) { 34 | free(ptr); 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/core/new.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef NEW_H 20 | #define NEW_H 21 | 22 | #include 23 | 24 | void * operator new(size_t size); 25 | void * operator new[](size_t size); 26 | void operator delete(void * ptr); 27 | void operator delete[](void * ptr); 28 | 29 | #endif 30 | 31 | -------------------------------------------------------------------------------- /src/core/wiring_analog.c: -------------------------------------------------------------------------------- 1 | /* 2 | wiring_analog.c - analog input and output 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2005-2006 David A. Mellis 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General 18 | Public License along with this library; if not, write to the 19 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 20 | Boston, MA 02111-1307 USA 21 | 22 | Modified 28 September 2010 by Mark Sproul 23 | */ 24 | 25 | #include "wiring_private.h" 26 | #include "pins_arduino.h" 27 | 28 | uint8_t analog_reference = DEFAULT; 29 | 30 | void analogReference(uint8_t mode) 31 | { 32 | // can't actually set the register here because the default setting 33 | // will connect AVCC and the AREF pin, which would cause a short if 34 | // there's something connected to AREF. 35 | analog_reference = mode; 36 | } 37 | 38 | int analogRead(uint8_t pin) 39 | { 40 | uint8_t low, high; 41 | 42 | #if defined(analogPinToChannel) 43 | #if defined(__AVR_ATmega32U4__) 44 | if (pin >= 18) pin -= 18; // allow for channel or pin numbers 45 | #endif 46 | pin = analogPinToChannel(pin); 47 | #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 48 | if (pin >= 54) pin -= 54; // allow for channel or pin numbers 49 | #elif defined(__AVR_ATmega32U4__) 50 | if (pin >= 18) pin -= 18; // allow for channel or pin numbers 51 | #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) 52 | if (pin >= 24) pin -= 24; // allow for channel or pin numbers 53 | #else 54 | if (pin >= 14) pin -= 14; // allow for channel or pin numbers 55 | #endif 56 | 57 | #if defined(ADCSRB) && defined(MUX5) 58 | // the MUX5 bit of ADCSRB selects whether we're reading from channels 59 | // 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high). 60 | ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5); 61 | #endif 62 | 63 | // set the analog reference (high two bits of ADMUX) and select the 64 | // channel (low 4 bits). this also sets ADLAR (left-adjust result) 65 | // to 0 (the default). 66 | #if defined(ADMUX) 67 | ADMUX = (analog_reference << 6) | (pin & 0x07); 68 | #endif 69 | 70 | // without a delay, we seem to read from the wrong channel 71 | //delay(1); 72 | 73 | #if defined(ADCSRA) && defined(ADCL) 74 | // start the conversion 75 | sbi(ADCSRA, ADSC); 76 | 77 | // ADSC is cleared when the conversion finishes 78 | while (bit_is_set(ADCSRA, ADSC)); 79 | 80 | // we have to read ADCL first; doing so locks both ADCL 81 | // and ADCH until ADCH is read. reading ADCL second would 82 | // cause the results of each conversion to be discarded, 83 | // as ADCL and ADCH would be locked when it completed. 84 | low = ADCL; 85 | high = ADCH; 86 | #else 87 | // we dont have an ADC, return 0 88 | low = 0; 89 | high = 0; 90 | #endif 91 | 92 | // combine the two bytes 93 | return (high << 8) | low; 94 | } 95 | 96 | // Right now, PWM output only works on the pins with 97 | // hardware support. These are defined in the appropriate 98 | // pins_*.c file. For the rest of the pins, we default 99 | // to digital output. 100 | void analogWrite(uint8_t pin, int val) 101 | { 102 | // We need to make sure the PWM output is enabled for those pins 103 | // that support it, as we turn it off when digitally reading or 104 | // writing with them. Also, make sure the pin is in output mode 105 | // for consistenty with Wiring, which doesn't require a pinMode 106 | // call for the analog output pins. 107 | pinMode(pin, OUTPUT); 108 | if (val == 0) 109 | { 110 | digitalWrite(pin, LOW); 111 | } 112 | else if (val == 255) 113 | { 114 | digitalWrite(pin, HIGH); 115 | } 116 | else 117 | { 118 | switch(digitalPinToTimer(pin)) 119 | { 120 | // XXX fix needed for atmega8 121 | #if defined(TCCR0) && defined(COM00) && !defined(__AVR_ATmega8__) 122 | case TIMER0A: 123 | // connect pwm to pin on timer 0 124 | sbi(TCCR0, COM00); 125 | OCR0 = val; // set pwm duty 126 | break; 127 | #endif 128 | 129 | #if defined(TCCR0A) && defined(COM0A1) 130 | case TIMER0A: 131 | // connect pwm to pin on timer 0, channel A 132 | sbi(TCCR0A, COM0A1); 133 | OCR0A = val; // set pwm duty 134 | break; 135 | #endif 136 | 137 | #if defined(TCCR0A) && defined(COM0B1) 138 | case TIMER0B: 139 | // connect pwm to pin on timer 0, channel B 140 | sbi(TCCR0A, COM0B1); 141 | OCR0B = val; // set pwm duty 142 | break; 143 | #endif 144 | 145 | #if defined(TCCR1A) && defined(COM1A1) 146 | case TIMER1A: 147 | // connect pwm to pin on timer 1, channel A 148 | sbi(TCCR1A, COM1A1); 149 | OCR1A = val; // set pwm duty 150 | break; 151 | #endif 152 | 153 | #if defined(TCCR1A) && defined(COM1B1) 154 | case TIMER1B: 155 | // connect pwm to pin on timer 1, channel B 156 | sbi(TCCR1A, COM1B1); 157 | OCR1B = val; // set pwm duty 158 | break; 159 | #endif 160 | 161 | #if defined(TCCR1A) && defined(COM1C1) 162 | case TIMER1C: 163 | // connect pwm to pin on timer 1, channel B 164 | sbi(TCCR1A, COM1C1); 165 | OCR1C = val; // set pwm duty 166 | break; 167 | #endif 168 | 169 | #if defined(TCCR2) && defined(COM21) 170 | case TIMER2: 171 | // connect pwm to pin on timer 2 172 | sbi(TCCR2, COM21); 173 | OCR2 = val; // set pwm duty 174 | break; 175 | #endif 176 | 177 | #if defined(TCCR2A) && defined(COM2A1) 178 | case TIMER2A: 179 | // connect pwm to pin on timer 2, channel A 180 | sbi(TCCR2A, COM2A1); 181 | OCR2A = val; // set pwm duty 182 | break; 183 | #endif 184 | 185 | #if defined(TCCR2A) && defined(COM2B1) 186 | case TIMER2B: 187 | // connect pwm to pin on timer 2, channel B 188 | sbi(TCCR2A, COM2B1); 189 | OCR2B = val; // set pwm duty 190 | break; 191 | #endif 192 | 193 | #if defined(TCCR3A) && defined(COM3A1) 194 | case TIMER3A: 195 | // connect pwm to pin on timer 3, channel A 196 | sbi(TCCR3A, COM3A1); 197 | OCR3A = val; // set pwm duty 198 | break; 199 | #endif 200 | 201 | #if defined(TCCR3A) && defined(COM3B1) 202 | case TIMER3B: 203 | // connect pwm to pin on timer 3, channel B 204 | sbi(TCCR3A, COM3B1); 205 | OCR3B = val; // set pwm duty 206 | break; 207 | #endif 208 | 209 | #if defined(TCCR3A) && defined(COM3C1) 210 | case TIMER3C: 211 | // connect pwm to pin on timer 3, channel C 212 | sbi(TCCR3A, COM3C1); 213 | OCR3C = val; // set pwm duty 214 | break; 215 | #endif 216 | 217 | #if defined(TCCR4A) 218 | case TIMER4A: 219 | //connect pwm to pin on timer 4, channel A 220 | sbi(TCCR4A, COM4A1); 221 | #if defined(COM4A0) // only used on 32U4 222 | cbi(TCCR4A, COM4A0); 223 | #endif 224 | OCR4A = val; // set pwm duty 225 | break; 226 | #endif 227 | 228 | #if defined(TCCR4A) && defined(COM4B1) 229 | case TIMER4B: 230 | // connect pwm to pin on timer 4, channel B 231 | sbi(TCCR4A, COM4B1); 232 | OCR4B = val; // set pwm duty 233 | break; 234 | #endif 235 | 236 | #if defined(TCCR4A) && defined(COM4C1) 237 | case TIMER4C: 238 | // connect pwm to pin on timer 4, channel C 239 | sbi(TCCR4A, COM4C1); 240 | OCR4C = val; // set pwm duty 241 | break; 242 | #endif 243 | 244 | #if defined(TCCR4C) && defined(COM4D1) 245 | case TIMER4D: 246 | // connect pwm to pin on timer 4, channel D 247 | sbi(TCCR4C, COM4D1); 248 | #if defined(COM4D0) // only used on 32U4 249 | cbi(TCCR4C, COM4D0); 250 | #endif 251 | OCR4D = val; // set pwm duty 252 | break; 253 | #endif 254 | 255 | 256 | #if defined(TCCR5A) && defined(COM5A1) 257 | case TIMER5A: 258 | // connect pwm to pin on timer 5, channel A 259 | sbi(TCCR5A, COM5A1); 260 | OCR5A = val; // set pwm duty 261 | break; 262 | #endif 263 | 264 | #if defined(TCCR5A) && defined(COM5B1) 265 | case TIMER5B: 266 | // connect pwm to pin on timer 5, channel B 267 | sbi(TCCR5A, COM5B1); 268 | OCR5B = val; // set pwm duty 269 | break; 270 | #endif 271 | 272 | #if defined(TCCR5A) && defined(COM5C1) 273 | case TIMER5C: 274 | // connect pwm to pin on timer 5, channel C 275 | sbi(TCCR5A, COM5C1); 276 | OCR5C = val; // set pwm duty 277 | break; 278 | #endif 279 | 280 | case NOT_ON_TIMER: 281 | default: 282 | if (val < 128) { 283 | digitalWrite(pin, LOW); 284 | } else { 285 | digitalWrite(pin, HIGH); 286 | } 287 | } 288 | } 289 | } 290 | 291 | -------------------------------------------------------------------------------- /src/core/wiring_digital.c: -------------------------------------------------------------------------------- 1 | /* 2 | wiring_digital.c - digital input and output functions 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2005-2006 David A. Mellis 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General 18 | Public License along with this library; if not, write to the 19 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 20 | Boston, MA 02111-1307 USA 21 | 22 | Modified 28 September 2010 by Mark Sproul 23 | */ 24 | 25 | #define ARDUINO_MAIN 26 | #include "wiring_private.h" 27 | #include "pins_arduino.h" 28 | 29 | void pinMode(uint8_t pin, uint8_t mode) 30 | { 31 | uint8_t bit = digitalPinToBitMask(pin); 32 | uint8_t port = digitalPinToPort(pin); 33 | volatile uint8_t *reg, *out; 34 | 35 | if (port == NOT_A_PIN) return; 36 | 37 | // JWS: can I let the optimizer do this? 38 | reg = portModeRegister(port); 39 | out = portOutputRegister(port); 40 | 41 | if (mode == INPUT) { 42 | uint8_t oldSREG = SREG; 43 | cli(); 44 | *reg &= ~bit; 45 | *out &= ~bit; 46 | SREG = oldSREG; 47 | } else if (mode == INPUT_PULLUP) { 48 | uint8_t oldSREG = SREG; 49 | cli(); 50 | *reg &= ~bit; 51 | *out |= bit; 52 | SREG = oldSREG; 53 | } else { 54 | uint8_t oldSREG = SREG; 55 | cli(); 56 | *reg |= bit; 57 | SREG = oldSREG; 58 | } 59 | } 60 | 61 | // Forcing this inline keeps the callers from having to push their own stuff 62 | // on the stack. It is a good performance win and only takes 1 more byte per 63 | // user than calling. (It will take more bytes on the 168.) 64 | // 65 | // But shouldn't this be moved into pinMode? Seems silly to check and do on 66 | // each digitalread or write. 67 | // 68 | // Mark Sproul: 69 | // - Removed inline. Save 170 bytes on atmega1280 70 | // - changed to a switch statment; added 32 bytes but much easier to read and maintain. 71 | // - Added more #ifdefs, now compiles for atmega645 72 | // 73 | //static inline void turnOffPWM(uint8_t timer) __attribute__ ((always_inline)); 74 | //static inline void turnOffPWM(uint8_t timer) 75 | static void turnOffPWM(uint8_t timer) 76 | { 77 | switch (timer) 78 | { 79 | #if defined(TCCR1A) && defined(COM1A1) 80 | case TIMER1A: cbi(TCCR1A, COM1A1); break; 81 | #endif 82 | #if defined(TCCR1A) && defined(COM1B1) 83 | case TIMER1B: cbi(TCCR1A, COM1B1); break; 84 | #endif 85 | #if defined(TCCR1A) && defined(COM1C1) 86 | case TIMER1C: cbi(TCCR1A, COM1C1); break; 87 | #endif 88 | 89 | #if defined(TCCR2) && defined(COM21) 90 | case TIMER2: cbi(TCCR2, COM21); break; 91 | #endif 92 | 93 | #if defined(TCCR0A) && defined(COM0A1) 94 | case TIMER0A: cbi(TCCR0A, COM0A1); break; 95 | #endif 96 | 97 | #if defined(TCCR0A) && defined(COM0B1) 98 | case TIMER0B: cbi(TCCR0A, COM0B1); break; 99 | #endif 100 | #if defined(TCCR2A) && defined(COM2A1) 101 | case TIMER2A: cbi(TCCR2A, COM2A1); break; 102 | #endif 103 | #if defined(TCCR2A) && defined(COM2B1) 104 | case TIMER2B: cbi(TCCR2A, COM2B1); break; 105 | #endif 106 | 107 | #if defined(TCCR3A) && defined(COM3A1) 108 | case TIMER3A: cbi(TCCR3A, COM3A1); break; 109 | #endif 110 | #if defined(TCCR3A) && defined(COM3B1) 111 | case TIMER3B: cbi(TCCR3A, COM3B1); break; 112 | #endif 113 | #if defined(TCCR3A) && defined(COM3C1) 114 | case TIMER3C: cbi(TCCR3A, COM3C1); break; 115 | #endif 116 | 117 | #if defined(TCCR4A) && defined(COM4A1) 118 | case TIMER4A: cbi(TCCR4A, COM4A1); break; 119 | #endif 120 | #if defined(TCCR4A) && defined(COM4B1) 121 | case TIMER4B: cbi(TCCR4A, COM4B1); break; 122 | #endif 123 | #if defined(TCCR4A) && defined(COM4C1) 124 | case TIMER4C: cbi(TCCR4A, COM4C1); break; 125 | #endif 126 | #if defined(TCCR4C) && defined(COM4D1) 127 | case TIMER4D: cbi(TCCR4C, COM4D1); break; 128 | #endif 129 | 130 | #if defined(TCCR5A) 131 | case TIMER5A: cbi(TCCR5A, COM5A1); break; 132 | case TIMER5B: cbi(TCCR5A, COM5B1); break; 133 | case TIMER5C: cbi(TCCR5A, COM5C1); break; 134 | #endif 135 | } 136 | } 137 | 138 | void digitalWrite(uint8_t pin, uint8_t val) 139 | { 140 | uint8_t timer = digitalPinToTimer(pin); 141 | uint8_t bit = digitalPinToBitMask(pin); 142 | uint8_t port = digitalPinToPort(pin); 143 | volatile uint8_t *out; 144 | 145 | if (port == NOT_A_PIN) return; 146 | 147 | // If the pin that support PWM output, we need to turn it off 148 | // before doing a digital write. 149 | if (timer != NOT_ON_TIMER) turnOffPWM(timer); 150 | 151 | out = portOutputRegister(port); 152 | 153 | uint8_t oldSREG = SREG; 154 | cli(); 155 | 156 | if (val == LOW) { 157 | *out &= ~bit; 158 | } else { 159 | *out |= bit; 160 | } 161 | 162 | SREG = oldSREG; 163 | } 164 | 165 | int digitalRead(uint8_t pin) 166 | { 167 | uint8_t timer = digitalPinToTimer(pin); 168 | uint8_t bit = digitalPinToBitMask(pin); 169 | uint8_t port = digitalPinToPort(pin); 170 | 171 | if (port == NOT_A_PIN) return LOW; 172 | 173 | // If the pin that support PWM output, we need to turn it off 174 | // before getting a digital reading. 175 | if (timer != NOT_ON_TIMER) turnOffPWM(timer); 176 | 177 | if (*portInputRegister(port) & bit) return HIGH; 178 | return LOW; 179 | } 180 | -------------------------------------------------------------------------------- /src/core/wiring_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | wiring_private.h - Internal header file. 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2005-2006 David A. Mellis 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General 18 | Public License along with this library; if not, write to the 19 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 20 | Boston, MA 02111-1307 USA 21 | */ 22 | 23 | #ifndef WiringPrivate_h 24 | #define WiringPrivate_h 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "Arduino.h" 32 | 33 | #ifdef __cplusplus 34 | extern "C"{ 35 | #endif 36 | 37 | #ifndef cbi 38 | #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) 39 | #endif 40 | #ifndef sbi 41 | #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) 42 | #endif 43 | 44 | uint32_t countPulseASM(volatile uint8_t *port, uint8_t bit, uint8_t stateMask, unsigned long maxloops); 45 | 46 | #define EXTERNAL_INT_0 0 47 | #define EXTERNAL_INT_1 1 48 | #define EXTERNAL_INT_2 2 49 | #define EXTERNAL_INT_3 3 50 | #define EXTERNAL_INT_4 4 51 | #define EXTERNAL_INT_5 5 52 | #define EXTERNAL_INT_6 6 53 | #define EXTERNAL_INT_7 7 54 | 55 | #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega256RFR2__) || \ 56 | defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__) 57 | #define EXTERNAL_NUM_INTERRUPTS 8 58 | #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) 59 | #define EXTERNAL_NUM_INTERRUPTS 3 60 | #elif defined(__AVR_ATmega32U4__) 61 | #define EXTERNAL_NUM_INTERRUPTS 5 62 | #else 63 | #define EXTERNAL_NUM_INTERRUPTS 2 64 | #endif 65 | 66 | typedef void (*voidFuncPtr)(void); 67 | 68 | #ifdef __cplusplus 69 | } // extern "C" 70 | #endif 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /src/core/wiring_pulse.S: -------------------------------------------------------------------------------- 1 | /* 2 | wiring_pulse.s - pulseInASM() function in different flavours 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2014 Martino Facchin 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General 18 | Public License along with this library; if not, write to the 19 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 20 | Boston, MA 02111-1307 USA 21 | */ 22 | 23 | /* 24 | * The following routine was generated by avr-gcc 4.8.3 with the following parameters 25 | * -gstabs -Wa,-ahlmsd=output.lst -dp -fverbose-asm -O2 26 | * on the original C function 27 | * 28 | * unsigned long pulseInSimpl(volatile uint8_t *port, uint8_t bit, uint8_t stateMask, unsigned long maxloops) 29 | * { 30 | * unsigned long width = 0; 31 | * // wait for any previous pulse to end 32 | * while ((*port & bit) == stateMask) 33 | * if (--maxloops == 0) 34 | * return 0; 35 | * 36 | * // wait for the pulse to start 37 | * while ((*port & bit) != stateMask) 38 | * if (--maxloops == 0) 39 | * return 0; 40 | * 41 | * // wait for the pulse to stop 42 | * while ((*port & bit) == stateMask) { 43 | * if (++width == maxloops) 44 | * return 0; 45 | * } 46 | * return width; 47 | * } 48 | * 49 | * some compiler outputs were removed but the rest of the code is untouched 50 | */ 51 | 52 | #include 53 | 54 | .section .text 55 | 56 | .global countPulseASM 57 | 58 | countPulseASM: 59 | 60 | .LM0: 61 | .LFBB1: 62 | push r12 ; ; 130 pushqi1/1 [length = 1] 63 | push r13 ; ; 131 pushqi1/1 [length = 1] 64 | push r14 ; ; 132 pushqi1/1 [length = 1] 65 | push r15 ; ; 133 pushqi1/1 [length = 1] 66 | push r16 ; ; 134 pushqi1/1 [length = 1] 67 | push r17 ; ; 135 pushqi1/1 [length = 1] 68 | /* prologue: function */ 69 | /* frame size = 0 */ 70 | /* stack size = 6 */ 71 | .L__stack_usage = 6 72 | mov r30,r24 ; port, port ; 2 *movhi/1 [length = 2] 73 | mov r31,r25 ; port, port 74 | /* unsigned long width = 0; 75 | *** // wait for any previous pulse to end 76 | *** while ((*port & bit) == stateMask) 77 | */ 78 | .LM1: 79 | rjmp .L2 ; ; 181 jump [length = 1] 80 | .L4: 81 | /* if (--maxloops == 0) */ 82 | .LM2: 83 | subi r16,1 ; maxloops, ; 17 addsi3/2 [length = 4] 84 | sbc r17, r1 ; maxloops 85 | sbc r18, r1 ; maxloops 86 | sbc r19, r1 ; maxloops 87 | breq .L13 ; , ; 19 branch [length = 1] 88 | .L2: 89 | /* if (--maxloops == 0) */ 90 | .LM3: 91 | ld r25,Z ; D.1554, *port_7(D) ; 22 movqi_insn/4 [length = 1] 92 | and r25,r22 ; D.1554, bit ; 24 andqi3/1 [length = 1] 93 | cp r25,r20 ; D.1554, stateMask ; 25 *cmpqi/2 [length = 1] 94 | breq .L4 ; , ; 26 branch [length = 1] 95 | rjmp .L6 ; ; 184 jump [length = 1] 96 | .L7: 97 | /* return 0; 98 | *** 99 | *** // wait for the pulse to start 100 | *** while ((*port & bit) != stateMask) 101 | *** if (--maxloops == 0) 102 | */ 103 | .LM4: 104 | subi r16,1 ; maxloops, ; 31 addsi3/2 [length = 4] 105 | sbc r17, r1 ; maxloops 106 | sbc r18, r1 ; maxloops 107 | sbc r19, r1 ; maxloops 108 | breq .L13 ; , ; 33 branch [length = 1] 109 | .L6: 110 | /* if (--maxloops == 0) */ 111 | .LM5: 112 | ld r25,Z ; D.1554, *port_7(D) ; 41 movqi_insn/4 [length = 1] 113 | and r25,r22 ; D.1554, bit ; 43 andqi3/1 [length = 1] 114 | cpse r25,r20 ; D.1554, stateMask ; 44 enable_interrupt-3 [length = 1] 115 | rjmp .L7 ; 116 | mov r12, r1 ; width ; 7 *movsi/2 [length = 4] 117 | mov r13, r1 ; width 118 | mov r14, r1 ; width 119 | mov r15, r1 ; width 120 | rjmp .L9 ; ; 186 jump [length = 1] 121 | .L10: 122 | /* return 0; 123 | *** 124 | *** // wait for the pulse to stop 125 | *** while ((*port & bit) == stateMask) { 126 | *** if (++width == maxloops) 127 | */ 128 | .LM6: 129 | ldi r24,-1 ; , ; 50 addsi3/3 [length = 5] 130 | sub r12,r24 ; width, 131 | sbc r13,r24 ; width, 132 | sbc r14,r24 ; width, 133 | sbc r15,r24 ; width, 134 | cp r16,r12 ; maxloops, width ; 51 *cmpsi/2 [length = 4] 135 | cpc r17,r13 ; maxloops, width 136 | cpc r18,r14 ; maxloops, width 137 | cpc r19,r15 ; maxloops, width 138 | breq .L13 ; , ; 52 branch [length = 1] 139 | .L9: 140 | /* if (++width == maxloops) */ 141 | .LM7: 142 | ld r24,Z ; D.1554, *port_7(D) ; 60 movqi_insn/4 [length = 1] 143 | and r24,r22 ; D.1554, bit ; 62 andqi3/1 [length = 1] 144 | cp r24,r20 ; D.1554, stateMask ; 63 *cmpqi/2 [length = 1] 145 | breq .L10 ; , ; 64 branch [length = 1] 146 | /* return 0; 147 | *** } 148 | *** return width; 149 | */ 150 | .LM8: 151 | mov r22,r12 ; D.1553, width ; 108 movqi_insn/1 [length = 1] 152 | mov r23,r13 ; D.1553, width ; 109 movqi_insn/1 [length = 1] 153 | mov r24,r14 ; D.1553, width ; 110 movqi_insn/1 [length = 1] 154 | mov r25,r15 ; D.1553, width ; 111 movqi_insn/1 [length = 1] 155 | /* epilogue start */ 156 | .LM9: 157 | pop r17 ; ; 171 popqi [length = 1] 158 | pop r16 ; ; 172 popqi [length = 1] 159 | pop r15 ; ; 173 popqi [length = 1] 160 | pop r14 ; ; 174 popqi [length = 1] 161 | pop r13 ; ; 175 popqi [length = 1] 162 | pop r12 ; ; 176 popqi [length = 1] 163 | ret ; 177 return_from_epilogue [length = 1] 164 | .L13: 165 | .LM10: 166 | ldi r22,0 ; D.1553 ; 120 movqi_insn/1 [length = 1] 167 | ldi r23,0 ; D.1553 ; 121 movqi_insn/1 [length = 1] 168 | ldi r24,0 ; D.1553 ; 122 movqi_insn/1 [length = 1] 169 | ldi r25,0 ; D.1553 ; 123 movqi_insn/1 [length = 1] 170 | /* epilogue start */ 171 | .LM11: 172 | pop r17 ; ; 138 popqi [length = 1] 173 | pop r16 ; ; 139 popqi [length = 1] 174 | pop r15 ; ; 140 popqi [length = 1] 175 | pop r14 ; ; 141 popqi [length = 1] 176 | pop r13 ; ; 142 popqi [length = 1] 177 | pop r12 ; ; 143 popqi [length = 1] 178 | ret ; 144 return_from_epilogue [length = 1] 179 | -------------------------------------------------------------------------------- /src/core/wiring_pulse.c: -------------------------------------------------------------------------------- 1 | /* 2 | wiring_pulse.c - pulseIn() function 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2005-2006 David A. Mellis 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General 18 | Public License along with this library; if not, write to the 19 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 20 | Boston, MA 02111-1307 USA 21 | */ 22 | 23 | #include "wiring_private.h" 24 | #include "pins_arduino.h" 25 | 26 | /* Measures the length (in microseconds) of a pulse on the pin; state is HIGH 27 | * or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds 28 | * to 3 minutes in length, but must be called at least a few dozen microseconds 29 | * before the start of the pulse. 30 | * 31 | * This function performs better with short pulses in noInterrupt() context 32 | */ 33 | unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout) 34 | { 35 | // cache the port and bit of the pin in order to speed up the 36 | // pulse width measuring loop and achieve finer resolution. calling 37 | // digitalRead() instead yields much coarser resolution. 38 | uint8_t bit = digitalPinToBitMask(pin); 39 | uint8_t port = digitalPinToPort(pin); 40 | uint8_t stateMask = (state ? bit : 0); 41 | 42 | // convert the timeout from microseconds to a number of times through 43 | // the initial loop; it takes approximately 16 clock cycles per iteration 44 | unsigned long maxloops = microsecondsToClockCycles(timeout)/16; 45 | 46 | unsigned long width = countPulseASM(portInputRegister(port), bit, stateMask, maxloops); 47 | 48 | // prevent clockCyclesToMicroseconds to return bogus values if countPulseASM timed out 49 | if (width) 50 | return clockCyclesToMicroseconds(width * 16 + 16); 51 | else 52 | return 0; 53 | } 54 | 55 | /* Measures the length (in microseconds) of a pulse on the pin; state is HIGH 56 | * or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds 57 | * to 3 minutes in length, but must be called at least a few dozen microseconds 58 | * before the start of the pulse. 59 | * 60 | * ATTENTION: 61 | * this function relies on micros() so cannot be used in noInterrupt() context 62 | */ 63 | unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout) 64 | { 65 | // cache the port and bit of the pin in order to speed up the 66 | // pulse width measuring loop and achieve finer resolution. calling 67 | // digitalRead() instead yields much coarser resolution. 68 | uint8_t bit = digitalPinToBitMask(pin); 69 | uint8_t port = digitalPinToPort(pin); 70 | uint8_t stateMask = (state ? bit : 0); 71 | 72 | unsigned long startMicros = micros(); 73 | 74 | // wait for any previous pulse to end 75 | while ((*portInputRegister(port) & bit) == stateMask) { 76 | if (micros() - startMicros > timeout) 77 | return 0; 78 | } 79 | 80 | // wait for the pulse to start 81 | while ((*portInputRegister(port) & bit) != stateMask) { 82 | if (micros() - startMicros > timeout) 83 | return 0; 84 | } 85 | 86 | unsigned long start = micros(); 87 | // wait for the pulse to stop 88 | while ((*portInputRegister(port) & bit) == stateMask) { 89 | if (micros() - startMicros > timeout) 90 | return 0; 91 | } 92 | return micros() - start; 93 | } 94 | -------------------------------------------------------------------------------- /src/core/wiring_shift.c: -------------------------------------------------------------------------------- 1 | /* 2 | wiring_shift.c - shiftOut() function 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2005-2006 David A. Mellis 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General 18 | Public License along with this library; if not, write to the 19 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 20 | Boston, MA 02111-1307 USA 21 | */ 22 | 23 | #include "wiring_private.h" 24 | 25 | uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) { 26 | uint8_t value = 0; 27 | uint8_t i; 28 | 29 | for (i = 0; i < 8; ++i) { 30 | digitalWrite(clockPin, HIGH); 31 | if (bitOrder == LSBFIRST) 32 | value |= digitalRead(dataPin) << i; 33 | else 34 | value |= digitalRead(dataPin) << (7 - i); 35 | digitalWrite(clockPin, LOW); 36 | } 37 | return value; 38 | } 39 | 40 | void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val) 41 | { 42 | uint8_t i; 43 | 44 | for (i = 0; i < 8; i++) { 45 | if (bitOrder == LSBFIRST) 46 | digitalWrite(dataPin, !!(val & (1 << i))); 47 | else 48 | digitalWrite(dataPin, !!(val & (1 << (7 - i)))); 49 | 50 | digitalWrite(clockPin, HIGH); 51 | digitalWrite(clockPin, LOW); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/ino.cpp: -------------------------------------------------------------------------------- 1 | #include "ino.h" 2 | #include "lib/sys.h" 3 | #include "bas.h" 4 | 5 | //--------------------------------------------------------------------------- 6 | void setup(void) 7 | { 8 | SysInit(); 9 | 10 | BasInit(); 11 | } 12 | //--------------------------------------------------------------------------- 13 | void loop(void) 14 | { 15 | if(SysLoop() == FALSE) 16 | { 17 | return; 18 | } 19 | 20 | BasLoop(); 21 | 22 | SysLoopEnd(); 23 | } 24 | -------------------------------------------------------------------------------- /src/ino.h: -------------------------------------------------------------------------------- 1 | #ifndef INO_H 2 | #define INO_H 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | #include "lib/common.h" 8 | 9 | //--------------------------------------------------------------------------- 10 | 11 | //--------------------------------------------------------------------------- 12 | 13 | 14 | 15 | //--------------------------------------------------------------------------- 16 | void setup(void); 17 | void loop(void); 18 | 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | #endif 24 | -------------------------------------------------------------------------------- /src/lib/common.cpp: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "oled.h" 3 | 4 | //--------------------------------------------------------------------------- 5 | void _Memset(void* s, u8 c, s16 size) 6 | { 7 | volatile char* s1 = (char*)s; 8 | 9 | if(size == 0) 10 | { 11 | goto End; 12 | } 13 | 14 | size++; 15 | while(--size > 0) 16 | { 17 | *s1++ = c; 18 | } 19 | 20 | End: ; 21 | } 22 | //--------------------------------------------------------------------------- 23 | char* _Sprintf(char* buf, const char* fmt, ...) 24 | { 25 | va_list ap; 26 | va_start(ap, fmt); 27 | _SprintfDo(buf, fmt, ap); 28 | va_end(ap); 29 | 30 | return buf; 31 | } 32 | //--------------------------------------------------------------------------- 33 | void _SprintfDo(char* str, const char* fmt, va_list ap) 34 | { 35 | s16 val; 36 | char* val2; 37 | char val3; 38 | 39 | char c; 40 | s16 col = 0; 41 | char colChr = ' '; 42 | bool isCol; 43 | 44 | for(;;) 45 | { 46 | c = *fmt++; 47 | 48 | if(c == '\0') 49 | { 50 | *str++ = '\0'; 51 | return; 52 | } 53 | 54 | if(c != '%') 55 | { 56 | *str++ = c; 57 | continue; 58 | } 59 | 60 | c = *fmt++; 61 | if(c == '0') 62 | { 63 | colChr = '0'; 64 | c = *fmt++; 65 | } 66 | 67 | if(_IsDigit(c) == TRUE) 68 | { 69 | col = c - '0'; 70 | isCol = TRUE; 71 | c = *fmt++; 72 | } 73 | else 74 | { 75 | isCol = FALSE; 76 | } 77 | 78 | switch(c) 79 | { 80 | case 'd': 81 | val = va_arg(ap, int); 82 | 83 | if(val < 0) 84 | { 85 | val *= -1; 86 | *str++ = '-'; 87 | } 88 | 89 | str = (isCol == TRUE) ? _SprintfNumCol(val, 10, str, col, colChr, TRUE) : _SprintfNum(val, 10, str); 90 | break; 91 | 92 | case 'x': 93 | str = (isCol == TRUE) ? _SprintfHexCol((u16)va_arg(ap, int), str, col, colChr, TRUE, 'a') : _SprintfHex((u16)va_arg(ap, int), str, 'a'); 94 | break; 95 | 96 | case 'l': 97 | str = (isCol == TRUE) ? _SprintfHexCol((u32)va_arg(ap, long), str, col, colChr, TRUE, 'a') : _SprintfHex((u32)va_arg(ap, long), str, 'a'); 98 | break; 99 | 100 | case 's': 101 | val2 = va_arg(ap, char*); 102 | str = _SprintfStr(val2, str); 103 | break; 104 | 105 | case 'c': 106 | val3 = va_arg(ap, int); 107 | *str++ = val3; 108 | break; 109 | 110 | case '\0': 111 | default: 112 | *str++ = '\0'; 113 | return; 114 | } 115 | } 116 | } 117 | //--------------------------------------------------------------------------- 118 | char* _SprintfNum(s16 val, s16 base, char* s) 119 | { 120 | s16 c = val % base; 121 | val = val / base; 122 | 123 | if(val > 0) 124 | { 125 | s = _SprintfNum(val, base, s); 126 | } 127 | 128 | *s++ = c+'0'; 129 | 130 | return s; 131 | } 132 | //--------------------------------------------------------------------------- 133 | char* _SprintfNumCol(s16 val, s16 base, char* s, s16 col, char colChr, bool isTop) 134 | { 135 | s16 c = val % base; 136 | val = val / base; 137 | 138 | if(val > 0 || col > 1) 139 | { 140 | s = _SprintfNumCol(val, base, s, col-1, colChr, FALSE); 141 | } 142 | 143 | if(c != 0 || val != 0 || isTop == TRUE) 144 | { 145 | *s++ = c+'0'; 146 | } 147 | else 148 | { 149 | *s++ = colChr; 150 | } 151 | 152 | return s; 153 | } 154 | //--------------------------------------------------------------------------- 155 | char* _SprintfHexCol(u32 val, char* s, s16 col, char colChr, bool isTop, char hex) 156 | { 157 | if(val >= 0x10 || col > 1) 158 | { 159 | s = _SprintfHexCol(val >> 4, s, col-1, colChr, FALSE, hex); 160 | } 161 | 162 | u16 c = val & 0xf; 163 | 164 | if(c != 0 || val != 0 || isTop == TRUE) 165 | { 166 | *s++ = (c>9) ? c-10+hex : c+'0'; 167 | } 168 | else 169 | { 170 | *s++ = colChr; 171 | } 172 | 173 | return s; 174 | } 175 | //--------------------------------------------------------------------------- 176 | char* _SprintfHex(u32 val, char* s, char hex) 177 | { 178 | if(val >= 0x10) 179 | { 180 | s = _SprintfHex(val >> 4, s, hex); 181 | } 182 | 183 | u16 c = val & 0xf; 184 | *s++ = (c>9) ? c-10+hex : c+'0'; 185 | 186 | return s; 187 | } 188 | //--------------------------------------------------------------------------- 189 | char* _SprintfStr(char* val, char* s) 190 | { 191 | while(*val != '\0') 192 | { 193 | *s++ = *val++; 194 | } 195 | 196 | return s; 197 | } 198 | //--------------------------------------------------------------------------- 199 | bool _IsDigit(char c) 200 | { 201 | return (c >= '0') && (c <= '9') ? TRUE : FALSE; 202 | } 203 | //--------------------------------------------------------------------------- 204 | void _SystemError(const char* fmt, ...) 205 | { 206 | char s[40]; 207 | 208 | va_list ap; 209 | va_start(ap, fmt); 210 | _SprintfDo(s, fmt, ap); 211 | va_end(ap); 212 | 213 | 214 | u16 i, x = 0; 215 | 216 | for(i=0; s[i] != '\0'; i++) 217 | { 218 | OledDrawChr(x++, 0, s[i]); 219 | } 220 | 221 | OledDisplay(); 222 | 223 | for(;;) 224 | { 225 | // EMPTY 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /src/lib/common.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_H 2 | #define COMMON_H 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | #include 8 | // #include "debug.h" 9 | 10 | //--------------------------------------------------------------------------- 11 | typedef unsigned char u8; 12 | typedef unsigned short u16; 13 | typedef unsigned long u32; 14 | typedef signed char s8; 15 | typedef signed short s16; 16 | typedef signed long s32; 17 | typedef volatile u8 vu8; 18 | typedef volatile u16 vu16; 19 | typedef volatile u32 vu32; 20 | typedef volatile s8 vs8; 21 | typedef volatile s16 vs16; 22 | typedef volatile s32 vs32; 23 | 24 | #define TRUE true 25 | #define FALSE false 26 | #define NUM2FIX(N) ((N) << 7) 27 | #define FIX2NUM(F) ((F) >> 7) 28 | #define ASSERT(x) if(!(x)) _SystemError("%s(%d)"#x"\n", __FILE__, __LINE__) 29 | #define ERROR(x) _SystemError("%s(%d)%x\n", #x, __FILE__, __LINE__) 30 | #define TRACEOUT DebugPrint 31 | 32 | //--------------------------------------------------------------------------- 33 | void _Memset(void* s, u8 c, s16 size); 34 | char* _Sprintf(char* buf, const char* fmt, ...); 35 | void _SprintfDo(char* str, const char* fmt, va_list ap); 36 | char* _SprintfNum(s16 val, s16 base, char* s); 37 | char* _SprintfNumCol(s16 val, s16 base, char* s, s16 col, char colChr, bool isTop); 38 | char* _SprintfHex(u32 val, char* s, char hex); 39 | char* _SprintfHexCol(u32 val, char* s, s16 col, char colChr, bool isTop, char hex); 40 | char* _SprintfStr(char* val, char* s); 41 | bool _IsDigit(char c); 42 | 43 | void _SystemError(const char* f, ...); 44 | 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | #endif 50 | -------------------------------------------------------------------------------- /src/lib/frame.cpp: -------------------------------------------------------------------------------- 1 | #include "frame.h" 2 | #include 3 | #include "sys.h" 4 | 5 | // timer 0 millis() 6 | 7 | 8 | //--------------------------------------------------------------------------- 9 | ST_FRAME Frame; 10 | 11 | 12 | //--------------------------------------------------------------------------- 13 | void FrameInit(void) 14 | { 15 | _Memset(&Frame, 0x00, sizeof(ST_FRAME)); 16 | 17 | FrameSetRate(60); 18 | } 19 | //--------------------------------------------------------------------------- 20 | void FrameSetRate(u8 rate) 21 | { 22 | Frame.rate = rate; 23 | Frame.eachMillis = 1000 / rate; 24 | } 25 | //--------------------------------------------------------------------------- 26 | u16 FrameGetCpuPercent(void) 27 | { 28 | return (Frame.lastDurationMs * 100) / Frame.eachMillis; 29 | } 30 | //--------------------------------------------------------------------------- 31 | u16 FrameGetCpuPercentMax(void) 32 | { 33 | u16 per = FrameGetCpuPercent(); 34 | 35 | if(Frame.cpuMaxPercent < per) 36 | { 37 | Frame.cpuMaxPercent = per; 38 | } 39 | 40 | return Frame.cpuMaxPercent; 41 | } 42 | //--------------------------------------------------------------------------- 43 | u8 FrameGetCnt(void) 44 | { 45 | return Frame.cnt; 46 | } 47 | //--------------------------------------------------------------------------- 48 | bool FrameIsMod(u8 num) 49 | { 50 | return (Frame.cnt % num == 0) ? TRUE : FALSE; 51 | } 52 | //--------------------------------------------------------------------------- 53 | bool FrameLoop(void) 54 | { 55 | u32 now = millis(); 56 | 57 | if(Frame.isPostRender == TRUE) 58 | { 59 | Frame.lastDurationMs = now - Frame.lastStart; 60 | Frame.count++; 61 | 62 | Frame.isPostRender = FALSE; 63 | } 64 | 65 | if(now < Frame.nextStart) 66 | { 67 | u8 remaining = Frame.nextStart - now; 68 | 69 | if(remaining > 1) 70 | { 71 | SysIdle(); 72 | } 73 | 74 | return FALSE; 75 | } 76 | 77 | Frame.nextStart = Frame.lastStart + Frame.eachMillis; 78 | 79 | if(Frame.nextStart < now) 80 | { 81 | Frame.nextStart = now; 82 | } 83 | 84 | Frame.lastStart = now; 85 | Frame.isPostRender = TRUE; 86 | Frame.cnt++; 87 | 88 | return TRUE; 89 | } 90 | -------------------------------------------------------------------------------- /src/lib/frame.h: -------------------------------------------------------------------------------- 1 | #ifndef FRAME_H 2 | #define FRAME_H 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | #include "common.h" 8 | 9 | //--------------------------------------------------------------------------- 10 | typedef struct { 11 | u8 rate; 12 | u16 count; 13 | u32 nextStart; 14 | u32 lastStart; 15 | u8 lastDurationMs; 16 | u8 eachMillis; 17 | bool isPostRender; 18 | 19 | u16 cpuMaxPercent; 20 | u8 cnt; 21 | } ST_FRAME; 22 | 23 | 24 | //--------------------------------------------------------------------------- 25 | void FrameInit(void); 26 | void FrameSetRate(u8 rate); 27 | u16 FrameGetCpuPercent(void); 28 | u16 FrameGetCpuPercentMax(void); 29 | u8 FrameGetCnt(void); 30 | bool FrameIsMod(u8 num); 31 | 32 | bool FrameLoop(void); 33 | 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | #endif 39 | -------------------------------------------------------------------------------- /src/lib/nouse/debug.cpp: -------------------------------------------------------------------------------- 1 | #include "debug.h" 2 | #include 3 | 4 | //--------------------------------------------------------------------------- 5 | 6 | 7 | //--------------------------------------------------------------------------- 8 | void DebugInit(void) 9 | { 10 | // Serial.begin(9600); 11 | } 12 | //--------------------------------------------------------------------------- 13 | void DebugPrint(const char* fmt, ...) 14 | { 15 | char s[40]; 16 | 17 | va_list ap; 18 | va_start(ap, fmt); 19 | _SprintfDo(s, fmt, ap); 20 | va_end(ap); 21 | 22 | // Serial.print(s); 23 | } 24 | -------------------------------------------------------------------------------- /src/lib/nouse/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef DEBUG_H 2 | #define DEBUG_H 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | #include "common.h" 8 | 9 | //--------------------------------------------------------------------------- 10 | 11 | 12 | //--------------------------------------------------------------------------- 13 | void DebugInit(void); 14 | void DebugPrint(const char* fmt, ...); 15 | 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | #endif 21 | -------------------------------------------------------------------------------- /src/lib/nouse/eep.cpp: -------------------------------------------------------------------------------- 1 | #include "eep.h" 2 | #include 3 | 4 | //--------------------------------------------------------------------------- 5 | ST_EEP Eep; 6 | 7 | 8 | //--------------------------------------------------------------------------- 9 | void EepInit(void) 10 | { 11 | _Memset(&Eep, 0x00, sizeof(ST_EEP)); 12 | } 13 | //--------------------------------------------------------------------------- 14 | void EepSeek(u16 adr) 15 | { 16 | Eep.adr = (u8*)adr; 17 | } 18 | //--------------------------------------------------------------------------- 19 | u8 EepRead8(void) 20 | { 21 | eeprom_busy_wait(); 22 | return eeprom_read_byte(EEP_START_OFFSET + Eep.adr++); 23 | } 24 | //--------------------------------------------------------------------------- 25 | u16 EepRead16(void) 26 | { 27 | u16 ret = 0; 28 | 29 | ret |= EepRead8(); 30 | ret |= EepRead8() << 8; 31 | 32 | return ret; 33 | } 34 | //--------------------------------------------------------------------------- 35 | u32 EepRead32(void) 36 | { 37 | u32 ret = 0; 38 | 39 | ret |= (u32)EepRead8(); 40 | ret |= (u32)EepRead8() << 8; 41 | ret |= (u32)EepRead8() << 16; 42 | ret |= (u32)EepRead8() << 24; 43 | 44 | return ret; 45 | } 46 | //--------------------------------------------------------------------------- 47 | void EepWrite8(u8 dat) 48 | { 49 | eeprom_busy_wait(); 50 | eeprom_write_byte(EEP_START_OFFSET + Eep.adr++, dat); 51 | } 52 | //--------------------------------------------------------------------------- 53 | void EepWrite16(u16 dat) 54 | { 55 | EepWrite8(dat & 0xff); 56 | EepWrite8(dat >> 8); 57 | } 58 | //--------------------------------------------------------------------------- 59 | void EepWrite32(u32 dat) 60 | { 61 | EepWrite8((dat ) & 0xff); 62 | EepWrite8((dat >> 8) & 0xff); 63 | EepWrite8((dat >> 16) & 0xff); 64 | EepWrite8((dat >> 24) & 0xff); 65 | } 66 | //--------------------------------------------------------------------------- 67 | void EepWriteAdr8(u8 adr, u8 dat) 68 | { 69 | EepSeek(adr); 70 | EepWrite8(dat); 71 | } 72 | -------------------------------------------------------------------------------- /src/lib/nouse/eep.h: -------------------------------------------------------------------------------- 1 | #ifndef EEP_H 2 | #define EEP_H 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | #include "common.h" 8 | 9 | //--------------------------------------------------------------------------- 10 | #define EEP_START_OFFSET 16 11 | 12 | 13 | //--------------------------------------------------------------------------- 14 | typedef struct { 15 | u8* adr; 16 | 17 | } ST_EEP; 18 | 19 | 20 | //--------------------------------------------------------------------------- 21 | void EepInit(void); 22 | void EepSeek(u16 adr); 23 | 24 | u8 EepRead8(void); 25 | u16 EepRead16(void); 26 | u32 EepRead32(void); 27 | void EepWrite8(u8 dat); 28 | void EepWrite16(u16 dat); 29 | void EepWrite32(u32 dat); 30 | 31 | void EepWriteAdr8(u8 adr, u8 dat); 32 | 33 | #ifdef __cplusplus 34 | } 35 | #endif 36 | #endif 37 | -------------------------------------------------------------------------------- /src/lib/nouse/key.cpp: -------------------------------------------------------------------------------- 1 | #include "key.h" 2 | #include 3 | 4 | //--------------------------------------------------------------------------- 5 | ST_KEY Key; 6 | 7 | 8 | //--------------------------------------------------------------------------- 9 | void KeyInit(void) 10 | { 11 | _Memset(&Key, 0x00, sizeof(ST_KEY)); 12 | 13 | pinMode(KEY_PIN_L, INPUT_PULLUP); 14 | pinMode(KEY_PIN_R, INPUT_PULLUP); 15 | pinMode(KEY_PIN_U, INPUT_PULLUP); 16 | pinMode(KEY_PIN_D, INPUT_PULLUP); 17 | pinMode(KEY_PIN_A, INPUT_PULLUP); 18 | pinMode(KEY_PIN_B, INPUT_PULLUP); 19 | } 20 | //--------------------------------------------------------------------------- 21 | void KeyLoop(void) 22 | { 23 | u8 cnt; 24 | 25 | #if defined(ARDUBOY_10) 26 | 27 | cnt = ((~PINF) & 0xf0); // up, down, left, right 28 | cnt |= ((~PINE) & 0x40) >> 3; // A 29 | cnt |= ((~PINB) & 0x10) >> 2; // B 30 | 31 | #elif defined(ARDUBOY_DEVKIT) 32 | 33 | cnt = ((~PINB) & 0x70); // down, left, up 34 | cnt |= ((~PINC) & 0x40) >> 4; // right 35 | cnt |= ((~PINF) & 0xc0) >> 6; // A, B 36 | 37 | #endif 38 | 39 | Key.trg = (Key.trg ^ cnt) & ~Key.cnt; 40 | Key.off = ~cnt & Key.cnt; 41 | Key.cnt = cnt; 42 | 43 | 44 | if(Key.trg & KEY_ALL || Key.repCnt == 0) 45 | { 46 | Key.rep = Key.cnt; 47 | Key.repCnt = KEY_REPEAT_CNT; 48 | } 49 | else 50 | { 51 | Key.rep = 0; 52 | } 53 | 54 | if(Key.cnt & KEY_ALL) 55 | { 56 | if(Key.repCnt != 0) Key.repCnt--; 57 | } 58 | else 59 | { 60 | Key.repCnt = 0; 61 | } 62 | } 63 | //--------------------------------------------------------------------------- 64 | u8 KeyGetCnt(void) 65 | { 66 | return Key.cnt; 67 | } 68 | //--------------------------------------------------------------------------- 69 | u8 KeyGetTrg(void) 70 | { 71 | return Key.trg; 72 | } 73 | //--------------------------------------------------------------------------- 74 | u8 KeyGetOff(void) 75 | { 76 | return Key.off; 77 | } 78 | //--------------------------------------------------------------------------- 79 | u8 KeyGetRep(void) 80 | { 81 | return Key.rep; 82 | } 83 | -------------------------------------------------------------------------------- /src/lib/nouse/key.h: -------------------------------------------------------------------------------- 1 | #ifndef KEY_H 2 | #define KEY_H 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | #include 8 | #include "common.h" 9 | 10 | //--------------------------------------------------------------------------- 11 | #define KEY_REPEAT_CNT 6 12 | 13 | 14 | //--------------------------------------------------------------------------- 15 | // Using symbolic pin names from pins_arduino.h 16 | #if defined(ARDUBOY_10) 17 | 18 | #define KEY_PIN_L A2 // PF5 19 | #define KEY_PIN_R A1 // PF6 20 | #define KEY_PIN_U A0 // PF7 21 | #define KEY_PIN_D A3 // PF4 22 | #define KEY_PIN_A 7 // PE6 23 | #define KEY_PIN_B 8 // PB4 24 | 25 | #elif defined(ARDUBOY_DEVKIT) 26 | 27 | #define KEY_PIN_L 9 28 | #define KEY_PIN_R 5 29 | #define KEY_PIN_U 8 30 | #define KEY_PIN_D 10 31 | #define KEY_PIN_A A0 32 | #define KEY_PIN_B A1 33 | 34 | #endif 35 | 36 | //--------------------------------------------------------------------------- 37 | enum { 38 | 39 | #if defined(ARDUBOY_10) 40 | 41 | KEY_A = _BV(3), 42 | KEY_B = _BV(2), 43 | KEY_L = _BV(5), 44 | KEY_R = _BV(6), 45 | KEY_U = _BV(7), 46 | KEY_D = _BV(4), 47 | 48 | #elif defined(ARDUBOY_DEVKIT) 49 | 50 | KEY_A = _BV(1), 51 | KEY_B = _BV(0), 52 | KEY_R = _BV(2), 53 | KEY_U = _BV(4), 54 | KEY_L = _BV(5), 55 | KEY_D = _BV(6), 56 | 57 | #endif 58 | 59 | KEY_ALL = (KEY_U | KEY_D | KEY_L | KEY_R | KEY_A | KEY_B), 60 | }; 61 | 62 | //--------------------------------------------------------------------------- 63 | typedef struct { 64 | u8 cnt; 65 | u8 trg; 66 | u8 off; 67 | u8 rep; 68 | s8 repCnt; 69 | 70 | } ST_KEY; 71 | 72 | //--------------------------------------------------------------------------- 73 | void KeyInit(void); 74 | void KeyLoop(void); 75 | 76 | u8 KeyGetCnt(void); 77 | u8 KeyGetTrg(void); 78 | u8 KeyGetOff(void); 79 | u8 KeyGetRep(void); 80 | 81 | 82 | #ifdef __cplusplus 83 | } 84 | #endif 85 | #endif 86 | -------------------------------------------------------------------------------- /src/lib/nouse/math.cpp: -------------------------------------------------------------------------------- 1 | #include "math.h" 2 | #include 3 | #include "tinymt32.h" 4 | 5 | 6 | //--------------------------------------------------------------------------- 7 | PROGMEM const s8 MathSinTable[] = { 8 | 0, /* no. 0 */ 9 | 2, /* no. 1 */ 10 | 3, /* no. 2 */ 11 | 5, /* no. 3 */ 12 | 6, /* no. 4 */ 13 | 8, /* no. 5 */ 14 | 9, /* no. 6 */ 15 | 11, /* no. 7 */ 16 | 12, /* no. 8 */ 17 | 14, /* no. 9 */ 18 | 16, /* no. 10 */ 19 | 17, /* no. 11 */ 20 | 19, /* no. 12 */ 21 | 20, /* no. 13 */ 22 | 22, /* no. 14 */ 23 | 23, /* no. 15 */ 24 | 24, /* no. 16 */ 25 | 26, /* no. 17 */ 26 | 27, /* no. 18 */ 27 | 29, /* no. 19 */ 28 | 30, /* no. 20 */ 29 | 32, /* no. 21 */ 30 | 33, /* no. 22 */ 31 | 34, /* no. 23 */ 32 | 36, /* no. 24 */ 33 | 37, /* no. 25 */ 34 | 38, /* no. 26 */ 35 | 39, /* no. 27 */ 36 | 41, /* no. 28 */ 37 | 42, /* no. 29 */ 38 | 43, /* no. 30 */ 39 | 44, /* no. 31 */ 40 | 45, /* no. 32 */ 41 | 46, /* no. 33 */ 42 | 47, /* no. 34 */ 43 | 48, /* no. 35 */ 44 | 49, /* no. 36 */ 45 | 50, /* no. 37 */ 46 | 51, /* no. 38 */ 47 | 52, /* no. 39 */ 48 | 53, /* no. 40 */ 49 | 54, /* no. 41 */ 50 | 55, /* no. 42 */ 51 | 56, /* no. 43 */ 52 | 56, /* no. 44 */ 53 | 57, /* no. 45 */ 54 | 58, /* no. 46 */ 55 | 59, /* no. 47 */ 56 | 59, /* no. 48 */ 57 | 60, /* no. 49 */ 58 | 60, /* no. 50 */ 59 | 61, /* no. 51 */ 60 | 61, /* no. 52 */ 61 | 62, /* no. 53 */ 62 | 62, /* no. 54 */ 63 | 62, /* no. 55 */ 64 | 63, /* no. 56 */ 65 | 63, /* no. 57 */ 66 | 63, /* no. 58 */ 67 | 64, /* no. 59 */ 68 | 64, /* no. 60 */ 69 | 64, /* no. 61 */ 70 | 64, /* no. 62 */ 71 | 64, /* no. 63 */ 72 | 64, /* no. 64 */ 73 | 64, /* no. 65 */ 74 | 64, /* no. 66 */ 75 | 64, /* no. 67 */ 76 | 64, /* no. 68 */ 77 | 64, /* no. 69 */ 78 | 63, /* no. 70 */ 79 | 63, /* no. 71 */ 80 | 63, /* no. 72 */ 81 | 62, /* no. 73 */ 82 | 62, /* no. 74 */ 83 | 62, /* no. 75 */ 84 | 61, /* no. 76 */ 85 | 61, /* no. 77 */ 86 | 60, /* no. 78 */ 87 | 60, /* no. 79 */ 88 | 59, /* no. 80 */ 89 | 59, /* no. 81 */ 90 | 58, /* no. 82 */ 91 | 57, /* no. 83 */ 92 | 56, /* no. 84 */ 93 | 56, /* no. 85 */ 94 | 55, /* no. 86 */ 95 | 54, /* no. 87 */ 96 | 53, /* no. 88 */ 97 | 52, /* no. 89 */ 98 | 51, /* no. 90 */ 99 | 50, /* no. 91 */ 100 | 49, /* no. 92 */ 101 | 48, /* no. 93 */ 102 | 47, /* no. 94 */ 103 | 46, /* no. 95 */ 104 | 45, /* no. 96 */ 105 | 44, /* no. 97 */ 106 | 43, /* no. 98 */ 107 | 42, /* no. 99 */ 108 | 41, /* no.100 */ 109 | 39, /* no.101 */ 110 | 38, /* no.102 */ 111 | 37, /* no.103 */ 112 | 36, /* no.104 */ 113 | 34, /* no.105 */ 114 | 33, /* no.106 */ 115 | 32, /* no.107 */ 116 | 30, /* no.108 */ 117 | 29, /* no.109 */ 118 | 27, /* no.110 */ 119 | 26, /* no.111 */ 120 | 24, /* no.112 */ 121 | 23, /* no.113 */ 122 | 22, /* no.114 */ 123 | 20, /* no.115 */ 124 | 19, /* no.116 */ 125 | 17, /* no.117 */ 126 | 16, /* no.118 */ 127 | 14, /* no.119 */ 128 | 12, /* no.120 */ 129 | 11, /* no.121 */ 130 | 9, /* no.122 */ 131 | 8, /* no.123 */ 132 | 6, /* no.124 */ 133 | 5, /* no.125 */ 134 | 3, /* no.126 */ 135 | 2, /* no.127 */ 136 | -0, /* no.128 */ 137 | -2, /* no.129 */ 138 | -3, /* no.130 */ 139 | -5, /* no.131 */ 140 | -6, /* no.132 */ 141 | -8, /* no.133 */ 142 | -9, /* no.134 */ 143 | -11, /* no.135 */ 144 | -12, /* no.136 */ 145 | -14, /* no.137 */ 146 | -16, /* no.138 */ 147 | -17, /* no.139 */ 148 | -19, /* no.140 */ 149 | -20, /* no.141 */ 150 | -22, /* no.142 */ 151 | -23, /* no.143 */ 152 | -24, /* no.144 */ 153 | -26, /* no.145 */ 154 | -27, /* no.146 */ 155 | -29, /* no.147 */ 156 | -30, /* no.148 */ 157 | -32, /* no.149 */ 158 | -33, /* no.150 */ 159 | -34, /* no.151 */ 160 | -36, /* no.152 */ 161 | -37, /* no.153 */ 162 | -38, /* no.154 */ 163 | -39, /* no.155 */ 164 | -41, /* no.156 */ 165 | -42, /* no.157 */ 166 | -43, /* no.158 */ 167 | -44, /* no.159 */ 168 | -45, /* no.160 */ 169 | -46, /* no.161 */ 170 | -47, /* no.162 */ 171 | -48, /* no.163 */ 172 | -49, /* no.164 */ 173 | -50, /* no.165 */ 174 | -51, /* no.166 */ 175 | -52, /* no.167 */ 176 | -53, /* no.168 */ 177 | -54, /* no.169 */ 178 | -55, /* no.170 */ 179 | -56, /* no.171 */ 180 | -56, /* no.172 */ 181 | -57, /* no.173 */ 182 | -58, /* no.174 */ 183 | -59, /* no.175 */ 184 | -59, /* no.176 */ 185 | -60, /* no.177 */ 186 | -60, /* no.178 */ 187 | -61, /* no.179 */ 188 | -61, /* no.180 */ 189 | -62, /* no.181 */ 190 | -62, /* no.182 */ 191 | -62, /* no.183 */ 192 | -63, /* no.184 */ 193 | -63, /* no.185 */ 194 | -63, /* no.186 */ 195 | -64, /* no.187 */ 196 | -64, /* no.188 */ 197 | -64, /* no.189 */ 198 | -64, /* no.190 */ 199 | -64, /* no.191 */ 200 | -64, /* no.192 */ 201 | -64, /* no.193 */ 202 | -64, /* no.194 */ 203 | -64, /* no.195 */ 204 | -64, /* no.196 */ 205 | -64, /* no.197 */ 206 | -63, /* no.198 */ 207 | -63, /* no.199 */ 208 | -63, /* no.200 */ 209 | -62, /* no.201 */ 210 | -62, /* no.202 */ 211 | -62, /* no.203 */ 212 | -61, /* no.204 */ 213 | -61, /* no.205 */ 214 | -60, /* no.206 */ 215 | -60, /* no.207 */ 216 | -59, /* no.208 */ 217 | -59, /* no.209 */ 218 | -58, /* no.210 */ 219 | -57, /* no.211 */ 220 | -56, /* no.212 */ 221 | -56, /* no.213 */ 222 | -55, /* no.214 */ 223 | -54, /* no.215 */ 224 | -53, /* no.216 */ 225 | -52, /* no.217 */ 226 | -51, /* no.218 */ 227 | -50, /* no.219 */ 228 | -49, /* no.220 */ 229 | -48, /* no.221 */ 230 | -47, /* no.222 */ 231 | -46, /* no.223 */ 232 | -45, /* no.224 */ 233 | -44, /* no.225 */ 234 | -43, /* no.226 */ 235 | -42, /* no.227 */ 236 | -41, /* no.228 */ 237 | -39, /* no.229 */ 238 | -38, /* no.230 */ 239 | -37, /* no.231 */ 240 | -36, /* no.232 */ 241 | -34, /* no.233 */ 242 | -33, /* no.234 */ 243 | -32, /* no.235 */ 244 | -30, /* no.236 */ 245 | -29, /* no.237 */ 246 | -27, /* no.238 */ 247 | -26, /* no.239 */ 248 | -24, /* no.240 */ 249 | -23, /* no.241 */ 250 | -22, /* no.242 */ 251 | -20, /* no.243 */ 252 | -19, /* no.244 */ 253 | -17, /* no.245 */ 254 | -16, /* no.246 */ 255 | -14, /* no.247 */ 256 | -12, /* no.248 */ 257 | -11, /* no.249 */ 258 | -9, /* no.250 */ 259 | -8, /* no.251 */ 260 | -6, /* no.252 */ 261 | -5, /* no.253 */ 262 | -3, /* no.254 */ 263 | -2, /* no.255 */ 264 | }; 265 | 266 | //--------------------------------------------------------------------------- 267 | 268 | 269 | //--------------------------------------------------------------------------- 270 | void MathInit(void) 271 | { 272 | // EMPTY 273 | } 274 | //--------------------------------------------------------------------------- 275 | s8 MathSin(u8 deg) 276 | { 277 | return __LPM(MathSinTable + (deg & 0xff)); 278 | } 279 | //--------------------------------------------------------------------------- 280 | s8 MathCos(u8 deg) 281 | { 282 | return __LPM(MathSinTable + ((deg + 192) & 0xff)); 283 | } 284 | -------------------------------------------------------------------------------- /src/lib/nouse/math.h: -------------------------------------------------------------------------------- 1 | #ifndef MATH_H 2 | #define MATH_H 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | #include "common.h" 8 | 9 | //--------------------------------------------------------------------------- 10 | 11 | 12 | 13 | //--------------------------------------------------------------------------- 14 | void MathInit(void); 15 | s8 MathSin(u8 deg); 16 | s8 MathCos(u8 deg); 17 | 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | #endif 23 | -------------------------------------------------------------------------------- /src/lib/nouse/snd.cpp: -------------------------------------------------------------------------------- 1 | #include "snd.h" 2 | #include 3 | #include 4 | #include "oled.h" 5 | 6 | //--------------------------------------------------------------------------- 7 | ST_SND Snd; 8 | 9 | 10 | //--------------------------------------------------------------------------- 11 | void SndInit(void) 12 | { 13 | _Memset(&Snd, 0x00, sizeof(ST_SND)); 14 | 15 | pinMode(SND_PIN1, OUTPUT); 16 | Snd.p[0].pPort = portOutputRegister(digitalPinToPort(SND_PIN1)); 17 | Snd.p[0].mask = digitalPinToBitMask(SND_PIN1); 18 | 19 | #if defined(ARDUBOY_10) 20 | 21 | pinMode(SND_PIN2, OUTPUT); 22 | Snd.p[1].pPort = portOutputRegister(digitalPinToPort(SND_PIN2)); 23 | Snd.p[1].mask = digitalPinToBitMask(SND_PIN2); 24 | 25 | #endif 26 | 27 | TCCR3A = 0; 28 | TCCR3B = 0; 29 | TCCR1A = 0; 30 | TCCR1B = 0; 31 | 32 | bitWrite(TCCR3B, WGM32, 1); 33 | bitWrite(TCCR3B, CS30, 1); 34 | bitWrite(TCCR1B, WGM12, 1); 35 | bitWrite(TCCR1B, CS10, 1); 36 | 37 | power_timer3_enable(); 38 | power_timer1_enable(); 39 | } 40 | //--------------------------------------------------------------------------- 41 | void SndPlay(u8 ch, u16 freq, u16 duration) 42 | { 43 | ST_SND_TONE* p = &Snd.t[ch]; 44 | 45 | if(p->isPlay == TRUE) 46 | { 47 | return; 48 | } 49 | p->isPlay = TRUE; 50 | 51 | 52 | u32 cnt = 2 * freq * duration / 1000; 53 | 54 | if(cnt == 0) 55 | { 56 | return; 57 | } 58 | p->cnt = cnt; 59 | 60 | 61 | SndStartTimer(ch, F_CPU / freq / 2); 62 | } 63 | //--------------------------------------------------------------------------- 64 | void SndStartTimer(u8 ch, u32 freq) 65 | { 66 | // timer ck/1 67 | u32 ocr = freq; 68 | u8 pre = 0x01; 69 | 70 | if(ocr > 0xffff) 71 | { 72 | // ck/64 73 | ocr /= 64; 74 | pre = 0x03; 75 | } 76 | ocr--; 77 | 78 | 79 | if(ch == 0) 80 | { 81 | TCCR3B = (TCCR3B & 0xf8) | pre; 82 | OCR3A = ocr; 83 | bitWrite(TIMSK3, OCIE3A, 1); 84 | } 85 | else 86 | { 87 | TCCR1B = (TCCR1B & 0xf8) | pre; 88 | OCR1A = ocr; 89 | bitWrite(TIMSK1, OCIE1A, 1); 90 | } 91 | } 92 | //--------------------------------------------------------------------------- 93 | void SndStopTimer(u8 ch) 94 | { 95 | if(ch == 0) 96 | { 97 | TIMSK3 &= ~(1 << OCIE3A); 98 | *Snd.p[0].pPort &= ~Snd.p[0].mask; 99 | } 100 | else 101 | { 102 | TIMSK1 &= ~(1 << OCIE1A); 103 | 104 | #if defined(ARDUBOY_10) 105 | 106 | *Snd.p[1].pPort &= ~Snd.p[1].mask; 107 | 108 | #endif 109 | 110 | } 111 | 112 | Snd.t[ch].isPlay = FALSE; 113 | } 114 | //--------------------------------------------------------------------------- 115 | // TIMER 3 ch0 116 | ISR(TIMER3_COMPA_vect) 117 | { 118 | *Snd.p[0].pPort ^= Snd.p[0].mask; 119 | 120 | if(--Snd.t[0].cnt == 0) 121 | { 122 | SndStopTimer(0); 123 | } 124 | } 125 | //--------------------------------------------------------------------------- 126 | // TIMER 1 ch1 127 | ISR(TIMER1_COMPA_vect) 128 | { 129 | 130 | #if defined(ARDUBOY_10) 131 | 132 | *Snd.p[1].pPort ^= Snd.p[1].mask; 133 | 134 | #endif 135 | 136 | if(--Snd.t[1].cnt == 0) 137 | { 138 | SndStopTimer(1); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/lib/nouse/snd.h: -------------------------------------------------------------------------------- 1 | #ifndef SND_H 2 | #define SND_H 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | // ISR(TIMER3_COMPA_vect) 8 | // ISR(TIMER1_COMPA_vect) 9 | 10 | #include "common.h" 11 | 12 | //--------------------------------------------------------------------------- 13 | #define SND_MAX_CH 2 14 | 15 | enum { 16 | SND_OP_PLAY_NOTE = 0x90, 17 | SND_OP_STOP_NOTE = 0x80, 18 | SND_OP_RESTART = 0xe0, 19 | SND_OP_STOP = 0xf0, 20 | }; 21 | 22 | //--------------------------------------------------------------------------- 23 | #if defined(ARDUBOY_10) 24 | 25 | #define SND_PIN1 5 // PC6 26 | #define SND_PIN2 13 // PC7 27 | 28 | #elif defined(ARDUBOY_DEVKIT) 29 | 30 | #define SND_PIN1 A2 31 | #define SND_PIN2 A3 32 | 33 | #endif 34 | 35 | //--------------------------------------------------------------------------- 36 | 37 | typedef struct { 38 | vu8* pPort; 39 | u8 mask; 40 | } ST_SND_PIN; 41 | 42 | typedef struct { 43 | bool isPlay; 44 | u32 cnt; 45 | } ST_SND_TONE; 46 | 47 | 48 | typedef struct { 49 | 50 | ST_SND_TONE t[SND_MAX_CH]; 51 | ST_SND_PIN p[SND_MAX_CH]; 52 | 53 | } ST_SND; 54 | 55 | 56 | //--------------------------------------------------------------------------- 57 | void SndInit(void); 58 | 59 | void SndPlay(u8 ch, u16 freq, u16 duration); 60 | void SndStartTimer(u8 ch, u32 freq); 61 | void SndStopTimer(u8 ch); 62 | 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | #endif 68 | -------------------------------------------------------------------------------- /src/lib/oled.cpp: -------------------------------------------------------------------------------- 1 | #include "oled.h" 2 | #include 3 | #include 4 | #include 5 | #include "../res/font.h" 6 | 7 | // SSD1306 OLED 8 | 9 | //--------------------------------------------------------------------------- 10 | PROGMEM const u8 OledBootProgram[] = { 11 | 0xD5, // Set Display Clock Divisor 0xF0 12 | 0xF0, 13 | 0x8D, // Charge Pump Setting 0x14 14 | 0x14, 15 | 0xA1, // Set Segment Re-map (A0) | (b0001) 16 | 0xC8, // Set COM Output Scan Direction 17 | 0x81, // Set Contrast 0xCF 18 | 0xCF, 19 | 0xD9, // Set Precharge 0xF1 20 | 0xF1, 21 | 0xAF, // Display On 22 | 0x20, // Set display mode 23 | 0x00, // Horizontal addressing mode 24 | }; 25 | 26 | //--------------------------------------------------------------------------- 27 | ST_OLED Oled; 28 | 29 | 30 | //--------------------------------------------------------------------------- 31 | void OledInit(void) 32 | { 33 | _Memset(&Oled, 0x00, sizeof(ST_OLED)); 34 | 35 | 36 | SPI.begin(); 37 | SPI.setClockDivider(SPI_CLOCK_DIV2); 38 | 39 | pinMode(OLED_PIN_DC, OUTPUT); 40 | pinMode(OLED_PIN_CS, OUTPUT); 41 | pinMode(OLED_PIN_RST, OUTPUT); 42 | 43 | // VDD (3.3V) goes high at start, lets just chill for a ms 44 | digitalWrite(OLED_PIN_RST, HIGH); 45 | delay(1); 46 | 47 | // bring reset low. wait 10ms 48 | digitalWrite(OLED_PIN_RST, LOW); 49 | delay(10); 50 | 51 | // bring out of reset 52 | digitalWrite(OLED_PIN_RST, HIGH); 53 | 54 | // setup the ports we need to talk to the OLED 55 | vu8* pCs = portOutputRegister(digitalPinToPort(OLED_PIN_CS)); 56 | vu8* pDc = portOutputRegister(digitalPinToPort(OLED_PIN_DC)); 57 | u8 csMask = digitalPinToBitMask(OLED_PIN_CS); 58 | u8 dcMask = digitalPinToBitMask(OLED_PIN_DC); 59 | 60 | // Command Mode 61 | *pCs |= csMask; 62 | *pDc &= ~dcMask; 63 | *pCs &= ~csMask; 64 | 65 | // Send boot Program 66 | u8 i; 67 | 68 | for(i=0; i= OLED_SCREEN_FONT_CX || fy >= OLED_SCREEN_FONT_CY) 119 | { 120 | return; 121 | } 122 | 123 | u8 x; 124 | 125 | for(x=0; x= OLED_SCREEN_CX || y >= OLED_SCREEN_CY) 134 | { 135 | return; 136 | } 137 | 138 | if(col) 139 | { 140 | Oled.buf[x + (y / 8) * OLED_SCREEN_CX] |= _BV(y % 8); 141 | } 142 | else 143 | { 144 | Oled.buf[x + (y / 8) * OLED_SCREEN_CX] &= ~_BV(y % 8); 145 | } 146 | } 147 | //--------------------------------------------------------------------------- 148 | void OledDrawCls(void) 149 | { 150 | // u16 i; 151 | // for(i=0; i= OLED_SCREEN_CY) 180 | { 181 | d += cx / 8; 182 | continue; 183 | } 184 | 185 | for(x=0; x= 0 && sx + x + b < OLED_SCREEN_CX) 193 | { 194 | if(chr & mask) 195 | { 196 | Oled.buf[(sx + x + b) + ((sy + y) / 8) * OLED_SCREEN_CX] |= _BV((sy + y) & 0x7); 197 | } 198 | } 199 | 200 | mask >>=1; 201 | } 202 | } 203 | } 204 | } 205 | //--------------------------------------------------------------------------- 206 | void OledDrawPng8(s8 bx, s8 by, u8* p, u8 num) 207 | { 208 | u8* d = (u8*)p + num * 8; 209 | u8 i; 210 | 211 | for(i=0; i<8; i++) 212 | { 213 | Oled.buf[(bx * 8 + by * OLED_SCREEN_CX) + i] |= __LPM(d + i); 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /src/lib/oled.h: -------------------------------------------------------------------------------- 1 | #ifndef OLED_H 2 | #define OLED_H 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | #include "common.h" 8 | 9 | //--------------------------------------------------------------------------- 10 | #define OLED_FONT_CX 5 11 | #define OLED_FONT_CY 8 12 | #define OLED_FONT_SIZE 5 13 | 14 | #define OLED_SCREEN_CX 128 15 | #define OLED_SCREEN_CY 64 16 | #define OLED_SCREEN_FONT_CX (OLED_SCREEN_CX / OLED_FONT_CX) 17 | #define OLED_SCREEN_FONT_CY (OLED_SCREEN_CY / OLED_FONT_CY) 18 | 19 | //--------------------------------------------------------------------------- 20 | #if defined(ARDUBOY_10) 21 | 22 | #define OLED_PIN_CS 12 23 | #define OLED_PIN_DC 4 24 | #define OLED_PIN_RST 6 25 | 26 | #elif defined(ARDUBOY_DEVKIT) 27 | 28 | #define OLED_PIN_CS 6 29 | #define OLED_PIN_DC 4 30 | #define OLED_PIN_RST 12 31 | 32 | #endif 33 | 34 | //--------------------------------------------------------------------------- 35 | typedef struct { 36 | u8 buf[OLED_SCREEN_CX * (OLED_SCREEN_CY / 8)]; 37 | 38 | } ST_OLED; 39 | 40 | 41 | //--------------------------------------------------------------------------- 42 | void OledInit(void); 43 | void OledDisplay(void); 44 | 45 | void OledDrawStr(u8 fx, u8 fy, const char* fmt, ...); 46 | void OledDrawStrP(u8 fx, u8 fy, const char* s); 47 | void OledDrawChr(u8 fx, u8 fy, char chr); 48 | void OledDrawDot(u8 x, u8 y, u8 col); 49 | void OledDrawCls(void); 50 | 51 | void OledDrawBmp(s8 sx, s8 sy, u8* p); 52 | void OledDrawPng8(s8 bx, s8 by, u8* p, u8 num); 53 | 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif 58 | #endif 59 | -------------------------------------------------------------------------------- /src/lib/rnd.cpp: -------------------------------------------------------------------------------- 1 | #include "rnd.h" 2 | #include "tinymt32.h" 3 | 4 | 5 | //--------------------------------------------------------------------------- 6 | tinymt32_t RndTinyMt; 7 | 8 | 9 | //--------------------------------------------------------------------------- 10 | void RndInit(void) 11 | { 12 | tinymt32_init(&RndTinyMt, 0xF67C129B); 13 | } 14 | //--------------------------------------------------------------------------- 15 | void RndInitSeed(u32 num) 16 | { 17 | tinymt32_init(&RndTinyMt, num); 18 | } 19 | //--------------------------------------------------------------------------- 20 | u32 Rnd32(void) 21 | { 22 | return tinymt32_generate_uint32(&RndTinyMt); 23 | } 24 | //--------------------------------------------------------------------------- 25 | u32 Rnd(u32 num) 26 | { 27 | s32 ret = Rnd32() % num; 28 | 29 | if(ret < 0) 30 | { 31 | ret *= -1; 32 | } 33 | 34 | return ret; 35 | } 36 | //--------------------------------------------------------------------------- 37 | bool RndIsBool(void) 38 | { 39 | return (Rnd32() & 0x1) ? TRUE : FALSE; 40 | } 41 | -------------------------------------------------------------------------------- /src/lib/rnd.h: -------------------------------------------------------------------------------- 1 | #ifndef RND_H 2 | #define RND_H 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | #include "common.h" 8 | 9 | //--------------------------------------------------------------------------- 10 | 11 | 12 | //--------------------------------------------------------------------------- 13 | void RndInit(void); 14 | void RndInitSeed(u32 num); 15 | 16 | u32 Rnd32(void); 17 | u32 Rnd(u32 num); 18 | 19 | bool RndIsBool(void); 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | #endif 25 | -------------------------------------------------------------------------------- /src/lib/sys.cpp: -------------------------------------------------------------------------------- 1 | #include "sys.h" 2 | #include 3 | #include 4 | #include "frame.h" 5 | // #include "snd.h" 6 | // #include "key.h" 7 | #include "oled.h" 8 | // #include "eep.h" 9 | // #include "math.h" 10 | #include "rnd.h" 11 | // #include "debug.h" 12 | 13 | //--------------------------------------------------------------------------- 14 | void SysInit(void) 15 | { 16 | power_timer2_disable(); 17 | power_adc_disable(); 18 | power_twi_disable(); 19 | power_usart0_disable(); 20 | power_usart1_disable(); 21 | 22 | OledInit(); 23 | FrameInit(); 24 | // SndInit(); 25 | // EepInit(); 26 | // KeyInit(); 27 | // MathInit(); 28 | RndInit(); 29 | // DebugInit(); 30 | } 31 | //--------------------------------------------------------------------------- 32 | void SysIdle(void) 33 | { 34 | set_sleep_mode(SLEEP_MODE_IDLE); 35 | sleep_mode(); 36 | } 37 | //--------------------------------------------------------------------------- 38 | bool SysLoop(void) 39 | { 40 | if(FrameLoop() == FALSE) 41 | { 42 | return FALSE; 43 | } 44 | 45 | // KeyLoop(); 46 | return TRUE; 47 | } 48 | //--------------------------------------------------------------------------- 49 | void SysLoopEnd(void) 50 | { 51 | OledDisplay(); 52 | // OledDrawCls(); 53 | } 54 | -------------------------------------------------------------------------------- /src/lib/sys.h: -------------------------------------------------------------------------------- 1 | #ifndef SYS_H 2 | #define SYS_H 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | #include "common.h" 8 | 9 | //--------------------------------------------------------------------------- 10 | 11 | 12 | //--------------------------------------------------------------------------- 13 | void SysInit(void); 14 | void SysIdle(void); 15 | bool SysLoop(void); 16 | void SysLoopEnd(void); 17 | 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | #endif 23 | -------------------------------------------------------------------------------- /src/lib/tinymt32.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tinymt32.c 3 | * 4 | * @brief Tiny Mersenne Twister only 127 bit internal state 5 | * 6 | * @author Mutsuo Saito (Hiroshima University) 7 | * @author Makoto Matsumoto (The University of Tokyo) 8 | * 9 | * Copyright (C) 2011 Mutsuo Saito, Makoto Matsumoto, 10 | * Hiroshima University and The University of Tokyo. 11 | * All rights reserved. 12 | * 13 | * The 3-clause BSD License is applied to this software, see 14 | * LICENSE.txt 15 | */ 16 | #include "tinymt32.h" 17 | #define MIN_LOOP 8 18 | #define PRE_LOOP 8 19 | 20 | /** 21 | * This function represents a function used in the initialization 22 | * by init_by_array 23 | * @param x 32-bit integer 24 | * @return 32-bit integer 25 | */ 26 | static uint32_t ini_func1(uint32_t x) { 27 | return (x ^ (x >> 27)) * UINT32_C(1664525); 28 | } 29 | 30 | /** 31 | * This function represents a function used in the initialization 32 | * by init_by_array 33 | * @param x 32-bit integer 34 | * @return 32-bit integer 35 | */ 36 | static uint32_t ini_func2(uint32_t x) { 37 | return (x ^ (x >> 27)) * UINT32_C(1566083941); 38 | } 39 | 40 | /** 41 | * This function certificate the period of 2^127-1. 42 | * @param random tinymt state vector. 43 | */ 44 | static void period_certification(tinymt32_t * random) { 45 | if ((random->status[0] & TINYMT32_MASK) == 0 && 46 | random->status[1] == 0 && 47 | random->status[2] == 0 && 48 | random->status[3] == 0) { 49 | random->status[0] = 'T'; 50 | random->status[1] = 'I'; 51 | random->status[2] = 'N'; 52 | random->status[3] = 'Y'; 53 | } 54 | } 55 | 56 | /** 57 | * This function initializes the internal state array with a 32-bit 58 | * unsigned integer seed. 59 | * @param random tinymt state vector. 60 | * @param seed a 32-bit unsigned integer used as a seed. 61 | */ 62 | void tinymt32_init(tinymt32_t * random, uint32_t seed) { 63 | random->status[0] = seed; 64 | random->status[1] = random->mat1; 65 | random->status[2] = random->mat2; 66 | random->status[3] = random->tmat; 67 | for (int i = 1; i < MIN_LOOP; i++) { 68 | random->status[i & 3] ^= i + UINT32_C(1812433253) 69 | * (random->status[(i - 1) & 3] 70 | ^ (random->status[(i - 1) & 3] >> 30)); 71 | } 72 | period_certification(random); 73 | for (int i = 0; i < PRE_LOOP; i++) { 74 | tinymt32_next_state(random); 75 | } 76 | } 77 | 78 | /** 79 | * This function initializes the internal state array, 80 | * with an array of 32-bit unsigned integers used as seeds 81 | * @param random tinymt state vector. 82 | * @param init_key the array of 32-bit integers, used as a seed. 83 | * @param key_length the length of init_key. 84 | */ 85 | void tinymt32_init_by_array(tinymt32_t * random, uint32_t init_key[], 86 | int key_length) { 87 | const int lag = 1; 88 | const int mid = 1; 89 | const int size = 4; 90 | int i, j; 91 | int count; 92 | uint32_t r; 93 | uint32_t * st = &random->status[0]; 94 | 95 | st[0] = 0; 96 | st[1] = random->mat1; 97 | st[2] = random->mat2; 98 | st[3] = random->tmat; 99 | if (key_length + 1 > MIN_LOOP) { 100 | count = key_length + 1; 101 | } else { 102 | count = MIN_LOOP; 103 | } 104 | r = ini_func1(st[0] ^ st[mid % size] 105 | ^ st[(size - 1) % size]); 106 | st[mid % size] += r; 107 | r += key_length; 108 | st[(mid + lag) % size] += r; 109 | st[0] = r; 110 | count--; 111 | for (i = 1, j = 0; (j < count) && (j < key_length); j++) { 112 | r = ini_func1(st[i % size] 113 | ^ st[(i + mid) % size] 114 | ^ st[(i + size - 1) % size]); 115 | st[(i + mid) % size] += r; 116 | r += init_key[j] + i; 117 | st[(i + mid + lag) % size] += r; 118 | st[i % size] = r; 119 | i = (i + 1) % size; 120 | } 121 | for (; j < count; j++) { 122 | r = ini_func1(st[i % size] 123 | ^ st[(i + mid) % size] 124 | ^ st[(i + size - 1) % size]); 125 | st[(i + mid) % size] += r; 126 | r += i; 127 | st[(i + mid + lag) % size] += r; 128 | st[i % size] = r; 129 | i = (i + 1) % size; 130 | } 131 | for (j = 0; j < size; j++) { 132 | r = ini_func2(st[i % size] 133 | + st[(i + mid) % size] 134 | + st[(i + size - 1) % size]); 135 | st[(i + mid) % size] ^= r; 136 | r -= i; 137 | st[(i + mid + lag) % size] ^= r; 138 | st[i % size] = r; 139 | i = (i + 1) % size; 140 | } 141 | period_certification(random); 142 | for (i = 0; i < PRE_LOOP; i++) { 143 | tinymt32_next_state(random); 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/lib/tinymt32.h: -------------------------------------------------------------------------------- 1 | #ifndef TINYMT32_H 2 | #define TINYMT32_H 3 | /** 4 | * @file tinymt32.h 5 | * 6 | * @brief Tiny Mersenne Twister only 127 bit internal state 7 | * 8 | * @author Mutsuo Saito (Hiroshima University) 9 | * @author Makoto Matsumoto (University of Tokyo) 10 | * 11 | * Copyright (C) 2011 Mutsuo Saito, Makoto Matsumoto, 12 | * Hiroshima University and The University of Tokyo. 13 | * All rights reserved. 14 | * 15 | * The 3-clause BSD License is applied to this software, see 16 | * LICENSE.txt 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #define TINYMT32_MEXP 127 23 | #define TINYMT32_SH0 1 24 | #define TINYMT32_SH1 10 25 | #define TINYMT32_SH8 8 26 | #define TINYMT32_MASK UINT32_C(0x7fffffff) 27 | #define TINYMT32_MUL (1.0f / 16777216.0f) 28 | 29 | #if defined(__cplusplus) 30 | extern "C" { 31 | #endif 32 | 33 | /** 34 | * tinymt32 internal state vector and parameters 35 | */ 36 | struct TINYMT32_T { 37 | uint32_t status[4]; 38 | uint32_t mat1; 39 | uint32_t mat2; 40 | uint32_t tmat; 41 | }; 42 | 43 | typedef struct TINYMT32_T tinymt32_t; 44 | 45 | void tinymt32_init(tinymt32_t * random, uint32_t seed); 46 | void tinymt32_init_by_array(tinymt32_t * random, uint32_t init_key[], 47 | int key_length); 48 | 49 | #if defined(__GNUC__) 50 | /** 51 | * This function always returns 127 52 | * @param random not used 53 | * @return always 127 54 | */ 55 | inline static int tinymt32_get_mexp( 56 | tinymt32_t * random __attribute__((unused))) { 57 | return TINYMT32_MEXP; 58 | } 59 | #else 60 | inline static int tinymt32_get_mexp(tinymt32_t * random) { 61 | return TINYMT32_MEXP; 62 | } 63 | #endif 64 | 65 | /** 66 | * This function changes internal state of tinymt32. 67 | * Users should not call this function directly. 68 | * @param random tinymt internal status 69 | */ 70 | inline static void tinymt32_next_state(tinymt32_t * random) { 71 | uint32_t x; 72 | uint32_t y; 73 | 74 | y = random->status[3]; 75 | x = (random->status[0] & TINYMT32_MASK) 76 | ^ random->status[1] 77 | ^ random->status[2]; 78 | x ^= (x << TINYMT32_SH0); 79 | y ^= (y >> TINYMT32_SH0) ^ x; 80 | random->status[0] = random->status[1]; 81 | random->status[1] = random->status[2]; 82 | random->status[2] = x ^ (y << TINYMT32_SH1); 83 | random->status[3] = y; 84 | random->status[1] ^= -((int32_t)(y & 1)) & random->mat1; 85 | random->status[2] ^= -((int32_t)(y & 1)) & random->mat2; 86 | } 87 | 88 | /** 89 | * This function outputs 32-bit unsigned integer from internal state. 90 | * Users should not call this function directly. 91 | * @param random tinymt internal status 92 | * @return 32-bit unsigned pseudorandom number 93 | */ 94 | inline static uint32_t tinymt32_temper(tinymt32_t * random) { 95 | uint32_t t0, t1; 96 | t0 = random->status[3]; 97 | #if defined(LINEARITY_CHECK) 98 | t1 = random->status[0] 99 | ^ (random->status[2] >> TINYMT32_SH8); 100 | #else 101 | t1 = random->status[0] 102 | + (random->status[2] >> TINYMT32_SH8); 103 | #endif 104 | t0 ^= t1; 105 | t0 ^= -((int32_t)(t1 & 1)) & random->tmat; 106 | return t0; 107 | } 108 | 109 | /** 110 | * This function outputs floating point number from internal state. 111 | * Users should not call this function directly. 112 | * @param random tinymt internal status 113 | * @return floating point number r (1.0 <= r < 2.0) 114 | */ 115 | inline static float tinymt32_temper_conv(tinymt32_t * random) { 116 | uint32_t t0, t1; 117 | union { 118 | uint32_t u; 119 | float f; 120 | } conv; 121 | 122 | t0 = random->status[3]; 123 | #if defined(LINEARITY_CHECK) 124 | t1 = random->status[0] 125 | ^ (random->status[2] >> TINYMT32_SH8); 126 | #else 127 | t1 = random->status[0] 128 | + (random->status[2] >> TINYMT32_SH8); 129 | #endif 130 | t0 ^= t1; 131 | conv.u = ((t0 ^ (-((int32_t)(t1 & 1)) & random->tmat)) >> 9) 132 | | UINT32_C(0x3f800000); 133 | return conv.f; 134 | } 135 | 136 | /** 137 | * This function outputs floating point number from internal state. 138 | * Users should not call this function directly. 139 | * @param random tinymt internal status 140 | * @return floating point number r (1.0 < r < 2.0) 141 | */ 142 | inline static float tinymt32_temper_conv_open(tinymt32_t * random) { 143 | uint32_t t0, t1; 144 | union { 145 | uint32_t u; 146 | float f; 147 | } conv; 148 | 149 | t0 = random->status[3]; 150 | #if defined(LINEARITY_CHECK) 151 | t1 = random->status[0] 152 | ^ (random->status[2] >> TINYMT32_SH8); 153 | #else 154 | t1 = random->status[0] 155 | + (random->status[2] >> TINYMT32_SH8); 156 | #endif 157 | t0 ^= t1; 158 | conv.u = ((t0 ^ (-((int32_t)(t1 & 1)) & random->tmat)) >> 9) 159 | | UINT32_C(0x3f800001); 160 | return conv.f; 161 | } 162 | 163 | /** 164 | * This function outputs 32-bit unsigned integer from internal state. 165 | * @param random tinymt internal status 166 | * @return 32-bit unsigned integer r (0 <= r < 2^32) 167 | */ 168 | inline static uint32_t tinymt32_generate_uint32(tinymt32_t * random) { 169 | tinymt32_next_state(random); 170 | return tinymt32_temper(random); 171 | } 172 | 173 | /** 174 | * This function outputs floating point number from internal state. 175 | * This function is implemented using multiplying by (1 / 2^24). 176 | * floating point multiplication is faster than using union trick in 177 | * my Intel CPU. 178 | * @param random tinymt internal status 179 | * @return floating point number r (0.0 <= r < 1.0) 180 | */ 181 | inline static float tinymt32_generate_float(tinymt32_t * random) { 182 | tinymt32_next_state(random); 183 | return (tinymt32_temper(random) >> 8) * TINYMT32_MUL; 184 | } 185 | 186 | /** 187 | * This function outputs floating point number from internal state. 188 | * This function is implemented using union trick. 189 | * @param random tinymt internal status 190 | * @return floating point number r (1.0 <= r < 2.0) 191 | */ 192 | inline static float tinymt32_generate_float12(tinymt32_t * random) { 193 | tinymt32_next_state(random); 194 | return tinymt32_temper_conv(random); 195 | } 196 | 197 | /** 198 | * This function outputs floating point number from internal state. 199 | * This function is implemented using union trick. 200 | * @param random tinymt internal status 201 | * @return floating point number r (0.0 <= r < 1.0) 202 | */ 203 | inline static float tinymt32_generate_float01(tinymt32_t * random) { 204 | tinymt32_next_state(random); 205 | return tinymt32_temper_conv(random) - 1.0f; 206 | } 207 | 208 | /** 209 | * This function outputs floating point number from internal state. 210 | * This function may return 1.0 and never returns 0.0. 211 | * @param random tinymt internal status 212 | * @return floating point number r (0.0 < r <= 1.0) 213 | */ 214 | inline static float tinymt32_generate_floatOC(tinymt32_t * random) { 215 | tinymt32_next_state(random); 216 | return 1.0f - tinymt32_generate_float(random); 217 | } 218 | 219 | /** 220 | * This function outputs floating point number from internal state. 221 | * This function returns neither 0.0 nor 1.0. 222 | * @param random tinymt internal status 223 | * @return floating point number r (0.0 < r < 1.0) 224 | */ 225 | inline static float tinymt32_generate_floatOO(tinymt32_t * random) { 226 | tinymt32_next_state(random); 227 | return tinymt32_temper_conv_open(random) - 1.0f; 228 | } 229 | 230 | /** 231 | * This function outputs double precision floating point number from 232 | * internal state. The returned value has 32-bit precision. 233 | * In other words, this function makes one double precision floating point 234 | * number from one 32-bit unsigned integer. 235 | * @param random tinymt internal status 236 | * @return floating point number r (0.0 < r <= 1.0) 237 | */ 238 | inline static double tinymt32_generate_32double(tinymt32_t * random) { 239 | tinymt32_next_state(random); 240 | return tinymt32_temper(random) * (1.0 / 4294967296.0); 241 | } 242 | 243 | #if defined(__cplusplus) 244 | } 245 | #endif 246 | 247 | #endif 248 | -------------------------------------------------------------------------------- /src/make_bin.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | set PATH="C:\Program Files (x86)\Arduino\hardware\tools\avr\bin";%PATH% 3 | 4 | :loop 5 | del test.* 6 | 7 | make 8 | avr-size test.elf -C --mcu=atmega32u4 9 | 10 | pause 11 | cls 12 | goto loop 13 | -------------------------------------------------------------------------------- /src/make_clean.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | rd /s /q obj >NUL 2>&1 3 | del /f test.* >NUL 2>&1 4 | 5 | pause 6 | -------------------------------------------------------------------------------- /src/make_usb.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | set PATH="C:\Program Files (x86)\Arduino\hardware\tools\avr\bin";%PATH% 3 | 4 | :loop 5 | del test.* 6 | make 7 | if exist test.hex goto usb 8 | 9 | :miss 10 | pause 11 | cls 12 | goto loop 13 | 14 | :usb 15 | ..\tool\reset COM4 16 | make usb 17 | avr-size test.elf -C --mcu=atmega32u4 18 | 19 | pause 20 | cls 21 | goto loop 22 | -------------------------------------------------------------------------------- /test.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | SET VAL1="C:\Program Files (x86)\Arduino\hardware\tools\avr\bin" 3 | SET VAL2=COM4 4 | SET VAL3="C:\Program Files (x86)\Arduino\hardware\tools\avr\etc\avrdude.conf" 5 | SET VAL4=COM3 6 | 7 | set PATH=%VAL1%;%PATH% 8 | 9 | 10 | tool\reset %VAL2% 11 | avrdude -C%VAL3% -v -patmega32u4 -cavr109 -P%VAL4% -b57600 -D -Uflash:w:test.hex:i 12 | 13 | pause 14 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export uart=/dev/tty.usbserial 4 | 5 | if [ `uname -s` = "Darwin" ]; then 6 | export avrdudeconf=/Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf 7 | export uart=/dev/tty.usbmodem1421 8 | python -c "import serial;ser=serial.Serial('/dev/tty.usbmodem1421',1200);ser.write('');ser.close()" 9 | else 10 | export avrdudeconf=/usr/share/arduino/hardware/tools/avrdude.conf 11 | if [ ! -f $avrdudeconf ]; then 12 | export avrdudeconf=/etc/avrdude.conf 13 | if ! [ -f $avrdudeconf ]; then 14 | echo "Couldn't find avrdudeconf - make sure you have arduino IDE installed and edit this file to provide the path" 15 | exit 16 | fi 17 | fi 18 | python -c "import serial;import sys;ser=serial.Serial(sys.argv[1],1200);ser.write('');ser.close()" $uart 19 | fi 20 | 21 | export hexfile=test.hex 22 | 23 | sleep 2 24 | avrdude -C${avrdudeconf} -v -patmega32u4 -cavr109 -P${uart} -b57600 -D -Uflash:w:${hexfile}:i 25 | 26 | -------------------------------------------------------------------------------- /tool/reset.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO.Ports; 7 | 8 | namespace ConsoleApplication1 9 | { 10 | class Program 11 | { 12 | static int Main(string[] args) 13 | { 14 | if(args.Length != 1) 15 | { 16 | Console.WriteLine("args error"); 17 | return -1; 18 | } 19 | 20 | 21 | Console.WriteLine("resetting..."); 22 | SerialPort port = new SerialPort(args[0], 1200); 23 | port.DtrEnable = true; 24 | 25 | try 26 | { 27 | port.Open(); 28 | } 29 | catch (Exception e) 30 | { 31 | Console.WriteLine(e.Message); 32 | return -1; 33 | } 34 | 35 | System.Threading.Thread.Sleep(500); 36 | 37 | port.DtrEnable = false; 38 | port.Close(); 39 | port.Dispose(); 40 | 41 | System.Threading.Thread.Sleep(2000); 42 | 43 | Console.WriteLine("done"); 44 | return 0; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tool/reset.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akkera102/07_tiny_basic/63b593d0f2d004cd961e404e226301acf6ed8c97/tool/reset.exe --------------------------------------------------------------------------------