OpenCores
URL https://opencores.org/ocsvn/usb_fpga_2_16/usb_fpga_2_16/trunk

Subversion Repositories usb_fpga_2_16

[/] [usb_fpga_2_16/] [trunk/] [include/] [ztex-flash1.h] - Diff between revs 2 and 3

Only display areas with differences | Details | Blame | View Log

Rev 2 Rev 3
/*!
/*!
   ZTEX Firmware Kit for EZ-USB FX2 Microcontrollers
   ZTEX Firmware Kit for EZ-USB FX2 Microcontrollers
   Copyright (C) 2009-2011 ZTEX GmbH.
   Copyright (C) 2009-2014 ZTEX GmbH.
   http://www.ztex.de
   http://www.ztex.de
 
 
   This program is free software; you can redistribute it and/or modify
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 3 as
   it under the terms of the GNU General Public License version 3 as
   published by the Free Software Foundation.
   published by the Free Software Foundation.
 
 
   This program is distributed in the hope that it will be useful, but
   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   General Public License for more details.
   General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program; if not, see http://www.gnu.org/licenses/.
   along with this program; if not, see http://www.gnu.org/licenses/.
!*/
!*/
 
 
/*
/*
    Support for SD cards in SPI mode.
    Support for SD cards in SPI mode.
    This module is not MMC compatible anymore since multi block read/write commands are used.
    This module is not MMC compatible anymore since multi block read/write commands are used.
*/
*/
 
 
#ifeq[MMC_PORT][E]
#ifeq[MMC_PORT][E]
#define[MMC_bmMODE]
#define[MMC_bmMODE]
#elifeq[MMC_PORT][A]
#elifeq[MMC_PORT][A]
#elifeq[MMC_PORT][B]
#elifeq[MMC_PORT][B]
#elifeq[MMC_PORT][C]
#elifeq[MMC_PORT][C]
#elifneq[MMC_PORT][D]
#elifneq[MMC_PORT][D]
#error[Macro `MMC_PORT' is not defined correctly. Valid values are: `A', `B', `C', `D' and `E'.]
#error[Macro `MMC_PORT' is not defined correctly. Valid values are: `A', `B', `C', `D' and `E'.]
#endif
#endif
 
 
#ifndef[ZTEX_FLASH1_H]
#ifndef[ZTEX_FLASH1_H]
#define[ZTEX_FLASH1_H]
#define[ZTEX_FLASH1_H]
 
 
#define[@CAPABILITY_FLASH;]
#define[@CAPABILITY_FLASH;]
 
 
#ifndef[MMC_PORT]
#ifndef[MMC_PORT]
#error[MMC_PORT not defined]
#error[MMC_PORT not defined]
#endif
#endif
 
 
#ifndef[MMC_BIT_CS]
#ifndef[MMC_BIT_CS]
#error[MMC_BIT_CS not defined]
#error[MMC_BIT_CS not defined]
#endif
#endif
 
 
#ifndef[MMC_BIT_DI]
#ifndef[MMC_BIT_DI]
#error[MMC_BIT_DI not defined]
#error[MMC_BIT_DI not defined]
#endif
#endif
 
 
#ifndef[MMC_BIT_DO]
#ifndef[MMC_BIT_DO]
#error[MMC_BIT_DO not defined]
#error[MMC_BIT_DO not defined]
#endif
#endif
 
 
#ifndef[MMC_BIT_CLK]
#ifndef[MMC_BIT_CLK]
#error[MMC_BIT_CLK not defined]
#error[MMC_BIT_CLK not defined]
#endif
#endif
 
 
#ifndef[MMC__PORT_DO]
#ifndef[MMC__PORT_DO]
#define[MMC__PORT_DO][MMC_PORT]
#define[MMC__PORT_DO][MMC_PORT]
#endif
#endif
 
 
#ifdef[MMC_bmMODE]
#ifdef[MMC_bmMODE]
#ifneq[MMC__PORT_DO][MMC_PORT]
#ifneq[MMC__PORT_DO][MMC_PORT]
#error[MMC__PORT_DO and MMC_PORT must be equal]
#error[MMC__PORT_DO and MMC_PORT must be equal]
#endif
#endif
#endif
#endif
 
 
#define[MMC_bmCS][bmBITMMC_BIT_CS]
#define[MMC_bmCS][bmBITMMC_BIT_CS]
#define[MMC_bmDI][bmBITMMC_BIT_DI]
#define[MMC_bmDI][bmBITMMC_BIT_DI]
#define[MMC_bmDO][bmBITMMC_BIT_DO]
#define[MMC_bmDO][bmBITMMC_BIT_DO]
#define[MMC_bmCLK][bmBITMMC_BIT_CLK]
#define[MMC_bmCLK][bmBITMMC_BIT_CLK]
 
 
#define[MMC_IO][IOMMC_PORT]
#define[MMC_IO][IOMMC_PORT]
#define[MMC__IO_DO][IOMMC__PORT_DO]
#define[MMC__IO_DO][IOMMC__PORT_DO]
 
 
#ifndef[MMC_bmMODE]
#ifndef[MMC_bmMODE]
#define[MMC_CS][IOMMC_PORTMMC_BIT_CS]
#define[MMC_CS][IOMMC_PORTMMC_BIT_CS]
#define[MMC_CLK][IOMMC_PORTMMC_BIT_CLK]
#define[MMC_CLK][IOMMC_PORTMMC_BIT_CLK]
#define[MMC_DI][IOMMC_PORTMMC_BIT_DI]
#define[MMC_DI][IOMMC_PORTMMC_BIT_DI]
#define[MMC_DO][IOMMC__PORT_DOMMC_BIT_DO]
#define[MMC_DO][IOMMC__PORT_DOMMC_BIT_DO]
#endif
#endif
 
 
// may be redefined if the first sectors are reserved (e.g. for a FPGA bitstream)
// may be redefined if the first sectors are reserved (e.g. for a FPGA bitstream)
#define[FLASH_FIRST_FREE_SECTOR][0]
#define[FLASH_FIRST_FREE_SECTOR][0]
 
 
__xdata BYTE flash_enabled;     // 0    1: enabled, 0:disabled
__xdata BYTE flash_enabled;     // 0    1: enabled, 0:disabled
__xdata WORD flash_sector_size; // 1    sector size
__xdata WORD flash_sector_size; // 1    sector size
__xdata DWORD flash_sectors;    // 3    number of sectors
__xdata DWORD flash_sectors;    // 3    number of sectors
__xdata BYTE flash_ec;          // 7    error code
__xdata BYTE flash_ec;          // 7    error code
 
 
__xdata BYTE mmc_last_cmd;      // 0
__xdata BYTE mmc_last_cmd;      // 0
__xdata BYTE mmc_response;      // 1
__xdata BYTE mmc_response;      // 1
__xdata BYTE mmc_version;       // 2
__xdata BYTE mmc_version;       // 2
__xdata BYTE mmc_buffer[16];    // 3
__xdata BYTE mmc_buffer[16];    // 3
 
 
__xdata BYTE mmc_ep0_wait;
__xdata BYTE mmc_ep0_wait;
 
 
#define[FLASH_EC_CMD_ERROR][1]
#define[FLASH_EC_CMD_ERROR][1]
#define[FLASH_EC_TIMEOUT][2]
#define[FLASH_EC_TIMEOUT][2]
#define[FLASH_EC_BUSY][3]
#define[FLASH_EC_BUSY][3]
#define[FLASH_EC_PENDING][4]
#define[FLASH_EC_PENDING][4]
#define[FLASH_EC_READ_ERROR][5]
#define[FLASH_EC_READ_ERROR][5]
#define[FLASH_EC_WRITE_ERROR][6]
#define[FLASH_EC_WRITE_ERROR][6]
#define[FLASH_EC_NOTSUPPORTED][7]
#define[FLASH_EC_NOTSUPPORTED][7]
 
 
/* *********************************************************************
/* *********************************************************************
   ***** mmc_clocks ****************************************************
   ***** mmc_clocks ****************************************************
   ********************************************************************* */
   ********************************************************************* */
// perform c (256 if c=0) clocks
// perform c (256 if c=0) clocks
void mmc_clocks (BYTE c) {
void mmc_clocks (BYTE c) {
        c;                                      // this avoids stupid warnings
        c;                                      // this avoids stupid warnings
__asm
__asm
        mov     r2,dpl
        mov     r2,dpl
#ifdef[MMC_bmMODE]
#ifdef[MMC_bmMODE]
        mov     a,_MMC_IO
        mov     a,_MMC_IO
        anl     a, #(~MMC_bmCLK)
        anl     a, #(~MMC_bmCLK)
        mov     r3, a
        mov     r3, a
        orl     a, #(MMC_bmCLK)
        orl     a, #(MMC_bmCLK)
        mov     r4, a
        mov     r4, a
010014$:
010014$:
        mov     _MMC_IO,r4
        mov     _MMC_IO,r4
        nop
        nop
        mov     _MMC_IO,r3
        mov     _MMC_IO,r3
#else
#else
010014$:
010014$:
        setb    _MMC_CLK
        setb    _MMC_CLK
        nop
        nop
        clr     _MMC_CLK
        clr     _MMC_CLK
#endif
#endif
        djnz    r2,010014$
        djnz    r2,010014$
__endasm;
__endasm;
}
}
 
 
 
 
/* *********************************************************************
/* *********************************************************************
   ***** flash_read_byte ***********************************************
   ***** flash_read_byte ***********************************************
   ********************************************************************* */
   ********************************************************************* */
