delete old firmware
This commit is contained in:
parent
e8564c7a96
commit
01abdb3287
|
@ -1,79 +0,0 @@
|
||||||
PROJECT=pentabug
|
|
||||||
|
|
||||||
OPTIMIZATION = -Os
|
|
||||||
MCU = atmega88pa
|
|
||||||
F_CPU = 8000000
|
|
||||||
QUARZ = 8MHZ
|
|
||||||
FUSES = lfuse:w:0xe2:m -U hfuse:w:0xdf:m -U efuse:w:0x01:m
|
|
||||||
|
|
||||||
#########################################################################
|
|
||||||
|
|
||||||
SRC=$(wildcard lib/*.c apps/*.c *.c)
|
|
||||||
OBJECTS= $(SRC:.c=.o)
|
|
||||||
LSTFILES= $(SRC:.c=.lst)
|
|
||||||
HEADERS=$(wildcard lib/*.h *.h)
|
|
||||||
|
|
||||||
# Compiler Options
|
|
||||||
GCFLAGS = -ffreestanding -std=gnu99 -mmcu=$(MCU) $(OPTIMIZATION) -Wl,-gc-sections -nostdlib -I.
|
|
||||||
# Warnings
|
|
||||||
GCFLAGS += -Wstrict-prototypes -Wundef -Wall -Wextra -Wunreachable-code
|
|
||||||
# Optimizazions
|
|
||||||
GCFLAGS += -fsingle-precision-constant -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -fno-builtin -ffunction-sections -fno-common -fdata-sections
|
|
||||||
# Debug stuff
|
|
||||||
GCFLAGS += -Wa,-adhlns=$(<:.c=.lst),-gstabs -g
|
|
||||||
|
|
||||||
GCFLAGS += -DF_CPU=$(F_CPU) -DQUARZ=$(QUARZ)
|
|
||||||
|
|
||||||
LDFLAGS = -mmcu=$(MCU) $(OPTIMIZATION) -gc-sections
|
|
||||||
|
|
||||||
|
|
||||||
# Paths
|
|
||||||
GCC = avr-gcc
|
|
||||||
OBJCOPY = avr-objcopy
|
|
||||||
REMOVE = rm -f
|
|
||||||
SIZE = avr-size
|
|
||||||
AVRDUDE = avrdude
|
|
||||||
|
|
||||||
#########################################################################
|
|
||||||
|
|
||||||
all: $(PROJECT).hex Makefile
|
|
||||||
@$(SIZE) --mcu=$(MCU) --format=avr $(PROJECT).elf
|
|
||||||
|
|
||||||
$(PROJECT).hex: $(PROJECT).elf Makefile
|
|
||||||
@echo " \033[1;34mOBJCOPY\033[0m $(PROJECT).elf -> $(PROJECT).hex"
|
|
||||||
@$(OBJCOPY) -O ihex -R .eeprom $(PROJECT).elf $(PROJECT).hex
|
|
||||||
|
|
||||||
$(PROJECT).elf: $(OBJECTS) Makefile
|
|
||||||
@echo " \033[1;34mLink \033[0m (\033[1;33m $(OBJECTS)\033[0m) -> $(PROJECT).elf"
|
|
||||||
@$(GCC) $(OBJECTS) $(LDFLAGS) -o $(PROJECT).elf
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(REMOVE) $(OBJECTS)
|
|
||||||
$(REMOVE) $(LSTFILES)
|
|
||||||
$(REMOVE) $(PROJECT).hex
|
|
||||||
$(REMOVE) $(PROJECT).elf
|
|
||||||
|
|
||||||
#########################################################################
|
|
||||||
|
|
||||||
%.o: %.c Makefile $(HEADERS)
|
|
||||||
@echo " \033[1;34mCompile\033[0m $<"
|
|
||||||
@$(GCC) $(GCFLAGS) -o $@ -c $<
|
|
||||||
|
|
||||||
|
|
||||||
#########################################################################
|
|
||||||
|
|
||||||
fuse:
|
|
||||||
$(AVRDUDE) -p m88 -F -c usbtiny -v -v -U $(FUSES)
|
|
||||||
|
|
||||||
flash: $(PROJECT).hex Makefile
|
|
||||||
$(AVRDUDE) -p m88 -F -c usbtiny -B 1 -U flash:w:$(PROJECT).hex
|
|
||||||
|
|
||||||
fljohn: $(PROJECT).hex Makefile
|
|
||||||
$(AVRDUDE) -p m88 -F -P /dev/serial/by-id/usb-FTDI_USB__-__Serial-if00-port0 -c stk500v2 -v -v -U flash:w:$(PROJECT).hex
|
|
||||||
|
|
||||||
flsmart: $(PROJECT).hex Makefile
|
|
||||||
$(AVRDUDE) -p m88 -F -P /dev/ttyUSB0 -c stk500v2 -v -v -U flash:w:$(PROJECT).hex
|
|
||||||
|
|
||||||
|
|
||||||
.PHONY : clean all fuse flash fljohn
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
## Firmware
|
|
||||||
|
|
||||||
This firmware is to be flashed to the atmega88 of the pentabug.
|
|
||||||
The Makefile supports 2 different ways of flashing the firmware image:
|
|
||||||
|
|
||||||
### the serial bootloader way
|
|
||||||
|
|
||||||
With the
|
|
||||||
|
|
||||||
make serflash
|
|
||||||
|
|
||||||
target of the Makefile You can flash the microcontroler via the serial bootloader that is part of the initial firmware.
|
|
||||||
|
|
||||||
|
|
||||||
### the isp way
|
|
||||||
|
|
||||||
With the
|
|
||||||
|
|
||||||
make flash
|
|
||||||
|
|
||||||
target of the Makefile you can flash the microcontroler via an isp programmer.
|
|
||||||
Adjust the avrdude settings to Your programmers needs beforehand.
|
|
||||||
|
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
#include <inttypes.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <avr/io.h>
|
|
||||||
|
|
||||||
#include "../lib/apps.h"
|
|
||||||
#include "../lib/bughal.h"
|
|
||||||
#include "../lib/util.h"
|
|
||||||
#include "../lib/music.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* just blink mode
|
|
||||||
* - left/right button switch motor off/on
|
|
||||||
*/
|
|
||||||
static void blink(void)
|
|
||||||
{
|
|
||||||
static timer_t mytimer;
|
|
||||||
static bool blink;
|
|
||||||
if (mode_uninitialized) {
|
|
||||||
init_leds();
|
|
||||||
mode_uninitialized = false;
|
|
||||||
music_setNote(NOTE_PAUSE, 4); //mute
|
|
||||||
set_motor(MOTOR_OFF);
|
|
||||||
timer_set(&mytimer, 10);
|
|
||||||
blink = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timer_expired(&mytimer)) {
|
|
||||||
if (!blink) {
|
|
||||||
/*lets blink*/
|
|
||||||
led_on(LED_L | LED_R);
|
|
||||||
timer_set(&mytimer, 1);
|
|
||||||
blink = true;
|
|
||||||
} else {
|
|
||||||
/*stop blink*/
|
|
||||||
led_off(LED_L | LED_R);
|
|
||||||
timer_set(&mytimer, 123);
|
|
||||||
blink = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}//end if timer_expired
|
|
||||||
|
|
||||||
if (btn_state(BTNST_SUP, BTN_LEFT)) {
|
|
||||||
button_clear(BTN_LEFT);
|
|
||||||
set_motor(MOTOR_OFF);
|
|
||||||
|
|
||||||
}
|
|
||||||
if (btn_state(BTNST_SUP, BTN_RIGHT)) {
|
|
||||||
button_clear(BTN_RIGHT);
|
|
||||||
set_motor(MOTOR_ON);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
REGISTER(blink)
|
|
||||||
|
|
|
@ -1,89 +0,0 @@
|
||||||
#include <inttypes.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <avr/io.h>
|
|
||||||
|
|
||||||
#include "../lib/apps.h"
|
|
||||||
#include "../lib/bughal.h"
|
|
||||||
#include "../lib/util.h"
|
|
||||||
#include "../lib/music.h"
|
|
||||||
#include "../lib/usart.h"
|
|
||||||
|
|
||||||
inline uint16_t biased_random(uint16_t value) {
|
|
||||||
return value / 8 * (rand() & 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void led_sound(void)
|
|
||||||
{
|
|
||||||
static bool discharge;
|
|
||||||
static timer_t mytimer;
|
|
||||||
uint16_t led1;
|
|
||||||
|
|
||||||
if(mode_last_tick) {
|
|
||||||
led_off(LED_L | LED_R);
|
|
||||||
set_motor(MOTOR_OFF);
|
|
||||||
music_setNote(NOTE_PAUSE, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode_uninitialized) {
|
|
||||||
mode_uninitialized = false;
|
|
||||||
set_motor(MOTOR_OFF);
|
|
||||||
ADMUX = (1 << REFS0); // use VCC reference
|
|
||||||
ADCSRA = (1 << ADPS1) | (1 << ADPS0); // prescaler F_CPU/8
|
|
||||||
ADCSRA |= (1 << ADEN); // ADC enable - turn it on
|
|
||||||
|
|
||||||
timer_set(&mytimer, 10);
|
|
||||||
discharge = true;
|
|
||||||
}
|
|
||||||
if (timer_expired(&mytimer)) {
|
|
||||||
if (discharge) {
|
|
||||||
led_off(LED_R | LED_L);
|
|
||||||
|
|
||||||
DDRC |= (1 << PORTC0) | (1 << PORTC1); //set LED Ports to output:
|
|
||||||
/*discharge*/
|
|
||||||
PORTC = (PORTC & 0b11110000);
|
|
||||||
/*set C0 and C2 to input (disable pullups)*/
|
|
||||||
DDRC &= ~(1 << PORTC0); //set Led Ports to input
|
|
||||||
/*pull ups off*/
|
|
||||||
PORTC &= ~(1 << PORTC0);
|
|
||||||
discharge = false;
|
|
||||||
|
|
||||||
timer_set(&mytimer, 1);
|
|
||||||
} else {
|
|
||||||
/*single measurement*/
|
|
||||||
ADMUX = (ADMUX & ~(0x1F)) | 0; // select channel 0
|
|
||||||
ADCSRA |= (1 << ADSC); // start single conversion
|
|
||||||
while (ADCSRA & (1 << ADSC)) ; // wait for conversion to end
|
|
||||||
led1 = ADCW; // read result
|
|
||||||
|
|
||||||
DDRC |= (1 << PORTC0) | (1 << PORTC1); //set LED Ports to output:
|
|
||||||
|
|
||||||
set_motor(biased_random(led1) > 0x50 ? MOTOR_ON : MOTOR_OFF);
|
|
||||||
|
|
||||||
if(biased_random(led1) > 0x20) {
|
|
||||||
led_on(LED_R);
|
|
||||||
} else {
|
|
||||||
led_off(LED_R);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(biased_random(led1) > 0x20) {
|
|
||||||
led_on(LED_L);
|
|
||||||
} else {
|
|
||||||
led_off(LED_L);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(biased_random(led1) > 0x90) {
|
|
||||||
uint16_t tone = (biased_random(led1) * 2) + 500;
|
|
||||||
music_setNote(tone, 0);
|
|
||||||
} else {
|
|
||||||
music_setNote(NOTE_PAUSE, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
discharge = true;
|
|
||||||
|
|
||||||
timer_set(&mytimer, 20);
|
|
||||||
}
|
|
||||||
} //end if timer_expired
|
|
||||||
} //end mode5
|
|
||||||
|
|
||||||
REGISTER(led_sound)
|
|
|
@ -1,134 +0,0 @@
|
||||||
#include <inttypes.h>
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include <avr/interrupt.h>
|
|
||||||
#define __DELAY_BACKWARD_COMPATIBLE__
|
|
||||||
#include <util/delay.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
#include "../lib/freq_table.h"
|
|
||||||
#include <lib/bughal.h>
|
|
||||||
|
|
||||||
#include <lib/timer.h>
|
|
||||||
#include <lib/apps.h>
|
|
||||||
|
|
||||||
void tetris_play(void);
|
|
||||||
|
|
||||||
static uint16_t osc0;
|
|
||||||
static uint16_t osc1;
|
|
||||||
static uint16_t sample;
|
|
||||||
static uint8_t row;
|
|
||||||
static uint16_t speedtime;
|
|
||||||
|
|
||||||
|
|
||||||
void synth_init(void){
|
|
||||||
init_buzzr();
|
|
||||||
|
|
||||||
osc0 = osc1 = sample = row = 0;
|
|
||||||
speedtime = 3000;
|
|
||||||
|
|
||||||
start_timer(tetris_play);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void synth_deinit(void) {
|
|
||||||
stop_timer();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum {
|
|
||||||
SONG_LENGTH = 128,
|
|
||||||
xxx = 0,
|
|
||||||
c_0 = 0, cs0 = 1, d_0 = 2, ds0 = 3, e_0 = 4, f_0 = 5,
|
|
||||||
fs0 = 6, g_0 = 7, gs0 = 8, a_0 = 9, as0 = 10, b_0 = 11,
|
|
||||||
c_1 = 12, cs1 = 13, d_1 = 14, ds1 = 15, e_1 = 16, f_1 = 17,
|
|
||||||
fs1 = 18, g_1 = 19, gs1 = 20, a_1 = 21, as1 = 22, b_1 = 23,
|
|
||||||
c_2 = 24, cs2 = 25, d_2 = 26, ds2 = 27, e_2 = 28, f_2 = 29,
|
|
||||||
fs2 = 30, g_2 = 31, gs2 = 32, a_2 = 33, as2 = 34, b_2 = 35,
|
|
||||||
c_3 = 36, cs3 = 37, d_3 = 38, ds3 = 39, e_3 = 40, f_3 = 41,
|
|
||||||
fs3 = 42, g_3 = 43, gs3 = 44, a_3 = 45, as3 = 46, b_3 = 47,
|
|
||||||
};
|
|
||||||
|
|
||||||
const char music_data[2][SONG_LENGTH] PROGMEM = {
|
|
||||||
{
|
|
||||||
e_1, xxx, e_2, xxx, e_1, xxx, e_2, xxx,
|
|
||||||
e_1, xxx, e_2, xxx, e_1, xxx, e_2, xxx,
|
|
||||||
a_0, xxx, a_1, xxx, a_0, xxx, a_1, xxx,
|
|
||||||
a_0, xxx, a_1, xxx, a_0, xxx, a_1, xxx,
|
|
||||||
gs0, xxx, gs1, xxx, gs0, xxx, gs1, xxx,
|
|
||||||
gs0, xxx, gs1, xxx, gs0, xxx, gs1, xxx,
|
|
||||||
a_0, xxx, a_1, xxx, a_0, xxx, a_1, xxx,
|
|
||||||
a_0, xxx, a_0, xxx, b_0, xxx, c_1, xxx,
|
|
||||||
d_1, xxx, d_2, xxx, d_1, xxx, d_2, xxx,
|
|
||||||
d_1, xxx, d_2, xxx, d_1, xxx, d_2, xxx,
|
|
||||||
c_1, xxx, c_2, xxx, c_1, xxx, c_2, xxx,
|
|
||||||
c_1, xxx, c_2, xxx, c_1, xxx, c_2, xxx,
|
|
||||||
b_0, xxx, b_1, xxx, b_0, xxx, b_1, xxx,
|
|
||||||
b_0, xxx, b_1, xxx, b_0, xxx, b_1, xxx,
|
|
||||||
a_0, xxx, a_1, xxx, a_0, xxx, a_1, xxx,
|
|
||||||
a_0, xxx, xxx, xxx, xxx, xxx, xxx, xxx,
|
|
||||||
}, {
|
|
||||||
e_3, e_3, e_3, e_3, b_2, b_2, c_3, c_3,
|
|
||||||
d_3, d_3, e_3, d_3, c_3, c_3, b_2, b_2,
|
|
||||||
a_2, a_2, a_2, a_2, a_2, a_2, c_3, c_3,
|
|
||||||
e_3, e_3, e_3, e_3, d_3, d_3, c_3, c_3,
|
|
||||||
b_2, b_2, b_2, b_2, b_2, b_2, c_3, c_3,
|
|
||||||
d_3, d_3, d_3, d_3, e_3, e_3, e_3, e_3,
|
|
||||||
c_3, c_3, c_3, c_3, a_2, a_2, a_2, a_2,
|
|
||||||
a_2, a_2, a_2, a_2, a_2, a_2, a_2, a_2,
|
|
||||||
xxx, xxx, d_3, d_3, d_3, d_3, f_3, f_3,
|
|
||||||
a_3, a_3, a_3, a_3, g_3, g_3, f_3, f_3,
|
|
||||||
e_3, e_3, e_3, e_3, e_3, e_3, c_3, c_3,
|
|
||||||
e_3, e_3, e_3, e_3, d_3, d_3, c_3, c_3,
|
|
||||||
b_2, b_2, b_2, b_2, b_2, b_2, c_3, c_3,
|
|
||||||
d_3, d_3, d_3, d_3, e_3, e_3, e_3, e_3,
|
|
||||||
c_3, c_3, c_3, c_3, a_2, a_2, a_2, a_2,
|
|
||||||
a_2, a_2, a_2, a_2, xxx, xxx, xxx, xxx,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void tetris_play(void) {
|
|
||||||
osc0 += pgm_read_word(&freq_table[ pgm_read_byte(&music_data[0][row])]);
|
|
||||||
osc1 += pgm_read_word(&freq_table[ pgm_read_byte(&music_data[1][row])]);
|
|
||||||
if (++sample == speedtime ) {
|
|
||||||
sample = 0;
|
|
||||||
if (speedtime > 600) speedtime -= 4;
|
|
||||||
if (++row == SONG_LENGTH) {
|
|
||||||
row = 0;
|
|
||||||
if (speedtime <= 600) speedtime = 3000;
|
|
||||||
}
|
|
||||||
led_on(row&4 ? LED_R : LED_L);
|
|
||||||
led_off(row&4 ? LED_L : LED_R);
|
|
||||||
}
|
|
||||||
if (osc0 >= 0x8000) PORTB |= (1 << PORTB2);
|
|
||||||
else PORTB &= ~(1<< PORTB2);
|
|
||||||
if (osc1 >= 0xc000) PORTC |= (1 << PORTC5);
|
|
||||||
else PORTC &= ~(1<< PORTC5);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* do crazy synthesizer mode
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static void crazy_synth(void)
|
|
||||||
{
|
|
||||||
/* initialisation required */
|
|
||||||
if (mode_uninitialized) {
|
|
||||||
mode_uninitialized = false;
|
|
||||||
synth_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*deinialisation required */
|
|
||||||
if (mode_last_tick) {
|
|
||||||
synth_deinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
REGISTER(crazy_synth)
|
|
||||||
|
|
|
@ -1,73 +0,0 @@
|
||||||
#include <inttypes.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <avr/io.h>
|
|
||||||
|
|
||||||
#include "../lib/apps.h"
|
|
||||||
#include "../lib/bughal.h"
|
|
||||||
#include "../lib/util.h"
|
|
||||||
#include "../lib/music.h"
|
|
||||||
#include "../lib/usart.h"
|
|
||||||
|
|
||||||
static void led_sound(void)
|
|
||||||
{
|
|
||||||
static bool discharge;
|
|
||||||
static timer_t mytimer;
|
|
||||||
uint16_t led1;
|
|
||||||
uint16_t led2;
|
|
||||||
|
|
||||||
if (mode_uninitialized) {
|
|
||||||
mode_uninitialized = false;
|
|
||||||
set_motor(MOTOR_OFF);
|
|
||||||
ADMUX = (1 << REFS0); // use VCC reference
|
|
||||||
ADCSRA = (1 << ADPS1) | (1 << ADPS0); // prescaler F_CPU/8
|
|
||||||
ADCSRA |= (1 << ADEN); // ADC enable - turn it on
|
|
||||||
/*do one conversion*/
|
|
||||||
ADCSRA |= (1 << ADSC);
|
|
||||||
while (ADCSRA & (1 << ADSC)) {
|
|
||||||
/*wait for conversion to end */
|
|
||||||
}
|
|
||||||
uint16_t __attribute__ ((unused)) dummy = ADCW; //read once
|
|
||||||
timer_set(&mytimer, 10);
|
|
||||||
discharge = true;
|
|
||||||
}
|
|
||||||
if (timer_expired(&mytimer)) {
|
|
||||||
if (discharge) {
|
|
||||||
DDRC |= (1 << PORTC0) | (1 << PORTC1) | //set LED Ports to output:
|
|
||||||
(1 << PORTC2) | (1 << PORTC3);
|
|
||||||
/*discharge*/
|
|
||||||
PORTC = (PORTC & 0b11110000);
|
|
||||||
/*set C0 and C2 to input (disable pullups)*/
|
|
||||||
DDRC &= ~((1 << PORTC0) | (1 << PORTC2)); //set Led Ports to input
|
|
||||||
/*pull ups off*/
|
|
||||||
PORTC &= ~((1 << PORTC0) | (1 << PORTC2));
|
|
||||||
discharge = false;
|
|
||||||
} else {
|
|
||||||
/*single measurement*/
|
|
||||||
ADMUX = (ADMUX & ~(0x1F)) | 0; // select channel 0
|
|
||||||
ADCSRA |= (1 << ADSC); // start single conversion
|
|
||||||
while (ADCSRA & (1 << ADSC)) ; // wait for conversion to end
|
|
||||||
led1 = ADCW; // read result
|
|
||||||
|
|
||||||
ADMUX = (ADMUX & ~(0x1F)) | 2; // select channel 2
|
|
||||||
ADCSRA |= (1 << ADSC); // start single conversion
|
|
||||||
while (ADCSRA & (1 << ADSC)) ; // wait for conversion to end
|
|
||||||
led2 = ADCW; // read result
|
|
||||||
#if 0
|
|
||||||
USART0_putc('1');
|
|
||||||
USART0_putc(':');
|
|
||||||
USART0_put_uint16(led1);
|
|
||||||
USART0_crlf();
|
|
||||||
USART0_putc('2');
|
|
||||||
USART0_putc(':');
|
|
||||||
USART0_put_uint16(led2);
|
|
||||||
USART0_crlf();
|
|
||||||
#endif
|
|
||||||
music_setNote(400 +
|
|
||||||
((0x1ff - led1) + (0x1ff - led2)) * 5, 0);
|
|
||||||
discharge = true;
|
|
||||||
}
|
|
||||||
timer_set(&mytimer, 2); //relaunch timer
|
|
||||||
} //end if timer_expired
|
|
||||||
} //end mode5
|
|
||||||
|
|
||||||
REGISTER(led_sound)
|
|
|
@ -1,65 +0,0 @@
|
||||||
#include <inttypes.h>
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include <avr/interrupt.h>
|
|
||||||
#define __DELAY_BACKWARD_COMPATIBLE__
|
|
||||||
#include <util/delay.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
#include <lib/bughal.h>
|
|
||||||
#include <lib/freq_table.h>
|
|
||||||
#include <lib/apps.h>
|
|
||||||
|
|
||||||
static uint16_t osc;
|
|
||||||
static uint16_t sample;
|
|
||||||
static uint8_t row;
|
|
||||||
|
|
||||||
|
|
||||||
#define LENGTH(x) (sizeof(x) / sizeof(x[0]))
|
|
||||||
static const uint8_t mushroom[] = {6,1,6,10,13,18,13,1,6,8,13,8,13,18,20,25,20,3,8,11,15,11,15,20,23,27,23};
|
|
||||||
|
|
||||||
static void mariofx_ISR(void) {
|
|
||||||
if (row < LENGTH(mushroom)) {
|
|
||||||
osc += pgm_read_word(&freq_table[mushroom[row] + 18]) * 3;
|
|
||||||
if (++sample == 800 ) {
|
|
||||||
sample = 0;
|
|
||||||
row++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (btn_state(BTNST_SUP, BTN_RIGHT)) {
|
|
||||||
button_clear(BTN_RIGHT);
|
|
||||||
row = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (osc >= 0xc000) {
|
|
||||||
PORTB |= (1 << PORTB2);
|
|
||||||
PORTC &= ~(1<< PORTC5);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
PORTB &= ~(1<< PORTB2);
|
|
||||||
PORTC |= (1 << PORTC5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void mariofx(void) {
|
|
||||||
/* initialisation required */
|
|
||||||
if (mode_uninitialized) {
|
|
||||||
mode_uninitialized = false;
|
|
||||||
|
|
||||||
init_buzzr();
|
|
||||||
osc = sample = row = 0;
|
|
||||||
start_timer(mariofx_ISR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*deinialisation required */
|
|
||||||
if (mode_last_tick) {
|
|
||||||
stop_timer();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
REGISTER(mariofx);
|
|
|
@ -1,92 +0,0 @@
|
||||||
#include <inttypes.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <avr/io.h>
|
|
||||||
|
|
||||||
#include "../lib/apps.h"
|
|
||||||
#include "../lib/bughal.h"
|
|
||||||
#include "../lib/util.h"
|
|
||||||
#include "../lib/music.h"
|
|
||||||
#include "../lib/usart.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* sound detection mode
|
|
||||||
* beeps,blinks and moves when sound is detected
|
|
||||||
* - beep on/off left switch (short)
|
|
||||||
* - motor on/off right switch (short)
|
|
||||||
*/
|
|
||||||
static void sound_detection(void)
|
|
||||||
{
|
|
||||||
if(mode_last_tick) {
|
|
||||||
led_off(LED_L | LED_R);
|
|
||||||
set_motor(MOTOR_OFF);
|
|
||||||
music_setNote(NOTE_PAUSE, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static timer_t mytimer;
|
|
||||||
static uint16_t maxval; // maximum of ADC values read during the las timer interval
|
|
||||||
static uint16_t lastmaxval; // maximum of values during last timer interval
|
|
||||||
uint16_t curval; // value on D5 (pin of piezo,the other is on GND)
|
|
||||||
static bool signaling; // are we currently signaling (beeping, blinking etc...)
|
|
||||||
static bool sound_on; // should sound be on when signaling
|
|
||||||
static bool motor_on; // should motor be on when signaling
|
|
||||||
|
|
||||||
if (mode_uninitialized) { //init after mode change
|
|
||||||
maxval = 0;
|
|
||||||
lastmaxval = 0;
|
|
||||||
mode_uninitialized = false;
|
|
||||||
signaling = false;
|
|
||||||
sound_on = true;
|
|
||||||
motor_on = true;
|
|
||||||
init_mic();
|
|
||||||
init_leds();
|
|
||||||
timer_set(&mytimer, 10);
|
|
||||||
}
|
|
||||||
/*single ADC measurement*/
|
|
||||||
curval = ADCW; // read result
|
|
||||||
maxval = (curval > maxval) ? curval : maxval;
|
|
||||||
|
|
||||||
/*check for Buttons*/
|
|
||||||
if (btn_state(BTNST_SUP, BTN_LEFT)) {
|
|
||||||
button_clear(BTN_LEFT);
|
|
||||||
sound_on = !sound_on;
|
|
||||||
}
|
|
||||||
if (btn_state(BTNST_SUP, BTN_RIGHT)) {
|
|
||||||
button_clear(BTN_RIGHT);
|
|
||||||
motor_on = !motor_on;
|
|
||||||
}
|
|
||||||
if (timer_expired(&mytimer)) {
|
|
||||||
if (signaling) {
|
|
||||||
//turn off sound
|
|
||||||
music_setNote(NOTE_PAUSE, 0); //mute
|
|
||||||
set_motor(MOTOR_OFF);
|
|
||||||
//re-init mic
|
|
||||||
init_mic();
|
|
||||||
led_off(LED_R | LED_L);
|
|
||||||
timer_set(&mytimer, 1);
|
|
||||||
signaling = false;
|
|
||||||
lastmaxval = 10000;
|
|
||||||
} else { //sound was off wer're in measuring mode
|
|
||||||
if (maxval > lastmaxval) {
|
|
||||||
USART0_put_uint16(maxval);
|
|
||||||
USART0_crlf();
|
|
||||||
led_on(LED_R | LED_L);
|
|
||||||
init_buzzr(); //buzzr to output
|
|
||||||
if (sound_on)
|
|
||||||
music_setNote(NOTE_C, 5);
|
|
||||||
if (motor_on)
|
|
||||||
set_motor(MOTOR_ON);
|
|
||||||
signaling = true;
|
|
||||||
timer_set(&mytimer, 5); //sound duration
|
|
||||||
} else {
|
|
||||||
timer_set(&mytimer, 1);
|
|
||||||
}
|
|
||||||
lastmaxval = maxval;
|
|
||||||
maxval = 0;
|
|
||||||
}//end if soundon
|
|
||||||
|
|
||||||
}//end if timer_expired
|
|
||||||
|
|
||||||
} /* end mode0 */
|
|
||||||
|
|
||||||
REGISTER(sound_detection)
|
|
|
@ -1,32 +0,0 @@
|
||||||
#ifndef CHIPDEF_H
|
|
||||||
#define CHIPDEF_H
|
|
||||||
|
|
||||||
#include <avr/io.h>
|
|
||||||
|
|
||||||
#if defined (SPMCSR)
|
|
||||||
#define SPM_REG SPMCSR
|
|
||||||
#elif defined (SPMCR)
|
|
||||||
#define SPM_REG SPMCR
|
|
||||||
#else
|
|
||||||
#error "AVR processor does not provide bootloader support!"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define APP_END (FLASHEND - (BOOTSIZE * 2))
|
|
||||||
|
|
||||||
#if (SPM_PAGESIZE > UINT8_MAX)
|
|
||||||
typedef uint16_t pagebuf_t;
|
|
||||||
#else
|
|
||||||
typedef uint8_t pagebuf_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__AVR_ATmega88PA__)
|
|
||||||
#include "mega88.h"
|
|
||||||
|
|
||||||
#elif defined(__AVR_ATmega88__)
|
|
||||||
#include "mega88.h"
|
|
||||||
|
|
||||||
#else
|
|
||||||
#error "no definition for MCU available in chipdef.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,330 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Minimal Bootloader for Atmega644(p/a)
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Based on:
|
|
||||||
*
|
|
||||||
* AVRPROG compatible boot-loader
|
|
||||||
* Version : 0.85 (Dec. 2008)
|
|
||||||
* Compiler : avr-gcc 4.1.2 / avr-libc 1.4.6
|
|
||||||
* size : depends on features and startup ( minmal features < 512 words)
|
|
||||||
* by : Martin Thomas, Kaiserslautern, Germany
|
|
||||||
* eversmith@heizung-thomas.de
|
|
||||||
* Additional code and improvements contributed by:
|
|
||||||
* - Uwe Bonnes
|
|
||||||
* - Bjoern Riemer
|
|
||||||
* - Olaf Rempel
|
|
||||||
*
|
|
||||||
* License : Copyright (c) 2006-2008 M. Thomas, U. Bonnes, O. Rempel
|
|
||||||
* Free to use. You have to mention the copyright
|
|
||||||
* owners in source-code and documentation of derived
|
|
||||||
* work. No warranty! (Yes, you can insert the BSD
|
|
||||||
* license here)
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* MCU frequency */
|
|
||||||
#ifndef F_CPU
|
|
||||||
#define F_CPU 8000000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* UART Baudrate */
|
|
||||||
#define BAUDRATE 115200
|
|
||||||
|
|
||||||
/* use "Double Speed Operation" */
|
|
||||||
#define UART_DOUBLESPEED
|
|
||||||
|
|
||||||
/* use second UART on mega128 / can128 / mega162 / mega324p / mega644p */
|
|
||||||
//#define UART_USE_SECOND
|
|
||||||
/* Device-Type:
|
|
||||||
For AVRProg the BOOT-option is prefered
|
|
||||||
which is the "correct" value for a bootloader.
|
|
||||||
avrdude may only detect the part-code for ISP */
|
|
||||||
#define DEVTYPE DEVTYPE_BOOT
|
|
||||||
// #define DEVTYPE DEVTYPE_ISP
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Pin "STARTPIN" on port "STARTPORT" in this port has to grounded
|
|
||||||
* (active low) to start the bootloader
|
|
||||||
*/
|
|
||||||
#define BLPORT PORTD
|
|
||||||
#define BLDDR DDRD
|
|
||||||
#define BLPIN PIND
|
|
||||||
#define BLPNUM PIND0
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Watchdog-reset is issued at exit
|
|
||||||
* define the timeout-value here (see avr-libc manual)
|
|
||||||
*/
|
|
||||||
#define EXIT_WDT_TIME WDTO_250MS
|
|
||||||
|
|
||||||
void __vector_default(void) {
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* define the following if the bootloader should not output
|
|
||||||
* itself at flash read (will fake an empty boot-section)
|
|
||||||
*/
|
|
||||||
#define READ_PROTECT_BOOTLOADER
|
|
||||||
|
|
||||||
#define VERSION_HIGH '0'
|
|
||||||
#define VERSION_LOW '8'
|
|
||||||
|
|
||||||
#ifdef UART_DOUBLESPEED
|
|
||||||
// #define UART_CALC_BAUDRATE(baudRate) (((F_CPU*10UL) / ((baudRate) *8UL) +5)/10 -1)
|
|
||||||
#define UART_CALC_BAUDRATE(baudRate) ((uint32_t)((F_CPU) + ((uint32_t)baudRate * 4UL)) / ((uint32_t)(baudRate) * 8UL) - 1)
|
|
||||||
#else
|
|
||||||
// #define UART_CALC_BAUDRATE(baudRate) (((F_CPU*10UL) / ((baudRate)*16UL) +5)/10 -1)
|
|
||||||
#define UART_CALC_BAUDRATE(baudRate) ((uint32_t)((F_CPU) + ((uint32_t)baudRate * 8UL)) / ((uint32_t)(baudRate) * 16UL) - 1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include <avr/wdt.h>
|
|
||||||
#include <avr/boot.h>
|
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
//#include <avr/interrupt.h>
|
|
||||||
//#include <util/delay.h>
|
|
||||||
|
|
||||||
#include "chipdef.h"
|
|
||||||
|
|
||||||
uint8_t gBuffer[SPM_PAGESIZE];
|
|
||||||
|
|
||||||
static void sendchar(uint8_t data) {
|
|
||||||
while (!(UART_STATUS & (1 << UART_TXREADY)))
|
|
||||||
;
|
|
||||||
UART_DATA = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t recvchar(void) {
|
|
||||||
while (!(UART_STATUS & (1 << UART_RXREADY)))
|
|
||||||
;
|
|
||||||
return UART_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void eraseFlash(void) {
|
|
||||||
// erase only main section (bootloader protection)
|
|
||||||
uint32_t addr = 0;
|
|
||||||
while (APP_END > addr) {
|
|
||||||
boot_page_erase(addr);
|
|
||||||
// Perform page erase
|
|
||||||
boot_spm_busy_wait(); // Wait until the memory is erased.
|
|
||||||
addr += SPM_PAGESIZE;
|
|
||||||
}
|
|
||||||
boot_rww_enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void recvBuffer(pagebuf_t size) {
|
|
||||||
pagebuf_t cnt;
|
|
||||||
uint8_t *tmp = gBuffer;
|
|
||||||
|
|
||||||
for (cnt = 0; cnt < sizeof(gBuffer); cnt++) {
|
|
||||||
*tmp++ = (cnt < size) ? recvchar() : 0xFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint16_t writeFlashPage(uint16_t waddr, pagebuf_t size) {
|
|
||||||
uint32_t pagestart = (uint32_t) waddr << 1;
|
|
||||||
uint32_t baddr = pagestart;
|
|
||||||
uint16_t data;
|
|
||||||
uint8_t *tmp = gBuffer;
|
|
||||||
|
|
||||||
do {
|
|
||||||
data = *tmp++;
|
|
||||||
data |= *tmp++ << 8;
|
|
||||||
|
|
||||||
if (baddr < APP_END) {
|
|
||||||
boot_page_fill(baddr, data);
|
|
||||||
// call asm routine.
|
|
||||||
}
|
|
||||||
|
|
||||||
baddr += 2; // Select next word in memory
|
|
||||||
size -= 2; // Reduce number of bytes to write by two
|
|
||||||
} while (size); // Loop until all bytes written
|
|
||||||
|
|
||||||
boot_page_write(pagestart);
|
|
||||||
boot_spm_busy_wait();
|
|
||||||
boot_rww_enable(); // Re-enable the RWW section
|
|
||||||
|
|
||||||
return baddr >> 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint16_t readFlashPage(uint16_t waddr, pagebuf_t size) {
|
|
||||||
uint32_t baddr = (uint32_t) waddr << 1;
|
|
||||||
uint16_t data;
|
|
||||||
|
|
||||||
do {
|
|
||||||
#ifndef READ_PROTECT_BOOTLOADER
|
|
||||||
#warning "Bootloader not read-protected"
|
|
||||||
#if defined(RAMPZ)
|
|
||||||
data = pgm_read_word_far(baddr);
|
|
||||||
#else
|
|
||||||
data = pgm_read_word_near(baddr);
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
// don't read bootloader
|
|
||||||
if (baddr < APP_END) {
|
|
||||||
#if defined(RAMPZ)
|
|
||||||
data = pgm_read_word_far(baddr);
|
|
||||||
#else
|
|
||||||
data = pgm_read_word_near(baddr);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
data = 0xFFFF; // fake empty
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
sendchar(data); // send LSB
|
|
||||||
sendchar((data >> 8)); // send MSB
|
|
||||||
baddr += 2; // Select next word in memory
|
|
||||||
size -= 2; // Subtract two bytes from number of bytes to read
|
|
||||||
} while (size); // Repeat until block has been read
|
|
||||||
|
|
||||||
return baddr >> 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void send_boot(void) {
|
|
||||||
sendchar('A');
|
|
||||||
sendchar('V');
|
|
||||||
sendchar('R');
|
|
||||||
sendchar('B');
|
|
||||||
sendchar('O');
|
|
||||||
sendchar('O');
|
|
||||||
sendchar('T');
|
|
||||||
}
|
|
||||||
|
|
||||||
static void (*jump_to_app)(void) = 0x0000;
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
|
|
||||||
bootloader_wdt_off();
|
|
||||||
|
|
||||||
uint16_t address = 0;
|
|
||||||
uint8_t device = 0, val;
|
|
||||||
|
|
||||||
BLDDR &= ~(1 << BLPNUM); // set as Input
|
|
||||||
BLPORT |= (1 << BLPNUM); // Enable pullup
|
|
||||||
|
|
||||||
UART_STATUS = (1 << UART_DOUBLE);
|
|
||||||
UART_BAUD_HIGH = 0;
|
|
||||||
UART_BAUD_LOW = 25;
|
|
||||||
|
|
||||||
UART_CTRL = UART_CTRL_DATA;
|
|
||||||
UART_CTRL2 = UART_CTRL2_DATA;
|
|
||||||
|
|
||||||
if (BLPIN & (1 << BLPNUM)) {
|
|
||||||
// jump to main app if pin is not grounded and GPIOR2 is zero
|
|
||||||
jump_to_app(); // Jump to application sector
|
|
||||||
}
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
val = recvchar();
|
|
||||||
// Autoincrement?
|
|
||||||
if (val == 'a') {
|
|
||||||
sendchar('Y'); // Autoincrement is quicker
|
|
||||||
|
|
||||||
//write address
|
|
||||||
} else if (val == 'A') {
|
|
||||||
address = recvchar(); //read address 8 MSB
|
|
||||||
address = (address << 8) | recvchar();
|
|
||||||
sendchar('\r');
|
|
||||||
|
|
||||||
// Buffer load support
|
|
||||||
} else if (val == 'b') {
|
|
||||||
sendchar('Y'); // Report buffer load supported
|
|
||||||
sendchar((sizeof(gBuffer) >> 8) & 0xFF); // Report buffer size in bytes
|
|
||||||
sendchar(sizeof(gBuffer) & 0xFF);
|
|
||||||
|
|
||||||
// Start buffer load
|
|
||||||
} else if (val == 'B') {
|
|
||||||
pagebuf_t size;
|
|
||||||
size = recvchar() << 8; // Load high byte of buffersize
|
|
||||||
size |= recvchar(); // Load low byte of buffersize
|
|
||||||
val = recvchar(); // Load memory type ('E' or 'F')
|
|
||||||
recvBuffer(size);
|
|
||||||
|
|
||||||
if (device == DEVTYPE) {
|
|
||||||
if (val == 'F') {
|
|
||||||
address = writeFlashPage(address, size);
|
|
||||||
}
|
|
||||||
sendchar('\r');
|
|
||||||
} else {
|
|
||||||
sendchar(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Block read
|
|
||||||
} else if (val == 'g') {
|
|
||||||
pagebuf_t size;
|
|
||||||
size = recvchar() << 8; // Load high byte of buffersize
|
|
||||||
size |= recvchar(); // Load low byte of buffersize
|
|
||||||
val = recvchar(); // Get memtype
|
|
||||||
|
|
||||||
if (val == 'F') {
|
|
||||||
address = readFlashPage(address, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Chip erase
|
|
||||||
} else if (val == 'e') {
|
|
||||||
if (device == DEVTYPE) {
|
|
||||||
eraseFlash();
|
|
||||||
}
|
|
||||||
sendchar('\r');
|
|
||||||
|
|
||||||
// Exit upgrade
|
|
||||||
} else if (val == 'E') {
|
|
||||||
wdt_enable(EXIT_WDT_TIME);
|
|
||||||
// Enable Watchdog Timer to give reset
|
|
||||||
sendchar('\r');
|
|
||||||
|
|
||||||
// Enter programming mode
|
|
||||||
} else if (val == 'P') {
|
|
||||||
sendchar('\r');
|
|
||||||
|
|
||||||
// Leave programming mode
|
|
||||||
} else if (val == 'L') {
|
|
||||||
sendchar('\r');
|
|
||||||
|
|
||||||
// return programmer type
|
|
||||||
} else if (val == 'p') {
|
|
||||||
sendchar('S'); // always serial programmer
|
|
||||||
|
|
||||||
// Return device type
|
|
||||||
} else if (val == 't') {
|
|
||||||
sendchar(DEVTYPE);
|
|
||||||
sendchar(0);
|
|
||||||
|
|
||||||
// clear and set LED ignored
|
|
||||||
} else if ((val == 'x') || (val == 'y')) {
|
|
||||||
recvchar();
|
|
||||||
sendchar('\r');
|
|
||||||
|
|
||||||
// set device
|
|
||||||
} else if (val == 'T') {
|
|
||||||
device = recvchar();
|
|
||||||
sendchar('\r');
|
|
||||||
|
|
||||||
// Return software identifier
|
|
||||||
} else if (val == 'S') {
|
|
||||||
send_boot();
|
|
||||||
|
|
||||||
// Return Software Version
|
|
||||||
} else if (val == 'V') {
|
|
||||||
sendchar(VERSION_HIGH);
|
|
||||||
sendchar(VERSION_LOW);
|
|
||||||
|
|
||||||
// Return Signature Bytes (it seems that
|
|
||||||
// AVRProg expects the "Atmel-byte" 0x1E last
|
|
||||||
// but shows it first in the dialog-window)
|
|
||||||
} else if (val == 's') {
|
|
||||||
sendchar(SIG_BYTE3);
|
|
||||||
sendchar(SIG_BYTE2);
|
|
||||||
sendchar(SIG_BYTE1);
|
|
||||||
|
|
||||||
/* ESC */
|
|
||||||
} else if (val != 0x1b) {
|
|
||||||
sendchar('?');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,462 +0,0 @@
|
||||||
# MCU name
|
|
||||||
MCU = atmega88
|
|
||||||
MCU_AVRDUDE = atmega88
|
|
||||||
## MCU = atmega644
|
|
||||||
|
|
||||||
|
|
||||||
#/* Select Boot Size in Words (select one, comment out the others) */
|
|
||||||
##BOOTSIZE=512 #(will not fit)
|
|
||||||
##BOOTSIZE=1024
|
|
||||||
##BOOTSIZE=2048
|
|
||||||
BOOTSIZE=512
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ifeq ($(MCU), atmega88pa)
|
|
||||||
ifeq ($(BOOTSIZE), 128)
|
|
||||||
MT_BOOTLOADER_ADDRESS = 0x1F00
|
|
||||||
FUSE_SETTINGS = - lfuse:w:0xe2:m -U hfuse:w:0xdf:m -U efuse:w:0xfe:m
|
|
||||||
endif
|
|
||||||
ifeq ($(BOOTSIZE), 256)
|
|
||||||
MT_BOOTLOADER_ADDRESS = 0x1E00
|
|
||||||
FUSE_SETTINGS = -U lfuse:w:0xe2:m -U hfuse:w:0xdf:m -U efuse:w:0xfc:m
|
|
||||||
endif
|
|
||||||
ifeq ($(BOOTSIZE), 512)
|
|
||||||
MT_BOOTLOADER_ADDRESS = 0x1C00
|
|
||||||
FUSE_SETTINGS = -U lfuse:w:0xe2:m -U hfuse:w:0xdf:m -U efuse:w:0xfa:m
|
|
||||||
endif
|
|
||||||
ifeq ($(BOOTSIZE), 1024)
|
|
||||||
MT_BOOTLOADER_ADDRESS = 0x1800
|
|
||||||
FUSE_SETTINGS = -U lfuse:w:0xe2:m -U hfuse:w:0xdf:m -U efuse:w:0xf8:m
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
ifeq ($(MCU), atmega88)
|
|
||||||
ifeq ($(BOOTSIZE), 128)
|
|
||||||
MT_BOOTLOADER_ADDRESS = 0x1F00
|
|
||||||
FUSE_SETTINGS = -U lfuse:w:0xe2:m -U hfuse:w:0xdf:m -U efuse:w:0xfe:m
|
|
||||||
endif
|
|
||||||
ifeq ($(BOOTSIZE), 256)
|
|
||||||
MT_BOOTLOADER_ADDRESS = 0x1E00
|
|
||||||
FUSE_SETTINGS = -U lfuse:w:0xe2:m -U hfuse:w:0xdf:m -U efuse:w:0xfc:m
|
|
||||||
endif
|
|
||||||
ifeq ($(BOOTSIZE), 512)
|
|
||||||
MT_BOOTLOADER_ADDRESS = 0x1C00
|
|
||||||
FUSE_SETTINGS = -U lfuse:w:0xe2:m -U hfuse:w:0xdf:m -U efuse:w:0xfa:m
|
|
||||||
endif
|
|
||||||
ifeq ($(BOOTSIZE), 1024)
|
|
||||||
MT_BOOTLOADER_ADDRESS = 0x1800
|
|
||||||
FUSE_SETTINGS = -U lfuse:w:0xe2:m -U hfuse:w:0xdf:m -U efuse:w:0xf8:m
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
# Output format. (can be srec, ihex, binary)
|
|
||||||
FORMAT = ihex
|
|
||||||
#FORMAT = srec
|
|
||||||
|
|
||||||
# Target file name (without extension).
|
|
||||||
TARGET = plbl
|
|
||||||
|
|
||||||
|
|
||||||
# List C source files here. (C dependencies are automatically generated.)
|
|
||||||
SRC = main.c
|
|
||||||
|
|
||||||
|
|
||||||
# List Assembler source files here.
|
|
||||||
# Make them always end in a capital .S. Files ending in a lowercase .s
|
|
||||||
# will not be considered source files but generated files (assembler
|
|
||||||
# output from the compiler), and will be deleted upon "make clean"!
|
|
||||||
# Even though the DOS/Win* filesystem matches both .s and .S the same,
|
|
||||||
# it will preserve the spelling of the filenames, and gcc itself does
|
|
||||||
# care about how the name is spelled on its command-line.
|
|
||||||
ASRC =
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Optimization level, can be [0, 1, 2, 3, s].
|
|
||||||
# 0 = turn off optimization. s = optimize for size.
|
|
||||||
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
|
|
||||||
OPT = s
|
|
||||||
|
|
||||||
# Debugging format.
|
|
||||||
# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
|
|
||||||
# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
|
|
||||||
DEBUG = stabs
|
|
||||||
|
|
||||||
# List any extra directories to look for include files here.
|
|
||||||
# Each directory must be seperated by a space.
|
|
||||||
EXTRAINCDIRS =
|
|
||||||
|
|
||||||
|
|
||||||
# Compiler flag to set the C Standard level.
|
|
||||||
# c89 - "ANSI" C
|
|
||||||
# gnu89 - c89 plus GCC extensions
|
|
||||||
# c99 - ISO C99 standard (not yet fully implemented)
|
|
||||||
# gnu99 - c99 plus GCC extensions
|
|
||||||
CSTANDARD = -std=gnu99
|
|
||||||
|
|
||||||
# Place -D or -U options here
|
|
||||||
CDEFS = -DBOOTSIZE=$(BOOTSIZE)
|
|
||||||
|
|
||||||
# Place -I options here
|
|
||||||
CINCS =
|
|
||||||
|
|
||||||
|
|
||||||
# Compiler flags.
|
|
||||||
# -g*: generate debugging information
|
|
||||||
# -O*: optimization level
|
|
||||||
# -f...: tuning, see GCC manual and avr-libc documentation
|
|
||||||
# -Wall...: warning level
|
|
||||||
# -Wa,...: tell GCC to pass this to the assembler.
|
|
||||||
# -adhlns...: create assembler listing
|
|
||||||
CFLAGS = -g$(DEBUG)
|
|
||||||
CFLAGS += $(CDEFS) $(CINCS)
|
|
||||||
CFLAGS += -O$(OPT)
|
|
||||||
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
|
|
||||||
CFLAGS += -Wall -Wstrict-prototypes
|
|
||||||
CFLAGS += -Wa,-adhlns=$(<:.c=.lst)
|
|
||||||
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
|
||||||
CFLAGS += $(CSTANDARD)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Assembler flags.
|
|
||||||
# -Wa,...: tell GCC to pass this to the assembler.
|
|
||||||
# -ahlms: create listing
|
|
||||||
# -gstabs: have the assembler create line number information; note that
|
|
||||||
# for use in COFF files, additional information about filenames
|
|
||||||
# and function names needs to be present in the assembler source
|
|
||||||
# files -- see avr-libc docs [FIXME: not yet described there]
|
|
||||||
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#Additional libraries.
|
|
||||||
|
|
||||||
# Minimalistic printf version
|
|
||||||
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
|
|
||||||
|
|
||||||
# Floating point printf version (requires MATH_LIB = -lm below)
|
|
||||||
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
|
|
||||||
|
|
||||||
PRINTF_LIB =
|
|
||||||
|
|
||||||
# Minimalistic scanf version
|
|
||||||
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
|
|
||||||
|
|
||||||
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
|
|
||||||
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
|
|
||||||
|
|
||||||
SCANF_LIB =
|
|
||||||
|
|
||||||
MATH_LIB = -lm
|
|
||||||
|
|
||||||
# External memory options
|
|
||||||
|
|
||||||
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
|
|
||||||
# used for variables (.data/.bss) and heap (malloc()).
|
|
||||||
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
|
|
||||||
|
|
||||||
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
|
|
||||||
# only used for heap (malloc()).
|
|
||||||
#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff
|
|
||||||
|
|
||||||
EXTMEMOPTS =
|
|
||||||
|
|
||||||
# Linker flags.
|
|
||||||
# -Wl,...: tell GCC to pass this to linker.
|
|
||||||
# -Map: create map file
|
|
||||||
# --cref: add cross reference to map file
|
|
||||||
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
|
|
||||||
LDFLAGS += $(EXTMEMOPTS)
|
|
||||||
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
|
|
||||||
|
|
||||||
################## BOOTLOADER ######################
|
|
||||||
# MT_BOOTLOADER_ADDRESS (=Start of Boot Loader section
|
|
||||||
# in bytes - not words) as defined above.
|
|
||||||
LDFLAGS += -Wl,--section-start=.text=$(MT_BOOTLOADER_ADDRESS)
|
|
||||||
|
|
||||||
BFD_MACH=avr5
|
|
||||||
LDFLAGS += -T./$(BFD_MACH).x
|
|
||||||
# Programming support using avrdude. Settings and variables.
|
|
||||||
|
|
||||||
# Programming hardware: alf avr910 avrisp bascom bsd
|
|
||||||
# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
|
|
||||||
#
|
|
||||||
# Type: avrdude -c ?
|
|
||||||
# to get a full listing.
|
|
||||||
#
|
|
||||||
AVRDUDE_PROGRAMMER = stk500v2
|
|
||||||
|
|
||||||
# com1 = serial port. Use lpt1 to connect to parallel port.
|
|
||||||
#AVRDUDE_PORT = /dev/ttyUSB1 # programmer connected to serial device
|
|
||||||
AVRDUDE_PORT = /dev/cu.SLAB_USBtoUART # programmer connected to serial device
|
|
||||||
#AVRDUDE_PORT = /dev/ttyS0 # programmer connected to serial device
|
|
||||||
|
|
||||||
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
|
|
||||||
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
|
|
||||||
|
|
||||||
AVRDUDE_WRITE_FUSE = $(FUSE_SETTINGS)
|
|
||||||
|
|
||||||
|
|
||||||
# Uncomment the following if you want avrdude's erase cycle counter.
|
|
||||||
# Note that this counter needs to be initialized first using -Yn,
|
|
||||||
# see avrdude manual.
|
|
||||||
#AVRDUDE_ERASE_COUNTER = -y
|
|
||||||
|
|
||||||
# Uncomment the following if you do /not/ wish a verification to be
|
|
||||||
# performed after programming the device.
|
|
||||||
#AVRDUDE_NO_VERIFY = -V
|
|
||||||
|
|
||||||
# Increase verbosity level. Please use this when submitting bug
|
|
||||||
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
|
|
||||||
# to submit bug reports.
|
|
||||||
#AVRDUDE_VERBOSE = -v -v
|
|
||||||
|
|
||||||
AVRDUDE_FLAGS = -p $(MCU_AVRDUDE) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
|
|
||||||
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
|
|
||||||
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
|
|
||||||
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Define directories, if needed.
|
|
||||||
#DIRAVR = c:/winavr
|
|
||||||
#DIRAVRBIN = $(DIRAVR)/bin
|
|
||||||
#DIRAVRUTILS = $(DIRAVR)/utils/bin
|
|
||||||
#DIRINC = .
|
|
||||||
#DIRLIB = $(DIRAVR)/avr/lib
|
|
||||||
|
|
||||||
|
|
||||||
# Define programs and commands.
|
|
||||||
#SHELL = $(DIRAVRUTILS)/sh
|
|
||||||
#NM = $(DIRAVRBIN)/avr-nm
|
|
||||||
#CC = $(DIRAVRBIN)/avr-gcc
|
|
||||||
#OBJCOPY = $(DIRAVRBIN)/avr-objcopy
|
|
||||||
#OBJDUMP= $(DIRAVRBIN)/avr-objdump
|
|
||||||
#SIZE = $(DIRAVRBIN)/avr-size
|
|
||||||
#AVRDUDE = $(DIRAVRBIN)/avrdude.sh
|
|
||||||
#REMOVE = rm -f
|
|
||||||
#COPY = cp
|
|
||||||
|
|
||||||
# Define programs and commands.
|
|
||||||
SHELL = sh
|
|
||||||
CC = avr-gcc
|
|
||||||
OBJCOPY = avr-objcopy
|
|
||||||
OBJDUMP = avr-objdump
|
|
||||||
SIZE = avr-size
|
|
||||||
NM = avr-nm
|
|
||||||
AVRDUDE = avrdude
|
|
||||||
REMOVE = rm -f
|
|
||||||
COPY = cp
|
|
||||||
WINSHELL = cmd
|
|
||||||
|
|
||||||
|
|
||||||
# Define Messages
|
|
||||||
# English
|
|
||||||
MSG_ERRORS_NONE = Errors: none
|
|
||||||
MSG_BEGIN = -------- begin --------
|
|
||||||
MSG_END = -------- end --------
|
|
||||||
MSG_SIZE_BEFORE = Size before:
|
|
||||||
MSG_SIZE_AFTER = Size after:
|
|
||||||
MSG_COFF = Converting to AVR COFF:
|
|
||||||
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
|
|
||||||
MSG_FLASH = Creating load file for Flash:
|
|
||||||
MSG_EEPROM = Creating load file for EEPROM:
|
|
||||||
MSG_EXTENDED_LISTING = Creating Extended Listing:
|
|
||||||
MSG_SYMBOL_TABLE = Creating Symbol Table:
|
|
||||||
MSG_LINKING = Linking:
|
|
||||||
MSG_COMPILING = Compiling:
|
|
||||||
MSG_ASSEMBLING = Assembling:
|
|
||||||
MSG_CLEANING = Cleaning project:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Define all object files.
|
|
||||||
OBJ = $(SRC:.c=.o) $(ASRC:.S=.o)
|
|
||||||
|
|
||||||
# Define all listing files.
|
|
||||||
LST = $(ASRC:.S=.lst) $(SRC:.c=.lst)
|
|
||||||
|
|
||||||
|
|
||||||
# Compiler flags to generate dependency files.
|
|
||||||
### GENDEPFLAGS = -Wp,-M,-MP,-MT,$(*F).o,-MF,.dep/$(@F).d
|
|
||||||
GENDEPFLAGS = -MD -MP
|
|
||||||
#GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d
|
|
||||||
|
|
||||||
# Combine all necessary flags and optional flags.
|
|
||||||
# Add target processor to flags.
|
|
||||||
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
|
|
||||||
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Default target.
|
|
||||||
all: begin gccversion sizebefore build sizeafter finished end
|
|
||||||
|
|
||||||
build: elf hex eep lss sym
|
|
||||||
|
|
||||||
elf: $(TARGET).elf
|
|
||||||
hex: $(TARGET).hex
|
|
||||||
eep: $(TARGET).eep
|
|
||||||
lss: $(TARGET).lss
|
|
||||||
sym: $(TARGET).sym
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Eye candy.
|
|
||||||
# AVR Studio 3.x does not check make's exit code but relies on
|
|
||||||
# the following magic strings to be generated by the compile job.
|
|
||||||
begin:
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_BEGIN)
|
|
||||||
|
|
||||||
finished:
|
|
||||||
@echo $(MSG_ERRORS_NONE)
|
|
||||||
|
|
||||||
end:
|
|
||||||
@echo $(MSG_END)
|
|
||||||
@echo
|
|
||||||
|
|
||||||
|
|
||||||
# Display size of file.
|
|
||||||
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
|
|
||||||
ELFSIZE = $(SIZE) -x -A $(TARGET).elf
|
|
||||||
sizebefore:
|
|
||||||
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi
|
|
||||||
|
|
||||||
sizeafter:
|
|
||||||
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Display compiler version information.
|
|
||||||
gccversion :
|
|
||||||
@$(CC) --version
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Program the device.
|
|
||||||
flash: $(TARGET).hex $(TARGET).eep
|
|
||||||
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
|
|
||||||
|
|
||||||
fuse:
|
|
||||||
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSE)
|
|
||||||
|
|
||||||
|
|
||||||
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
|
|
||||||
COFFCONVERT=$(OBJCOPY) --debugging \
|
|
||||||
--change-section-address .data-0x800000 \
|
|
||||||
--change-section-address .bss-0x800000 \
|
|
||||||
--change-section-address .noinit-0x800000 \
|
|
||||||
--change-section-address .eeprom-0x810000
|
|
||||||
|
|
||||||
|
|
||||||
coff: $(TARGET).elf
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_COFF) $(TARGET).cof
|
|
||||||
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
|
|
||||||
|
|
||||||
|
|
||||||
extcoff: $(TARGET).elf
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
|
|
||||||
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Create final output files (.hex, .eep) from ELF output file.
|
|
||||||
%.hex: %.elf
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_FLASH) $@
|
|
||||||
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
|
|
||||||
|
|
||||||
%.eep: %.elf
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_EEPROM) $@
|
|
||||||
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
|
|
||||||
--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
|
|
||||||
|
|
||||||
# Create extended listing file from ELF output file.
|
|
||||||
%.lss: %.elf
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_EXTENDED_LISTING) $@
|
|
||||||
$(OBJDUMP) -h -S $< > $@
|
|
||||||
|
|
||||||
# Create a symbol table from ELF output file.
|
|
||||||
%.sym: %.elf
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_SYMBOL_TABLE) $@
|
|
||||||
$(NM) -n $< > $@
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Link: create ELF output file from object files.
|
|
||||||
.SECONDARY : $(TARGET).elf
|
|
||||||
.PRECIOUS : $(OBJ)
|
|
||||||
%.elf: $(OBJ)
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_LINKING) $@
|
|
||||||
$(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
|
|
||||||
|
|
||||||
|
|
||||||
# Compile: create object files from C source files.
|
|
||||||
%.o : %.c
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_COMPILING) $<
|
|
||||||
$(CC) -c $(ALL_CFLAGS) $< -o $@
|
|
||||||
|
|
||||||
|
|
||||||
# Compile: create assembler files from C source files.
|
|
||||||
%.s : %.c
|
|
||||||
$(CC) -S $(ALL_CFLAGS) $< -o $@
|
|
||||||
|
|
||||||
|
|
||||||
# Assemble: create object files from assembler source files.
|
|
||||||
%.o : %.S
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_ASSEMBLING) $<
|
|
||||||
$(CC) -c $(ALL_ASFLAGS) $< -o $@
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Target: clean project.
|
|
||||||
clean: begin clean_list finished end
|
|
||||||
|
|
||||||
clean_list :
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_CLEANING)
|
|
||||||
$(REMOVE) $(TARGET).hex
|
|
||||||
$(REMOVE) $(TARGET).eep
|
|
||||||
$(REMOVE) $(TARGET).obj
|
|
||||||
$(REMOVE) $(TARGET).cof
|
|
||||||
$(REMOVE) $(TARGET).elf
|
|
||||||
$(REMOVE) $(TARGET).map
|
|
||||||
$(REMOVE) $(TARGET).obj
|
|
||||||
$(REMOVE) $(TARGET).a90
|
|
||||||
$(REMOVE) $(TARGET).sym
|
|
||||||
$(REMOVE) $(TARGET).lnk
|
|
||||||
$(REMOVE) $(TARGET).lss
|
|
||||||
$(REMOVE) $(OBJ)
|
|
||||||
$(REMOVE) $(LST)
|
|
||||||
$(REMOVE) $(SRC:.c=.s)
|
|
||||||
$(REMOVE) $(SRC:.c=.d)
|
|
||||||
# $(REMOVE) .dep/*
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Include the dependency files.
|
|
||||||
#-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
|
|
||||||
|
|
||||||
|
|
||||||
# Listing of phony targets.
|
|
||||||
.PHONY : all begin finish end sizebefore sizeafter gccversion \
|
|
||||||
build elf hex eep lss sym coff extcoff \
|
|
||||||
clean clean_list program
|
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
#ifndef _MEGA88_H_
|
|
||||||
#define _MEGA88_H_
|
|
||||||
|
|
||||||
/* Part-Code ISP */
|
|
||||||
#define DEVTYPE_ISP 0x76
|
|
||||||
/* Part-Code BOOT */
|
|
||||||
#define DEVTYPE_BOOT 0x77
|
|
||||||
|
|
||||||
#define SIG_BYTE1 0x1E
|
|
||||||
#define SIG_BYTE2 0x93
|
|
||||||
#define SIG_BYTE3 0x0F
|
|
||||||
|
|
||||||
#define UART_BAUD_HIGH UBRR0H
|
|
||||||
#define UART_BAUD_LOW UBRR0L
|
|
||||||
#define UART_STATUS UCSR0A
|
|
||||||
#define UART_TXREADY UDRE0
|
|
||||||
#define UART_RXREADY RXC0
|
|
||||||
#define UART_DOUBLE U2X0
|
|
||||||
#define UART_CTRL UCSR0B
|
|
||||||
#define UART_CTRL_DATA ((1<<TXEN0) | (1<<RXEN0))
|
|
||||||
#define UART_CTRL2 UCSR0C
|
|
||||||
#define UART_CTRL2_DATA (1<<UCSZ00)|(1<<UCSZ01)//((1<<URSEL0) | (1<<UCSZ10) | (1<<UCSZ00))
|
|
||||||
#define UART_DATA UDR0
|
|
||||||
|
|
||||||
static inline void bootloader_wdt_off(void) {
|
|
||||||
// cli();
|
|
||||||
wdt_reset();
|
|
||||||
/* Clear WDRF in MCUSR */
|
|
||||||
MCUSR &= ~(1 << WDRF);
|
|
||||||
/* Write logical one to WDCE and WDE */
|
|
||||||
/* Keep old prescaler setting to prevent unintentional time-out */
|
|
||||||
WDTCSR |= (1 << WDCE) | (1 << WDE);
|
|
||||||
/* Turn off WDT */
|
|
||||||
WDTCSR = 0x00;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // #ifndef _MEGA88_H_
|
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
#include <inttypes.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <avr/io.h>
|
|
||||||
|
|
||||||
#include "../lib/apps.h"
|
|
||||||
#include "../lib/bughal.h"
|
|
||||||
#include "../lib/util.h"
|
|
||||||
#include "../lib/music.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* crazymoves mode
|
|
||||||
* - play random sounds and move in random fashion
|
|
||||||
*/
|
|
||||||
static void crazy(void)
|
|
||||||
{
|
|
||||||
static timer_t mytimer;
|
|
||||||
uint8_t max = 50;
|
|
||||||
uint8_t min = 5;
|
|
||||||
uint16_t maxfreq = 5000;
|
|
||||||
uint16_t minfreq = 1000;
|
|
||||||
|
|
||||||
if (mode_uninitialized) {
|
|
||||||
mode_uninitialized = false;
|
|
||||||
music_setNote(NOTE_PAUSE, 4); //mute
|
|
||||||
timer_set(&mytimer, 10);
|
|
||||||
init_leds();
|
|
||||||
led_off(LED_L | LED_R);
|
|
||||||
set_motor(MOTOR_OFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timer_expired(&mytimer)) {
|
|
||||||
set_motor(MOTOR_OFF);
|
|
||||||
music_setNote(NOTE_PAUSE, 0); //mute
|
|
||||||
/*set random led*/
|
|
||||||
switch (rand() % 4) {
|
|
||||||
case 0: led_on(LED_L); break;
|
|
||||||
case 1: led_on(LED_R); break;
|
|
||||||
case 2: led_on(LED_L | LED_R); break;
|
|
||||||
default: led_off(LED_L | LED_R); break;
|
|
||||||
};
|
|
||||||
/*decide if to switch motor on (40% chance)*/
|
|
||||||
if (rand() % 5 > 2)
|
|
||||||
set_motor(MOTOR_ON);
|
|
||||||
|
|
||||||
/*decide if to play sound (70% chance)*/
|
|
||||||
if (rand() % 10 > 2) {
|
|
||||||
music_setNote((rand() % (maxfreq - minfreq)) + minfreq,
|
|
||||||
0);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
timer_set(&mytimer, (rand() % (max - min)) + min);
|
|
||||||
}//end if timer_expired
|
|
||||||
|
|
||||||
/*deinialisation */
|
|
||||||
if (mode_last_tick) {
|
|
||||||
set_motor(MOTOR_OFF);
|
|
||||||
music_setNote(NOTE_PAUSE, 0); //mute
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
REGISTER(crazy)
|
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
#ifndef APPS_H
|
|
||||||
#define APPS_H
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* REGISTER makro exploits special avr-libc startup code voodo.
|
|
||||||
* This could be understood by reading
|
|
||||||
* http://www.nongnu.org/avr-libc/user-manual/mem_sections.html
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
|
|
||||||
|
|
||||||
#define MAX_FUNS 16
|
|
||||||
#define REGISTER(fun) static void init(void) __attribute__ ((naked, used, section (".init8"))); \
|
|
||||||
void init(void) { \
|
|
||||||
mode_funs[mode_num] = fun; \
|
|
||||||
++mode_num; \
|
|
||||||
} \
|
|
||||||
|
|
||||||
typedef void (*mode_fun)(void);
|
|
||||||
|
|
||||||
extern mode_fun mode_funs[MAX_FUNS];
|
|
||||||
extern uint8_t mode_num;
|
|
||||||
|
|
||||||
extern uint8_t mode_uninitialized;
|
|
||||||
extern uint8_t mode_last_tick;
|
|
||||||
|
|
||||||
#endif /* APPS_H */
|
|
|
@ -1,219 +0,0 @@
|
||||||
#include <inttypes.h>
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include "bughal.h"
|
|
||||||
#include "util.h" //for timer
|
|
||||||
/* Hardware abstraction layer for Pentabug hardware */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* initialize LEDs on C0-C3
|
|
||||||
*/
|
|
||||||
|
|
||||||
static uint8_t oldinput; // button readings from last poll cycle
|
|
||||||
static uint8_t curinput; // button readings from current poll cycle
|
|
||||||
|
|
||||||
//each switch has its own state machine
|
|
||||||
static uint8_t btnstates[BTN_BUTTONS]; //array for current button states
|
|
||||||
static uint8_t btncounters[BTN_BUTTONS]; //individual counter for button state machine
|
|
||||||
static timer_t btntimers[BTN_BUTTONS]; //individiual timer for for button state machine
|
|
||||||
|
|
||||||
void init_leds(void) {
|
|
||||||
//enable LED channels as output
|
|
||||||
DDRC |= (1 << PORTC0) | (1 << PORTC1) | (1 << PORTC2) | (1 << PORTC3);
|
|
||||||
// both LEDs off
|
|
||||||
PORTC &= ~((1 << PORTC0) | (1 << PORTC1) | (1 << PORTC2) | (1 << PORTC3));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void led_on(int leds) {
|
|
||||||
PORTC |= leds;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void led_off(int leds) {
|
|
||||||
PORTC &= ~leds;
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_buzzr(void) {
|
|
||||||
// its on B2 and C5
|
|
||||||
DDRC |= (1 << PORTC5);
|
|
||||||
DDRB |= (1 << PORTB2);
|
|
||||||
// switch it off
|
|
||||||
buzzr_off();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_mic(void) {
|
|
||||||
// buzzer is on B2 and C5, for reasons
|
|
||||||
// ... we use it as microphone
|
|
||||||
DDRC &= ~(1 << PORTC5); // switch C5 to input
|
|
||||||
DDRB |= (1 << PORTB2); // B2 as output
|
|
||||||
PORTB &= ~(1 << PORTB2); //and to GND
|
|
||||||
ADMUX = (1 << REFS1) | (1 << REFS0); // use internal 1.1V as reference
|
|
||||||
ADCSRA = (1 << ADPS1) | (1 << ADPS0); // prescaler F_CPU/8
|
|
||||||
ADCSRA |= (1 << ADEN) | (1 << ADATE); // ADC enable - turn it on in free running mode
|
|
||||||
ADCSRB &= (1 << ACME); //leave only ACME as it is (others zerp for free running)
|
|
||||||
ADMUX = (ADMUX & ~(0x1F)) | 5; // select channel 5
|
|
||||||
ADCSRA |= (1 << ADSC); // start conversion
|
|
||||||
uint16_t __attribute__((unused)) dummy = ADCW; //read once
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void buzzr_up(void) {
|
|
||||||
// one pin Vcc, other GND
|
|
||||||
PORTC &= ~(1 << PORTC5);
|
|
||||||
PORTB |= (1 << PORTB2);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
void buzzr_down(void) {
|
|
||||||
// one pin GND,other pin Vcc
|
|
||||||
PORTC |= (1 << PORTC5);
|
|
||||||
PORTB &= ~(1 << PORTB2);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void buzzr_off(void) {
|
|
||||||
// both pins to GND
|
|
||||||
PORTC &= ~(1 << PORTC5);
|
|
||||||
PORTB &= ~(1 << PORTB2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void buzzr_inv(void) {
|
|
||||||
// read and invert pin settings, make the piezo flip polarity
|
|
||||||
PORTC ^= (1 << PORTC5);
|
|
||||||
PORTB ^= (1 << PORTB2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void init_switch(void) {
|
|
||||||
// init switch 1 and switch 2
|
|
||||||
DDRD &= ~((1 << PORTD1) | (1 << PORTD0)); // D0 and D1 as input
|
|
||||||
PORTD |= (1 << PORTD1) | (1 << PORTD0); // pull-ups FTW
|
|
||||||
// set predefined button states
|
|
||||||
oldinput = 0;
|
|
||||||
curinput = 0;
|
|
||||||
// initialize the state machine of each button
|
|
||||||
for (uint8_t i = 0; i < BTN_BUTTONS; i++) {
|
|
||||||
btnstates[i] = BTNST_NTRL; //init button states
|
|
||||||
btncounters[i] = 0; //init button counters
|
|
||||||
timer_set(&btntimers[i], 0x05); //50ms - init button timers
|
|
||||||
};
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool switch_l(void) {
|
|
||||||
return !(PIND & 0b00000001);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool switch_r(void) {
|
|
||||||
return !(PIND & 0b00000010);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void init_motor(void) {
|
|
||||||
/* vibration motor on B1, initially off: */
|
|
||||||
DDRB |= (1 << PORTB1);
|
|
||||||
PORTB &= ~(1 << PORTB1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_motor(int val) {
|
|
||||||
if (val == MOTOR_ON) {
|
|
||||||
PORTB |= 0x02;
|
|
||||||
} else {
|
|
||||||
PORTB &= ~(0x02);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset button to neutral state
|
|
||||||
void button_clear(uint8_t button) {
|
|
||||||
btnstates[button] = BTNST_NTRL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void stateswitch(uint8_t i) {
|
|
||||||
switch (btnstates[i]) {
|
|
||||||
case BTNST_NTRL: //NEUTRAL
|
|
||||||
if (curinput & (1 << i)) { //button down
|
|
||||||
btncounters[i] = 0;
|
|
||||||
btnstates[i] = BTNST_DBNC;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BTNST_DBNC: //intermediate state, check if button is still pressed to debounce
|
|
||||||
btnstates[i] = (curinput & (1 << i)) ? BTNST_SDN : BTNST_NTRL;
|
|
||||||
(btncounters[i])++;
|
|
||||||
break;
|
|
||||||
case BTNST_SDN:
|
|
||||||
if (curinput & (1 << i)) {
|
|
||||||
btncounters[i]++;
|
|
||||||
if (btncounters[i] > BTN_T_LONGFACT) { //500ms held
|
|
||||||
btnstates[i] = BTNST_LDN;
|
|
||||||
}
|
|
||||||
} else { //button was released
|
|
||||||
btnstates[i] = BTNST_SUP;
|
|
||||||
//signal shortclick
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BTNST_LDN:
|
|
||||||
if (!(curinput & (1 << i))) {
|
|
||||||
//button was released
|
|
||||||
btnstates[i] = BTNST_LUP; //signal longpress
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BTNST_SUP:
|
|
||||||
if ((curinput & (1 << i))) {
|
|
||||||
//button was pressed again or is bouncing after release
|
|
||||||
btnstates[i] = BTNST_SUPDBNC; //going in special debounce
|
|
||||||
btncounters[i] = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BTNST_LUP:
|
|
||||||
if ((curinput & (1 << i))) {
|
|
||||||
//button was pressed again or is bouncing after release
|
|
||||||
btnstates[i] = BTNST_LUPDBNC; //going in special debounce
|
|
||||||
btncounters[i] = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BTNST_SUPDBNC:
|
|
||||||
if ((curinput & (1 << i))) {
|
|
||||||
//button is still pressed --> going to shortpress
|
|
||||||
btncounters[i]++;
|
|
||||||
btnstates[i] = BTNST_SDN; //starting over from short pressed
|
|
||||||
} else {
|
|
||||||
btnstates[i] = BTNST_SUP; //nope, it was bouncing, back to old state
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BTNST_LUPDBNC:
|
|
||||||
if ((curinput & (1 << i))) {
|
|
||||||
//button is still pressed --> going to shortpress
|
|
||||||
btncounters[i]++;
|
|
||||||
btnstates[i] = BTNST_SDN; //starting over from short pressed
|
|
||||||
} else {
|
|
||||||
btnstates[i] = BTNST_LUP; //nope, it was bouncing, back to old state
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default: //curently catches nothing
|
|
||||||
// do nothing yet
|
|
||||||
;
|
|
||||||
break;
|
|
||||||
}; //end switch
|
|
||||||
timer_set(&btntimers[i], BTN_T_DEBOUNCE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void button_poll() {
|
|
||||||
curinput = ~(PIND & 0b00000011);
|
|
||||||
for (uint8_t i = 0; i < BTN_BUTTONS; i++) {
|
|
||||||
if (timer_expired(&btntimers[i])) {
|
|
||||||
stateswitch(i);
|
|
||||||
} //end if timer expired
|
|
||||||
} //end for
|
|
||||||
oldinput = curinput;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool btn_state(uint8_t btnstate, uint8_t btn) {
|
|
||||||
return (btnstates[btn] == btnstate);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
#ifndef BUGHAL_H
|
|
||||||
#define BUGHAL_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
/* Hardware abstraction layer for Pentabug hardware */
|
|
||||||
|
|
||||||
enum {
|
|
||||||
BUZZR_OUT, //initialize buzzer for OUTPUT mode (emmiting soundwaves)
|
|
||||||
BUZZR_IN
|
|
||||||
//initialize buzzer for INPUT mode (registering soundwaves)
|
|
||||||
};
|
|
||||||
|
|
||||||
#define LED_L (1 << PORTC0)
|
|
||||||
#define LED_R (1 << PORTC2)
|
|
||||||
#define MOTOR_ON 1
|
|
||||||
#define MOTOR_OFF 0
|
|
||||||
|
|
||||||
#define BTN_RIGHT 1
|
|
||||||
#define BTN_LEFT 0
|
|
||||||
#define BTN_BUTTONS 2 //numer of Buttons
|
|
||||||
#define BTN_T_DEBOUNCE 5 // 50ms debounce time = minimum short press time
|
|
||||||
#define BTN_T_LONGFACT 10 // after 10 * T_DEBOUNCE = 500ms button registers as long pressed
|
|
||||||
//BUTTON state machine states
|
|
||||||
#define BTNST_NTRL 0 // neutral - initial state nothing interesting, please go along
|
|
||||||
#define BTNST_DBNC 1 // debounce - pin went up, but we wait for things to stabilize and stop oscillating
|
|
||||||
#define BTNST_SDN 4 // affirmative, button is pressed,
|
|
||||||
// and it's pressed no longer than
|
|
||||||
// BTN_T_LONGFACT * BTN_T_DEBOUNCE * 10ms
|
|
||||||
|
|
||||||
#define BTNST_SUP 8 // and button went up after beeing pressed for a _short_ time
|
|
||||||
#define BTNST_LDN 16 // button is still down for more than
|
|
||||||
//BTN_T_LONGFACT * BTN_T_DEBOUNCE * 10ms
|
|
||||||
|
|
||||||
#define BTNST_LUP 32 // button came up after being pressed for a long time
|
|
||||||
#define BTNST_SUPDBNC 64 // debounce after short up
|
|
||||||
#define BTNST_LUPDBNC 128 // debounce after long up
|
|
||||||
void init_leds(void);
|
|
||||||
void led_on(int);
|
|
||||||
void led_off(int);
|
|
||||||
|
|
||||||
void init_buzzr(void);
|
|
||||||
void init_mic(void);
|
|
||||||
void buzzr_up(void);
|
|
||||||
void buzzr_down(void);
|
|
||||||
void buzzr_off(void);
|
|
||||||
void buzzr_inv(void);
|
|
||||||
|
|
||||||
// init ports and stuff for button functions
|
|
||||||
void init_switch(void);
|
|
||||||
|
|
||||||
// direct low level access to switches
|
|
||||||
bool switch_l(void); //switch pressed?
|
|
||||||
bool switch_r(void); //switch pressed?
|
|
||||||
|
|
||||||
void init_motor(void);
|
|
||||||
void set_motor(int);
|
|
||||||
|
|
||||||
// higher level functions for accessing switches
|
|
||||||
|
|
||||||
void button_poll(void); //needs to be polled in regular intervalls (lets say every 10ms)
|
|
||||||
|
|
||||||
// reset button to neutral state
|
|
||||||
void button_clear(uint8_t button);
|
|
||||||
|
|
||||||
//test if buttonstate of btn eqals btnstate, returns true if yes
|
|
||||||
bool btn_state(uint8_t btnstate, uint8_t btn);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,51 +0,0 @@
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
const uint16_t freq_table[] PROGMEM = {
|
|
||||||
/*0x00*/ 0,
|
|
||||||
/*0x01*/ 130,
|
|
||||||
/*0x02*/ 137,
|
|
||||||
/*0x03*/ 145,
|
|
||||||
/*0x04*/ 154,
|
|
||||||
/*0x05*/ 163,
|
|
||||||
/*0x06*/ 173,
|
|
||||||
/*0x07*/ 183,
|
|
||||||
/*0x08*/ 194,
|
|
||||||
/*0x09*/ 206,
|
|
||||||
/*0x0a*/ 218,
|
|
||||||
/*0x0b*/ 231,
|
|
||||||
/*0x0c*/ 245,
|
|
||||||
/*0x0d*/ 259,
|
|
||||||
/*0x0e*/ 275,
|
|
||||||
/*0x0f*/ 291,
|
|
||||||
/*0x10*/ 308,
|
|
||||||
/*0x11*/ 327,
|
|
||||||
/*0x12*/ 346,
|
|
||||||
/*0x13*/ 367,
|
|
||||||
/*0x14*/ 388,
|
|
||||||
/*0x15*/ 412,
|
|
||||||
/*0x16*/ 436,
|
|
||||||
/*0x17*/ 462,
|
|
||||||
/*0x18*/ 489,
|
|
||||||
/*0x19*/ 518,
|
|
||||||
/*0x1a*/ 549,
|
|
||||||
/*0x1b*/ 582,
|
|
||||||
/*0x1c*/ 617,
|
|
||||||
/*0x1d*/ 653,
|
|
||||||
/*0x1e*/ 692,
|
|
||||||
/*0x1f*/ 733,
|
|
||||||
/*0x20*/ 777,
|
|
||||||
/*0x21*/ 823,
|
|
||||||
/*0x22*/ 872,
|
|
||||||
/*0x23*/ 924,
|
|
||||||
/*0x24*/ 979,
|
|
||||||
/*0x25*/ 1037,
|
|
||||||
/*0x26*/ 1099,
|
|
||||||
/*0x27*/ 1164,
|
|
||||||
/*0x28*/ 1233,
|
|
||||||
/*0x29*/ 1306,
|
|
||||||
/*0x2a*/ 1384,
|
|
||||||
/*0x2b*/ 1466,
|
|
||||||
/*0x2c*/ 1554,
|
|
||||||
/*0x2d*/ 1646,
|
|
||||||
/*0x2e*/ 1744,
|
|
||||||
/*0x2f*/ 1848,
|
|
||||||
};
|
|
|
@ -1 +0,0 @@
|
||||||
extern const uint16_t freq_table[] PROGMEM;
|
|
|
@ -1,43 +0,0 @@
|
||||||
#include <stdint.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <avr/interrupt.h>
|
|
||||||
#include <avr/common.h>
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include "util.h"
|
|
||||||
#include "bughal.h"
|
|
||||||
#include "music.h"
|
|
||||||
|
|
||||||
//static volatile uint16_t currentNote;
|
|
||||||
|
|
||||||
void music_init(void) {
|
|
||||||
|
|
||||||
TCCR1A = 0; //TIMER1, normal, no PWM
|
|
||||||
TCCR1B = (1 << WGM12) | (1 << CS11); //CTC Mode, Clear Timer on Compare, Prescaler = 8
|
|
||||||
TIMSK1 &= ~(1 << OCIE1A); //disable Output Compare Interrupt
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
void music_setNote(uint16_t note, uint8_t octave) {
|
|
||||||
|
|
||||||
cli();
|
|
||||||
if (note != NOTE_PAUSE) {
|
|
||||||
//Play a Note
|
|
||||||
buzzr_up();
|
|
||||||
TIMSK1 |= (1 << OCIE1A); //enable Output Compare Interrupt
|
|
||||||
OCR1A = octave == 0 ? note : note / (1 << octave);
|
|
||||||
} else { // Pause (silence)
|
|
||||||
buzzr_off();
|
|
||||||
TIMSK1 &= ~(1 << OCIE1A); //disable Output Compare Interrupt
|
|
||||||
}
|
|
||||||
sei();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* timer interrupt function */ISR(TIMER1_COMPA_vect, ISR_NOBLOCK) {
|
|
||||||
|
|
||||||
// invert buzzer polarity
|
|
||||||
buzzr_inv();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
/* small timer library, uses timer2 */
|
|
||||||
|
|
||||||
#ifndef _MUSIC_H
|
|
||||||
#define _MUSIC_H
|
|
||||||
|
|
||||||
#define NOTE_PAUSE (65000) //Pause
|
|
||||||
//Values for Octave 0
|
|
||||||
#define NOTE_C (30577) // note C
|
|
||||||
#define NOTE_Db (28862) // note C# / Db
|
|
||||||
#define NOTE_D (27242) // note D
|
|
||||||
#define NOTE_Eb (25713) // note D# / Eb
|
|
||||||
#define NOTE_E (24270) // note E
|
|
||||||
#define NOTE_F (22908) // note F
|
|
||||||
#define NOTE_Gb (21622) // note F# / Gb
|
|
||||||
#define NOTE_G (20408) // note G
|
|
||||||
#define NOTE_Ab (19263) // note G# / Ab
|
|
||||||
#define NOTE_A (18182) // note A
|
|
||||||
#define NOTE_Bb (17161) // note A# / Bb
|
|
||||||
#define NOTE_B (16198) // note B
|
|
||||||
|
|
||||||
void music_init(void);
|
|
||||||
void music_setNote(uint16_t note, uint8_t octave);
|
|
||||||
#endif
|
|
|
@ -1,40 +0,0 @@
|
||||||
#include <avr/io.h>
|
|
||||||
#include <avr/interrupt.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <lib/timer.h>
|
|
||||||
|
|
||||||
timer_cb cur_cb;
|
|
||||||
|
|
||||||
void start_timer(timer_cb cb) {
|
|
||||||
cur_cb = cb;
|
|
||||||
|
|
||||||
cli();
|
|
||||||
|
|
||||||
/* set timer0 to CTC & prescaler 64 → 125kHz increment */
|
|
||||||
TCCR0A = (1 << WGM01);
|
|
||||||
TCCR0B = (1 << CS00) | (1 << CS01);
|
|
||||||
|
|
||||||
OCR0A = 4; /* TOP */
|
|
||||||
TCNT0 = 0;
|
|
||||||
|
|
||||||
/*enable interrupt */
|
|
||||||
TIMSK0 |= (1 << OCIE0A);
|
|
||||||
|
|
||||||
sei();
|
|
||||||
}
|
|
||||||
|
|
||||||
void stop_timer(void) {
|
|
||||||
cli();
|
|
||||||
TIMSK0 = 0;
|
|
||||||
sei();
|
|
||||||
|
|
||||||
cur_cb = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ISR(TIMER0_COMPA_vect,ISR_NOBLOCK) {
|
|
||||||
if(cur_cb != NULL) {
|
|
||||||
cur_cb();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
#ifndef TIMER_H
|
|
||||||
#define TIMER_H
|
|
||||||
|
|
||||||
typedef void (*timer_cb)(void);
|
|
||||||
|
|
||||||
void start_timer(timer_cb cb);
|
|
||||||
|
|
||||||
void stop_timer(void);
|
|
||||||
|
|
||||||
#endif /* TIMER_H */
|
|
|
@ -1,118 +0,0 @@
|
||||||
/*
|
|
||||||
* PentaFnord Firmware
|
|
||||||
*
|
|
||||||
* by Alexander Lorz <bigalex@gmx.de>
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* The USART control code is derived by code from the 4CHLED project
|
|
||||||
* by sebseb7: https://github.com/sebseb7/eagle/tree/master/4CHLED/firmware
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 3 as published by
|
|
||||||
* the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include <avr/interrupt.h>
|
|
||||||
|
|
||||||
#include "usart.h"
|
|
||||||
|
|
||||||
#define UART_RXBUFSIZE 32
|
|
||||||
|
|
||||||
static volatile uint8_t rxbuf0[UART_RXBUFSIZE];
|
|
||||||
static volatile uint8_t * volatile rxhead0, * volatile rxtail0;
|
|
||||||
|
|
||||||
|
|
||||||
ISR (USART_RX_vect) {
|
|
||||||
UCSR0B &= ~(1 << RXCIE0);
|
|
||||||
asm volatile("sei");
|
|
||||||
|
|
||||||
int diff;
|
|
||||||
uint8_t c;
|
|
||||||
c = UDR0;
|
|
||||||
diff = rxhead0 - rxtail0;
|
|
||||||
if (diff < 0)
|
|
||||||
diff += UART_RXBUFSIZE;
|
|
||||||
if (diff < UART_RXBUFSIZE - 1) {
|
|
||||||
*rxhead0 = c;
|
|
||||||
++rxhead0;
|
|
||||||
if (rxhead0 == (rxbuf0 + UART_RXBUFSIZE))
|
|
||||||
rxhead0 = rxbuf0;
|
|
||||||
|
|
||||||
}
|
|
||||||
UCSR0B |= (1 << RXCIE0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void USART0_Init(void) {
|
|
||||||
// set baudrate
|
|
||||||
#define BAUD_TOL 4
|
|
||||||
#undef BAUD
|
|
||||||
#define BAUD 115200
|
|
||||||
#include <util/setbaud.h>
|
|
||||||
UBRR0H = UBRRH_VALUE;
|
|
||||||
UBRR0L = UBRRL_VALUE;
|
|
||||||
|
|
||||||
#if USE_2X
|
|
||||||
UCSR0A |= (1 << U2X0); // enable double speed operation
|
|
||||||
#else
|
|
||||||
UCSR0A &= ~(1 << U2X0); // disable double speed operation
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// flush receive buffer
|
|
||||||
while (UCSR0A & (1 << RXC0))
|
|
||||||
UDR0;
|
|
||||||
|
|
||||||
// set 8N1
|
|
||||||
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
|
|
||||||
UCSR0B &= ~(1 << UCSZ02);
|
|
||||||
|
|
||||||
UCSR0B |= (1 << RXEN0) | (1 << TXEN0); //enable send and receive
|
|
||||||
|
|
||||||
UCSR0B |= (1 << RXCIE0); //enable receive interrup
|
|
||||||
|
|
||||||
rxhead0 = rxtail0 = rxbuf0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void USART0_putc(char c) {
|
|
||||||
loop_until_bit_is_set(UCSR0A, UDRE0);
|
|
||||||
UDR0 = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t USART0_Getc_nb(uint8_t *c) {
|
|
||||||
if (rxhead0 == rxtail0)
|
|
||||||
return 0;
|
|
||||||
*c = *rxtail0;
|
|
||||||
if (++rxtail0 == (rxbuf0 + UART_RXBUFSIZE))
|
|
||||||
rxtail0 = rxbuf0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void USART0_crlf(void) {
|
|
||||||
USART0_putc(0x0A); //newline
|
|
||||||
USART0_putc(0x0D); //carriage return
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
void USART0_put_uint8(uint8_t x) {
|
|
||||||
uint8_t highchar = ((x & 0b11110000) >> 4) + 0x30;
|
|
||||||
uint8_t lowchar = (x & 0b00001111) + 0x30;
|
|
||||||
highchar = highchar > 0x39 ? highchar + 0x07 : highchar; //chars A to F start with 0x41 not 0x3A
|
|
||||||
lowchar = lowchar > 0x39 ? lowchar + 0x07 : lowchar;
|
|
||||||
USART0_putc(highchar);
|
|
||||||
USART0_putc(lowchar);
|
|
||||||
|
|
||||||
}
|
|
||||||
void USART0_put_uint16(uint16_t x) {
|
|
||||||
USART0_put_uint8((x & 0xFF00) >> 8);
|
|
||||||
USART0_put_uint8(x & 0x00FF);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
/*
|
|
||||||
* PentaFnord Firmware
|
|
||||||
*
|
|
||||||
* by Alexander Lorz <bigalex@gmx.de>
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* The USART control code is derived by code from the 4CHLED project
|
|
||||||
* by sebseb7: https://github.com/sebseb7/eagle/tree/master/4CHLED/firmware
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 3 as published by
|
|
||||||
* the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _USART_H
|
|
||||||
#define _USART_H
|
|
||||||
|
|
||||||
void USART0_Init(void);
|
|
||||||
void USART0_putc(char c);
|
|
||||||
uint8_t USART0_Getc_nb(uint8_t*);
|
|
||||||
void USART0_put_uint8(uint8_t);
|
|
||||||
void USART0_crlf(void);
|
|
||||||
void USART0_put_uint16(uint16_t);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
#include <stdint.h>
|
|
||||||
#include <avr/interrupt.h>
|
|
||||||
#include <avr/common.h>
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
static volatile uint8_t internal_counter;
|
|
||||||
|
|
||||||
void timer_init(void) {
|
|
||||||
/* initialize timer2, CTC at 10ms, prescaler 1024 */
|
|
||||||
OCR2A = F_CPU / 1024 / 100;
|
|
||||||
TCCR2A = _BV(WGM21);
|
|
||||||
TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20);
|
|
||||||
TIMSK2 = _BV(OCIE2A);
|
|
||||||
}
|
|
||||||
|
|
||||||
void timer_set(timer_t *t, uint8_t timeout) {
|
|
||||||
t->current = internal_counter;
|
|
||||||
t->timeout = timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
void timerL_set(timerL_t *t, uint16_t timeout) {
|
|
||||||
t->current = internal_counter;
|
|
||||||
t->timeout = timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool timer_expired(timer_t *t) {
|
|
||||||
if (t->timeout == 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
/* attention: may fail if internal counter is incremented by more than one
|
|
||||||
* between two calls of timer_expired()! (that is if its is called less than every 10ms*/
|
|
||||||
if (t->current != internal_counter) {
|
|
||||||
t->timeout--;
|
|
||||||
t->current = internal_counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool timerL_expired(timerL_t *t) {
|
|
||||||
if (t->timeout == 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
/* attention: may fail if internal counter is incremented by more than one
|
|
||||||
* between two calls of timer_expired()! */
|
|
||||||
if (t->current != internal_counter) {
|
|
||||||
t->timeout--;
|
|
||||||
t->current = internal_counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* timer interrupt function */ISR(TIMER2_COMPA_vect, ISR_NOBLOCK) {
|
|
||||||
internal_counter++;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
/* small timer library, uses timer2 */
|
|
||||||
|
|
||||||
#ifndef _UTIL_H
|
|
||||||
#define _UTIL_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
/* structures */
|
|
||||||
typedef struct {
|
|
||||||
uint8_t current;
|
|
||||||
uint8_t timeout;
|
|
||||||
} timer_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint16_t current;
|
|
||||||
uint16_t timeout;
|
|
||||||
} timerL_t;
|
|
||||||
|
|
||||||
/* functions */
|
|
||||||
void timer_init(void);
|
|
||||||
void timer_set(timer_t *t, uint8_t timeout);
|
|
||||||
bool timer_expired(timer_t *t);
|
|
||||||
void timerL_set(timerL_t *t, uint16_t timeout);
|
|
||||||
bool timerL_expired(timerL_t *t);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,172 +0,0 @@
|
||||||
#include <inttypes.h>
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include <avr/sleep.h>
|
|
||||||
#include <avr/interrupt.h>
|
|
||||||
#define __DELAY_BACKWARD_COMPATIBLE__
|
|
||||||
#include <util/delay.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
|
|
||||||
#define ever (;;) /* awesomnes++ */
|
|
||||||
|
|
||||||
#include "lib/usart.h"
|
|
||||||
#include "lib/bughal.h"
|
|
||||||
#include "lib/util.h"
|
|
||||||
#include "lib/music.h"
|
|
||||||
|
|
||||||
#include "lib/apps.h"
|
|
||||||
|
|
||||||
mode_fun mode_funs[MAX_FUNS] = { NULL };
|
|
||||||
uint8_t mode_num = 0;
|
|
||||||
|
|
||||||
/*specialmodes, not in normal mode loop*/
|
|
||||||
#define MODE_PWDN mode_num //go to sleep
|
|
||||||
|
|
||||||
uint8_t OpMode = 0;
|
|
||||||
uint8_t NextMode = 0;
|
|
||||||
|
|
||||||
uint8_t mode_uninitialized = true;
|
|
||||||
uint8_t mode_last_tick = false;
|
|
||||||
|
|
||||||
/*check if mode should be changed (one of the buttons long pressed)*/
|
|
||||||
void modeswitch_poll(void)
|
|
||||||
{
|
|
||||||
if (btn_state(BTNST_LUP, BTN_LEFT)) {
|
|
||||||
//opmode --
|
|
||||||
NextMode = OpMode <= 0 ? mode_num - 1 : OpMode - 1;
|
|
||||||
button_clear(BTN_LEFT);
|
|
||||||
}
|
|
||||||
if (btn_state(BTNST_LUP, BTN_RIGHT)) {
|
|
||||||
//opmode ++
|
|
||||||
NextMode = (OpMode +1) % mode_num;
|
|
||||||
button_clear(BTN_RIGHT);
|
|
||||||
}
|
|
||||||
if ( btn_state(BTNST_LDN, BTN_RIGHT) &&
|
|
||||||
btn_state(BTNST_LDN, BTN_LEFT) ) {
|
|
||||||
NextMode = MODE_PWDN;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void do_powerDown(void)
|
|
||||||
{
|
|
||||||
static timer_t mytimer;
|
|
||||||
static uint8_t pwdn_state;
|
|
||||||
static bool ledRon;
|
|
||||||
uint8_t oldreg;
|
|
||||||
if (mode_uninitialized) {
|
|
||||||
mode_uninitialized = false;
|
|
||||||
pwdn_state = 0;
|
|
||||||
timer_set(&mytimer, 5);
|
|
||||||
set_motor(MOTOR_OFF);
|
|
||||||
ledRon = true;
|
|
||||||
};
|
|
||||||
if (timer_expired(&mytimer)) {
|
|
||||||
switch (pwdn_state) {
|
|
||||||
case 0:
|
|
||||||
if (ledRon) {
|
|
||||||
led_on(LED_L);
|
|
||||||
led_off(LED_R);
|
|
||||||
} else {
|
|
||||||
led_off(LED_L);
|
|
||||||
led_on(LED_R);
|
|
||||||
};
|
|
||||||
ledRon = !ledRon;
|
|
||||||
timer_set(&mytimer, 6);
|
|
||||||
if ((btn_state(BTNST_SUP, BTN_RIGHT)
|
|
||||||
|| btn_state(BTNST_LUP, BTN_RIGHT))
|
|
||||||
&& (btn_state(BTNST_SUP, BTN_LEFT)
|
|
||||||
|| btn_state(BTNST_LUP, BTN_LEFT))) {
|
|
||||||
//both buttons released
|
|
||||||
led_off(LED_L | LED_R);
|
|
||||||
pwdn_state = 1;
|
|
||||||
timer_set(&mytimer, 10);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
music_setNote(NOTE_A, 4);
|
|
||||||
timer_set(&mytimer, 10);
|
|
||||||
pwdn_state++;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
music_setNote(NOTE_F, 4);
|
|
||||||
timer_set(&mytimer, 5);
|
|
||||||
pwdn_state++;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
music_setNote(NOTE_D, 3);
|
|
||||||
timer_set(&mytimer, 15);
|
|
||||||
pwdn_state++;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
music_setNote(NOTE_PAUSE, 4);
|
|
||||||
timer_set(&mytimer, 1);
|
|
||||||
pwdn_state++;
|
|
||||||
break;
|
|
||||||
case 5: //now we can really power down
|
|
||||||
// lets switch everything off
|
|
||||||
oldreg = PCMSK2;
|
|
||||||
PCIFR = 0;
|
|
||||||
PCICR |= (1<<PCIE2);
|
|
||||||
PCMSK2 |= 3; //PCINT16 PCINT17
|
|
||||||
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
|
||||||
sleep_enable();
|
|
||||||
sei();
|
|
||||||
sleep_cpu();
|
|
||||||
PCICR &= ~(1<<PCIE2);
|
|
||||||
sleep_disable();
|
|
||||||
PCMSK2 = oldreg;
|
|
||||||
NextMode = 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
|
|
||||||
} //end switch
|
|
||||||
|
|
||||||
} //end timer expired
|
|
||||||
} // end do_powerDown
|
|
||||||
|
|
||||||
|
|
||||||
ISR(PCINT2_vect){ ; }
|
|
||||||
|
|
||||||
|
|
||||||
void __attribute__ ((noreturn)) main(void)
|
|
||||||
{
|
|
||||||
/* hardware initialisation: */
|
|
||||||
init_leds();
|
|
||||||
init_buzzr();
|
|
||||||
init_switch();
|
|
||||||
USART0_Init();
|
|
||||||
init_motor();
|
|
||||||
/* software initialisation */
|
|
||||||
timer_init();
|
|
||||||
music_init();
|
|
||||||
|
|
||||||
/* here the show begins: */
|
|
||||||
sei();
|
|
||||||
for ever {
|
|
||||||
//main polling loop;
|
|
||||||
button_poll();
|
|
||||||
|
|
||||||
if(OpMode < mode_num) {
|
|
||||||
modeswitch_poll();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OpMode != NextMode){
|
|
||||||
mode_last_tick = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(OpMode < mode_num) {
|
|
||||||
mode_funs[OpMode]();
|
|
||||||
} else {
|
|
||||||
do_powerDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OpMode != NextMode){
|
|
||||||
mode_last_tick = false;
|
|
||||||
mode_uninitialized = true;
|
|
||||||
OpMode = NextMode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,2 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user