diff options
author | Daniel Friesel <derf@finalrewind.org> | 2021-02-07 21:12:04 +0100 |
---|---|---|
committer | Daniel Friesel <derf@finalrewind.org> | 2021-02-07 21:12:04 +0100 |
commit | 998419816c815175cd4c4f226e619c578d42e0aa (patch) | |
tree | 3efa872828bb973406a15469ac9ddfd245f29cfa /include/arch/atmega2560/driver | |
parent | 30431427adbf05a3e5cc17f6fb4b1b1cbc105b39 (diff) |
add arch atmega2560 (preliminary support)
Diffstat (limited to 'include/arch/atmega2560/driver')
-rw-r--r-- | include/arch/atmega2560/driver/counter.h | 41 | ||||
-rw-r--r-- | include/arch/atmega2560/driver/gpio.h | 234 | ||||
-rw-r--r-- | include/arch/atmega2560/driver/stdout.h | 24 | ||||
-rw-r--r-- | include/arch/atmega2560/driver/timer.h | 40 | ||||
-rw-r--r-- | include/arch/atmega2560/driver/uptime.h | 34 |
5 files changed, 373 insertions, 0 deletions
diff --git a/include/arch/atmega2560/driver/counter.h b/include/arch/atmega2560/driver/counter.h new file mode 100644 index 0000000..06ff73a --- /dev/null +++ b/include/arch/atmega2560/driver/counter.h @@ -0,0 +1,41 @@ +/* + * Copyright 2021 Daniel Friesel + * + * SPDX-License-Identifier: BSD-2-Clause + */ +#ifndef COUNTER_H +#define COUNTER_H + +#include <avr/io.h> +#include <avr/interrupt.h> + +typedef uint16_t counter_value_t; +typedef uint8_t counter_overflow_t; + +class Counter { + private: + Counter(const Counter ©); + + public: + uint16_t value; + volatile uint8_t overflow; + + Counter() : overflow(0) {} + + inline void start() { + overflow = 0; + TCNT3 = 0; + TCCR3A = 0; + TCCR3B = _BV(CS10); // no prescaler + TIMSK3 = _BV(TOIE3); + } + + inline void stop() { + TCCR3B = 0; + value = TCNT3; + } +}; + +extern Counter counter; + +#endif diff --git a/include/arch/atmega2560/driver/gpio.h b/include/arch/atmega2560/driver/gpio.h new file mode 100644 index 0000000..b163ea0 --- /dev/null +++ b/include/arch/atmega2560/driver/gpio.h @@ -0,0 +1,234 @@ +/* + * Copyright 2021 Daniel Friesel + * + * SPDX-License-Identifier: BSD-2-Clause + */ +#ifndef GPIO_H +#define GPIO_H + +#include <avr/io.h> + +class GPIO { + private: + GPIO(const GPIO ©); + + public: + GPIO () {} + + enum Pin : unsigned char { + pa0 = 0, + pa1 = 1, + pa2 = 2, + pa3 = 3, + pa4 = 4, + pa5 = 5, + pa6 = 6, + pa7 = 7, + pb0 = 8, + pb1 = 9, + pb2 = 10, + pb3 = 11, + pb4 = 12, + pb5 = 13, + pb6 = 14, + pb7 = 15, + pc0 = 16, + pc1 = 17, + pc2 = 18, + pc3 = 19, + pc4 = 20, + pc5 = 21, + pc6 = 22, + pc7 = 23, + pd0 = 24, + pd1 = 25, + pd2 = 26, + pd3 = 27, + pd4 = 28, + pd5 = 29, + pd6 = 30, + pd7 = 31, + pe0 = 32, + pe1 = 33, + pe2 = 34, + pe3 = 35, + pe4 = 36, + pe5 = 37, + pe6 = 38, + pe7 = 39, + pf0 = 40, + pf1 = 41, + pf2 = 42, + pf3 = 43, + pf4 = 44, + pf5 = 45, + pf6 = 46, + pf7 = 47, + pg0 = 48, + pg1 = 49, + pg2 = 50, + pg3 = 51, + pg4 = 52, + pg5 = 53, + ph0 = 56, + ph1 = 57, + ph2 = 58, + ph3 = 59, + ph4 = 60, + ph5 = 61, + ph6 = 62, + ph7 = 63, + pj0 = 64, + pj1 = 65, + pj2 = 66, + pj3 = 67, + pj4 = 68, + pj5 = 69, + pj6 = 70, + pj7 = 71, + pk0 = 72, + pk1 = 73, + pk2 = 74, + pk3 = 75, + pk4 = 76, + pk5 = 77, + pk6 = 78, + pk7 = 79, + pl0 = 80, + pl1 = 81, + pl2 = 82, + pl3 = 83, + pl4 = 84, + pl5 = 85, + pl6 = 86, + pl7 = 87 + }; + + inline void setup() { + DDRB = _BV(PB7); + } + inline volatile uint8_t * pinToPort(uint8_t pin) { + if (pin <= pa7) { + return &PORTA; + } + if (pin <= pb7) { + return &PORTB; + } + if (pin <= pc7) { + return &PORTC; + } + return &PORTD; + } + inline unsigned char pinToBitmask(uint8_t pin) { + return _BV(pin % 8); + } +#pragma GCC diagnostic ignored "-Wunused-parameter" + inline void led_on(unsigned char id) { + PORTB |= _BV(PB7); + } + inline void led_off(unsigned char id) { + PORTB &= ~_BV(PB7); + } + inline void led_toggle(unsigned char id) { + PINB = _BV(PB7); + } + inline void input(unsigned char const pin) { + if (pin < 8) { + DDRA &= ~_BV(pin); + } else if (pin < 16) { + DDRB &= ~_BV(pin - 8); + } else if (pin < 24) { + DDRC &= ~_BV(pin - 16); + } else if (pin < 32) { + DDRD &= ~_BV(pin - 24); + } + } +#pragma GCC diagnostic pop + inline void input(unsigned char const pin, unsigned char const pull) { + if (pin < 8) { + DDRA &= ~_BV(pin); + PORTA |= _BV(pin); + } else if (pin < 16) { + DDRB &= ~_BV(pin - 8); + PORTB |= _BV(pin - 8); + } else if (pin < 24) { + DDRC &= ~_BV(pin - 16); + PORTC |= _BV(pin - 16); + } else if (pin < 32) { + DDRD &= ~_BV(pin - 24); + PORTD |= _BV(pin - 24); + } + } + inline void output(unsigned char const pin) { + if (pin < 8) { + DDRA |= _BV(pin); + } else if (pin < 16) { + DDRB |= _BV(pin - 8); + } else if (pin < 24) { + DDRC |= _BV(pin - 16); + } else if (pin < 32) { + DDRD |= _BV(pin - 24); + } + } + inline void output(unsigned char const pin, unsigned char const value) { + if (pin < 8) { + PORTA = value ? (PORTA | _BV(pin)) : (PORTA & ~_BV(pin)); + DDRA |= _BV(pin); + } else if (pin < 16) { + PORTB = value ? (PORTB | _BV(pin - 8)) : (PORTB & ~_BV(pin - 8)); + DDRB |= _BV(pin - 8); + } else if (pin < 24) { + PORTC = value ? (PORTC | _BV(pin - 16)) : (PORTC & ~_BV(pin - 16)); + DDRC |= _BV(pin - 16); + } else if (pin < 32) { + PORTD = value ? (PORTD | _BV(pin - 24)) : (PORTD & ~_BV(pin - 24)); + DDRD |= _BV(pin - 24); + } + } + inline unsigned char read(unsigned char const pin) { + if (pin < 8) { + return (PINA & _BV(pin)); + } + if (pin < 16) { + return (PINB & _BV(pin - 8)); + } + if (pin < 24) { + return (PINC & _BV(pin - 16)); + } + if (pin < 32) { + return (PIND & _BV(pin - 24)); + } + return 0; + } + inline void write(unsigned char const pin, unsigned char value) { + if (pin < 8) { + if (value) { + PORTA |= _BV(pin); + } else { + PORTA &= ~_BV(pin); + } + } else if (pin < 16) { + if (value) { + PORTB |= _BV(pin - 8); + } else { + PORTB &= ~_BV(pin - 8); + } + } else if (pin < 24) { + if (value) { + PORTC |= _BV(pin - 16); + } else { + PORTC &= ~_BV(pin - 16); + } + } else if (pin < 32) { + if (value) { + PORTD |= _BV(pin - 24); + } else { + PORTD &= ~_BV(pin - 24); + } + } + } +}; + +extern GPIO gpio; + +#endif diff --git a/include/arch/atmega2560/driver/stdout.h b/include/arch/atmega2560/driver/stdout.h new file mode 100644 index 0000000..09b18c1 --- /dev/null +++ b/include/arch/atmega2560/driver/stdout.h @@ -0,0 +1,24 @@ +/* + * Copyright 2021 Daniel Friesel + * + * SPDX-License-Identifier: BSD-2-Clause + */ +#ifndef STANDARDOUTPUT_H +#define STANDARDOUTPUT_H + +#include "object/outputstream.h" + +class StandardOutput : public OutputStream { + private: + StandardOutput(const StandardOutput ©); + + public: + StandardOutput () {} + void setup(); + + virtual void put(char c) override; +}; + +extern StandardOutput kout; + +#endif diff --git a/include/arch/atmega2560/driver/timer.h b/include/arch/atmega2560/driver/timer.h new file mode 100644 index 0000000..73a8125 --- /dev/null +++ b/include/arch/atmega2560/driver/timer.h @@ -0,0 +1,40 @@ +/* + * Copyright 2021 Daniel Friesel + * + * SPDX-License-Identifier: BSD-2-Clause + */ +#include <avr/io.h> +#include <avr/interrupt.h> + +#define ON_TIMER_INTERRUPT_head ISR(TIMER0_COMPA_vect) { +#define ON_TIMER_INTERRUPT_tail } + +class Timer { + private: + Timer(const Timer ©); + unsigned char prescaler; + + public: + Timer() {} + + inline void setup_khz(uint16_t const frequency) { + OCR0A = frequency ? 255 / frequency : 1; + TCCR0A = _BV(WGM01); + prescaler = _BV(CS01) | _BV(CS00); + } + inline void setup_hz(uint16_t const frequency) { + OCR0A = frequency ? 255 / frequency : 1; + TCCR0A = _BV(WGM01); + prescaler = _BV(CS02) | _BV(CS00); + } + inline void start(unsigned char const interrupt) { + TCNT0 = 0; + TCCR0B = prescaler; + if (interrupt) { + TIMSK0 = _BV(OCIE0A); + } + } + inline void stop() { TCCR0B = 0; TIMSK0 = 0; } +}; + +extern Timer timer; diff --git a/include/arch/atmega2560/driver/uptime.h b/include/arch/atmega2560/driver/uptime.h new file mode 100644 index 0000000..621a55c --- /dev/null +++ b/include/arch/atmega2560/driver/uptime.h @@ -0,0 +1,34 @@ +/* + * Copyright 2021 Daniel Friesel + * + * SPDX-License-Identifier: BSD-2-Clause + */ +#ifndef UPTIME_H +#define UPTIME_H + +#include <avr/io.h> + +class Uptime { + private: + Uptime(const Uptime ©); +#ifdef TIMER_S + uint8_t seconds; +#endif + + public: +#ifdef TIMER_S + Uptime () : seconds(0) {} +#else + Uptime () {} +#endif + inline uint8_t get_cycles() { return TCNT0; } + inline uint8_t get_us() { return TCNT2/2; } +#ifdef TIMER_S + inline uint8_t get_s() { return seconds; } + inline void tick_s() { seconds++; } +#endif +}; + +extern Uptime uptime; + +#endif |