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

Subversion Repositories usb_fpga_1_11

[/] [usb_fpga_1_11/] [trunk/] [include/] [ztex-flash2.h] - Diff between revs 8 and 9

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

Rev 8 Rev 9
/*!
/*!
   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 standard SPI flash.
    Support for standard SPI flash.
*/
*/
 
 
#ifeq[SPI_PORT][A]
#ifeq[SPI_PORT][A]
#elifeq[SPI_PORT][B]
#elifeq[SPI_PORT][B]
#elifeq[SPI_PORT][C]
#elifeq[SPI_PORT][C]
#elifneq[SPI_PORT][D]
#elifneq[SPI_PORT][D]
#error[Macro `SPI_PORT' is not defined correctly. Valid values are: `A', `B', `C' and `D'.]
#error[Macro `SPI_PORT' is not defined correctly. Valid values are: `A', `B', `C' and `D'.]
#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[SPI_PORT]
#ifndef[SPI_PORT]
#error[SPI_PORT not defined]
#error[SPI_PORT not defined]
#endif
#endif
 
 
#ifndef[SPI_BIT_CS]
#ifndef[SPI_BIT_CS]
#error[SPI_BIT_CS not defined]
#error[SPI_BIT_CS not defined]
#endif
#endif
 
 
#ifndef[SPI_BIT_DI]
#ifndef[SPI_BIT_DI]
#error[SPI_BIT_DI not defined]
#error[SPI_BIT_DI not defined]
#endif
#endif
 
 
#ifndef[SPI_BIT_DO]
#ifndef[SPI_BIT_DO]
#error[SPI_BIT_DO not defined]
#error[SPI_BIT_DO not defined]
#endif
#endif
 
 
#ifndef[SPI_BIT_CLK]
#ifndef[SPI_BIT_CLK]
#error[SPI_BIT_CLK not defined]
#error[SPI_BIT_CLK not defined]
#endif
#endif
 
 
#ifndef[SPI_DOPORT]
#ifndef[SPI_OPORT]
#define[SPI_OPORT][SPI_PORT]
#define[SPI_OPORT][SPI_PORT]
#endif
#endif
 
 
#define[SPI_IO@][IOSPI_PORT]
#define[SPI_IO@][IOSPI_PORT]
#define[SPI_OIO@][IOSPI_OPORT]
#define[SPI_OIO@][IOSPI_OPORT]
 
 
#define[SPI_CS][SPI_IO@SPI_BIT_CS]
#define[SPI_CS][SPI_IO@SPI_BIT_CS]
#define[SPI_CLK][SPI_IO@SPI_BIT_CLK]
#define[SPI_CLK][SPI_IO@SPI_BIT_CLK]
#define[SPI_DI][SPI_IO@SPI_BIT_DI]
#define[SPI_DI][SPI_IO@SPI_BIT_DI]
#define[SPI_DO][SPI_OIO@SPI_BIT_DO]
#define[SPI_DO][SPI_OIO@SPI_BIT_DO]
 
 
// 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 <sector size> = MSB==0 : flash_sector_size and 0x7fff ? 1<<(flash_sector_size and 0x7fff)
__xdata WORD flash_sector_size; // 1    sector size <sector size> = MSB==0 : flash_sector_size and 0x7fff ? 1<<(flash_sector_size and 0x7fff)
__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 spi_vendor;        // 0
__xdata BYTE spi_vendor;        // 0
__xdata BYTE spi_device;        // 1
__xdata BYTE spi_device;        // 1
__xdata BYTE spi_memtype;       // 2
__xdata BYTE spi_memtype;       // 2
__xdata BYTE spi_erase_cmd;     // 3
__xdata BYTE spi_erase_cmd;     // 3
__xdata BYTE spi_last_cmd;      // 4
__xdata BYTE spi_last_cmd;      // 4
__xdata BYTE spi_buffer[4];     // 5
__xdata BYTE spi_buffer[4];     // 5
 
 
__xdata WORD spi_write_addr_hi;
__xdata WORD spi_write_addr_hi;
__xdata BYTE spi_write_addr_lo;
__xdata BYTE spi_write_addr_lo;
__xdata BYTE spi_need_pp;
__xdata BYTE spi_need_pp;
__xdata WORD spi_write_sector;
__xdata WORD spi_write_sector;
__xdata BYTE ep0_read_mode;
__xdata BYTE ep0_read_mode;
__xdata BYTE ep0_write_mode;
__xdata BYTE ep0_write_mode;
 
 
#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_NOTSUPPORTED][7]
#define[FLASH_EC_NOTSUPPORTED][7]
 
 
/* *********************************************************************
/* *********************************************************************
   ***** spi_clocks ****************************************************
   ***** spi_clocks ****************************************************
   ********************************************************************* */
   ********************************************************************* */
