From 22fbb4f11cf7133db0a427afbb3460a2737fc0c1 Mon Sep 17 00:00:00 2001 From: Oliver Lehmann Date: Tue, 5 Jun 2012 18:21:48 +0000 Subject: [PATCH] complete overhaul and reimplementation of the MMC Code Implement Checksumming Implement Multiblock-Operation Also increase performance by reducing function calls for SPI handling --- P8000_WDC_Emulator/P8000_WDC_Emulator.atsuo | Bin 27648 -> 34304 bytes .../P8000_WDC_Emulator/Debug/Makefile | 4 +- .../P8000_WDC_Emulator.cproj | 7 + .../P8000_WDC_Emulator/wdc_config.h | 26 +- .../P8000_WDC_Emulator/wdc_drv_mmc.c | 686 +++++++++++------- .../P8000_WDC_Emulator/wdc_drv_mmc.h | 61 +- .../P8000_WDC_Emulator/wdc_if_disk.c | 44 +- .../P8000_WDC_Emulator/wdc_if_disk.h | 15 +- .../P8000_WDC_Emulator/wdc_if_p8000.h | 14 +- .../P8000_WDC_Emulator/wdc_main.c | 111 ++- 10 files changed, 597 insertions(+), 371 deletions(-) diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator.atsuo b/P8000_WDC_Emulator/P8000_WDC_Emulator.atsuo index 53d88090388c1cbfda49a73c0cdd04ff99cfcb3a..e0604323680e7275e89f5cd838504913e81d347d 100755 GIT binary patch delta 2979 zcmai03slqB8NWBCB!mPL(1<+4`yu=jBt!%ZK|qj-;Uyx()`cw<~ zR(Gn_iak?{+NuAuwd?6wQQYdL7HGGg?QA;HQ+u?!;fCuub;7=z2aV^f+x_R4`@R0( z{l0te|9;o`N9x=oICDv`Dw_~8JLhRDkY<#R&qY2Dk&jq~&?5>E21FrZcBtx+OK1z$ zEIK$?Sag*xK-p*!zf-uIF6M)f!Nz&8S?2~8Hc^vOJ`!g+)Kli zfb^yQL$5|f5uzAT0t!(mt${?5I_!YA&cb8Si%%sWRR)t;S+HIk02A>-c#s_htCGSO*ex070*eHJ?pcwb8N_h0pb?6A zN6@$s#zHf}AvXpRF{+aM)G&imin-1$^po-qMI{vnqeST^4cLW@MGD`9lndDcfH6KD z9HB-S6K3)=p;94?MyJG>Z~=PpDJEv(K$yrn(nFd_{WuGYKxx=Y7)`S)jQ9SO`)=iM z)#sPq{?!O+b%cPNTeLt$TH#vo66iGsgLB#UF_a9HVHI+5rkGQ zbA^`)qnJByn&1fc=CQU(NdZM{i*?)3J+CA zu^fG>{6^&+u~GpX6F0zwPU2lDr7K}9kc6U@!q1Xw`G*NXlsO=VqFhsDUr$?~xl85B ziihbA1)r9rq;4mYpQBEXq3DxfOeL^Yq})^uhZsSQ?GXdTCKJgyDDXSjxN9+eUw)V9(H=D9JEvMmh*(USWK1WZFt-0N7 z?KU+bI8JS|HmT7_jXJfK({anyD0KgntYczpceAbE(xSFI`mEh;?qp=Te7LC#0ZaA< zc*_tA)0^ZlU?_C=l@%Iqq6^`cP63U&mC%$Ff?H$4n&_L2aqGcA33*0Jh=_auQ)^a0 zN5?3A9%#;6DevIajUY}U*ul5;vB+vOu?lbP1OYyj3Uk>t{}z`7ZJZk{08wc z;u3%wxrSb(db1m ztQr;D%#NNu6K)k0!(8DTFjbri=T{$My^In{aV*xX2AC)XHUe(KV*f$(aCwbX!oH_S zL@{%{S8lg(>@=NkP+6#jsia6)(-|i9Ka1c9jPW6qzj*B z>@|cVI)oOnlUVWOWG5)IsloHJpIA`VgLXA|qH?4HpCa-s778nA!v5R0O2R+QNf zBWhu)tc9%si%Q{|kBX4vNTl#Jfo>+6$3_Yrv^EJ5~%+t-|9ng0wAZ_nQ>1xaHR+znIGZlH0kOYImliz2ms*!;ss z17EEF%6U_JynQ0t{r0EEbXBmC=en9P_gwtz@7=jS@^VE4Gn8@YM2%qo z)le8yKJWOy+QUs{0(30h53?y^5J$fcmelp&TsI2)l3${=5S#aOkZ(LfqG4d^^Jp0W z4J!`t2BVYGT^M_TtLi+QO)hX%7qMzVe+&K9H9{?$5nnl-sYcs0=&v218St>yC`@Ep ztb|kp{Tph8seZ;Vv*Gu`j3)$j6XG-!r27ej*y6m2zy=SLi=iW535Ro)aDH7@xM!De zI90Z?!#{uewTrUWzb1Wo{QmY^u#j5}N9&_uFsuQB^KQeiEE#*L{B*V`PuV?|fAC`G zflc?jH@QpZ#)hNvx;r^eo3^32v3uu@_S7%!Zbek%QTd5&8IJGY`J3d@VC1w{O9Sh4>WoJyDYVX**N5IeI87LUc|K{tPPSBw(k>@OU0iny$o?YGM-*L1~ zh}n%P=LumOI%0*n?Fxmyf=VdXAELWqYDEkjSywCjHf=(p;F|t3aK^?#+~znjy9oyQ zd6IsG%rJsAS3(>dt*w?$BE8Km@yOz;GI=9>29*BH*1BE($8M${h`hh(RL^{tuy0pThtE delta 2052 zcmZ9N3s6%>6o&7HKtc$bfV@&LAP}B`goKC6BjF|}T8IG!6tq%M(SnFTTa`zwj!Z{X z$mw)!rwl%(jtExdc68d#6p&U>p=fKZTHlYVQ?0ZUrmbzEXOUR!X1?q>|Jl2{_w2pr zS{iwl%cOIF=QuV#KCT7gFy6dUYvq?t+u*X`&My5BabOt6V&pdS>xjp7XLPX9u@o9h z0avG;+Tlqx4Et~-0*OSFNE8x{s1P+0gBTGQbc*z$)9BFABdG|B7?2W>3fxI81Ph{l z>6l#9@(^k-!#;n~h7E!QVX58e6eLP5=(HnsNIkL@{t+|~IouQmK!?H)S^|^0oLQbD ziN_$A0wcL9mtj8i@zqczF*y?<%E2@wj|u=4UjQ~#87EYxPf@ul=^`S;&5V0aQJreg zkvqdPw*^9at1eSwP~~m{R-)!??qWXinJ4TnASJ6;_4J8r0`VBs7j0A<5imkPCsM@!_07;Ypx4EDH=7+rhSA9autl zNFRFj{t=}Jx-#StZ+64mtu)ItO;a1R z#rwffxEORk6%y&TEsxp`U-M00`q!@~ax=`(>obF7k@U1f|X7nf2_NTvJ z!R}10YdvVvo%F?No6X)XObHqUu`saJ+uN$#B+%dRzn3!_2Nq?I>#edll9@EWZaK|m zv)PYZ7gazcfma{rJ-gri=%1X!_928T8sB5gnt zT0_s{@<)*C2;I(6Z0lP4ni${j^B(IrOr-;oLkW#3X+JS%xsMC4WTw=Mjg( zwd=ub2#3#7TruHRc$gMO9N|m$J+xA!Z{a5FEe8z(!>KKJbqchzVv!>%wEP+RaFJc~ zV4W(9iwZXu}53s$m1I34R@&0=ZY zAdjIsE1Mrj=d@P>Tb7038&|!!p5(yjViR9LqqGhzh3X~Qd|J%ygTc1sBA-_H|Ad_L zLR$7|EwYOuD>^L*N*S6IUJ(PYh2^?LF-1%wQ_gH)R>A%}Ig}cLX{rqLQd$BH4a6`< zg}*KOm^5R&)~Hsd#%nc7wc4Ok>Wyl>Ql-+X*x9PIv@}*zTa%cvwz4Q~ZRx7Y%&^}z1Y}Fal05~6v0W|O&7qk?rlx$| zURr%1ci91n-^mNDOB(NL`lEg3nn}B5BH*7cf{^^Z63v+%wa4aEW}6p3$Q*zDNy$X; zZvJh4B)wzI9M}p>jzl@>aaGG3dC;RzTrue 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