├── .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 | 
5 |
6 | 
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 |
--------------------------------------------------------------------------------