Atmega8 SourceCode

37
Program Code of Programing device for AVT ATmega8 ProgramingDevice.c /***************************************************** This program was produced by the CodeWizardAVR V1.25.9 Standard Automatic Program Generator © Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.com Project : Programming device for AVR ATmega8 Version : 1.0 Date : 19/10/2008 Author : F4CG Company : F4CG Comments: We impress the tiem doing this prject. Chip type : ATmega128 Program type : Application Clock frequency : 16.000000 MHz Memory model : Small External SRAM size : 0 Data Stack size : 1024 *****************************************************/ #include <mega128.h> #include <delay.h> #include <string.h> //Keypad #define A PINA.0 #define B PINA.1 #define C PINA.2 #define D PINA.3 #define OE PORTA.4 #define DA PINA.5 //GLCD #define CS1 PORTD.4 #define CS2 PORTD.3 #define RES PORTD.2 #define DI PORTD.5 #define RW PORTD.6 #define E PORTD.7 #define LCDData PORTC //SPI #define DDR_SPI DDRB #define POST_SPI PORTB #define DD_SS 0 #define DD_SCK 1 #define DD_MOSI 2 #define DD_MISO 3 #define ResetPort 4 #define SPE 6

Transcript of Atmega8 SourceCode

Page 1: Atmega8 SourceCode

Program Code of Programing device for AVT ATmega8

ProgramingDevice.c/*****************************************************This program was produced by theCodeWizardAVR V1.25.9 StandardAutomatic Program Generator© Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.http://www.hpinfotech.com

Project : Programming device for AVR ATmega8Version : 1.0Date : 19/10/2008Author : F4CG Company : F4CG Comments: We impress the tiem doing this prject.

Chip type : ATmega128Program type : ApplicationClock frequency : 16.000000 MHzMemory model : SmallExternal SRAM size : 0Data Stack size : 1024*****************************************************/

#include <mega128.h> #include <delay.h>#include <string.h>

//Keypad#define A PINA.0#define B PINA.1#define C PINA.2 #define D PINA.3#define OE PORTA.4#define DA PINA.5

//GLCD#define CS1 PORTD.4#define CS2 PORTD.3#define RES PORTD.2#define DI PORTD.5#define RW PORTD.6#define E PORTD.7#define LCDData PORTC

//SPI#define DDR_SPI DDRB#define POST_SPI PORTB#define DD_SS 0#define DD_SCK 1#define DD_MOSI 2#define DD_MISO 3#define ResetPort 4#define SPE 6

Page 2: Atmega8 SourceCode

#define MSTR 4#define SPI2X 0#define SPR1 1#define SPR0 0#define SPIF 7

// EEPROM#define EERIE 3#define EEMWE 2#define EEWE 1#define EERE 0

// SPI Programming#define SS PORTB.0#define SCK PORTB.1#define Reset PORTB.4

// StatusLED#define StatusLED PORTG

//GLCD Charactor Constantunsigned char character[94][5] = {0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,//Space

0b00000000,0b00000000,0b10011110,0b00000000,0b00000000,//!0b00000000,0b00001110,0b00000000,0b00001110,0b00000000,//"0b00101000,0b11111110,0b00101000,0b11111110,0b00101000,//#0b01001000,0b01010100,0b11111110,0b01010100,0b00100100,//$0b01000110,0b00100110,0b00010000,0b11001000,0b11000100,//%0b01101100,0b10010010,0b10101100,0b01000000,0b10110000,//&0b00000000,0b10100000,0b01100000,0b00000000,0b00000000,//'0b00000000,0b00111000,0b01000100,0b10000010,0b00000000,//(0b00000000,0b10000010,0b01000100,0b00111000,0b00000000,//)0b01000100,0b00101000,0b11111110,0b00101000,0b01000100,//*0b00010000,0b00010000,0b01111100,0b00010000,0b00010000,//+0b00000000,0b10100000,0b01100000,0b00000000,0b00000000,//,0b00010000,0b00010000,0b00010000,0b00010000,0b00010000,//-0b00000000,0b11000000,0b11000000,0b00000000,0b00000000,//.0b00000000,0b11000000,0b11000000,0b00000000,0b00000000,///0b01111100,0b10100010,0b10010010,0b10001010,0b01111100,//00b00000000,0b10000100,0b11111110,0b10000000,0b00000000,//10b10000100,0b11000010,0b10100010,0b10010010,0b10001100,//20b01000010,0b10000010,0b10001010,0b10010110,0b01100010,//30b00110000,0b00101000,0b00100100,0b11111110,0b00100000,//40b01001110,0b10001010,0b10001010,0b10001010,0b01110010,//50b01111000,0b10010100,0b10010010,0b10010010,0b01100000,//60b00000010,0b00000010,0b11100010,0b00011010,0b00000110,//70b01101100,0b10010010,0b10010010,0b10010010,0b01101100,//80b00001100,0b10010010,0b10010010,0b01010010,0b00111100,//90b00000000,0b01101100,0b01101100,0b00000000,0b00000000,//:0b00000000,0b10101100,0b01101100,0b00000000,0b00000000,//;0b00010000,0b00101000,0b01000100,0b10000010,0b00000000,//<0b00101000,0b00101000,0b00101000,0b00101000,0b00101000,//=0b00000000,0b10000010,0b01000100,0b00101000,0b00010000,//>0b00000110,0b00000001,0b10110001,0b00010001,0b00001110,//?0b01111100,0b10000010,0b10111010,0b10101010,0b00111100,//@0b11111100,0b00010010,0b00010010,0b00010010,0b11111100,//A0b11111110,0b10010010,0b10010010,0b10010010,0b01101100,//B0b01111100,0b10000010,0b10000010,0b10000010,0b01000100,//C0b11111110,0b10000010,0b10000010,0b01000100,0b00111000,//D

Page 3: Atmega8 SourceCode