// perform c (256 if c=0) clocks
// perform c (256 if c=0) clocks
void spi_clocks (BYTE c) {
void spi_clocks (BYTE c) {
        c;                                      // this avoids stupid warnings
        c;                                      // this avoids stupid warnings
__asm
__asm
        mov     r2,dpl
        mov     r2,dpl
010014$:
010014$:
        setb    _SPI_CLK        // 1
        setb    _SPI_CLK        // 1
        nop                     // 1
        nop                     // 1
        nop                     // 1
        nop                     // 1
        nop                     // 1
        nop                     // 1
        clr     _SPI_CLK        // 1
        clr     _SPI_CLK        // 1
        djnz    r2,010014$      // 3
        djnz    r2,010014$      // 3
__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
        // 8*7 + 6 = 62 clocks 
        // 8*7 + 6 = 62 clocks 
        mov     c,_SPI_DO       // 7
        mov     c,_SPI_DO       // 7
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a
        rlc     a
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     c,_SPI_DO       // 6
        mov     c,_SPI_DO       // 6
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a
        rlc     a
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     c,_SPI_DO       // 5
        mov     c,_SPI_DO       // 5
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a
        rlc     a
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     c,_SPI_DO       // 4
        mov     c,_SPI_DO       // 4
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a
        rlc     a
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     c,_SPI_DO       // 3
        mov     c,_SPI_DO       // 3
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a
        rlc     a
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     c,_SPI_DO       // 2
        mov     c,_SPI_DO       // 2
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a
        rlc     a
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     c,_SPI_DO       // 1
        mov     c,_SPI_DO       // 1
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a
        rlc     a
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     c,_SPI_DO       // 0
        mov     c,_SPI_DO       // 0
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a
        rlc     a
        clr     _SPI_CLK
        clr     _SPI_CLK
        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
010012$:
010012$:
        // 2 + len*(8*7 + 9) + 4 = 6 + len*65 clocks
        // 2 + len*(8*7 + 9) + 4 = 6 + len*65 clocks
        mov     c,_SPI_DO       // 7
        mov     c,_SPI_DO       // 7
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a
        rlc     a
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     c,_SPI_DO       // 6
        mov     c,_SPI_DO       // 6
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a
        rlc     a
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     c,_SPI_DO       // 5
        mov     c,_SPI_DO       // 5
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a
        rlc     a
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     c,_SPI_DO       // 4
        mov     c,_SPI_DO       // 4
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a
        rlc     a
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     c,_SPI_DO       // 3
        mov     c,_SPI_DO       // 3
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a
        rlc     a
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     c,_SPI_DO       // 2
        mov     c,_SPI_DO       // 2
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a
        rlc     a
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     c,_SPI_DO       // 1
        mov     c,_SPI_DO       // 1
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a
        rlc     a
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     c,_SPI_DO       // 0
        mov     c,_SPI_DO       // 0
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a
        rlc     a
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        movx    @dptr,a
        movx    @dptr,a
        inc     dptr
        inc     dptr
        djnz    r2,010012$
        djnz    r2,010012$
__endasm;
__endasm;
}
}
 
 
/* *********************************************************************
/* *********************************************************************
   ***** spi_write_byte ************************************************
   ***** spi_write_byte ************************************************
   ********************************************************************* */
   ********************************************************************* */
