replace mmc layer with old software spi stuff

This commit is contained in:
David Voswinkel 2009-08-09 14:19:32 +02:00
parent d095867fe4
commit 4a0740dd02
7 changed files with 879 additions and 957 deletions

1216
avr/usbload/fat.c Executable file → Normal file

File diff suppressed because it is too large Load Diff

0
avr/usbload/fat.h Executable file → Normal file
View File

0
avr/usbload/file.c Executable file → Normal file
View File

0
avr/usbload/file.h Executable file → Normal file
View File

497
avr/usbload/mmc.c Executable file → Normal file
View File

@ -1,273 +1,224 @@
/*####################################################################################### /*#######################################################################################
Connect AVR to MMC/SD Connect AVR to MMC/SD
Copyright (C) 2004 Ulrich Radig Copyright (C) 2004 Ulrich Radig
Bei Fragen und Verbesserungen wendet euch per EMail an Bei Fragen und Verbesserungen wendet euch per EMail an
mail@ulrichradig.de mail@ulrichradig.de
oder im Forum meiner Web Page : www.ulrichradig.de oder im Forum meiner Web Page : www.ulrichradig.de
Dieses Programm ist freie Software. Sie k<EFBFBD>nnen es unter den Bedingungen der Dieses Programm ist freie Software. Sie können es unter den Bedingungen der
GNU General Public License, wie von der Free Software Foundation ver<EFBFBD>ffentlicht, GNU General Public License, wie von der Free Software Foundation veröffentlicht,
weitergeben und/oder modifizieren, entweder gem<EFBFBD><EFBFBD> Version 2 der Lizenz oder weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder
(nach Ihrer Option) jeder sp<EFBFBD>teren Version. (nach Ihrer Option) jeder späteren Version.
Die Ver<EFBFBD>ffentlichung dieses Programms erfolgt in der Hoffnung, Die Veröffentlichung dieses Programms erfolgt in der Hoffnung,
da<EFBFBD> es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, daß es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE,
sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT
F<EFBFBD>R EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License.
Sie sollten eine Kopie der GNU General Public License zusammen mit diesem Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
Programm erhalten haben. Programm erhalten haben.
Falls nicht, schreiben Sie an die Free Software Foundation, Falls nicht, schreiben Sie an die Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#######################################################################################*/ #######################################################################################*/
#include <avr/io.h> #include <avr/io.h>
#include <util/delay.h>
#include "mmc.h"
#include "mmc.h"
#include <util/delay.h>
uint8_t mmc_init()
//############################################################################ {
//Routine zur Initialisierung der MMC/SD-Karte (SPI-MODE) uint16_t Timeout = 0, i;
unsigned char mmc_init (void){ MMC_REG |= ((1 << MMC_DO) | (1 << MMC_CS) | (1 << MMC_CLK));
MMC_REG &= ~(1 << MMC_DI);
unsigned char a; MMC_WRITE |= ((1 << MMC_DO) | (1 << MMC_DI) | (1 << MMC_CS));
unsigned int Timeout = 0; _delay_ms(20);
for (i = 0; i < 250; i++) {
//Konfiguration des Ports an der die MMC/SD-Karte angeschlossen wurde MMC_WRITE ^= (1 << MMC_CLK);
MMC_Direction_REG &=~(1<<SPI_DI); //Setzen von Pin MMC_DI auf Input _delay_us(4);
MMC_Direction_REG |= (1<<SPI_Clock); //Setzen von Pin MMC_Clock auf Output }
MMC_Direction_REG |= (1<<SPI_DO); //Setzen von Pin MMC_DO auf Output MMC_WRITE &= ~(1 << MMC_CLK);
MMC_Direction_REG |= (1<<MMC_Chip_Select);//Setzen von Pin MMC_Chip_Select auf Output _delay_us(10);
MMC_Direction_REG |= (1<<SPI_SS); MMC_WRITE &= ~(1 << MMC_CS);
MMC_Write |= (1<<MMC_Chip_Select); //Setzt den Pin MMC_Chip_Select auf High Pegel _delay_us(3);
for(a=0;a<200;a++){ uint8_t CMD[] = { 0x40, 0x00, 0x00, 0x00, 0x00, 0x95 };
nop(); while (mmc_write_command(CMD) != 1) {
}; //Wartet eine kurze Zeit if (Timeout++ > 20) {
mmc_disable();
//Aktiviren des SPI - Bus, Clock = Idel LOW return (1);
//SPI Clock teilen durch 128 }
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1); //Enable SPI, SPI in Master Mode }
//Initialisiere MMC/SD-Karte in den SPI-Mode Timeout = 0;
for (a = 0;a<0x0f;a++){ //Sendet min 74+ Clocks an die MMC/SD-Karte CMD[0] = 0x41;
mmc_write_byte(0xff); CMD[5] = 0xFF;
} while (mmc_write_command(CMD) != 0) {
if (Timeout++ > 800) {
//Sendet Commando CMD0 an MMC/SD-Karte mmc_disable();
unsigned char CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95}; return (9);
while(mmc_write_command (CMD) !=1){ }
if (Timeout++ > 200){ }
MMC_Disable(); return (0);
return(1); //Abbruch bei Commando1 (Return Code1) }
} uint8_t mmc_write_command(uint8_t * cmd)
} {
//Sendet Commando CMD1 an MMC/SD-Karte uint8_t tmp = 0xff;
Timeout = 0; uint16_t Timeout = 0;
CMD[0] = 0x41;//Commando 1 uint8_t a;
CMD[5] = 0xFF;
while( mmc_write_command (CMD) !=0){ for (a = 0; a < 0x06; a++) {
if (Timeout++ > 400){ mmc_write_byte(*cmd++);
MMC_Disable(); }
return(2); //Abbruch bei Commando2 (Return Code2)
} while (tmp == 0xff) {
} tmp = mmc_read_byte();
if (Timeout++ > 50) {
//SPI Bus auf max Geschwindigkeit break;
SPCR &= ~((1<<SPR0) | (1<<SPR1)); }
SPSR = SPSR|(1<<SPI2X); }
return (tmp);
//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv) }
MMC_Disable();
return(0);
} uint8_t mmc_read_byte(void)
{
//############################################################################ uint8_t Byte = 0, j;
//Sendet ein Commando an die MMC/SD-Karte for (j = 0; j < 8; j++) {
unsigned char mmc_write_command (unsigned char *cmd){ Byte = (Byte << 1);
unsigned char a; MMC_WRITE |= (1 << MMC_CLK);
unsigned char tmp = 0xff; _delay_us(4);
unsigned int Timeout = 0; if (PINB & (1 << MMC_DI)) {
Byte |= 1;
//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv) }
MMC_Disable();
else {
//sendet 8 Clock Impulse Byte &= ~1;
mmc_write_byte(0xFF); }
MMC_WRITE &= ~(1 << MMC_CLK);
//set MMC_Chip_Select to low (MMC/SD-Karte Aktiv) _delay_us(4);
MMC_Enable(); }
return (Byte);
//sendet 6 Byte Commando }
for (a = 0;a<0x06;a++){
mmc_write_byte(*cmd++);
} void mmc_write_byte(uint8_t Byte)
{
//Wartet auf ein gültige Antwort von der MMC/SD-Karte uint8_t i;
while (tmp == 0xff){ for (i = 0; i < 8; i++) {
tmp = mmc_read_byte(); if (Byte & 0x80) {
if (Timeout++ > 500){ MMC_WRITE |= (1 << MMC_DO);
break; //Abbruch da die MMC/SD-Karte nicht Antwortet }
}
} else {
return(tmp); MMC_WRITE &= ~(1 << MMC_DO);
} }
Byte = (Byte << 1);
//############################################################################ MMC_WRITE |= (1 << MMC_CLK);
//Routine zum Empfangen eines Bytes von der MMC-Karte _delay_us(4);
unsigned char mmc_read_byte (void){ MMC_WRITE &= ~(1 << MMC_CLK);
SPDR = 0xff; _delay_us(4);
while(!(SPSR & (1<<SPIF))){}; }
return (SPDR); MMC_WRITE |= (1 << MMC_DO);
} }
//############################################################################ uint8_t mmc_write_sector(uint32_t addr, uint8_t * Buffer)
//Routine zum Senden eines Bytes zur MMC-Karte {
void mmc_write_byte (unsigned char Byte){ uint8_t tmp;
SPDR = Byte; //Sendet ein Byte
while(!(SPSR & (1<<SPIF))){ ; //Wartet bis Byte gesendet wurde
} uint8_t cmd[] = { 0x58, 0x00, 0x00, 0x00, 0x00, 0xFF };
} uint8_t a;
uint16_t i;
//############################################################################ addr = addr << 9;
//Routine zum schreiben eines Blocks(512Byte) auf die MMC/SD-Karte cmd[1] = ((addr & 0xFF000000) >> 24);
unsigned char mmc_write_sector (unsigned long addr,unsigned char *Buffer){ cmd[2] = ((addr & 0x00FF0000) >> 16);
unsigned char tmp; cmd[3] = ((addr & 0x0000FF00) >> 8);
unsigned int a;
unsigned char b;
tmp = mmc_write_command(cmd);
//Commando 24 zum schreiben eines Blocks auf die MMC/SD - Karte if (tmp != 0) {
unsigned char cmd[] = {0x58,0x00,0x00,0x00,0x00,0xFF}; return (tmp);
}
/*Die Adressierung der MMC/SD-Karte wird in Bytes angegeben,
addr wird von Blocks zu Bytes umgerechnet danach werden for (a = 0; a < 100; a++) {
diese in das Commando eingefuegt*/ mmc_read_byte();
}
addr = addr << 9; //addr = addr * 512
mmc_write_byte(0xFE);
cmd[1] = ((addr & 0xFF000000) >>24 );
cmd[2] = ((addr & 0x00FF0000) >>16 ); for (a = 0; i < 512; i++) {
cmd[3] = ((addr & 0x0000FF00) >>8 ); mmc_write_byte(*Buffer++);
}
//Sendet Commando cmd24 an MMC/SD-Karte (Write 1 Block/512 Bytes)
tmp = mmc_write_command (cmd); mmc_write_byte(0xFF);
mmc_write_byte(0xFF);
if (tmp != 0) return(tmp);
if ((mmc_read_byte() & 0x1F) != 0x05)
//Wartet einen Moment und sendet einen Clock an die MMC/SD-Karte return (1);
for (b=0;b<100;b++)
{ while (mmc_read_byte() != 0xff) {
mmc_read_byte(); };
} return (0);
}
//Sendet Start Byte an MMC/SD-Karte
mmc_write_byte(0xFE);
void mmc_read_block(uint8_t * cmd, uint8_t * Buffer, uint16_t Bytes)
//Schreiben des Bolcks (512Bytes) auf MMC/SD-Karte {
a=511; // do while konstrukt weils schneller geht uint16_t a;
tmp=*Buffer++; // holt neues byte aus ram in register
do{ if (mmc_write_command(cmd) != 0) {
SPDR = tmp; //Sendet ein Byte return;
tmp=*Buffer++; // holt schonmal neues aus ram in register }
while( !(SPSR & (1<<SPIF)) ){ ;}//Wartet bis Byte gesendet wurde
}while(a--); while (mmc_read_byte() != 0xfe) {
};
//CRC-Byte schreiben
mmc_write_byte(0xFF); //Schreibt Dummy CRC
mmc_write_byte(0xFF); //CRC Code wird nicht benutzt for (a = 0; a < Bytes; a++) {
*Buffer++ = mmc_read_byte();
//Fehler beim schreiben? (Data Response XXX00101 = OK) }
if((mmc_read_byte()&0x1F) != 0x05) return(1);
mmc_read_byte();
//Wartet auf MMC/SD-Karte Bussy mmc_read_byte();
while (mmc_read_byte() != 0xff){}; return;
}
//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
MMC_Disable(); uint8_t mmc_read_sector(uint32_t addr, uint8_t * Buffer)
{
return(0);
}
uint8_t cmd[] = { 0x51, 0x00, 0x00, 0x00, 0x00, 0xFF };
//############################################################################
//Routine zum lesen des CID Registers von der MMC/SD-Karte (16Bytes) addr = addr << 9;
void mmc_read_block(unsigned char *cmd,unsigned char *Buffer,unsigned int Bytes){ cmd[1] = ((addr & 0xFF000000) >> 24);
cmd[2] = ((addr & 0x00FF0000) >> 16);
unsigned int a; cmd[3] = ((addr & 0x0000FF00) >> 8);
mmc_read_block(cmd, Buffer, 512);
//Sendet Commando cmd an MMC/SD-Karte return (0);
if (mmc_write_command (cmd) != 0) }
{
return;
} uint8_t mmc_read_cid(uint8_t * Buffer)
{
//Wartet auf Start Byte von der MMC/SD-Karte (FEh/Start Byte)
uint8_t cmd[] = { 0x4A, 0x00, 0x00, 0x00, 0x00, 0xFF };
while (mmc_read_byte() != 0xfe){}; mmc_read_block(cmd, Buffer, 16);
return (0);
//Lesen des Bolcks (normal 512Bytes) von MMC/SD-Karte }
for (a=0;a<Bytes;a++)
{
*Buffer++ = mmc_read_byte(); uint8_t mmc_read_csd(uint8_t * Buffer)
} {
//CRC-Byte auslesen
mmc_read_byte();//CRC - Byte wird nicht ausgewertet uint8_t cmd[] = { 0x49, 0x00, 0x00, 0x00, 0x00, 0xFF };
mmc_read_byte();//CRC - Byte wird nicht ausgewertet mmc_read_block(cmd, Buffer, 16);
return (0);
//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv) }
MMC_Disable();
return;
}
//############################################################################
//Routine zum lesen eines Blocks(512Byte) von der MMC/SD-Karte
unsigned char mmc_read_sector (unsigned long addr,unsigned char *Buffer){
//Commando 16 zum lesen eines Blocks von der MMC/SD - Karte
unsigned char cmd[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
/*Die Adressierung der MMC/SD-Karte wird in Bytes angegeben,
addr wird von Blocks zu Bytes umgerechnet danach werden
diese in das Commando eingef<EFBFBD>gt*/
addr = addr << 9; //addr = addr * 512
cmd[1] = ((addr & 0xFF000000) >>24 );
cmd[2] = ((addr & 0x00FF0000) >>16 );
cmd[3] = ((addr & 0x0000FF00) >>8 );
mmc_read_block(cmd,Buffer,512);
return(0);
}
/*
//############################################################################
//Routine zum lesen des CID Registers von der MMC/SD-Karte (16Bytes)
unsigned char mmc_read_cid (unsigned char *Buffer){
//Commando zum lesen des CID Registers
unsigned char cmd[] = {0x4A,0x00,0x00,0x00,0x00,0xFF};
mmc_read_block(cmd,Buffer,16);
return(0);
}
//############################################################################
//Routine zum lesen des CSD Registers von der MMC/SD-Karte (16Bytes)
unsigned char mmc_read_csd (unsigned char *Buffer){
//Commando zum lesen des CSD Registers
unsigned char cmd[] = {0x49,0x00,0x00,0x00,0x00,0xFF};
mmc_read_block(cmd,Buffer,16);
return(0);
}
*/

88
avr/usbload/mmc.h Executable file → Normal file
View File

@ -1,44 +1,44 @@
/*####################################################################################### /*#######################################################################################
Connect ARM to MMC/SD Connect ARM to MMC/SD
Copyright (C) 2004 Ulrich Radig Copyright (C) 2004 Ulrich Radig
#######################################################################################*/ #######################################################################################*/
#ifndef _MMC_H #ifndef _MMC_H
#define _MMC_H #define _MMC_H
#define MMC_Write PORTB //Port an der die MMC/SD-Karte angeschlossen ist also des SPI
#define MMC_Read PINB #define SPI_Mode 0 //1 = Hardware SPI | 0 = Software SPI
#define MMC_Direction_REG DDRB
#define MMC_WRITE PORTB
#define MMC_READ PINB
#if defined (__AVR_ATmega644__) #define MMC_REG DDRB
#define SPI_DI 6 //Port Pin an dem Data Output der MMC/SD-Karte angeschlossen ist
#define SPI_DO 5 //Port Pin an dem Data Input der MMC/SD-Karte angeschlossen ist #define MMC_CS PB4
#define SPI_Clock 7 //Port Pin an dem die Clock der MMC/SD-Karte angeschlossen ist (clk) #define MMC_DO PB6
#define MMC_Chip_Select 3 //Port Pin an dem Chip Select der MMC/SD-Karte angeschlossen ist #define MMC_DI PB5
#define SPI_SS 4 //Nicht Benutz mu<6D> aber definiert werden #define MMC_CLK PB7
#endif
#define MMC_WRITE PORTB //Port an der die MMC/SD-Karte angeschlossen ist also des SPI
#define MMC_READ PINB
//Prototypes #define MMC_REG DDRB
extern unsigned char mmc_read_byte(void);
extern void mmc_write_byte(unsigned char);
extern void mmc_read_block(unsigned char *,unsigned char *,unsigned in);
extern unsigned char mmc_init(void);
extern unsigned char mmc_read_sector (unsigned long,unsigned char *); extern unsigned char mmc_read_byte(void);
extern unsigned char mmc_write_sector (unsigned long,unsigned char *); extern void mmc_write_byte(unsigned char);
extern unsigned char mmc_write_command (unsigned char *); extern void mmc_read_block(unsigned char *,unsigned char *,unsigned in);
//extern unsigned char mmc_read_csd (unsigned char *); extern unsigned char mmc_init(void);
//extern unsigned char mmc_read_cid (unsigned char *); extern unsigned char mmc_read_sector (unsigned long,unsigned char *);
extern unsigned char mmc_write_sector (unsigned long,unsigned char *);
//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv) extern unsigned char mmc_write_command (unsigned char *);
#define MMC_Disable() MMC_Write|= (1<<MMC_Chip_Select);
#define mmc_disable() MMC_WRITE|= (1<<MMC_CS);
//set MMC_Chip_Select to low (MMC/SD-Karte Aktiv)
#define MMC_Enable() MMC_Write&=~(1<<MMC_Chip_Select); #define mmc_enable() MMC_WRITE&=~(1<<MMC_CS);
#define nop() __asm__ __volatile__ ("nop" ::) #define nop() __asm__ __volatile__ ("nop" ::)
#endif #endif

View File

@ -1,5 +1,3 @@
/* /*
* ===================================================================================== * =====================================================================================
* *
@ -120,8 +118,6 @@ void test_sdcard(void){
while (mmc_init() !=0){ //ist der Rückgabewert ungleich NULL ist ein Fehler aufgetreten while (mmc_init() !=0){ //ist der Rückgabewert ungleich NULL ist ein Fehler aufgetreten
printf("no sdcard\n"); printf("no sdcard\n");
} }
if (fat_initfat()==0){ if (fat_initfat()==0){
printf("fatinit ok\n"); printf("fatinit ok\n");
} else { } else {
@ -130,49 +126,24 @@ void test_sdcard(void){
} }
ffls(); ffls();
char datei[12]="test.txt"; // hier muss platz für 11 zeichen sein (8.3), da fat_str diesen string benutzt !! char datei[12]="test.txt"; // hier muss platz für 11 zeichen sein (8.3), da fat_str diesen string benutzt !!
fat_str(datei); // wandelt "test.txt" in das fat format 8.3 der form: "TEST TXT" muss immer dieses Format haben, auch ordner !! fat_str(datei);
printf("rmove %s\n",datei);
// 0.) ______________löschen von dateien/ordnern (ordner rekursiv)____________________________________________
ffrm( datei ); // löschen der datei/ordner falls vorhanden ffrm( datei ); // löschen der datei/ordner falls vorhanden
// 1.) ______________anlegen und schreiben____________________________________________________________________
/* öffnet datei, wenn nicht vorhanden, legt ffopen datei an (rückgabewert = 1 datei existiert, also nur öffnen, 2 = angelegt). */
printf("open %s\n",datei); printf("open %s\n",datei);
ffopen( datei ); ffopen( datei );
printf("write %s\n",datei); printf("write %s\n",datei);
/* schreibt string */
ffwrites((char*)"Hallo Datei :)"); ffwrites((char*)"Hallo Datei :)");
// neue zeile in der datei
ffwrite(0x0D); ffwrite(0x0D);
ffwrite(0x0A); ffwrite(0x0A);
printf("close %s\n",datei); printf("close %s\n",datei);
/* schließt datei */
ffclose(); ffclose();
printf("open %s\n",datei); printf("open %s\n",datei);
// 2.)________________ändern von vorhandenen daten in dateien__________________________________________________
ffopen( datei ); // siehe oben...
printf("seek %s\n",datei);
ffseek(12); // spult in datei auf position 12 vor (fängt immer bei 0 an zu zählen !)
printf("write %s\n",datei);
ffwrite(';'); // schreibt dann ab position 12 (überschreibt daten der datei, hier nur 1 zeichen)
printf("close %s\n",datei);
ffclose(); // schließt datei
// 3.)________________lesen von dateien_________________________________________________________________________
ffopen( datei ); ffopen( datei );
ffls();
// siehe oben...
printf("open %s\n",datei); printf("open %s\n",datei);
unsigned long int seek=file.length; // eine variable setzen und runterzählen bis 0 geht am schnellsten ! unsigned long int seek=file.length; // eine variable setzen und runterzählen bis 0 geht am schnellsten !
do{ do{
printf("%c",ffread()); // liest ein zeichen und gibt es über uart aus ! printf("%c",ffread()); // liest ein zeichen und gibt es über uart aus !
}while(--seek); // liest solange bytes da sind (von datei länge bis 0) }while(--seek); // liest solange bytes da sind (von datei länge bis 0)
ffclose(); // schließt datei ffclose(); // schließt datei
} }