This code is from project: 8 bit sound player
main.h
#ifndef _H_MAIN_ #define _H_MAIN_ #define F_CPU 8000000L #define H(a,b) a |=(1<<(b)) #define L(a,b) a &=~(1<<(b)) #define IS(a,b) bit_is_set(a,b) #define BS(a,b) (a & (1<<(b))) #endif #ifndef F_CPU #error CPU speed unknown #endif
main.c
#include "main.h"
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>
// for SPI
#define SPI_PORT PORTB
#define SPI_DDR DDRB
#define SPI_SS PB2
#define SPI_SI PB3
#define SPI_SO PB4
#define SPI_SCK PB5
// for flash
#define S1 1 // sound start page
#define S2 64
#define S3 84
// for delay
#define nop() __asm__ __volatile__("nop")
/****************************************************************************/
/* Declarations (this shoud be in .h file). */
/****************************************************************************/
void delay_ms(unsigned short);
void delay_us(unsigned short);
void disable();
void enable();
void initSPI();
uint8_t write(uint8_t);
void play(uint16_t);
void initPWM();
/****************************************************************************/
/* Main function */
/****************************************************************************/
int main()
{
// while(1); // when programming flash from raspberry, this should
// be uncommented, otherwise, amtega8 will disturb whole
// operation
initSPI();
initPWM();
while(1) {
play(S1); // play sound one
delay_ms(200); // delay
play(S2);
delay_ms(200);
play(S3);
};
return 0;
}
/****************************************************************************/
/* Delay functions */
/****************************************************************************/
void delay_ms(unsigned short ms) {
while ( ms ) {
ms--;
_delay_ms(1);
}
}
void delay_us(unsigned short us) {
while ( us ) {
us--;
_delay_us(1);
}
}
/****************************************************************************/
/* SPI functions. */
/****************************************************************************/
void disable() {
H(SPI_PORT, SPI_SS); // logic '1' on Chip Select mens 'disable slave'
}
void enable() {
H(SPI_PORT, SPI_SS); // logic '1->0' change means 'enable slave'
L(SPI_PORT, SPI_SS);
}
void initSPI() {
H(SPI_DDR, SPI_SS); // set directoins on pins
H(SPI_DDR, SPI_SI);
L(SPI_DDR, SPI_SO);
H(SPI_DDR, SPI_SCK);
SPSR = (1<<SPI2X); // set SPI specified registers
SPCR = (1<<SPE) | (1<<MSTR) | (1 << SPR1) | (1 << SPR0);
disable(); // make sure to disable at init
}
uint8_t write(uint8_t data) {
SPDR = data;
while(!(SPSR & (1 << SPIF)));
return SPDR;
}
/****************************************************************************/
/* PWM/SPI functoins */
/****************************************************************************/
void play(uint16_t addr) {
enable(); // enable SPI slave (Chip Select)
// continous read from Flash memmory (check datasheet)
write(0x03);
// move to current page
write( (addr >> 7) & 0x1F );
write( ((uint8_t) (addr << 1) & 0xFF) | (0 & 0x01) );
// move to current byte in page (here is 0, no offset)
write( (uint8_t) 0);
// play loop
while(1) {
// read one byte from flash memory, and write it directly
// to OCR1A register
OCR1A = write(0x00);
// found End Of Sound flag
if(OCR1A == 0)
break;
// SPI is in x2 mode, so slow down here
delay_us(17);
}
disable(); // disable SPI slave
}
/****************************************************************************/
/* PWM functions. */
/****************************************************************************/
void initPWM() {
H(DDRB, PB1);
// values below are experimental
TCCR1A = (1<<COM1A1) | (1<<COM1A0) | (1<<WGM10);
TCCR1B = (1<<CS10) | (1<<WGM12);
OCR1A = 0;
}
Makefile
CPU=atmega8 GCC=avr-gcc CFLAGS= -Os -mmcu=$(CPU) -Wall -fpack-struct -fshort-enums -funsigned-bitfields -Wl,--relax -fno-move-loop-invariants -funsigned-char -fno-inline-small-functions -fdata-sections -fno-tree-loop-optimize -lprintf_min INCLUDES= LIBS= OBJCPY=avr-objcopy OBJECTS=main.o PROJECT_NAME=mega8 HEX_FILE=$(PROJECT_NAME).hex HEX_FILE_DUMP=$(PROJECT_NAME)_dump.hex PROG=uisp PROG_FLAGS=-dprog=dapa all: cls $(PROJECT_NAME) obj size #upload $(PROJECT_NAME): $(OBJECTS) $(GCC) -o $(PROJECT_NAME) $(OBJECTS) $(CFLAGS) $(LIBS) $(INCLUDES) main.o: main.c main.h $(GCC) $(CFLAGS) $(INCLUDES) -c main.c obj: $(OBJECTS) $(OBJCPY) -O ihex $(PROJECT_NAME) $(HEX_FILE) clean: rm -f $(PROJECT_NAME) $(OBJECTS) $(HEX_FILE) cls: clear size: du -b $(HEX_FILE) upload: all $(HEX_FILE) $(PROG) $(PROG_FLAGS) --erase --upload if=$(HEX_FILE) download: $(PROG) $(PROG_FLAGS) --download of=$(HEX_FILE_DUMP)
No comments:
Post a Comment