Skip to content

Commit c31fe0d

Browse files
committed
add constant checks, fix analogRead ADMUX setting
1 parent a307c8a commit c31fe0d

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

avr/cores/picocore/Arduino.h

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ void loop();
2929

3030
uint32_t millis();
3131

32+
void badArg(const char*) __attribute((error("")));
33+
34+
#define ASSERT_CONST(pin) \
35+
if (!__builtin_constant_p(pin)) \
36+
badArg("pin must be a constant");
37+
3238
extern inline void delayMicroseconds(uint16_t us)
3339
{
3440
_delay_us(us);
@@ -50,7 +56,8 @@ enum _pin_mode {
5056
};
5157

5258
extern inline void pinMode(uint8_t pin, _pin_mode mode)
53-
{
59+
{
60+
ASSERT_CONST(pin);
5461
if (mode == OUTPUT) DDRB |= (1<<pin);
5562
else {
5663
DDRB &= ~(1<<pin);
@@ -60,6 +67,12 @@ extern inline void pinMode(uint8_t pin, _pin_mode mode)
6067

6168
extern inline void digitalWrite(uint8_t pin, uint8_t val)
6269
{
70+
if (__builtin_constant_p(pin)) {
71+
if (pin > 5) badArg("pin out of range");
72+
} else {
73+
badArg("pin must be a constant");
74+
}
75+
6376
if (val)
6477
PORTB |= (1<<pin);
6578
else
@@ -71,8 +84,6 @@ extern inline uint8_t digitalRead(uint8_t pin)
7184
return (PINB & (1<<pin)) ? HIGH : LOW;
7285
}
7386

74-
void badArg(const char*) __attribute((error("")));
75-
7687
// PWM supported on PB0/OCOA & PB1/OC0B
7788
inline void analogWrite(uint8_t pin, uint8_t count)
7889
{
@@ -92,12 +103,12 @@ inline void analogWrite(uint8_t pin, uint8_t count)
92103
if (pin == 0)
93104
{
94105
TCCR0A |= FastPWM | (1 << COM0A1);
95-
OCR0A = count;
106+
OCR0A = count;
96107
}
97108
else
98109
{
99110
TCCR0A |= FastPWM | (1 << COM0B1);
100-
OCR0B = count;
111+
OCR0B = count;
101112
}
102113
}
103114

@@ -113,7 +124,8 @@ inline void analogReference(_analog_ref ref)
113124
enum _analog_pin { A0 = 0, A1, A2, A3, BAD_ANALOG_PIN };
114125

115126
// 9 instr / 18B compiled
116-
__attribute((noinline))
127+
// try extern inline instead of always_inline?
128+
__attribute((always_inline))
117129
inline int analogRead(_analog_pin pin)
118130
{
119131
if (__builtin_constant_p(pin)) {
@@ -123,7 +135,7 @@ inline int analogRead(_analog_pin pin)
123135
}
124136

125137
// MUX1 & MUX0 are 2 lowest bits in ADMUX
126-
ADMUX |= pin;
138+
ADMUX = (ADMUX & 0xFC) | pin;
127139

128140
// start ADC with /32 prescaler
129141
ADCSRA = (1 << ADPS2) | (1 << ADPS0) | (1 << ADSC) | (1 << ADEN);

0 commit comments

Comments
 (0)