Skip to content

Commit 0222c3f

Browse files
committed
tweak pinMode code
1 parent cdae1ac commit 0222c3f

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=ArduinoShrink
2-
version=0.7.0
2+
version=0.7.1
33
author=Ralph Doncaster
44
maintainer=
55
sentence=

src/as_wdigital.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// (c) Ralph Doncaster 2020
2+
// thanks to Bill W for inspiration
3+
// github.com/WestfW/Duino-hacks/blob/master/fastdigitalIO/fastdigitalIO.h
4+
// 20200709 v0.1.0 release
5+
// 20200410 alias _to_xxx_PGM[] arrays as __flash for runtime pin manipulation
6+
7+
#include <stdint.h>
8+
#include <avr/io.h>
9+
10+
// todo: use constants.h from PicoCore
11+
enum {LOW, HIGH}; // for digitalWrite()
12+
enum {INPUT, OUTPUT, INPUT_PULLUP}; // for pinMode()
13+
14+
extern __flash const uint16_t port_to_output_PGM[];
15+
extern __flash const uint8_t digital_pin_to_port_PGM[];
16+
extern __flash const uint8_t digital_pin_to_bit_mask_PGM[];
17+
18+
typedef volatile uint8_t* ioreg_p;
19+
20+
#define ALWAYS_INLINE __attribute__((always_inline)) inline
21+
22+
ALWAYS_INLINE ioreg_p pin_to_port(uint8_t pin)
23+
{
24+
// use pointer instead of array operators due to avr-gcc bug:
25+
// https://www.avrfreaks.net/forum/avr-gcc-have-i-told-you-lately-i-hate-you
26+
//return (ioreg_p) port_to_output_PGM[digital_pin_to_port_PGM[pin]];
27+
return (ioreg_p) *(port_to_output_PGM + *(digital_pin_to_port_PGM +pin));
28+
}
29+
30+
ALWAYS_INLINE ioreg_p pin_to_ddr(uint8_t pin)
31+
{
32+
// DDR address is 1 less than PORT address
33+
return pin_to_port(pin) - 1;
34+
}
35+
36+
ALWAYS_INLINE ioreg_p pin_to_pinreg(uint8_t pin)
37+
{
38+
// PIN address is 2 less than PORT address
39+
return pin_to_port(pin) - 2;
40+
}
41+
42+
ALWAYS_INLINE uint8_t pin_to_bit(uint8_t pin)
43+
{
44+
//return digital_pin_to_bit_mask_PGM[pin];
45+
return *(digital_pin_to_bit_mask_PGM + pin);
46+
}
47+
48+
void pinMode(uint8_t pin, uint8_t mode)
49+
{
50+
ioreg_p ddr = pin_to_ddr(pin);
51+
uint8_t bit = pin_to_bit(pin);
52+
if (mode == OUTPUT)
53+
*ddr|= bit;
54+
else {
55+
*ddr &= ~bit;
56+
if (mode == INPUT_PULLUP) *pin_to_port(pin) |= bit;
57+
}
58+
}
59+
60+
void digitalWrite(uint8_t pin, uint8_t val)
61+
{
62+
ioreg_p port = pin_to_ddr(pin);
63+
uint8_t bit = pin_to_bit(pin);
64+
if (val == LOW)
65+
*port &= ~bit;
66+
else // HIGH
67+
*port |= bit;
68+
}
69+
70+
int digitalRead(uint8_t pin)
71+
{
72+
return (*pin_to_pinreg(pin) & pin_to_bit(pin)) ? HIGH : LOW;
73+
}

0 commit comments

Comments
 (0)