summaryrefslogtreecommitdiff
path: root/avr/pin.c
diff options
context:
space:
mode:
authorLeo C2014-11-21 13:49:19 +0100
committerLeo C2014-11-21 13:49:19 +0100
commit05994bd90cb36f10ff72c6a70d7cecc61b67fb2f (patch)
treee3f56ddcf2255a77db11566dfbf52bdac4fb356c /avr/pin.c
parentfc454c83abd628f03eb39800b269d25c54f9591a (diff)
downloadz180-stamp-05994bd90cb36f10ff72c6a70d7cecc61b67fb2f.zip
Rename pin.. to gpio..
Diffstat (limited to 'avr/pin.c')
-rw-r--r--avr/pin.c372
1 files changed, 0 insertions, 372 deletions
diff --git a/avr/pin.c b/avr/pin.c
deleted file mode 100644
index 6e88aa5..0000000
--- a/avr/pin.c
+++ /dev/null
@@ -1,372 +0,0 @@
-#include "common.h"
-#include <util/atomic.h>
-#include <limits.h>
-#include "debug.h"
-#include "pin.h"
-
-
-/*
-
-Pin Name Port Timer Mode max div max div min f [Hz]
-----------------------------------------------------------------------------------
-0 PG5 OC0B PWM (2**8)*1024 262144 70.31
-1 PG4
-2 CLK2 PB4 OC2A Toggle (2**8)*1024*2 524288 35.16
-3 ZCLK PB5 OC1A PWM (2**16)*1024 67108864 0.2746
-4 PB6 OC1B PWM (2**16)*1024 67108864 0.2746
-5 PB7 OC0A Toggle (2**8)*1024*2 524288 35.16
-6 PG3
-7 PG2
-8 PG1
-9 PG0
-10 CLKO PE7
-
-
-pre Timer0 Timer1 Timer2
---------------------------------------------------
-0 0 0 0
-1 1 1 1
-2 8 x8 8 x8 8 x8
-3 64 x8 64 x8 32 x4
-4 256 x4 256 x4 64 x2
-5 1024 x4 1024 x4 128 x2
-6 256 x2
-7 1024 x4
---------------------------------------------------
-
-*/
-
-
-#define PWMTOGGLE 0b01
-#define PWMPOS 0b10
-#define PWMNEG 0b11
-
-
-const FLASH uint8_t prescale_factors_01[] =
- { 8, 8, 4, 4, 0 };
-
-const FLASH uint8_t prescale_factors_2[] =
- { 8, 4, 2, 2, 2, 4, 0 };
-
-typedef volatile struct {
- uint8_t pin;
- uint8_t ddr;
- uint8_t pout;
-} port_t ;
-
-struct pindef_s {
- port_t * const adr;
- const uint8_t mask;
-#define NO_TIMER 0
-#define TIMER0 (1 << 0)
-#define TIMER1 (2 << 0)
-#define TIMER2 (3 << 0)
-#define TIMER (3 << 0)
-#define T_16BIT (1 << 3)
-#define CHANA (1 << 4)
-#define CHANB (0 << 4)
- const uint8_t timer;
-};
-
-
-const FLASH struct pindef_s pinlist[PIN_MAX] = {
- { (port_t *) &PING, _BV(5), TIMER0 | CHANB },
- { (port_t *) &PING, _BV(4), NO_TIMER },
- { (port_t *) &PINB, _BV(4), TIMER2 | CHANA },
- { (port_t *) &PINB, _BV(5), TIMER1 | CHANA | T_16BIT },
- { (port_t *) &PINB, _BV(6), TIMER1 | CHANB | T_16BIT },
- { (port_t *) &PINB, _BV(7), TIMER0 | CHANA },
- { (port_t *) &PING, _BV(3), NO_TIMER },
- { (port_t *) &PING, _BV(2), NO_TIMER },
- { (port_t *) &PING, _BV(1), NO_TIMER },
- { (port_t *) &PING, _BV(0), NO_TIMER },
- { (port_t *) &PINE, _BV(7), NO_TIMER },
-};
-
-void pin_timer_off(uint8_t timertype)
-{
- uint8_t chan_mask;
-
- if (timertype & CHANA)
- chan_mask = 0xc0;
- else
- chan_mask = 0x30;
-
- switch (timertype & TIMER) {
- case TIMER0:
- if (TCCR0A & chan_mask) {
- TCCR0B = 0;
- TCCR0A = 0;
- PRR0 |= _BV(PRTIM0);
- }
- break;
- case TIMER1:
- if (TCCR1A & chan_mask) {
- TCCR1B = 0;
- TCCR1A = 0;
- PRR0 |= _BV(PRTIM1);
- }
- break;
- case TIMER2:
- if (TCCR2A & chan_mask) {
- TCCR2B = 0;
- TCCR2A = 0;
- PRR0 |= _BV(PRTIM2);
- }
- break;
- }
-}
-
-int pin_config(int pin, pinmode_t mode)
-{
- if ((unsigned) pin >= ARRAY_SIZE(pinlist)) {
- /* Invalid pin number */
- return -1;
- } else {
-
- port_t *p = pinlist[pin].adr;
- uint8_t bit = pinlist[pin].mask;
-
- switch (mode) {
- case INPUT:
- pin_timer_off(pinlist[pin].timer);
- ATOMIC_BLOCK(ATOMIC_FORCEON) {
- p->ddr &= ~bit;
- p->pout &= ~bit;
- }
- break;
- case INPUT_PULLUP:
- pin_timer_off(pinlist[pin].timer);
- ATOMIC_BLOCK(ATOMIC_FORCEON) {
- p->ddr &= ~bit;
- p->pout |= bit;
- }
- break;
- case OUTPUT:
- pin_timer_off(pinlist[pin].timer);
- case OUTPUT_TIMER:
- ATOMIC_BLOCK(ATOMIC_FORCEON) {
- p->ddr |= bit;
- }
- break;
- default:
- /* Invalid pin mode */
- return -1;
- }
- }
- return 0;
-}
-
-void pin_write(int pin, uint8_t val)
-{
- port_t *p = pinlist[pin].adr;
- uint8_t bit = pinlist[pin].mask;
-
- ATOMIC_BLOCK(ATOMIC_FORCEON) {
- if (val)
- p->pout |= bit;
- else
- p->pout &= ~bit;
- }
-}
-
-int pin_read(int pin)
-{
- port_t *p = pinlist[pin].adr;
- uint8_t bit = pinlist[pin].mask;
-
- return (p->pin & bit) != 0;
-}
-
-pinmode_t pin_config_get(int pin)
-{
- uint8_t timertype = pinlist[pin].timer;
-
- if (timertype & TIMER) {
-
- uint8_t chan_mask;
- if (timertype & CHANA)
- chan_mask = 0xc0;
- else
- chan_mask = 0x30;
-
- switch (timertype & TIMER) {
- case TIMER0:
- if (TCCR0A & chan_mask)
- return OUTPUT_TIMER;
- break;
- case TIMER1:
- if (TCCR1A & chan_mask)
- return OUTPUT_TIMER;
- break;
- case TIMER2:
- if (TCCR2A & chan_mask)
- return OUTPUT_TIMER;
- break;
- }
- }
-
- port_t *p = pinlist[pin].adr;
- uint8_t bit = pinlist[pin].mask;
-
- if (p->ddr & bit)
- return OUTPUT;
-
- if (p->pout & bit)
- return INPUT_PULLUP;
-
- return INPUT;
-}
-
-/*
- * return -1: pin has no timer output
- * 0: pin is not configured for timer output
- * > 0: divider
- */
-
-long pin_clockdiv_get(int pin)
-{
- long divider;
- uint8_t prescale;
- const FLASH uint8_t *pstab;
-
- uint8_t timertype = pinlist[pin].timer;
- if ((timertype & TIMER) == 0)
- return -1;
-
- if (pin_config_get(pin) != OUTPUT_TIMER)
- return 0;
-
- switch (timertype & TIMER) {
- case TIMER0:
- prescale = TCCR0B;
- divider = OCR0A;
- break;
-
- case TIMER1:
- prescale = TCCR1B;
- divider = ICR1;
- break;
-
- case TIMER2:
- prescale = TCCR2B;
- divider = OCR2A;
- break;
- }
-
- prescale = (prescale & 0x07) - 1;
- divider += 1;
-
- pstab = (timertype & TIMER) == TIMER2 ?
- prescale_factors_2 : prescale_factors_01;
-
- while (prescale--)
- divider *= pstab[prescale];
-
- if ((timertype & (CHANA|T_16BIT)) == CHANA)
- divider *= 2;
-
- return divider;
-}
-
-int pin_clockdiv_set(int pin, unsigned long divider)
-{
- unsigned long ltop;
- uint16_t top;
- uint8_t prescale;
- const FLASH uint8_t *pstab;
-
- uint8_t timertype = pinlist[pin].timer;
- if ((timertype & TIMER) == 0)
- return 0;
-
- if (divider < 2)
- return -1;
-
- ltop = divider;
- if ((timertype & (CHANA|T_16BIT)) == CHANA)
- ltop /= 2;
-
- if (ltop > 1024 * ((timertype & T_16BIT) ? (1L<<16) : (1L<<8)))
- return -1;
-
- prescale = 1;
- pstab = (timertype & TIMER) == TIMER2 ?
- prescale_factors_2 : prescale_factors_01;
-
-// debug("** clockdiv_set: pin: %d, ltop: %lu, prescale: %d\n",
-// pin, ltop, prescale);
-
- while (ltop > ((timertype & T_16BIT) ? (1L<<16) : (1L<<8))) {
-// debug("** clockdiv_set: pin: %d, ltop: %lu, prescale: %d, *pstab %d\n",
-// pin, ltop, prescale, *pstab);
-
- if (*pstab == 0)
- return -1;
- ltop /= *pstab++;
- prescale++;
- }
-
- if (ltop == 0)
- return -1;
-
- top = ltop - 1;
-
- PING |= _BV(0); /* Debug */
-
- switch (timertype & TIMER) {
- case TIMER0:
- PRR0 &= ~_BV(PRTIM0);
- TCCR0B = (1 << WGM02);
- TCNT0 = 0;
- OCR0A = top;
- if (timertype & CHANA) {
- TCCR0A = (PWMTOGGLE << COM0A0) | (0b11 << WGM00);
- } else {
- OCR0B = top/2;
- TCCR0A = (PWMPOS << COM0B0) | (0b11 << WGM10);
- }
- TCCR0B = (1 << WGM02) | (prescale << CS10);
- break;
-
- case TIMER1:
- PRR0 &= ~_BV(PRTIM1);
- TCCR1B = (0b11 << WGM12);
- TCNT1 = 0;
- ICR1 = top;
- if (timertype & CHANA) {
- OCR1A = top/2;
- TCCR1A = (PWMPOS << COM1A0) | (0b10 << WGM10);
- } else {
- OCR1B = top/2;
- TCCR1A = (PWMPOS << COM1B0) | (0b10 << WGM10);
- }
-// debug("pin: %d, top: %u,"
-// " ICR1: %u, OCR1A: %u, OCR1B: %u\n",
-// pin, top, ICR1, OCR1A, OCR1B);
-
- TCCR1B = (0b11 << WGM12) | (prescale << CS10);
- break;
-
- case TIMER2:
- PRR0 &= ~_BV(PRTIM2);
- TCCR2B = (1 << WGM22);
- TCNT2 = 0;
- OCR2A = top;
- if (timertype & CHANA) {
- TCCR2A = (PWMTOGGLE << COM2A0) | (0b11 << WGM20);
- } else {
- OCR2B = top/2;
- TCCR2A = (PWMPOS << COM2B0) | (0b11 << WGM10);
- }
- TCCR2B = (1 << WGM22) | (prescale << CS10);
- break;
- }
-
- PING |= _BV(0); /* Debug */
-
- pin_config(pin, OUTPUT_TIMER);
-
- return 0;
-}
-