0b11111110,0b10010010,0b10010010,0b10010010,0b10000010,//E0b11111110,0b00010010,0b00010010,0b00010010,0b00000010,//F0b01111100,0b10000010,0b10010010,0b10010010,0b11110100,//G0b11111110,0b00010000,0b00010000,0b00010000,0b11111110,//H0b00000000,0b10000010,0b11111110,0b10000010,0b00000000,//I0b01000000,0b10000010,0b10000010,0b01111110,0b00000010,//J0b11111110,0b00010000,0b00101000,0b01000100,0b10000010,//K0b11111110,0b10000000,0b10000000,0b10000000,0b10000000,//L0b11111110,0b00000100,0b00011000,0b00000100,0b11111110,//M0b11111110,0b00001000,0b00010000,0b00100000,0b11111110,//N0b01111100,0b10000010,0b10000010,0b10000010,0b01111100,//O0b11111110,0b00010010,0b00010010,0b00010010,0b00001100,//P0b01111100,0b10000010,0b10100010,0b01000010,0b10111100,//Q0b11111110,0b00010010,0b00110010,0b01010010,0b10001100,//R0b01001100,0b10010010,0b10010010,0b10010010,0b01100100,//S0b00000010,0b00000010,0b11111110,0b00000010,0b00000010,//T0b01111110,0b10000000,0b10000000,0b10000000,0b01111110,//U0b00111110,0b01000000,0b10000000,0b01000000,0b00111110,//V0b01111110,0b10000000,0b01110000,0b10000000,0b01111110,//W0b11000110,0b00101000,0b00010000,0b00101000,0b11000110,//X0b00000110,0b00001000,0b11110000,0b00001000,0b00000110,//Y0b11000010,0b10100010,0b10010010,0b10001010,0b10000110,//Z0b11111110,0b10000010,0b10000010,0b00000000,0b00000000,//[0b00000000,0b00000000,0b10000010,0b10000010,0b11111110,//]0b00000100,0b00001000,0b00010000,0b00100000,0b01000000,//'0b00001000,0b00000100,0b00000010,0b00000100,0b00001000,//^0b10000000,0b10000000,0b10000000,0b10000000,0b10000000,//_0b00000000,0b00000000,0b00000110,0b00000000,0b00000000,//'0b01000000,0b10101000,0b10101000,0b10101000,0b11110000,//a0b11111110,0b10001000,0b10001000,0b10001000,0b01110000,//b0b01110000,0b10001000,0b10001000,0b10001000,0b10001000,//c0b01110000,0b10001000,0b10001000,0b10001000,0b11111110,//d0b01110000,0b10101000,0b10101000,0b10101000,0b00110000,//e0b00001000,0b00001000,0b11111100,0b00001010,0b00001010,//f0b00010000,0b10101000,0b10101000,0b10101000,0b01111000,//g0b11111110,0b00010000,0b00001000,0b00001000,0b11110000,//h0b00000000,0b10001000,0b11111010,0b10000000,0b00000000,//i0b01000000,0b10000000,0b10001000,0b01111010,0b00000000,//j0b00000000,0b11111110,0b00100000,0b01010000,0b10001000,//k0b00000000,0b10000010,0b11111110,0b10000000,0b00000000,//l0b11111000,0b00001000,0b11110000,0b00001000,0b11110000,//m0b11111000,0b00010000,0b00001000,0b00001000,0b11110000,//n0b01110000,0b10001000,0b10001000,0b10001000,0b01110000,//o0b11111000,0b00101000,0b00101000,0b00101000,0b00010000,//p0b00010000,0b00101000,0b00101000,0b00101000,0b11111000,//q0b00000000,0b11111000,0b00010000,0b00001000,0b00001000,//r0b10010000,0b10101000,0b10101000,0b10101000,0b01000000,//s0b00001000,0b00001000,0b01111110,0b10001000,0b10001000,//t0b01111000,0b10000000,0b10000000,0b01000000,0b11111000,//u0b00111000,0b01000000,0b10000000,0b01000000,0b00111000,//v0b01111000,0b10000000,0b01100000,0b10000000,0b01111000,//w0b10001000,0b01010000,0b00100000,0b01010000,0b10001000,//x0b00011000,0b10100000,0b10100000,0b10100000,0b01111000,//y0b10001000,0b11001000,0b10101000,0b10011000,0b10001000,//z0b00000000,0b00010000,0b01101100,0b10000010,0b10000010,//{0b00000000,0b00000000,0b11111110,0b00000000,0b00000000,//|0b10000010,0b10000010,0b01101100,0b00010000,0b00000000};//}

Page 4: Atmega8 SourceCode

//Device code and nameunsigned char deviceName[17][10] = {"tiny12","tiny15","S1200","S2313","S2323","S2333","S2343","S4414","S4433","S4434","S8515","S8535","mega32","mega83","mega103","mega161","mega163"};unsigned char deviceCode[17][2] = {0x90,0x05,0x90,0x06,0x90,0x01,0x91,0x01,0x91,0x02,0x91,0x05,0x91,0x03,0x92,0x01,0x92,0x03,0x92,0x02,0x93,0x01,0x93,0x03,0x95,0x01,0x93,0x05,0x97,0x01,0x94,0x01,0x94,0x02};

//GLCD //Integer to Ascii, not usedvoid IToA(unsigned char num,unsigned char *temp,unsigned char base){ if(base == 16) { if(num<10) { temp[0] = num+48; } else { temp[0] = num+55; } temp[1] = '\0'; }}

//Print flash text on GLCDvoid LCDPrintFlash(flash char *data,unsigned char flag){

unsigned char i = 0;unsigned char j = 0;

i = 0;DI = 1;while(data[j] != '\0'){

i = 0;while(i < 5){

LCDData = character[((data[j])-32)][i];if(flag) LCDData = 0xff-LCDData;E = 1;E = 0;delay_ms(1);i++;

}LCDData = 0x00; if(flag) LCDData = 0xff-LCDData;E = 1;E = 0;delay_ms(1);j++;

}}

Page 5: Atmega8 SourceCode

//Goto XYvoid LCDGotoXY(unsigned char page, unsigned char y, unsigned char CS){

unsigned char init[2];unsigned char i = 0;

DI = 0;if(CS == 0){

CS1 = 1;CS2 = 0;

}else{

CS1 = 0;CS2 = 1;

}init[0] = 0xB8 + page;init[1] = 0x40 + (y*6);if(CS==0){

init[1] += 4;}while(i < 2){

LCDData = init[i];E = 1;E = 0;delay_ms(1);i++;

}}

//Clear GLCD by write space on evey areavoid LCDClear(void){

unsigned char i = 0;unsigned char j = 0;

CS1 = 1;CS2 = 1;while(j < 8){

DI = 0;LCDData = 0xB8 + j;E = 1;E = 0;delay_ms(1);i++;i=0;DI = 1;while(i < 64){

LCDData = 0x00;CS2 = 1;E = 1;E = 0;delay_ms(1);i++;

Page 6: Atmega8 SourceCode

}j++;

}LCDGotoXY(0,0,0);

}

//Init GLCDvoid LCDInit(void){

unsigned char init[4];unsigned char i = 0;

RES = 1;RW = 0;DI = 0;CS1 = 1;CS2 = 1;init[0] = 0x3F; //Turn Oninit[1] = 0xC0; //Z addressinit[2] = 0x40; //Y addressinit[3] = 0xB8; //X address (page)

while(i<4){

LCDData = init[i];E = 1;E = 0;delay_ms(1);i++;

}CS2 = 0;LCDClear();

}

//Keypad//Wait until any key press and return that keyunsigned char GetKey(void){ unsigned char temp; temp = 0x00; //Enable key scan OE = 0; temp = 0x00; while(!DA); if(A) { if(B) { if(C) { if(D) { //Return temp = 0x0F; } else

Page 7: Atmega8 SourceCode

