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