aboutsummaryrefslogtreecommitdiff
path: root/avr/gpio.c
diff options
context:
space:
mode:
authorOtto Mattik <otto@mattik.org>2021-07-08 18:10:55 +0200
committerOtto Mattik <otto@mattik.org>2021-07-08 18:10:55 +0200
commitda34d97efb21719b2b332f8c60b2750d11bcde1f (patch)
tree2de9fe89f6d79b8ebfcde64c5e86204e904aedf2 /avr/gpio.c
downloadarmen-master.tar.gz
armen-master.zip
git: update to v1.0HEADv1.0master
Diffstat (limited to 'avr/gpio.c')
-rw-r--r--avr/gpio.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/avr/gpio.c b/avr/gpio.c
new file mode 100644
index 0000000..8a5885f
--- /dev/null
+++ b/avr/gpio.c
@@ -0,0 +1,162 @@
+/************************************************************************/
+/* */
+/* File: avr/gpio.c */
+/* Description: general purpose input/output driver. */
+/* Version: 1.0 */
+/* Author: Otto Mattik */
+/* */
+/* (C)Copyright Otto Mattik 2014-2021. */
+/* */
+/* This file is a part of 'armen' (a tiny operating system). */
+/* 'armen' is distributed under the CeCILL-V2.1 licence. For more */
+/* details about this licence, please visit the website cecill.info */
+/* */
+/************************************************************************/
+
+#ifndef AVR_GPIO_C
+ #error "do not use this code directly, it must be included via gpio.c"
+#endif
+
+#include <stdint.h>
+#include <avr/io.h>
+
+#if defined(__AVR_ATtiny84__)
+ #define GPIO_MAX_PORT 2
+#elif defined(__AVR_ATtiny841__)
+ #define GPIO_MAX_PORT 2
+#elif defined(__AVR_ATtiny85__)
+ #define GPIO_MAX_PORT 1
+#elif defined(__AVR_ATtiny1634__)
+ #define GPIO_MAX_PORT 3
+#elif defined(__AVR_ATmega328P__)
+ #define GPIO_MAX_PORT 3
+#elif defined(__AVR_ATmega2560__)
+ #define GPIO_MAX_PORT 11
+#else
+ #error "no or unavailable cpu defined"
+#endif
+
+static struct {
+ uint8_t* pin;
+ uint8_t* ddr;
+ uint8_t* port;
+} ports[GPIO_MAX_PORT] = {
+#if defined(__AVR_ATtiny84__)\
+ || defined(__AVR_ATtiny841__)
+ { 0x0039, 0x003A, 0x003B },
+ { 0x0036, 0x0037, 0x0038 }
+#elif defined(__AVR_ATtiny85__)
+ { 0x0016, 0x0017, 0x0018 }
+#elif defined(__AVR_ATtiny1634__)
+ { 0x002F, 0x0030, 0x0031 },
+ { 0x002B, 0x002C, 0x002D },
+ { 0x0027, 0x0028, 0x0029 }
+#elif defined(__AVR_ATmega328P__)
+ { 0x0023, 0x0024, 0x0025 },
+ { 0x0026, 0x0027, 0x0028 },
+ { 0x0029, 0x002A, 0x002B }
+#elif defined(__AVR_ATmega2560__)
+ { 0x0020, 0x0021, 0x0022 },
+ { 0x0023, 0x0024, 0x0025 },
+ { 0x0026, 0x0027, 0x0028 },
+ { 0x0029, 0x002A, 0x002B },
+ { 0x002C, 0x002D, 0x002E },
+ { 0x002F, 0x0030, 0x0031 },
+ { 0x0032, 0x0033, 0x0034 },
+ { 0x0100, 0x0101, 0x0102 },
+ { 0x0104, 0x0104, 0x0105 },
+ { 0x0106, 0x0107, 0x0108 },
+ { 0x0109, 0x010A, 0x010B }
+#endif
+};
+
+/*
+ * read state of a gpio pin
+ *
+ * input:
+ * gpio gpio pin
+ * output:
+ * low or high if success, otherwise -1
+*/
+int8_t gpio_pin_get( uint8_t gpio )
+{
+#ifdef CHECK_PARAM
+ if( gpio >= (GPIO_MAX_PORT << 3) )
+ return( -1 );
+#endif
+ return( (*ports[gpio >> 3].pin >> (gpio & 7)) & 1 );
+}
+
+/*
+ * set state of a gpio pin
+ *
+ * input:
+ * gpio gpio pin
+ * value low or high
+*/
+void gpio_pin_set( uint8_t gpio, uint8_t value )
+{
+#ifdef CHECK_PARAM
+ if( gpio < (GPIO_MAX_PORT << 3) )
+#endif
+ {
+ uint8_t port = gpio >> 3;
+ uint8_t mask = 1 << (gpio & 7);
+
+ if( value != 0 )
+ *ports[gpio >> 3].port |= mask;
+ else
+ *ports[gpio >> 3].port &= ~mask;
+ }
+}
+
+/*
+ * set a gpio pin as input
+ *
+ * input:
+ * gpio gpio pin
+*/
+void gpio_pin_mode_input( uint8_t gpio )
+{
+#ifdef CHECK_PARAM
+ if( gpio < (GPIO_MAX_PORT << 3) )
+#endif
+ *ports[gpio >> 3].ddr &= ~(1 << (gpio & 7));
+}
+
+/*
+ * set a gpio pin as output
+ *
+ * input:
+ * gpio gpio pin
+ * value initial value, low or high
+*/
+void gpio_pin_mode_output( uint8_t gpio, uint8_t value )
+{
+#ifdef CHECK_PARAM
+ if( gpio < (GPIO_MAX_PORT << 3) )
+#endif
+ {
+ uint8_t port = gpio >> 3;
+ uint8_t mask = 1 << (gpio & 7);
+
+ if( value != 0 )
+ *ports[port].port |= mask;
+ else
+ *ports[port].port &= ~mask;
+ *ports[port].ddr |= mask;
+ }
+}
+
+#ifdef USE_ADC
+ #include "avr/adc.c"
+#endif
+
+#ifdef USE_PWM
+ #include "avr/pwm.c"
+#endif
+
+#ifdef USE_PCINT
+ #include "avr/pcint.c"
+#endif
+