{ //0 temp = 0x00; } } else { if(D) { //> temp = 0x0B; } else { //< temp = 0x0A; } } } else { if(C) { if(D) { //^ temp = 0x0D; } else { //5 temp = 0x05; } } else { if(D) { //6 temp = 0x06; } else { //4 temp = 0x04; } } } } else { if(B) { if(C) { if(D) { //V temp = 0x0E;

Page 8: Atmega8 SourceCode

} else { //8 temp = 0x08; } } else { if(D) { //9 temp = 0x09; } else { //7 temp = 0x7; } } } else { if(C) { if(D) { //Set temp = 0x0C; } else { //2 temp = 0x2; } } else { if(D) { //3 temp = 0x03; } else { //1 temp = 0x01; } } } } delay_ms(300); //Disable key scan OE = 1; return(temp);}

Page 9: Atmega8 SourceCode

//SPI//Enable SPI for chip programmingvoid SPI_MasterInit(void){ // Enable SPI, Master, set clock rate fck/128 SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0);}

//SPI transmitvoid SPI_MasterTransmit(char cData){ // Start transmission SPDR = cData; // Wait for transmission complete while(!(SPSR & (1<<SPIF)));}

//SPI receivechar SPI_SlaveReceive(void){ // Wait for reception complete while(!(SPSR & (1<<SPIF))); // Return data register return(SPDR);}

//EEPROM//Write data into EEPROMvoid EEPROM_write(unsigned int uiAddress, unsigned char ucData){ // Wait for completion of previous write while(EECR & (1<<EEWE)) ; // Set up address and data registers EEAR = uiAddress; EEDR = ucData; // Write logical one to EEMWE EECR |= (1<<EEMWE); // Start eeprom write by setting EEWE EECR |= (1<<EEWE);}

//Read data from EEPROMunsigned char EEPROM_read(unsigned int uiAddress){ // Wait for completion of previous write while(EECR & (1<<EEWE)) ; // Set up address register EEAR = uiAddress; // Start eeprom read by writing EERE EECR |= (1<<EERE); // Return data from data register return EEDR;}

Page 10: Atmega8 SourceCode

//SPI Programing//Use flash LED to show response of target void Response(flash unsigned char *data){ unsigned char i = 0; DDRG = 0xff; while(data[i] != '\0') { delay_ms(100); if(data[i] == '0') { PORTG =0x00; } else { PORTG =0x01; } i++; }}

//Send programming enable command to the targetunsigned char SPI_Programming_Init(void){ unsigned char temp = 0x00; //Power-up sequence Reset = 0; SCK = 0; //Given possitive pulse of at lease two CPU clock cycle duration Reset = 0; Reset = 1; Reset = 1; Reset = 1; Reset = 1; Reset = 1; Reset = 0; //Wait at lease 20 ms delay_ms(100); //Send programing enable command SPI_MasterTransmit(0xAC); SPI_MasterTransmit(0x53); SPI_MasterTransmit(0x00); temp = SPI_SlaveReceive(); SPI_MasterTransmit(0x00); //Check response from target if(temp == 0x53) { return(0xFF); } else { return(0x00); }}

Page 11: Atmega8 SourceCode

//Read vendor code, part family, flash size, and part number//of the target chipunsigned char ReadDeviceCode(void){ unsigned char vendorCode = 0x00; unsigned char partFamilyAndFlashSize = 0x00; unsigned char partNumber = 0x00; unsigned char i = 0x00; //Read device code SPI_MasterTransmit(0x30); SPI_MasterTransmit(0x00); SPI_MasterTransmit(0x00); SPI_MasterTransmit(0x30); vendorCode = SPI_SlaveReceive(); //Read part family and memory size SPI_MasterTransmit(0x30); SPI_MasterTransmit(0x00); SPI_MasterTransmit(0x01); SPI_MasterTransmit(0x30); partFamilyAndFlashSize = SPI_SlaveReceive(); //Read part family and memory size SPI_MasterTransmit(0x30); SPI_MasterTransmit(0x00); SPI_MasterTransmit(0x02); SPI_MasterTransmit(0x30); partNumber = SPI_SlaveReceive(); if(vendorCode == 0x1E) { while(1) { if(deviceCode[i][0] == partFamilyAndFlashSize & deviceCode[i][0] == partNumber) break; i++; } return(i); } else { return(0xFF); }}

//Read flash high and low byteunsigned int ReadFlash(unsigned int address){ unsigned char addressH; unsigned char addressL; unsigned char flashH; unsigned char flashL; unsigned int data = 0x0000; addressH = address>>8; addressL = address;

Page 12: Atmega8 SourceCode

//Read flash high byte SPI_MasterTransmit(0x28); SPI_MasterTransmit(addressH); SPI_MasterTransmit(addressL); SPI_MasterTransmit(0x00); flashH = SPI_SlaveReceive(); //Read flash low byte SPI_MasterTransmit(0x20); SPI_MasterTransmit(addressH); SPI_MasterTransmit(addressL); SPI_MasterTransmit(0x00); flashL = SPI_SlaveReceive(); data = flashL; data = data<<8; data += flashH; return(data);}

//Write flash, using EEPROM datavoid WritePageFlash(void){ unsigned int i = 0x00; unsigned int j = 0x00; //Write only 128 page for(i=0;i<128;i++) { //Write data in tempororary page for(j=0;j<32;j++) { //Low byte SPI_MasterTransmit(0x40); SPI_MasterTransmit(0x00); SPI_MasterTransmit(j); SPI_MasterTransmit(EEPROM_read((i*0x0040)+(j*2))); //High byte SPI_MasterTransmit(0x48); SPI_MasterTransmit(0x00); SPI_MasterTransmit(j); SPI_MasterTransmit(EEPROM_read((i*0x0040)+(j*2)+1)); } //Write temporary page into the real flash SPI_MasterTransmit(0x4C); SPI_MasterTransmit(i>>3); SPI_MasterTransmit(i<<5); SPI_MasterTransmit(0x00); //Show status delay_ms(5); StatusLED = 1; delay_ms(5); StatusLED = 0; }}

Page 13: Atmega8 SourceCode

//Check data in flash compare to the data in EEPROM//Return 0xFF if all data are correct//and 0x00 if some data is not correctunsigned char VerifyFlash(void){ unsigned int address; unsigned char data; for(address=0;address<4096;address++) { //Low byte SPI_MasterTransmit(0x20); SPI_MasterTransmit(address>>8); SPI_MasterTransmit(address); SPI_MasterTransmit(0x00); data = SPI_SlaveReceive(); if(EEPROM_read((2*address)) != data) { return(0x00); } //High byte SPI_MasterTransmit(0x28); SPI_MasterTransmit(address>>8); SPI_MasterTransmit(address); SPI_MasterTransmit(0x00); data = SPI_SlaveReceive(); if(EEPROM_read((2*address)+1) != data) { return(0x00); } } return(0xFF); }

//Write target EEPROM datavoid WriteEEPROM(void){ unsigned int address; for(address=0;address<512;address++) { SPI_MasterTransmit(0xC0); SPI_MasterTransmit(address>>8); SPI_MasterTransmit(address); SPI_MasterTransmit(EEPROM_read(address)); delay_ms(5); StatusLED = 1; delay_ms(5); StatusLED = 0; }}

//Check data in target EEPROM compare to the data in EEPROM//Return 0xFF if all data are correct//and 0x00 if some data is not correctunsigned char VerifyEEPROM(void){

Page 14: Atmega8 SourceCode

unsigned int address; unsigned int data; for(address=0;address<512;address++) { SPI_MasterTransmit(0xa0); SPI_MasterTransmit(address>>8); SPI_MasterTransmit(address); SPI_MasterTransmit(0x00); data = SPI_SlaveReceive(); if(EEPROM_read(address) != data) { return(0x00); } delay_ms(5); StatusLED = 1; delay_ms(5); StatusLED = 0; } return(0xFF);}

//Erease the target chipvoid ChipErease(void){ SPI_MasterTransmit(0xAC); SPI_MasterTransmit(0x80); SPI_MasterTransmit(0x04); SPI_MasterTransmit(0x00); delay_ms(100);}

//Menuvoid ShowTitle(void){ LCDClear(); LCDGotoXY(2,0,0); LCDPrintFlash(" Programme",0); LCDGotoXY(2,0,1); LCDPrintFlash("r Device",0); LCDGotoXY(4,0,0); LCDPrintFlash(" For AVR",0); LCDGotoXY(4,0,1); LCDPrintFlash(" ATmega8",0);}

void ShowMenu(void){ LCDClear(); LCDGotoXY(1,0,0); LCDPrintFlash(" ME",0); LCDGotoXY(1,0,1); LCDPrintFlash("NU",0); LCDGotoXY(3,0,0); LCDPrintFlash(" > Progra",0); LCDGotoXY(3,0,1);

Page 15: Atmega8 SourceCode

LCDPrintFlash("m Flash",0); LCDGotoXY(4,0,0); LCDPrintFlash(" Progra",0); LCDGotoXY(4,0,1); LCDPrintFlash("m EEPROM",0); LCDGotoXY(5,0,0); LCDPrintFlash(" Comman",0); LCDGotoXY(5,0,1); LCDPrintFlash("d 3",0); LCDGotoXY(6,0,0); LCDPrintFlash(" Comman",0); LCDGotoXY(6,0,1); LCDPrintFlash("d 4",0);}