// send one bytes from buffer buf to the card
// send one bytes from buffer buf to the card
void spi_write_byte (BYTE b) {  // b is in dpl
void spi_write_byte (BYTE b) {  // b is in dpl
        b;                              // this avoids stupid warnings
        b;                              // this avoids stupid warnings
__asm
__asm
        // 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     _SPI_DI,c
        mov     _SPI_DI,c
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a               // 6
        rlc     a               // 6
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     _SPI_DI,c
        mov     _SPI_DI,c
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a               // 5
        rlc     a               // 5
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     _SPI_DI,c
        mov     _SPI_DI,c
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a               // 4
        rlc     a               // 4
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     _SPI_DI,c
        mov     _SPI_DI,c
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a               // 3
        rlc     a               // 3
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     _SPI_DI,c
        mov     _SPI_DI,c
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a               // 2
        rlc     a               // 2
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     _SPI_DI,c
        mov     _SPI_DI,c
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a               // 1
        rlc     a               // 1
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     _SPI_DI,c
        mov     _SPI_DI,c
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a               // 0
        rlc     a               // 0
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     _SPI_DI,c
        mov     _SPI_DI,c
        setb    _SPI_CLK
        setb    _SPI_CLK
        nop
        nop
        clr     _SPI_CLK
        clr     _SPI_CLK
__endasm;
__endasm;
}
}
 
 
/* *********************************************************************
/* *********************************************************************
   ***** spi_write *****************************************************
   ***** spi_write *****************************************************
   ********************************************************************* */
   ********************************************************************* */
// write len (256 if len=0) bytes from the buffer to the flash
// write len (256 if len=0) bytes from the buffer to the flash
void spi_write(__xdata BYTE *buf, BYTE len) {
void spi_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
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     _SPI_DI,c
        mov     _SPI_DI,c
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a               // 6
        rlc     a               // 6
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     _SPI_DI,c
        mov     _SPI_DI,c
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a               // 5
        rlc     a               // 5
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     _SPI_DI,c
        mov     _SPI_DI,c
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a               // 4
        rlc     a               // 4
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     _SPI_DI,c
        mov     _SPI_DI,c
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a               // 3
        rlc     a               // 3
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     _SPI_DI,c
        mov     _SPI_DI,c
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a               // 2
        rlc     a               // 2
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     _SPI_DI,c
        mov     _SPI_DI,c
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a               // 1
        rlc     a               // 1
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     _SPI_DI,c
        mov     _SPI_DI,c
        setb    _SPI_CLK
        setb    _SPI_CLK
        rlc     a               // 0
        rlc     a               // 0
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        mov     _SPI_DI,c
        mov     _SPI_DI,c
        setb    _SPI_CLK
        setb    _SPI_CLK
        inc     dptr
        inc     dptr
        clr     _SPI_CLK
        clr     _SPI_CLK
 
 
        djnz    r2,010013$
        djnz    r2,010013$
__endasm;
__endasm;
}
}
 
 
/* *********************************************************************
/* *********************************************************************
   ***** spi_select ****************************************************
   ***** spi_select ****************************************************
   ********************************************************************* */
   ********************************************************************* */
/*
/*
   select the flash (CS)
   select the flash (CS)
*/
*/
void spi_select() {
void spi_select() {
    SPI_CS = 1;                                 // CS = 1;
    SPI_CS = 1;                                 // CS = 1;
    spi_clocks(8);                              // 8 dummy clocks to finish a previous command
    spi_clocks(8);                              // 8 dummy clocks to finish a previous command
    SPI_CS = 0;
    SPI_CS = 0;
}
}
 
 
/* *********************************************************************
/* *********************************************************************
   ***** spi_deselect **************************************************
   ***** spi_deselect **************************************************
   ********************************************************************* */
   ********************************************************************* */
// de-select the flash (CS)
// de-select the flash (CS)
void spi_deselect() {
void spi_deselect() {
    SPI_CS = 1;                                 // CS = 1;
    SPI_CS = 1;                                 // CS = 1;
    spi_clocks(8);                              // 8 dummy clocks to finish a previous command
    spi_clocks(8);                              // 8 dummy clocks to finish a previous command
}
}
 
 
/* *********************************************************************
/* *********************************************************************
   ***** spi_start_cmd *************************************************
   ***** spi_start_cmd *************************************************
   ********************************************************************* */
   ********************************************************************* */
// send a command   
// send a command   
#define[spi_start_cmd(][);][{                   // send a command, argument=0
#define[spi_start_cmd(][);][{                   // send a command, argument=0
    spi_last_cmd = $0;
    spi_last_cmd = $0;
    spi_select();                               // select
    spi_select();                               // select
    spi_write_byte($0);                          // CMD 90h
    spi_write_byte($0);                          // CMD 90h
}]
}]
 
 
/* *********************************************************************
/* *********************************************************************
   ***** spi_wait ******************************************************
   ***** spi_wait ******************************************************
   ********************************************************************* */
   ********************************************************************* */
