some code formatting

This commit is contained in:
bigalex 2012-10-07 02:04:16 +02:00
parent 06dc89109f
commit 84bf510e36
13 changed files with 505 additions and 696 deletions

View File

@ -1,30 +1,29 @@
/***************************************************************************** /*****************************************************************************
* *
* Minimal Bootloader for Atmega644(p/a) * Minimal Bootloader for Atmega644(p/a)
* *
* *
* Based on: * Based on:
* *
* AVRPROG compatible boot-loader * AVRPROG compatible boot-loader
* Version : 0.85 (Dec. 2008) * Version : 0.85 (Dec. 2008)
* Compiler : avr-gcc 4.1.2 / avr-libc 1.4.6 * Compiler : avr-gcc 4.1.2 / avr-libc 1.4.6
* size : depends on features and startup ( minmal features < 512 words) * size : depends on features and startup ( minmal features < 512 words)
* by : Martin Thomas, Kaiserslautern, Germany * by : Martin Thomas, Kaiserslautern, Germany
* eversmith@heizung-thomas.de * eversmith@heizung-thomas.de
* Additional code and improvements contributed by: * Additional code and improvements contributed by:
* - Uwe Bonnes * - Uwe Bonnes
* - Bjoern Riemer * - Bjoern Riemer
* - Olaf Rempel * - Olaf Rempel
* *
* License : Copyright (c) 2006-2008 M. Thomas, U. Bonnes, O. Rempel * License : Copyright (c) 2006-2008 M. Thomas, U. Bonnes, O. Rempel
* Free to use. You have to mention the copyright * Free to use. You have to mention the copyright
* owners in source-code and documentation of derived * owners in source-code and documentation of derived
* work. No warranty! (Yes, you can insert the BSD * work. No warranty! (Yes, you can insert the BSD
* license here) * license here)
* *
******************************************************************************/ ******************************************************************************/
/* MCU frequency */ /* MCU frequency */
#ifndef F_CPU #ifndef F_CPU
#define F_CPU 8000000 #define F_CPU 8000000
@ -38,11 +37,10 @@
/* use second UART on mega128 / can128 / mega162 / mega324p / mega644p */ /* use second UART on mega128 / can128 / mega162 / mega324p / mega644p */
//#define UART_USE_SECOND //#define UART_USE_SECOND
/* Device-Type: /* Device-Type:
For AVRProg the BOOT-option is prefered For AVRProg the BOOT-option is prefered
which is the "correct" value for a bootloader. which is the "correct" value for a bootloader.
avrdude may only detect the part-code for ISP */ avrdude may only detect the part-code for ISP */
#define DEVTYPE DEVTYPE_BOOT #define DEVTYPE DEVTYPE_BOOT
// #define DEVTYPE DEVTYPE_ISP // #define DEVTYPE DEVTYPE_ISP
@ -61,7 +59,9 @@
*/ */
#define EXIT_WDT_TIME WDTO_250MS #define EXIT_WDT_TIME WDTO_250MS
void __vector_default(void) { ; } void __vector_default(void) {
;
}
/* /*
* define the following if the bootloader should not output * define the following if the bootloader should not output
@ -69,11 +69,9 @@ void __vector_default(void) { ; }
*/ */
#define READ_PROTECT_BOOTLOADER #define READ_PROTECT_BOOTLOADER
#define VERSION_HIGH '0' #define VERSION_HIGH '0'
#define VERSION_LOW '8' #define VERSION_LOW '8'
#ifdef UART_DOUBLESPEED #ifdef UART_DOUBLESPEED
// #define UART_CALC_BAUDRATE(baudRate) (((F_CPU*10UL) / ((baudRate) *8UL) +5)/10 -1) // #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) #define UART_CALC_BAUDRATE(baudRate) ((uint32_t)((F_CPU) + ((uint32_t)baudRate * 4UL)) / ((uint32_t)(baudRate) * 8UL) - 1)
@ -82,7 +80,6 @@ void __vector_default(void) { ; }
#define UART_CALC_BAUDRATE(baudRate) ((uint32_t)((F_CPU) + ((uint32_t)baudRate * 8UL)) / ((uint32_t)(baudRate) * 16UL) - 1) #define UART_CALC_BAUDRATE(baudRate) ((uint32_t)((F_CPU) + ((uint32_t)baudRate * 8UL)) / ((uint32_t)(baudRate) * 16UL) - 1)
#endif #endif
#include <stdint.h> #include <stdint.h>
#include <avr/io.h> #include <avr/io.h>
#include <avr/wdt.h> #include <avr/wdt.h>
@ -95,32 +92,31 @@ void __vector_default(void) { ; }
uint8_t gBuffer[SPM_PAGESIZE]; uint8_t gBuffer[SPM_PAGESIZE];
static void sendchar(uint8_t data) static void sendchar(uint8_t data) {
{ while (!(UART_STATUS & (1 << UART_TXREADY)))
while (!(UART_STATUS & (1<<UART_TXREADY))); ;
UART_DATA = data; UART_DATA = data;
} }
static uint8_t recvchar(void) static uint8_t recvchar(void) {
{ while (!(UART_STATUS & (1 << UART_RXREADY)))
while (!(UART_STATUS & (1<<UART_RXREADY))); ;
return UART_DATA; return UART_DATA;
} }
static inline void eraseFlash(void) static inline void eraseFlash(void) {
{
// erase only main section (bootloader protection) // erase only main section (bootloader protection)
uint32_t addr = 0; uint32_t addr = 0;
while (APP_END > addr) { while (APP_END > addr) {
boot_page_erase(addr); // Perform page erase boot_page_erase(addr);
boot_spm_busy_wait(); // Wait until the memory is erased. // Perform page erase
boot_spm_busy_wait(); // Wait until the memory is erased.
addr += SPM_PAGESIZE; addr += SPM_PAGESIZE;
} }
boot_rww_enable(); boot_rww_enable();
} }
static inline void recvBuffer(pagebuf_t size) static inline void recvBuffer(pagebuf_t size) {
{
pagebuf_t cnt; pagebuf_t cnt;
uint8_t *tmp = gBuffer; uint8_t *tmp = gBuffer;
@ -129,9 +125,8 @@ static inline void recvBuffer(pagebuf_t size)
} }
} }
static inline uint16_t writeFlashPage(uint16_t waddr, pagebuf_t size) static inline uint16_t writeFlashPage(uint16_t waddr, pagebuf_t size) {
{ uint32_t pagestart = (uint32_t) waddr << 1;
uint32_t pagestart = (uint32_t)waddr<<1;
uint32_t baddr = pagestart; uint32_t baddr = pagestart;
uint16_t data; uint16_t data;
uint8_t *tmp = gBuffer; uint8_t *tmp = gBuffer;
@ -140,26 +135,24 @@ static inline uint16_t writeFlashPage(uint16_t waddr, pagebuf_t size)
data = *tmp++; data = *tmp++;
data |= *tmp++ << 8; data |= *tmp++ << 8;
if ( baddr < APP_END ) if (baddr < APP_END) {
{ boot_page_fill(baddr, data);
boot_page_fill(baddr, data); // call asm routine. // call asm routine.
} }
baddr += 2; // Select next word in memory baddr += 2; // Select next word in memory
size -= 2; // Reduce number of bytes to write by two size -= 2; // Reduce number of bytes to write by two
} while (size); // Loop until all bytes written } while (size); // Loop until all bytes written
boot_page_write(pagestart); boot_page_write(pagestart);
boot_spm_busy_wait(); boot_spm_busy_wait();
boot_rww_enable(); // Re-enable the RWW section boot_rww_enable(); // Re-enable the RWW section
return baddr>>1; return baddr >> 1;
} }
static inline uint16_t readFlashPage(uint16_t waddr, pagebuf_t size) {
static inline uint16_t readFlashPage(uint16_t waddr, pagebuf_t size) uint32_t baddr = (uint32_t) waddr << 1;
{
uint32_t baddr = (uint32_t)waddr<<1;
uint16_t data; uint16_t data;
do { do {
@ -172,30 +165,26 @@ static inline uint16_t readFlashPage(uint16_t waddr, pagebuf_t size)
#endif #endif
#else #else
// don't read bootloader // don't read bootloader
if ( baddr < APP_END ) { if (baddr < APP_END) {
#if defined(RAMPZ) #if defined(RAMPZ)
data = pgm_read_word_far(baddr); data = pgm_read_word_far(baddr);
#else #else
data = pgm_read_word_near(baddr); data = pgm_read_word_near(baddr);
#endif #endif
} } else {
else {
data = 0xFFFF; // fake empty data = 0xFFFF; // fake empty
} }
#endif #endif
sendchar(data); // send LSB sendchar(data); // send LSB
sendchar((data >> 8)); // send MSB sendchar((data >> 8)); // send MSB
baddr += 2; // Select next word in memory baddr += 2; // Select next word in memory
size -= 2; // Subtract two bytes from number of bytes to read size -= 2; // Subtract two bytes from number of bytes to read
} while (size); // Repeat until block has been read } while (size); // Repeat until block has been read
return baddr>>1; return baddr >> 1;
} }
static void send_boot(void) {
static void send_boot(void)
{
sendchar('A'); sendchar('A');
sendchar('V'); sendchar('V');
sendchar('R'); sendchar('R');
@ -207,55 +196,52 @@ static void send_boot(void)
static void (*jump_to_app)(void) = 0x0000; static void (*jump_to_app)(void) = 0x0000;
int main(void) int main(void) {
{
bootloader_wdt_off(); bootloader_wdt_off();
uint16_t address = 0; uint16_t address = 0;
uint8_t device = 0, val; uint8_t device = 0, val;
BLDDR &= ~(1<<BLPNUM); // set as Input BLDDR &= ~(1 << BLPNUM); // set as Input
BLPORT |= (1<<BLPNUM); // Enable pullup BLPORT |= (1 << BLPNUM); // Enable pullup
UART_STATUS = (1 << UART_DOUBLE);
UART_STATUS = ( 1<<UART_DOUBLE );
UART_BAUD_HIGH = 0; UART_BAUD_HIGH = 0;
UART_BAUD_LOW = 25; UART_BAUD_LOW = 25;
UART_CTRL = UART_CTRL_DATA; UART_CTRL = UART_CTRL_DATA;
UART_CTRL2 = UART_CTRL2_DATA; UART_CTRL2 = UART_CTRL2_DATA;
if (BLPIN & (1<<BLPNUM)) { if (BLPIN & (1 << BLPNUM)) {
// jump to main app if pin is not grounded and GPIOR2 is zero // jump to main app if pin is not grounded and GPIOR2 is zero
jump_to_app(); // Jump to application sector jump_to_app(); // Jump to application sector
} }
for(;;) { for (;;) {
val = recvchar(); val = recvchar();
// Autoincrement? // Autoincrement?
if (val == 'a') { if (val == 'a') {
sendchar('Y'); // Autoincrement is quicker sendchar('Y'); // Autoincrement is quicker
//write address //write address
} else if (val == 'A') { } else if (val == 'A') {
address = recvchar(); //read address 8 MSB address = recvchar(); //read address 8 MSB
address = (address<<8) | recvchar(); address = (address << 8) | recvchar();
sendchar('\r'); sendchar('\r');
// Buffer load support // Buffer load support
} else if (val == 'b') { } else if (val == 'b') {
sendchar('Y'); // Report buffer load supported sendchar('Y'); // Report buffer load supported
sendchar((sizeof(gBuffer) >> 8) & 0xFF); // Report buffer size in bytes sendchar((sizeof(gBuffer) >> 8) & 0xFF); // Report buffer size in bytes
sendchar(sizeof(gBuffer) & 0xFF); sendchar(sizeof(gBuffer) & 0xFF);
// Start buffer load // Start buffer load
} else if (val == 'B') { } else if (val == 'B') {
pagebuf_t size; pagebuf_t size;
size = recvchar() << 8; // Load high byte of buffersize size = recvchar() << 8; // Load high byte of buffersize
size |= recvchar(); // Load low byte of buffersize size |= recvchar(); // Load low byte of buffersize
val = recvchar(); // Load memory type ('E' or 'F') val = recvchar(); // Load memory type ('E' or 'F')
recvBuffer(size); recvBuffer(size);
if (device == DEVTYPE) { if (device == DEVTYPE) {
@ -267,75 +253,76 @@ int main(void)
sendchar(0); sendchar(0);
} }
// Block read // Block read
} else if (val == 'g') { } else if (val == 'g') {
pagebuf_t size; pagebuf_t size;
size = recvchar() << 8; // Load high byte of buffersize size = recvchar() << 8; // Load high byte of buffersize
size |= recvchar(); // Load low byte of buffersize size |= recvchar(); // Load low byte of buffersize
val = recvchar(); // Get memtype val = recvchar(); // Get memtype
if (val == 'F') { if (val == 'F') {
address = readFlashPage(address, size); address = readFlashPage(address, size);
} }
// Chip erase // Chip erase
} else if (val == 'e') { } else if (val == 'e') {
if (device == DEVTYPE) { if (device == DEVTYPE) {
eraseFlash(); eraseFlash();
} }
sendchar('\r'); sendchar('\r');
// Exit upgrade // Exit upgrade
} else if (val == 'E') { } else if (val == 'E') {
wdt_enable(EXIT_WDT_TIME); // Enable Watchdog Timer to give reset wdt_enable(EXIT_WDT_TIME);
// Enable Watchdog Timer to give reset
sendchar('\r'); sendchar('\r');
// Enter programming mode // Enter programming mode
} else if (val == 'P') { } else if (val == 'P') {
sendchar('\r'); sendchar('\r');
// Leave programming mode // Leave programming mode
} else if (val == 'L') { } else if (val == 'L') {
sendchar('\r'); sendchar('\r');
// return programmer type // return programmer type
} else if (val == 'p') { } else if (val == 'p') {
sendchar('S'); // always serial programmer sendchar('S'); // always serial programmer
// Return device type // Return device type
} else if (val == 't') { } else if (val == 't') {
sendchar(DEVTYPE); sendchar(DEVTYPE);
sendchar(0); sendchar(0);
// clear and set LED ignored // clear and set LED ignored
} else if ((val == 'x') || (val == 'y')) { } else if ((val == 'x') || (val == 'y')) {
recvchar(); recvchar();
sendchar('\r'); sendchar('\r');
// set device // set device
} else if (val == 'T') { } else if (val == 'T') {
device = recvchar(); device = recvchar();
sendchar('\r'); sendchar('\r');
// Return software identifier // Return software identifier
} else if (val == 'S') { } else if (val == 'S') {
send_boot(); send_boot();
// Return Software Version // Return Software Version
} else if (val == 'V') { } else if (val == 'V') {
sendchar(VERSION_HIGH); sendchar(VERSION_HIGH);
sendchar(VERSION_LOW); sendchar(VERSION_LOW);
// Return Signature Bytes (it seems that // Return Signature Bytes (it seems that
// AVRProg expects the "Atmel-byte" 0x1E last // AVRProg expects the "Atmel-byte" 0x1E last
// but shows it first in the dialog-window) // but shows it first in the dialog-window)
} else if (val == 's') { } else if (val == 's') {
sendchar(SIG_BYTE3); sendchar(SIG_BYTE3);
sendchar(SIG_BYTE2); sendchar(SIG_BYTE2);
sendchar(SIG_BYTE1); sendchar(SIG_BYTE1);
/* ESC */ /* ESC */
} else if(val != 0x1b) { } else if (val != 0x1b) {
sendchar('?'); sendchar('?');
} }
} }

View File

@ -22,23 +22,17 @@
#define UART_CTRL2_DATA (1<<UCSZ00)|(1<<UCSZ01)//((1<<URSEL0) | (1<<UCSZ10) | (1<<UCSZ00)) #define UART_CTRL2_DATA (1<<UCSZ00)|(1<<UCSZ01)//((1<<URSEL0) | (1<<UCSZ10) | (1<<UCSZ00))
#define UART_DATA UDR0 #define UART_DATA UDR0
static inline void bootloader_wdt_off(void) {
static inline void bootloader_wdt_off(void)
{
// cli(); // cli();
wdt_reset(); wdt_reset();
/* Clear WDRF in MCUSR */ /* Clear WDRF in MCUSR */
MCUSR &= ~(1<<WDRF); MCUSR &= ~(1 << WDRF);
/* Write logical one to WDCE and WDE */ /* Write logical one to WDCE and WDE */
/* Keep old prescaler setting to prevent unintentional time-out */ /* Keep old prescaler setting to prevent unintentional time-out */
WDTCSR |= (1<<WDCE) | (1<<WDE); WDTCSR |= (1 << WDCE) | (1 << WDE);
/* Turn off WDT */ /* Turn off WDT */
WDTCSR = 0x00; WDTCSR = 0x00;
} }
#endif // #ifndef _MEGA88_H_ #endif // #ifndef _MEGA88_H_

View File

@ -1,106 +1,104 @@
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
const uint16_t freq_table[] PROGMEM = { const uint16_t freq_table[] PROGMEM = {
/*0x00*/ 39, /*0x00*/39,
/*0x01*/ 41, /*0x01*/41,
/*0x02*/ 43, /*0x02*/43,
/*0x03*/ 46, /*0x03*/46,
/*0x04*/ 49, /*0x04*/49,
/*0x05*/ 51, /*0x05*/51,
/*0x06*/ 54, /*0x06*/54,
/*0x07*/ 58, /*0x07*/58,
/*0x08*/ 61, /*0x08*/61,
/*0x09*/ 65, /*0x09*/65,
/*0x0a*/ 69, /*0x0a*/69,
/*0x0b*/ 73, /*0x0b*/73,
/*0x0c*/ 77, /*0x0c*/77,
/*0x0d*/ 82, /*0x0d*/82,
/*0x0e*/ 87, /*0x0e*/87,
/*0x0f*/ 92, /*0x0f*/92,
/*0x10*/ 97, /*0x10*/97,
/*0x11*/ 103, /*0x11*/103,
/*0x12*/ 109, /*0x12*/109,
/*0x13*/ 115, /*0x13*/115,
/*0x14*/ 122, /*0x14*/122,
/*0x15*/ 130, /*0x15*/130,
/*0x16*/ 137, /*0x16*/137,
/*0x17*/ 145, /*0x17*/145,
/*0x18*/ 154, /*0x18*/154,
/*0x19*/ 163, /*0x19*/163,
/*0x1a*/ 173, /*0x1a*/173,
/*0x1b*/ 183, /*0x1b*/183,
/*0x1c*/ 194, /*0x1c*/194,
/*0x1d*/ 206, /*0x1d*/206,
/*0x1e*/ 218, /*0x1e*/218,
/*0x1f*/ 231, /*0x1f*/231,
/*0x20*/ 245, /*0x20*/245,
/*0x21*/ 259, /*0x21*/259,
/*0x22*/ 275, /*0x22*/275,
/*0x23*/ 291, /*0x23*/291,
/*0x24*/ 308, /*0x24*/308,
/*0x25*/ 327, /*0x25*/327,
/*0x26*/ 346, /*0x26*/346,
/*0x27*/ 367, /*0x27*/367,
/*0x28*/ 388, /*0x28*/388,
/*0x29*/ 412, /*0x29*/412,
/*0x2a*/ 436, /*0x2a*/436,
/*0x2b*/ 462, /*0x2b*/462,
/*0x2c*/ 489, /*0x2c*/489,
/*0x2d*/ 518, /*0x2d*/518,
/*0x2e*/ 549, /*0x2e*/549,
/*0x2f*/ 582, /*0x2f*/582,
/*0x30*/ 617, /*0x30*/617,
/*0x31*/ 653, /*0x31*/653,
/*0x32*/ 692, /*0x32*/692,
/*0x33*/ 733, /*0x33*/733,
/*0x34*/ 777, /*0x34*/777,
/*0x35*/ 823, /*0x35*/823,
/*0x36*/ 872, /*0x36*/872,
/*0x37*/ 924, /*0x37*/924,
/*0x38*/ 979, /*0x38*/979,
/*0x39*/ 1037, /*0x39*/1037,
/*0x3a*/ 1099, /*0x3a*/1099,
/*0x3b*/ 1164, /*0x3b*/1164,
/*0x3c*/ 1233, /*0x3c*/1233,
/*0x3d*/ 1306, /*0x3d*/1306,
/*0x3e*/ 1384, /*0x3e*/1384,
/*0x3f*/ 1466, /*0x3f*/1466,
/*0x40*/ 1554, /*0x40*/1554,
/*0x41*/ 1646, /*0x41*/1646,
/*0x42*/ 1744, /*0x42*/1744,
/*0x43*/ 1848, /*0x43*/1848,
/*0x44*/ 1957, /*0x44*/1957,
/*0x45*/ 2074, /*0x45*/2074,
/*0x46*/ 2197, /*0x46*/2197,
/*0x47*/ 2328, /*0x47*/2328,
/*0x48*/ 2466, /*0x48*/2466,
/*0x49*/ 2613, /*0x49*/2613,
/*0x4a*/ 2768, /*0x4a*/2768,
/*0x4b*/ 2933, /*0x4b*/2933,
/*0x4c*/ 3107, /*0x4c*/3107,
/*0x4d*/ 3292, /*0x4d*/3292,
/*0x4e*/ 3488, /*0x4e*/3488,
/*0x4f*/ 3695, /*0x4f*/3695,
/*0x50*/ 3915, /*0x50*/3915,
/*0x51*/ 4148, /*0x51*/4148,
/*0x52*/ 4394, /*0x52*/4394,
/*0x53*/ 4656, /*0x53*/4656,
/*0x54*/ 4933, /*0x54*/4933,
/*0x55*/ 5226, /*0x55*/5226,
/*0x56*/ 5537, /*0x56*/5537,
/*0x57*/ 5866, /*0x57*/5866,
/*0x58*/ 6215, /*0x58*/6215,
/*0x59*/ 6584, /*0x59*/6584,
/*0x5a*/ 6976, /*0x5a*/6976,
/*0x5b*/ 7390, /*0x5b*/7390,
/*0x5c*/ 7830, /*0x5c*/7830,
/*0x5d*/ 8295, /*0x5d*/8295,
/*0x5e*/ 8789, /*0x5e*/8789,
/*0x5f*/ 9311, /*0x5f*/9311,
/*0x60*/ 9865, /*0x60*/9865,
/*0x61*/ 10452, /*0x61*/10452,
/*0x62*/ 11073, /*0x62*/11073,
/*0x63*/ 11732, /*0x63*/11732,
}; };

View File

@ -2,223 +2,211 @@
#include <avr/io.h> #include <avr/io.h>
#include "bughal.h" #include "bughal.h"
#include "util.h" //for timer #include "util.h" //for timer
/* Hardware abstraction layer for Pentabug hardware */ /* Hardware abstraction layer for Pentabug hardware */
/* /*
* initialize LEDs on C0-C3 * initialize LEDs on C0-C3
*/ */
static uint8_t oldinput; // button readings from last poll cycle static uint8_t oldinput; // button readings from last poll cycle
static uint8_t curinput; // button readings from current poll cycle static uint8_t curinput; // button readings from current poll cycle
//each switch has its own state machine //each switch has its own state machine
static uint8_t btnstates[BTN_BUTTONS]; //array for current button states static uint8_t btnstates[BTN_BUTTONS]; //array for current button states
static uint8_t btncounters[BTN_BUTTONS]; //individual counter for button state machine 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 static timer_t btntimers[BTN_BUTTONS]; //individiual timer for for button state machine
void init_leds(void) {
void init_leds(void){
//enable LED channels as output //enable LED channels as output
DDRC |= (1 << PORTC0) | (1 << PORTC1) | (1 << PORTC2) | (1 << PORTC3); DDRC |= (1 << PORTC0) | (1 << PORTC1) | (1 << PORTC2) | (1 << PORTC3);
// both LEDs off // both LEDs off
PORTC &= ~((1 << PORTC0) | (1 << PORTC1) | (1 << PORTC2) | (1 << PORTC3)); PORTC &= ~((1 << PORTC0) | (1 << PORTC1) | (1 << PORTC2) | (1 << PORTC3));
return;
//TCCR2A = (1 << WGM21);
//TCCR2B = (1 << CS20)|(1 << CS21);
//OCR2A = 255; /* TOP */
// TCNT2 = 0;
// /*enable interrupt*/
// TIMSK2 |= (1<<OCIE2A);
return;
} }
inline void led_on(int leds){ inline void led_on(int leds) {
PORTC |= leds; PORTC |= leds;
} }
inline void led_off(int leds){ inline void led_off(int leds) {
PORTC &= ~leds; PORTC &= ~leds;
} }
void init_buzzr(void) {
// its on B2 and C5
void init_buzzr(void){
//its on B2 and C5, for reasons
DDRC |= (1 << PORTC5); DDRC |= (1 << PORTC5);
DDRB |= (1 << PORTB2); DDRB |= (1 << PORTB2);
//switch it off // switch it off
buzzr_off(); buzzr_off();
return; return;
} }
void init_mic(void) {
void init_mic(void){ // buzzer is on B2 and C5, for reasons
//buzzer is on B2 and C5, for reasons // ... we use it as microphone
// we use it as a mic DDRC &= ~(1 << PORTC5); // switch C5 to input
DDRC &= ~(1 << PORTC5); //switch C5 to input DDRB |= (1 << PORTB2); // B2 as output
DDRB |= (1 << PORTB2); //B2 as output PORTB &= ~(1 << PORTB2); //and to GND
PORTB &= ~(1 << PORTB2);//and to GND ADMUX = (1 << REFS1) | (1 << REFS0); // use internal 1.1V as reference
ADMUX = (1<<REFS1) | (1<<REFS0); //use internal 1.1V as reference ADCSRA = (1 << ADPS1) | (1 << ADPS0); // prescaler F_CPU/8
ADCSRA = (1<<ADPS1) | (1<<ADPS0);// prescaler F_CPU/8 ADCSRA |= (1 << ADEN) | (1 << ADATE); // ADC enable - turn it on in free running mode
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)
ADCSRB &= (1<<ACME); //leave only ACME as it is (others zerp for free running) ADMUX = (ADMUX & ~(0x1F)) | 5; // select channel 5
ADMUX = (ADMUX & ~(0x1F)) | 5; // select channel 5 ADCSRA |= (1 << ADSC); // start conversion
ADCSRA |= (1<<ADSC); // start conversion
uint16_t __attribute__((unused)) dummy = ADCW; //read once uint16_t __attribute__((unused)) dummy = ADCW; //read once
return; return;
} }
void buzzr_up(void) {
// one pin Vcc, other GND
void buzzr_up(void){
PORTC &= ~(1 << PORTC5); PORTC &= ~(1 << PORTC5);
PORTB |= (1 << PORTB2); PORTB |= (1 << PORTB2);
return; return;
} }
;
void buzzr_down(void){ void buzzr_down(void) {
// one pin GND,other pin Vcc
PORTC |= (1 << PORTC5); PORTC |= (1 << PORTC5);
PORTB &= ~(1 << PORTB2); PORTB &= ~(1 << PORTB2);
} }
inline void buzzr_off(void){ inline void buzzr_off(void) {
// both pins to GND
PORTC &= ~(1 << PORTC5); PORTC &= ~(1 << PORTC5);
PORTB &= ~(1 << PORTB2); PORTB &= ~(1 << PORTB2);
} }
void buzzr_inv(void){
void buzzr_inv(void) {
// read and invert pin settings, make the piezo flip polarity
PORTC ^= (1 << PORTC5); PORTC ^= (1 << PORTC5);
PORTB ^= (1 << PORTB2); PORTB ^= (1 << PORTB2);
} }
void init_switch(void){
DDRD &= ~( (1 << PORTD1) | (1<<PORTD0)); void init_switch(void) {
PORTD |= (1 << PORTD1) | (1<<PORTD0); //Pullups FTW // init switch 1 and switch 2
// set predefined buttonstates DDRD &= ~((1 << PORTD1) | (1 << PORTD0)); // D0 and D1 as input
PORTD |= (1 << PORTD1) | (1 << PORTD0); // pull-ups FTW
// set predefined button states
oldinput = 0; oldinput = 0;
curinput = 0; curinput = 0;
for(uint8_t i=0; i<BTN_BUTTONS; i++){ // initialize the state machine of each button
for (uint8_t i = 0; i < BTN_BUTTONS; i++) {
btnstates[i] = BTNST_NTRL; //init button states btnstates[i] = BTNST_NTRL; //init button states
btncounters[i] = 0; //init button counters btncounters[i] = 0; //init button counters
timer_set(&btntimers[i], 0x05); //50ms - init button timers timer_set(&btntimers[i], 0x05); //50ms - init button timers
} };
return; return;
} }
bool switch_l(void){
bool switch_l(void) {
return !(PIND & 0b00000001); return !(PIND & 0b00000001);
}; }
bool switch_r(void){
bool switch_r(void) {
return !(PIND & 0b00000010); return !(PIND & 0b00000010);
}; }
void init_motor(void) void init_motor(void) {
{
/* vibration motor on B1, initially off: */ /* vibration motor on B1, initially off: */
DDRB |= (1 << PORTB1); DDRB |= (1 << PORTB1);
PORTB &= ~( 1<<PORTB1); PORTB &= ~(1 << PORTB1);
return; return;
} }
void set_motor(int val){ void set_motor(int val) {
if (val==MOTOR_ON) { if (val == MOTOR_ON) {
PORTB |= 0x02; PORTB |= 0x02;
} else { } else {
PORTB &= ~(0x02); PORTB &= ~(0x02);
} }
return; return;
} }
// reset button to neutral state // reset button to neutral state
void button_clear(uint8_t button){ void button_clear(uint8_t button) {
btnstates[button] = BTNST_NTRL; btnstates[button] = BTNST_NTRL;
} }
void stateswitch(uint8_t i) {
void stateswitch(uint8_t i ){ switch (btnstates[i]) {
switch(btnstates[i]) case BTNST_NTRL:
{ if (curinput & (1 << i)) { //button down
case BTNST_NTRL: btncounters[i] = 0;
if (curinput & (1<<i)){ //button down btnstates[i] = BTNST_DBNC;
btncounters[i] = 0; }
btnstates[i] = BTNST_DBNC; break;
//intermediate state, check if button is still pressed to debounce
case BTNST_DBNC:
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;
} }
break; } else { //button was released
//intermediate state, check if button is still pressed to debounce btnstates[i] = BTNST_SUP;
case BTNST_DBNC: //signal shortclick
btnstates[i] = (curinput & (1<<i))? BTNST_SDN: BTNST_NTRL; }
(btncounters[i])++; break;
break; case BTNST_LDN:
case BTNST_SDN: if (!(curinput & (1 << i))) {
if (curinput & (1<<i)){ //button was released
btncounters[i]++; btnstates[i] = BTNST_LUP; //signal longpress
if (btncounters[i] > BTN_T_LONGFACT){ //500ms held }
btnstates[i] = BTNST_LDN; break;
} case BTNST_SUP:
} else { //button was released if ((curinput & (1 << i))) {
btnstates[i] = BTNST_SUP; //button was pressed again or is bouncing after release
//signal shortclick btnstates[i] = BTNST_SUPDBNC; //going in special debounce
} btncounters[i] = 0;
break; }
case BTNST_LDN: break;
if (!(curinput & (1<<i))){ case BTNST_LUP:
//button was released if ((curinput & (1 << i))) {
btnstates[i] = BTNST_LUP; //signal longpress //button was pressed again or is bouncing after release
} btnstates[i] = BTNST_LUPDBNC; //going in special debounce
break; btncounters[i] = 0;
case BTNST_SUP: }
if ((curinput & (1<<i))){ break;
//button was pressed again or is bouncing after release case BTNST_SUPDBNC:
btnstates[i] = BTNST_SUPDBNC; //going in special debounce if ((curinput & (1 << i))) {
btncounters[i] = 0; //button is still pressed --> going to shortpress
} btncounters[i]++;
break; btnstates[i] = BTNST_SDN; //starting over from short pressed
case BTNST_LUP: } else {
if ((curinput & (1<<i))){ btnstates[i] = BTNST_SUP; //nope, it was bouncing, back to old state
//button was pressed again or is bouncing after release }
btnstates[i] = BTNST_LUPDBNC; //going in special debounce break;
btncounters[i] = 0; case BTNST_LUPDBNC:
} if ((curinput & (1 << i))) {
break; //button is still pressed --> going to shortpress
case BTNST_SUPDBNC: btncounters[i]++;
if ((curinput & (1<<i))){ btnstates[i] = BTNST_SDN; //starting over from short pressed
//button is still pressed --> going to shortpress } else {
btncounters[i]++; btnstates[i] = BTNST_LUP; //nope, it was bouncing, back to old state
btnstates[i] = BTNST_SDN; //starting over from short pressed }
} else { break;
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 default: //curently catches nothing
// do nothing yet // do nothing yet
; ;
break; break;
} //end switch }; //end switch
timer_set(&btntimers[i], BTN_T_DEBOUNCE); timer_set(&btntimers[i], BTN_T_DEBOUNCE);
} }
void button_poll() {
void button_poll(){
curinput = ~(PIND & 0b00000011); curinput = ~(PIND & 0b00000011);
for(uint8_t i=0; i<BTN_BUTTONS; i++){ for (uint8_t i = 0; i < BTN_BUTTONS; i++) {
if (timer_expired(&btntimers[i])){ if (timer_expired(&btntimers[i])) {
stateswitch(i); stateswitch(i);
} //end if timer expired } //end if timer expired
} //end for } //end for
@ -226,9 +214,7 @@ void button_poll(){
return; return;
} }
bool btn_state(uint8_t btnstate, uint8_t btn){ bool btn_state(uint8_t btnstate, uint8_t btn) {
return (btnstates[btn]==btnstate); return (btnstates[btn] == btnstate);
} }

View File

@ -7,7 +7,8 @@
enum { enum {
BUZZR_OUT, //initialize buzzer for OUTPUT mode (emmiting soundwaves) BUZZR_OUT, //initialize buzzer for OUTPUT mode (emmiting soundwaves)
BUZZR_IN //initialize buzzer for INPUT mode (registering soundwaves) BUZZR_IN
//initialize buzzer for INPUT mode (registering soundwaves)
}; };
#define LED_L (1 << PORTC0) #define LED_L (1 << PORTC0)

View File

@ -1,4 +1,3 @@
#include <stdint.h> #include <stdint.h>
#include <math.h> #include <math.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
@ -10,47 +9,35 @@
//static volatile uint16_t currentNote; //static volatile uint16_t currentNote;
void music_init(void){ void music_init(void) {
TCCR1A = 0; //TIMER1, normal, no PWM TCCR1A = 0; //TIMER1, normal, no PWM
TCCR1B = (1 << WGM12) | (1 << CS11); //CTC Mode, Clear Timer on Compare, Prescaler = 8 TCCR1B = (1 << WGM12) | (1 << CS11); //CTC Mode, Clear Timer on Compare, Prescaler = 8
// OCR1A = 500; //invert with 2 KHz --> 1 KHz sound --> 8000000/8/2000 TIMSK1 &= ~(1 << OCIE1A); //disable Output Compare Interrupt
// OCR1A = 10000;
// TIMSK1 |= (1 << OCIE1A); //enable Output Compare Interrupt
TIMSK1 &= ~(1 << OCIE1A); //disable Output Compare Interrupt
return; return;
}; }
;
void music_setNote(uint16_t note, uint8_t octave) {
void music_setNote(uint16_t note, uint8_t octave){ cli();
if (note != NOTE_PAUSE) {
//Play a Note
cli(); buzzr_up();
if (note != NOTE_PAUSE){ TIMSK1 |= (1 << OCIE1A); //enable Output Compare Interrupt
//Play a Note OCR1A = octave == 0 ? note : note / (1 << octave);
buzzr_up();
TIMSK1 |= (1 << OCIE1A); //enable Output Compare Interrupt
OCR1A = octave==0 ? note : note / (1 << octave);
} else { // Pause (silence) } else { // Pause (silence)
buzzr_off(); buzzr_off();
TIMSK1 &= ~(1 << OCIE1A); //disable Output Compare Interrupt TIMSK1 &= ~(1 << OCIE1A); //disable Output Compare Interrupt
} }
sei(); sei();
return; return;
} }
/* timer interrupt function */ISR(TIMER1_COMPA_vect, ISR_NOBLOCK) {
// invert buzzer polarity
buzzr_inv();
/* timer interrupt function */
ISR(TIMER1_COMPA_vect, ISR_NOBLOCK) {
// invert buzzer polarity
buzzr_inv();
} }

View File

@ -3,9 +3,7 @@
#ifndef _MUSIC_H #ifndef _MUSIC_H
#define _MUSIC_H #define _MUSIC_H
#define NOTE_PAUSE (65000) //Pause #define NOTE_PAUSE (65000) //Pause
//Values for Octave 0 //Values for Octave 0
#define NOTE_C (30577) // note C #define NOTE_C (30577) // note C
#define NOTE_Db (28862) // note C# / Db #define NOTE_Db (28862) // note C# / Db
@ -20,8 +18,6 @@
#define NOTE_Bb (17161) // note A# / Bb #define NOTE_Bb (17161) // note A# / Bb
#define NOTE_B (16198) // note B #define NOTE_B (16198) // note B
void music_init(void); void music_init(void);
void music_setNote(uint16_t note, uint8_t octave); void music_setNote(uint16_t note, uint8_t octave);
#endif #endif

View File

@ -14,171 +14,54 @@ enum {
pattern_length = 16 pattern_length = 16
}; };
static const synth_instrument_t instruments[] = { { 1 << 15, 100, 12, 0 }, { 0,
100, 12, 0 }, { 0, 200, 10, 0 }, { 1 << 13, 0, 0, 2 }, { 1 << 13, 0, 5,
2 }, };
static const uint8_t wave_table[][2] = { { 0, WAVE_PULSE }, { 3, WAVE_PULSE }, {
7, WAVE_PULSE }, { 12, WAVE_PULSE }, { 256 - 4, 0xff },
static const synth_instrument_t instruments[] = { { 0, WAVE_PULSE }, { 2, WAVE_PULSE }, { 7, WAVE_PULSE }, { 10, WAVE_PULSE }, {
{ 1<<15, 100, 12, 0 }, 256 - 4, 0xff },
{ 0, 100, 12, 0 },
{ 0, 200, 10, 0 },
{ 1<<13, 0, 0, 2 },
{ 1<<13, 0, 5, 2 },
};
static const uint8_t wave_table[][2] = { { 0, WAVE_NOISE }, { 0, WAVE_PULSE }, { 0xff, 0xff },
{ 0, WAVE_PULSE },
{ 3, WAVE_PULSE },
{ 7, WAVE_PULSE },
{ 12, WAVE_PULSE },
{ 256 - 4, 0xff },
{ 0, WAVE_PULSE }, { 0, WAVE_PULSE }, { 0xff, 0xff },
{ 2, WAVE_PULSE },
{ 7, WAVE_PULSE },
{ 10, WAVE_PULSE },
{ 256 - 4, 0xff },
{ 0, WAVE_NOISE },
{ 0, WAVE_PULSE },
{ 0xff, 0xff },
{ 0, WAVE_PULSE },
{ 0xff, 0xff },
}; };
static const uint8_t patterns[][pattern_length][2] PROGMEM = { { }, { { 33 - 12,
0 }, { 0, 0 }, { 0xff, 1 }, { 0, 0 }, { 33, 1 }, { 0xff, 1 }, { 33, 1 },
{ 0xff, 1 }, { 33, 1 }, { 0xff, 1 }, { 33 - 12, 1 }, { 0xff, 1 }, { 33
- 12, 1 }, { 0xff, 1 }, { 33, 1 }, { 0xff, 1 }, }, { { 28 - 12,
0 }, { 0, 0 }, { 0xff, 1 }, { 0, 0 }, { 28, 1 }, { 0xff, 1 }, { 28, 1 },
{ 0xff, 1 }, { 28, 1 }, { 0xff, 1 }, { 28 - 12, 1 }, { 0xff, 1 }, { 28
- 12, 1 }, { 0xff, 1 }, { 28, 1 }, { 0xff, 1 }, }, { { 0, 0 }, {
0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, {
57, 3 }, }, { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 57, 4 }, },
static const uint8_t patterns[][pattern_length][2] PROGMEM = { { { 60, 2 }, }, { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 57, 2 }, { 0, 0 }, {
{}, 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 55, 2 }, {
{ 0, 0 }, { 57, 2 }, { 0, 0 }, }, { { 55, 2 }, }, { { 0, 0 }, { 0, 0 }, {
{ 33 - 12, 0 }, 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0,
{ 0, 0 }, 0 }, { 0, 0 }, { 0, 0 }, { 57, 2 }, }, { { 55 - 3, 2 }, },
{ 0xff, 1 },
{ 0, 0 },
{ 33, 1 },
{ 0xff, 1 },
{ 33, 1 },
{ 0xff, 1 },
{ 33, 1 },
{ 0xff, 1 },
{ 33 - 12, 1 },
{ 0xff, 1 },
{ 33 - 12, 1 },
{ 0xff, 1 },
{ 33, 1 },
{ 0xff, 1 },
},
{
{ 28 - 12, 0 },
{ 0, 0 },
{ 0xff, 1 },
{ 0, 0 },
{ 28, 1 },
{ 0xff, 1 },
{ 28, 1 },
{ 0xff, 1 },
{ 28, 1 },
{ 0xff, 1 },
{ 28 - 12, 1 },
{ 0xff, 1 },
{ 28 - 12, 1 },
{ 0xff, 1 },
{ 28, 1 },
{ 0xff, 1 },
},
{
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 57, 3 },
},
{
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 57, 4 },
},
{
{ 60, 2 },
},
{
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 57, 2 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 55, 2 },
{ 0, 0 },
{ 57, 2 },
{ 0, 0 },
},
{
{ 55, 2 },
},
{
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 57, 2 },
},
{
{ 55-3, 2 },
},
}; };
static const uint8_t pattern_table[][channel_count] = { static const uint8_t pattern_table[][channel_count] = { { 1, 0, 5 },
{ 1, 0, 5 }, { 1, 3, 0 }, { 1, 0, 7 }, { 1, 3, 6 }, { 2, 0, 7 }, { 2, 4, 8 }, { 2, 0,
{ 1, 3, 0 }, 9 }, { 2, 4, 0 }, };
{ 1, 0, 7 },
{ 1, 3, 6 },
{ 2, 0, 7 },
{ 2, 4, 8 },
{ 2, 0, 9 },
{ 2, 4, 0 },
};
enum { enum {
pattern_table_length = sizeof(pattern_table) / sizeof(pattern_table[0]) pattern_table_length = sizeof(pattern_table) / sizeof(pattern_table[0])
}; };
static synth_channel_t channels[channel_count]; static synth_channel_t channels[channel_count];
static int8_t sample; static int8_t sample;
static int8_t tick; static int8_t tick;
static int8_t row; static int8_t row;
static int8_t seq; static int8_t seq;
/* PROTOTYPES */ /* PROTOTYPES */
uint8_t synth_mix(void); uint8_t synth_mix(void);
@ -189,12 +72,10 @@ static uint8_t timeslots_read; // current read head
/*register for atomic ++ and -- */ /*register for atomic ++ and -- */
register uint8_t timeslots_fill asm("r2"); register uint8_t timeslots_fill asm("r2");
static void enqueue_timeslot(uint8_t synthval); static void enqueue_timeslot(uint8_t synthval);
static uint8_t dequeue_timeslot(void); static uint8_t dequeue_timeslot(void);
void synth_init(void) void synth_init(void) {
{
sample = 0; sample = 0;
tick = 0; tick = 0;
row = 0; row = 0;
@ -202,66 +83,69 @@ void synth_init(void)
timeslots_fill = 0; timeslots_fill = 0;
} }
inline uint8_t synth_mix(void) inline uint8_t synth_mix(void) {
{ if (sample == 0) { // new tick
if(sample == 0) { // new tick for (int i = 1; i < channel_count; i++) {
for(int i = 1; i < channel_count; i++) {
synth_channel_t* chan = &channels[i]; synth_channel_t* chan = &channels[i];
const synth_instrument_t* inst = &instruments[chan->inst_nr]; const synth_instrument_t* inst = &instruments[chan->inst_nr];
if(chan->level > inst->decay) chan->level -= inst->decay; if (chan->level > inst->decay)
else chan->level = 0; chan->level -= inst->decay;
else
chan->level = 0;
chan->pulse_width += inst->pulse_sweep; chan->pulse_width += inst->pulse_sweep;
chan->pos++; chan->pos++;
if(wave_table[chan->pos][1] == 0xff) chan->pos += wave_table[chan->pos][0]; if (wave_table[chan->pos][1] == 0xff)
chan->pos += wave_table[chan->pos][0];
// enter new rol // enter new rol
// w // w
if(tick == 0) { if (tick == 0) {
uint8_t pattern_nr = pattern_table[seq][i]; uint8_t pattern_nr = pattern_table[seq][i];
uint8_t note = pgm_read_byte(&patterns[pattern_nr][row][0]); uint8_t note = pgm_read_byte(&patterns[pattern_nr][row][0]);
if(note) { // new note, maybe? if (note) { // new note, maybe?
if(note == 0xff) { if (note == 0xff) {
chan->level = 0; chan->level = 0;
} else { } else {
chan->level = 80; // TODO: less? chan->level = 80; // TODO: less?
chan->note = note; chan->note = note;
chan->inst_nr = pgm_read_byte(&patterns[pattern_nr][row][1]); chan->inst_nr =
pgm_read_byte(&patterns[pattern_nr][row][1]);
inst = &instruments[chan->inst_nr]; inst = &instruments[chan->inst_nr];
chan->pos = inst->wave_table_pos; chan->pos = inst->wave_table_pos;
if(inst->pulse_width) chan->pulse_width = inst->pulse_width; if (inst->pulse_width)
chan->pulse_width = inst->pulse_width;
} }
} }
} }
} }
} }
if(++sample == 0){ if (++sample == 0) {
if(++tick == row_length) { if (++tick == row_length) {
tick = 0; tick = 0;
if(++row == pattern_length) { if (++row == pattern_length) {
row = 0; row = 0;
if(++seq == pattern_table_length) { if (++seq == pattern_table_length) {
seq = 0; seq = 0;
} }
} }
} }
} }
uint8_t output = 0; uint8_t output = 0;
for(int i = 0; i < channel_count; i++) { for (int i = 0; i < channel_count; i++) {
synth_channel_t* chan = &channels[i]; synth_channel_t* chan = &channels[i];
// const synth_instrument_t* inst = &instruments[chan->inst_nr]; // const synth_instrument_t* inst = &instruments[chan->inst_nr];
chan->phase += pgm_read_word(&freq_table[(uint8_t)(chan->note + wave_table[chan->pos][0])]); chan->phase +=
pgm_read_word(&freq_table[(uint8_t)(chan->note + wave_table[chan->pos][0])]);
uint8_t amp; uint8_t amp;
switch(wave_table[chan->pos][1]) { switch (wave_table[chan->pos][1]) {
case WAVE_PULSE: case WAVE_PULSE:
amp = -(chan->phase < chan->pulse_width); amp = -(chan->phase < chan->pulse_width);
break; break;
@ -286,12 +170,11 @@ inline uint8_t synth_mix(void)
return output; return output;
} }
/* fill all the timeslots */ /* fill all the timeslots */
inline void synth_poll(void) { inline void synth_poll(void) {
/* refill timeslots queue */ /* refill timeslots queue */
// while (timeslots_fill < (SYNTH_BUFSIZE-1)) // while (timeslots_fill < (SYNTH_BUFSIZE-1))
if (timeslots_fill < (SYNTH_BUFSIZE-1)) if (timeslots_fill < (SYNTH_BUFSIZE - 1))
enqueue_timeslot(synth_mix()); enqueue_timeslot(synth_mix());
} }
@ -304,21 +187,18 @@ static inline void enqueue_timeslot(uint8_t synthval) {
static inline uint8_t dequeue_timeslot() { static inline uint8_t dequeue_timeslot() {
uint8_t t = timeslots[timeslots_read & SYNTH_BUFMASK]; uint8_t t = timeslots[timeslots_read & SYNTH_BUFMASK];
if(timeslots_fill){ if (timeslots_fill) {
/* buffer not underrun... move forward in readbuffer */ /* buffer not underrun... move forward in readbuffer */
timeslots_fill --; timeslots_fill--;
timeslots_read ++; timeslots_read++;
} }
return t; return t;
} }
ISR(TIMER0_COMPA_vect) {
ISR(TIMER0_COMPA_vect)
{
/* calculate next analog sample value in synth mixer:*/ /* calculate next analog sample value in synth mixer:*/
OCR1B = dequeue_timeslot(); OCR1B = dequeue_timeslot();
} }

View File

@ -4,30 +4,30 @@
#define SYNTH_BUFSIZE (16) #define SYNTH_BUFSIZE (16)
#define SYNTH_BUFMASK (0b00001111) #define SYNTH_BUFMASK (0b00001111)
enum { WAVE_OFF, WAVE_PULSE, WAVE_SAW, WAVE_NOISE }; enum {
WAVE_OFF, WAVE_PULSE, WAVE_SAW, WAVE_NOISE
};
typedef struct { typedef struct {
uint8_t note; uint8_t note;
uint8_t inst_nr; uint8_t inst_nr;
uint8_t pos; uint8_t pos;
uint16_t phase; uint16_t phase;
uint16_t pulse_width; uint16_t pulse_width;
uint8_t level; // envelop level uint8_t level; // envelop level
} synth_channel_t; } synth_channel_t;
typedef struct { typedef struct {
uint16_t pulse_width; uint16_t pulse_width;
uint8_t pulse_sweep; uint8_t pulse_sweep;
uint8_t wave_table_pos; uint8_t wave_table_pos;
uint8_t decay; uint8_t decay;
} synth_instrument_t; } synth_instrument_t;
void synth_init(void); void synth_init(void);
void synth_poll(void); void synth_poll(void);

View File

@ -23,62 +23,58 @@
#include <avr/io.h> #include <avr/io.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
//#include "main.h"
#include "usart.h" #include "usart.h"
#define UART_RXBUFSIZE 32 #define UART_RXBUFSIZE 32
static volatile uint8_t rxbuf0[UART_RXBUFSIZE]; static volatile uint8_t rxbuf0[UART_RXBUFSIZE];
static volatile uint8_t *volatile rxhead0, *volatile rxtail0; static volatile uint8_t * volatile rxhead0, * volatile rxtail0;
//volatile uint8_t xon = 0;
ISR (USART_RX_vect) ISR (USART_RX_vect) {
{
UCSR0B &= ~(1 << RXCIE0); UCSR0B &= ~(1 << RXCIE0);
asm volatile("sei"); asm volatile("sei");
int diff; int diff;
uint8_t c; uint8_t c;
c=UDR0; c = UDR0;
diff = rxhead0 - rxtail0; diff = rxhead0 - rxtail0;
if (diff < 0) diff += UART_RXBUFSIZE; if (diff < 0)
if (diff < UART_RXBUFSIZE -1) diff += UART_RXBUFSIZE;
{ if (diff < UART_RXBUFSIZE - 1) {
*rxhead0 = c; *rxhead0 = c;
++rxhead0; ++rxhead0;
if (rxhead0 == (rxbuf0 + UART_RXBUFSIZE)) rxhead0 = rxbuf0; if (rxhead0 == (rxbuf0 + UART_RXBUFSIZE))
rxhead0 = rxbuf0;
} }
UCSR0B |= (1 << RXCIE0); UCSR0B |= (1 << RXCIE0);
} }
void USART0_Init(void) {
void USART0_Init (void)
{
// set baudrate // set baudrate
#define BAUD_TOL 4 #define BAUD_TOL 4
#undef BAUD #undef BAUD
#define BAUD 115200 #define BAUD 115200
#include <util/setbaud.h> #include <util/setbaud.h>
UBRR0H = UBRRH_VALUE; UBRR0H = UBRRH_VALUE;
UBRR0L = UBRRL_VALUE; UBRR0L = UBRRL_VALUE;
#if USE_2X
UCSR0A |= (1 << U2X0); // enable double speed operation
#else
UCSR0A &= ~(1 << U2X0); // disable double speed operation
#endif
#if USE_2X
UCSR0A |= (1 << U2X0); // enable double speed operation
#else
UCSR0A &= ~(1 << U2X0); // disable double speed operation
#endif
// flush receive buffer // flush receive buffer
while ( UCSR0A & (1 << RXC0) ) UDR0; while (UCSR0A & (1 << RXC0))
UDR0;
// set 8N1 // set 8N1
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
UCSR0B &= ~(1 << UCSZ02); UCSR0B &= ~(1 << UCSZ02);
UCSR0B |= (1 << RXEN0)|(1 << TXEN0); //enable send and receive UCSR0B |= (1 << RXEN0) | (1 << TXEN0); //enable send and receive
UCSR0B |= (1 << RXCIE0); //enable receive interrup UCSR0B |= (1 << RXCIE0); //enable receive interrup
@ -86,39 +82,37 @@ void USART0_Init (void)
} }
void USART0_putc(char c) {
void USART0_putc (char c)
{
loop_until_bit_is_set(UCSR0A, UDRE0); loop_until_bit_is_set(UCSR0A, UDRE0);
UDR0 = c; UDR0 = c;
} }
uint8_t USART0_Getc_nb(uint8_t *c) {
uint8_t USART0_Getc_nb(uint8_t *c) if (rxhead0 == rxtail0)
{ return 0;
if (rxhead0==rxtail0) return 0;
*c = *rxtail0; *c = *rxtail0;
if (++rxtail0 == (rxbuf0 + UART_RXBUFSIZE)) rxtail0 = rxbuf0; if (++rxtail0 == (rxbuf0 + UART_RXBUFSIZE))
rxtail0 = rxbuf0;
return 1; return 1;
} }
void USART0_crlf(void){ void USART0_crlf(void) {
USART0_putc(0x0A); //newline USART0_putc(0x0A); //newline
USART0_putc(0x0D); //carriage return USART0_putc(0x0D); //carriage return
}; }
;
void USART0_put_uint8(uint8_t x){ void USART0_put_uint8(uint8_t x) {
uint8_t highchar=((x & 0b11110000)>>4)+0x30; uint8_t highchar = ((x & 0b11110000) >> 4) + 0x30;
uint8_t lowchar = (x & 0b00001111)+0x30; uint8_t lowchar = (x & 0b00001111) + 0x30;
highchar = highchar>0x39 ? highchar + 0x07 : highchar; //chars A to F start with 0x41 not 0x3A highchar = highchar > 0x39 ? highchar + 0x07 : highchar; //chars A to F start with 0x41 not 0x3A
lowchar = lowchar>0x39 ? lowchar + 0x07 : lowchar; lowchar = lowchar > 0x39 ? lowchar + 0x07 : lowchar;
USART0_putc(highchar); USART0_putc(highchar);
USART0_putc(lowchar); USART0_putc(lowchar);
} }
void USART0_put_uint16(uint16_t x){ void USART0_put_uint16(uint16_t x) {
USART0_put_uint8 ((x & 0xFF00)>>8); USART0_put_uint8((x & 0xFF00) >> 8);
USART0_put_uint8 (x & 0x00FF); USART0_put_uint8(x & 0x00FF);
} }

View File

@ -23,8 +23,8 @@
#ifndef _USART_H #ifndef _USART_H
#define _USART_H #define _USART_H
void USART0_Init (void); void USART0_Init(void);
void USART0_putc (char c); void USART0_putc(char c);
uint8_t USART0_Getc_nb(uint8_t*); uint8_t USART0_Getc_nb(uint8_t*);
void USART0_put_uint8(uint8_t); void USART0_put_uint8(uint8_t);
void USART0_crlf(void); void USART0_crlf(void);

View File

@ -1,4 +1,3 @@
#include <stdint.h> #include <stdint.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <avr/common.h> #include <avr/common.h>
@ -7,65 +6,53 @@
static volatile uint8_t internal_counter; static volatile uint8_t internal_counter;
void timer_init(void) void timer_init(void) {
{ /* initialize timer2, CTC at 10ms, prescaler 1024 */
/* initialize timer2, CTC at 10ms, prescaler 1024 */ OCR2A = F_CPU / 1024 / 100;
OCR2A = F_CPU/1024/100; TCCR2A = _BV(WGM21);
TCCR2A = _BV(WGM21); TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20);
TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20); TIMSK2 = _BV(OCIE2A);
TIMSK2 = _BV(OCIE2A);
} }
void timer_set(timer_t *t, uint8_t timeout) void timer_set(timer_t *t, uint8_t timeout) {
{ t->current = internal_counter;
t->current = internal_counter; t->timeout = timeout;
t->timeout = timeout;
} }
void timerL_set(timerL_t *t, uint16_t timeout) void timerL_set(timerL_t *t, uint16_t timeout) {
{ t->current = internal_counter;
t->current = internal_counter; t->timeout = timeout;
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 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;
bool timerL_expired(timerL_t *t) /* attention: may fail if internal counter is incremented by more than one
{ * between two calls of timer_expired()! */
if (t->timeout == 0) if (t->current != internal_counter) {
return true; t->timeout--;
t->current = internal_counter;
}
/* attention: may fail if internal counter is incremented by more than one return false;
* 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++;
/* timer interrupt function */
ISR(TIMER2_COMPA_vect, ISR_NOBLOCK) {
internal_counter++;
} }

View File

@ -8,16 +8,15 @@
/* structures */ /* structures */
typedef struct { typedef struct {
uint8_t current; uint8_t current;
uint8_t timeout; uint8_t timeout;
} timer_t; } timer_t;
typedef struct { typedef struct {
uint16_t current; uint16_t current;
uint16_t timeout; uint16_t timeout;
} timerL_t; } timerL_t;
/* functions */ /* functions */
void timer_init(void); void timer_init(void);
void timer_set(timer_t *t, uint8_t timeout); void timer_set(timer_t *t, uint8_t timeout);