void main(void){// Declare your local variables hereunsigned char SPI_enable = 0x00;unsigned char enableLine = 0x00;unsigned char key = 0x00;

// Input/Output Ports initialization// Port A initialization// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTA=0x00;DDRA=0x10;

// Port B initialization// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTB=0x00;DDRB=0x17;

// Port C initialization// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00;DDRC=0xFF;

// Port D initialization// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTD=0x00;DDRD=0xFF;

// Port E initialization// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTE=0x00;DDRE=0x00;

// Port F initialization// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTF=0x00;DDRF=0x00;

Page 16: Atmega8 SourceCode

// Port G initialization// Func4=In Func3=In Func2=In Func1=In Func0=In // State4=T State3=T State2=T State1=T State0=T

//Show titleLCDInit();LCDClear();ShowTitle();

//Wait for key pressGetKey();while(1){ //Show menu LCDClear(); ShowMenu(); enableLine = 0x03; //Get key key = 0x00; //Wait for select a menu while(!(key==0x0F & (enableLine == 0x03 | enableLine == 0x04))) { key = GetKey(); //Shift cursor down if(key == 0x0E & enableLine < 0x06) { LCDGotoXY(enableLine,0,0); LCDPrintFlash(" ",0); enableLine++; LCDGotoXY(enableLine,0,0); LCDPrintFlash(" >",0); } //Shift cursor up if(key == 0x0D & enableLine > 0x03) { LCDGotoXY(enableLine,0,0); LCDPrintFlash(" ",0); enableLine--; LCDGotoXY(enableLine,0,0); LCDPrintFlash(" >",0); } } // Start flash programming if(enableLine == 0x03) { //Programming init SPI_MasterInit(); LCDClear(); LCDGotoXY(1,0,0); LCDPrintFlash("Starting",0); Response("101010101"); SPI_enable=0x00;

Page 17: Atmega8 SourceCode

//Enter prgramming mode while(SPI_enable==0x00) { SPI_enable = SPI_Programming_Init(); Response("11110000"); if(SPI_enable==0x00) { LCDClear(); LCDGotoXY(2,0,0); LCDPrintFlash("Starting fail.",0); Response("101010101"); } } //Chip Erease LCDGotoXY(2,0,0); LCDPrintFlash("Ereasing",0); ChipErease(); Response("101010101"); //Writing LCDGotoXY(3,0,0); LCDPrintFlash("Writing",0); WritePageFlash(); Response("101010101"); //Verifying LCDGotoXY(4,0,0); LCDPrintFlash("Verifying",0); if(VerifyFlash() == 0xFF) { LCDGotoXY(5,0,0); LCDPrintFlash("Programmin",0); LCDGotoXY(5,0,1); LCDPrintFlash("g Success ",0); Response("101010101"); } else { LCDGotoXY(5,0,0); LCDPrintFlash("Programmin",0); LCDGotoXY(5,0,1); LCDPrintFlash("g Fail ",0); Response("101010101"); } //Finished Reset = 1; delay_ms(500); } // Start EEPROM programming if(enableLine == 0x04) { //Programming init SPI_MasterInit(); LCDClear(); LCDGotoXY(1,0,0);

Page 18: Atmega8 SourceCode

LCDPrintFlash("Starting",0); Response("101010101"); SPI_enable=0x00; //Enter programming mode while(SPI_enable==0x00) { SPI_enable = SPI_Programming_Init(); Response("11110000"); if(SPI_enable==0x00) { LCDClear(); LCDGotoXY(2,0,0); LCDPrintFlash("Starting fail.",0); Response("101010101"); } } //Writing LCDGotoXY(2,0,0); LCDPrintFlash("Writing",0); WriteEEPROM(); Response("101010101"); //Verifying LCDGotoXY(3,0,0); LCDPrintFlash("Verifying",0); if(VerifyEEPROM() == 0xFF) { LCDGotoXY(4,0,0); LCDPrintFlash("Programmin",0); LCDGotoXY(4,0,1); LCDPrintFlash("g Success ",0); Response("101010101"); } else { LCDGotoXY(4,0,0); LCDPrintFlash("Programmin",0); LCDGotoXY(4,0,1); LCDPrintFlash("g Fail ",0); Response("101010101"); } //Finished Reset = 1; delay_ms(500); }};

}

Page 19: Atmega8 SourceCode

Lee.c

#include <avr/io.h>#include <avr/signal.h>#include <avr/interrupt.h>#include <avr/wdt.h>#include <stdio.h>#include <stdarg.h>#include <string.h>#include <stdlib.h>

#define F_CPU 16000000#include <util/delay.h>

#include "lcd.h"

#include "mydefs.h"#include "util.h"

#include "fatfile/fatfile.h"

//------------------------------------------------------------------------//char mmc_card_present (void){ MMC_CARD_PORT |= _BV (MMC_CARD_DET); // enable card detection, pull-up MMC_CARD_DDR &= ~_BV (MMC_CARD_DET); if (bit_is_clear(MMC_CARD_INP, MMC_CARD_DET)) return 0; // card detected return 1; // have card }//------------------------------------------------------------------------//unsigned char menu (void){

unsigned char choice;

printf ("\r\n");printf ("\r\n(1) Init card");printf ("\r\n(2) Read File");printf ("\r\n(3) Read Card information");printf ("\r\n\nPlease select ?");

while (1){

choice = ser_getc ();if ((choice > '0') && (choice < '4')){

break;}_delay_ms (1000);

};return choice;

}

//------------------------------------------------------------------------////-------------------------------------------------------------------------//unsigned char initCard (void){

unsigned char initCardFlag = 0;

Page 20: Atmega8 SourceCode

if (!mmc_card_present ()){

if(GetDriveInformation()!=F_OK) // get drive parameters{

printf ("\r\nCard Fail");initCardFlag = 0;LED_PORT &= ~_BV(LED);

}else{ // Card OK

printf ("\r\nCard OK\n");initCardFlag = 1;LED_PORT |= _BV(LED);

}}else{

printf ("\r\nNo Card");initCardFlag = 0;

}return initCardFlag;

}//------------------------------------------------------------------------//void ReadCardInfo (void){

LED_PORT |= _BV(LED);if(Findfirst()!=0) //Finde erste Datei/Verzeichnis im aktuellen Verzeichnis{

do{

printf("%s ",ffblk.ff_name); //8.3 DOS Nameif(ffblk.ff_attr==ATTR_FILE)

printf("% 9lu\n",ffblk.ff_fsize);if(ffblk.ff_attr==ATTR_DIRECTORY)

printf("<DIR>\n");if(ffblk.ff_longname[0]!=0)

printf("%s\n",ffblk.ff_longname);} while (Findnext()!=0);

}else{

printf("No file/dir found !\n");}

}//------------------------------------------------------------------------////------------------------------------------------------------------------////------------------------------------------------------------------------////------------------------------------------------------------------------////------------------------------------------------------------------------//int main(void){

DDRG |= _BV(LED);

SFIOR&=!(1<<PUD);

ser_init();

Page 21: Atmega8 SourceCode

init_uart1 ();

sei();

LED_PORT &= ~_BV(LED);

#ifdef LCDinit_lcd ();lcd_gotoxy (1,1);lcd_printf ("SD CARD");lcd_gotoxy (2,1);

#endif //LCD

printf ("\r\nSD card test");