/*
/*
   wait if prvious read/write command is still prcessed
   wait if prvious read/write command is still prcessed
   result is flash_ec (FLASH_EC_TIMEOUT or 0)
   result is flash_ec (FLASH_EC_TIMEOUT or 0)
*/
*/
BYTE spi_wait() {
BYTE spi_wait() {
    WORD i;
    WORD i;
    // wait up to 11s
    // wait up to 11s
    spi_start_cmd(0x05);
    spi_start_cmd(0x05);
    for (i=0; (flash_read_byte() & bmBIT0) && i<65535; i++ ) {
    for (i=0; (flash_read_byte() & bmBIT0) && i<65535; i++ ) {
        spi_clocks(0);                           // 256 dummy clocks
        spi_clocks(0);                           // 256 dummy clocks
//      uwait(20);
//      uwait(20);
    }
    }
    flash_ec = flash_read_byte() & bmBIT0 ? FLASH_EC_TIMEOUT : 0;
    flash_ec = flash_read_byte() & bmBIT0 ? FLASH_EC_TIMEOUT : 0;
    spi_deselect();
    spi_deselect();
    return flash_ec;
    return flash_ec;
}
}
 
 
/* *********************************************************************
/* *********************************************************************
   ***** flash_read_init ***********************************************
   ***** flash_read_init ***********************************************
   ********************************************************************* */
   ********************************************************************* */
/*
/*
   Start the initialization sequence for reading sector s.
   Start the initialization sequence for reading sector s.
   returns an error code (FLASH_EC_*). 0 means no error.
   returns an error code (FLASH_EC_*). 0 means no error.
*/
*/
BYTE flash_read_init(WORD s) {
BYTE flash_read_init(WORD s) {
    if ( (SPI_CS) == 0 ) {
    if ( (SPI_CS) == 0 ) {
        flash_ec = FLASH_EC_PENDING;
        flash_ec = FLASH_EC_PENDING;
        return FLASH_EC_PENDING;                // we interrupted a pending Flash operation
        return FLASH_EC_PENDING;                // we interrupted a pending Flash operation
    }
    }
 
    OESPI_OPORT &= ~bmBITSPI_BIT_DO;
 
    OESPI_PORT |= bmBITSPI_BIT_CS | bmBITSPI_BIT_DI | bmBITSPI_BIT_CLK;
    if ( spi_wait() ) {
    if ( spi_wait() ) {
        return flash_ec;
        return flash_ec;
    }
    }
 
 
    s = s << ((BYTE)flash_sector_size - 8);
    s = s << ((BYTE)flash_sector_size - 8);
    spi_start_cmd(0x0b);                        // read command
    spi_start_cmd(0x0b);                        // read command
    spi_write_byte(s >> 8);                     // 24 byte address
    spi_write_byte(s >> 8);                     // 24 byte address
    spi_write_byte(s & 255);
    spi_write_byte(s & 255);
    spi_write_byte(0);
    spi_write_byte(0);
    spi_clocks(8);                              // 8 dummy clocks
    spi_clocks(8);                              // 8 dummy clocks
    return 0;
    return 0;
}
}
 
 
/* *********************************************************************
/* *********************************************************************
   ***** flash_read_next ***********************************************
   ***** flash_read_next ***********************************************
   ********************************************************************* */
   ********************************************************************* */
/*
/*
   dummy function for compatibilty
   dummy function for compatibilty
*/
*/
BYTE flash_read_next() {
BYTE flash_read_next() {
    return 0;
    return 0;
}
}
 
 
 
 
/* *********************************************************************
/* *********************************************************************
   ***** flash_read_finish *********************************************
   ***** flash_read_finish *********************************************
   ********************************************************************* */
   ********************************************************************* */
/*
/*
    Runs the finalization sequence for the read operation.
    Runs the finalization sequence for the read operation.
*/
*/
void flash_read_finish(WORD n) {
void flash_read_finish(WORD n) {
   n;                                   // avoids warnings
   n;                                   // avoids warnings
   spi_deselect();
   spi_deselect();
}
}
 
 
 
 
/* *********************************************************************
/* *********************************************************************
   ***** spi_pp ********************************************************
   ***** spi_pp ********************************************************
   ********************************************************************* */
   ********************************************************************* */