// read a single byte from the flash
// read a single byte from the flash
BYTE flash_read_byte() { // uses r2,r3,r4
BYTE flash_read_byte() { // uses r2,r3,r4
__asm
__asm
#ifdef[MMC_bmMODE]
#ifdef[MMC_bmMODE]
        // 8 - 1 + 8*13 + 1 + 6 = 118 clocks
        // 8 - 1 + 8*13 + 1 + 6 = 118 clocks
        mov     a,_MMC_IO
        mov     a,_MMC_IO
        anl     a, #(~MMC_bmCLK)
        anl     a, #(~MMC_bmCLK)
        mov     r2, a
        mov     r2, a
        orl     a, #(MMC_bmCLK)
        orl     a, #(MMC_bmCLK)
        mov     r3, a
        mov     r3, a
 
 
        mov     a,_MMC_IO       // 7
        mov     a,_MMC_IO       // 7
        anl     a,#(MMC_bmDO)
        anl     a,#(MMC_bmDO)
        mov     _MMC_IO, r3
        mov     _MMC_IO, r3
        subb    a,#1
        subb    a,#1
        rlc     a
        rlc     a
        mov     r4,a
        mov     r4,a
        mov     _MMC_IO, r2
        mov     _MMC_IO, r2
 
 
        mov     a,_MMC_IO       // 6
        mov     a,_MMC_IO       // 6
        anl     a,#(MMC_bmDO)
        anl     a,#(MMC_bmDO)
        mov     _MMC_IO, r3
        mov     _MMC_IO, r3
        subb    a,#1
        subb    a,#1
        mov     a,r4
        mov     a,r4
        rlc     a
        rlc     a
        mov     r4,a
        mov     r4,a
        mov     _MMC_IO, r2
        mov     _MMC_IO, r2
 
 
        mov     a,_MMC_IO       // 5
        mov     a,_MMC_IO       // 5
        anl     a,#(MMC_bmDO)
        anl     a,#(MMC_bmDO)
        mov     _MMC_IO, r3
        mov     _MMC_IO, r3
        subb    a,#1
        subb    a,#1
        mov     a,r4
        mov     a,r4
        rlc     a
        rlc     a
        mov     r4,a
        mov     r4,a
        mov     _MMC_IO, r2
        mov     _MMC_IO, r2
 
 
        mov     a,_MMC_IO       // 4
        mov     a,_MMC_IO       // 4
        anl     a,#(MMC_bmDO)
        anl     a,#(MMC_bmDO)
        mov     _MMC_IO, r3
        mov     _MMC_IO, r3
        subb    a,#1
        subb    a,#1
        mov     a,r4
        mov     a,r4
        rlc     a
        rlc     a
        mov     r4,a
        mov     r4,a
        mov     _MMC_IO, r2
        mov     _MMC_IO, r2
 
 
        mov     a,_MMC_IO       // 3
        mov     a,_MMC_IO       // 3
        anl     a,#(MMC_bmDO)
        anl     a,#(MMC_bmDO)
        mov     _MMC_IO, r3
        mov     _MMC_IO, r3
        subb    a,#1
        subb    a,#1
        mov     a,r4
        mov     a,r4
        rlc     a
        rlc     a
        mov     r4,a
        mov     r4,a
        mov     _MMC_IO, r2
        mov     _MMC_IO, r2
 
 
        mov     a,_MMC_IO       // 2
        mov     a,_MMC_IO       // 2
        anl     a,#(MMC_bmDO)
        anl     a,#(MMC_bmDO)
        mov     _MMC_IO, r3
        mov     _MMC_IO, r3
        subb    a,#1
        subb    a,#1
        mov     a,r4
        mov     a,r4
        rlc     a
        rlc     a
        mov     r4,a
        mov     r4,a
        mov     _MMC_IO, r2
        mov     _MMC_IO, r2
 
 
        mov     a,_MMC_IO       // 1
        mov     a,_MMC_IO       // 1
        anl     a,#(MMC_bmDO)
        anl     a,#(MMC_bmDO)
        mov     _MMC_IO, r3
        mov     _MMC_IO, r3
        subb    a,#1
        subb    a,#1
        mov     a,r4
        mov     a,r4
        rlc     a
        rlc     a
        mov     r4,a
        mov     r4,a
        mov     _MMC_IO, r2
        mov     _MMC_IO, r2
 
 
        mov     a,_MMC_IO       // 0
        mov     a,_MMC_IO       // 0
        anl     a,#(MMC_bmDO)
        anl     a,#(MMC_bmDO)
        mov     _MMC_IO, r3
        mov     _MMC_IO, r3
        subb    a,#1
        subb    a,#1
        mov     a,r4
        mov     a,r4
        rlc     a
        rlc     a
        xrl     a,#255
        xrl     a,#255
        mov     _MMC_IO, r2
        mov     _MMC_IO, r2
 
 
#else
#else
        // 8*7 + 6 = 62 clocks 
        // 8*7 + 6 = 62 clocks 
        mov     c,_MMC_DO       // 7
        mov     c,_MMC_DO       // 7
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a
        rlc     a
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     c,_MMC_DO       // 6
        mov     c,_MMC_DO       // 6
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a
        rlc     a
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     c,_MMC_DO       // 5
        mov     c,_MMC_DO       // 5
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a
        rlc     a
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     c,_MMC_DO       // 4
        mov     c,_MMC_DO       // 4
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a
        rlc     a
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     c,_MMC_DO       // 3
        mov     c,_MMC_DO       // 3
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a
        rlc     a
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     c,_MMC_DO       // 2
        mov     c,_MMC_DO       // 2
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a
        rlc     a
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     c,_MMC_DO       // 1
        mov     c,_MMC_DO       // 1
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a
        rlc     a
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     c,_MMC_DO       // 0
        mov     c,_MMC_DO       // 0
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a
        rlc     a
        clr     _MMC_CLK
        clr     _MMC_CLK
#endif
#endif
        mov     dpl,a
        mov     dpl,a
        ret
        ret
__endasm;
__endasm;
        return 0;                // never ever called (just to avoid warnings)
        return 0;                // never ever called (just to avoid warnings)
}
}
 
 
/* *********************************************************************
/* *********************************************************************
   ***** flash_read ****************************************************
   ***** flash_read ****************************************************
   ********************************************************************* */
   ********************************************************************* */
// read len (256 if len=0) bytes from the flash to the buffer
// read len (256 if len=0) bytes from the flash to the buffer
void flash_read(__xdata BYTE *buf, BYTE len) {
void flash_read(__xdata BYTE *buf, BYTE len) {
        *buf;                                   // this avoids stupid warnings
        *buf;                                   // this avoids stupid warnings
        len;                                    // this too
        len;                                    // this too
__asm                                           // *buf is in dptr, len is in _flash_read_PARM_2
__asm                                           // *buf is in dptr, len is in _flash_read_PARM_2
        mov     r2,_flash_read_PARM_2
        mov     r2,_flash_read_PARM_2
#ifdef[MMC_bmMODE]
#ifdef[MMC_bmMODE]
        mov     a,_MMC_IO
        mov     a,_MMC_IO
        anl     a, #(~MMC_bmCLK)
        anl     a, #(~MMC_bmCLK)
        mov     r5, a
        mov     r5, a
        orl     a, #(MMC_bmCLK)
        orl     a, #(MMC_bmCLK)
        mov     r3, a
        mov     r3, a
 
 
010012$:
010012$:
        // 8 + len*(-1 + 8*13 - 1 + 2 + 9) + 4 = 12 + len*113 clocks
        // 8 + len*(-1 + 8*13 - 1 + 2 + 9) + 4 = 12 + len*113 clocks
        mov     a,_MMC_IO       // 7
        mov     a,_MMC_IO       // 7
        anl     a,#(MMC_bmDO)
        anl     a,#(MMC_bmDO)
        mov     _MMC_IO, r3
        mov     _MMC_IO, r3
        subb    a,#1
        subb    a,#1
        rlc     a
        rlc     a
        mov     r4,a
        mov     r4,a
        mov     _MMC_IO, r5
        mov     _MMC_IO, r5
 
 
        mov     a,_MMC_IO       // 6
        mov     a,_MMC_IO       // 6
        anl     a,#(MMC_bmDO)
        anl     a,#(MMC_bmDO)
        mov     _MMC_IO, r3
        mov     _MMC_IO, r3
        subb    a,#1
        subb    a,#1
        mov     a,r4
        mov     a,r4
        rlc     a
        rlc     a
        mov     r4,a
        mov     r4,a
        mov     _MMC_IO, r5
        mov     _MMC_IO, r5
 
 
        mov     a,_MMC_IO       // 5
        mov     a,_MMC_IO       // 5
        anl     a,#(MMC_bmDO)
        anl     a,#(MMC_bmDO)
        mov     _MMC_IO, r3
        mov     _MMC_IO, r3
        subb    a,#1
        subb    a,#1
        mov     a,r4
        mov     a,r4
        rlc     a
        rlc     a
        mov     r4,a
        mov     r4,a
        mov     _MMC_IO, r5
        mov     _MMC_IO, r5
 
 
        mov     a,_MMC_IO       // 4
        mov     a,_MMC_IO       // 4
        anl     a,#(MMC_bmDO)
        anl     a,#(MMC_bmDO)
        mov     _MMC_IO, r3
        mov     _MMC_IO, r3
        subb    a,#1
        subb    a,#1
        mov     a,r4
        mov     a,r4
        rlc     a
        rlc     a
        mov     r4,a
        mov     r4,a
        mov     _MMC_IO, r5
        mov     _MMC_IO, r5
 
 
        mov     a,_MMC_IO       // 3
        mov     a,_MMC_IO       // 3
        anl     a,#(MMC_bmDO)
        anl     a,#(MMC_bmDO)
        mov     _MMC_IO, r3
        mov     _MMC_IO, r3
        subb    a,#1
        subb    a,#1
        mov     a,r4
        mov     a,r4
        rlc     a
        rlc     a
        mov     r4,a
        mov     r4,a
        mov     _MMC_IO, r5
        mov     _MMC_IO, r5
 
 
        mov     a,_MMC_IO       // 2
        mov     a,_MMC_IO       // 2
        anl     a,#(MMC_bmDO)
        anl     a,#(MMC_bmDO)
        mov     _MMC_IO, r3
        mov     _MMC_IO, r3
        subb    a,#1
        subb    a,#1
        mov     a,r4
        mov     a,r4
        rlc     a
        rlc     a
        mov     r4,a
        mov     r4,a
        mov     _MMC_IO, r5
        mov     _MMC_IO, r5
 
 
        mov     a,_MMC_IO       // 1
        mov     a,_MMC_IO       // 1
        anl     a,#(MMC_bmDO)
        anl     a,#(MMC_bmDO)
        mov     _MMC_IO, r3
        mov     _MMC_IO, r3
        subb    a,#1
        subb    a,#1
        mov     a,r4
        mov     a,r4
        rlc     a
        rlc     a
        mov     r4,a
        mov     r4,a
        mov     _MMC_IO, r5
        mov     _MMC_IO, r5
 
 
        mov     a,_MMC_IO       // 0
        mov     a,_MMC_IO       // 0
        anl     a,#(MMC_bmDO)
        anl     a,#(MMC_bmDO)
        mov     _MMC_IO, r3
        mov     _MMC_IO, r3
        subb    a,#1
        subb    a,#1
        mov     a,r4
        mov     a,r4
        rlc     a
        rlc     a
        xrl     a,#255
        xrl     a,#255
        mov     _MMC_IO, r5
        mov     _MMC_IO, r5
#else
#else
010012$:
010012$:
        // 2 + len*(8*7 + 9) + 4 = 6 + len*65 clocks
        // 2 + len*(8*7 + 9) + 4 = 6 + len*65 clocks
        mov     c,_MMC_DO       // 7
        mov     c,_MMC_DO       // 7
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a
        rlc     a
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     c,_MMC_DO       // 6
        mov     c,_MMC_DO       // 6
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a
        rlc     a
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     c,_MMC_DO       // 5
        mov     c,_MMC_DO       // 5
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a
        rlc     a
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     c,_MMC_DO       // 4
        mov     c,_MMC_DO       // 4
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a
        rlc     a
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     c,_MMC_DO       // 3
        mov     c,_MMC_DO       // 3
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a
        rlc     a
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     c,_MMC_DO       // 2
        mov     c,_MMC_DO       // 2
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a
        rlc     a
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     c,_MMC_DO       // 1
        mov     c,_MMC_DO       // 1
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a
        rlc     a
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     c,_MMC_DO       // 0
        mov     c,_MMC_DO       // 0
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a
        rlc     a
        clr     _MMC_CLK
        clr     _MMC_CLK
#endif
#endif
        movx    @dptr,a
        movx    @dptr,a
        inc     dptr
        inc     dptr
        djnz    r2,010012$
        djnz    r2,010012$
__endasm;
__endasm;
}
}
 
 
/* *********************************************************************
/* *********************************************************************
   ***** flash_write_byte **********************************************
   ***** flash_write_byte **********************************************
   ********************************************************************* */
   ********************************************************************* */
