├── .gitattributes ├── 3PhaseSPWM.componentinfo.xml ├── 3PhaseSPWM.cpp ├── 3PhaseSPWM.cppproj ├── 3PhaseSPWM.png ├── 3PhaseSPWM.vi ├── 3PhaseScopeTrace.png ├── LICENSE ├── README.md ├── include ├── core │ ├── Arduino.h │ ├── Client.h │ ├── HardwareSerial.h │ ├── HardwareSerial_private.h │ ├── IPAddress.h │ ├── PluggableUSB.h │ ├── Print.h │ ├── Printable.h │ ├── Server.h │ ├── Stream.h │ ├── USBAPI.h │ ├── USBCore.h │ ├── USBDesc.h │ ├── Udp.h │ ├── WCharacter.h │ ├── WString.h │ ├── binary.h │ ├── new.h │ └── wiring_private.h └── variants │ └── mega │ └── pins_arduino.h ├── library.cpp └── src └── core ├── CDC.cpp ├── HardwareSerial.cpp ├── HardwareSerial0.cpp ├── HardwareSerial1.cpp ├── HardwareSerial2.cpp ├── HardwareSerial3.cpp ├── IPAddress.cpp ├── PluggableUSB.cpp ├── PreprocessingAssembly └── wiring_pulse.S ├── Print.cpp ├── Stream.cpp ├── Tone.cpp ├── USBCore.cpp ├── WInterrupts.c ├── WMath.cpp ├── WString.cpp ├── abi.cpp ├── hooks.c ├── main.cpp ├── new.cpp ├── wiring.c ├── wiring_analog.c ├── wiring_digital.c ├── wiring_pulse.c └── wiring_shift.c /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto -------------------------------------------------------------------------------- /3PhaseSPWM.componentinfo.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | Device 8 | Startup 9 | 10 | 11 | Atmel 12 | 1.1.0 13 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs 14 | 15 | 16 | 17 | 18 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.1.130\include 19 | 20 | include 21 | C 22 | 23 | 24 | include 25 | 26 | 27 | 28 | 29 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.1.130\include\avr\iom2560.h 30 | 31 | header 32 | C 33 | y62MZP1QC6MflsAr6ze0Ew== 34 | 35 | include/avr/iom2560.h 36 | 37 | 38 | 39 | 40 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.1.130\templates\main.c 41 | template 42 | source 43 | C Exe 44 | GD1k8YYhulqRs6FD1B2Hog== 45 | 46 | templates/main.c 47 | Main file (.c) 48 | 49 | 50 | 51 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.1.130\templates\main.cpp 52 | template 53 | source 54 | C Exe 55 | E+ppgXCgJmW1Lw4UopwNvQ== 56 | 57 | templates/main.cpp 58 | Main file (.cpp) 59 | 60 | 61 | 62 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.1.130\gcc\dev\atmega2560 63 | 64 | libraryPrefix 65 | GCC 66 | 67 | 68 | gcc/dev/atmega2560 69 | 70 | 71 | 72 | 73 | ATmega_DFP 74 | C:/Program Files (x86)/Atmel/Studio/7.0/Packs/atmel/ATmega_DFP/1.1.130/Atmel.ATmega_DFP.pdsc 75 | 1.1.130 76 | true 77 | ATmega2560 78 | 79 | 80 | 81 | Resolved 82 | Fixed 83 | true 84 | 85 | 86 | -------------------------------------------------------------------------------- /3PhaseSPWM.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /*************************************** 4 | * 3-Phase SPWM Motor Controller 5 | * 6 | ***************************************/ 7 | 8 | #include 9 | //Beginning of Auto generated function prototypes by Atmel Studio 10 | void clear_string(char read_string); 11 | void get_serial(char read_string); 12 | void setup_pwm(); 13 | void setup_dds(); 14 | void dds_update(void ); 15 | void update_pwm(); 16 | void update_spwm(); 17 | void pause_spwm(); 18 | //End of Auto generated function prototypes by Atmel Studio 19 | 20 | 21 | 22 | #define PIN0 0 23 | 24 | /********3 PHASE SPWM START*****************************/ 25 | 26 | //LUT size 27 | #define TABLE_SIZE 256 28 | 29 | //Channel 1-3 on TIMER1 30 | #define PWM_PIN_SPWM1 6 31 | #define PWM_PIN_SPWM2 7 32 | #define PWM_PIN_SPWM3 8 33 | 34 | //Timer 1 = PWM 35 | //Timer 3 = Output compare and Phase accumulator update ISR 36 | #define TIMER_NUM1 1 37 | #define TIMER_NUM3 3 38 | 39 | //HardwareTimer classes for both TIMERS 40 | HardwareTimer timer_spwm(TIMER_NUM1); 41 | HardwareTimer timer_oc(TIMER_NUM3); 42 | 43 | //Initialize the variables 44 | //declare them volatile since they will used in ISR 45 | volatile uint32 phase_accumulator = 0; 46 | volatile uint8 phasor = 0; 47 | volatile uint8 pulse_width1 = 0; 48 | volatile uint8 pulse_width2 = 0; 49 | volatile uint8 pulse_width3 = 0; 50 | 51 | volatile uint32 phase_increment = 3067833; 52 | 53 | volatile const unsigned char sine_table[] = { 54 | 127,130,133,136,139,143,146,149,152,155,158,161,164,167,170,173,176,178,181,184,187,190,192,195,198,200,203,205,208,210,212,215,217,219,221,223,225,227,229,231,233,234,236,238,239,240, 55 | 242,243,244,245,247,248,249,249,250,251,252,252,253,253,253,254,254,254,254,254,254,254,253,253,253,252,252,251,250,249,249,248,247,245,244,243,242,240,239,238,236,234,233,231,229,227,225,223, 56 | 221,219,217,215,212,210,208,205,203,200,198,195,192,190,187,184,181,178,176,173,170,167,164,161,158,155,152,149,146,143,139,136,133,130,127,124,121,118,115,111,108,105,102,99,96,93,90,87,84,81,78, 57 | 76,73,70,67,64,62,59,56,54,51,49,46,44,42,39,37,35,33,31,29,27,25,23,21,20,18,16,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0,0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,16,18,20,21,23,25,27,29,31, 58 | 33,35,37,39,42,44,46,49,51,54,56,59,62,64,67,70,73,76,78,81,84,87,90,93,96,99,102,105,108,111,115,118,121,124 59 | }; 60 | 61 | uint8 offset_120 = 85; 62 | uint8 offset_240 = 170; 63 | 64 | uint32 tuning_word = 3067833; 65 | uint8 three_phase_spwm = 0; 66 | uint8 center_align_pwm = 0; 67 | 68 | /********3 PHASE SPWM END***********************/ 69 | 70 | #define STRING_SIZE 21 71 | 72 | #define TIMER_NUM2 2 73 | 74 | //Channel 1-4 on TIMER2 75 | #define PWM_PIN_CH1 1 76 | #define PWM_PIN_CH2 2 77 | #define PWM_PIN_CH3 3 78 | #define PWM_PIN_CH4 0 79 | 80 | //Overflow and compare values for all channels for TIMER2 81 | 82 | uint16 arr_val = 65535; 83 | uint16 pre_scaler = 1024; 84 | uint16 compare_val_ch1 = 32767; 85 | uint16 compare_val_ch2 = 32767; 86 | uint16 compare_val_ch3 = 32767; 87 | uint16 compare_val_ch4 = 32767; 88 | 89 | //HardwareTimer class for TIMER2 90 | HardwareTimer timer_pwm(TIMER_NUM2); 91 | 92 | //intialize the serial buffer string 93 | void clear_string(char * read_string) { 94 | for(int i = 0; i < STRING_SIZE; i++) 95 | read_string[i] = 0; 96 | } 97 | 98 | /***************************************** 99 | Function to communicate with the LabVIEW interface 100 | Reads each character from a delimited string which is sent from the LabVIEW program 101 | and assigns the values to all the different variables 102 | *****************************************/ 103 | 104 | void get_serial(char * read_string) { 105 | 106 | char read_char = 0; 107 | int read_count = 0; 108 | int i = 0; 109 | 110 | read_char = SerialUSB.read(); 111 | 112 | while(read_char != '#') { 113 | if(read_char == ';') { 114 | read_count++; 115 | switch(read_count) { 116 | case 1: 117 | arr_val = atoi(read_string); 118 | clear_string(read_string); 119 | i = 0; 120 | break; 121 | case 2: 122 | pre_scaler = atoi(read_string); 123 | clear_string(read_string); 124 | i = 0; 125 | break; 126 | case 3: 127 | compare_val_ch1 = atoi(read_string); 128 | clear_string(read_string); 129 | i = 0; 130 | break; 131 | case 4: 132 | compare_val_ch2 = atoi(read_string); 133 | clear_string(read_string); 134 | i = 0; 135 | break; 136 | case 5: 137 | compare_val_ch3 = atoi(read_string); 138 | clear_string(read_string); 139 | i = 0; 140 | break; 141 | case 6: 142 | compare_val_ch4 = atoi(read_string); 143 | clear_string(read_string); 144 | i = 0; 145 | break; 146 | case 7: 147 | tuning_word = atoi(read_string); 148 | clear_string(read_string); 149 | i = 0; 150 | break; 151 | case 8: 152 | three_phase_spwm = atoi(read_string); 153 | clear_string(read_string); 154 | i = 0; 155 | break; 156 | case 9: 157 | center_align_pwm = atoi(read_string); 158 | clear_string(read_string); 159 | i = 0; 160 | break; 161 | } 162 | } else { 163 | read_string[i] = read_char; 164 | i++; 165 | } 166 | read_char = SerialUSB.read(); 167 | } 168 | toggleLED(); 169 | } 170 | 171 | /******************************************* 172 | Setup TIMER2 and all its channel for individual PWM mode 173 | *******************************************/ 174 | 175 | void setup_pwm() { 176 | 177 | //Pause both timers 178 | timer_pwm.pause(); 179 | 180 | //Set TIMER2 for PWM 181 | //Start with a 50% duty cycle 182 | 183 | timer_pwm.setMode(TIMER_CH1, TIMER_PWM); 184 | timer_pwm.setMode(TIMER_CH2, TIMER_PWM); 185 | timer_pwm.setMode(TIMER_CH3, TIMER_PWM); 186 | timer_pwm.setMode(TIMER_CH4, TIMER_PWM); 187 | 188 | //Set the prescaler and overflow 189 | timer_pwm.setPrescaleFactor(pre_scaler); 190 | timer_pwm.setOverflow(arr_val); 191 | 192 | //Configure the compare registers for the different channels 193 | 194 | timer_pwm.setCompare(TIMER_CH1, compare_val_ch1); 195 | timer_pwm.setCompare(TIMER_CH2, compare_val_ch2); 196 | timer_pwm.setCompare(TIMER_CH3, compare_val_ch3); 197 | timer_pwm.setCompare(TIMER_CH4, compare_val_ch4); 198 | 199 | } 200 | 201 | /***************************************** 202 | Setup Direct Digital Synthesis on Timer 1 203 | Timer 3 updates the phase accumulator register 204 | ******************************************/ 205 | 206 | void setup_dds() { 207 | 208 | //Pause both timers 209 | timer_spwm.pause(); 210 | timer_oc.pause(); 211 | 212 | //Set TIMER1 for PWM 213 | //Prescaler = 1 214 | //Overflow = 256 gives a 280 kHz waveform, the number matches with the LUT size 215 | //We will be modifying this value to control the phase of the resultant output wave 216 | //Start with a 50% duty cycle 217 | 218 | /******************************************** 219 | Center-aligned mode setting on TIMER 1 220 | ********************************************/ 221 | 222 | TIMER1_BASE->CR1 |= 0x0040; 223 | 224 | timer_spwm.setMode(TIMER_CH1, TIMER_PWM); 225 | 226 | timer_spwm.setPrescaleFactor(1); 227 | timer_spwm.setOverflow(TABLE_SIZE); 228 | timer_spwm.setCompare(TIMER_CH1, (uint16)(TABLE_SIZE/2)); 229 | 230 | timer_spwm.setMode(TIMER_CH2, TIMER_PWM); 231 | timer_spwm.setOverflow(TABLE_SIZE); 232 | timer_spwm.setCompare(TIMER_CH2, (uint16)(TABLE_SIZE/2)); 233 | 234 | timer_spwm.setMode(TIMER_CH3, TIMER_PWM); 235 | timer_spwm.setOverflow(TABLE_SIZE); 236 | timer_spwm.setCompare(TIMER_CH3, (uint16)(TABLE_SIZE/2)); 237 | 238 | //Set TIMER3 for Output Compare 239 | //Prescaler = 1 240 | //Overflow = 512 gives a 140 kHz wave form 241 | //Dutycycle is 50% 242 | timer_oc.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE); 243 | timer_oc.setPrescaleFactor(1); 244 | timer_oc.setOverflow(TABLE_SIZE*2); 245 | timer_oc.setCompare(TIMER_CH1, TABLE_SIZE); 246 | 247 | //Phase accumulator update ISR 248 | timer_oc.attachInterrupt(TIMER_CH1, dds_update); 249 | 250 | //Update the registers for both timers with new values 251 | timer_spwm.refresh(); 252 | timer_oc.refresh(); 253 | 254 | } 255 | 256 | /*The heart of the DDS implementation*/ 257 | 258 | void dds_update(void) { 259 | 260 | // digitalWrite(PIN0, HIGH); 261 | /*Set the duty cycle for TIMER1 and thereby increment the phase of the desired sinusoidal wave */ 262 | 263 | timer_spwm.setCompare(TIMER_CH1, pulse_width1); 264 | timer_spwm.setCompare(TIMER_CH2, pulse_width2); 265 | timer_spwm.setCompare(TIMER_CH3, pulse_width3); 266 | 267 | /*Calculate the phase for the next time ISR is executed */ 268 | 269 | //Increment phase with the Tuning word 270 | 271 | phase_accumulator += tuning_word; 272 | 273 | //Set the index for the LUT to the high byte (top 8 bits) of the accumulator 274 | 275 | phasor = (uint8)(phase_accumulator >> 24); 276 | 277 | //Finally set the pulse width for the next iteration 278 | 279 | pulse_width1 = sine_table[255-phasor]; 280 | pulse_width2 = sine_table[255-uint8(phasor + offset_120)]; 281 | pulse_width3 = sine_table[255-uint8(phasor + offset_240)]; 282 | 283 | //Refresh the timer with the updated values 284 | 285 | timer_spwm.refresh(); 286 | // digitalWrite(PIN0, LOW); 287 | } 288 | 289 | //Update PWM with new settings 290 | 291 | void update_pwm() { 292 | timer_pwm.setPrescaleFactor(pre_scaler); 293 | timer_pwm.setOverflow(arr_val); 294 | timer_pwm.setCompare(TIMER_CH1, compare_val_ch1); 295 | timer_pwm.setCompare(TIMER_CH2, compare_val_ch2); 296 | timer_pwm.setCompare(TIMER_CH3, compare_val_ch3); 297 | timer_pwm.setCompare(TIMER_CH4, compare_val_ch4); 298 | 299 | //set center-aligned PWM if user has set it 300 | 301 | if(center_align_pwm == 1) { 302 | TIMER2_BASE->CR1 |= 0x0040; 303 | } 304 | if(center_align_pwm == 0) { 305 | TIMER2_BASE->CR1 &= 0xFFBF; 306 | } 307 | 308 | timer_pwm.refresh(); 309 | timer_pwm.resume(); 310 | } 311 | 312 | //Update SPWM with new settings 313 | void update_spwm() { 314 | timer_spwm.resume(); 315 | timer_oc.resume(); 316 | } 317 | 318 | //Pause SPWM on command 319 | void pause_spwm() { 320 | timer_spwm.pause(); 321 | timer_oc.pause(); 322 | } 323 | 324 | //Setup the output pins for PWM and the on-board LED 325 | //Setup DDS for SPWM and initialize PWM 326 | 327 | void setup () { 328 | 329 | //Setup the output pin for PWM 330 | //Setup the onboard LED 331 | 332 | pinMode(PWM_PIN_CH1, PWM); 333 | pinMode(PWM_PIN_CH2, PWM); 334 | pinMode(PWM_PIN_CH3, PWM); 335 | // pinMode(PWM_PIN_CH4, PWM); 336 | pinMode(PIN0, OUTPUT); 337 | digitalWrite(PIN0, LOW); 338 | 339 | pinMode(PWM_PIN_SPWM1, PWM); 340 | pinMode(PWM_PIN_SPWM2, PWM); 341 | pinMode(PWM_PIN_SPWM3, PWM); 342 | 343 | pinMode(BOARD_LED_PIN, OUTPUT); 344 | 345 | setup_pwm(); 346 | setup_dds(); 347 | 348 | } 349 | 350 | //Main loop polls the serial interface for commands from the GUI and processes them 351 | void loop () { 352 | 353 | char read_string[21] = {0}; 354 | 355 | int bytes_available = SerialUSB.available(); 356 | if(bytes_available > 0) { 357 | digitalWrite(0, HIGH); 358 | get_serial(read_string); 359 | update_pwm(); 360 | digitalWrite(0, LOW); 361 | if(three_phase_spwm == 1) 362 | update_spwm(); 363 | else if(three_phase_spwm == 0) 364 | pause_spwm(); 365 | } 366 | } 367 | -------------------------------------------------------------------------------- /3PhaseSPWM.cppproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 2.0 5 | 7.0 6 | com.Atmel.AVRGCC8.CPP 7 | dce6c7e3-ee26-4d79-826b-08594b9ad897 8 | atmega2560 9 | none 10 | Executable 11 | CPP 12 | $(MSBuildProjectName) 13 | Sketch 14 | .elf 15 | $(MSBuildProjectDirectory)\$(Configuration) 16 | 3PhaseSPWM 17 | 3PhaseSPWM 18 | C:\Program Files (x86)\Arduino 19 | Native 20 | true 21 | false 22 | true 23 | true 24 | 25 | 26 | true 27 | 28 | 2 29 | 1 30 | 3PhaseSPWM 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -mmcu=atmega2560 -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.1.130\gcc\dev\atmega2560" 48 | True 49 | True 50 | True 51 | True 52 | True 53 | False 54 | True 55 | True 56 | 57 | 58 | NDEBUG 59 | F_CPU=16000000L 60 | ARDUINO=10801 61 | ARDUINO_AVR_MEGA2560 62 | ARDUINO_ARCH_AVR 63 | USB_VID=0x2341 64 | USB_PID=0x0010 65 | USB_MANUFACTURER="\"Arduino LLC\"" 66 | 67 | 68 | 69 | 70 | %24(PackRepoDir)\atmel\ATmega_DFP\1.1.130\include 71 | %24(ProjectDir)\..\ArduinoCore\include\core 72 | %24(ProjectDir)\..\ArduinoCore\include\variants\mega 73 | 74 | 75 | Optimize for size (-Os) 76 | -fno-threadsafe-statics 77 | True 78 | True 79 | Default (-g2) 80 | True 81 | True 82 | -std=gnu99 -std=gnu11 83 | True 84 | True 85 | 86 | 87 | NDEBUG 88 | F_CPU=16000000L 89 | ARDUINO=10801 90 | ARDUINO_AVR_MEGA2560 91 | ARDUINO_ARCH_AVR 92 | USB_VID=0x2341 93 | USB_PID=0x0010 94 | USB_MANUFACTURER="\"Arduino LLC\"" 95 | 96 | 97 | 98 | 99 | %24(PackRepoDir)\atmel\ATmega_DFP\1.1.130\include 100 | %24(ProjectDir)\..\ArduinoCore\include\core 101 | %24(ProjectDir)\..\ArduinoCore\include\variants\mega 102 | 103 | 104 | Optimize for size (-Os) 105 | -fno-threadsafe-statics 106 | True 107 | True 108 | Default (-g2) 109 | True 110 | True 111 | -std=gnu++11 112 | 113 | 114 | libm 115 | 116 | 117 | -Os 118 | 119 | 120 | %24(PackRepoDir)\atmel\ATmega_DFP\1.1.130\include 121 | 122 | 123 | Default (-Wa,-g) 124 | 125 | 126 | 127 | 128 | 129 | 130 | -mmcu=atmega2560 -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.1.130\gcc\dev\atmega2560" 131 | True 132 | True 133 | True 134 | True 135 | True 136 | False 137 | True 138 | True 139 | 140 | 141 | DEBUG 142 | F_CPU=16000000L 143 | ARDUINO=10801 144 | ARDUINO_AVR_MEGA2560 145 | ARDUINO_ARCH_AVR 146 | USB_VID=0x2341 147 | USB_PID=0x0010 148 | USB_MANUFACTURER="\"Arduino LLC\"" 149 | 150 | 151 | 152 | 153 | %24(PackRepoDir)\atmel\ATmega_DFP\1.1.130\include 154 | %24(ProjectDir)\..\ArduinoCore\include\core 155 | %24(ProjectDir)\..\ArduinoCore\include\variants\mega 156 | 157 | 158 | Optimize for size (-Os) 159 | -fno-threadsafe-statics 160 | True 161 | True 162 | Default (-g2) 163 | True 164 | True 165 | -std=gnu99 -std=gnu11 166 | True 167 | True 168 | 169 | 170 | DEBUG 171 | F_CPU=16000000L 172 | ARDUINO=10801 173 | ARDUINO_AVR_MEGA2560 174 | ARDUINO_ARCH_AVR 175 | USB_VID=0x2341 176 | USB_PID=0x0010 177 | USB_MANUFACTURER="\"Arduino LLC\"" 178 | 179 | 180 | 181 | 182 | %24(PackRepoDir)\atmel\ATmega_DFP\1.1.130\include 183 | %24(ProjectDir)\..\ArduinoCore\include\core 184 | %24(ProjectDir)\..\ArduinoCore\include\variants\mega 185 | 186 | 187 | Optimize for size (-Os) 188 | -fno-threadsafe-statics 189 | True 190 | True 191 | Default (-g2) 192 | True 193 | True 194 | -std=gnu++11 195 | 196 | 197 | libm 198 | 199 | 200 | -Os 201 | 202 | 203 | %24(PackRepoDir)\atmel\ATmega_DFP\1.1.130\include 204 | 205 | 206 | Default (-Wa,-g) 207 | 208 | 209 | 210 | 211 | 212 | compile 213 | 214 | 215 | 216 | 217 | 218 | 219 | ArduinoCore 220 | 0981de3c-e41f-410e-a491-c3fb1bbaab7f 221 | True 222 | 223 | 224 | 225 | -------------------------------------------------------------------------------- /3PhaseSPWM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkrishn3/3PhaseSPWM/4006995b9f80b6f9621db0b3053710600d8d4144/3PhaseSPWM.png -------------------------------------------------------------------------------- /3PhaseSPWM.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkrishn3/3PhaseSPWM/4006995b9f80b6f9621db0b3053710600d8d4144/3PhaseSPWM.vi -------------------------------------------------------------------------------- /3PhaseScopeTrace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkrishn3/3PhaseSPWM/4006995b9f80b6f9621db0b3053710600d8d4144/3PhaseScopeTrace.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 hkrishn3 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 3PhaseSPWM 2 | Three Phase Sinusoidal Pulse Width Modulation Motor Controller for microcontroller projects. Originally written for the STM32 platform. LabVIEW interface included. 3 | 4 | ![Alt text](/3PhaseSPWM.png?raw=true "Optional Title") 5 | 6 | ![Alt text](/3PhaseScopeTrace.png?raw=true "Optional Title") 7 | -------------------------------------------------------------------------------- /include/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__) 65 | #define DEFAULT 0 66 | #define EXTERNAL 1 67 | #define INTERNAL1V1 2 68 | #define INTERNAL INTERNAL1V1 69 | #elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) 70 | #define DEFAULT 0 71 | #define EXTERNAL 4 72 | #define INTERNAL1V1 8 73 | #define INTERNAL INTERNAL1V1 74 | #define INTERNAL2V56 9 75 | #define INTERNAL2V56_EXTCAP 13 76 | #else 77 | #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__) 78 | #define INTERNAL1V1 2 79 | #define INTERNAL2V56 3 80 | #else 81 | #define INTERNAL 3 82 | #endif 83 | #define DEFAULT 1 84 | #define EXTERNAL 0 85 | #endif 86 | 87 | // undefine stdlib's abs if encountered 88 | #ifdef abs 89 | #undef abs 90 | #endif 91 | 92 | #define min(a,b) ((a)<(b)?(a):(b)) 93 | #define max(a,b) ((a)>(b)?(a):(b)) 94 | #define abs(x) ((x)>0?(x):-(x)) 95 | #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) 96 | #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) 97 | #define radians(deg) ((deg)*DEG_TO_RAD) 98 | #define degrees(rad) ((rad)*RAD_TO_DEG) 99 | #define sq(x) ((x)*(x)) 100 | 101 | #define interrupts() sei() 102 | #define noInterrupts() cli() 103 | 104 | #define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) 105 | #define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) 106 | #define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() ) 107 | 108 | #define lowByte(w) ((uint8_t) ((w) & 0xff)) 109 | #define highByte(w) ((uint8_t) ((w) >> 8)) 110 | 111 | #define bitRead(value, bit) (((value) >> (bit)) & 0x01) 112 | #define bitSet(value, bit) ((value) |= (1UL << (bit))) 113 | #define bitClear(value, bit) ((value) &= ~(1UL << (bit))) 114 | #define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) 115 | 116 | // avr-libc defines _NOP() since 1.6.2 117 | #ifndef _NOP 118 | #define _NOP() do { __asm__ volatile ("nop"); } while (0) 119 | #endif 120 | 121 | typedef unsigned int word; 122 | 123 | #define bit(b) (1UL << (b)) 124 | 125 | typedef bool boolean; 126 | typedef uint8_t byte; 127 | 128 | void init(void); 129 | void initVariant(void); 130 | 131 | int atexit(void (*func)()) __attribute__((weak)); 132 | 133 | void pinMode(uint8_t, uint8_t); 134 | void digitalWrite(uint8_t, uint8_t); 135 | int digitalRead(uint8_t); 136 | int analogRead(uint8_t); 137 | void analogReference(uint8_t mode); 138 | void analogWrite(uint8_t, int); 139 | 140 | unsigned long millis(void); 141 | unsigned long micros(void); 142 | void delay(unsigned long); 143 | void delayMicroseconds(unsigned int us); 144 | unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout); 145 | unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout); 146 | 147 | void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val); 148 | uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder); 149 | 150 | void attachInterrupt(uint8_t, void (*)(void), int mode); 151 | void detachInterrupt(uint8_t); 152 | 153 | void setup(void); 154 | void loop(void); 155 | 156 | // Get the bit location within the hardware port of the given virtual pin. 157 | // This comes from the pins_*.c file for the active board configuration. 158 | 159 | #define analogInPinToBit(P) (P) 160 | 161 | // On the ATmega1280, the addresses of some of the port registers are 162 | // greater than 255, so we can't store them in uint8_t's. 163 | extern const uint16_t PROGMEM port_to_mode_PGM[]; 164 | extern const uint16_t PROGMEM port_to_input_PGM[]; 165 | extern const uint16_t PROGMEM port_to_output_PGM[]; 166 | 167 | extern const uint8_t PROGMEM digital_pin_to_port_PGM[]; 168 | // extern const uint8_t PROGMEM digital_pin_to_bit_PGM[]; 169 | extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[]; 170 | extern const uint8_t PROGMEM digital_pin_to_timer_PGM[]; 171 | 172 | // Get the bit location within the hardware port of the given virtual pin. 173 | // This comes from the pins_*.c file for the active board configuration. 174 | // 175 | // These perform slightly better as macros compared to inline functions 176 | // 177 | #define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) ) 178 | #define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) ) 179 | #define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) ) 180 | #define analogInPinToBit(P) (P) 181 | #define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) ) 182 | #define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) ) 183 | #define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) ) 184 | 185 | #define NOT_A_PIN 0 186 | #define NOT_A_PORT 0 187 | 188 | #define NOT_AN_INTERRUPT -1 189 | 190 | #ifdef ARDUINO_MAIN 191 | #define PA 1 192 | #define PB 2 193 | #define PC 3 194 | #define PD 4 195 | #define PE 5 196 | #define PF 6 197 | #define PG 7 198 | #define PH 8 199 | #define PJ 10 200 | #define PK 11 201 | #define PL 12 202 | #endif 203 | 204 | #define NOT_ON_TIMER 0 205 | #define TIMER0A 1 206 | #define TIMER0B 2 207 | #define TIMER1A 3 208 | #define TIMER1B 4 209 | #define TIMER1C 5 210 | #define TIMER2 6 211 | #define TIMER2A 7 212 | #define TIMER2B 8 213 | 214 | #define TIMER3A 9 215 | #define TIMER3B 10 216 | #define TIMER3C 11 217 | #define TIMER4A 12 218 | #define TIMER4B 13 219 | #define TIMER4C 14 220 | #define TIMER4D 15 221 | #define TIMER5A 16 222 | #define TIMER5B 17 223 | #define TIMER5C 18 224 | 225 | #ifdef __cplusplus 226 | } // extern "C" 227 | #endif 228 | 229 | #ifdef __cplusplus 230 | #include "WCharacter.h" 231 | #include "WString.h" 232 | #include "HardwareSerial.h" 233 | #include "USBAPI.h" 234 | #if defined(HAVE_HWSERIAL0) && defined(HAVE_CDCSERIAL) 235 | #error "Targets with both UART0 and CDC serial not supported" 236 | #endif 237 | 238 | uint16_t makeWord(uint16_t w); 239 | uint16_t makeWord(byte h, byte l); 240 | 241 | #define word(...) makeWord(__VA_ARGS__) 242 | 243 | unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); 244 | unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); 245 | 246 | void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0); 247 | void noTone(uint8_t _pin); 248 | 249 | // WMath prototypes 250 | long random(long); 251 | long random(long, long); 252 | void randomSeed(unsigned long); 253 | long map(long, long, long, long, long); 254 | 255 | #endif 256 | 257 | #include "pins_arduino.h" 258 | 259 | #endif 260 | -------------------------------------------------------------------------------- /include/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 | -------------------------------------------------------------------------------- /include/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 | -------------------------------------------------------------------------------- /include/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 | -------------------------------------------------------------------------------- /include/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 | -------------------------------------------------------------------------------- /include/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 | -------------------------------------------------------------------------------- /include/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 | -------------------------------------------------------------------------------- /include/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 | -------------------------------------------------------------------------------- /include/core/Server.h: -------------------------------------------------------------------------------- 1 | /* 2 | Server.h - Base class that provides Server 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 server_h 21 | #define server_h 22 | 23 | #include "Print.h" 24 | 25 | class Server : public Print { 26 | public: 27 | virtual void begin() =0; 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /include/core/Stream.h: -------------------------------------------------------------------------------- 1 | /* 2 | Stream.h - base class for character-based streams. 3 | Copyright (c) 2010 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 | parsing functions based on TextFinder library by Michael Margolis 20 | */ 21 | 22 | #ifndef Stream_h 23 | #define Stream_h 24 | 25 | #include 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 | unsigned long getTimeout(void) { return _timeout; } 70 | 71 | bool find(char *target); // reads data from the stream until the target string is found 72 | bool find(uint8_t *target) { return find ((char *)target); } 73 | // returns true if target string is found, false if timed out (see setTimeout) 74 | 75 | bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found 76 | bool find(uint8_t *target, size_t length) { return find ((char *)target, length); } 77 | // returns true if target string is found, false if timed out 78 | 79 | bool find(char target) { return find (&target, 1); } 80 | 81 | bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found 82 | bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); } 83 | 84 | bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found 85 | bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); } 86 | 87 | long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); 88 | // returns the first valid (long) integer value from the current position. 89 | // lookahead determines how parseInt looks ahead in the stream. 90 | // See LookaheadMode enumeration at the top of the file. 91 | // Lookahead is terminated by the first character that is not a valid part of an integer. 92 | // Once parsing commences, 'ignore' will be skipped in the stream. 93 | 94 | float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); 95 | // float version of parseInt 96 | 97 | size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer 98 | size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); } 99 | // terminates if length characters have been read or timeout (see setTimeout) 100 | // returns the number of characters placed in the buffer (0 means no valid data found) 101 | 102 | size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character 103 | size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); } 104 | // terminates if length characters have been read, timeout, or if the terminator character detected 105 | // returns the number of characters placed in the buffer (0 means no valid data found) 106 | 107 | // Arduino String functions to be added here 108 | String readString(); 109 | String readStringUntil(char terminator); 110 | 111 | protected: 112 | long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); } 113 | float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); } 114 | // These overload exists for compatibility with any class that has derived 115 | // Stream and used parseFloat/Int with a custom ignore character. To keep 116 | // the public API simple, these overload remains protected. 117 | 118 | struct MultiTarget { 119 | const char *str; // string you're searching for 120 | size_t len; // length of string you're searching for 121 | size_t index; // index used by the search routine. 122 | }; 123 | 124 | // This allows you to search for an arbitrary number of strings. 125 | // Returns index of the target that is found first or -1 if timeout occurs. 126 | int findMulti(struct MultiTarget *targets, int tCount); 127 | }; 128 | 129 | #undef NO_IGNORE_CHAR 130 | #endif 131 | -------------------------------------------------------------------------------- /include/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 | -------------------------------------------------------------------------------- /include/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 | #ifndef USB_VERSION 130 | #define USB_VERSION 0x200 131 | #endif 132 | 133 | // Device 134 | typedef struct { 135 | u8 len; // 18 136 | u8 dtype; // 1 USB_DEVICE_DESCRIPTOR_TYPE 137 | u16 usbVersion; // 0x200 or 0x210 138 | u8 deviceClass; 139 | u8 deviceSubClass; 140 | u8 deviceProtocol; 141 | u8 packetSize0; // Packet 0 142 | u16 idVendor; 143 | u16 idProduct; 144 | u16 deviceVersion; // 0x100 145 | u8 iManufacturer; 146 | u8 iProduct; 147 | u8 iSerialNumber; 148 | u8 bNumConfigurations; 149 | } DeviceDescriptor; 150 | 151 | // Config 152 | typedef struct { 153 | u8 len; // 9 154 | u8 dtype; // 2 155 | u16 clen; // total length 156 | u8 numInterfaces; 157 | u8 config; 158 | u8 iconfig; 159 | u8 attributes; 160 | u8 maxPower; 161 | } ConfigDescriptor; 162 | 163 | // String 164 | 165 | // Interface 166 | typedef struct 167 | { 168 | u8 len; // 9 169 | u8 dtype; // 4 170 | u8 number; 171 | u8 alternate; 172 | u8 numEndpoints; 173 | u8 interfaceClass; 174 | u8 interfaceSubClass; 175 | u8 protocol; 176 | u8 iInterface; 177 | } InterfaceDescriptor; 178 | 179 | // Endpoint 180 | typedef struct 181 | { 182 | u8 len; // 7 183 | u8 dtype; // 5 184 | u8 addr; 185 | u8 attr; 186 | u16 packetSize; 187 | u8 interval; 188 | } EndpointDescriptor; 189 | 190 | // Interface Association Descriptor 191 | // Used to bind 2 interfaces together in CDC compostite device 192 | typedef struct 193 | { 194 | u8 len; // 8 195 | u8 dtype; // 11 196 | u8 firstInterface; 197 | u8 interfaceCount; 198 | u8 functionClass; 199 | u8 funtionSubClass; 200 | u8 functionProtocol; 201 | u8 iInterface; 202 | } IADDescriptor; 203 | 204 | // CDC CS interface descriptor 205 | typedef struct 206 | { 207 | u8 len; // 5 208 | u8 dtype; // 0x24 209 | u8 subtype; 210 | u8 d0; 211 | u8 d1; 212 | } CDCCSInterfaceDescriptor; 213 | 214 | typedef struct 215 | { 216 | u8 len; // 4 217 | u8 dtype; // 0x24 218 | u8 subtype; 219 | u8 d0; 220 | } CDCCSInterfaceDescriptor4; 221 | 222 | typedef struct 223 | { 224 | u8 len; 225 | u8 dtype; // 0x24 226 | u8 subtype; // 1 227 | u8 bmCapabilities; 228 | u8 bDataInterface; 229 | } CMFunctionalDescriptor; 230 | 231 | typedef struct 232 | { 233 | u8 len; 234 | u8 dtype; // 0x24 235 | u8 subtype; // 1 236 | u8 bmCapabilities; 237 | } ACMFunctionalDescriptor; 238 | 239 | typedef struct 240 | { 241 | // IAD 242 | IADDescriptor iad; // Only needed on compound device 243 | 244 | // Control 245 | InterfaceDescriptor cif; // 246 | CDCCSInterfaceDescriptor header; 247 | CMFunctionalDescriptor callManagement; // Call Management 248 | ACMFunctionalDescriptor controlManagement; // ACM 249 | CDCCSInterfaceDescriptor functionalDescriptor; // CDC_UNION 250 | EndpointDescriptor cifin; 251 | 252 | // Data 253 | InterfaceDescriptor dif; 254 | EndpointDescriptor in; 255 | EndpointDescriptor out; 256 | } CDCDescriptor; 257 | 258 | typedef struct 259 | { 260 | InterfaceDescriptor msc; 261 | EndpointDescriptor in; 262 | EndpointDescriptor out; 263 | } MSCDescriptor; 264 | 265 | 266 | #define D_DEVICE(_class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs) \ 267 | { 18, 1, USB_VERSION, _class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs } 268 | 269 | #define D_CONFIG(_totalLength,_interfaces) \ 270 | { 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_BUS_POWERED | USB_CONFIG_REMOTE_WAKEUP, USB_CONFIG_POWER_MA(500) } 271 | 272 | #define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \ 273 | { 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 } 274 | 275 | #define D_ENDPOINT(_addr,_attr,_packetSize, _interval) \ 276 | { 7, 5, _addr,_attr,_packetSize, _interval } 277 | 278 | #define D_IAD(_firstInterface, _count, _class, _subClass, _protocol) \ 279 | { 8, 11, _firstInterface, _count, _class, _subClass, _protocol, 0 } 280 | 281 | #define D_CDCCS(_subtype,_d0,_d1) { 5, 0x24, _subtype, _d0, _d1 } 282 | #define D_CDCCS4(_subtype,_d0) { 4, 0x24, _subtype, _d0 } 283 | 284 | // Bootloader related fields 285 | // Old Caterina bootloader places the MAGIC key into unsafe RAM locations (it can be rewritten 286 | // by the running sketch before to actual reboot). 287 | // Newer bootloaders, recognizable by the LUFA "signature" at the end of the flash, can handle both 288 | // the usafe and the safe location. Check once (in USBCore.cpp) if the bootloader in new, then set the global 289 | // _updatedLUFAbootloader variable to true/false and place the magic key consequently 290 | #ifndef MAGIC_KEY 291 | #define MAGIC_KEY 0x7777 292 | #endif 293 | 294 | #ifndef MAGIC_KEY_POS 295 | #define MAGIC_KEY_POS 0x0800 296 | #endif 297 | 298 | #ifndef NEW_LUFA_SIGNATURE 299 | #define NEW_LUFA_SIGNATURE 0xDCFB 300 | #endif 301 | 302 | #endif 303 | -------------------------------------------------------------------------------- /include/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 -------------------------------------------------------------------------------- /include/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 | -------------------------------------------------------------------------------- /include/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 -------------------------------------------------------------------------------- /include/core/WString.h: -------------------------------------------------------------------------------- 1 | /* 2 | WString.h - String library for Wiring & Arduino 3 | ...mostly rewritten by Paul Stoffregen... 4 | Copyright (c) 2009-10 Hernando Barragan. All right reserved. 5 | Copyright 2011, Paul Stoffregen, paul@pjrc.com 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 Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef String_class_h 23 | #define String_class_h 24 | #ifdef __cplusplus 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | // When compiling programs with this class, the following gcc parameters 32 | // dramatically increase performance and memory (RAM) efficiency, typically 33 | // with little or no increase in code size. 34 | // -felide-constructors 35 | // -std=c++0x 36 | 37 | class __FlashStringHelper; 38 | #define F(string_literal) (reinterpret_cast(PSTR(string_literal))) 39 | 40 | // An inherited class for holding the result of a concatenation. These 41 | // result objects are assumed to be writable by subsequent concatenations. 42 | class StringSumHelper; 43 | 44 | // The string class 45 | class String 46 | { 47 | // use a function pointer to allow for "if (s)" without the 48 | // complications of an operator bool(). for more information, see: 49 | // http://www.artima.com/cppsource/safebool.html 50 | typedef void (String::*StringIfHelperType)() const; 51 | void StringIfHelper() const {} 52 | 53 | public: 54 | // constructors 55 | // creates a copy of the initial value. 56 | // if the initial value is null or invalid, or if memory allocation 57 | // fails, the string will be marked as invalid (i.e. "if (s)" will 58 | // be false). 59 | String(const char *cstr = ""); 60 | String(const String &str); 61 | String(const __FlashStringHelper *str); 62 | #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) 63 | String(String &&rval); 64 | String(StringSumHelper &&rval); 65 | #endif 66 | explicit String(char c); 67 | explicit String(unsigned char, unsigned char base=10); 68 | explicit String(int, unsigned char base=10); 69 | explicit String(unsigned int, unsigned char base=10); 70 | explicit String(long, unsigned char base=10); 71 | explicit String(unsigned long, unsigned char base=10); 72 | explicit String(float, unsigned char decimalPlaces=2); 73 | explicit String(double, unsigned char decimalPlaces=2); 74 | ~String(void); 75 | 76 | // memory management 77 | // return true on success, false on failure (in which case, the string 78 | // is left unchanged). reserve(0), if successful, will validate an 79 | // invalid string (i.e., "if (s)" will be true afterwards) 80 | unsigned char reserve(unsigned int size); 81 | inline unsigned int length(void) const {return len;} 82 | 83 | // creates a copy of the assigned value. if the value is null or 84 | // invalid, or if the memory allocation fails, the string will be 85 | // marked as invalid ("if (s)" will be false). 86 | String & operator = (const String &rhs); 87 | String & operator = (const char *cstr); 88 | String & operator = (const __FlashStringHelper *str); 89 | #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) 90 | String & operator = (String &&rval); 91 | String & operator = (StringSumHelper &&rval); 92 | #endif 93 | 94 | // concatenate (works w/ built-in types) 95 | 96 | // returns true on success, false on failure (in which case, the string 97 | // is left unchanged). if the argument is null or invalid, the 98 | // concatenation is considered unsucessful. 99 | unsigned char concat(const String &str); 100 | unsigned char concat(const char *cstr); 101 | unsigned char concat(char c); 102 | unsigned char concat(unsigned char c); 103 | unsigned char concat(int num); 104 | unsigned char concat(unsigned int num); 105 | unsigned char concat(long num); 106 | unsigned char concat(unsigned long num); 107 | unsigned char concat(float num); 108 | unsigned char concat(double num); 109 | unsigned char concat(const __FlashStringHelper * str); 110 | 111 | // if there's not enough memory for the concatenated value, the string 112 | // will be left unchanged (but this isn't signalled in any way) 113 | String & operator += (const String &rhs) {concat(rhs); return (*this);} 114 | String & operator += (const char *cstr) {concat(cstr); return (*this);} 115 | String & operator += (char c) {concat(c); return (*this);} 116 | String & operator += (unsigned char num) {concat(num); return (*this);} 117 | String & operator += (int num) {concat(num); return (*this);} 118 | String & operator += (unsigned int num) {concat(num); return (*this);} 119 | String & operator += (long num) {concat(num); return (*this);} 120 | String & operator += (unsigned long num) {concat(num); return (*this);} 121 | String & operator += (float num) {concat(num); return (*this);} 122 | String & operator += (double num) {concat(num); return (*this);} 123 | String & operator += (const __FlashStringHelper *str){concat(str); return (*this);} 124 | 125 | friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs); 126 | friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr); 127 | friend StringSumHelper & operator + (const StringSumHelper &lhs, char c); 128 | friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num); 129 | friend StringSumHelper & operator + (const StringSumHelper &lhs, int num); 130 | friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num); 131 | friend StringSumHelper & operator + (const StringSumHelper &lhs, long num); 132 | friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num); 133 | friend StringSumHelper & operator + (const StringSumHelper &lhs, float num); 134 | friend StringSumHelper & operator + (const StringSumHelper &lhs, double num); 135 | friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs); 136 | 137 | // comparison (only works w/ Strings and "strings") 138 | operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; } 139 | int compareTo(const String &s) const; 140 | unsigned char equals(const String &s) const; 141 | unsigned char equals(const char *cstr) const; 142 | unsigned char operator == (const String &rhs) const {return equals(rhs);} 143 | unsigned char operator == (const char *cstr) const {return equals(cstr);} 144 | unsigned char operator != (const String &rhs) const {return !equals(rhs);} 145 | unsigned char operator != (const char *cstr) const {return !equals(cstr);} 146 | unsigned char operator < (const String &rhs) const; 147 | unsigned char operator > (const String &rhs) const; 148 | unsigned char operator <= (const String &rhs) const; 149 | unsigned char operator >= (const String &rhs) const; 150 | unsigned char equalsIgnoreCase(const String &s) const; 151 | unsigned char startsWith( const String &prefix) const; 152 | unsigned char startsWith(const String &prefix, unsigned int offset) const; 153 | unsigned char endsWith(const String &suffix) const; 154 | 155 | // character acccess 156 | char charAt(unsigned int index) const; 157 | void setCharAt(unsigned int index, char c); 158 | char operator [] (unsigned int index) const; 159 | char& operator [] (unsigned int index); 160 | void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const; 161 | void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const 162 | { getBytes((unsigned char *)buf, bufsize, index); } 163 | const char* c_str() const { return buffer; } 164 | char* begin() { return buffer; } 165 | char* end() { return buffer + length(); } 166 | const char* begin() const { return c_str(); } 167 | const char* end() const { return c_str() + length(); } 168 | 169 | // search 170 | int indexOf( char ch ) const; 171 | int indexOf( char ch, unsigned int fromIndex ) const; 172 | int indexOf( const String &str ) const; 173 | int indexOf( const String &str, unsigned int fromIndex ) const; 174 | int lastIndexOf( char ch ) const; 175 | int lastIndexOf( char ch, unsigned int fromIndex ) const; 176 | int lastIndexOf( const String &str ) const; 177 | int lastIndexOf( const String &str, unsigned int fromIndex ) const; 178 | String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); }; 179 | String substring( unsigned int beginIndex, unsigned int endIndex ) const; 180 | 181 | // modification 182 | void replace(char find, char replace); 183 | void replace(const String& find, const String& replace); 184 | void remove(unsigned int index); 185 | void remove(unsigned int index, unsigned int count); 186 | void toLowerCase(void); 187 | void toUpperCase(void); 188 | void trim(void); 189 | 190 | // parsing/conversion 191 | long toInt(void) const; 192 | float toFloat(void) const; 193 | double toDouble(void) const; 194 | 195 | protected: 196 | char *buffer; // the actual char array 197 | unsigned int capacity; // the array length minus one (for the '\0') 198 | unsigned int len; // the String length (not counting the '\0') 199 | protected: 200 | void init(void); 201 | void invalidate(void); 202 | unsigned char changeBuffer(unsigned int maxStrLen); 203 | unsigned char concat(const char *cstr, unsigned int length); 204 | 205 | // copy and move 206 | String & copy(const char *cstr, unsigned int length); 207 | String & copy(const __FlashStringHelper *pstr, unsigned int length); 208 | #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) 209 | void move(String &rhs); 210 | #endif 211 | }; 212 | 213 | class StringSumHelper : public String 214 | { 215 | public: 216 | StringSumHelper(const String &s) : String(s) {} 217 | StringSumHelper(const char *p) : String(p) {} 218 | StringSumHelper(char c) : String(c) {} 219 | StringSumHelper(unsigned char num) : String(num) {} 220 | StringSumHelper(int num) : String(num) {} 221 | StringSumHelper(unsigned int num) : String(num) {} 222 | StringSumHelper(long num) : String(num) {} 223 | StringSumHelper(unsigned long num) : String(num) {} 224 | StringSumHelper(float num) : String(num) {} 225 | StringSumHelper(double num) : String(num) {} 226 | }; 227 | 228 | #endif // __cplusplus 229 | #endif // String_class_h 230 | -------------------------------------------------------------------------------- /include/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 | -------------------------------------------------------------------------------- /include/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 | -------------------------------------------------------------------------------- /library.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ArduinoCore.cpp 3 | * 4 | * Created: 9/26/2017 11:10:30 AM 5 | * Author : hkrishnan 6 | */ 7 | 8 | #include 9 | 10 | 11 | /* Replace with your library code */ 12 | int myfunc(void) 13 | { 14 | return 0; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /src/core/CDC.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* Copyright (c) 2011, Peter Barrett 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 | #include "USBAPI.h" 20 | #include 21 | #include 22 | 23 | #if defined(USBCON) 24 | 25 | typedef struct 26 | { 27 | u32 dwDTERate; 28 | u8 bCharFormat; 29 | u8 bParityType; 30 | u8 bDataBits; 31 | u8 lineState; 32 | } LineInfo; 33 | 34 | static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 }; 35 | static volatile int32_t breakValue = -1; 36 | 37 | bool _updatedLUFAbootloader = false; 38 | 39 | #define WEAK __attribute__ ((weak)) 40 | 41 | extern const CDCDescriptor _cdcInterface PROGMEM; 42 | const CDCDescriptor _cdcInterface = 43 | { 44 | D_IAD(0,2,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,1), 45 | 46 | // CDC communication interface 47 | D_INTERFACE(CDC_ACM_INTERFACE,1,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,0), 48 | D_CDCCS(CDC_HEADER,0x10,0x01), // Header (1.10 bcd) 49 | D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management (not) 50 | D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported 51 | D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0 52 | D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10,0x40), 53 | 54 | // CDC data interface 55 | D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0), 56 | D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,USB_EP_SIZE,0), 57 | D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,USB_EP_SIZE,0) 58 | }; 59 | 60 | int CDC_GetInterface(u8* interfaceNum) 61 | { 62 | interfaceNum[0] += 2; // uses 2 63 | return USB_SendControl(TRANSFER_PGM,&_cdcInterface,sizeof(_cdcInterface)); 64 | } 65 | 66 | bool CDC_Setup(USBSetup& setup) 67 | { 68 | u8 r = setup.bRequest; 69 | u8 requestType = setup.bmRequestType; 70 | 71 | if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType) 72 | { 73 | if (CDC_GET_LINE_CODING == r) 74 | { 75 | USB_SendControl(0,(void*)&_usbLineInfo,7); 76 | return true; 77 | } 78 | } 79 | 80 | if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType) 81 | { 82 | if (CDC_SEND_BREAK == r) 83 | { 84 | breakValue = ((uint16_t)setup.wValueH << 8) | setup.wValueL; 85 | } 86 | 87 | if (CDC_SET_LINE_CODING == r) 88 | { 89 | USB_RecvControl((void*)&_usbLineInfo,7); 90 | } 91 | 92 | if (CDC_SET_CONTROL_LINE_STATE == r) 93 | { 94 | _usbLineInfo.lineState = setup.wValueL; 95 | } 96 | 97 | if (CDC_SET_LINE_CODING == r || CDC_SET_CONTROL_LINE_STATE == r) 98 | { 99 | // auto-reset into the bootloader is triggered when the port, already 100 | // open at 1200 bps, is closed. this is the signal to start the watchdog 101 | // with a relatively long period so it can finish housekeeping tasks 102 | // like servicing endpoints before the sketch ends 103 | 104 | uint16_t magic_key_pos = MAGIC_KEY_POS; 105 | 106 | // If we don't use the new RAMEND directly, check manually if we have a newer bootloader. 107 | // This is used to keep compatible with the old leonardo bootloaders. 108 | // You are still able to set the magic key position manually to RAMEND-1 to save a few bytes for this check. 109 | #if MAGIC_KEY_POS != (RAMEND-1) 110 | // For future boards save the key in the inproblematic RAMEND 111 | // Which is reserved for the main() return value (which will never return) 112 | if (_updatedLUFAbootloader) { 113 | // horray, we got a new bootloader! 114 | magic_key_pos = (RAMEND-1); 115 | } 116 | #endif 117 | 118 | // We check DTR state to determine if host port is open (bit 0 of lineState). 119 | if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0) 120 | { 121 | #if MAGIC_KEY_POS != (RAMEND-1) 122 | // Backup ram value if its not a newer bootloader. 123 | // This should avoid memory corruption at least a bit, not fully 124 | if (magic_key_pos != (RAMEND-1)) { 125 | *(uint16_t *)(RAMEND-1) = *(uint16_t *)magic_key_pos; 126 | } 127 | #endif 128 | // Store boot key 129 | *(uint16_t *)magic_key_pos = MAGIC_KEY; 130 | wdt_enable(WDTO_120MS); 131 | } 132 | else 133 | { 134 | // Most OSs do some intermediate steps when configuring ports and DTR can 135 | // twiggle more than once before stabilizing. 136 | // To avoid spurious resets we set the watchdog to 250ms and eventually 137 | // cancel if DTR goes back high. 138 | 139 | wdt_disable(); 140 | wdt_reset(); 141 | #if MAGIC_KEY_POS != (RAMEND-1) 142 | // Restore backed up (old bootloader) magic key data 143 | if (magic_key_pos != (RAMEND-1)) { 144 | *(uint16_t *)magic_key_pos = *(uint16_t *)(RAMEND-1); 145 | } else 146 | #endif 147 | { 148 | // Clean up RAMEND key 149 | *(uint16_t *)magic_key_pos = 0x0000; 150 | } 151 | } 152 | } 153 | return true; 154 | } 155 | return false; 156 | } 157 | 158 | 159 | void Serial_::begin(unsigned long /* baud_count */) 160 | { 161 | peek_buffer = -1; 162 | } 163 | 164 | void Serial_::begin(unsigned long /* baud_count */, byte /* config */) 165 | { 166 | peek_buffer = -1; 167 | } 168 | 169 | void Serial_::end(void) 170 | { 171 | } 172 | 173 | int Serial_::available(void) 174 | { 175 | if (peek_buffer >= 0) { 176 | return 1 + USB_Available(CDC_RX); 177 | } 178 | return USB_Available(CDC_RX); 179 | } 180 | 181 | int Serial_::peek(void) 182 | { 183 | if (peek_buffer < 0) 184 | peek_buffer = USB_Recv(CDC_RX); 185 | return peek_buffer; 186 | } 187 | 188 | int Serial_::read(void) 189 | { 190 | if (peek_buffer >= 0) { 191 | int c = peek_buffer; 192 | peek_buffer = -1; 193 | return c; 194 | } 195 | return USB_Recv(CDC_RX); 196 | } 197 | 198 | int Serial_::availableForWrite(void) 199 | { 200 | return USB_SendSpace(CDC_TX); 201 | } 202 | 203 | void Serial_::flush(void) 204 | { 205 | USB_Flush(CDC_TX); 206 | } 207 | 208 | size_t Serial_::write(uint8_t c) 209 | { 210 | return write(&c, 1); 211 | } 212 | 213 | size_t Serial_::write(const uint8_t *buffer, size_t size) 214 | { 215 | /* only try to send bytes if the high-level CDC connection itself 216 | is open (not just the pipe) - the OS should set lineState when the port 217 | is opened and clear lineState when the port is closed. 218 | bytes sent before the user opens the connection or after 219 | the connection is closed are lost - just like with a UART. */ 220 | 221 | // TODO - ZE - check behavior on different OSes and test what happens if an 222 | // open connection isn't broken cleanly (cable is yanked out, host dies 223 | // or locks up, or host virtual serial port hangs) 224 | if (_usbLineInfo.lineState > 0) { 225 | int r = USB_Send(CDC_TX,buffer,size); 226 | if (r > 0) { 227 | return r; 228 | } else { 229 | setWriteError(); 230 | return 0; 231 | } 232 | } 233 | setWriteError(); 234 | return 0; 235 | } 236 | 237 | // This operator is a convenient way for a sketch to check whether the 238 | // port has actually been configured and opened by the host (as opposed 239 | // to just being connected to the host). It can be used, for example, in 240 | // setup() before printing to ensure that an application on the host is 241 | // actually ready to receive and display the data. 242 | // We add a short delay before returning to fix a bug observed by Federico 243 | // where the port is configured (lineState != 0) but not quite opened. 244 | Serial_::operator bool() { 245 | bool result = false; 246 | if (_usbLineInfo.lineState > 0) 247 | result = true; 248 | delay(10); 249 | return result; 250 | } 251 | 252 | unsigned long Serial_::baud() { 253 | // Disable interrupts while reading a multi-byte value 254 | uint32_t baudrate; 255 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { 256 | baudrate = _usbLineInfo.dwDTERate; 257 | } 258 | return baudrate; 259 | } 260 | 261 | uint8_t Serial_::stopbits() { 262 | return _usbLineInfo.bCharFormat; 263 | } 264 | 265 | uint8_t Serial_::paritytype() { 266 | return _usbLineInfo.bParityType; 267 | } 268 | 269 | uint8_t Serial_::numbits() { 270 | return _usbLineInfo.bDataBits; 271 | } 272 | 273 | bool Serial_::dtr() { 274 | return _usbLineInfo.lineState & 0x1; 275 | } 276 | 277 | bool Serial_::rts() { 278 | return _usbLineInfo.lineState & 0x2; 279 | } 280 | 281 | int32_t Serial_::readBreak() { 282 | int32_t ret; 283 | // Disable IRQs while reading and clearing breakValue to make 284 | // sure we don't overwrite a value just set by the ISR. 285 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { 286 | ret = breakValue; 287 | breakValue = -1; 288 | } 289 | return ret; 290 | } 291 | 292 | Serial_ Serial; 293 | 294 | #endif /* if defined(USBCON) */ 295 | -------------------------------------------------------------------------------- /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/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/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 | uint16_t acc = 0; // Accumulator 49 | uint8_t dots = 0; 50 | 51 | while (*address) 52 | { 53 | char c = *address++; 54 | if (c >= '0' && c <= '9') 55 | { 56 | acc = acc * 10 + (c - '0'); 57 | if (acc > 255) { 58 | // Value out of [0..255] range 59 | return false; 60 | } 61 | } 62 | else if (c == '.') 63 | { 64 | if (dots == 3) { 65 | // Too much dots (there must be 3 dots) 66 | return false; 67 | } 68 | _address.bytes[dots++] = acc; 69 | acc = 0; 70 | } 71 | else 72 | { 73 | // Invalid char 74 | return false; 75 | } 76 | } 77 | 78 | if (dots != 3) { 79 | // Too few dots (there must be 3 dots) 80 | return false; 81 | } 82 | _address.bytes[3] = acc; 83 | return true; 84 | } 85 | 86 | IPAddress& IPAddress::operator=(const uint8_t *address) 87 | { 88 | memcpy(_address.bytes, address, sizeof(_address.bytes)); 89 | return *this; 90 | } 91 | 92 | IPAddress& IPAddress::operator=(uint32_t address) 93 | { 94 | _address.dword = address; 95 | return *this; 96 | } 97 | 98 | bool IPAddress::operator==(const uint8_t* addr) const 99 | { 100 | return memcmp(addr, _address.bytes, sizeof(_address.bytes)) == 0; 101 | } 102 | 103 | size_t IPAddress::printTo(Print& p) const 104 | { 105 | size_t n = 0; 106 | for (int i =0; i < 3; i++) 107 | { 108 | n += p.print(_address.bytes[i], DEC); 109 | n += p.print('.'); 110 | } 111 | n += p.print(_address.bytes[3], DEC); 112 | return n; 113 | } 114 | 115 | -------------------------------------------------------------------------------- /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/PreprocessingAssembly/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/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 | unsigned int toPrint = (unsigned int)(remainder); 261 | n += print(toPrint); 262 | remainder -= toPrint; 263 | } 264 | 265 | return n; 266 | } 267 | -------------------------------------------------------------------------------- /src/core/Stream.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Stream.cpp - adds parsing methods to Stream class 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 | Created July 2011 20 | parsing functions based on TextFinder library by Michael Margolis 21 | 22 | findMulti/findUntil routines written by Jim Leonard/Xuth 23 | */ 24 | 25 | #include "Arduino.h" 26 | #include "Stream.h" 27 | 28 | #define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait 29 | 30 | // private method to read stream with timeout 31 | int Stream::timedRead() 32 | { 33 | int c; 34 | _startMillis = millis(); 35 | do { 36 | c = read(); 37 | if (c >= 0) return c; 38 | } while(millis() - _startMillis < _timeout); 39 | return -1; // -1 indicates timeout 40 | } 41 | 42 | // private method to peek stream with timeout 43 | int Stream::timedPeek() 44 | { 45 | int c; 46 | _startMillis = millis(); 47 | do { 48 | c = peek(); 49 | if (c >= 0) return c; 50 | } while(millis() - _startMillis < _timeout); 51 | return -1; // -1 indicates timeout 52 | } 53 | 54 | // returns peek of the next digit in the stream or -1 if timeout 55 | // discards non-numeric characters 56 | int Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal) 57 | { 58 | int c; 59 | while (1) { 60 | c = timedPeek(); 61 | 62 | if( c < 0 || 63 | c == '-' || 64 | (c >= '0' && c <= '9') || 65 | (detectDecimal && c == '.')) return c; 66 | 67 | switch( lookahead ){ 68 | case SKIP_NONE: return -1; // Fail code. 69 | case SKIP_WHITESPACE: 70 | switch( c ){ 71 | case ' ': 72 | case '\t': 73 | case '\r': 74 | case '\n': break; 75 | default: return -1; // Fail code. 76 | } 77 | case SKIP_ALL: 78 | break; 79 | } 80 | read(); // discard non-numeric 81 | } 82 | } 83 | 84 | // Public Methods 85 | ////////////////////////////////////////////////////////////// 86 | 87 | void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait 88 | { 89 | _timeout = timeout; 90 | } 91 | 92 | // find returns true if the target string is found 93 | bool Stream::find(char *target) 94 | { 95 | return findUntil(target, strlen(target), NULL, 0); 96 | } 97 | 98 | // reads data from the stream until the target string of given length is found 99 | // returns true if target string is found, false if timed out 100 | bool Stream::find(char *target, size_t length) 101 | { 102 | return findUntil(target, length, NULL, 0); 103 | } 104 | 105 | // as find but search ends if the terminator string is found 106 | bool Stream::findUntil(char *target, char *terminator) 107 | { 108 | return findUntil(target, strlen(target), terminator, strlen(terminator)); 109 | } 110 | 111 | // reads data from the stream until the target string of the given length is found 112 | // search terminated if the terminator string is found 113 | // returns true if target string is found, false if terminated or timed out 114 | bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen) 115 | { 116 | if (terminator == NULL) { 117 | MultiTarget t[1] = {{target, targetLen, 0}}; 118 | return findMulti(t, 1) == 0 ? true : false; 119 | } else { 120 | MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}}; 121 | return findMulti(t, 2) == 0 ? true : false; 122 | } 123 | } 124 | 125 | // returns the first valid (long) integer value from the current position. 126 | // lookahead determines how parseInt looks ahead in the stream. 127 | // See LookaheadMode enumeration at the top of the file. 128 | // Lookahead is terminated by the first character that is not a valid part of an integer. 129 | // Once parsing commences, 'ignore' will be skipped in the stream. 130 | long Stream::parseInt(LookaheadMode lookahead, char ignore) 131 | { 132 | bool isNegative = false; 133 | long value = 0; 134 | int c; 135 | 136 | c = peekNextDigit(lookahead, false); 137 | // ignore non numeric leading characters 138 | if(c < 0) 139 | return 0; // zero returned if timeout 140 | 141 | do{ 142 | if(c == ignore) 143 | ; // ignore this character 144 | else if(c == '-') 145 | isNegative = true; 146 | else if(c >= '0' && c <= '9') // is c a digit? 147 | value = value * 10 + c - '0'; 148 | read(); // consume the character we got with peek 149 | c = timedPeek(); 150 | } 151 | while( (c >= '0' && c <= '9') || c == ignore ); 152 | 153 | if(isNegative) 154 | value = -value; 155 | return value; 156 | } 157 | 158 | // as parseInt but returns a floating point value 159 | float Stream::parseFloat(LookaheadMode lookahead, char ignore) 160 | { 161 | bool isNegative = false; 162 | bool isFraction = false; 163 | long value = 0; 164 | int c; 165 | float fraction = 1.0; 166 | 167 | c = peekNextDigit(lookahead, true); 168 | // ignore non numeric leading characters 169 | if(c < 0) 170 | return 0; // zero returned if timeout 171 | 172 | do{ 173 | if(c == ignore) 174 | ; // ignore 175 | else if(c == '-') 176 | isNegative = true; 177 | else if (c == '.') 178 | isFraction = true; 179 | else if(c >= '0' && c <= '9') { // is c a digit? 180 | value = value * 10 + c - '0'; 181 | if(isFraction) 182 | fraction *= 0.1; 183 | } 184 | read(); // consume the character we got with peek 185 | c = timedPeek(); 186 | } 187 | while( (c >= '0' && c <= '9') || (c == '.' && !isFraction) || c == ignore ); 188 | 189 | if(isNegative) 190 | value = -value; 191 | if(isFraction) 192 | return value * fraction; 193 | else 194 | return value; 195 | } 196 | 197 | // read characters from stream into buffer 198 | // terminates if length characters have been read, or timeout (see setTimeout) 199 | // returns the number of characters placed in the buffer 200 | // the buffer is NOT null terminated. 201 | // 202 | size_t Stream::readBytes(char *buffer, size_t length) 203 | { 204 | size_t count = 0; 205 | while (count < length) { 206 | int c = timedRead(); 207 | if (c < 0) break; 208 | *buffer++ = (char)c; 209 | count++; 210 | } 211 | return count; 212 | } 213 | 214 | 215 | // as readBytes with terminator character 216 | // terminates if length characters have been read, timeout, or if the terminator character detected 217 | // returns the number of characters placed in the buffer (0 means no valid data found) 218 | 219 | size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) 220 | { 221 | if (length < 1) return 0; 222 | size_t index = 0; 223 | while (index < length) { 224 | int c = timedRead(); 225 | if (c < 0 || c == terminator) break; 226 | *buffer++ = (char)c; 227 | index++; 228 | } 229 | return index; // return number of characters, not including null terminator 230 | } 231 | 232 | String Stream::readString() 233 | { 234 | String ret; 235 | int c = timedRead(); 236 | while (c >= 0) 237 | { 238 | ret += (char)c; 239 | c = timedRead(); 240 | } 241 | return ret; 242 | } 243 | 244 | String Stream::readStringUntil(char terminator) 245 | { 246 | String ret; 247 | int c = timedRead(); 248 | while (c >= 0 && c != terminator) 249 | { 250 | ret += (char)c; 251 | c = timedRead(); 252 | } 253 | return ret; 254 | } 255 | 256 | int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) { 257 | // any zero length target string automatically matches and would make 258 | // a mess of the rest of the algorithm. 259 | for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { 260 | if (t->len <= 0) 261 | return t - targets; 262 | } 263 | 264 | while (1) { 265 | int c = timedRead(); 266 | if (c < 0) 267 | return -1; 268 | 269 | for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { 270 | // the simple case is if we match, deal with that first. 271 | if (c == t->str[t->index]) { 272 | if (++t->index == t->len) 273 | return t - targets; 274 | else 275 | continue; 276 | } 277 | 278 | // if not we need to walk back and see if we could have matched further 279 | // down the stream (ie '1112' doesn't match the first position in '11112' 280 | // but it will match the second position so we can't just reset the current 281 | // index to 0 when we find a mismatch. 282 | if (t->index == 0) 283 | continue; 284 | 285 | int origIndex = t->index; 286 | do { 287 | --t->index; 288 | // first check if current char works against the new current index 289 | if (c != t->str[t->index]) 290 | continue; 291 | 292 | // if it's the only char then we're good, nothing more to check 293 | if (t->index == 0) { 294 | t->index++; 295 | break; 296 | } 297 | 298 | // otherwise we need to check the rest of the found string 299 | int diff = origIndex - t->index; 300 | size_t i; 301 | for (i = 0; i < t->index; ++i) { 302 | if (t->str[i] != t->str[i + diff]) 303 | break; 304 | } 305 | 306 | // if we successfully got through the previous loop then our current 307 | // index is good. 308 | if (i == t->index) { 309 | t->index++; 310 | break; 311 | } 312 | 313 | // otherwise we just try the next index 314 | } while (t->index); 315 | } 316 | } 317 | // unreachable 318 | return -1; 319 | } 320 | -------------------------------------------------------------------------------- /src/core/WInterrupts.c: -------------------------------------------------------------------------------- 1 | /* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2 | 3 | /* 4 | Part of the Wiring project - http://wiring.uniandes.edu.co 5 | 6 | Copyright (c) 2004-05 Hernando Barragan 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 | Modified 24 November 2006 by David A. Mellis 24 | Modified 1 August 2010 by Mark Sproul 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "wiring_private.h" 34 | 35 | static void nothing(void) { 36 | } 37 | 38 | static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS] = { 39 | #if EXTERNAL_NUM_INTERRUPTS > 8 40 | #warning There are more than 8 external interrupts. Some callbacks may not be initialized. 41 | nothing, 42 | #endif 43 | #if EXTERNAL_NUM_INTERRUPTS > 7 44 | nothing, 45 | #endif 46 | #if EXTERNAL_NUM_INTERRUPTS > 6 47 | nothing, 48 | #endif 49 | #if EXTERNAL_NUM_INTERRUPTS > 5 50 | nothing, 51 | #endif 52 | #if EXTERNAL_NUM_INTERRUPTS > 4 53 | nothing, 54 | #endif 55 | #if EXTERNAL_NUM_INTERRUPTS > 3 56 | nothing, 57 | #endif 58 | #if EXTERNAL_NUM_INTERRUPTS > 2 59 | nothing, 60 | #endif 61 | #if EXTERNAL_NUM_INTERRUPTS > 1 62 | nothing, 63 | #endif 64 | #if EXTERNAL_NUM_INTERRUPTS > 0 65 | nothing, 66 | #endif 67 | }; 68 | // volatile static voidFuncPtr twiIntFunc; 69 | 70 | void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) { 71 | if(interruptNum < EXTERNAL_NUM_INTERRUPTS) { 72 | intFunc[interruptNum] = userFunc; 73 | 74 | // Configure the interrupt mode (trigger on low input, any change, rising 75 | // edge, or falling edge). The mode constants were chosen to correspond 76 | // to the configuration bits in the hardware register, so we simply shift 77 | // the mode into place. 78 | 79 | // Enable the interrupt. 80 | 81 | switch (interruptNum) { 82 | #if defined(__AVR_ATmega32U4__) 83 | // I hate doing this, but the register assignment differs between the 1280/2560 84 | // and the 32U4. Since avrlib defines registers PCMSK1 and PCMSK2 that aren't 85 | // even present on the 32U4 this is the only way to distinguish between them. 86 | case 0: 87 | EICRA = (EICRA & ~((1<= 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/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/wiring.c: -------------------------------------------------------------------------------- 1 | /* 2 | wiring.c - Partial implementation of the Wiring API for the ATmega8. 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 | // the prescaler is set so that timer0 ticks every 64 clock cycles, and the 26 | // the overflow handler is called every 256 ticks. 27 | #define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256)) 28 | 29 | // the whole number of milliseconds per timer0 overflow 30 | #define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000) 31 | 32 | // the fractional number of milliseconds per timer0 overflow. we shift right 33 | // by three to fit these numbers into a byte. (for the clock speeds we care 34 | // about - 8 and 16 MHz - this doesn't lose precision.) 35 | #define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3) 36 | #define FRACT_MAX (1000 >> 3) 37 | 38 | volatile unsigned long timer0_overflow_count = 0; 39 | volatile unsigned long timer0_millis = 0; 40 | static unsigned char timer0_fract = 0; 41 | 42 | #if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) 43 | ISR(TIM0_OVF_vect) 44 | #else 45 | ISR(TIMER0_OVF_vect) 46 | #endif 47 | { 48 | // copy these to local variables so they can be stored in registers 49 | // (volatile variables must be read from memory on every access) 50 | unsigned long m = timer0_millis; 51 | unsigned char f = timer0_fract; 52 | 53 | m += MILLIS_INC; 54 | f += FRACT_INC; 55 | if (f >= FRACT_MAX) { 56 | f -= FRACT_MAX; 57 | m += 1; 58 | } 59 | 60 | timer0_fract = f; 61 | timer0_millis = m; 62 | timer0_overflow_count++; 63 | } 64 | 65 | unsigned long millis() 66 | { 67 | unsigned long m; 68 | uint8_t oldSREG = SREG; 69 | 70 | // disable interrupts while we read timer0_millis or we might get an 71 | // inconsistent value (e.g. in the middle of a write to timer0_millis) 72 | cli(); 73 | m = timer0_millis; 74 | SREG = oldSREG; 75 | 76 | return m; 77 | } 78 | 79 | unsigned long micros() { 80 | unsigned long m; 81 | uint8_t oldSREG = SREG, t; 82 | 83 | cli(); 84 | m = timer0_overflow_count; 85 | #if defined(TCNT0) 86 | t = TCNT0; 87 | #elif defined(TCNT0L) 88 | t = TCNT0L; 89 | #else 90 | #error TIMER 0 not defined 91 | #endif 92 | 93 | #ifdef TIFR0 94 | if ((TIFR0 & _BV(TOV0)) && (t < 255)) 95 | m++; 96 | #else 97 | if ((TIFR & _BV(TOV0)) && (t < 255)) 98 | m++; 99 | #endif 100 | 101 | SREG = oldSREG; 102 | 103 | return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond()); 104 | } 105 | 106 | void delay(unsigned long ms) 107 | { 108 | uint32_t start = micros(); 109 | 110 | while (ms > 0) { 111 | yield(); 112 | while ( ms > 0 && (micros() - start) >= 1000) { 113 | ms--; 114 | start += 1000; 115 | } 116 | } 117 | } 118 | 119 | /* Delay for the given number of microseconds. Assumes a 1, 8, 12, 16, 20 or 24 MHz clock. */ 120 | void delayMicroseconds(unsigned int us) 121 | { 122 | // call = 4 cycles + 2 to 4 cycles to init us(2 for constant delay, 4 for variable) 123 | 124 | // calling avrlib's delay_us() function with low values (e.g. 1 or 125 | // 2 microseconds) gives delays longer than desired. 126 | //delay_us(us); 127 | #if F_CPU >= 24000000L 128 | // for the 24 MHz clock for the aventurous ones, trying to overclock 129 | 130 | // zero delay fix 131 | if (!us) return; // = 3 cycles, (4 when true) 132 | 133 | // the following loop takes a 1/6 of a microsecond (4 cycles) 134 | // per iteration, so execute it six times for each microsecond of 135 | // delay requested. 136 | us *= 6; // x6 us, = 7 cycles 137 | 138 | // account for the time taken in the preceeding commands. 139 | // we just burned 22 (24) cycles above, remove 5, (5*4=20) 140 | // us is at least 6 so we can substract 5 141 | us -= 5; //=2 cycles 142 | 143 | #elif F_CPU >= 20000000L 144 | // for the 20 MHz clock on rare Arduino boards 145 | 146 | // for a one-microsecond delay, simply return. the overhead 147 | // of the function call takes 18 (20) cycles, which is 1us 148 | __asm__ __volatile__ ( 149 | "nop" "\n\t" 150 | "nop" "\n\t" 151 | "nop" "\n\t" 152 | "nop"); //just waiting 4 cycles 153 | if (us <= 1) return; // = 3 cycles, (4 when true) 154 | 155 | // the following loop takes a 1/5 of a microsecond (4 cycles) 156 | // per iteration, so execute it five times for each microsecond of 157 | // delay requested. 158 | us = (us << 2) + us; // x5 us, = 7 cycles 159 | 160 | // account for the time taken in the preceeding commands. 161 | // we just burned 26 (28) cycles above, remove 7, (7*4=28) 162 | // us is at least 10 so we can substract 7 163 | us -= 7; // 2 cycles 164 | 165 | #elif F_CPU >= 16000000L 166 | // for the 16 MHz clock on most Arduino boards 167 | 168 | // for a one-microsecond delay, simply return. the overhead 169 | // of the function call takes 14 (16) cycles, which is 1us 170 | if (us <= 1) return; // = 3 cycles, (4 when true) 171 | 172 | // the following loop takes 1/4 of a microsecond (4 cycles) 173 | // per iteration, so execute it four times for each microsecond of 174 | // delay requested. 175 | us <<= 2; // x4 us, = 4 cycles 176 | 177 | // account for the time taken in the preceeding commands. 178 | // we just burned 19 (21) cycles above, remove 5, (5*4=20) 179 | // us is at least 8 so we can substract 5 180 | us -= 5; // = 2 cycles, 181 | 182 | #elif F_CPU >= 12000000L 183 | // for the 12 MHz clock if somebody is working with USB 184 | 185 | // for a 1 microsecond delay, simply return. the overhead 186 | // of the function call takes 14 (16) cycles, which is 1.5us 187 | if (us <= 1) return; // = 3 cycles, (4 when true) 188 | 189 | // the following loop takes 1/3 of a microsecond (4 cycles) 190 | // per iteration, so execute it three times for each microsecond of 191 | // delay requested. 192 | us = (us << 1) + us; // x3 us, = 5 cycles 193 | 194 | // account for the time taken in the preceeding commands. 195 | // we just burned 20 (22) cycles above, remove 5, (5*4=20) 196 | // us is at least 6 so we can substract 5 197 | us -= 5; //2 cycles 198 | 199 | #elif F_CPU >= 8000000L 200 | // for the 8 MHz internal clock 201 | 202 | // for a 1 and 2 microsecond delay, simply return. the overhead 203 | // of the function call takes 14 (16) cycles, which is 2us 204 | if (us <= 2) return; // = 3 cycles, (4 when true) 205 | 206 | // the following loop takes 1/2 of a microsecond (4 cycles) 207 | // per iteration, so execute it twice for each microsecond of 208 | // delay requested. 209 | us <<= 1; //x2 us, = 2 cycles 210 | 211 | // account for the time taken in the preceeding commands. 212 | // we just burned 17 (19) cycles above, remove 4, (4*4=16) 213 | // us is at least 6 so we can substract 4 214 | us -= 4; // = 2 cycles 215 | 216 | #else 217 | // for the 1 MHz internal clock (default settings for common Atmega microcontrollers) 218 | 219 | // the overhead of the function calls is 14 (16) cycles 220 | if (us <= 16) return; //= 3 cycles, (4 when true) 221 | if (us <= 25) return; //= 3 cycles, (4 when true), (must be at least 25 if we want to substract 22) 222 | 223 | // compensate for the time taken by the preceeding and next commands (about 22 cycles) 224 | us -= 22; // = 2 cycles 225 | // the following loop takes 4 microseconds (4 cycles) 226 | // per iteration, so execute it us/4 times 227 | // us is at least 4, divided by 4 gives us 1 (no zero delay bug) 228 | us >>= 2; // us div 4, = 4 cycles 229 | 230 | 231 | #endif 232 | 233 | // busy wait 234 | __asm__ __volatile__ ( 235 | "1: sbiw %0,1" "\n\t" // 2 cycles 236 | "brne 1b" : "=w" (us) : "0" (us) // 2 cycles 237 | ); 238 | // return = 4 cycles 239 | } 240 | 241 | void init() 242 | { 243 | // this needs to be called before setup() or some functions won't 244 | // work there 245 | sei(); 246 | 247 | // on the ATmega168, timer 0 is also used for fast hardware pwm 248 | // (using phase-correct PWM would mean that timer 0 overflowed half as often 249 | // resulting in different millis() behavior on the ATmega8 and ATmega168) 250 | #if defined(TCCR0A) && defined(WGM01) 251 | sbi(TCCR0A, WGM01); 252 | sbi(TCCR0A, WGM00); 253 | #endif 254 | 255 | // set timer 0 prescale factor to 64 256 | #if defined(__AVR_ATmega128__) 257 | // CPU specific: different values for the ATmega128 258 | sbi(TCCR0, CS02); 259 | #elif defined(TCCR0) && defined(CS01) && defined(CS00) 260 | // this combination is for the standard atmega8 261 | sbi(TCCR0, CS01); 262 | sbi(TCCR0, CS00); 263 | #elif defined(TCCR0B) && defined(CS01) && defined(CS00) 264 | // this combination is for the standard 168/328/1280/2560 265 | sbi(TCCR0B, CS01); 266 | sbi(TCCR0B, CS00); 267 | #elif defined(TCCR0A) && defined(CS01) && defined(CS00) 268 | // this combination is for the __AVR_ATmega645__ series 269 | sbi(TCCR0A, CS01); 270 | sbi(TCCR0A, CS00); 271 | #else 272 | #error Timer 0 prescale factor 64 not set correctly 273 | #endif 274 | 275 | // enable timer 0 overflow interrupt 276 | #if defined(TIMSK) && defined(TOIE0) 277 | sbi(TIMSK, TOIE0); 278 | #elif defined(TIMSK0) && defined(TOIE0) 279 | sbi(TIMSK0, TOIE0); 280 | #else 281 | #error Timer 0 overflow interrupt not set correctly 282 | #endif 283 | 284 | // timers 1 and 2 are used for phase-correct hardware pwm 285 | // this is better for motors as it ensures an even waveform 286 | // note, however, that fast pwm mode can achieve a frequency of up 287 | // 8 MHz (with a 16 MHz clock) at 50% duty cycle 288 | 289 | #if defined(TCCR1B) && defined(CS11) && defined(CS10) 290 | TCCR1B = 0; 291 | 292 | // set timer 1 prescale factor to 64 293 | sbi(TCCR1B, CS11); 294 | #if F_CPU >= 8000000L 295 | sbi(TCCR1B, CS10); 296 | #endif 297 | #elif defined(TCCR1) && defined(CS11) && defined(CS10) 298 | sbi(TCCR1, CS11); 299 | #if F_CPU >= 8000000L 300 | sbi(TCCR1, CS10); 301 | #endif 302 | #endif 303 | // put timer 1 in 8-bit phase correct pwm mode 304 | #if defined(TCCR1A) && defined(WGM10) 305 | sbi(TCCR1A, WGM10); 306 | #endif 307 | 308 | // set timer 2 prescale factor to 64 309 | #if defined(TCCR2) && defined(CS22) 310 | sbi(TCCR2, CS22); 311 | #elif defined(TCCR2B) && defined(CS22) 312 | sbi(TCCR2B, CS22); 313 | //#else 314 | // Timer 2 not finished (may not be present on this CPU) 315 | #endif 316 | 317 | // configure timer 2 for phase correct pwm (8-bit) 318 | #if defined(TCCR2) && defined(WGM20) 319 | sbi(TCCR2, WGM20); 320 | #elif defined(TCCR2A) && defined(WGM20) 321 | sbi(TCCR2A, WGM20); 322 | //#else 323 | // Timer 2 not finished (may not be present on this CPU) 324 | #endif 325 | 326 | #if defined(TCCR3B) && defined(CS31) && defined(WGM30) 327 | sbi(TCCR3B, CS31); // set timer 3 prescale factor to 64 328 | sbi(TCCR3B, CS30); 329 | sbi(TCCR3A, WGM30); // put timer 3 in 8-bit phase correct pwm mode 330 | #endif 331 | 332 | #if defined(TCCR4A) && defined(TCCR4B) && defined(TCCR4D) /* beginning of timer4 block for 32U4 and similar */ 333 | sbi(TCCR4B, CS42); // set timer4 prescale factor to 64 334 | sbi(TCCR4B, CS41); 335 | sbi(TCCR4B, CS40); 336 | sbi(TCCR4D, WGM40); // put timer 4 in phase- and frequency-correct PWM mode 337 | sbi(TCCR4A, PWM4A); // enable PWM mode for comparator OCR4A 338 | sbi(TCCR4C, PWM4D); // enable PWM mode for comparator OCR4D 339 | #else /* beginning of timer4 block for ATMEGA1280 and ATMEGA2560 */ 340 | #if defined(TCCR4B) && defined(CS41) && defined(WGM40) 341 | sbi(TCCR4B, CS41); // set timer 4 prescale factor to 64 342 | sbi(TCCR4B, CS40); 343 | sbi(TCCR4A, WGM40); // put timer 4 in 8-bit phase correct pwm mode 344 | #endif 345 | #endif /* end timer4 block for ATMEGA1280/2560 and similar */ 346 | 347 | #if defined(TCCR5B) && defined(CS51) && defined(WGM50) 348 | sbi(TCCR5B, CS51); // set timer 5 prescale factor to 64 349 | sbi(TCCR5B, CS50); 350 | sbi(TCCR5A, WGM50); // put timer 5 in 8-bit phase correct pwm mode 351 | #endif 352 | 353 | #if defined(ADCSRA) 354 | // set a2d prescaler so we are inside the desired 50-200 KHz range. 355 | #if F_CPU >= 16000000 // 16 MHz / 128 = 125 KHz 356 | sbi(ADCSRA, ADPS2); 357 | sbi(ADCSRA, ADPS1); 358 | sbi(ADCSRA, ADPS0); 359 | #elif F_CPU >= 8000000 // 8 MHz / 64 = 125 KHz 360 | sbi(ADCSRA, ADPS2); 361 | sbi(ADCSRA, ADPS1); 362 | cbi(ADCSRA, ADPS0); 363 | #elif F_CPU >= 4000000 // 4 MHz / 32 = 125 KHz 364 | sbi(ADCSRA, ADPS2); 365 | cbi(ADCSRA, ADPS1); 366 | sbi(ADCSRA, ADPS0); 367 | #elif F_CPU >= 2000000 // 2 MHz / 16 = 125 KHz 368 | sbi(ADCSRA, ADPS2); 369 | cbi(ADCSRA, ADPS1); 370 | cbi(ADCSRA, ADPS0); 371 | #elif F_CPU >= 1000000 // 1 MHz / 8 = 125 KHz 372 | cbi(ADCSRA, ADPS2); 373 | sbi(ADCSRA, ADPS1); 374 | sbi(ADCSRA, ADPS0); 375 | #else // 128 kHz / 2 = 64 KHz -> This is the closest you can get, the prescaler is 2 376 | cbi(ADCSRA, ADPS2); 377 | cbi(ADCSRA, ADPS1); 378 | sbi(ADCSRA, ADPS0); 379 | #endif 380 | // enable a2d conversions 381 | sbi(ADCSRA, ADEN); 382 | #endif 383 | 384 | // the bootloader connects pins 0 and 1 to the USART; disconnect them 385 | // here so they can be used as normal digital i/o; they will be 386 | // reconnected in Serial.begin() 387 | #if defined(UCSRB) 388 | UCSRB = 0; 389 | #elif defined(UCSR0B) 390 | UCSR0B = 0; 391 | #endif 392 | } 393 | -------------------------------------------------------------------------------- /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 | #if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) 68 | ADMUX = (analog_reference << 4) | (pin & 0x07); 69 | #else 70 | ADMUX = (analog_reference << 6) | (pin & 0x07); 71 | #endif 72 | #endif 73 | 74 | // without a delay, we seem to read from the wrong channel 75 | //delay(1); 76 | 77 | #if defined(ADCSRA) && defined(ADCL) 78 | // start the conversion 79 | sbi(ADCSRA, ADSC); 80 | 81 | // ADSC is cleared when the conversion finishes 82 | while (bit_is_set(ADCSRA, ADSC)); 83 | 84 | // we have to read ADCL first; doing so locks both ADCL 85 | // and ADCH until ADCH is read. reading ADCL second would 86 | // cause the results of each conversion to be discarded, 87 | // as ADCL and ADCH would be locked when it completed. 88 | low = ADCL; 89 | high = ADCH; 90 | #else 91 | // we dont have an ADC, return 0 92 | low = 0; 93 | high = 0; 94 | #endif 95 | 96 | // combine the two bytes 97 | return (high << 8) | low; 98 | } 99 | 100 | // Right now, PWM output only works on the pins with 101 | // hardware support. These are defined in the appropriate 102 | // pins_*.c file. For the rest of the pins, we default 103 | // to digital output. 104 | void analogWrite(uint8_t pin, int val) 105 | { 106 | // We need to make sure the PWM output is enabled for those pins 107 | // that support it, as we turn it off when digitally reading or 108 | // writing with them. Also, make sure the pin is in output mode 109 | // for consistenty with Wiring, which doesn't require a pinMode 110 | // call for the analog output pins. 111 | pinMode(pin, OUTPUT); 112 | if (val == 0) 113 | { 114 | digitalWrite(pin, LOW); 115 | } 116 | else if (val == 255) 117 | { 118 | digitalWrite(pin, HIGH); 119 | } 120 | else 121 | { 122 | switch(digitalPinToTimer(pin)) 123 | { 124 | // XXX fix needed for atmega8 125 | #if defined(TCCR0) && defined(COM00) && !defined(__AVR_ATmega8__) 126 | case TIMER0A: 127 | // connect pwm to pin on timer 0 128 | sbi(TCCR0, COM00); 129 | OCR0 = val; // set pwm duty 130 | break; 131 | #endif 132 | 133 | #if defined(TCCR0A) && defined(COM0A1) 134 | case TIMER0A: 135 | // connect pwm to pin on timer 0, channel A 136 | sbi(TCCR0A, COM0A1); 137 | OCR0A = val; // set pwm duty 138 | break; 139 | #endif 140 | 141 | #if defined(TCCR0A) && defined(COM0B1) 142 | case TIMER0B: 143 | // connect pwm to pin on timer 0, channel B 144 | sbi(TCCR0A, COM0B1); 145 | OCR0B = val; // set pwm duty 146 | break; 147 | #endif 148 | 149 | #if defined(TCCR1A) && defined(COM1A1) 150 | case TIMER1A: 151 | // connect pwm to pin on timer 1, channel A 152 | sbi(TCCR1A, COM1A1); 153 | OCR1A = val; // set pwm duty 154 | break; 155 | #endif 156 | 157 | #if defined(TCCR1A) && defined(COM1B1) 158 | case TIMER1B: 159 | // connect pwm to pin on timer 1, channel B 160 | sbi(TCCR1A, COM1B1); 161 | OCR1B = val; // set pwm duty 162 | break; 163 | #endif 164 | 165 | #if defined(TCCR1A) && defined(COM1C1) 166 | case TIMER1C: 167 | // connect pwm to pin on timer 1, channel B 168 | sbi(TCCR1A, COM1C1); 169 | OCR1C = val; // set pwm duty 170 | break; 171 | #endif 172 | 173 | #if defined(TCCR2) && defined(COM21) 174 | case TIMER2: 175 | // connect pwm to pin on timer 2 176 | sbi(TCCR2, COM21); 177 | OCR2 = val; // set pwm duty 178 | break; 179 | #endif 180 | 181 | #if defined(TCCR2A) && defined(COM2A1) 182 | case TIMER2A: 183 | // connect pwm to pin on timer 2, channel A 184 | sbi(TCCR2A, COM2A1); 185 | OCR2A = val; // set pwm duty 186 | break; 187 | #endif 188 | 189 | #if defined(TCCR2A) && defined(COM2B1) 190 | case TIMER2B: 191 | // connect pwm to pin on timer 2, channel B 192 | sbi(TCCR2A, COM2B1); 193 | OCR2B = val; // set pwm duty 194 | break; 195 | #endif 196 | 197 | #if defined(TCCR3A) && defined(COM3A1) 198 | case TIMER3A: 199 | // connect pwm to pin on timer 3, channel A 200 | sbi(TCCR3A, COM3A1); 201 | OCR3A = val; // set pwm duty 202 | break; 203 | #endif 204 | 205 | #if defined(TCCR3A) && defined(COM3B1) 206 | case TIMER3B: 207 | // connect pwm to pin on timer 3, channel B 208 | sbi(TCCR3A, COM3B1); 209 | OCR3B = val; // set pwm duty 210 | break; 211 | #endif 212 | 213 | #if defined(TCCR3A) && defined(COM3C1) 214 | case TIMER3C: 215 | // connect pwm to pin on timer 3, channel C 216 | sbi(TCCR3A, COM3C1); 217 | OCR3C = val; // set pwm duty 218 | break; 219 | #endif 220 | 221 | #if defined(TCCR4A) 222 | case TIMER4A: 223 | //connect pwm to pin on timer 4, channel A 224 | sbi(TCCR4A, COM4A1); 225 | #if defined(COM4A0) // only used on 32U4 226 | cbi(TCCR4A, COM4A0); 227 | #endif 228 | OCR4A = val; // set pwm duty 229 | break; 230 | #endif 231 | 232 | #if defined(TCCR4A) && defined(COM4B1) 233 | case TIMER4B: 234 | // connect pwm to pin on timer 4, channel B 235 | sbi(TCCR4A, COM4B1); 236 | OCR4B = val; // set pwm duty 237 | break; 238 | #endif 239 | 240 | #if defined(TCCR4A) && defined(COM4C1) 241 | case TIMER4C: 242 | // connect pwm to pin on timer 4, channel C 243 | sbi(TCCR4A, COM4C1); 244 | OCR4C = val; // set pwm duty 245 | break; 246 | #endif 247 | 248 | #if defined(TCCR4C) && defined(COM4D1) 249 | case TIMER4D: 250 | // connect pwm to pin on timer 4, channel D 251 | sbi(TCCR4C, COM4D1); 252 | #if defined(COM4D0) // only used on 32U4 253 | cbi(TCCR4C, COM4D0); 254 | #endif 255 | OCR4D = val; // set pwm duty 256 | break; 257 | #endif 258 | 259 | 260 | #if defined(TCCR5A) && defined(COM5A1) 261 | case TIMER5A: 262 | // connect pwm to pin on timer 5, channel A 263 | sbi(TCCR5A, COM5A1); 264 | OCR5A = val; // set pwm duty 265 | break; 266 | #endif 267 | 268 | #if defined(TCCR5A) && defined(COM5B1) 269 | case TIMER5B: 270 | // connect pwm to pin on timer 5, channel B 271 | sbi(TCCR5A, COM5B1); 272 | OCR5B = val; // set pwm duty 273 | break; 274 | #endif 275 | 276 | #if defined(TCCR5A) && defined(COM5C1) 277 | case TIMER5C: 278 | // connect pwm to pin on timer 5, channel C 279 | sbi(TCCR5A, COM5C1); 280 | OCR5C = val; // set pwm duty 281 | break; 282 | #endif 283 | 284 | case NOT_ON_TIMER: 285 | default: 286 | if (val < 128) { 287 | digitalWrite(pin, LOW); 288 | } else { 289 | digitalWrite(pin, HIGH); 290 | } 291 | } 292 | } 293 | } 294 | 295 | -------------------------------------------------------------------------------- /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_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 | --------------------------------------------------------------------------------