BYTE spi_pp () {
BYTE spi_pp () {
    spi_deselect();                             // finish previous write cmd
    spi_deselect();                             // finish previous write cmd
 
 
    spi_need_pp = 0;
    spi_need_pp = 0;
 
 
    if ( spi_wait() ) {
    if ( spi_wait() ) {
        return flash_ec;
        return flash_ec;
    }
    }
    spi_start_cmd(0x06);                        // write enable command
    spi_start_cmd(0x06);                        // write enable command
    spi_deselect();
    spi_deselect();
 
 
    spi_start_cmd(0x02);                        // page write
    spi_start_cmd(0x02);                        // page write
    spi_write_byte(spi_write_addr_hi >> 8);     // 24 byte address
    spi_write_byte(spi_write_addr_hi >> 8);     // 24 byte address
    spi_write_byte(spi_write_addr_hi & 255);
    spi_write_byte(spi_write_addr_hi & 255);
    spi_write_byte(0);
    spi_write_byte(0);
    return 0;
    return 0;
}
}
 
 
 
 
/* *********************************************************************
/* *********************************************************************
   ***** flash_write_byte **********************************************
   ***** flash_write_byte **********************************************
   ********************************************************************* */
   ********************************************************************* */
BYTE flash_write_byte (BYTE b) {
BYTE flash_write_byte (BYTE b) {
    if ( spi_need_pp && spi_pp() ) return flash_ec;
    if ( spi_need_pp && spi_pp() ) return flash_ec;
    spi_write_byte(b);
    spi_write_byte(b);
    spi_write_addr_lo++;
    spi_write_addr_lo++;
    if ( spi_write_addr_lo == 0 ) {
    if ( spi_write_addr_lo == 0 ) {
        spi_write_addr_hi++;
        spi_write_addr_hi++;
        spi_deselect();                         // finish write cmd
        spi_deselect();                         // finish write cmd
        spi_need_pp = 1;
        spi_need_pp = 1;
    }
    }
    return 0;
    return 0;
}
}
 
 
 
 
/* *********************************************************************
/* *********************************************************************
   ***** flash_write ***************************************************
   ***** flash_write ***************************************************
   ********************************************************************* */
   ********************************************************************* */
