Skip to content

Commit d3de30e

Browse files
authored
Merge pull request #18 from bcmi-labs/UNOCompatibility
Uno compatibility
2 parents 038713f + 235150e commit d3de30e

File tree

4 files changed

+320
-4
lines changed

4 files changed

+320
-4
lines changed

Diff for: boards.txt

+4
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,8 @@ uno2018.build.core=arduino
2020
uno2018.build.variant=uno2018
2121
#uno2018.build.extra_flags=-B{runtime.tools.atpack.path}/gcc/dev/{build.mcu}
2222

23+
menu.mode=Registers emulation
24+
uno2018.menu.mode.on=ATMEGA328
25+
uno2018.menu.mode.on.build.extra_flags=-DUNO_WIFI_REV2_328MODE
26+
uno2018.menu.mode.off=None (ATMEGA4809)
2327
##############################################################

Diff for: cores/arduino/Arduino.h

+5-4
Original file line numberDiff line numberDiff line change
@@ -125,14 +125,13 @@ bool isDoubleBondedActive(uint8_t pin);
125125
#define analogPinToBitMask(pin) ( (pin < NUM_ANALOG_INPUTS) ? (1 << analogPinToBitPosition(pin)) : NOT_A_PIN )
126126
#define digitalPinToTimer(pin) ( (pin < NUM_TOTAL_PINS) ? pgm_read_byte(digital_pin_to_timer + pin) : NOT_ON_TIMER )
127127

128-
#define portInputRegister(port) ( &(((PORT_t*)(&PORTA + port))->IN) )
129-
130128
#define portToPortStruct(port) ( (port < NUM_TOTAL_PORTS) ? ((PORT_t *)&PORTA + port) : NULL)
131129
#define digitalPinToPortStruct(pin) ( (pin < NUM_TOTAL_PINS) ? ((PORT_t *)&PORTA + digitalPinToPort(pin)) : NULL)
132-
#define getPINnCTRLregister(port, bit_pos) ( ((port != NULL) && (bit_pos < NOT_A_PIN)) ? ((uint8_t *)&(port->PIN0CTRL) + bit_pos) : NULL )
130+
#define getPINnCTRLregister(port, bit_pos) ( ((port != NULL) && (bit_pos < NOT_A_PIN)) ? ((volatile uint8_t *)&(port->PIN0CTRL) + bit_pos) : NULL )
133131
#define digitalPinToInterrupt(p) ( digitalPinToPort(p) * 8 + digitalPinToBitPosition(p) )
134132

135133
#define portOutputRegister(P) ( (volatile uint8_t *)( &portToPortStruct(P)->OUT ) )
134+
#define portInputRegister(P) ( (volatile uint8_t *)( &portToPortStruct(P)->IN ) )
136135

137136
#ifdef __cplusplus
138137
} // extern "C"
@@ -143,12 +142,14 @@ bool isDoubleBondedActive(uint8_t pin);
143142
#include "USBCore.h"
144143
#include "CDC.h"
145144
#include "MSC.h"
145+
#ifdef UNO_WIFI_REV2_328MODE
146+
#include <UNO_compat.h>
147+
#endif
146148
#if defined(HAVE_HWSERIAL0) && defined(HAVE_CDCSERIAL)
147149
#error "Targets with both UART0 and CDC serial not supported"
148150
#endif
149151

150152
#endif
151153

152154
#include "pins_arduino.h"
153-
154155
#endif

Diff for: cores/arduino/UNO_compat.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
Copyright (c) 2018 Arduino Team. All right reserved.
3+
This library is free software; you can redistribute it and/or
4+
modify it under the terms of the GNU Lesser General Public
5+
License as published by the Free Software Foundation; either
6+
version 2.1 of the License, or (at your option) any later version.
7+
This library is distributed in the hope that it will be useful,
8+
but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10+
Lesser General Public License for more details.
11+
You should have received a copy of the GNU Lesser General Public
12+
License along with this library; if not, write to the Free Software
13+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14+
*/
15+
16+
#include "UNO_compat.h"
17+
18+
PORTBClass PORTB;
19+
PORTCClass PORTC;
20+
PORTDClass PORTD;
21+
22+
DDRBClass DDRB;
23+
DDRCClass DDRC;
24+
DDRDClass DDRD;

Diff for: cores/arduino/UNO_compat.h

