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

📄 drv.c

📁 MMI层OBJ不能完全编译
💻 C
📖 第 1 页 / 共 5 页
字号:
   cpsr=int_disable();
   /*LOCOSTO-Live Unlock Fix */
   flash[0]=0x0f0;
   flash[0]= 0x0060; // sector unlock sequence
   flash[0]= 0x0060; // sector unlock sequence
   flash[unlockOffset]= 0x0060; // sector unlock sequence (address 6 = VIH)
   flash[0]=0x0f0;

   /* sector erase command -- 6 cycles */
   flash[0x555] =0xAA;
   flash[0x2AA]=0x55;
   flash[0x555]=0x80;
   flash[0x555]= 0xAA;
   flash[0x2AA]=0x55;
   *((volatile uint16*)(dev.addr))=0x30;   /* write the command to sector address */

   /* Enable the interrupts */
 //CQ62129 start - new while loop added

 // delay re-enabling until after sector erased or we have an int to service

 /* Wait for the erase to complete  */
 while ((*dev.addr & 0x80) == 0)   /* DQ7 will have 1 on completion of erase */  /* Data polling */
 // add option to suspend if a frame interrupt occurs, same as old AMD single bank driver

 {  	 // Poll interrupts, taking interrupt mask into account and check if IRQ was actually enabled
        if ((INT_REQUESTED) && !(cpsr & ~0x80))
        {
            // 1. suspend erase
            // 2. enable interrupts
            // .. now the interrupt code executes
            // 3. disable interrupts
            // 4. resume erase

            // Suspend erase
            *((volatile uint16*)(dev.addr)) = 0xB0;

            // wait for erase suspend to finish
            while ((*((volatile uint16*)(dev.addr)) & 0x80) == 0);

            dev.state = DEV_ERASE_SUSPEND;


   int_enable(cpsr);

            // Other interrupts and tasks run now...

            cpsr=int_disable();

             // Before resuming erase we must? check if the erase is really
            // suspended or if it did finish
            *((volatile uint16*)(dev.addr)) = 0x30;
            dev.state = DEV_ERASE;

        }





 }
 int_enable(cpsr);
//CQ62129 end

 ttw(ttr(TTrDrvErase, "}" NL));

 /* change the device state  to default READ mode */
    dev.state=DEV_READ;

}

void ffsdrv_amd_fg_write_suspend(void)
{
    OS_LOCK_MUTEX(&ffs_write_mutex);

    /* Got the Mutex Write Got over */
    OS_UNLOCK_MUTEX(&ffs_write_mutex);
}

void ffsdrv_amd_mb_write_halfword(volatile uint16 *addr, uint16 value)
{
    volatile uint16 *flash = (volatile uint16*)dev.base;
    uint32 cpsr;
	uint8 * offset;
	uint32 unlockOffset;
	static int badFlashCount=0;
	unsigned short temp1;

   offset = (uint8*)addr - (uint32)(dev.base);
   unlockOffset = (dev.binfo[offset2block(offset)].offset+ 0x80)>>1;

   /* device state is write state */
   OS_LOCK_MUTEX(&ffs_write_mutex);
   dev.state=DEV_WRITE;
    /* Dissable the interrupts */
   cpsr=int_disable();

	
	temp1 = (*addr);
redowrite:
   flash[0]=0x0f0;

    /* two unlock cycles */
   flash[0x555]=0xAA;
   flash[0x2AA]=0x55;

   /* issue the program command now */
   flash[0x555]=0xA0;

   dev.addr=addr;    /* record the last write */
   dev.data=value;

   *addr = value;   /* this will be base+offset */

   /* Enable the interrupts */

   int_enable(cpsr);

   /* Wait for the write to complete */
   while (1)
   {
   		unsigned short temp= (*addr);
		badFlashCount++;
		if(!((temp ^ dev.data) & 0x80))
			break;
		else if ((temp & 0x20))
		{
			 if((((*addr) ^ dev.data) & 0x80))
			 	goto redowrite;
			 break;
		}
		else
			continue;
   }/* Data polling */

   /* change the state to default read mode */
   dev.state=DEV_READ;

   OS_UNLOCK_MUTEX(&ffs_write_mutex);

}

void ffsdrv_amd_mb_write(void *dst, const void *src, uint16 size)
{
    uint8 *mydst = dst;
    const uint8 *mysrc = src;

    if (size > 0)
    {
        if ((unsigned int) mydst & 1) {
            ffsdrv_write_byte(mydst++, *mysrc++);
            size--;
        }
        while (size >= 2) {
            ffsdrv_amd_mb_write_halfword((uint16 *) mydst,
                                      mysrc[0] | (mysrc[1] << 8));
            size -= 2;
            mysrc += 2;
            mydst += 2;
        }
        if (size == 1)
            ffsdrv_write_byte(mydst++, *mysrc++);
    }

}