// write len (256 if len=0) bytes from the buffer to the flash
// write len (256 if len=0) bytes from the buffer to the flash
BYTE flash_write(__xdata BYTE *buf, BYTE len) {
BYTE flash_write(__xdata BYTE *buf, BYTE len) {
    BYTE b;
    BYTE b;
    if ( spi_need_pp && spi_pp() ) return flash_ec;
    if ( spi_need_pp && spi_pp() ) return flash_ec;
 
 
    if ( spi_write_addr_lo == 0 ) {
    if ( spi_write_addr_lo == 0 ) {
        spi_write(buf,len);
        spi_write(buf,len);
    }
    }
    else {
    else {
        b = (~spi_write_addr_lo) + 1;
        b = (~spi_write_addr_lo) + 1;
        if ( len==0 || len>b ) {
        if ( len==0 || len>b ) {
            spi_write(buf,b);
            spi_write(buf,b);
            len-=b;
            len-=b;
            spi_write_addr_hi++;
            spi_write_addr_hi++;
            spi_write_addr_lo=0;
            spi_write_addr_lo=0;
            buf+=b;
            buf+=b;
            if ( spi_pp() ) return flash_ec;
            if ( spi_pp() ) return flash_ec;
        }
        }
        spi_write(buf,len);
        spi_write(buf,len);
    }
    }
 
 
    spi_write_addr_lo+=len;
    spi_write_addr_lo+=len;
 
 
    if ( spi_write_addr_lo == 0 ) {
    if ( spi_write_addr_lo == 0 ) {
        spi_write_addr_hi++;
        spi_write_addr_hi++;
        spi_deselect();                         // finish write cmd
        spi_deselect();                         // finish write cmd
        spi_need_pp = 1;
        spi_need_pp = 1;
    }
    }
 
 
    return 0;
    return 0;
}
}
 
 
 
 
/* *********************************************************************
/* *********************************************************************
   ***** 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 will be modified
   The whole sector will be modified
   returns an error code (FLASH_EC_*). 0 means no error.
   returns an error code (FLASH_EC_*). 0 means no error.
*/
*/
BYTE flash_write_init(WORD s) {
BYTE flash_write_init(WORD s) {
    if ( !SPI_CS ) {
    if ( !SPI_CS ) {
        flash_ec = FLASH_EC_PENDING;
        flash_ec = FLASH_EC_PENDING;
        return FLASH_EC_PENDING;                // we interrupted a pending Flash operation
        return FLASH_EC_PENDING;                // we interrupted a pending Flash operation
    }
    }
 
    OESPI_OPORT &= ~bmBITSPI_BIT_DO;
 
    OESPI_PORT |= bmBITSPI_BIT_CS | bmBITSPI_BIT_DI | bmBITSPI_BIT_CLK;
    if ( spi_wait() ) {
    if ( spi_wait() ) {
        return flash_ec;
        return flash_ec;
    }
    }
    spi_write_sector = s;
    spi_write_sector = s;
    s = s << ((BYTE)flash_sector_size - 8);
    s = s << ((BYTE)flash_sector_size - 8);
    spi_write_addr_hi = s;
    spi_write_addr_hi = s;
    spi_write_addr_lo = 0;
    spi_write_addr_lo = 0;
 
 
    spi_start_cmd(0x06);                        // write enable command
    spi_start_cmd(0x06);                        // write enable command
    spi_deselect();
    spi_deselect();
 
 
    spi_start_cmd(spi_erase_cmd);               // erase command
    spi_start_cmd(spi_erase_cmd);               // erase command
    spi_write_byte(s >> 8);                     // 24 byte address
    spi_write_byte(s >> 8);                     // 24 byte address
    spi_write_byte(s & 255);
    spi_write_byte(s & 255);
    spi_write_byte(0);
    spi_write_byte(0);
    spi_deselect();
    spi_deselect();
 
 
    spi_need_pp = 1;
    spi_need_pp = 1;
    return 0;
    return 0;
}
}
 
 
 
 
/* *********************************************************************
/* *********************************************************************
   ***** flash_write_finish_sector *************************************
   ***** flash_write_finish_sector *************************************
   ********************************************************************* */
   ********************************************************************* */
/*
/*
   Dummy function for compatibilty.
   Dummy function for compatibilty.
*/
*/
BYTE flash_write_finish_sector (WORD n) {
BYTE flash_write_finish_sector (WORD n) {
    n;
    n;
    spi_deselect();
    spi_deselect();
    return 0;
    return 0;
}
}
 
 
 
 
/* *********************************************************************
/* *********************************************************************
   ***** flash_write_finish ********************************************
   ***** flash_write_finish ********************************************
   ********************************************************************* */
   ********************************************************************* */
/*
/*
   Dummy function for compatibilty.
   Dummy function for compatibilty.
*/
*/
void flash_write_finish () {
void flash_write_finish () {
    spi_deselect();
    spi_deselect();
}
}
 
 
 
 
/* *********************************************************************
/* *********************************************************************
   ***** flash_write_next **********************************************
   ***** flash_write_next **********************************************
   ********************************************************************* */
   ********************************************************************* */
/*
/*
   Prepare the next sector for writing, see flash_write_finish1.
   Prepare the next sector for writing, see flash_write_finish1.
*/
*/
BYTE flash_write_next () {
BYTE flash_write_next () {
    spi_deselect();
    spi_deselect();
    return flash_write_init(spi_write_sector+1);
    return flash_write_init(spi_write_sector+1);
}
}
 
 
 
 
/* *********************************************************************
/* *********************************************************************
   ***** flash_init ****************************************************
   ***** flash_init ****************************************************
   ********************************************************************* */
   ********************************************************************* */
