From 64500ab11ab76d2309608f8e02a1dd9658963b3e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 12 Oct 2012 14:04:57 -0700 Subject: altos: Add attiny architecture files These are designed to work with the ATtiny85 processor, but can presuambly be easily adapted to others in that series Signed-off-by: Keith Packard --- src/attiny/ao_arch.h | 82 +++++++++++++++ src/attiny/ao_arch_funcs.h | 125 +++++++++++++++++++++++ src/attiny/ao_clock.c | 114 +++++++++++++++++++++ src/attiny/ao_eeprom_tiny.c | 71 +++++++++++++ src/attiny/ao_exti.c | 37 +++++++ src/attiny/ao_exti.h | 34 +++++++ src/attiny/ao_i2c_attiny.c | 238 ++++++++++++++++++++++++++++++++++++++++++++ src/attiny/ao_led.c | 63 ++++++++++++ src/attiny/ao_spi_attiny.c | 123 +++++++++++++++++++++++ 9 files changed, 887 insertions(+) create mode 100644 src/attiny/ao_arch.h create mode 100644 src/attiny/ao_arch_funcs.h create mode 100644 src/attiny/ao_clock.c create mode 100644 src/attiny/ao_eeprom_tiny.c create mode 100644 src/attiny/ao_exti.c create mode 100644 src/attiny/ao_exti.h create mode 100644 src/attiny/ao_i2c_attiny.c create mode 100644 src/attiny/ao_led.c create mode 100644 src/attiny/ao_spi_attiny.c (limited to 'src/attiny') diff --git a/src/attiny/ao_arch.h b/src/attiny/ao_arch.h new file mode 100644 index 00000000..c34206e6 --- /dev/null +++ b/src/attiny/ao_arch.h @@ -0,0 +1,82 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_ARCH_H_ +#define _AO_ARCH_H_ + +#include +#include +#include +#include + +#define F_CPU 8000000UL // 8 MHz + +/* + * AVR definitions and code fragments for AltOS + */ + +#define AO_STACK_SIZE 116 + +/* Various definitions to make GCC look more like SDCC */ + +#define ao_arch_naked_declare __attribute__((naked)) +#define ao_arch_naked_define +#define __pdata +#define __data +#define __xdata +#define __code const +#define __reentrant +#define __critical +#define __interrupt(n) +#define __at(n) + +#define ao_arch_reboot() /* XXX */ + +#define ao_arch_nop() asm("nop") + +#define ao_arch_interrupt(n) /* nothing */ + +#undef putchar +#undef getchar +#define putchar(c) ao_putchar(c) +#define getchar ao_getchar + +#define ao_arch_cpu_idle() do { \ + sleep_enable(); \ + sei(); \ + sleep_cpu(); \ + sleep_disable(); \ + } while (0) + +#define ao_arch_critical(b) do { cli(); do { b } while (0); sei(); } while (0) + +#define ao_mutex_get(m) +#define ao_mutex_put(m) + +void +ao_delay_until(uint16_t target); + +/* We can't hit 100 Hz, but we can hit 125 */ +#define AO_HERTZ 125 + +void +ao_eeprom_read(uint16_t addr, void *buf, uint16_t len); + +void +ao_eeprom_write(uint16_t addr, void *buf, uint16_t len); + +#endif /* _AO_ARCH_H_ */ diff --git a/src/attiny/ao_arch_funcs.h b/src/attiny/ao_arch_funcs.h new file mode 100644 index 00000000..8c9d1ae6 --- /dev/null +++ b/src/attiny/ao_arch_funcs.h @@ -0,0 +1,125 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +/* + * ao_spi.c + */ + +#define ao_spi_get_mask(reg,mask,bus,speed) do { \ + (reg) &= ~(mask); \ + } while (0) + +#define ao_spi_put_mask(reg,mask,bus) do { \ + (reg) |= (mask); \ + } while (0) + +#define ao_spi_get_bit(reg,bit,pin,bus,speed) do { \ + (pin) = 0; \ + } while (0) + +#define ao_spi_put_bit(reg,bit,pin,bus) do { \ + (pin) = 1; \ + } while (0) + + +#define ao_gpio_token_paster(x,y) x ## y +#define ao_gpio_token_evaluator(x,y) ao_gpio_token_paster(x,y) + +#define ao_gpio_set(port, bit, pin, v) do { \ + if (v) \ + PORTB |= (1 << bit); \ + else \ + PORTB &= ~(1 << bit); \ + } while (0) + +/* + * The SPI mutex must be held to call either of these + * functions -- this mutex covers the entire SPI operation, + * from chip select low to chip select high + */ + +#define ao_enable_output(port, bit, pin, v) do { \ + ao_gpio_set(port, bit, pin, v); \ + ao_gpio_token_evaluator(DDR,port) |= (1 << bit); \ + } while (0) + + +void +ao_spi_send_bus(void __xdata *block, uint16_t len) __reentrant; + +void +ao_spi_recv_bus(void __xdata *block, uint16_t len) __reentrant; + +#define ao_spi_send(block, len, bus) ao_spi_send_bus(block, len) +#define ao_spi_recv(block, len, bus) ao_spi_recv_bus(block, len) + +void +ao_spi_init(void); + +#define ao_spi_get(bus, speed) +#define ao_spi_put(bus) + +#define ao_spi_init_cs(port, mask) do { \ + PORTB |= (mask); \ + DDRB |= (mask); \ + } while (0) + +/* I2C */ + +void +ao_i2c_get(uint8_t i2c_index); + +uint8_t +ao_i2c_start_bus(uint8_t address); + +#define ao_i2c_start(i,a) ao_i2c_start_bus(a) + +void +ao_i2c_put(uint8_t i2c_index); + +uint8_t +ao_i2c_send_bus(void *block, uint16_t len, uint8_t stop); + +#define ao_i2c_send(b,l,i,s) ao_i2c_send_bus(b,l.s) + +uint8_t +ao_i2c_send_fixed_bus(uint8_t value, uint16_t len, uint8_t stop); + +#define ao_i2c_send_fixed(v,l,i,s) ao_i2c_send_fixed_bus(v,l.s) + +uint8_t +ao_i2c_recv_bus(void *block, uint16_t len, uint8_t stop); + +#define ao_i2c_recv(b,l,i,s) ao_i2c_recv_bus(b,l.s) + +void +ao_i2c_init(void); + +/* notask.c */ + +uint8_t +ao_sleep(__xdata void *wchan); + +void +ao_wakeup(__xdata void *wchan); + +extern alt_t ao_max_height; + +extern void ao_report_altitude(void); + +void ao_delay_us(uint16_t us); + diff --git a/src/attiny/ao_clock.c b/src/attiny/ao_clock.c new file mode 100644 index 00000000..a381b47f --- /dev/null +++ b/src/attiny/ao_clock.c @@ -0,0 +1,114 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include + +volatile AO_TICK_TYPE ao_tick_count; +static volatile AO_TICK_TYPE ao_wakeup_count; + +ISR(TIMER1_COMPA_vect) +{ + PORTB ^= 2; + ++ao_tick_count; + if ((int16_t) (ao_tick_count - ao_wakeup_count) >= 0) + ao_wakeup((void *) &ao_tick_count); +} + +uint16_t +ao_time(void) +{ + uint16_t r; + + cli(); + r = ao_tick_count; + sei(); + return r; +} + +void +ao_timer_init(void) +{ + cli(); + CLKPR = (1 << CLKPCE); + CLKPR = 0; + sei(); + + /* Overall division ratio is 512 * 125, + * so our 8MHz base clock ends up as a 125Hz + * clock + */ + TCCR1 = ((1 << CTC1) | /* Clear timer on match */ + (0 << PWM1A) | /* Not PWM mode */ + (0 << COM1A0) | /* Don't change output pins */ + (0 << COM1A1) | /* ... */ + (1 << CS13) | /* Prescale by 512 */ + (0 << CS12) | /* ... */ + (1 << CS11) | /* ... */ + (0 << CS10)); /* ... */ + GTCCR = ((0 << PWM1B) | /* Not PWM mode */ + (0 << COM1B1) | /* Don't change output pins */ + (0 << COM1B0) | /* ... */ + (0 << FOC1B) | /* Don't force output compare */ + (0 << FOC1A) | /* ... */ + (0 << PSR1)); /* Don't bother to reset scaler */ + + OCR1A = 0; + OCR1B = 0; + OCR1C = 124; /* Divide by as many 5s as we can (5^3 = 125) */ + + TIMSK = ((1 << OCIE1A) | /* Enable TIMER1_COMPA interrupt */ + (0 << OCIE1B) | /* Disable TIMER1_COMPB interrupt */ + (0 << TOIE1)); /* Disable TIMER1_OVF interrupt */ + DDRB |= 2; +} + +#define PER_LOOP 8 +#define US_LOOPS ((AVR_CLOCK / 1000000) / PER_LOOP) + +void ao_delay_us(uint16_t us) +{ +#if US_LOOPS > 1 + us *= US_LOOPS; +#endif + for (;;) { + ao_arch_nop(); + ao_arch_nop(); + ao_arch_nop(); + --us; + /* A bit funky to keep the optimizer + * from short-circuiting the test */ + if (!((uint8_t) (us | (us >> 8)))) + break; + } +} + +void +ao_delay_until(uint16_t target) +{ + cli(); + ao_wakeup_count = target; + while ((int16_t) (target - ao_tick_count) > 0) + ao_sleep((void *) &ao_tick_count); + sei(); +} + +void +ao_delay(uint16_t ticks) +{ + ao_delay_until(ao_time() + ticks); +} + diff --git a/src/attiny/ao_eeprom_tiny.c b/src/attiny/ao_eeprom_tiny.c new file mode 100644 index 00000000..83014183 --- /dev/null +++ b/src/attiny/ao_eeprom_tiny.c @@ -0,0 +1,71 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include + +static void +ao_eeprom_wait(void) +{ + /* Wait for previous write to complete */ + while (EECR & (1 << EEPE)) + ; +} + +static uint8_t +ao_eeprom_read_byte(uint16_t addr) +{ + uint8_t v; + + ao_eeprom_wait(); + EEAR = addr; + cli(); + EECR |= (1 << EERE); + v = EEDR; + sei(); + return v; +} + +static void +ao_eeprom_write_byte(uint16_t addr, uint8_t v) +{ + ao_eeprom_wait(); + EECR = (0 << EEPM1) | (0 << EEPM0); + EEAR = addr; + EEDR = v; + cli(); + EECR |= (1 << EEMPE); + EECR |= (1 << EEPE); + sei(); +} + +void +ao_eeprom_read(uint16_t addr, void *buf, uint16_t len) +{ + uint8_t *b = buf; + + while (len--) + *b++ = ao_eeprom_read_byte(addr++); +} + +void +ao_eeprom_write(uint16_t addr, void *buf, uint16_t len) +{ + uint8_t *b = buf; + + while (len--) + ao_eeprom_write_byte(addr++, *b++); +} diff --git a/src/attiny/ao_exti.c b/src/attiny/ao_exti.c new file mode 100644 index 00000000..0ca10ca4 --- /dev/null +++ b/src/attiny/ao_exti.c @@ -0,0 +1,37 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include +#include + +static void (*pcint_callback)(void); +static uint8_t pcint_mask; + +ISR(PCINT0_vect) +{ + if (PINB & pcint_mask) + (*pcint_callback)(); +} + +void +ao_exti_setup_port(uint8_t pin, uint8_t mode, void (*callback)(void)) +{ + pcint_callback = callback; + pcint_mask = (1 << pin); + ao_exti_disable(PORTB, pin); + GIMSK |= (1 << PCIE); +} diff --git a/src/attiny/ao_exti.h b/src/attiny/ao_exti.h new file mode 100644 index 00000000..2ea4f47d --- /dev/null +++ b/src/attiny/ao_exti.h @@ -0,0 +1,34 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_EXTI_H_ +#define _AO_EXTI_H_ + +void +ao_exti_setup_port(uint8_t pin, uint8_t mode, void (*callback)(void)); + +#define ao_exti_setup(port, pin, mode, callback) ao_exti_setup_port(pin, mode, callback) + +#define ao_exti_enable(gpio, pin) (PCMSK |= (1 << (pin))) + +#define ao_exti_disable(gpio, pin) (PCMSK &= ~(1 << (pin))) + +#define ao_exti_init() + +#define AO_EXTI_MODE_RISING 1 + +#endif /* _AO_EXTI_H_ */ diff --git a/src/attiny/ao_i2c_attiny.c b/src/attiny/ao_i2c_attiny.c new file mode 100644 index 00000000..2ee44fd2 --- /dev/null +++ b/src/attiny/ao_i2c_attiny.c @@ -0,0 +1,238 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include + +/* + * ATtiny USI as an I2C interface + */ + +#define I2C_USICR ((0 << USISIE) | /* No start condition interrupt */ \ + (0 << USIOIE) | /* No counter overflow interrupt */ \ + (1 << USIWM1) | /* Two-wire mode */ \ + (0 << USIWM0) | /* ... */ \ + (1 << USICS1) | /* Software clock strobe */ \ + (0 << USICS0) | /* ... */ \ + (1 << USICLK)) /* ... */ \ + +#define I2C_USICR_TICK (I2C_USICR | (1 << USITC)) /* Toggle the clock on every write */ + +#define I2C_USISR_1BIT ((1<4.7μs */ +#define T4_TWI 4 /* >4.0μs */ + +static inline void ao_i2c_transfer(uint8_t sr) +{ + USISR = sr; + for (;;) { + ao_delay_us(T2_TWI); + + /* Clock high */ + USICR = I2C_USICR_TICK; + + /* Wait for clock high (clock stretching) */ + ao_delay_us(T4_TWI); + while(!(I2C_PIN & (1< + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "ao.h" + +__pdata uint8_t ao_led_enable; + +#define LED_PORT PORTB +#define LED_DDR DDRB + +void +ao_led_on(uint8_t colors) +{ + LED_PORT |= (colors & ao_led_enable); +} + +void +ao_led_off(uint8_t colors) +{ + LED_PORT &= ~(colors & ao_led_enable); +} + +void +ao_led_set(uint8_t colors) +{ + LED_PORT = (LED_PORT & ~(ao_led_enable)) | (colors & ao_led_enable); +} + +void +ao_led_toggle(uint8_t colors) +{ + LED_PORT ^= (colors & ao_led_enable); +} + +void +ao_led_for(uint8_t colors, uint16_t ticks) __reentrant +{ + ao_led_on(colors); + ao_delay(ticks); + ao_led_off(colors); +} + +void +ao_led_init(uint8_t enable) +{ + ao_led_enable = enable; + LED_PORT &= ~enable; + LED_DDR |= enable; +} diff --git a/src/attiny/ao_spi_attiny.c b/src/attiny/ao_spi_attiny.c new file mode 100644 index 00000000..064876d7 --- /dev/null +++ b/src/attiny/ao_spi_attiny.c @@ -0,0 +1,123 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include + +/* + * ATtiny USI as a SPI interface + */ + +/* + * Transfer one byte in/out of the USI interface + */ + +/* Three wire mode */ +#define SPI_USICR_WM ((0 << USIWM1) | (1 << USIWM0)) +#define SPI_USICR_CS ((1 << USICS1) | (0 << USICS0) | (1 << USICLK)) + +#define SPI_USICR_FAST_2 ((1 << USIWM0) | (1 << USITC)) +#define SPI_USICR_FAST_1 ((1 << USIWM0) | (1 << USITC) | (1 << USICLK)) + + +static uint8_t +ao_spi_transfer(uint8_t i) +{ + /* Load data register */ + USIDR = i; + +#if 1 + USISR = (1 << USIOIF); + do { + USICR = SPI_USICR_WM | SPI_USICR_CS | (1 << USITC); + } while ((USISR & (1 << USIOIF)) == 0); +#else + /* 8 clocks */ + USICR = SPI_USICR_FAST_1; + USICR = SPI_USICR_FAST_2; + + USICR = SPI_USICR_FAST_1; + USICR = SPI_USICR_FAST_2; + + USICR = SPI_USICR_FAST_1; + USICR = SPI_USICR_FAST_2; + + USICR = SPI_USICR_FAST_1; + USICR = SPI_USICR_FAST_2; + + USICR = SPI_USICR_FAST_1; + USICR = SPI_USICR_FAST_2; + + USICR = SPI_USICR_FAST_1; + USICR = SPI_USICR_FAST_2; + + USICR = SPI_USICR_FAST_1; + USICR = SPI_USICR_FAST_2; + + USICR = SPI_USICR_FAST_1; + USICR = SPI_USICR_FAST_2; +#endif + + /* Pull data from the port */ + return USIDR; +} + +/* Send bytes over SPI. + * + * This just polls; the SPI is set to go as fast as possible, + * so using interrupts would take way too long + */ +void +ao_spi_send_bus(void __xdata *block, uint16_t len) __reentrant +{ + uint8_t *d = block; + + while (len--) + ao_spi_transfer (*d++); +} + +/* Receive bytes over SPI. + * + * Poll, sending zeros and reading data back + */ +void +ao_spi_recv_bus(void __xdata *block, uint16_t len) __reentrant +{ + uint8_t *d = block; + + while (len--) + *d++ = ao_spi_transfer (0xff); +} + +/* + * Initialize USI + * + * Chip select is the responsibility of the caller + */ + +void +ao_spi_init(void) +{ +#if 1 + USICR = (1 << USIWM0) | (1 << USICS1) | (1 << USICLK); +#else + USICR = SPI_USICR_FAST_2; +#endif + SPI_DIR &= ~(1 << DDB0); /* DI */ + SPI_DIR |= (1 << DDB1); /* DO */ + SPI_DIR |= (1 << DDB2); /* SCLK */ + SPI_DIR |= (1 << DDB3); /* CS */ +} -- cgit v1.2.3 From 0623bc06a77536b903da09acbd12999d0ed05360 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 29 Oct 2012 11:43:02 -0700 Subject: altos/attiny: Update to new interrupt macros Add ao_arch_block/release_interrupts macros to attiny architecture Signed-off-by: Keith Packard --- src/attiny/ao_arch.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/attiny') diff --git a/src/attiny/ao_arch.h b/src/attiny/ao_arch.h index c34206e6..52bed981 100644 --- a/src/attiny/ao_arch.h +++ b/src/attiny/ao_arch.h @@ -64,6 +64,9 @@ #define ao_arch_critical(b) do { cli(); do { b } while (0); sei(); } while (0) +#define ao_arch_block_interrupts() cli() +#define ao_arch_release_interrupts() sei() + #define ao_mutex_get(m) #define ao_mutex_put(m) -- cgit v1.2.3 From e8a4a00a5bb333d4ee9601d53242a82dfe0372c2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 30 Oct 2012 19:39:55 -0700 Subject: altos/attiny: Don't initialize the CS pin in the general SPI setup Let the CS pin be configured by the driver, which can set the correct value before enabling the output. Signed-off-by: Keith Packard --- src/attiny/ao_spi_attiny.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/attiny') diff --git a/src/attiny/ao_spi_attiny.c b/src/attiny/ao_spi_attiny.c index 064876d7..3c4afb02 100644 --- a/src/attiny/ao_spi_attiny.c +++ b/src/attiny/ao_spi_attiny.c @@ -119,5 +119,4 @@ ao_spi_init(void) SPI_DIR &= ~(1 << DDB0); /* DI */ SPI_DIR |= (1 << DDB1); /* DO */ SPI_DIR |= (1 << DDB2); /* SCLK */ - SPI_DIR |= (1 << DDB3); /* CS */ } -- cgit v1.2.3 From 371da0c909098092db7b596496df9d58eed43703 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 30 Oct 2012 19:41:08 -0700 Subject: altos/micropeak: Clock micropeak at 250kHz to save power This reduces average current consumption from 2mA to .4mA. This makes the battery last longer, but also gets the current under something that the typical CR1025 battery can support. Would be nice to reduce current even further; cheap CR1025 batteries still seem to fade a bit at this current level. Signed-off-by: Keith Packard --- src/attiny/ao_clock.c | 40 +++++++++++++++++++++++++++++++++++----- src/micropeak/ao_pins.h | 2 +- 2 files changed, 36 insertions(+), 6 deletions(-) (limited to 'src/attiny') diff --git a/src/attiny/ao_clock.c b/src/attiny/ao_clock.c index a381b47f..b40f59d4 100644 --- a/src/attiny/ao_clock.c +++ b/src/attiny/ao_clock.c @@ -39,12 +39,45 @@ ao_time(void) return r; } +#if AVR_CLOCK == 8000000UL +#define AO_CLKPS 0 /* divide by 1 */ +#define AO_CS 10 /* prescale by 512 */ +#endif +#if AVR_CLOCK == 4000000UL +#define AO_CLKPS 1 /* divide by 2 */ +#define AO_CS 9 /* prescale by 256 */ +#endif +#if AVR_CLOCK == 2000000UL +#define AO_CLKPS 2 /* divide by 4 */ +#define AO_CS 8 /* prescale by 128 */ +#endif +#if AVR_CLOCK == 1000000UL +#define AO_CLKPS 3 /* divide by 8 */ +#define AO_CS 7 /* prescale by 64 */ +#endif +#if AVR_CLOCK == 500000UL +#define AO_CLKPS 4 /* divide by 16 */ +#define AO_CS 6 /* prescale by 32 */ +#endif +#if AVR_CLOCK == 250000UL +#define AO_CLKPS 5 /* divide by 32 */ +#define AO_CS 5 /* prescale by 16 */ +#endif +#if AVR_CLOCK == 125000UL +#define AO_CLKPS 6 /* divide by 64 */ +#define AO_CS 4 /* prescale by 32 */ +#endif +#if AVR_CLOCK == 62500UL +#define AO_CLKPS 7 /* divide by 128 */ +#define AO_CS 4 /* prescale by 32 */ +#endif + void ao_timer_init(void) { cli(); CLKPR = (1 << CLKPCE); - CLKPR = 0; + CLKPR = (AO_CLKPS << CLKPS0); sei(); /* Overall division ratio is 512 * 125, @@ -55,10 +88,7 @@ ao_timer_init(void) (0 << PWM1A) | /* Not PWM mode */ (0 << COM1A0) | /* Don't change output pins */ (0 << COM1A1) | /* ... */ - (1 << CS13) | /* Prescale by 512 */ - (0 << CS12) | /* ... */ - (1 << CS11) | /* ... */ - (0 << CS10)); /* ... */ + (AO_CS << CS10)); /* Prescale */ GTCCR = ((0 << PWM1B) | /* Not PWM mode */ (0 << COM1B1) | /* Don't change output pins */ (0 << COM1B0) | /* ... */ diff --git a/src/micropeak/ao_pins.h b/src/micropeak/ao_pins.h index 67de1a8e..cf5951df 100644 --- a/src/micropeak/ao_pins.h +++ b/src/micropeak/ao_pins.h @@ -32,7 +32,7 @@ #define HAS_MS5611 0 #define HAS_EEPROM 0 #define HAS_BEEP 0 -#define AVR_CLOCK 8000000UL +#define AVR_CLOCK 250000UL /* SPI */ #define SPI_PORT PORTB -- cgit v1.2.3 From fcdaa0d748058a7f52a1bdc1a1627dc394762e5a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 30 Oct 2012 19:56:51 -0700 Subject: altos/attiny: Remove debugging code which frobs PB1 This was clearly stuck there to debug something; not a good idea... Signed-off-by: Keith Packard --- src/attiny/ao_clock.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/attiny') diff --git a/src/attiny/ao_clock.c b/src/attiny/ao_clock.c index b40f59d4..22de8e99 100644 --- a/src/attiny/ao_clock.c +++ b/src/attiny/ao_clock.c @@ -22,7 +22,6 @@ static volatile AO_TICK_TYPE ao_wakeup_count; ISR(TIMER1_COMPA_vect) { - PORTB ^= 2; ++ao_tick_count; if ((int16_t) (ao_tick_count - ao_wakeup_count) >= 0) ao_wakeup((void *) &ao_tick_count); -- cgit v1.2.3 From 6f3bbb11880f45284f1f094990ffa32a66bf4560 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 22 Apr 2013 20:24:48 -0500 Subject: altos: Move ao_notask to core The STM flash loader wants to be taskless too, share this very simple implementation of sleep/wakeup. Signed-off-by: Keith Packard --- src/attiny/ao_arch.h | 2 +- src/core/ao.h | 2 ++ src/core/ao_notask.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/core/ao_notask.h | 27 +++++++++++++++++++++++++++ src/micropeak/ao_notask.c | 45 --------------------------------------------- 5 files changed, 75 insertions(+), 46 deletions(-) create mode 100644 src/core/ao_notask.c create mode 100644 src/core/ao_notask.h delete mode 100644 src/micropeak/ao_notask.c (limited to 'src/attiny') diff --git a/src/attiny/ao_arch.h b/src/attiny/ao_arch.h index 52bed981..8140dd30 100644 --- a/src/attiny/ao_arch.h +++ b/src/attiny/ao_arch.h @@ -55,7 +55,7 @@ #define putchar(c) ao_putchar(c) #define getchar ao_getchar -#define ao_arch_cpu_idle() do { \ +#define ao_arch_wait_interrupt() do { \ sleep_enable(); \ sei(); \ sleep_cpu(); \ diff --git a/src/core/ao.h b/src/core/ao.h index 6bcb3664..0ad3e4aa 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -45,6 +45,8 @@ #if HAS_TASK #include +#else +#include #endif /* diff --git a/src/core/ao_notask.c b/src/core/ao_notask.c new file mode 100644 index 00000000..a41712d2 --- /dev/null +++ b/src/core/ao_notask.c @@ -0,0 +1,45 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include + +static volatile void *ao_wchan; + +uint8_t +ao_sleep(__xdata void *wchan) +{ +#if 1 + ao_wchan = wchan; + ao_arch_wait_interrupt(); +#else + uint8_t sreg; + + ao_wchan = wchan; + asm("in %0,__SREG__" : "=&r" (sreg)); + sei(); + while (ao_wchan) + ao_arch_cpu_idle(); + asm("out __SREG__,%0" : : "r" (sreg)); +#endif + return 0; +} + +void +ao_wakeup(__xdata void *wchan) +{ + ao_wchan = 0; +} diff --git a/src/core/ao_notask.h b/src/core/ao_notask.h new file mode 100644 index 00000000..6b6b5bb8 --- /dev/null +++ b/src/core/ao_notask.h @@ -0,0 +1,27 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_NOTASK_H_ +#define _AO_NOTASK_H_ + +uint8_t +ao_sleep(__xdata void *wchan); + +void +ao_wakeup(__xdata void *wchan); + +#endif /* _AO_NOTASK_H_ */ diff --git a/src/micropeak/ao_notask.c b/src/micropeak/ao_notask.c deleted file mode 100644 index 0aef9cf3..00000000 --- a/src/micropeak/ao_notask.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#include - -static volatile void *ao_wchan; - -uint8_t -ao_sleep(__xdata void *wchan) -{ -#if 1 - ao_wchan = wchan; - ao_arch_cpu_idle(); -#else - uint8_t sreg; - - ao_wchan = wchan; - asm("in %0,__SREG__" : "=&r" (sreg)); - sei(); - while (ao_wchan) - ao_arch_cpu_idle(); - asm("out __SREG__,%0" : : "r" (sreg)); -#endif - return 0; -} - -void -ao_wakeup(__xdata void *wchan) -{ - ao_wchan = 0; -} -- cgit v1.2.3