// send one bytes from buffer buf to the card
// send one bytes from buffer buf to the card
void flash_write_byte (BYTE b) {        // b is in dpl
void flash_write_byte (BYTE b) {        // b is in dpl
        b;                              // this avoids stupid warnings
        b;                              // this avoids stupid warnings
__asm
__asm
#ifdef[MMC_bmMODE]
#ifdef[MMC_bmMODE]
        // up to 7 + 8*12 + 6 = 109 clocks
        // up to 7 + 8*12 + 6 = 109 clocks
        mov     a,_MMC_IO
        mov     a,_MMC_IO
        anl     a, #(255 - MMC_bmCLK - MMC_bmDI )
        anl     a, #(255 - MMC_bmCLK - MMC_bmDI )
        mov     r3, a
        mov     r3, a
        mov     a,dpl
        mov     a,dpl
 
 
        rlc     a               // 7
        rlc     a               // 7
        mov     _MMC_IO,r3
        mov     _MMC_IO,r3
        jnc     0100157$
        jnc     0100157$
        orl     _MMC_IO, #(MMC_bmDI)
        orl     _MMC_IO, #(MMC_bmDI)
0100157$:
0100157$:
        orl     _MMC_IO, #(MMC_bmCLK)
        orl     _MMC_IO, #(MMC_bmCLK)
 
 
        rlc     a               // 6
        rlc     a               // 6
        mov     _MMC_IO,r3
        mov     _MMC_IO,r3
        jnc     0100156$
        jnc     0100156$
        orl     _MMC_IO, #(MMC_bmDI)
        orl     _MMC_IO, #(MMC_bmDI)
0100156$:
0100156$:
        orl     _MMC_IO, #(MMC_bmCLK)
        orl     _MMC_IO, #(MMC_bmCLK)
 
 
        rlc     a               // 5
        rlc     a               // 5
        mov     _MMC_IO,r3
        mov     _MMC_IO,r3
        jnc     0100155$
        jnc     0100155$
        orl     _MMC_IO, #(MMC_bmDI)
        orl     _MMC_IO, #(MMC_bmDI)
0100155$:
0100155$:
        orl     _MMC_IO, #(MMC_bmCLK)
        orl     _MMC_IO, #(MMC_bmCLK)
 
 
        rlc     a               // 4
        rlc     a               // 4
        mov     _MMC_IO,r3
        mov     _MMC_IO,r3
        jnc     0100154$
        jnc     0100154$
        orl     _MMC_IO, #(MMC_bmDI)
        orl     _MMC_IO, #(MMC_bmDI)
0100154$:
0100154$:
        orl     _MMC_IO, #(MMC_bmCLK)
        orl     _MMC_IO, #(MMC_bmCLK)
 
 
        rlc     a               // 3
        rlc     a               // 3
        mov     _MMC_IO,r3
        mov     _MMC_IO,r3
        jnc     0100153$
        jnc     0100153$
        orl     _MMC_IO, #(MMC_bmDI)
        orl     _MMC_IO, #(MMC_bmDI)
0100153$:
0100153$:
        orl     _MMC_IO, #(MMC_bmCLK)
        orl     _MMC_IO, #(MMC_bmCLK)
 
 
        rlc     a               // 2
        rlc     a               // 2
        mov     _MMC_IO,r3
        mov     _MMC_IO,r3
        jnc     0100152$
        jnc     0100152$
        orl     _MMC_IO, #(MMC_bmDI)
        orl     _MMC_IO, #(MMC_bmDI)
0100152$:
0100152$:
        orl     _MMC_IO, #(MMC_bmCLK)
        orl     _MMC_IO, #(MMC_bmCLK)
 
 
        rlc     a               // 1
        rlc     a               // 1
        mov     _MMC_IO,r3
        mov     _MMC_IO,r3
        jnc     0100151$
        jnc     0100151$
        orl     _MMC_IO, #(MMC_bmDI)
        orl     _MMC_IO, #(MMC_bmDI)
0100151$:
0100151$:
        orl     _MMC_IO, #(MMC_bmCLK)
        orl     _MMC_IO, #(MMC_bmCLK)
 
 
        rlc     a               // 0
        rlc     a               // 0
        mov     _MMC_IO,r3
        mov     _MMC_IO,r3
        jnc     0100150$
        jnc     0100150$
        orl     _MMC_IO, #(MMC_bmDI)
        orl     _MMC_IO, #(MMC_bmDI)
0100150$:
0100150$:
        orl     _MMC_IO, #(MMC_bmCLK)
        orl     _MMC_IO, #(MMC_bmCLK)
 
 
        mov     _MMC_IO,r3
        mov     _MMC_IO,r3
#else
#else
        // 3 + 8*7 + 4 = 63 clocks 
        // 3 + 8*7 + 4 = 63 clocks 
        mov     a,dpl
        mov     a,dpl
        rlc     a               // 7
        rlc     a               // 7
 
 
        mov     _MMC_DI,c
        mov     _MMC_DI,c
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a               // 6
        rlc     a               // 6
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     _MMC_DI,c
        mov     _MMC_DI,c
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a               // 5
        rlc     a               // 5
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     _MMC_DI,c
        mov     _MMC_DI,c
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a               // 4
        rlc     a               // 4
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     _MMC_DI,c
        mov     _MMC_DI,c
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a               // 3
        rlc     a               // 3
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     _MMC_DI,c
        mov     _MMC_DI,c
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a               // 2
        rlc     a               // 2
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     _MMC_DI,c
        mov     _MMC_DI,c
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a               // 1
        rlc     a               // 1
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     _MMC_DI,c
        mov     _MMC_DI,c
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a               // 0
        rlc     a               // 0
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     _MMC_DI,c
        mov     _MMC_DI,c
        setb    _MMC_CLK
        setb    _MMC_CLK
        nop
        nop
        clr     _MMC_CLK
        clr     _MMC_CLK
#endif  
#endif  
__endasm;
__endasm;
}
}
 
 
/* *********************************************************************
/* *********************************************************************
   ***** flash_write ***************************************************
   ***** flash_write ***************************************************
   ********************************************************************* */
   ********************************************************************* */
