⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intelsbdrv.c

📁 是一个手机功能的模拟程序
💻 C
字号:
/******************************************************************************
 * Flash File System (ffs)
 * Idea, design and coding by Mads Meisner-Jensen, mmj@ti.com
 *
 * FFS AMD single bank low level flash driver RAM code
 *
 * $Id: intelsbdrv.c,v 1.1.1.1 2004/06/19 06:00:30 root Exp $
 *
 ******************************************************************************/

#include "ffs.cfg"

#include "ffs.h"
#include "drv.h"
#include "ffstrace.h"


#define INTEL_UNLOCK_SLOW 1


#undef  tlw
#define tlw(contents)
#undef  ttw
#define ttw(contents)

// Status bits for Intel flash memory devices
#define INTEL_STATE_MACHINE_DONE     (1<<7)
#define FLASH_READ(addr)        (*(volatile uint16 *) (addr))
#define FLASH_WRITE(addr, data) (*(volatile uint16 *) (addr)) = data

asm("        .label _ffsdrv_ram_intel_begin");
asm("        .def   _ffsdrv_ram_intel_begin");

uint32 intel_int_disable(void);
void intel_int_enable(uint32 tmp);

/******************************************************************************
 * INTEL Single Bank Driver Functions
 ******************************************************************************/
// Actual we should have disabled and enable the interrupts in this
// function, but when the interrupt functions are used ffs don't run!
// Anyway, currently the interrupts are already disabled ad this point thus
// it dos not cause any problems.
int ffsdrv_ram_intel_sb_init(void)
{
    uint32 cpsr, i;
    volatile char *addr;
	uint16 status;

    for (i = 0; i < dev.numblocks; i++)
    {
        addr = block2addr(i);
      
        *addr = 0x50; // Intel Clear Status Register
        *addr = 0xFF; // Intel read array

        *addr = 0x60; // Intel Config Setup
        *addr = 0xD0; // Intel Unlock Block

		// Wait for unlock to finish
		do {
            status = FLASH_READ(addr);
        } while (!(status & INTEL_STATE_MACHINE_DONE));

		*addr = 0x70; // Intel Read Status Register
		status = FLASH_READ(addr);
		
		// Is there an erase suspended?
		if ((status & 0x40) != 0) {
			*addr = 0xD0; // Intel erase resume

			*addr = 0x70; // Intel Read Status Register
			// wait for erase to finish
			do {
				status = FLASH_READ(addr);
			} while (!(status & INTEL_STATE_MACHINE_DONE));
		}

        *addr = 0xFF; // Intel Read Array
    }

    return 0;
}

void ffsdrv_ram_intel_sb_write_halfword(volatile uint16 *addr, uint16 value)
{
    uint32 cpsr;

    ttw(ttr(TTrDrv, "wh(%x,%x)" NL, addr, value));

    if (~*addr & value) {
        ttw(ttr(TTrFatal, "wh(%x,%x->%x) fatal" NL, addr, *addr, value));
        return;
    }

    cpsr = intel_int_disable();
    tlw(led_on(LED_WRITE));

#if (INTEL_UNLOCK_SLOW == 1)
    *addr = 0x60; // Intel Config Setup
    *addr = 0xD0; // Intel Unlock Block
#endif

    *addr = 0x50; // Intel Clear Status Register
    *addr = 0x40; // Intel program byte/word
    *addr = value;
    while ((*addr & 0x80) == 0)
        ;
    *addr = 0xFF; // Intel read array
    tlw(led_off(LED_WRITE));
    intel_int_enable(cpsr);
}