+287
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
1+
/*
2+
Copyright (c) 2018 Arduino Team. All right reserved.
3+
This library is free software; you can redistribute it and/or
4+
modify it under the terms of the GNU Lesser General Public
5+
License as published by the Free Software Foundation; either
6+
version 2.1 of the License, or (at your option) any later version.
7+
This library is distributed in the hope that it will be useful,
8+
but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10+
Lesser General Public License for more details.
11+
You should have received a copy of the GNU Lesser General Public
12+
License along with this library; if not, write to the Free Software
13+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14+
*/
15+
16+
#pragma once
17+
#include "Arduino.h"
18+
19+
#warning "ATMEGA328 registers emulation is enabled. You may encounter some speed issue. Please consider to disable it in the Tools menu"
20+
21+
/*
22+
ARDUINO PIN ATMEGA 328 ATMEGA 4809
23+
0 PD0 PC5
24+
1 PD1 PC4
25+
2 PD2 PA0
26+
3 PD3 PF5
27+
4 PD4 PC6
28+
5 PD5 PB2
29+
6 PD6 PF4
30+
7 PD7 PA1
31+
8 PB0 PE3
32+
9 PB1 PB0
33+
10 PB2 PB1
34+
11 PB3 PE0
35+
12 PB4 PE1
36+
13 PB5 PE2
37+
A0 PC0 PD0
38+
A1 PC1 PD1
39+
A2 PC2 PD2
40+
A3 PC3 PD3
41+
A4 PC4 PD4
42+
A5 PC5 PD5
43+
*/
44+
45+
#define PORTA_ARDUINO (*(PORT_t *) 0x0400) /* I/O Ports */
46+
#define PORTB_ARDUINO (*(PORT_t *) 0x0420) /* I/O Ports */
47+
#define PORTC_ARDUINO (*(PORT_t *) 0x0440) /* I/O Ports */
48+
#define PORTD_ARDUINO (*(PORT_t *) 0x0460) /* I/O Ports */
49+
#define PORTE_ARDUINO (*(PORT_t *) 0x0480) /* I/O Ports */
50+
#define PORTF_ARDUINO (*(PORT_t *) 0x04A0) /* I/O Ports */
51+
52+
#undef PORTB
53+
#undef PORTC
54+
#undef PORTD
55+
56+
#define SET_PORT_REGISTER(inPosition, port, position) if ((1 << inPosition) & (uint8_t)value) { port.OUTSET = (1 << position);}
57+
#define CLEAR_PORT_REGISTER(inPosition, port, position) if ((uint8_t)~(1 << inPosition) == (uint8_t)value) { port.OUTCLR = (1 << position);}
58+
#define SET_OR_CLEAR_PORT_REGISTER(inPosition, port, position) if ((uint8_t)~(1 << inPosition) & (uint8_t)value) { port.OUTSET = (1 << position); } else {port.OUTCLR = (1 << position); }
59+
60+
#define SET_DIR_REGISTER(inPosition, port, position) if ((1 << inPosition) & (uint8_t)value) { port.DIRSET = (1 << position);}
61+
#define CLEAR_DIR_REGISTER(inPosition, port, position) if ((uint8_t)~(1 << inPosition) == (uint8_t)value) { port.DIRCLR = (1 << position);}
62+
#define SET_OR_CLEAR_DIR_REGISTER(inPosition, port, position) if ((uint8_t)~(1 << inPosition) & (uint8_t)value) { port.DIRSET = (1 << position); } else {port.DIRCLR = (1 << position); }
63+
64+
65+
/** DDR Classes**/
66+
class DDRBClass {
67+
public:
68+
DDRBClass() {}
69+
DDRBClass& operator=(uint8_t value) {
70+
SET_OR_CLEAR_DIR_REGISTER(0, PORTE_ARDUINO, 3);
71+
SET_OR_CLEAR_DIR_REGISTER(1, PORTB_ARDUINO, 0);
72+
SET_OR_CLEAR_DIR_REGISTER(2, PORTB_ARDUINO, 1);
73+
SET_OR_CLEAR_DIR_REGISTER(3, PORTE_ARDUINO, 0);
74+
SET_OR_CLEAR_DIR_REGISTER(4, PORTE_ARDUINO, 1);
75+
SET_OR_CLEAR_DIR_REGISTER(5, PORTE_ARDUINO, 2);
76+
return *this;
77+
}
78+
79+
DDRBClass& operator&=(uint8_t value) {
80+
CLEAR_DIR_REGISTER(0, PORTE_ARDUINO, 3);
81+
CLEAR_DIR_REGISTER(1, PORTB_ARDUINO, 0);
82+
CLEAR_DIR_REGISTER(2, PORTB_ARDUINO, 1);
83+
CLEAR_DIR_REGISTER(3, PORTE_ARDUINO, 0);
84+
CLEAR_DIR_REGISTER(4, PORTE_ARDUINO, 1);
85+
CLEAR_DIR_REGISTER(5, PORTE_ARDUINO, 2);
86+
return *this;
87+
}
88+
89+
DDRBClass& operator|=(uint8_t value) {
90+
SET_DIR_REGISTER(0, PORTE_ARDUINO, 3);
91+
SET_DIR_REGISTER(1, PORTB_ARDUINO, 0);
92+
SET_DIR_REGISTER(2, PORTB_ARDUINO, 1);
93+
SET_DIR_REGISTER(3, PORTE_ARDUINO, 0);
94+
SET_DIR_REGISTER(4, PORTE_ARDUINO, 1);
95+
SET_DIR_REGISTER(5, PORTE_ARDUINO, 2);
96+
return *this;
97+
}
98+
};
99+
100+
class DDRCClass {
101+
public:
102+
DDRCClass() {}
103+
DDRCClass& operator=(uint8_t value) {
104+
SET_OR_CLEAR_DIR_REGISTER(0, PORTD_ARDUINO, 0);
105+
SET_OR_CLEAR_DIR_REGISTER(1, PORTD_ARDUINO, 1);
106+
SET_OR_CLEAR_DIR_REGISTER(2, PORTD_ARDUINO, 2);
107+
SET_OR_CLEAR_DIR_REGISTER(3, PORTD_ARDUINO, 3);
108+
SET_OR_CLEAR_DIR_REGISTER(4, PORTD_ARDUINO, 4);
109+
SET_OR_CLEAR_DIR_REGISTER(5, PORTD_ARDUINO, 5);
110+
return *this;
111+
}
112+
113+
DDRCClass& operator&=(uint8_t value) {
114+
CLEAR_DIR_REGISTER(0, PORTD_ARDUINO, 0);
115+
CLEAR_DIR_REGISTER(1, PORTD_ARDUINO, 1);
116+
CLEAR_DIR_REGISTER(2, PORTD_ARDUINO, 2);
117+
CLEAR_DIR_REGISTER(3, PORTD_ARDUINO, 3);
118+
CLEAR_DIR_REGISTER(4, PORTD_ARDUINO, 4);
119+
CLEAR_DIR_REGISTER(5, PORTD_ARDUINO, 5);
120+
return *this;
121+
}
122+
123+
DDRCClass& operator|=(uint8_t value) {
124+
SET_DIR_REGISTER(0, PORTD_ARDUINO, 0);
125+
SET_DIR_REGISTER(1, PORTD_ARDUINO, 1);
126+
SET_DIR_REGISTER(2, PORTD_ARDUINO, 2);
127+
SET_DIR_REGISTER(3, PORTD_ARDUINO, 3);
128+
SET_DIR_REGISTER(4, PORTD_ARDUINO, 4);
129+
SET_DIR_REGISTER(5, PORTD_ARDUINO, 5);
130+
return *this;
131+
}
132+
};
133+
134+
class DDRDClass {
135+
public:
136+
DDRDClass() {}
137+
DDRDClass& operator=(uint8_t value) {
138+
SET_OR_CLEAR_DIR_REGISTER(0, PORTC_ARDUINO, 5);
139+
SET_OR_CLEAR_DIR_REGISTER(1, PORTC_ARDUINO, 4);
140+
SET_OR_CLEAR_DIR_REGISTER(2, PORTA_ARDUINO, 0);
141+
SET_OR_CLEAR_DIR_REGISTER(3, PORTF_ARDUINO, 5);
142+
SET_OR_CLEAR_DIR_REGISTER(4, PORTC_ARDUINO, 6);
143+
SET_OR_CLEAR_DIR_REGISTER(5, PORTB_ARDUINO, 2);
144+
SET_OR_CLEAR_DIR_REGISTER(6, PORTF_ARDUINO, 4);
145+
SET_OR_CLEAR_DIR_REGISTER(7, PORTA_ARDUINO, 1);
146+
return *this;
147+
}
148+
149+
DDRDClass& operator&=(uint8_t value) {
150+
CLEAR_DIR_REGISTER(0, PORTC_ARDUINO, 5);
151+
CLEAR_DIR_REGISTER(1, PORTC_ARDUINO, 4);
152+
CLEAR_DIR_REGISTER(2, PORTA_ARDUINO, 0);
153+
CLEAR_DIR_REGISTER(3, PORTF_ARDUINO, 5);
154+
CLEAR_DIR_REGISTER(4, PORTC_ARDUINO, 6);
155+
CLEAR_DIR_REGISTER(5, PORTB_ARDUINO, 2);
156+
CLEAR_DIR_REGISTER(6, PORTF_ARDUINO, 4);
157+
CLEAR_DIR_REGISTER(7, PORTA_ARDUINO, 1);
158+
return *this;
159+
}
160+
161+
DDRDClass& operator|=(uint8_t value) {
162+
SET_DIR_REGISTER(0, PORTC_ARDUINO, 5);
163+
SET_DIR_REGISTER(1, PORTC_ARDUINO, 4);
164+
SET_DIR_REGISTER(2, PORTA_ARDUINO, 0);
165+
SET_DIR_REGISTER(3, PORTF_ARDUINO, 5);
166+
SET_DIR_REGISTER(4, PORTC_ARDUINO, 6);
167+
SET_DIR_REGISTER(5, PORTB_ARDUINO, 2);
168+
SET_DIR_REGISTER(6, PORTF_ARDUINO, 4);
169+
SET_DIR_REGISTER(7, PORTA_ARDUINO, 1);
170+
return *this;
171+
}
172+
};
173+
/** PORT Classes**/
174+
class PORTBClass {
175+
public:
176+
PORTBClass() {}
177+
PORTBClass& operator=(uint8_t value) {
178+
SET_OR_CLEAR_PORT_REGISTER(0, PORTE_ARDUINO, 3);
179+
SET_OR_CLEAR_PORT_REGISTER(1, PORTB_ARDUINO, 0);
180+
SET_OR_CLEAR_PORT_REGISTER(2, PORTB_ARDUINO, 1);
181+
SET_OR_CLEAR_PORT_REGISTER(3, PORTE_ARDUINO, 0);
182+
SET_OR_CLEAR_PORT_REGISTER(4, PORTE_ARDUINO, 1);
183+
SET_OR_CLEAR_PORT_REGISTER(5, PORTE_ARDUINO, 2);
184+
return *this;
185+
}
186+
187+
PORTBClass& operator&=(uint8_t value) {
188+
CLEAR_PORT_REGISTER(0, PORTE_ARDUINO, 3);
189+
CLEAR_PORT_REGISTER(1, PORTB_ARDUINO, 0);
190+
CLEAR_PORT_REGISTER(2, PORTB_ARDUINO, 1);
191+
CLEAR_PORT_REGISTER(3, PORTE_ARDUINO, 0);
192+
CLEAR_PORT_REGISTER(4, PORTE_ARDUINO, 1);
193+
CLEAR_PORT_REGISTER(5, PORTE_ARDUINO, 2);
194+
return *this;
195+
}
196+
197+
PORTBClass& operator|=(uint8_t value) {
198+
SET_PORT_REGISTER(0, PORTE_ARDUINO, 3);
199+
SET_PORT_REGISTER(1, PORTB_ARDUINO, 0);
200+
SET_PORT_REGISTER(2, PORTB_ARDUINO, 1);
201+
SET_PORT_REGISTER(3, PORTE_ARDUINO, 0);
202+
SET_PORT_REGISTER(4, PORTE_ARDUINO, 1);
203+
SET_PORT_REGISTER(5, PORTE_ARDUINO, 2);
204+
return *this;
205+
}
206+
};
207+
208+
class PORTCClass {
209+
public:
210+
PORTCClass() {}
211+
PORTCClass& operator=(uint8_t value) {
212+
SET_OR_CLEAR_PORT_REGISTER(0, PORTD_ARDUINO, 0);
213+
SET_OR_CLEAR_PORT_REGISTER(1, PORTD_ARDUINO, 1);
214+
SET_OR_CLEAR_PORT_REGISTER(2, PORTD_ARDUINO, 2);
215+
SET_OR_CLEAR_PORT_REGISTER(3, PORTD_ARDUINO, 3);
216+
SET_OR_CLEAR_PORT_REGISTER(4, PORTD_ARDUINO, 4);
217+
SET_OR_CLEAR_PORT_REGISTER(5, PORTD_ARDUINO, 5);
218+
return *this;
219+
}
220+
221+
PORTCClass& operator&=(uint8_t value) {
222+
CLEAR_PORT_REGISTER(0, PORTD_ARDUINO, 0);
223+
CLEAR_PORT_REGISTER(1, PORTD_ARDUINO, 1);
224+
CLEAR_PORT_REGISTER(2, PORTD_ARDUINO, 2);
225+
CLEAR_PORT_REGISTER(3, PORTD_ARDUINO, 3);
226+
CLEAR_PORT_REGISTER(4, PORTD_ARDUINO, 4);
227+
CLEAR_PORT_REGISTER(5, PORTD_ARDUINO, 5);
228+
return *this;
229+
}
230+
231+
PORTCClass& operator|=(uint8_t value) {
232+
SET_PORT_REGISTER(0, PORTD_ARDUINO, 0);
233+
SET_PORT_REGISTER(1, PORTD_ARDUINO, 1);
234+
SET_PORT_REGISTER(2, PORTD_ARDUINO, 2);
235+
SET_PORT_REGISTER(3, PORTD_ARDUINO, 3);
236+
SET_PORT_REGISTER(4, PORTD_ARDUINO, 4);
237+
SET_PORT_REGISTER(5, PORTD_ARDUINO, 5);
238+
return *this;
239+
}
240+
};
241+
242+
class PORTDClass {
243+
public:
244+
PORTDClass() {}
245+
PORTDClass& operator=(uint8_t value) {
246+
SET_OR_CLEAR_PORT_REGISTER(0, PORTC_ARDUINO, 5);
247+
SET_OR_CLEAR_PORT_REGISTER(1, PORTC_ARDUINO, 4);
248+
SET_OR_CLEAR_PORT_REGISTER(2, PORTA_ARDUINO, 0);
249+
SET_OR_CLEAR_PORT_REGISTER(3, PORTF_ARDUINO, 5);
250+
SET_OR_CLEAR_PORT_REGISTER(4, PORTC_ARDUINO, 6);
251+
SET_OR_CLEAR_PORT_REGISTER(5, PORTB_ARDUINO, 2);
252+
SET_OR_CLEAR_PORT_REGISTER(6, PORTF_ARDUINO, 4);
253+
SET_OR_CLEAR_PORT_REGISTER(7, PORTA_ARDUINO, 1);
254+
return *this;
255+
}
256+
257+
PORTDClass& operator&=(uint8_t value) {
258+
CLEAR_PORT_REGISTER(0, PORTC_ARDUINO, 5);
259+
CLEAR_PORT_REGISTER(1, PORTC_ARDUINO, 4);
260+
CLEAR_PORT_REGISTER(2, PORTA_ARDUINO, 0);
261+
CLEAR_PORT_REGISTER(3, PORTF_ARDUINO, 5);
262+
CLEAR_PORT_REGISTER(4, PORTC_ARDUINO, 6);
263+
CLEAR_PORT_REGISTER(5, PORTB_ARDUINO, 2);
264+
CLEAR_PORT_REGISTER(6, PORTF_ARDUINO, 4);
265+
CLEAR_PORT_REGISTER(7, PORTA_ARDUINO, 1);
266+
return *this;
267+
}
268+
269+
PORTDClass& operator|=(uint8_t value) {
270+
SET_PORT_REGISTER(0, PORTC_ARDUINO, 5);
271+
SET_PORT_REGISTER(1, PORTC_ARDUINO, 4);
272+
SET_PORT_REGISTER(2, PORTA_ARDUINO, 0);
273+
SET_PORT_REGISTER(3, PORTF_ARDUINO, 5);
274+
SET_PORT_REGISTER(4, PORTC_ARDUINO, 6);
275+
SET_PORT_REGISTER(5, PORTB_ARDUINO, 2);
276+
SET_PORT_REGISTER(6, PORTF_ARDUINO, 4);
277+
SET_PORT_REGISTER(7, PORTA_ARDUINO, 1);
278+
return *this;
279+
}
280+
};
281+
282+
extern PORTBClass PORTB;
283+
extern PORTCClass PORTC;
284+
extern PORTDClass PORTD;
285+
extern DDRBClass DDRB;
286+
extern DDRCClass DDRC;
287+
extern DDRDClass DDRD;

0 commit comments

Comments
 (0)