// init the flash
// init the flash
void flash_init() {
void flash_init() {
    BYTE i;
    BYTE i;
 
 
    PORTCCFG = 0;
    PORTCCFG = 0;
 
 
    flash_enabled = 1;
    flash_enabled = 1;
    flash_ec = 0;
    flash_ec = 0;
    flash_sector_size = 0x8010;  // 64 KByte
    flash_sector_size = 0x8010;  // 64 KByte
    spi_erase_cmd = 0xd8;
    spi_erase_cmd = 0xd8;
 
 
    OESPI_OPORT &= ~bmBITSPI_BIT_DO;
    OESPI_OPORT &= ~bmBITSPI_BIT_DO;
    OESPI_PORT |= bmBITSPI_BIT_CS | bmBITSPI_BIT_DI | bmBITSPI_BIT_CLK;
    OESPI_PORT |= bmBITSPI_BIT_CS | bmBITSPI_BIT_DI | bmBITSPI_BIT_CLK;
    SPI_CS = 1;
    SPI_CS = 1;
    spi_clocks(0);                               // 256 clocks
    spi_clocks(0);                               // 256 clocks
 
 
    spi_start_cmd(0x90);                        // CMD 90h, not supported by all chips
    spi_start_cmd(0x90);                        // CMD 90h, not supported by all chips
    spi_clocks(24);                             // ADDR=0
    spi_clocks(24);                             // ADDR=0
    spi_device = flash_read_byte();
    spi_device = flash_read_byte();
    spi_deselect();                             // deselect
    spi_deselect();                             // deselect
 
 
    spi_start_cmd(0x9F);                        // CMD 9Fh
    spi_start_cmd(0x9F);                        // CMD 9Fh
    flash_read(spi_buffer,3);                   // read data
    flash_read(spi_buffer,3);                   // read data
    spi_deselect();                             // deselect
    spi_deselect();                             // deselect
    if ( spi_buffer[2]<16 || spi_buffer[2]>24 ) {
    if ( spi_buffer[2]<16 || spi_buffer[2]>24 ) {
        goto  disable;
        goto  disable;
    }
    }
    spi_vendor = spi_buffer[0];
    spi_vendor = spi_buffer[0];
    spi_memtype = spi_buffer[1];
    spi_memtype = spi_buffer[1];
 
 
#ifeq[USE_4KSECTORS_ENABLED][1]
#ifeq[USE_4KSECTORS_ENABLED][1]
    if ( ( spi_vendor==1 && spi_memtype == 0x40 ) ||
    if ( ( spi_vendor==1 && spi_memtype == 0x40 ) ||
         ( spi_vendor==0x20 && spi_memtype == 0xba )
         ( spi_vendor==0x20 && spi_memtype == 0xba )
       ) {
       ) {
        // support of uniform 4 kbyte (logical) sectors
        // support of uniform 4 kbyte (logical) sectors
        flash_sector_size = 0x800C;  // 4 KByte
        flash_sector_size = 0x800C;  // 4 KByte
        spi_erase_cmd = 0x20;
        spi_erase_cmd = 0x20;
        i=spi_buffer[2]-12;
        i=spi_buffer[2]-12;
    }
    }
    else {
    else {
        // support of uniform 64 kbyte (logical) sectors
        // support of uniform 64 kbyte (logical) sectors
        i=spi_buffer[2]-16;
        i=spi_buffer[2]-16;
    }
    }
#else    
#else    
    i=spi_buffer[2]-16;
    i=spi_buffer[2]-16;
#endif    
#endif    
    flash_sectors = 1 << i;
    flash_sectors = 1 << i;
 
 
    return;
    return;
 
 
disable:
disable:
    flash_enabled = 0;
    flash_enabled = 0;
    flash_ec = FLASH_EC_NOTSUPPORTED;
    flash_ec = FLASH_EC_NOTSUPPORTED;
    OESPI_PORT &= ~( bmBITSPI_BIT_CS | bmBITSPI_BIT_DI | bmBITSPI_BIT_CLK );
    OESPI_PORT &= ~( bmBITSPI_BIT_CS | bmBITSPI_BIT_DI | bmBITSPI_BIT_CLK );
}
}
 
 
 
 
/* *********************************************************************
/* *********************************************************************
   ***** EP0 vendor request 0x40 ***************************************
   ***** EP0 vendor request 0x40 ***************************************
   ********************************************************************* */
   ********************************************************************* */