void ffsdrv_amd_mb_erase(uint8 block)
{
    volatile uint16 *flash = (volatile uint16*)dev.base;
    uint32 cpsr;
	uint32 unlockOffset;

    dev.addr = (uint16 *) block2addr(block);
    unlockOffset = ((uint32)(dev.addr)-(uint32)(dev.base) + 0x80) >> 1;

    /* change the device status */
    dev.state=DEV_ERASE;

   /* disable the interrupts */
   cpsr=int_disable();

   /* sector erase command -- 6 cycles */
   flash[0x555] =0xAA;
   flash[0x2AA]=0x55;
   flash[0x555]=0x80;
   flash[0x555]= 0xAA;
   flash[0x2AA]=0x55;
   *((volatile uint16*)(dev.addr))=0x30;   /* write the command to (short) sector address */

   /* Enable the interrupts */
 //CQ72069 start - new while loop added

 // delay re-enabling until after sector erased or we have an int to service

 /* Wait for the erase to complete  */
 while ((*dev.addr & 0x80) == 0)   /* DQ7 will have 1 on completion of erase */  /* Data polling */
 // add option to suspend if a frame interrupt occurs, same as old AMD single bank driver

 {  	 // Poll interrupts, taking interrupt mask into account and check if IRQ was actually enabled
        if ((INT_REQUESTED) && !(cpsr & ~0x80))
        {
            // 1. suspend erase
            // 2. enable interrupts
            // .. now the interrupt code executes
            // 3. disable interrupts
            // 4. resume erase

            // Suspend erase
            *((volatile uint16*)(dev.addr)) = 0xB0;

            // wait for erase suspend to finish
            while ((*((volatile uint16*)(dev.addr)) & 0x80) == 0);

            dev.state = DEV_ERASE_SUSPEND;
   		int_enable(cpsr);

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

             // Before resuming erase we must? check if the erase is really
            // suspended or if it did finish
            *((volatile uint16*)(dev.addr)) = 0x30;
            dev.state = DEV_ERASE;

        }
 }
 int_enable(cpsr);
//CQ72069 end

 ttw(ttr(TTrDrvErase, "}" NL));

 /* change the device state  to default READ mode */
    dev.state=DEV_READ;
}

void ffsdrv_amd_mb_erase_sector(void *dst)
{
    volatile uint16 *flash;
    uint32 cpsr;

    dev.addr = (uint16 *) dst;
	flash= dev.addr;

    /* change the device status */
    dev.state=DEV_ERASE;

    OS_LOCK_MUTEX(&ffs_write_mutex);
  /* disable the interrupts */
   cpsr=int_disable();

   /* sector erase command -- 6 cycles */
   flash[0x555] =0xAA;
   flash[0x2AA]=0x55;
   flash[0x555]=0x80;
   flash[0x555]= 0xAA;
   flash[0x2AA]=0x55;
   *((volatile uint16*)(dev.addr))=0x30;   /* write the command to sector address */

   /* Enable the interrupts */
   int_enable(cpsr);

 /* Wait for the erase to complete  */
    while ((*dev.addr & 0x80) == 0);   /* DQ7 will have 1 on completion of erase */  /* Data polling */

 /* change the device state  to default READ mode */
    dev.state=DEV_READ;
 }

void ffsdrv_amd_mb_write_erase_suspend(void)
{
    uint32 cpsr;

    tlw(led_on(LED_ERASE_SUSPEND));
    ttw(str(TTrDrvErase, "es" NL));

    // if erase has finished then all is ok
    if (*dev.addr & 0x80) {
        ffsdrv_amd_erase_end();
        tlw(led_off(LED_ERASE_SUSPEND));
        return;
    }

    // NOTEME: As there is no way to be absolutely certain that erase
    // doesn't finish between last poll and the following erase suspend
    // command, we assume that the erase suspend is safe even though the
    // erase IS actually already finished.

    cpsr = int_disable();
    dev.state = DEV_ERASE_SUSPEND;
    *dev.addr = 0xB0;

    // Wait for erase suspend to finish
    while ((*dev.addr & 0x80) == 0)     /* Enabling the interrupt should be after this while, */
		                                            /* becose DQ7==1 on entering to erase suspend mode */
        ;


    int_enable(cpsr);
}