// write len (256 id len=0) bytes from the buffer to the flash
// write len (256 id len=0) bytes from the buffer to the flash
void flash_write(__xdata BYTE *buf, BYTE len) {
void flash_write(__xdata BYTE *buf, BYTE len) {
        *buf;                                   // this avoids stupid warnings
        *buf;                                   // this avoids stupid warnings
        len;                                    // this too
        len;                                    // this too
__asm                                           // *buf is in dptr, len is in _flash_read_PARM_2
__asm                                           // *buf is in dptr, len is in _flash_read_PARM_2
        mov     r2,_flash_read_PARM_2
        mov     r2,_flash_read_PARM_2
#ifdef[MMC_bmMODE]
#ifdef[MMC_bmMODE]
        // 7 + len*(2 + 8*12 + 7 ) + 6 = 13 + len*105 clocks
        // 7 + len*(2 + 8*12 + 7 ) + 6 = 13 + len*105 clocks
        mov     a,_MMC_IO
        mov     a,_MMC_IO
        anl     a, #(255 - MMC_bmCLK - MMC_bmDI )
        anl     a, #(255 - MMC_bmCLK - MMC_bmDI )
        mov     r3, a
        mov     r3, a
010013$:
010013$:
        movx    a,@dptr
        movx    a,@dptr
 
 
        rlc     a               // 7
        rlc     a               // 7
        mov     _MMC_IO,r3
        mov     _MMC_IO,r3
        jnc     0100167$
        jnc     0100167$
        orl     _MMC_IO, #(MMC_bmDI)
        orl     _MMC_IO, #(MMC_bmDI)
0100167$:
0100167$:
        orl     _MMC_IO, #(MMC_bmCLK)
        orl     _MMC_IO, #(MMC_bmCLK)
 
 
        rlc     a               // 6
        rlc     a               // 6
        mov     _MMC_IO,r3
        mov     _MMC_IO,r3
        jnc     0100166$
        jnc     0100166$
        orl     _MMC_IO, #(MMC_bmDI)
        orl     _MMC_IO, #(MMC_bmDI)
0100166$:
0100166$:
        orl     _MMC_IO, #(MMC_bmCLK)
        orl     _MMC_IO, #(MMC_bmCLK)
 
 
        rlc     a               // 5
        rlc     a               // 5
        mov     _MMC_IO,r3
        mov     _MMC_IO,r3
        jnc     0100165$
        jnc     0100165$
        orl     _MMC_IO, #(MMC_bmDI)
        orl     _MMC_IO, #(MMC_bmDI)
0100165$:
0100165$:
        orl     _MMC_IO, #(MMC_bmCLK)
        orl     _MMC_IO, #(MMC_bmCLK)
 
 
        rlc     a               // 4
        rlc     a               // 4
        mov     _MMC_IO,r3
        mov     _MMC_IO,r3
        jnc     0100164$
        jnc     0100164$
        orl     _MMC_IO, #(MMC_bmDI)
        orl     _MMC_IO, #(MMC_bmDI)
0100164$:
0100164$:
        orl     _MMC_IO, #(MMC_bmCLK)
        orl     _MMC_IO, #(MMC_bmCLK)
 
 
        rlc     a               // 3
        rlc     a               // 3
        mov     _MMC_IO,r3
        mov     _MMC_IO,r3
        jnc     0100163$
        jnc     0100163$
        orl     _MMC_IO, #(MMC_bmDI)
        orl     _MMC_IO, #(MMC_bmDI)
0100163$:
0100163$:
        orl     _MMC_IO, #(MMC_bmCLK)
        orl     _MMC_IO, #(MMC_bmCLK)
 
 
        rlc     a               // 2
        rlc     a               // 2
        mov     _MMC_IO,r3
        mov     _MMC_IO,r3
        jnc     0100162$
        jnc     0100162$
        orl     _MMC_IO, #(MMC_bmDI)
        orl     _MMC_IO, #(MMC_bmDI)
0100162$:
0100162$:
        orl     _MMC_IO, #(MMC_bmCLK)
        orl     _MMC_IO, #(MMC_bmCLK)
 
 
        rlc     a               // 1
        rlc     a               // 1
        mov     _MMC_IO,r3
        mov     _MMC_IO,r3
        jnc     0100161$
        jnc     0100161$
        orl     _MMC_IO, #(MMC_bmDI)
        orl     _MMC_IO, #(MMC_bmDI)
0100161$:
0100161$:
        orl     _MMC_IO, #(MMC_bmCLK)
        orl     _MMC_IO, #(MMC_bmCLK)
 
 
        rlc     a               // 0
        rlc     a               // 0
        mov     _MMC_IO,r3
        mov     _MMC_IO,r3
        jnc     0100160$
        jnc     0100160$
        orl     _MMC_IO, #(MMC_bmDI)
        orl     _MMC_IO, #(MMC_bmDI)
0100160$:
0100160$:
        orl     _MMC_IO, #(MMC_bmCLK)
        orl     _MMC_IO, #(MMC_bmCLK)
 
 
        inc     dptr
        inc     dptr
        djnz    r2,010013$
        djnz    r2,010013$
 
 
        mov     _MMC_IO,r3
        mov     _MMC_IO,r3
#else
#else
010013$:
010013$:
        // 2 + len*(3 + 8*7 - 1 + 7 ) + 4 = 6 + len*65 clocks
        // 2 + len*(3 + 8*7 - 1 + 7 ) + 4 = 6 + len*65 clocks
        movx    a,@dptr
        movx    a,@dptr
        rlc     a               // 7
        rlc     a               // 7
 
 
        mov     _MMC_DI,c
        mov     _MMC_DI,c
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a               // 6
        rlc     a               // 6
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     _MMC_DI,c
        mov     _MMC_DI,c
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a               // 5
        rlc     a               // 5
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     _MMC_DI,c
        mov     _MMC_DI,c
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a               // 4
        rlc     a               // 4
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     _MMC_DI,c
        mov     _MMC_DI,c
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a               // 3
        rlc     a               // 3
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     _MMC_DI,c
        mov     _MMC_DI,c
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a               // 2
        rlc     a               // 2
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     _MMC_DI,c
        mov     _MMC_DI,c
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a               // 1
        rlc     a               // 1
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     _MMC_DI,c
        mov     _MMC_DI,c
        setb    _MMC_CLK
        setb    _MMC_CLK
        rlc     a               // 0
        rlc     a               // 0
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        mov     _MMC_DI,c
        mov     _MMC_DI,c
        setb    _MMC_CLK
        setb    _MMC_CLK
        inc     dptr
        inc     dptr
        clr     _MMC_CLK
        clr     _MMC_CLK
 
 
        djnz    r2,010013$
        djnz    r2,010013$
#endif
#endif
__endasm;
__endasm;
}
}
 
 
/* *********************************************************************
/* *********************************************************************
   ***** mmc_wait_busy *************************************************
   ***** mmc_wait_busy *************************************************
   ********************************************************************* */
   ********************************************************************* */
BYTE mmc_wait_busy () {
BYTE mmc_wait_busy () {
    WORD i;
    WORD i;
    flash_ec = FLASH_EC_BUSY;
    flash_ec = FLASH_EC_BUSY;
    MMC_IO |= MMC_bmDI;                         // avoids that in-data is interpreted as command
    MMC_IO |= MMC_bmDI;                         // avoids that in-data is interpreted as command
    for (i=0; (flash_read_byte()!=255) && i<65535; i++ ) ;
    for (i=0; (flash_read_byte()!=255) && i<65535; i++ ) ;
//    for (i=0; (flash_read_byte()==0) && i<65535; i++ ) ;
//    for (i=0; (flash_read_byte()==0) && i<65535; i++ ) ;
    if ( MMC__IO_DO & MMC_bmDO ) {
    if ( MMC__IO_DO & MMC_bmDO ) {
        flash_ec = 0;
        flash_ec = 0;
        return 0;
        return 0;
    }
    }
    return 1;
    return 1;
}
}
 
 
/* *********************************************************************
/* *********************************************************************
   ***** mmc_select ****************************************************
   ***** mmc_select ****************************************************
   ********************************************************************* */
   ********************************************************************* */
/*
/*
   select the card (CS) and waits if busy
   select the card (CS) and waits if busy
   returns 1 if busy
   returns 1 if busy
*/
*/
BYTE mmc_select() {
BYTE mmc_select() {
    MMC_IO |= MMC_bmCS;                         // CS = 1
    MMC_IO |= MMC_bmCS;                         // CS = 1
    mmc_clocks(8);                              // 8 dummy clocks to finish a previous command
    mmc_clocks(8);                              // 8 dummy clocks to finish a previous command
    MMC_IO &= ~MMC_bmCS;                        // CS = 0
    MMC_IO &= ~MMC_bmCS;                        // CS = 0
 
 
    return mmc_wait_busy();
    return mmc_wait_busy();
}
}
 
 
/* *********************************************************************
/* *********************************************************************
   ***** mmc_deselect **************************************************
   ***** mmc_deselect **************************************************
   ********************************************************************* */
   ********************************************************************* */
// de-select the card (CS) and waits if busy
// de-select the card (CS) and waits if busy
void mmc_deselect() {
void mmc_deselect() {
    MMC_IO |= MMC_bmDI;                         // CS = 1
    MMC_IO |= MMC_bmDI;                         // CS = 1
    mmc_clocks(8);                              // 8 dummy clocks to finish a previous command
    mmc_clocks(8);                              // 8 dummy clocks to finish a previous command
    MMC_IO |= MMC_bmCS;                         // CS = 1
    MMC_IO |= MMC_bmCS;                         // CS = 1
    mmc_clocks(8);                              // 8 more dummy clocks
    mmc_clocks(8);                              // 8 more dummy clocks
}
}
 
 
/* *********************************************************************
/* *********************************************************************
   ***** mmc_read_response *********************************************
   ***** mmc_read_response *********************************************
   ********************************************************************* */
   ********************************************************************* */
// read the first response byte
// read the first response byte
BYTE mmc_read_response() {
BYTE mmc_read_response() {
        MMC_IO |= MMC_bmDI;                     // avoids that in-data is interpreted as command
        MMC_IO |= MMC_bmDI;                     // avoids that in-data is interpreted as command
__asm
__asm
        mov     r2,#0x255
        mov     r2,#0x255
010010$:
010010$:
        lcall   _flash_read_byte
        lcall   _flash_read_byte
        mov     a,dpl
        mov     a,dpl
        jnb     acc.7,010011$
        jnb     acc.7,010011$
        djnz    r2, 010010$
        djnz    r2, 010010$
 
 
010011$:
010011$:
        mov     dptr,#_mmc_response
        mov     dptr,#_mmc_response
        movx    @dptr,a
        movx    @dptr,a
        mov     dpl,a
        mov     dpl,a
        ret
        ret
__endasm;
__endasm;
        return 0;                                // never ever called, just to avoid stupid warnings
        return 0;                                // never ever called, just to avoid stupid warnings
}
}
 
 
/* *********************************************************************
/* *********************************************************************
   ***** mmc_send_cmd **************************************************
   ***** mmc_send_cmd **************************************************
   ********************************************************************* */
   ********************************************************************* */