// send flash information structure (card size, error status,  ...) to the host
// send flash information structure (card size, error status,  ...) to the host
ADD_EP0_VENDOR_REQUEST((0x40,,
ADD_EP0_VENDOR_REQUEST((0x40,,
    if ( flash_ec == 0 && SPI_CS == 0 ) {
    if ( flash_ec == 0 && SPI_CS == 0 ) {
        flash_ec = FLASH_EC_PENDING;
        flash_ec = FLASH_EC_PENDING;
    }
    }
    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 ***************************************
   ********************************************************************* */
   ********************************************************************* */
/* read modes (ep0_read_mode)
/* read modes (ep0_read_mode)
        0: start read
        0: start read
        1: continue read
        1: continue read
        2: finish read
        2: finish read
*/
*/
void spi_read_ep0 () {
void spi_read_ep0 () {
    flash_read(EP0BUF, ep0_payload_transfer);
    flash_read(EP0BUF, ep0_payload_transfer);
    if ( ep0_read_mode==2 && ep0_payload_remaining==0 ) {
    if ( ep0_read_mode==2 && ep0_payload_remaining==0 ) {
        spi_deselect();
        spi_deselect();
    }
    }
}
}
 
 
ADD_EP0_VENDOR_REQUEST((0x41,,                  // read data
ADD_EP0_VENDOR_REQUEST((0x41,,                  // read data
    ep0_read_mode = SETUPDAT[5];
    ep0_read_mode = SETUPDAT[5];
    if ( (ep0_read_mode==0) && flash_read_init((SETUPDAT[3] << 8) | SETUPDAT[2]) ) {
    if ( (ep0_read_mode==0) && flash_read_init((SETUPDAT[3] << 8) | SETUPDAT[2]) ) {
        EP0_STALL;
        EP0_STALL;
    }
    }
    spi_read_ep0();
    spi_read_ep0();
    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;
        spi_read_ep0();
        spi_read_ep0();
    }
    }
    EP0BCH = 0;
    EP0BCH = 0;
    EP0BCL = ep0_payload_transfer;
    EP0BCL = ep0_payload_transfer;
));;
));;
 
 
/* *********************************************************************
/* *********************************************************************
   ***** EP0 vendor command 0x42 ***************************************
   ***** EP0 vendor command 0x42 ***************************************
   ********************************************************************* */
   ********************************************************************* */
void spi_send_ep0 () {
void spi_send_ep0 () {
    flash_write(EP0BUF, ep0_payload_transfer);
    flash_write(EP0BUF, ep0_payload_transfer);
    if ( ep0_write_mode==2 && ep0_payload_remaining==0 ) {
    if ( ep0_write_mode==2 && ep0_payload_remaining==0 ) {
        spi_deselect();
        spi_deselect();
    }
    }
}
}
 
 
ADD_EP0_VENDOR_COMMAND((0x42,,                  // write integer number of sectors
ADD_EP0_VENDOR_COMMAND((0x42,,                  // write integer number of sectors
    ep0_write_mode = SETUPDAT[5];
    ep0_write_mode = SETUPDAT[5];
    if ( (ep0_write_mode == 0) && flash_write_init((SETUPDAT[3] << 8) | SETUPDAT[2]) ) {
    if ( (ep0_write_mode == 0) && flash_write_init((SETUPDAT[3] << 8) | SETUPDAT[2]) ) {
        EP0_STALL;
        EP0_STALL;
    }
    }
,,
,,
    if ( ep0_payload_transfer != 0 ) {
    if ( ep0_payload_transfer != 0 ) {
        flash_ec = 0;
        flash_ec = 0;
        spi_send_ep0();
        spi_send_ep0();
        if ( flash_ec != 0 ) {
        if ( flash_ec != 0 ) {
            spi_deselect();
            spi_deselect();
            EP0_STALL;
            EP0_STALL;
        }
        }
    }
    }
));;
));;
 
 
/* *********************************************************************
/* *********************************************************************
   ***** EP0 vendor request 0x43 ***************************************
   ***** EP0 vendor request 0x43 ***************************************
   ********************************************************************* */
   ********************************************************************* */
// send detailed SPI status plus debug information
// send detailed SPI status plus debug information
ADD_EP0_VENDOR_REQUEST((0x43,,
ADD_EP0_VENDOR_REQUEST((0x43,,
    MEM_COPY1(flash_ec,EP0BUF,10);
    MEM_COPY1(flash_ec,EP0BUF,10);
    EP0BCH = 0;
    EP0BCH = 0;
    EP0BCL = 10;
    EP0BCL = 10;
,,
,,
));;
));;
 
 
 
 

powered by: WebSVN 2.1.0

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