void ffsdrv_amd_write_erase_resume(void)
{
    uint32 cpsr;

    ttw(str(TTrDrvErase, "er" NL));

    // NOTEME: See note in erase_suspend()... We assume that the erase
    // resume is safe even though the erase IS actually already finished.
    cpsr = int_disable();
    dev.state = DEV_ERASE;
    *dev.addr = 0x30;
    int_enable(cpsr);

    tlw(led_off(LED_ERASE_SUSPEND));
}

void ffsdrv_amd_mb_buffer_write(void *dst, const void *src, uint16 size)
{
    uint8 *mydst = dst;
    const uint8 *mysrc = src;
    uint8 unalignedbytes = 0;	
    uint16 sizeEven;

// use halfword write for size less than 32 bytes	
    if (size <= 32)
    {
        if ((unsigned int) mydst & 1) {
            ffsdrv_write_byte(mydst++, *mysrc++);
            size--;
        }
	while (size >= 2) 
	{
            ffsdrv_amd_mb_write_halfword((uint16 *) mydst, mysrc[0] | (mysrc[1] << 8));
	            size -= 2;
	            mysrc += 2;
	            mydst += 2;
	}
	if (size == 1)
	{
		ffsdrv_write_byte(mydst++, *mysrc++);
		size--;
	 }
    }
// If size is more than 32 bytes then go for write buffer feature
    else if (size > 32)
    {
	// if the destination addredd is odd, write first byte in that.
        if ((unsigned int) mydst & 1) {
            ffsdrv_write_byte(mydst++, *mysrc++);
            size--;
        }
	// write unaligned bytes in the write buffer page, since write buffer feature does not allow 
	// write across write buffer boundaries and write can not start in the midded of the write buffer page.
	unalignedbytes = (0x20 - (unsigned int) mydst & 0x0000001F);
	if(unalignedbytes > 0)
	{
	       while (unalignedbytes > 0)
		{
				ffsdrv_amd_mb_write_halfword((uint16 *) mydst, mysrc[0] | (mysrc[1] << 8));
				size -= 2;
				mysrc += 2;
				mydst += 2;
				unalignedbytes -= 2;			
			}
	}

	// Write data using buffer write function
        if (size >=2)
        {
	     // Truncate to an even number of bytes
            sizeEven = size & (uint16) ~1;
	// write the data using write buffer feature
	ffsdrv_amd_mb_buffer_write_new((uint16 *) mydst, mysrc, sizeEven);
		size -=sizeEven;
		mysrc += sizeEven;
		mydst += sizeEven;
		
        }
//	Write Last byte

	if(size==1 )
	{
		ffsdrv_write_byte(mydst++, *mysrc++);
            	size--;
	}
    }
}

void ffsdrv_amd_mb_buffer_write_new(volatile UINT16 *dst_addr, const UINT8 *src_addr, UINT16 size)
{
    volatile uint16 *flash = (volatile uint16*)dev.base;
    volatile UINT16 *dst_ptr; 
    const UINT8 *src_ptr; 
    volatile UINT16 *last_loaded_addr;
    UINT16 write_data;
    UINT32 word_count;
    UINT32 word_size = size >> 1;
    uint32 cpsr;
    static int badFlashCount=0;
	
	dst_ptr=dst_addr;
	src_ptr=src_addr;

OS_LOCK_MUTEX(&ffs_write_mutex);
   dev.state=DEV_WRITE;

   cpsr=int_disable();
       // two unlock cycles
	  flash[0x555]=0xAA;
	   flash[0x2AA]=0x55;
	   // Unlock Bypass
	  flash[0x555]=0x20;
    int_enable(cpsr);
 
    while (word_size >0)
    {
       cpsr=int_disable();
	// maximum 16 words can be written using write buffer
       word_count = 16;		

        if (word_count > word_size)
        {
            word_count = word_size;
        }
        word_size -= word_count;
   
	
	   
   
redowrite_buf:
   	flash[0]=0x0f0;

	/* Write to Buffer Command */
        FLASH_WRITE(dst_ptr, 0x25);

	dev.addr=dst_ptr;
	dev.data=src_ptr[0] | (src_ptr[1] << 8);
		
        /* Write number of locations to program */
        FLASH_WRITE(dst_ptr, word_count - 1);

	
        /* Load data into buffer */
        while (word_count > 0)
        {
            /* Store last loaded address and data value (for polling) */
            last_loaded_addr = dst_ptr;
            write_data = src_ptr[0] | (src_ptr[1] << 8);

            /* Write Data */
		*dst_ptr=write_data;
            dst_ptr++;
            src_ptr +=2;
            word_count--;
        }

        /* Program Buffer to Flash Command */
   

⌨️ 快捷键说明

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