if (!mmc_card_present ()){

printf ("\r\nCard Ready....");

if(GetDriveInformation()!=F_OK) // get drive parameters{

#ifdef LCDlcd_gotoxy (2,1);lcd_printf ("\r\nCard Fail");

#endifprintf ("\n\rCard Fail");

}else{

LED_PORT |= _BV(LED);#ifdef LCD

lcd_gotoxy (2,1);lcd_printf ("\r\nSD/MMC Ready");

#endifprintf ("\r\nCard OK\n");

}}else{

#ifdef LCDlcd_gotoxy (2,1);lcd_printf ("\r\nNo card");

#endif printf ("\r\nNO Card");

}

unsigned char key;

while (1){

key = menu ();#ifdef DEBUG

printf ("\r\nKey = %c",key);#endif

switch (key){

case '1' : //init card

Page 22: Atmega8 SourceCode

initCard ();break;

case '2' : //Read cardif (initCard ()){

LED_PORT |= _BV(LED);printf ("\r\nRead Files TEST.TXT");printf ("\r\nDetail in File : ");ReadFileRaw ("TEST.TXT");printf ("\r\n");

}else{

printf ("\r\nPlease select 1 before");

LED_PORT &= ~_BV(LED);}break;

case '3' :if (initCard ()){

printf ("\r\nGet Card Information\r\n");

ReadCardInfo ();printf ("\r\n");

}break;

default : //none valuebreak;

}

};

while (1);}

mydefs.h

#ifndef __MYDEFS_H#define __MYDEFS_H

#define F_16#define F_CPU 16000000 //processor clock

#define LCD

#define LED_PORT PORTG#define LED PG0

#endif //__MYDEFS_H

Page 23: Atmega8 SourceCode

util.h

#include <avr/io.h>#include <avr/signal.h>#include <avr/interrupt.h>

#define NOP() asm volatile ("nop" ::)#define sbi(portn, bitn) ((portn)|=(1<<(bitn)))#define cbi(portn, bitn) ((portn)&=~(1<<(bitn)))

dir.h#ifndef __DIR_H#define __DIR_H

extern unsigned char Mkdir(char *name);extern unsigned char Chdir(char *name);extern unsigned char MakeNewFileEntry(char fileid);extern unsigned char UpdateFileEntry(char fileid);

extern unsigned char ScanRootDir(char fileid);extern unsigned char ScanOneDirectorySector(char fileid, unsigned long sector);extern unsigned char SearchRootDir(char fileid);

#ifdef USE_FAT32 extern unsigned char SearchSubDir(char fileid, unsigned long cluster);extern unsigned char ScanSubDir(char fileid, unsigned long startcluster);#else extern unsigned char SearchSubDir(char fileid, unsigned int cluster); extern unsigned char ScanSubDir(char fileid, unsigned int startcluster);#endif

extern unsigned char SearchDirSector(char fileid, unsigned long sector);

extern void MakeFileName(char *inname, char fileid);

#define ls() FindName(-1)

#endif //__DIR_H

Page 24: Atmega8 SourceCode

dos.h

#ifndef __DOS_H#define __DOS_H

#define MAX_OPEN_FILE ((char) 1)// every 1 declared open file takes 558 Bytes for FAT12/16/32// every 1 declared open file takes 554 Bytes for FAT12/16 only// ATMega32 has only 2kB RAM. If you want to use 2 open files, you // have to switch off the FAT buffer !

//#define SMALL_FWRITE // less code but slower#define FAST_FWRITE // more code but faster

//#define SMALL_FREAD // less code but slower#define FAST_FREAD // more code but faster

// security check !#if defined (SMALL_FWRITE) && defined (FAST_FWRITE) #error "Define SMALL_FWRITE or FAST_FWRITE only in dos.h, NOT both !"#endif

#if !defined (SMALL_FWRITE) && !defined (FAST_FWRITE) #error "Define at least SMALL_FWRITE or FAST_FWRITE in dos.h !"#endif

#if defined (SMALL_FREAD) && defined (FAST_FREAD) #error "Define SMALL_FREAD or FAST_FREAD only in dos.h, NOT both !"#endif

#if !defined (SMALL_FREAD) && !defined (FAST_FREAD) #error "Define at least SMALL_FREAD or FAST_FREAD in dos.h !"#endif

// Some more defines for special filesystem handling

#define STRICT_FILESYSTEM_CHECKING // If you define this, some very rare special cases will be

// noticed. But this needs more code. // Special cases when files where made on a Win system

and // copied to the flash card: //

// Bug found by Michele Ribaudo // Files with zero filesize have no clusters

allocated ! // Calling Remove() and Fopen() may hang up the system. // If you define STRICT_FILESYSTEM_CHECKING opening a // zero length file for reading or writing gives an

error. // You can remove a zero length file ! // // You don't need this define if all files where made

with // my FAT system. Even if filesize is zero.

// If unsure keep it defined !

//fopen flags#define F_CLOSED 0

Page 25: Atmega8 SourceCode

#define F_READ 1#define F_WRITE 2

#define F_ERROR 0 // dir/file operation failed#define F_OK 1 // dir/file operation successfull

// #undef defines below in "mydefs.h" if you don't need them// spare program memory by deciding if we want to read, write or both#define DOS_READ //define this if you want to read files#define DOS_WRITE //define this if you want to write files#define DOS_DELETE //define this if you want to delete files#define DOS_READ_RAW //define this if you want to read files with ReadFileRaw()

#define DOS_CHDIR //define this if you want to go into subdirectories#define DOS_MKDIR //define this if you want to make subdirectories

// spare program memory by deciding if we want to use FAT12, FAT16, FAT32.// don't touch if you don't know the FAT type of your drive !#define USE_FAT12 //define this if you want to use FAT12#define USE_FAT16 //define this if you want to use FAT16#define USE_FAT32 //define this if you want to use FAT32

#define USE_FATBUFFER //define this if you want to use a FAT buffer //needs 517 Bytes of RAM !

#define USE_FINDFILE //define this if you want to use Findfirst(); Findnext();#define USE_FINDLONG //define this if you want to get long filenames

//from Findfirst(); Findnext();

extern char Fopen(char *name, unsigned char flag);extern void Fclose(char fileid);

extern unsigned int Fread(unsigned char *buf, unsigned int count, char fileid );extern unsigned int Fwrite(unsigned char *buf, unsigned int count, char fileid);

extern void Fflush(char fileid);extern void fflush_all(void);extern unsigned char Remove(char *name);extern unsigned long Filelength(char fileid);

extern unsigned char ReadFileRaw(char *name);extern unsigned char FindName(char fileid);extern char findfreefiledsc(void); // return -1 if too many open files

//this is for easier and faster converting from byte arrays to UINT, ULONG//ui and ul share the same memory space

union Convert { unsigned int ui; unsigned long ul;};

struct DateTime {// Default if you not have time

unsigned int day;unsigned int date;unsigned int month;unsigned int year; // 2007 (1980+27); == 2007unsigned int hour;

Page 26: Atmega8 SourceCode

unsigned int min;unsigned int sec;

};

struct DateTime RTC;

unsigned char updatefiles;

#ifdef MMC_CARD_SPI #include "mmc_spi.h"

#endif

#include "fat.h"#include "dir.h"

#ifdef USE_FINDFILE #include "find_x.h"#endif

#include "drivefree.h"

#endif //__DOS_H

drivefree.h

#ifndef __DRIVEFREE_H#define __DRIVEFREE_Hextern unsigned long drivefree(void);extern unsigned long driveused(void);extern unsigned long drivesize(void);#endif // __DRIVEFREE_H

Page 27: Atmega8 SourceCode

fat.h

#ifndef __FAT_H#define __FAT_H//#define FAT_DEBUG //activate output via printf() or puts()//file operations#define END_DIR 0#define NO_MATCH 1#define MATCH_NAME 2#define MATCH_EXT 3#define FULL_MATCH MATCH_NAME + MATCH_EXT