// send a command   
// send a command   
#define[mmc_send_cmd(][,$1.$2.$3.$4,$5);][{                     // send a command, argument=0
#define[mmc_send_cmd(][,$1.$2.$3.$4,$5);][{                     // send a command, argument=0
    mmc_clocks(8);                              // 8 dummy clocks
    mmc_clocks(8);                              // 8 dummy clocks
    mmc_last_cmd = $0;
    mmc_last_cmd = $0;
    mmc_buffer[0] = 64 | ($0 & 127);
    mmc_buffer[0] = 64 | ($0 & 127);
    mmc_buffer[1] = $1;
    mmc_buffer[1] = $1;
    mmc_buffer[2] = $2;
    mmc_buffer[2] = $2;
    mmc_buffer[3] = $3;
    mmc_buffer[3] = $3;
    mmc_buffer[4] = $4;
    mmc_buffer[4] = $4;
    mmc_buffer[5] = $5 | 1;
    mmc_buffer[5] = $5 | 1;
    flash_write(mmc_buffer,6);
    flash_write(mmc_buffer,6);
    mmc_read_response();
    mmc_read_response();
}]
}]
 
 
/* *********************************************************************
/* *********************************************************************
   ***** mmc_wait_start ************************************************
   ***** mmc_wait_start ************************************************
   ********************************************************************* */
   ********************************************************************* */
/*
/*
   wait for the start byte
   wait for the start byte
   returns 1 on error
   returns 1 on error
*/
*/
BYTE mmc_wait_start() {
BYTE mmc_wait_start() {
    WORD to;
    WORD to;
    to=0;
    to=0;
    MMC_IO |= MMC_bmDI;                         // avoids that in-data is interpreted as command
    MMC_IO |= MMC_bmDI;                         // avoids that in-data is interpreted as command
    while ( flash_read_byte() != 0xfe ) {       // wait for the start byte
    while ( flash_read_byte() != 0xfe ) {       // wait for the start byte
        if ( ++to == 0 )                         // 65536 * 8 clocks
        if ( ++to == 0 )                         // 65536 * 8 clocks
            return 1;
            return 1;
    }
    }
    return 0;
    return 0;
}
}
 
 
/* *********************************************************************
/* *********************************************************************
   ***** flash_read_init ***********************************************
   ***** flash_read_init ***********************************************
   ********************************************************************* */
   ********************************************************************* */
/*
/*
   Start the initialization sequence for reading sector s.
   Start the initialization sequence for reading sector s.
   The whole sector must be read.
   The whole sector must be read.
   returns an error code (FLASH_EC_*). 0 means no error.
   returns an error code (FLASH_EC_*). 0 means no error.
*/
*/
BYTE flash_read_init(DWORD s) {
BYTE flash_read_init(DWORD s) {
    if ( (MMC_IO & MMC_bmCS) == 0 ) {
    if ( (MMC_IO & MMC_bmCS) == 0 ) {
        return FLASH_EC_PENDING;                // we interrupted a pending Flash operation
        return FLASH_EC_PENDING;                // we interrupted a pending Flash operation
    }
    }
    if ( mmc_select() ) {                       // select the card
    if ( mmc_select() ) {                       // select the card
        mmc_deselect();
        mmc_deselect();
        return FLASH_EC_BUSY;
        return FLASH_EC_BUSY;
    }
    }
    mmc_clocks(8);                              // 8 dummy clocks
    mmc_clocks(8);                              // 8 dummy clocks
    mmc_last_cmd = 18;
    mmc_last_cmd = 18;
    mmc_buffer[0] = 18 | 64;
    mmc_buffer[0] = 18 | 64;
    if ( mmc_version == 0 ) {
    if ( mmc_version == 0 ) {
        s = s << 1;
        s = s << 1;
        mmc_buffer[1] = s >> 16;
        mmc_buffer[1] = s >> 16;
        mmc_buffer[2] = s >> 8;
        mmc_buffer[2] = s >> 8;
        mmc_buffer[3] = s;
        mmc_buffer[3] = s;
        mmc_buffer[4] = 0;
        mmc_buffer[4] = 0;
    }
    }
    else {
    else {
        mmc_buffer[1] = s >> 24;
        mmc_buffer[1] = s >> 24;
        mmc_buffer[2] = s >> 16;
        mmc_buffer[2] = s >> 16;
        mmc_buffer[3] = s >> 8;
        mmc_buffer[3] = s >> 8;
        mmc_buffer[4] = s;
        mmc_buffer[4] = s;
    }
    }
    mmc_buffer[5] = 1;
    mmc_buffer[5] = 1;
    flash_write(mmc_buffer,6);
    flash_write(mmc_buffer,6);
    mmc_read_response();
    mmc_read_response();
    if ( mmc_response != 0 ) {
    if ( mmc_response != 0 ) {
        mmc_deselect();
        mmc_deselect();
        return FLASH_EC_CMD_ERROR;
        return FLASH_EC_CMD_ERROR;
    }
    }
 
 
    if ( mmc_wait_start() ) {                   // wait for the start byte
    if ( mmc_wait_start() ) {                   // wait for the start byte
        mmc_deselect();
        mmc_deselect();
        return FLASH_EC_TIMEOUT;
        return FLASH_EC_TIMEOUT;
    }
    }
    return 0;
    return 0;
}
}
 
 
/* *********************************************************************
/* *********************************************************************
   ***** flash_read_next ***********************************************
   ***** flash_read_next ***********************************************
   ********************************************************************* */
   ********************************************************************* */
/*
/*
   Initialization sequence for reading the next sector.
   Initialization sequence for reading the next sector.
   The whole sector must be read.
   The whole sector must be read.
   returns an error code (FLASH_EC_*). 0 means no error.
   returns an error code (FLASH_EC_*). 0 means no error.
*/
*/
BYTE flash_read_next() {
BYTE flash_read_next() {
    mmc_clocks(16);                             // 16 CRC clocks
    mmc_clocks(16);                             // 16 CRC clocks
    if ( mmc_wait_start() ) {                   // wait for the start byte
    if ( mmc_wait_start() ) {                   // wait for the start byte
        mmc_deselect();
        mmc_deselect();
        return FLASH_EC_TIMEOUT;
        return FLASH_EC_TIMEOUT;
    }
    }
    return 0;
    return 0;
}
}
 
 
/* *********************************************************************
/* *********************************************************************
   ***** flash_read_finish *********************************************
   ***** flash_read_finish *********************************************
   ********************************************************************* */
   ********************************************************************* */
/*
/*
   Reads n dummy bytes (the whole sector has to be read out)
   Reads n dummy bytes (the whole sector has to be read out)
   and runs the finalization sequence for a sector read.
   and runs the finalization sequence for a sector read.
*/
*/
void flash_read_finish(WORD n) {
void flash_read_finish(WORD n) {
    while ( n > 32 ) {
    while ( n > 32 ) {
        mmc_clocks(0);                   // 256 clocks = 32 dummy bytes
        mmc_clocks(0);                   // 256 clocks = 32 dummy bytes
        n-=32;
        n-=32;
    }
    }
    if ( n>0) mmc_clocks(n << 3);
    if ( n>0) mmc_clocks(n << 3);
    mmc_clocks(16);                     // 16 CRC clocks 
    mmc_clocks(16);                     // 16 CRC clocks 
    mmc_send_cmd(12, 0.0.0.0, 0);        // stop transmission command, errors are ignored
    mmc_send_cmd(12, 0.0.0.0, 0);        // stop transmission command, errors are ignored
//    mmc_wait_busy();                  // not required here
//    mmc_wait_busy();                  // not required here
    mmc_clocks(8);                      // 8 dummy clocks
    mmc_clocks(8);                      // 8 dummy clocks
   mmc_deselect();
   mmc_deselect();
}
}
 
 
 
 
/* *********************************************************************
/* *********************************************************************
   ***** flash_write_init **********************************************
   ***** flash_write_init **********************************************
   ********************************************************************* */
   ********************************************************************* */
/*
/*
   Start the initialization sequence for writing sector s
   Start the initialization sequence for writing sector s
   The whole sector must be written.
   The whole sector must be written.
   returns an error code (FLASH_EC_*). 0 means no error.
   returns an error code (FLASH_EC_*). 0 means no error.
*/
*/
BYTE flash_write_init(DWORD s) {
BYTE flash_write_init(DWORD s) {
    if ( (MMC_IO & MMC_bmCS) == 0 ) {
    if ( (MMC_IO & MMC_bmCS) == 0 ) {
        return FLASH_EC_PENDING;                // we interrupted a pending Flash operation
        return FLASH_EC_PENDING;                // we interrupted a pending Flash operation
    }
    }
    if ( mmc_select() ) {                       // select the card
    if ( mmc_select() ) {                       // select the card
        mmc_deselect();
        mmc_deselect();
        return FLASH_EC_BUSY;
        return FLASH_EC_BUSY;
    }
    }
    mmc_clocks(8);                              // 8 dummy clocks
    mmc_clocks(8);                              // 8 dummy clocks
    mmc_last_cmd = 25;
    mmc_last_cmd = 25;
    mmc_buffer[0] = 25 | 64;
    mmc_buffer[0] = 25 | 64;
    if ( mmc_version == 0 ) {
    if ( mmc_version == 0 ) {
        s = s << 1;
        s = s << 1;
        mmc_buffer[1] = s >> 16;
        mmc_buffer[1] = s >> 16;
        mmc_buffer[2] = s >> 8;
        mmc_buffer[2] = s >> 8;
        mmc_buffer[3] = s;
        mmc_buffer[3] = s;
        mmc_buffer[4] = 0;
        mmc_buffer[4] = 0;
    }
    }
    else {
    else {
        mmc_buffer[1] = s >> 24;
        mmc_buffer[1] = s >> 24;
        mmc_buffer[2] = s >> 16;
        mmc_buffer[2] = s >> 16;
        mmc_buffer[3] = s >> 8;
        mmc_buffer[3] = s >> 8;
        mmc_buffer[4] = s;
        mmc_buffer[4] = s;
    }
    }
    mmc_buffer[5] = 1;
    mmc_buffer[5] = 1;
    flash_write(mmc_buffer,6);
    flash_write(mmc_buffer,6);
    mmc_read_response();
    mmc_read_response();
    if ( mmc_response != 0 ) {
    if ( mmc_response != 0 ) {
        mmc_deselect();
        mmc_deselect();
        return FLASH_EC_CMD_ERROR;
        return FLASH_EC_CMD_ERROR;
    }
    }
 
 
    MMC_IO |= MMC_bmDI;
    MMC_IO |= MMC_bmDI;
    mmc_clocks(8);                              // send one dummy byte
    mmc_clocks(8);                              // send one dummy byte
    flash_write_byte( 0xfc );                   // send the start byte
    flash_write_byte( 0xfc );                   // send the start byte
    return 0;
    return 0;
}
}
 
 
/* *********************************************************************
/* *********************************************************************
   ***** flash_write_finish_sector *************************************
   ***** flash_write_finish_sector *************************************
   ********************************************************************* */
   ********************************************************************* */
