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

📄 intelsbdrv.c

📁 MMI层OBJ不能完全编译
💻 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 1.13 Thu, 08 Jan 2004 15:05:23 +0100 tsj $
 *
 ******************************************************************************/

#ifdef VIRTIO_NOR
#define TARGET 1
#else
#include "ffs.cfg"
#endif

#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
 ******************************************************************************/
// Actually we should have disabled and enable the interrupts in this
// function, but when the interrupt functions are used Target don't run!
// Anyway, currently the interrupts are already disabled at this point thus
// it does not cause any problems.
int ffsdrv_ram_intel_sb_init(void)
{
    uint32 cpsr, i;
    volatile char *addr;
	uint16 status;

    cpsr = intel_int_disable();

    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
    }

    intel_int_enable(cpsr);

    return 0;
}

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

    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();
    dev.state = DEV_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) {
        // Poll interrupts, taking interrupt mask into account.
        if (INT_REQUESTED)
        {
            *addr = 0xB0; // Intel Suspend
            *addr = 0x70; // Intel Read Status Register
            while (((poll = *addr) & 0x80) == 0)
                ;

            // If write is complete, exit immediately
            if ((*addr & 0x04) == 0)
                break;

            dev.state = DEV_WRITE_SUSPEND;
            *addr = 0xFF; // Intel read array

            intel_int_enable(cpsr);
            // Other interrupts and tasks run now...
            cpsr = intel_int_disable();

            *addr = 0xD0; // Intel resume
			*addr = 0x70; // Intel Read Status Register
            dev.state = DEV_WRITE;
        }
    }

    dev.state = DEV_READ;
    *addr = 0xFF; // Intel read array
    intel_int_enable(cpsr);
}

void ffsdrv_ram_intel_sb_erase(uint8 block)
{
    char *addr = block2addr(block);
    ffsdrv.erase_sector(addr);
}

void ffsdrv_ram_intel_sb_erase_sector(void *dst)
{
    volatile char *addr;
    uint32 cpsr;
    uint16 poll;

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

    addr = (char *)dst;

    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

⌨️ 快捷键说明

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