void ffsdrv_ram_intel_sb_erase(uint8 block)
{
    volatile char *addr;
    uint32 cpsr;
    uint16 poll;

    ttw(ttr(TTrDrvEra, "e(%d)" NL, block));

    addr = block2addr(block);

    cpsr = intel_int_disable();
    tlw(led_on(LED_ERASE));

#if (INTEL_UNLOCK_SLOW == 1)
    *addr = 0x60; // Intel Config Setup
    *addr = 0xD0; // Intel Unlock Block
#endif

    *addr = 0x50; // Intel Clear Status Register
    *addr = 0x20; // Intel Erase Setup
    *addr = 0xD0; // Intel Erase Confirm
	*addr = 0x70; // Intel Read Status Register

    // Wait for erase to finish.
    while ((*addr & 0x80) == 0) {
        tlw(led_toggle(LED_ERASE));
        // Poll interrupts, taking interrupt mask into account.
        if (INT_REQUESTED)
        {
            // 1. suspend erase
            // 2. enable interrupts
            // .. now the interrupt code executes
            // 3. disable interrupts
            // 4. resume erase

            tlw(led_on(LED_ERASE_SUSPEND));

            *addr = 0xB0; // Intel Erase Suspend
            *addr = 0x70; // Intel Read Status Register
            while (((poll = *addr) & 0x80) == 0)
                ;
            
            // If erase is complete, exit immediately
            if ((poll & 0x40) == 0)
                break;

            *addr = 0xFF; // Intel read array

            tlw(led_off(LED_ERASE_SUSPEND));
            intel_int_enable(cpsr);

            // Other interrupts and tasks run now...

            cpsr = intel_int_disable();
            tlw(led_on(LED_ERASE_SUSPEND));

            *addr = 0xD0; // Intel erase resume

// The following "extra" Read Status command is required because Intel has
// changed the specification of the W30 flash! (See "1.8 Volt Intel?// Wireless Flash Memory with 3 Volt I/O 28F6408W30, 28F640W30, 28F320W30
// Specification Update")
			*addr = 0x70; // Intel Read Status Register

            tlw(led_off(LED_ERASE_SUSPEND));
        }
    }
    *addr = 0xFF; // Intel read array

    tlw(led_on(LED_ERASE));
    tlw(led_off(LED_ERASE));
    intel_int_enable(cpsr);
}

// TODO: remove below function, not in use anymore.
void ffsdrv_ram_intel_erase(uint8 block) 
{
    uint32 cpsr;
    uint16 status;

    ttw(ttr(TTrDrvErase, "e(%d)" NL, block));
    tlw(led_on(LED_ERASE));

    dev.addr = (uint16 *) block2addr(block);

    cpsr = intel_int_disable();
    dev.state = DEV_ERASE;

    *dev.addr = 0x60; // Intel Config setup
    *dev.addr = 0xD0; // Intel Unlock block

    *dev.addr = 0x50; // Intel clear status register (not really necessary)
    *dev.addr = 0x20; // Intel erase setup
    *dev.addr = 0xD0; // Intel erase confirm

    intel_int_enable(cpsr);

    while ((*dev.addr & 0x80) == 0)
        ;

    *dev.addr = 0xFF; // Intel read array
    dev.state = DEV_READ;
    tlw(led_off(LED_WRITE));
}


/******************************************************************************
 * Interrupt Enable/Disable
 ******************************************************************************/

uint32 intel_int_disable(void)
{
    asm("        .state16");
    asm("        mov       A1, #0xC0");
    asm("        ldr       A2, tct_intel_disable");
    asm("        bx        A2      ");

    asm("tct_intel_disable 	.field     _TCT_Control_Interrupts+0,32");
    asm("	                .global	   _TCT_Control_Interrupts");
}

void intel_int_enable(uint32 cpsr)
{
    asm("        .state16");
    asm("        ldr       A2, tct_intel_enable");
    asm("        bx        A2      ");

    asm("tct_intel_enable 	.field     _TCT_Control_Interrupts+0,32");
    asm("	                .global	   _TCT_Control_Interrupts");
}

// Even though we have this end label, we cannot determine the number of
// constant/PC-relative data following the code!
asm("        .state32");
asm("        .label _ffsdrv_ram_intel_end");
asm("        .def   _ffsdrv_ram_intel_end");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -