diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator.atsuo b/P8000_WDC_Emulator/P8000_WDC_Emulator.atsuo
index 53d8809..e060432 100755
Binary files a/P8000_WDC_Emulator/P8000_WDC_Emulator.atsuo and b/P8000_WDC_Emulator/P8000_WDC_Emulator.atsuo differ
diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/Debug/Makefile b/P8000_WDC_Emulator/P8000_WDC_Emulator/Debug/Makefile
index 75fadc2..eb01bae 100755
--- a/P8000_WDC_Emulator/P8000_WDC_Emulator/Debug/Makefile
+++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/Debug/Makefile
@@ -110,7 +110,7 @@ OUTPUT_FILE_DEP:= ./makedep.mk
./%.o: .././%.c
@echo Building file: $<
@echo Invoking: AVR/GNU C Compiler : (AVR_8_bit_GNU_Toolchain_3.4.0_663) 4.6.2
- $(QUOTE)C:\Program Files (x86)\Atmel\Atmel Studio 6.0\extensions\Atmel\AVRGCC\3.4.0.65\AVRToolchain\bin\avr-gcc.exe$(QUOTE) -funsigned-char -funsigned-bitfields -O1 -fpack-struct -fshort-enums -Wall -Wundef -Werror -pedantic -pedantic-errors -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)" -mmcu=atmega1284p -o"$@" "$<"
+ $(QUOTE)C:\Program Files (x86)\Atmel\Atmel Studio 6.0\extensions\Atmel\AVRGCC\3.4.0.65\AVRToolchain\bin\avr-gcc.exe$(QUOTE) -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fpack-struct -fshort-enums -Wall -Wundef -Werror -pedantic -pedantic-errors -c -std=gnu99 -save-temps -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)" -mmcu=atmega1284p -o"$@" "$<"
@echo Finished building: $<
@@ -138,7 +138,7 @@ all: $(OUTPUT_FILE_PATH) $(ADDITIONAL_DEPENDENCIES)
$(OUTPUT_FILE_PATH): $(OBJS) $(USER_OBJS) $(OUTPUT_FILE_DEP)
@echo Building target: $@
@echo Invoking: AVR/GNU Linker : (AVR_8_bit_GNU_Toolchain_3.4.0_663) 4.6.2
- $(QUOTE)C:\Program Files (x86)\Atmel\Atmel Studio 6.0\extensions\Atmel\AVRGCC\3.4.0.65\AVRToolchain\bin\avr-gcc.exe$(QUOTE) -o$(OUTPUT_FILE_PATH_AS_ARGS) $(OBJS_AS_ARGS) $(USER_OBJS) $(LIBS) -Wl,-Map="P8000_WDC_Emulator.map" -Wl,--start-group -Wl,-lm -Wl,--end-group -mmcu=atmega1284p
+ $(QUOTE)C:\Program Files (x86)\Atmel\Atmel Studio 6.0\extensions\Atmel\AVRGCC\3.4.0.65\AVRToolchain\bin\avr-gcc.exe$(QUOTE) -o$(OUTPUT_FILE_PATH_AS_ARGS) $(OBJS_AS_ARGS) $(USER_OBJS) $(LIBS) -Wl,-Map="P8000_WDC_Emulator.map" -Wl,--start-group -Wl,-lm -Wl,--end-group -Wl,--gc-sections -mrelax -mmcu=atmega1284p
@echo Finished building target: $@
"C:\Program Files (x86)\Atmel\Atmel Studio 6.0\extensions\Atmel\AVRGCC\3.4.0.65\AVRToolchain\bin\avr-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature "P8000_WDC_Emulator.elf" "P8000_WDC_Emulator.hex"
"C:\Program Files (x86)\Atmel\Atmel Studio 6.0\extensions\Atmel\AVRGCC\3.4.0.65\AVRToolchain\bin\avr-objcopy.exe" -j .eeprom --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0 --no-change-warnings -O ihex "P8000_WDC_Emulator.elf" "P8000_WDC_Emulator.eep" || exit 0
diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/P8000_WDC_Emulator.cproj b/P8000_WDC_Emulator/P8000_WDC_Emulator/P8000_WDC_Emulator.cproj
index 9c8ae6d..713de11 100644
--- a/P8000_WDC_Emulator/P8000_WDC_Emulator/P8000_WDC_Emulator.cproj
+++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/P8000_WDC_Emulator.cproj
@@ -51,6 +51,7 @@
True
True
Optimize (-O1)
+ True
True
True
True
@@ -58,11 +59,14 @@
True
True
True
+ True
m
+ True
+ True
@@ -82,6 +86,9 @@
compile
+
+ compile
+
compile
diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_config.h b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_config.h
index e9e234e..d63a7c0 100644
--- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_config.h
+++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_config.h
@@ -1,9 +1,9 @@
/*
* P8000 WDC Emulator
*
- * $Id: wdc_config.h,v 1.4 2012/05/30 20:07:10 olivleh1 Exp $
- *
- */
+ * $Id: wdc_config.h,v 1.5 2012/06/05 18:21:48 olivleh1 Exp $
+ *
+ */
#ifndef CONFIG_H_
@@ -11,6 +11,10 @@
#define F_CPU 18432000UL
+/*
+ * P8000 Interface
+ */
+
#define PORT_DATA PORTA
#define PIN_DATA PINA
#define DDR_DATA DDRA
@@ -28,4 +32,20 @@
#define PIN_INFO_TR PINC6
#define PIN_INFO_RST PINC7
+/*
+ * SD-Card Interface
+ */
+#define PORT_MMC PORTB
+#define PIN_MMC PINB
+#define DDR_MMC DDRB
+
+#define PIN_MMC_CS PINB4 //AVR Port where the MMC Card /CS signal is connected to
+#define PIN_MMC_MOSI PINB5 //AVR Port: MOSI / MMC Card: Data-In
+#define PIN_MMC_MISO PINB6 //AVR Port: MISO / MMC Card: Data-Out
+#define PIN_MMC_SCK PINB7 //AVR Port: SCk / MMC Card: CLK
+
+//maximum performance with both turned off
+//#define MMC_PRESET_MULTIBLOCKCOUNT 1
+//#define SPI_CRC 1
+
#endif /* CONFIG_H_ */
\ No newline at end of file
diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_drv_mmc.c b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_drv_mmc.c
index 0875458..7794785 100644
--- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_drv_mmc.c
+++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_drv_mmc.c
@@ -1,34 +1,43 @@
-/*#######################################################################################
-Connect AVR to MMC/SD
-
-Copyright (C) 2004 Ulrich Radig
-
-Bei Fragen und Verbesserungen wendet euch per EMail an
-
-mail@ulrichradig.de
-
-oder im Forum meiner Web Page : www.ulrichradig.de
-
-Dieses Programm ist freie Software. Sie können es unter den Bedingungen der
-GNU General Public License, wie von der Free Software Foundation veröffentlicht,
-weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder
-(nach Ihrer Option) jeder späteren Version.
-
-Die Veröffentlichung dieses Programms erfolgt in der Hoffnung,
-daß es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE,
-sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT
-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
-Programm erhalten haben.
-Falls nicht, schreiben Sie an die Free Software Foundation,
-Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-#######################################################################################*/
+/*
+ * P8000 WDC Emulator
+ *
+ * $Id: wdc_drv_mmc.c,v 1.4 2012/06/05 18:21:48 olivleh1 Exp $
+ *
+ */
+#include
+#include "config.h"
#include "mmc.h"
+#define wait_till_send_done() while ( ! ( SPSR & ( 1 << SPIF ) ) )
+#define wait_till_card_ready() do { send_dummy_byte(); } while ( !recv_byte() )
+#define send_dummy_byte() SPDR = 0xFF; wait_till_send_done()
+#define recv_byte() SPDR
+#define xmit_byte(x) SPDR = x
+#define MMC_Disable() PORT_MMC|= (1<>= 1 ) {
-
- bit = crc & 0x40;
- crc <<= 1;
- if ( c & i ) crc |= 1;
- if ( bit ) crc ^= CRC7_POLY;
- }
- }
-
- for ( i = 0; i < 7; i++ ) {
-
- if ( crc & 0x40 ) {
- crc = ( crc << 1 ) ^ CRC7_POLY;
- } else
- crc <<= 1;
- }
-
- return ( crc & 0x7F );
+ uint8_t crc = 0x00;
+ while ( len-- )
+ crc = crc7_table[ ( crc << 1 ) ^ *buffer++];
+ return crc;
}
-
-unsigned short CRC_16Bit ( unsigned char *pData, unsigned int uiLen )
+uint16_t crc16 ( const uint8_t *buffer, uint16_t len )
{
- unsigned short usCRC;
-
- //Init CRC register to zero (Required by SD card)
- usCRC = 0x0000;
-
- while ( uiLen-- ) {
- //Do table lookup and xor result
- //see "Painless guide to CRC error detection algorithms" section 10
- usCRC = ( usCRC << 8 ) ^ crc_itu_t_table[ ( usCRC >> 8 ) ^ *pData++];
+ uint16_t crc = 0x0000;
+ while ( len-- ) {
+ crc = ( crc << 8 ) ^ crc16_table[ ( crc >> 8 ) ^ *buffer++];
}
-
- return usCRC;
+ return crc;
}
#endif
-unsigned int SDSetCRC ( unsigned int uiCRC )
+uint8_t SDSetCRC ( uint8_t on_off )
{
- unsigned char ucSDSetCRC[] = {0x3B, 0x00, 0x00, 0x00, 0x00, 0xFF};
+ unsigned char cmd[] = {CMD59, 0x00, 0x00, 0x00, 0x00, 0xFF};
- ucSDSetCRC[0] = 0x3B;
- //tail bit of uiCRC sets or clears CRC mode
- ucSDSetCRC[4] = uiCRC & 0x01;
+ //last bit enables or disables CRC mode
+ cmd[4] = on_off & 0x01;
- if ( mmc_write_command ( ucSDSetCRC ) != 0 ) {
+ if ( mmc_cmd ( cmd ) != 0 ) {
return 1;
}
return 0;
}
-//############################################################################
-//Routine zur Initialisierung der MMC/SD-Karte (SPI-MODE)
uint8_t mmc_init ()
-//############################################################################
{
uint8_t Timeout = 0;
- //Konfiguration des Ports an der die MMC/SD-Karte angeschlossen wurde
- MMC_Direction_REG &= ~ ( 1 << SPI_DI ); //Setzen von Pin MMC_DI auf Input
- 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_Direction_REG |= ( 1 << MMC_Chip_Select ); //Setzen von Pin MMC_Chip_Select auf Output
- MMC_Write |= ( 1 << MMC_Chip_Select ); //Setzt den Pin MMC_Chip_Select auf High Pegel
+
+ DDR_MMC &= ~ ( 1 << PIN_MMC_MISO );
+ DDR_MMC |= ( 1 << PIN_MMC_SCK );
+ DDR_MMC |= ( 1 << PIN_MMC_MOSI );
+ DDR_MMC |= ( 1 << PIN_MMC_CS );
+
+ MMC_Enable();
for ( uint8_t a = 0; a < 200; a++ ) {
nop();
- }; //Wartet eine kurze Zeit
+ };
-#if SPI_Mode
- //Aktiviren des SPI - Bus, Clock = Idel LOW
- //SPI Clock teilen durch 128
SPCR = ( 1 << SPE ) | ( 1 << MSTR ) | ( 1 << SPR0 ) | ( 1 << SPR1 ); //Enable SPI, SPI in Master Mode
SPSR = ( 0 << SPI2X );
-#endif
- //Initialisiere MMC/SD-Karte in den SPI-Mode
- for ( uint8_t b = 0; b < 0x0f; b++ ) { //Sendet min 74+ Clocks an die MMC/SD-Karte
- mmc_write_byte ( 0xff );
+ for ( uint8_t b = 0; b < 0x0f; b++ ) {
+ send_dummy_byte();
}
- //Sendet Commando CMD0 an MMC/SD-Karte
- uint8_t CMD[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x95};
- while ( mmc_write_command ( CMD ) != 1 ) {
+ /*
+ * send CMD0
+ */
+ uint8_t cmd[] = {CMD0, 0x00, 0x00, 0x00, 0x00, 0x95};
+ while ( mmc_cmd ( cmd ) != 1 ) {
if ( Timeout++ > 200 ) {
MMC_Disable();
- return ( 1 ); //Abbruch bei Commando1 (Return Code1)
+ return ( 1 );
}
}
- //Sendet Commando CMD1 an MMC/SD-Karte
+
+ /*
+ * send CMD1
+ */
Timeout = 0;
- CMD[0] = 0x41;//Commando 1
- CMD[5] = 0xFF;
- while ( mmc_write_command ( CMD ) != 0 ) {
+ cmd[0] = CMD1;
+ cmd[5] = 0xFF;
+ while ( mmc_cmd ( cmd ) != 0 ) {
if ( Timeout++ > 400 ) {
MMC_Disable();
- return ( 2 ); //Abbruch bei Commando2 (Return Code2)
+ return ( 2 );
}
}
-#if SPI_Mode
- //SPI Bus auf max Geschwindigkeit
+
+ //SPI Bus to max. speed
SPCR &= ~ ( ( 1 << SPR0 ) | ( 1 << SPR1 ) );
SPSR = SPSR | ( 1 << SPI2X );
-#endif
#ifdef SPI_CRC
SDSetCRC ( 1 );
-#else
- SDSetCRC ( 0 );
#endif
- //set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
MMC_Disable();
return ( 0 );
}
-//############################################################################
-//Sendet ein Commando an die MMC/SD-Karte
-uint8_t mmc_write_command ( uint8_t *cmd )
-//############################################################################
+uint8_t mmc_cmd ( uint8_t *cmd )
{
- uint8_t tmp = 0xff;
- uint8_t Timeout = 0;
+ uint8_t tmp = 0x80;
+ uint8_t i = 10;
+ uint8_t cmd0 = cmd[0];
#ifdef SPI_CRC
- unsigned char ucCRC;
-
//Calculate CRC and framing bits
- cmd [0] = ( cmd[0] | ( 1 << 6 ) ) & 0x7F;
- ucCRC = CRC_7Bit ( cmd, 5 ) << 1;
- cmd[5] = ucCRC;
+ cmd[0] = ( cmd[0] | ( 1 << 6 ) ) & 0x7F;
+ cmd[5] = crc7 ( cmd, 5 ) << 1;
#endif
- //set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
- MMC_Disable();
- //sendet 8 Clock Impulse
- mmc_write_byte ( 0xFF );
-
- //set MMC_Chip_Select to low (MMC/SD-Karte Aktiv)
- MMC_Enable();
-
- //sendet 6 Byte Commando
- for ( uint8_t a = 0; a < 0x06; a++ ) { //sendet 6 Byte Commando zur MMC/SD-Karte
- mmc_write_byte ( *cmd++ );
+ // send command
+ for ( uint8_t a = 0; a < 0x06; a++ ) {
+ xmit_byte ( *cmd++ );
+ wait_till_send_done();
}
- //Wartet auf ein gültige Antwort von der MMC/SD-Karte
- while ( tmp == 0xff ) {
- tmp = mmc_read_byte();
- if ( Timeout++ > 500 ) {
- break; //Abbruch da die MMC/SD-Karte nicht Antwortet
- }
- }
+ if ( cmd0 == ( CMD12 ) ) recv_byte();
+
+ do {
+ send_dummy_byte();
+ tmp = recv_byte();
+ } while ( ( tmp & 0x80 ) && --i );
return ( tmp );
}
-//############################################################################
-//Routine zum Empfangen eines Bytes von der MMC-Karte
-uint8_t mmc_read_byte ( void )
-//############################################################################
-{
- uint8_t Byte = 0;
-#if SPI_Mode //Routine für Hardware SPI
- SPDR = 0xff;
- while ( ! ( SPSR & ( 1 << SPIF ) ) ) {};
- Byte = SPDR;
-
-#else //Routine für Software SPI
- for ( uint8_t a = 8; a > 0; a-- ) { //das Byte wird Bitweise nacheinander Empangen MSB First
- MMC_Write &= ~ ( 1 << SPI_Clock ); //erzeugt ein Clock Impuls (Low)
-
- if ( bit_is_set ( MMC_Read, SPI_DI ) > 0 ) { //Lesen des Pegels von MMC_DI
- Byte |= ( 1 << ( a - 1 ) );
- } else {
- Byte &= ~ ( 1 << ( a - 1 ) );
- }
- MMC_Write |= ( 1 << SPI_Clock ); //setzt Clock Impuls wieder auf (High)
- }
-#endif
- return ( Byte );
-}
-
-
-//############################################################################
-//Routine zum Senden eines Bytes zur MMC-Karte
-void mmc_write_byte ( uint8_t Byte )
-//############################################################################
-{
-#if SPI_Mode //Routine für Hardware SPI
-
- SPDR = Byte; //Sendet ein Byte
-
- while ( ! ( SPSR & ( 1 << SPIF ) ) ) { //Wartet bis Byte gesendet wurde
- }
-
-#else //Routine für Software SPI
- for ( uint8_t a = 8; a > 0; a-- ) { //das Byte wird Bitweise nacheinander Gesendet MSB First
- if ( bit_is_set ( Byte, ( a - 1 ) ) > 0 ) { //Ist Bit a in Byte gesetzt
- MMC_Write |= ( 1 << SPI_DO ); //Set Output High
- } else {
- MMC_Write &= ~ ( 1 << SPI_DO ); //Set Output Low
- }
- MMC_Write &= ~ ( 1 << SPI_Clock ); //erzeugt ein Clock Impuls (LOW)
-
- MMC_Write |= ( 1 << SPI_Clock ); //setzt Clock Impuls wieder auf (High)
- }
- MMC_Write |= ( 1 << SPI_DO ); //setzt Output wieder auf High
-#endif
-}
-
-//############################################################################
-//Routine zum schreiben eines Blocks(512Byte) auf die MMC/SD-Karte
uint8_t mmc_write_sector ( uint32_t addr, uint8_t *Buffer )
-//############################################################################
{
uint8_t tmp;
- //Commando 24 zum schreiben eines Blocks auf die MMC/SD - Karte
- uint8_t cmd[] = {0x58, 0x00, 0x00, 0x00, 0x00, 0xFF};
+ uint8_t cmd[] = {CMD24, 0x00, 0x00, 0x00, 0x00, 0xFF};
#ifdef SPI_CRC
- unsigned int uiCheckSum;
+ uint16_t crc;
+ uint8_t crcl, crch;
#endif
- /*Die Adressierung der MMC/SD-Karte wird in Bytes angegeben,
- addr wird von Blocks zu Bytes umgerechnet danach werden
- diese in das Commando eingefügt*/
+
+ MMC_Enable();
+
+ // convert blocks to bytes
addr = addr << 9; //addr = addr * 512
cmd[1] = ( ( addr & 0xFF000000 ) >> 24 );
cmd[2] = ( ( addr & 0x00FF0000 ) >> 16 );
cmd[3] = ( ( addr & 0x0000FF00 ) >> 8 );
- //Sendet Commando cmd24 an MMC/SD-Karte (Write 1 Block/512 Bytes)
- tmp = mmc_write_command ( cmd );
+ /*
+ * send CMD24
+ */
+ tmp = mmc_cmd ( cmd );
if ( tmp != 0 ) {
+ MMC_Disable();
return ( tmp );
}
- SPDR = 0xFE; //Sendet Startbyte
+ //send Startbyte
+ xmit_byte ( SB_START );
#ifdef SPI_CRC
- uiCheckSum = CRC_16Bit ( Buffer, 512 );
+ crc = crc16 ( Buffer, 512 );
+ crch = crc >> 8;
+ crcl = crc & 0xff;
#endif
- //Schreiben des Bolcks (512Bytes) auf MMC/SD-Karte
+ //write a single block
for ( uint16_t a = 0; a < 512; a++ ) {
uint8_t data = *Buffer;
Buffer++;
- while ( ! ( SPSR & ( 1 << SPIF ) ) );
- SPDR = data; //Sendet ein Byte
+ wait_till_send_done();
+ xmit_byte ( data );
}
- while ( ! ( SPSR & ( 1 << SPIF ) ) );
+ wait_till_send_done();
- //CRC-Byte schreiben
+ //handle CRC
#ifdef SPI_CRC
- SPDR = uiCheckSum >> 8;
- while ( ! ( SPSR & ( 1 << SPIF ) ) );
- SPDR = uiCheckSum & 0xFF;
+ xmit_byte ( crch );
+ wait_till_send_done();
+ xmit_byte ( crcl );
+ wait_till_send_done();
#else
- SPDR = 0xFF;
- while ( ! ( SPSR & ( 1 << SPIF ) ) );
- SPDR = 0xFF;
+ send_dummy_byte();
+ send_dummy_byte();
#endif
- while ( ! ( SPSR & ( 1 << SPIF ) ) );
- //Fehler beim schreiben? (Data Response XXX00101 = OK)
- SPDR = 0xff;
- while ( ! ( SPSR & ( 1 << SPIF ) ) ) {};
- if ( ( SPDR & 0x1F ) != 0x05 ) return ( 0x02 );
-
- //Wartet auf MMC/SD-Karte Bussy
- while ( 1 ) {
- SPDR = 0xff;
- while ( ! ( SPSR & ( 1 << SPIF ) ) ) {};
- if ( SPDR == 0xff )
- break;
+ //check for errors
+ send_dummy_byte();
+ if ( ( recv_byte() & 0x1F ) != 0x05 ) {
+ MMC_Disable();
+ return ( 2 );
}
- //set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
+ wait_till_card_ready();
+
MMC_Disable();
return ( 0 );
}
-//############################################################################
-//Routine zum lesen des CID Registers von der MMC/SD-Karte (16Bytes)
uint8_t mmc_read_block ( uint8_t *cmd, uint8_t *Buffer, uint16_t Bytes )
-//############################################################################
{
#ifdef SPI_CRC
uint16_t crc;
#endif
- //Sendet Commando cmd an MMC/SD-Karte
- if ( mmc_write_command ( cmd ) != 0 ) {
+
+ MMC_Enable();
+
+ //send command
+ if ( mmc_cmd ( cmd ) != 0 ) {
+ MMC_Disable();
return ( 1 );
}
- //Wartet auf Start Byte von der MMC/SD-Karte (FEh/Start Byte)
+ //wait for startbyte
while ( 1 ) {
- SPDR = 0xff;
- while ( ! ( SPSR & ( 1 << SPIF ) ) ) {};
- if ( SPDR == 0xfe )
+ send_dummy_byte();
+ if ( recv_byte() == SB_START )
break;
}
- SPDR = 0xff;
- while ( ! ( SPSR & ( 1 << SPIF ) ) );
- *Buffer = SPDR;
+ //read first byte
+ send_dummy_byte();
+ *Buffer = recv_byte();
- //Lesen des Bolcks (normal 512Bytes) von MMC/SD-Karte
+ //read the remaining 511 bytes
for ( uint16_t a = 0; a < Bytes - 1; a++ ) {
- SPDR = 0xff;
+ xmit_byte ( 0xff ); // send dummy byte
Buffer++;
- while ( ! ( SPSR & ( 1 << SPIF ) ) );
- *Buffer = SPDR;
+ wait_till_send_done();
+ *Buffer = recv_byte();
}
Buffer = Buffer - ( Bytes - 1 );
- //CRC-Byte auslesen
+ //handle CRC
#ifdef SPI_CRC
- SPDR = 0xff;
- while ( ! ( SPSR & ( 1 << SPIF ) ) );
- crc = SPDR << 8;
- SPDR = 0xff;
- while ( ! ( SPSR & ( 1 << SPIF ) ) );
- crc |= SPDR;
+ send_dummy_byte();
+ crc = recv_byte() << 8;
+ send_dummy_byte();
+ crc |= recv_byte();
- if ( crc != CRC_16Bit ( Buffer, Bytes ) ) {
+ if ( crc != crc16 ( Buffer, Bytes ) ) {
MMC_Disable();
return ( 1 );
}
#else
- SPDR = 0xff;
- while ( ! ( SPSR & ( 1 << SPIF ) ) );
- SPDR;
- SPDR = 0xff;
- while ( ! ( SPSR & ( 1 << SPIF ) ) );
- SPDR;
+ send_dummy_byte();
+ send_dummy_byte();
#endif
-
- //set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
MMC_Disable();
return ( 0 );
}
-//############################################################################
-//Routine zum lesen eines Blocks(512Byte) von der MMC/SD-Karte
uint8_t mmc_read_sector ( uint32_t addr, uint8_t *Buffer )
-//############################################################################
{
- //Commando 16 zum lesen eines Blocks von der MMC/SD - Karte
- uint8_t 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ügt*/
+ /*
+ * send CMD17
+ */
+ uint8_t cmd[] = {CMD17, 0x00, 0x00, 0x00, 0x00, 0xFF};
+ // convert blocks to bytes
addr = addr << 9; //addr = addr * 512
-
cmd[1] = ( ( addr & 0xFF000000 ) >> 24 );
cmd[2] = ( ( addr & 0x00FF0000 ) >> 16 );
cmd[3] = ( ( addr & 0x0000FF00 ) >> 8 );
@@ -442,24 +367,221 @@ uint8_t mmc_read_sector ( uint32_t addr, uint8_t *Buffer )
}
-//############################################################################
-//Routine zum lesen des CID Registers von der MMC/SD-Karte (16Bytes)
-uint8_t mmc_read_cid ( uint8_t *Buffer )
-//############################################################################
+uint8_t mmc_read_multiblock ( uint32_t addr, uint8_t *Buffer, uint8_t numblocks )
{
- //Commando zum lesen des CID Registers
- uint8_t cmd[] = {0x4A, 0x00, 0x00, 0x00, 0x00, 0xFF};
+ uint8_t resp;
+ uint8_t cmd[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF };
+#ifdef SPI_CRC
+ uint16_t crc;
+#endif
- return mmc_read_block ( cmd, Buffer, 16 );
+ MMC_Enable();
+
+#ifdef MMC_PRESET_MULTIBLOCKCOUNT
+ wait_till_card_ready();
+
+ /*
+ * send CMD55
+ */
+ cmd[0] = CMD55;
+ mmc_cmd ( cmd );
+
+ /*
+ * send CMD23
+ */
+ cmd[0] = CMD23;
+ cmd[4] = numblocks;
+ mmc_cmd ( cmd );
+
+ wait_till_card_ready();
+#endif
+
+ // convert blocks to bytes
+ addr = addr << 9; //addr = addr * 512
+ cmd[0] = CMD18;
+ cmd[1] = ( ( addr & 0xFF000000 ) >> 24 );
+ cmd[2] = ( ( addr & 0x00FF0000 ) >> 16 );
+ cmd[3] = ( ( addr & 0x0000FF00 ) >> 8 );
+ cmd[4] = ( addr & 0x000000FF );
+
+ wait_till_card_ready();
+
+ /*
+ * send CMD18
+ */
+ resp = mmc_cmd ( cmd );
+ if ( resp > 1 ) {
+ MMC_Disable();
+ return ( 1 );
+ }
+
+ for ( uint8_t n = numblocks; n > 0; n-- ) {
+ // wait for startbyte
+ while ( 1 ) {
+ send_dummy_byte();
+ if ( recv_byte() == SB_START )
+ break;
+ }
+
+ send_dummy_byte();
+ *Buffer = recv_byte();
+ // receive the block
+ for ( uint16_t a = 0; a < 512 - 1; a++ ) {
+ xmit_byte ( 0xff );
+ Buffer++;
+ wait_till_send_done();
+ *Buffer = recv_byte();
+ }
+ // handle CRC
+#ifdef SPI_CRC
+ Buffer = Buffer - ( 512 - 1 );
+ send_dummy_byte();
+ crc = recv_byte() << 8;
+ send_dummy_byte();
+ crc |= recv_byte();
+ if ( crc != crc16 ( Buffer, 512 ) ) {
+ MMC_Disable();
+ return ( 1 );
+ }
+ Buffer = Buffer + 512;
+#else
+ send_dummy_byte();
+ send_dummy_byte();
+ Buffer++;
+#endif
+
+ }
+
+ wait_till_card_ready();
+
+ /*
+ * send CMD12
+ */
+ cmd[0] = CMD12;
+ cmd[1] = cmd[2] = cmd[3] = cmd[4] = 0;
+
+ resp = mmc_cmd ( cmd );
+
+/* TODO: Apacer Card I have sends 0x7f after some reads - No idea why - CRC was correct
+ if ( resp > 1 ) {
+ MMC_Disable();
+ return ( 2 );
+ }
+*/
+ // Pad 8
+ send_dummy_byte();
+
+ MMC_Disable()
+
+ return ( 0 );
}
-//############################################################################
-//Routine zum lesen des CSD Registers von der MMC/SD-Karte (16Bytes)
-uint8_t mmc_read_csd ( uint8_t *Buffer )
-//############################################################################
+uint8_t mmc_write_multiblock ( uint32_t addr, uint8_t *Buffer, uint8_t numblocks )
{
- //Commando zum lesen des CSD Registers
- uint8_t cmd[] = {0x49, 0x00, 0x00, 0x00, 0x00, 0xFF};
+ uint8_t resp;
+ uint8_t cmd[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF };
+#ifdef SPI_CRC
+ uint16_t crc;
+ uint8_t crcl, crch;
+#endif
- return mmc_read_block ( cmd, Buffer, 16 );
+ MMC_Enable();
+
+#ifdef MMC_PRESET_MULTIBLOCKCOUNT
+ wait_till_card_ready();
+
+ /*
+ * send CMD55
+ */
+ cmd[0] = CMD55;
+ mmc_cmd ( cmd );
+
+ /*
+ * send CMD23
+ */
+ cmd[0] = CMD23;
+ cmd[4] = numblocks;
+ mmc_cmd ( cmd );
+
+ wait_till_card_ready();
+#endif
+
+ // convert blocks to bytes
+ addr = addr << 9;
+ cmd[0] = CMD25;
+ cmd[1] = ( ( addr & 0xFF000000 ) >> 24 );
+ cmd[2] = ( ( addr & 0x00FF0000 ) >> 16 );
+ cmd[3] = ( ( addr & 0x0000FF00 ) >> 8 );
+ cmd[4] = 0;
+
+ /*
+ * send CMD25
+ */
+ resp = mmc_cmd ( cmd );
+ if ( resp > 1 ) {
+ MMC_Disable();
+ return ( 1 );
+ }
+
+ for ( uint8_t n = numblocks; n > 0; n-- ) {
+#ifdef SPI_CRC
+ crc = crc16 ( Buffer, 512 );
+ crch = crc >> 8;
+ crcl = crc & 0xff;
+#endif
+ wait_till_card_ready();
+
+ // Send multi-block start-token
+ xmit_byte ( MB_START );
+
+ //actually transfer the data
+ for ( uint16_t i = 512; i; i-- ) {
+ uint8_t data = *Buffer;
+ Buffer++;
+ wait_till_send_done();
+ xmit_byte ( data );
+ }
+
+ wait_till_send_done();
+ // handle CRC
+#ifdef SPI_CRC
+ xmit_byte ( crch );
+ wait_till_send_done();
+ xmit_byte ( crcl );
+#else
+ xmit_byte ( 0xff );
+ wait_till_send_done();
+ xmit_byte ( 0xff );
+#endif
+
+#ifdef MMC_PRESET_MULTIBLOCKCOUNT
+ // Pad 8
+ send_dummy_byte();
+#else
+ wait_till_send_done();
+#endif
+
+ // Get response
+ send_dummy_byte();
+ resp = recv_byte();
+ if ( ( resp & 0x0E ) != 4 ) {
+ MMC_Disable();
+ return ( 2 );
+ }
+ }
+
+ wait_till_card_ready();
+
+ // Send "transfer stop byte"
+ xmit_byte ( MB_STOP );
+ wait_till_send_done();
+
+ // Pad 8
+ send_dummy_byte();
+
+ wait_till_card_ready();
+
+ MMC_Disable();
+
+ return ( 0 );
}
diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_drv_mmc.h b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_drv_mmc.h
index 6236d42..659b3f6 100644
--- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_drv_mmc.h
+++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_drv_mmc.h
@@ -1,50 +1,23 @@
-/*#######################################################################################
-Connect ARM to MMC/SD
+/*
+ * P8000 WDC Emulator
+ *
+ * $Id: wdc_drv_mmc.h,v 1.3 2012/06/05 18:21:48 olivleh1 Exp $
+ *
+ */
-Copyright (C) 2004 Ulrich Radig
-#######################################################################################*/
+#ifndef MMC_H_
+#define MMC_H_
-#ifndef _MMC_H_
-#define _MMC_H_
+extern uint8_t mmc_init ();
-#include
+extern uint8_t mmc_read_sector ( uint32_t addr, uint8_t *Buffer );
+extern uint8_t mmc_write_sector ( uint32_t addr, uint8_t *Buffer );
-#define SPI_Mode 1 //1 = Hardware SPI | 0 = Software SPI
-//#define SPI_Mode 0
-
-#define SPI_CRC 1
-
-#define MMC_Write PORTB //Port an der die MMC/SD-Karte angeschlossen ist also des SPI
-#define MMC_Read PINB
-#define MMC_Direction_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 SPI_Clock 7 //Port Pin an dem die Clock der MMC/SD-Karte angeschlossen ist (clk)
-#define MMC_Chip_Select 4 //Port Pin an dem Chip Select der MMC/SD-Karte angeschlossen ist
-
-//Prototypes
-
-extern uint8_t mmc_read_byte ( void );
-extern void mmc_write_byte ( uint8_t );
-extern uint8_t mmc_read_block ( uint8_t *, uint8_t *, uint16_t );
-
-extern uint8_t mmc_init ( void );
-extern uint8_t mmc_read_sector ( uint32_t, uint8_t * );
-extern uint8_t mmc_write_sector ( uint32_t, uint8_t * );
-
-extern uint8_t mmc_write_command ( uint8_t * );
-extern uint8_t mmc_read_csd ( uint8_t * );
-extern uint8_t mmc_read_cid ( uint8_t * );
-
-//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
-#define MMC_Disable() MMC_Write|= (1<
#include "mmc.h"
#include "uart.h"
extern uint8_t par_table[200];
@@ -36,14 +37,14 @@ uint32_t wdc_p8kblock2sdblock ( uint32_t blockno )
return ( blockno + ( par_table[25] * par_table[26] ) );
}
-uint8_t wdc_write_sector ( uint16_t addr, uint8_t *sector )
+uint8_t wdc_write_sector ( uint32_t addr, uint8_t *sector )
{
uint8_t errorcode;
errorcode = mmc_write_sector ( addr, sector );
if ( errorcode ) {
uart_puts_p ( PSTR ( " write error at address: " ) );
- uart_putw_dec ( addr );
+ uart_putdw_dec ( addr );
uart_puts_p ( PSTR ( " / errorcode is: " ) );
uart_putc_hex ( errorcode );
uart_putc ( '\n' );
@@ -52,18 +53,51 @@ uint8_t wdc_write_sector ( uint16_t addr, uint8_t *sector )
return 0;
}
-uint8_t wdc_read_sector ( uint16_t addr, uint8_t *sector )
+uint8_t wdc_read_sector ( uint32_t addr, uint8_t *sector )
{
uint8_t errorcode;
errorcode = mmc_read_sector ( addr, sector );
if ( errorcode ) {
uart_puts_p ( PSTR ( " read error at address: " ) );
- uart_putw_dec ( addr );
+ uart_putdw_dec ( addr );
uart_puts_p ( PSTR ( " / errorcode is: " ) );
uart_putc_hex ( errorcode );
uart_putc ( '\n' );
return errorcode;
} else
return 0;
+}
+
+uint8_t wdc_read_multiblock ( uint32_t addr, uint8_t *sector, uint8_t numblocks )
+{
+ uint8_t errorcode;
+
+ errorcode = mmc_read_multiblock ( addr, sector, numblocks );
+ if ( errorcode ) {
+ uart_puts_p ( PSTR ( " read error at address: " ) );
+ uart_putdw_dec ( addr );
+ uart_puts_p ( PSTR ( " / errorcode is: " ) );
+ uart_putc_hex ( errorcode );
+ uart_putc ( '\n' );
+ return errorcode;
+ } else
+ return 0;
+}
+
+uint8_t wdc_write_multiblock ( uint32_t addr, uint8_t *sector, uint8_t numblocks )
+{
+ uint8_t errorcode;
+
+ errorcode = mmc_write_multiblock ( addr, sector, numblocks );
+// errorcode = mmc_write_multiblock_predef ( addr, sector, numblocks );
+ if ( errorcode ) {
+ uart_puts_p ( PSTR ( " write error at address: " ) );
+ uart_putdw_dec ( addr );
+ uart_puts_p ( PSTR ( " / errorcode is: " ) );
+ uart_putc_hex ( errorcode );
+ uart_putc ( '\n' );
+ return errorcode;
+ } else
+ return 0;
}
\ No newline at end of file
diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_disk.h b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_disk.h
index 1873acd..4f9311c 100644
--- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_disk.h
+++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_disk.h
@@ -1,17 +1,18 @@
/*
* P8000 WDC Emulator
*
- * $Id: wdc_if_disk.h,v 1.3 2012/06/02 23:04:30 olivleh1 Exp $
+ * $Id: wdc_if_disk.h,v 1.4 2012/06/05 18:21:48 olivleh1 Exp $
*
*/
#ifndef WDC_IF_SDCARD_H_
#define WDC_IF_SDCARD_H_
-uint8_t wdc_init_sdcard();
-uint32_t wdc_sector2sdblock ( uint16_t req_cylinder, uint8_t req_head, uint8_t req_sector );
-uint32_t wdc_p8kblock2sdblock ( uint32_t blockno );
-uint8_t wdc_write_sector ( uint16_t addr, uint8_t *sector );
-uint8_t wdc_read_sector ( uint16_t addr, uint8_t *sector );
-
+extern uint8_t wdc_init_sdcard();
+extern uint32_t wdc_sector2sdblock ( uint16_t req_cylinder, uint8_t req_head, uint8_t req_sector );
+extern uint32_t wdc_p8kblock2sdblock ( uint32_t blockno );
+extern uint8_t wdc_write_sector ( uint32_t addr, uint8_t *sector );
+extern uint8_t wdc_read_sector ( uint32_t addr, uint8_t *sector );
+extern uint8_t wdc_read_multiblock ( uint32_t addr, uint8_t *sector, uint8_t numblocks );
+extern uint8_t wdc_write_multiblock ( uint32_t addr, uint8_t *sector, uint8_t numblocks );
#endif /* WDC_IF_SDCARD_H_ */
\ No newline at end of file
diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_p8000.h b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_p8000.h
index 9777ece..c8fb8bf 100644
--- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_p8000.h
+++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_p8000.h
@@ -1,7 +1,7 @@
/*
* P8000 WDC Emulator
*
- * $Id: wdc_if_p8000.h,v 1.4 2012/06/03 13:38:03 olivleh1 Exp $
+ * $Id: wdc_if_p8000.h,v 1.5 2012/06/05 18:21:48 olivleh1 Exp $
*
*/
@@ -43,11 +43,11 @@
#define INFO_STAT_ERROR ((1 << PIN_INFO_STATUS0) | (1 << PIN_INFO_STATUS1) | (1 << PIN_INFO_STATUS2)) /* 0x07 */
#define INFO_TR (1 << PIN_INFO_TR) /* 0x40 */
-void wdc_init_ports();
-void wdc_wait_for_reset();
-void wdc_receive_cmd ( uint8_t *buffer, uint16_t count );
-void wdc_receive_data ( uint8_t *buffer, uint16_t count );
-void wdc_send_data ( uint8_t *buffer, uint16_t count );
-void wdc_send_error();
+extern void wdc_init_ports();
+extern void wdc_wait_for_reset();
+extern void wdc_receive_cmd ( uint8_t *buffer, uint16_t count );
+extern void wdc_receive_data ( uint8_t *buffer, uint16_t count );
+extern void wdc_send_data ( uint8_t *buffer, uint16_t count );
+extern void wdc_send_error();
#endif /* WDC_IF_PIO_H_ */
\ No newline at end of file
diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.c b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.c
index b3d7748..854e1f3 100644
--- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.c
+++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.c
@@ -1,7 +1,7 @@
/*
* P8000 WDC Emulator
*
- * $Id: wdc_main.c,v 1.9 2012/06/03 13:51:43 olivleh1 Exp $
+ * $Id: wdc_main.c,v 1.10 2012/06/05 18:21:48 olivleh1 Exp $
*
* TODO: - Different Errorcodes in the MMC layer (use defines)
* - errorchecking in several places
@@ -44,6 +44,7 @@ ISR ( TIMER0_OVF_vect )
int __attribute__ ( ( OS_main ) )
main ( void )
{
+#ifndef MEASURE_SDCARD_TIME
uint16_t cmd_counter = 9;
uint16_t data_counter;
uint32_t blockno;
@@ -52,14 +53,14 @@ main ( void )
uint8_t cmd_buffer[9];
uint8_t i8;
uint16_t i16;
-
+#endif
atmega_setup();
uart_puts_p ( PSTR ( "P8000 WDC Emulator 0.01\n" ) );
#ifdef MEASURE_SDCARD_TIME
measure_performance();
-#endif
+#else
/* load Parameter Table into RAM if valid */
blockno = 0;
@@ -84,9 +85,12 @@ main ( void )
, cmd_counter
);
-#if DEBUG == 2
+#if DEBUG >= 2
+#if DEBUG >= 3
uart_puts_p ( PSTR ( " CMD:" ) );
+#endif
uart_putc_hex ( cmd_buffer[0] );
+#if DEBUG >= 3
uart_putc_hex ( cmd_buffer[1] );
uart_putc_hex ( cmd_buffer[2] );
uart_putc_hex ( cmd_buffer[3] );
@@ -96,6 +100,7 @@ main ( void )
uart_putc_hex ( cmd_buffer[7] );
uart_putc_hex ( cmd_buffer[8] );
uart_putc ( '\n' );
+#endif
#endif
switch ( cmd_buffer[0] ) {
@@ -107,11 +112,19 @@ main ( void )
, data_counter
);
errorcode = 1;
+ if(data_counter/512 == 1) {
+ errorcode = wdc_write_sector ( blockno, data_buffer);
+ } else {
+ uart_putc('#');
+ errorcode = wdc_write_multiblock( blockno, data_buffer, data_counter/512);
+ }
+/* check if this really works - this must be used if the card does not support multiblock-access (there are some)
for ( i16 = 0; i16 < data_counter; i16 += 512 ) {
errorcode = wdc_write_sector ( blockno, &data_buffer[i16] );
if ( errorcode ) break;
blockno++;
}
+*/
if ( errorcode )
wdc_send_error();
break;
@@ -120,12 +133,21 @@ main ( void )
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
blockno = wdc_p8kblock2sdblock ( ( ( uint32_t ) cmd_buffer[5] << 24 ) | ( ( uint32_t ) cmd_buffer[4] << 16 ) | ( ( uint16_t ) cmd_buffer[3] << 8 ) | cmd_buffer[2] );
+
errorcode = 1;
+ if(data_counter/512 == 1) {
+ errorcode = wdc_read_sector ( blockno, data_buffer);
+ } else {
+ uart_putc('#');
+ errorcode = wdc_read_multiblock( blockno, data_buffer, data_counter/512);
+ }
+/* check if this really works - this must be used if the card does not support multiblock-access (there are some)
for ( i16 = 0; i16 < data_counter; i16 += 512 ) {
errorcode = wdc_read_sector ( blockno, &data_buffer[i16] );
if ( errorcode ) break;
blockno++;
}
+*/
if ( errorcode )
wdc_send_error();
wdc_send_data ( data_buffer
@@ -311,7 +333,7 @@ main ( void )
break;
}
}
-
+#endif
return 0;
}
@@ -332,38 +354,85 @@ void atmega_setup ( void )
void measure_performance()
{
uint32_t starttime;
- uint8_t *data_buffer;
- uint32_t blockno;
+ uint8_t data_buffer[4096];
+ uint32_t blockno=0;
+ uint8_t numblocks=4;
+ uint8_t i8, errorcode;
+ uint8_t nr_of_tests=5;
+#define BLOCKNO 300000
sei();
TIMSK0 |= ( 0x01 << TOIE0 );
TCCR0B = ( 1 << CS01 ); // Prescaler 8
TCNT0 = 0x00;
- uart_putdw_dec ( overflow );
- data_buffer = malloc ( 512 * sizeof ( *data_buffer ) );
- uart_putc ( 'w' );
- uart_putc ( '\n' );
- for ( i8 = 0; i8 < 5; i8++ ) {
- for ( blockno = 200000, starttime = overflow; blockno < 205000; blockno++ ) {
- errorcode = wdc_write_sector ( blockno, data_buffer );
+ uart_puts_p ( PSTR ( "Performance Measurement. Displayed are the Timer-Overflows." ) );uart_putc ( '\n' );
+ uart_puts_p ( PSTR ( "Timer is initialized with a Prescaler 8" ) );uart_putc ( '\n' );
+
+ uart_puts_p ( PSTR ( "Test Read 5000 512B-Blocks with Multiblock-Read (4KB Blocksize):" ) );uart_putc ( '\n' );
+
+ for ( i8 = 0; i8 < nr_of_tests; i8++ ) {
+ blockno=BLOCKNO;
+ for ( starttime = overflow; blockno < (BLOCKNO+5000); blockno+=numblocks ) {
+ errorcode = wdc_read_multiblock ( blockno, data_buffer,numblocks );
+ if(errorcode) {
+ break;
+ }
}
+ if(errorcode)
+ break;
uart_putdw_dec ( overflow - starttime );
uart_putc ( '\n' );
}
- uart_putc ( '\n' );
- uart_putc ( 'r' );
- uart_putc ( '\n' );
- for ( i8 = 0; i8 < 5; i8++ ) {
- for ( blockno = 200000, starttime = overflow; blockno < 205000; blockno++ ) {
+ uart_puts_p ( PSTR ( "Test Write 5000 512B-Blocks with Multiblock-Write (4KB Blocksize):" ) );uart_putc ( '\n' );
+ memset ( &data_buffer[0], 0xCC, 512*numblocks );
+ for ( i8 = 0; i8 < nr_of_tests; i8++ ) {
+ blockno=BLOCKNO;
+ for ( starttime = overflow; blockno < (BLOCKNO+5000); blockno+=numblocks ) {
+ errorcode = wdc_write_multiblock ( blockno, data_buffer,numblocks );
+ if(errorcode) {
+ break;
+ }
+ }
+ if(errorcode)
+ break;
+ uart_putdw_dec ( overflow - starttime );
+ uart_putc ( '\n' );
+ }
+
+ uart_puts_p ( PSTR ( "Test Read 5000 512B-Blocks with Singleblock-Read (512B Blocksize):" ) );uart_putc ( '\n' );
+
+ for ( i8 = 0; i8 < nr_of_tests; i8++ ) {
+ blockno=BLOCKNO;
+ for ( starttime = overflow; blockno < (BLOCKNO+5000); blockno++ ) {
errorcode = wdc_read_sector ( blockno, data_buffer );
+ if(errorcode) {
+ break;
+ }
}
+ if(errorcode)
+ break;
uart_putdw_dec ( overflow - starttime );
uart_putc ( '\n' );
}
- uart_putc ( '\n' );
- free ( data_buffer );
+ uart_puts_p ( PSTR ( "Test Write 5000 512B-Blocks with Singleblock-Write (512B Blocksize):" ) );uart_putc ( '\n' );
+ memset ( &data_buffer[0], 0xCC, 512*numblocks );
+ for ( i8 = 0; i8 < nr_of_tests; i8++ ) {
+ blockno=BLOCKNO;
+ for ( starttime = overflow; blockno < (BLOCKNO+5000); blockno++ ) {
+ errorcode = wdc_write_sector ( blockno, data_buffer );
+ if(errorcode) {
+ break;
+ }
+ }
+ if(errorcode)
+ break;
+ uart_putdw_dec ( overflow - starttime );
+ uart_putc ( '\n' );
+ }
+
+ while(1);
}
#endif
\ No newline at end of file