#define PART1_TABLE_OFFSET 0x01BE //offset to first partitiontable in sector 0

//Using structures needs less memory than indexing in arrays like inbuff[]//partitiontable structure//most of it is not used in this program//bootsector offset is the only thing we need//because C/H/S values are not used. LBA !

struct PartInfo { unsigned char status; //Partition status, 0x80 = Active, 0x00 = inactive unsigned char firsthead; //First head used by partition unsigned int firstseccyl; //First sector and cylinder used by partition unsigned char type; //Partition type unsigned char lasthead; //Last head used by partition unsigned int lastseccyl; //Last sector and cylinder used by partition unsigned long bootoffset; //Location of boot sector. !!!!!!!!!!! unsigned long secofpart; //Number of sectors for partition};

//first sector of disc is the master boot record//it contains four partitiontables//only the first partition is used in this programstruct MBR { unsigned char dummy[PART1_TABLE_OFFSET]; //we don't need all these bytes struct PartInfo part1; struct PartInfo part2; struct PartInfo part3; struct PartInfo part4;//all bytes below are not necessary};

//part of FAT12/16 bootsector different to FAT32struct RemBoot //FAT12/16 defs beginning at offset 36 {

unsigned char BS_DrvNum;unsigned char BS_Reserved1;unsigned char BS_BootSig;unsigned char BS_VolID[4];char BS_VolLab[11];char BS_FilSysType[8];unsigned char remaining_part[450];

};

Page 28: Atmega8 SourceCode

//part of FAT32 bootsector different to FAT12/16struct RemBoot32 //FAT32 defs beginning at offset 36 {

unsigned long BPB_FATSz32; //4 bytesunsigned int BPB_ExtFlags; //2 bytesunsigned int BPB_FSVer; //2 bytesunsigned long BPB_RootClus; //4 bytesunsigned int BPB_FSInfo; //2 bytesunsigned int BPB_BkBootSec; //2 bytesunsigned char BPB_Reserved[12];unsigned char BS_DrvNum;unsigned char BS_Reserved1;unsigned char BS_BootSig;unsigned long BS_VolID; //4 byteschar BS_VolLab[11];char BS_FilSysType[8];unsigned char remaining_part[422];

};

union endboot { struct RemBoot rm; struct RemBoot32 rm32;};