/*
/*
   Writes the rest of the sector (n dummy bytes + CRC, the whole sector has to be written)
   Writes the rest of the sector (n dummy bytes + CRC, the whole sector has to be written)
   but do not run the finalization procedure. This is done by flash_write_finish
   but do not run the finalization procedure. This is done by flash_write_finish
   or flash_write_next, i.e. these functions must be called after flash_write_finish_sector.
   or flash_write_next, i.e. these functions must be called after flash_write_finish_sector.
 
 
   Between flash_write_finish / flash_write_next and flash_write_finish_sector some code
   Between flash_write_finish / flash_write_next and flash_write_finish_sector some code
   may be executed because flash_write_finish / flash_write_next start with
   may be executed because flash_write_finish / flash_write_next start with
   mmc_wait_busy().
   mmc_wait_busy().
 
 
   Returns an error code (FLASH_EC_*). 0 means no error.
   Returns an error code (FLASH_EC_*). 0 means no error.
*/
*/
BYTE flash_write_finish_sector (WORD n) {
BYTE flash_write_finish_sector (WORD n) {
    MMC_IO &= ~MMC_bmDI;                        // value of the dummy data is 0
    MMC_IO &= ~MMC_bmDI;                        // value of the dummy data is 0
    while ( n > 32 ) {
    while ( n > 32 ) {
        mmc_clocks(0);                           // 256 clocks = 32 dummy bytes
        mmc_clocks(0);                           // 256 clocks = 32 dummy bytes
        n-=32;
        n-=32;
    }
    }
    if ( n>0) mmc_clocks(n << 3);
    if ( n>0) mmc_clocks(n << 3);
 
 
    MMC_IO |= MMC_bmDI;
    MMC_IO |= MMC_bmDI;
    mmc_clocks(16);                             // 16 CRC clocks
    mmc_clocks(16);                             // 16 CRC clocks
 
 
    if ( (flash_read_byte() & 0xf) != 5 ) {     // data response: last four bits must be 5
    if ( (flash_read_byte() & 0xf) != 5 ) {     // data response: last four bits must be 5
       flash_ec = FLASH_EC_WRITE_ERROR;
       flash_ec = FLASH_EC_WRITE_ERROR;
       mmc_send_cmd(12, 0.0.0.0, 0);             // stop transmission command, errors are ignored
       mmc_send_cmd(12, 0.0.0.0, 0);             // stop transmission command, errors are ignored
       mmc_clocks(8);                           // 8 dummy clocks
       mmc_clocks(8);                           // 8 dummy clocks
       mmc_deselect();
       mmc_deselect();
       return FLASH_EC_WRITE_ERROR;
       return FLASH_EC_WRITE_ERROR;
    }
    }
    return 0;
    return 0;
}
}
 
 
/* *********************************************************************
/* *********************************************************************
   ***** flash_write_finish ********************************************
   ***** flash_write_finish ********************************************
   ********************************************************************* */
   ********************************************************************* */
/*
/*
   Stops the write transimssion, see flash_write_finish1.
   Stops the write transimssion, see flash_write_finish1.
*/
*/
void flash_write_finish () {
void flash_write_finish () {
    mmc_wait_busy();
    mmc_wait_busy();
    flash_write_byte( 0xfd );                   // send the stop byte
    flash_write_byte( 0xfd );                   // send the stop byte
    mmc_clocks(8);                              // 8 dummy clocks
    mmc_clocks(8);                              // 8 dummy clocks
    mmc_deselect();
    mmc_deselect();
}
}
 
 
/* *********************************************************************
/* *********************************************************************
   ***** flash_write_next **********************************************
   ***** flash_write_next **********************************************
   ********************************************************************* */
   ********************************************************************* */
/*
/*
   Prepare the nexte sector for writing, see flash_write_finish_sector.
   Prepare the nexte sector for writing, see flash_write_finish_sector.
*/
*/
void flash_write_next () {
void flash_write_next () {
    mmc_wait_busy();
    mmc_wait_busy();
    flash_write_byte( 0xfc );                   // send the stop byte
    flash_write_byte( 0xfc );                   // send the stop byte
}
}
 
 
/* *********************************************************************
/* *********************************************************************
   ***** flash_init ****************************************************
   ***** flash_init ****************************************************
   ********************************************************************* */
   ********************************************************************* */
// init the card
// init the card
void flash_init() {
void flash_init() {
    BYTE i, j, k;
    BYTE i, j, k;
 
 
#ifeq[UFM_1_15X_DETECTION_ENABLED][1]
#ifeq[UFM_1_15X_DETECTION_ENABLED][1]
    if ( is_ufm_1_15x ) {
    if ( is_ufm_1_15x ) {
        flash_enabled = 0;
        flash_enabled = 0;
        flash_ec = FLASH_EC_NOTSUPPORTED;
        flash_ec = FLASH_EC_NOTSUPPORTED;
        return;
        return;
    }
    }
#endif    
#endif    
 
 
    flash_enabled = 1;
    flash_enabled = 1;
    flash_sector_size = 512;
    flash_sector_size = 512;
    mmc_version = 0;
    mmc_version = 0;
 
 
    OEMMC_PORT = OEMMC_PORT | ( MMC_bmCS | MMC_bmDI | MMC_bmCLK );
    OEMMC_PORT = OEMMC_PORT | ( MMC_bmCS | MMC_bmDI | MMC_bmCLK );
    OEMMC__PORT_DO = OEMMC__PORT_DO & ~MMC_bmDO;
    OEMMC__PORT_DO = OEMMC__PORT_DO & ~MMC_bmDO;
 
 
    MMC_IO |= MMC_bmDI;
    MMC_IO |= MMC_bmDI;
    MMC_IO |= MMC_bmCS;
    MMC_IO |= MMC_bmCS;
    mmc_clocks(0);                               // 256 clocks
    mmc_clocks(0);                               // 256 clocks
 
 
    mmc_select();                               // select te card
    mmc_select();                               // select te card
    flash_ec = FLASH_EC_BUSY;
    flash_ec = FLASH_EC_BUSY;
 
 
    mmc_send_cmd(0, 0.0.0.0, 0x95);              // send reset command
    mmc_send_cmd(0, 0.0.0.0, 0x95);              // send reset command
    if ( mmc_response & ~1 ) {                  // check for errors
    if ( mmc_response & ~1 ) {                  // check for errors
        wait(50);
        wait(50);
        mmc_send_cmd(0, 0.0.0.0, 0x95);          // 2nd try
        mmc_send_cmd(0, 0.0.0.0, 0x95);          // 2nd try
        if ( mmc_response & ~1 )                // check for errors 
        if ( mmc_response & ~1 )                // check for errors 
            goto mmc_init_cmd_err;
            goto mmc_init_cmd_err;
    }
    }
 
 
    // send cmd8, valid ? 2.0 mode : 1.xx mode
    // send cmd8, valid ? 2.0 mode : 1.xx mode
    mmc_send_cmd(8, 0.0.1.0xaa, 0x87);
    mmc_send_cmd(8, 0.0.1.0xaa, 0x87);
    if ( ( mmc_response & bmBIT2) == 0 ) {
    if ( ( mmc_response & bmBIT2) == 0 ) {
        if ( (mmc_response & 0xfe) != 0 )
        if ( (mmc_response & 0xfe) != 0 )
            goto mmc_init_cmd_err;
            goto mmc_init_cmd_err;
        flash_read(mmc_buffer,4);
        flash_read(mmc_buffer,4);
        if ( ( (mmc_buffer[2] & 15) != 1) || (mmc_buffer[3] != 0xaa ) ) {
        if ( ( (mmc_buffer[2] & 15) != 1) || (mmc_buffer[3] != 0xaa ) ) {
            flash_ec = FLASH_EC_NOTSUPPORTED;
            flash_ec = FLASH_EC_NOTSUPPORTED;
            goto mmc_init_err;
            goto mmc_init_err;
        }
        }
        mmc_version=1;
        mmc_version=1;
    }
    }
 
 
    // CMD1 is not recommended, therefore we try ACMD41 first
    // CMD1 is not recommended, therefore we try ACMD41 first
    k=mmc_version ? 64 : 0;
    k=mmc_version ? 64 : 0;
    mmc_send_cmd(55, 0.0.0.0, 0);
    mmc_send_cmd(55, 0.0.0.0, 0);
    if ( (mmc_response & 0xfe) == 0 )
    if ( (mmc_response & 0xfe) == 0 )
        mmc_send_cmd(41, k.0.0.0, 0);
        mmc_send_cmd(41, k.0.0.0, 0);
    j = mmc_response & 0xfe;
    j = mmc_response & 0xfe;
 
 
    for ( i=0; mmc_response != 0 && i<255; i++ ) {        // send the init command and wait wait (up to 1s) until ready
    for ( i=0; mmc_response != 0 && i<255; i++ ) {        // send the init command and wait wait (up to 1s) until ready
        wait(4);
        wait(4);
        if ( j ) {
        if ( j ) {
            mmc_send_cmd(1, k.0.0.0, 0xff);
            mmc_send_cmd(1, k.0.0.0, 0xff);
        }
        }
        else {
        else {
            mmc_send_cmd(55, 0.0.0.0, 0);
            mmc_send_cmd(55, 0.0.0.0, 0);
            mmc_send_cmd(41, k.0.0.0, 0);
            mmc_send_cmd(41, k.0.0.0, 0);
        }
        }
    }
    }
    if ( mmc_response != 0 ) {                   // check for errors
    if ( mmc_response != 0 ) {                   // check for errors
        goto mmc_init_cmd_err;
        goto mmc_init_cmd_err;
    }
    }
 
 
    if ( mmc_version ) {
    if ( mmc_version ) {
        mmc_send_cmd(58, 0.0.0.0, 0);            // check the high capacity mode
        mmc_send_cmd(58, 0.0.0.0, 0);            // check the high capacity mode
        if ( mmc_response != 0 )                 // check for errors
        if ( mmc_response != 0 )                 // check for errors
            goto mmc_init_cmd_err;
            goto mmc_init_cmd_err;
        flash_read(mmc_buffer,4);
        flash_read(mmc_buffer,4);
        if ( (mmc_buffer[0] & 64) == 0 )  // card in standard capacity mode
        if ( (mmc_buffer[0] & 64) == 0 )  // card in standard capacity mode
            mmc_version = 0;
            mmc_version = 0;
    }
    }
 
 
    mmc_send_cmd(9, 0.0.0.0, 0);         // read the CSD
    mmc_send_cmd(9, 0.0.0.0, 0);         // read the CSD
    if ( mmc_wait_start() ) {
    if ( mmc_wait_start() ) {
        flash_ec = FLASH_EC_TIMEOUT;
        flash_ec = FLASH_EC_TIMEOUT;
        goto mmc_init_err;
        goto mmc_init_err;
    }
    }
    flash_read(mmc_buffer,16);
    flash_read(mmc_buffer,16);
    mmc_clocks(16);                             // CRC is clocked out
    mmc_clocks(16);                             // CRC is clocked out
 
 
    mmc_buffer[0] &= 192;
    mmc_buffer[0] &= 192;
    if ( (mmc_buffer[0] & 192) == 0  ) {
    if ( (mmc_buffer[0] & 192) == 0  ) {
        i = (mmc_buffer[5] & 15) + ((mmc_buffer[10] >> 7) | ((mmc_buffer[9] & 3) << 1)) - 7;
        i = (mmc_buffer[5] & 15) + ((mmc_buffer[10] >> 7) | ((mmc_buffer[9] & 3) << 1)) - 7;
        flash_sectors = ((mmc_buffer[8] >> 6) | (mmc_buffer[7] << 2) | ((mmc_buffer[6] & 3) << 10)) + 1;
        flash_sectors = ((mmc_buffer[8] >> 6) | (mmc_buffer[7] << 2) | ((mmc_buffer[6] & 3) << 10)) + 1;
        flash_sectors = flash_sectors << i;
        flash_sectors = flash_sectors << i;
    }
    }
    else if ( (mmc_buffer[0] & 192) == 64  ) { // todo
    else if ( (mmc_buffer[0] & 192) == 64  ) { // todo
        flash_sectors = ( ( ((DWORD)(mmc_buffer[7] & 63) << 16) | (mmc_buffer[8] << 8) | mmc_buffer[9]  ) +1 ) << 10;
        flash_sectors = ( ( ((DWORD)(mmc_buffer[7] & 63) << 16) | (mmc_buffer[8] << 8) | mmc_buffer[9]  ) +1 ) << 10;
    }
    }
    else {
    else {
        flash_ec = FLASH_EC_NOTSUPPORTED;
        flash_ec = FLASH_EC_NOTSUPPORTED;
        goto mmc_init_err;
        goto mmc_init_err;
    }
    }
 
 
    flash_ec = 0;
    flash_ec = 0;
    mmc_deselect();
    mmc_deselect();
 
 
    return;
    return;
 
 
mmc_init_cmd_err:
mmc_init_cmd_err:
    flash_ec = FLASH_EC_CMD_ERROR;
    flash_ec = FLASH_EC_CMD_ERROR;
mmc_init_err:
mmc_init_err:
    flash_enabled = 0;
    flash_enabled = 0;
    mmc_deselect();
    mmc_deselect();
}
}
 
 
 
 
/* *********************************************************************
/* *********************************************************************
   ***** EP0 vendor request 0x40 ***************************************
   ***** EP0 vendor request 0x40 ***************************************
   ********************************************************************* */
   ********************************************************************* */
// send mmc information structure (card size, error status,  ...) to the host
// send mmc information structure (card size, error status,  ...) to the host
ADD_EP0_VENDOR_REQUEST((0x40,,
ADD_EP0_VENDOR_REQUEST((0x40,,
    MEM_COPY1(flash_enabled,EP0BUF,8);
    MEM_COPY1(flash_enabled,EP0BUF,8);
    EP0BCH = 0;
    EP0BCH = 0;
    EP0BCL = 8;
    EP0BCL = 8;
,,
,,
));;
));;
 
 
/* *********************************************************************
/* *********************************************************************
   ***** EP0 vendor request 0x41 ***************************************
   ***** EP0 vendor request 0x41 ***************************************
   ********************************************************************* */
   ********************************************************************* */
void mmc_read_ep0 () {
void mmc_read_ep0 () {
    if ( mmc_ep0_wait ) {
    if ( mmc_ep0_wait ) {
        mmc_ep0_wait = 0;
        mmc_ep0_wait = 0;
        if ( mmc_wait_start() ) {               // wait for the start byte of the next block
        if ( mmc_wait_start() ) {               // wait for the start byte of the next block
            flash_ec = FLASH_EC_TIMEOUT;
            flash_ec = FLASH_EC_TIMEOUT;
            mmc_send_cmd(12, 0.0.0.0, 0);        // stop transmission command
            mmc_send_cmd(12, 0.0.0.0, 0);        // stop transmission command
            mmc_clocks(8);                      // 8 dummy clocks
            mmc_clocks(8);                      // 8 dummy clocks
            mmc_deselect();
            mmc_deselect();
            return;
            return;
        }
        }
    }
    }
 
 
    flash_read(EP0BUF, ep0_payload_transfer);
    flash_read(EP0BUF, ep0_payload_transfer);
    if ( ep0_payload_remaining == 0 ) {
    if ( ep0_payload_remaining == 0 ) {
        mmc_clocks(16);                         // 16 CRC clocks 
        mmc_clocks(16);                         // 16 CRC clocks 
        mmc_send_cmd(12, 0.0.0.0, 0);            // stop transmission command, errors are ignored
        mmc_send_cmd(12, 0.0.0.0, 0);            // stop transmission command, errors are ignored
//      mmc_wait_busy();                        // not required here
//      mmc_wait_busy();                        // not required here
        mmc_clocks(8);                          // 8 dummy clocks
        mmc_clocks(8);                          // 8 dummy clocks
        mmc_deselect();
        mmc_deselect();
    }
    }
    else if ( (ep0_payload_remaining & 511) == 0 ) {
    else if ( (ep0_payload_remaining & 511) == 0 ) {
        mmc_clocks(16);                         // 16 CRC clocks
        mmc_clocks(16);                         // 16 CRC clocks
        mmc_ep0_wait = 1;
        mmc_ep0_wait = 1;
    }
    }
}
}
 
 
ADD_EP0_VENDOR_REQUEST((0x41,,                  // read integer number of sectotrs
ADD_EP0_VENDOR_REQUEST((0x41,,                  // read integer number of sectotrs
    if ( (MMC_IO & MMC_bmCS) == 0 ) {
    if ( (MMC_IO & MMC_bmCS) == 0 ) {
        flash_ec = FLASH_EC_PENDING;            // we interrupted a pending Flash operation
        flash_ec = FLASH_EC_PENDING;            // we interrupted a pending Flash operation
        EP0_STALL;
        EP0_STALL;
    }
    }
    if ( mmc_select() ) {                       // select the card
    if ( mmc_select() ) {                       // select the card
        mmc_deselect();
        mmc_deselect();
        EP0_STALL;
        EP0_STALL;
    }
    }
    mmc_clocks(8);                              // 8 dummy clocks
    mmc_clocks(8);                              // 8 dummy clocks
    mmc_last_cmd = 18;
    mmc_last_cmd = 18;
    mmc_buffer[0] = 18 | 64;
    mmc_buffer[0] = 18 | 64;
    if ( mmc_version == 0 ) {
    if ( mmc_version == 0 ) {
__asm
__asm
    clr c
    clr c
    mov dptr,#(_SETUPDAT + 2)
    mov dptr,#(_SETUPDAT + 2)
    movx a,@dptr
    movx a,@dptr
    mov dptr,#(_mmc_buffer + 3)
    mov dptr,#(_mmc_buffer + 3)
    rlc a
    rlc a
    movx @dptr,a
    movx @dptr,a
 
 
    mov dptr,#(_SETUPDAT + 3)
    mov dptr,#(_SETUPDAT + 3)
    movx a,@dptr
    movx a,@dptr
    mov dptr,#(_mmc_buffer + 2)
    mov dptr,#(_mmc_buffer + 2)
    rlc a
    rlc a
    movx @dptr,a
    movx @dptr,a
 
 
    mov dptr,#(_SETUPDAT + 4)
    mov dptr,#(_SETUPDAT + 4)
    movx a,@dptr
    movx a,@dptr
    mov dptr,#(_mmc_buffer + 1)
    mov dptr,#(_mmc_buffer + 1)
    rlc a
    rlc a
    movx @dptr,a
    movx @dptr,a
__endasm;
__endasm;
        mmc_buffer[4] = 0;
        mmc_buffer[4] = 0;
    }
    }
    else {
    else {
        mmc_buffer[1] = SETUPDAT[5];
        mmc_buffer[1] = SETUPDAT[5];
        mmc_buffer[2] = SETUPDAT[4];
        mmc_buffer[2] = SETUPDAT[4];
        mmc_buffer[3] = SETUPDAT[3];
        mmc_buffer[3] = SETUPDAT[3];
        mmc_buffer[4] = SETUPDAT[2];
        mmc_buffer[4] = SETUPDAT[2];
    }
    }
    mmc_buffer[5] = 1;
    mmc_buffer[5] = 1;
    flash_write(mmc_buffer,6);
    flash_write(mmc_buffer,6);
    mmc_read_response();
    mmc_read_response();
    if ( mmc_response != 0 ) {
    if ( mmc_response != 0 ) {
        flash_ec = FLASH_EC_CMD_ERROR;
        flash_ec = FLASH_EC_CMD_ERROR;
        mmc_deselect();
        mmc_deselect();
        EP0_STALL;
        EP0_STALL;
    }
    }
 
 
    mmc_ep0_wait = 1;
    mmc_ep0_wait = 1;
    mmc_read_ep0();
    mmc_read_ep0();
    if ( flash_ec != 0 ) {
    if ( flash_ec != 0 ) {
        EP0_STALL;
        EP0_STALL;
    }
    }
    EP0BCH = 0;
    EP0BCH = 0;
    EP0BCL = ep0_payload_transfer;
    EP0BCL = ep0_payload_transfer;
,,
,,
    if ( ep0_payload_transfer != 0 ) {
    if ( ep0_payload_transfer != 0 ) {
        flash_ec = 0;
        flash_ec = 0;
        mmc_read_ep0();
        mmc_read_ep0();
        if ( flash_ec != 0 ) {
        if ( flash_ec != 0 ) {
            EP0_STALL;
            EP0_STALL;
        }
        }
    }
    }
    EP0BCH = 0;
    EP0BCH = 0;
    EP0BCL = ep0_payload_transfer;
    EP0BCL = ep0_payload_transfer;
));;
));;
 
 
/* *********************************************************************
/* *********************************************************************
   ***** EP0 vendor command 0x42 ***************************************
   ***** EP0 vendor command 0x42 ***************************************
   ********************************************************************* */
   ********************************************************************* */
