diff options
| author | Otto Mattik <otto@mattik.org> | 2021-07-08 18:10:55 +0200 |
|---|---|---|
| committer | Otto Mattik <otto@mattik.org> | 2021-07-08 18:10:55 +0200 |
| commit | da34d97efb21719b2b332f8c60b2750d11bcde1f (patch) | |
| tree | 2de9fe89f6d79b8ebfcde64c5e86204e904aedf2 /avr/gpio.c | |
| download | armen-a861fb554ced7709555d2d1b639c534e3f45a83f.tar.gz armen-a861fb554ced7709555d2d1b639c534e3f45a83f.zip | |
Diffstat (limited to 'avr/gpio.c')
| -rw-r--r-- | avr/gpio.c | 162 |
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 + |