struct BootSec {

unsigned char BS_jmpBoot[3]; //3 bytechar BS_OEMName[8]; //8 byteunsigned int BPB_BytesPerSec; //2 bytesunsigned char BPB_SecPerClus; //1unsigned int BPB_RsvdSecCnt; //2 bytesunsigned char BPB_NumFATs; //1unsigned int BPB_RootEntCnt; //2 bytesunsigned int BPB_TotSec16; //2 bytesunsigned char BPB_Media; //1unsigned int BPB_FATSz16; //2 bytesunsigned int BPB_SecPerTrk; //2 bytesunsigned int BPB_NumHeads; //2 bytesunsigned long BPB_HiddSec; //4 bytesunsigned long BPB_TotSec32; //4 bytes

union endboot eb; //remaining part of bootsector};

#define BYTE_PER_SEC (unsigned int)512

#define FAT12 12#define FAT16 16#define FAT32 32

//defines for special cluster values//free cluster has value 0//for fat32 don't use upper four bits ! ignore them//cluster value of 0x10000000 is a FREE cluster in FAT32//values for end of cluster chain//ranges for example for FAT12 from 0xFF8 to 0xFFF

#define EOC12 0xFF8#define EOC16 0xFFF8

Page 29: Atmega8 SourceCode

#define EOC32 0x0FFFFFF8

//values for bad marked clusters#define BADC12 0xFF7#define BADC16 0xFFF7#define BADC32 0x0FFFFFF7

//values for reserved clusters//ranges for example for FAT12 from 0xFF0 to 0xFF6#define RESC12 0xFF0#define RESC16 0xFFF0#define RESC32 0x0FFFFFF0

#ifdef USE_FAT32 #define DISK_FULL 0xFFFFFFFF#else #define DISK_FULL 0xFFFF#endif

//File/Dir Attributes#define ATTR_FILE 0x00 //not defined by MS ! I did it #define ATTR_READ_ONLY 0x01#define ATTR_HIDDEN 0x02#define ATTR_SYSTEM 0x04#define ATTR_VOLUME_ID 0x08#define ATTR_DIRECTORY 0x10#define ATTR_ARCHIVE 0x20#define ATTR_LONG_NAME 0x0F#define ATTR_NO_ATTR 0xFF //not defined by MS ! I did it

//Char codes not allowed in a filename//NOT checked yet//0x22, 0x2A, 0x2B, 0x2C, 0x2E, 0x2F, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x5B, 0x5C, 0x5D, and 0x7C.

struct DirEntry { unsigned char DIR_Name[8]; //8 chars filename unsigned char DIR_Ext[3]; //3 chars extension unsigned char DIR_Attr; //file attributes RSHA unsigned char DIR_NTres; //set to zero unsigned char DIR_CrtTimeTenth; //creation time part in milliseconds unsigned int DIR_CrtTime; //creation time unsigned int DIR_CrtDate; //creation date unsigned int DIR_LastAccDate; //last access date (no time for this !) unsigned int DIR_FstClusHI; //first cluster high word unsigned int DIR_WrtTime; //last write time unsigned int DIR_WrtDate; //last write date unsigned int DIR_FstClusLO; //first cluster low word unsigned long DIR_FileSize; };

//do a little trick for getting long name characters from a DirEntry//DirEntryBuffer later gets the same adress as DirEntrystruct DirEntryBuffer { unsigned char longchars[sizeof(struct DirEntry)];};

Page 30: Atmega8 SourceCode

//Prototypesextern unsigned char GetDriveInformation(void);extern void UpdateFATBuffer(unsigned long newsector);

#ifdef USE_FAT32 extern unsigned long GetFirstSectorOfCluster(unsigned long n); extern unsigned long GetNextClusterNumber(unsigned long cluster); extern unsigned char WriteClusterNumber(unsigned long cluster, unsigned long number); extern unsigned long AllocCluster(unsigned long currentcluster); extern unsigned long FindFreeCluster(unsigned long currentcluster);#else extern unsigned long GetFirstSectorOfCluster(unsigned int n); extern unsigned int GetNextClusterNumber(unsigned int cluster); extern unsigned char WriteClusterNumber(unsigned int cluster, unsigned int number); extern unsigned int AllocCluster(unsigned int currentcluster); extern unsigned int FindFreeCluster(unsigned int currentcluster);#endif

#ifdef USE_FAT32 extern unsigned long endofclusterchain; extern unsigned long maxcluster; // last usable cluster+1 extern unsigned long FAT32RootCluster;#else extern unsigned int endofclusterchain; extern unsigned int maxcluster; // last usable cluster+1#endif

extern unsigned long maxsect; // last sector on driveextern unsigned char secPerCluster;extern unsigned long BytesPerCluster;

extern unsigned char dirbuf[]; //buffer for directory sectorsextern unsigned char fatbuf[]; //buffer for FAT sectors

struct FileDesc { //FileDescriptor structure unsigned char iob[BYTE_PER_SEC]; //file i/o buffer unsigned char FileName[8]; //file name

unsigned char FileExt[3]; //file extension unsigned char FileDirOffset; //dir entry offset in

FileDirSector/32 unsigned long FileCurrentSector; //number of sector with last

data read/written unsigned long File1stClusterSector; //1st sector of current cluster

used unsigned long FileDirSector; //dir sector holding this

fileentry unsigned long FileSize; unsigned long FilePosition; //file byte position unsigned char FileFlag; //open or closed unsigned char FileAttr; //file attribute. also used for

directory functions unsigned long FileClusterCount; //this is NOT uint !

#ifdef USE_FAT32 unsigned long FileFirstCluster; //needed for UpdateFileEntry() ! unsigned long FileCurrentCluster; //number of cluster in use

Page 31: Atmega8 SourceCode

#else //#ifdef USE_FAT32 unsigned int FileFirstCluster; unsigned int FileCurrentCluster;#endif //#ifdef USE_FAT32 };

extern struct FileDesc FileDescriptors[];

#ifdef USE_FAT32 extern unsigned long FirstDirCluster;#else extern unsigned int FirstDirCluster;#endif

//extern unsigned long FATHits; // count FAT write cycles. you don't really need this ;)extern unsigned long FATFirstSector;extern unsigned long FATCurrentSector;extern unsigned char FATtype;extern unsigned char FATStatus; // only for FAT write buffering

extern unsigned long FirstRootSector;extern unsigned long FirstDataSector; extern unsigned long RootDirSectors;#endif //FAT_H

fatfile.h

#ifndef __FATFILE__#define __FATFILE__#include "dir.h"#include "dos.h"#include "drivefree.h"#include "fat.h"#include "media.h"#include "mmc_spi.h"#include "printf.h"#include "serial.h"#endif

Page 32: Atmega8 SourceCode

find_x.h#ifndef __FINDX_H#define __FINDX_H

#define _MAX_NAME 255 // Max. length of long filenames + 1.// This should be 256, but i dont want// to use an unsigned int.// Maybe 128 or 64 Bytes are also enough// for a microcontroller DOS.// Change it here if you have problems// with free RAM.

struct FindFile{ unsigned char ff_attr; // file attributes like file, dir

// long name ,hidden,system and readonly flags are ignored unsigned long ff_fsize; // filesize of the file ( not directory ! )

char ff_name[13]; // 8.3 DOS filename with '.' in it and \0 at the end for fopen()#ifdef USE_FINDLONG char ff_longname[_MAX_NAME]; // The very long filename.#endif#ifdef USE_FAT32 unsigned long newposition; // position of this file entry in current directory (1 means first file) unsigned long lastposition; // position of last file entry found in current directory (1 means first file)#else unsigned int newposition; // position of this file entry in current directory (1 means first file) unsigned int lastposition; // position of last file entry found in current directory (1 means first file) // does also count ".", ".." entrys ! // does not count long filename entrys and volume id#endif};

extern struct FindFile ffblk;

extern unsigned char Findfirst(void);extern unsigned char Findnext(void);

extern unsigned char FindInOneDirectorySector(unsigned long sector);

#ifdef USE_FAT32 extern unsigned char FindInSubDir(unsigned long startcluster);#else extern unsigned char FindInSubDir(unsigned int startcluster);#endif

extern unsigned char FindInRootDir(void);

#endif //__FINDX_H

Page 33: Atmega8 SourceCode

media.h

#ifndef __FLASH_MEDIA_H#define __FLASH_MEDIA_H#define MMC_CARD_SPI //SD_CARD_SPI too !#endif //__FLASH_MEDIA_H

mmc_spi.h

#ifndef __MMC_CARD_SPI_H#define __MMC_CARD_SPI_H

//#define STANDARD_SPI_READ // No optimizations #define FAST_SPI_READ // Optimizations

//#define STANDARD_SPI_WRITE // No optimizations #define FAST_SPI_WRITE // Optimizations

#define SPI_REGISTER SPDR //makes it easier to switch to another hardware#define SPI_WRITE(a) { SPI_REGISTER=(a); while(! ( SPSR & (1<<SPIF) ));}#define SPI_WAIT() { while(! ( SPSR & (1<<SPIF) ) ); }

//#define MMC_DEBUG //activate debug output via printf()

#if defined (__AVR_ATmega644__)#define SPCR SPCR0#define SPIE SPIE0#define SPE SPE0#define DORD DORD0#define MSTR MSTR0#define CPOL CPOL0#define CPHA CPHA0#define SPR1 SPR01#define SPR0 SPR00

#define SPSR SPSR0#define SPIF SPIF0#define WCOL WCOL0#define SPI2X SPI2X0

#define SPDR SPDR0#endif

#if defined (__AVR_ATmega32__) || defined (__AVR_ATmega323__) || defined (__AVR_ATmega644__)

#define MMC_CS_PIN 4 //Pin number for MMC_CS #define MMC_CS_PORT PORTB //Port where MMC_CS is located #define MMC_CS_DDR DDRB //Port direction register where MMC_CS is located

#define MMC_SCK_BIT 7 #define MMC_SCK_PORT PORTB #define MMC_SCK_DDR DDRB #define MMC_MISO_BIT 6 #define MMC_MISO_PORT PORTB

Page 34: Atmega8 SourceCode

#define MMC_MISO_DDR DDRB

#define MMC_MOSI_BIT 5 #define MMC_MOSI_PORT PORTB #define MMC_MOSI_DDR DDRB

#elif defined (__AVR_ATmega128__) || defined (__AVR_ATmega64__)

#define MMC_CS_PIN 0 //Pin number for MMC_CS #define MMC_CS_PORT PORTB //Port where MMC_CS is located #define MMC_CS_DDR DDRB //Port direction register where MMC_CS is located

#define MMC_SCK_BIT 1 #define MMC_SCK_PORT PORTB #define MMC_SCK_DDR DDRB

#define MMC_MOSI_BIT 2 #define MMC_MOSI_PORT PORTB #define MMC_MOSI_DDR DDRB #define MMC_MISO_BIT 3 #define MMC_MISO_PORT PORTB #define MMC_MISO_DDR DDRB #define MMC_CARD_DET 4 #define MMC_CARD_PORT PORTB #define MMC_CARD_DDR DDRB #define MMC_CARD_INP PINB#else# error "processor type not defined in mmc_spi.h"#endif

#define MMC_CS_ON() sbi(MMC_CS_PORT,MMC_CS_PIN);#define MMC_CS_OFF() cbi(MMC_CS_PORT,MMC_CS_PIN);

// MMC/SD commands#define MMC_RESET 0x40 + 0#define MMC_INIT 0x40 + 1#define MMC_READ_CSD 0x40 + 9#define MMC_READ_CID 0x40 + 10#define MMC_STOP_TRANSMISSION 0x40 + 12#define MMC_SEND_STATUS 0x40 + 13#define MMC_SET_BLOCKLEN 0x40 + 16#define MMC_READ_BLOCK 0x40 + 17#define MMC_READ_MULTI_BLOCK 0x40 + 18#define MMC_WRITE_BLOCK 0x40 + 24#define MMC_WRITE_MULTI_BLOCK 0x40 + 25

//prototypesextern unsigned char MMCReadSector(unsigned long sector, unsigned char *buf);extern unsigned char MMCWriteSector(unsigned long sector, unsigned char *buf);extern unsigned char MMCIdentify(void);extern void MMC_IO_Init(void);

#define ReadSector(a,b) MMCReadSector((a),(b))#define WriteSector(a,b) MMCWriteSector((a),(b))#define IdentifyMedia() MMCIdentify()

#endif

Page 35: Atmega8 SourceCode

printf.h

#ifndef __PRINTF_H#define __PRINTF_H

#include <avr/pgmspace.h>extern void myputchar(unsigned char c);extern void _puts_P(char const *txt);

#define puts(text) _puts_P(PSTR(text))

extern void _printf_P (char const *fmt0, ...);#define printf(format, args...) _printf_P(PSTR(format) , ## args)#endif

serial.h

#ifndef ___SERIAL_H#define ___SERIAL_H

#include <avr/pgmspace.h>

#ifndef UART_BAUD_RATE//#define UART_BAUD_RATE 4800

#define UART_BAUD_RATE 9600

//#define UART_BAUD_RATE 19200//#define UART_BAUD_RATE 38400//#define UART_BAUD_RATE 115200 #endif

#define UART_BAUD_SELECT (F_CPU/(UART_BAUD_RATE*16l)-1)

extern void ser_init(void);extern void ser_putc(unsigned char c);extern void ser_puts(unsigned char *s);extern int ser_gets(unsigned char *s, unsigned char len);extern unsigned char ser_getc(void);extern void ser_puthex(unsigned char by);

extern volatile unsigned char rcnt, rpos;extern volatile unsigned char busy;

extern void _serputs_P(char const *txt);#define serputs_P(text) _serputs_P(PSTR(text))

extern void init_uart1 (void);extern char uart1_ReceiveByte (void);extern void uart1_SendByte (char data);extern void uart1_SendString (char *str);

Page 36: Atmega8 SourceCode

// Anpassungen an die vielen bescheuerten Namens ไ nderungen die ATMEL// quasi von ATMega zu ATMega in den Datenbl ไ ttern vornimmt.// Es k ๖ nnte soo einfach sein.#if defined (__AVR_ATmega32__) || defined (__AVR_ATmega323__) #define TX0_BIT 1 #define TX0_PORT PORTD #define TX0_DDR DDRD

#define SIG_UART0_RECEIVE SIG_UART_RECV #define SIG_UART0_TRANSMIT SIG_UART_TRANS #define UART0_RECEIVE_REGISTER UDR #define UART0_TRANSMIT_REGISTER UDR #define ENABLE_UART0_TRANSMIT_INT sbi(UCSRB,TXEN) //Wieso nehme ich hier nicht TXCIE ? #define DISABLE_UART0_TRANSMIT_INT cbi(UCSRB,TXEN) //Es gibt einen Grund, aber habe vergessen #define ENABLE_UART0_RECEIVE_INT sbi(UCSRB,RXCIE) #define DISABLE_UART0_RECEIVE_INT cbi(UCSRB,RXCIE) #define UART0_BAUD_REGISTER_HIGH UBRRH #define UART0_BAUD_REGISTER_LOW UBRRL #define UART0_CONFIGURE1 UCSRB= (1<<RXCIE) | (1<<TXCIE) | (1<<RXEN) | (1<<TXEN) #define UART0_CONFIGURE2 UCSRC= (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0) //8 Bit,1 Stop, no parity #elif defined (__AVR_ATmega161__) #define TX0_BIT 1 #define TX0_PORT PORTD #define TX0_DDR DDRD

#define SIG_UART0_RECEIVE SIG_UART0_RECV #define SIG_UART0_TRANSMIT SIG_UART0_TRANS #define UART0_RECEIVE_REGISTER UDR0 #define UART0_TRANSMIT_REGISTER UDR0 #define ENABLE_UART0_TRANSMIT_INT sbi(UCSR0B,TXEN) #define DISABLE_UART0_TRANSMIT_INT cbi(UCSR0B,TXEN); #define ENABLE_UART0_RECEIVE_INT sbi(UCSR0B,RXCIE) #define DISABLE_UART0_RECEIVE_INT cbi(UCSR0B,RXCIE) #define UART0_BAUD_REGISTER_HIGH UBRRH #define UART0_BAUD_REGISTER_LOW UBRR0 // Ich glaub es nicht. Wieso kein L statt 0 ? #define UART0_CONFIGURE1 UCSR0B= (1<<RXCIE) | (1<<TXCIE) | (1<<RXEN) | (1<<TXEN) #define UART0_CONFIGURE2 NOP() //Ho, ho, hoo. 8 Bit,1 Stop, no parity

#elif defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega644__) #define TX0_BIT 1 #define TX0_PORT PORTD #define TX0_DDR DDRD

#define SIG_UART0_RECEIVE SIG_USART_RECV #define SIG_UART0_TRANSMIT SIG_USART_TRANS #define UART0_RECEIVE_REGISTER UDR0 // UDR hat ne Null hinten, aber USART nicht. Ich schmei ฿ mich weg !!! #define UART0_TRANSMIT_REGISTER UDR0 #define ENABLE_UART0_TRANSMIT_INT sbi(UCSR0B,TXEN0);

Page 37: Atmega8 SourceCode

#define DISABLE_UART0_TRANSMIT_INT cbi(UCSR0B,TXEN0); #define ENABLE_UART0_RECEIVE_INT sbi(UCSR0B,RXCIE0) #define DISABLE_UART0_RECEIVE_INT cbi(UCSR0B,RXCIE0) #define UART0_BAUD_REGISTER_HIGH UBRR0H #define UART0_BAUD_REGISTER_LOW UBRR0L #define UART0_CONFIGURE1 UCSR0B= (1<<RXCIE0) | (1<<TXCIE0) | (1<<RXEN0) | (1<<TXEN0) // Was sollen jetzt die 0en hinter den Bits ? #define UART0_CONFIGURE2 UCSR0C= (1<<UCSZ01) | (1<<UCSZ00) //8 Bit,1 Stop, no parity

#elif defined (__AVR_ATmega8__) #define TX0_BIT 1 #define TX0_PORT PORTD #define TX0_DDR DDRD

#define SIG_UART0_RECEIVE SIG_UART_RECV #define SIG_UART0_TRANSMIT SIG_UART_TRANS #define UART0_RECEIVE_REGISTER UDR #define UART0_TRANSMIT_REGISTER UDR #define ENABLE_UART0_TRANSMIT_INT sbi(UCSRB,TXEN); #define DISABLE_UART0_TRANSMIT_INT cbi(UCSRB,TXEN); #define ENABLE_UART0_RECEIVE_INT sbi(UCSRB,RXCIE) #define DISABLE_UART0_RECEIVE_INT cbi(UCSRB,RXCIE) #define UART0_BAUD_REGISTER_HIGH UBRRH #define UART0_BAUD_REGISTER_LOW UBRRL #define UART0_CONFIGURE1 UCSRB= (1<<RXCIE) | (1<<TXCIE) | (1<<RXEN) | (1<<TXEN) #define UART0_CONFIGURE2 UCSRC= (1<<UCSZ1) | (1<<UCSZ0) //8 Bit,1 Stop, no parity

#elif defined (__AVR_ATmega128__) || defined (__AVR_ATmega64__) #define TX0_BIT 1 #define TX0_PORT PORTE #define TX0_DDR DDRE

#define SIG_UART0_RECEIVE SIG_UART0_RECV #define SIG_UART0_TRANSMIT SIG_UART0_TRANS #define UART0_RECEIVE_REGISTER UDR0 #define UART0_TRANSMIT_REGISTER UDR0 #define ENABLE_UART0_TRANSMIT_INT sbi(UCSR0B,TXEN) #define DISABLE_UART0_TRANSMIT_INT cbi(UCSR0B,TXEN); #define ENABLE_UART0_RECEIVE_INT sbi(UCSR0B,RXCIE) #define DISABLE_UART0_RECEIVE_INT cbi(UCSR0B,RXCIE)

#define UART0_BAUD_REGISTER_HIGH UBRR0H #define UART0_BAUD_REGISTER_LOW UBRR0L #define UART0_CONFIGURE1 UCSR0B= (1<<RXCIE) | (1<<TXCIE) | (1<<RXEN) | (1<<TXEN) #define UART0_CONFIGURE2 UCSR0C= (1<<UCSZ1) | (1<<UCSZ0) //8 Bit,1 Stop, no parity

#else# error "processor type not defined in serial.h"#endif

#endif