void mmc_send_ep0 () {
void mmc_send_ep0 () {
    if ( mmc_ep0_wait ) {
    if ( mmc_ep0_wait ) {
        mmc_ep0_wait = 0;
        mmc_ep0_wait = 0;
        mmc_wait_busy();
        mmc_wait_busy();
        flash_write_byte( 0xfc );                       // send the start byte of the next data block
        flash_write_byte( 0xfc );                       // send the start byte of the next data block
    }
    }
 
 
    flash_write(EP0BUF, ep0_payload_transfer);
    flash_write(EP0BUF, ep0_payload_transfer);
    if ( (ep0_payload_remaining & 511) == 0 ) {
    if ( (ep0_payload_remaining & 511) == 0 ) {
        MMC_IO |= MMC_bmDI;
        MMC_IO |= MMC_bmDI;
        mmc_clocks(16);                                 // 16 CRC clocks
        mmc_clocks(16);                                 // 16 CRC clocks
 
 
        if ( (flash_read_byte() & 0xf) != 5 ) {         // data response: last four bits must be 5
        if ( (flash_read_byte() & 0xf) != 5 ) {         // data response: last four bits must be 5
           flash_ec = FLASH_EC_WRITE_ERROR;
           flash_ec = FLASH_EC_WRITE_ERROR;
           mmc_send_cmd(12, 0.0.0.0, 0);         // stop transmission command, errors are ignored
           mmc_send_cmd(12, 0.0.0.0, 0);         // stop transmission command, errors are ignored
           mmc_clocks(8);                               // 8 dummy clocks
           mmc_clocks(8);                               // 8 dummy clocks
           mmc_deselect();
           mmc_deselect();
        }
        }
 
 
        if ( ep0_payload_remaining != 0 ) {
        if ( ep0_payload_remaining != 0 ) {
            mmc_ep0_wait = 1;
            mmc_ep0_wait = 1;
        }
        }
        else {
        else {
            mmc_wait_busy();
            mmc_wait_busy();
            flash_write_byte( 0xfd );                   // send the stop byte
            flash_write_byte( 0xfd );                   // send the stop byte
            mmc_clocks(8);                              // 8 dummy clocks
            mmc_clocks(8);                              // 8 dummy clocks
            mmc_deselect();
            mmc_deselect();
        }
        }
    }
    }
}
}
 
 
ADD_EP0_VENDOR_COMMAND((0x42,,                  // write integer number of sectors
ADD_EP0_VENDOR_COMMAND((0x42,,                  // write integer number of sectors
    if ( (MMC_IO & MMC_bmCS) == 0 ) {
    if ( (MMC_IO & MMC_bmCS) == 0 ) {
        flash_ec = FLASH_EC_PENDING;            // we interrupted a pending Flash operation
        flash_ec = FLASH_EC_PENDING;            // we interrupted a pending Flash operation
        EP0_STALL;
        EP0_STALL;
    }
    }
    if ( mmc_select() ) {                       // select the card
    if ( mmc_select() ) {                       // select the card
        mmc_deselect();
        mmc_deselect();
        EP0_STALL;
        EP0_STALL;
    }
    }
    mmc_clocks(8);                              // 8 dummy clocks
    mmc_clocks(8);                              // 8 dummy clocks
    mmc_last_cmd = 25;
    mmc_last_cmd = 25;
    mmc_buffer[0] = 25 | 64;
    mmc_buffer[0] = 25 | 64;
    if ( mmc_version == 0 ) {
    if ( mmc_version == 0 ) {
__asm
__asm
    clr c
    clr c
    mov dptr,#(_SETUPDAT + 2)
    mov dptr,#(_SETUPDAT + 2)
    movx a,@dptr
    movx a,@dptr
    mov dptr,#(_mmc_buffer + 3)
    mov dptr,#(_mmc_buffer + 3)
    rlc a
    rlc a
    movx @dptr,a
    movx @dptr,a
 
 
    mov dptr,#(_SETUPDAT + 3)
    mov dptr,#(_SETUPDAT + 3)
    movx a,@dptr
    movx a,@dptr
    mov dptr,#(_mmc_buffer + 2)
    mov dptr,#(_mmc_buffer + 2)
    rlc a
    rlc a
    movx @dptr,a
    movx @dptr,a
 
 
    mov dptr,#(_SETUPDAT + 4)
    mov dptr,#(_SETUPDAT + 4)
    movx a,@dptr
    movx a,@dptr
    mov dptr,#(_mmc_buffer + 1)
    mov dptr,#(_mmc_buffer + 1)
    rlc a
    rlc a
    movx @dptr,a
    movx @dptr,a
__endasm;
__endasm;
        mmc_buffer[4] = 0;
        mmc_buffer[4] = 0;
    }
    }
    else {
    else {
        mmc_buffer[1] = SETUPDAT[5];
        mmc_buffer[1] = SETUPDAT[5];
        mmc_buffer[2] = SETUPDAT[4];
        mmc_buffer[2] = SETUPDAT[4];
        mmc_buffer[3] = SETUPDAT[3];
        mmc_buffer[3] = SETUPDAT[3];
        mmc_buffer[4] = SETUPDAT[2];
        mmc_buffer[4] = SETUPDAT[2];
    }
    }
 
 
    mmc_buffer[5] = 1;
    mmc_buffer[5] = 1;
    flash_write(mmc_buffer,6);
    flash_write(mmc_buffer,6);
    mmc_read_response();
    mmc_read_response();
    if ( mmc_response != 0 ) {
    if ( mmc_response != 0 ) {
        flash_ec = FLASH_EC_CMD_ERROR;
        flash_ec = FLASH_EC_CMD_ERROR;
        mmc_deselect();
        mmc_deselect();
        EP0_STALL;
        EP0_STALL;
    }
    }
 
 
    MMC_IO |= MMC_bmDI;
    MMC_IO |= MMC_bmDI;
    mmc_clocks(8);                              // send one dummy byte
    mmc_clocks(8);                              // send one dummy byte
    flash_write_byte( 0xfc );                   // send the start byte
    flash_write_byte( 0xfc );                   // send the start byte
    mmc_ep0_wait = 0;
    mmc_ep0_wait = 0;
,,
,,
    if ( ep0_payload_transfer != 0 ) {
    if ( ep0_payload_transfer != 0 ) {
        flash_ec = 0;
        flash_ec = 0;
        mmc_send_ep0();
        mmc_send_ep0();
        if ( flash_ec != 0 ) {
        if ( flash_ec != 0 ) {
            EP0_STALL;
            EP0_STALL;
        }
        }
    }
    }
));;
));;
 
 
/* *********************************************************************
/* *********************************************************************
   ***** EP0 vendor request 0x43 ***************************************
   ***** EP0 vendor request 0x43 ***************************************
   ********************************************************************* */
   ********************************************************************* */
// send detailed MMC status plus debug information
// send detailed MMC status plus debug information
ADD_EP0_VENDOR_REQUEST((0x43,,                  // this may interrupt a pending operation
ADD_EP0_VENDOR_REQUEST((0x43,,                  // this may interrupt a pending operation
    MEM_COPY1(flash_ec,EP0BUF+2,20);
    MEM_COPY1(flash_ec,EP0BUF+2,20);
    EP0BUF[22] = (MMC__IO_DO & MMC_bmDO) == 0;
    EP0BUF[22] = (MMC__IO_DO & MMC_bmDO) == 0;
    mmc_select();
    mmc_select();
    mmc_send_cmd(13, 0.0.0.0, 0);
    mmc_send_cmd(13, 0.0.0.0, 0);
    EP0BUF[0] = mmc_response;
    EP0BUF[0] = mmc_response;
    EP0BUF[1] = flash_read_byte();
    EP0BUF[1] = flash_read_byte();
    mmc_deselect();
    mmc_deselect();
    EP0BCH = 0;
    EP0BCH = 0;
    EP0BCL = 23;
    EP0BCL = 23;
,,
,,
));;
));;
 
 
#endif  /*ZTEX_FLASH1_H*/
#endif  /*ZTEX_FLASH1_H*/
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.