📄 flashdrv.c
字号:
/********************************************************************************* Motorola Inc.* (c) Copyright 2002 Motorola, Inc.* ALL RIGHTS RESERVED.** $Element: $ * $Author: $ * $Revision: $ * $VOB: $ * $OS: $ ** Description: Flash driver for DSP5680x** Notes: *******************************************************************************/#include "port.h"#include "arch.h"#include "arch_off.h"#include "bsp.h"#include "io.h"#include "flashdrv.h"#include "periph.h"#include "string.h"unsigned int UpdatePageContex( handle_t hndl, size_t n_bytes );void mainFlashConfig();char* copyFromBuf( unsigned int off, char* buf, unsigned int len );char* compareWithBuf( unsigned int off, char* buf, unsigned int len );char* copyToBuf( unsigned int off, char* buf, unsigned int len ); // char* copyToBuf( struct sflashDesc* hndl, char* buf, unsigned int len );union s_flash_tmp_buf{ unsigned char buf8[9]; unsigned int buf16[PAGE_SIZE_IN_WORDS]; /* temporary buffer */ unsigned int bufp16[PAGE_SIZE_P_IN_WORDS]; /* for p: */ unsigned long buf32[1];};union s_flash_tmp_buf flash_tmp_buf= {0};/* define temporary buffer for flash operations */ssize_t flashPCompare( handle_t hndl, const void * pBuffer, size_t n_bytes ){#if __m56800E_lmm__ asm(move.w A0,A); asm(move.w A1,Y0);#else asm(nop); asm(nop);#endif asm( move.w Y0, N ); asm( move.l X:(R2 + sFlash_offset_seek), A ); /* P byte address */ asm( asr A ); asm( move.l A10, R1 ); asm( bcc skip_odd_first ); asm( move.w P:(R1)+, X0 ); asm( asrr.w #8, X0 ); asm( dec.w Y0 ); /* update length */ asm( moveu.bp X:(R3)+, Y1 ); asm( cmp.b X0, Y1 ); asm( bne no_compare );skip_odd_first: asm( asr Y0 ); /* shift off to first words */ asm( rol.w A ); /* C ->B1:0 */ asm( do Y0, enddo ); asm( moveu.bp X:(R3)+, X0 ); asm( moveu.bp X:(R3)+, Y1 ); asm( asll.w #8, Y1 ); asm( or.w X0, Y1 ); asm( move.w P:(R1)+, X0 ); asm( cmp.w X0, Y1 ); asm( beq continue_compare ); asm( enddo ); asm( bra no_compare );continue_compare: asm( nop ); /* 1 nop needed ? */ asm( nop );enddo: asm( brclr #0x0001, A1, skip_odd_last ); asm( move.w P:(R1)+, X0 ); asm( moveu.bp X:(R3)+, Y1 ); asm( cmp.b X0, Y1 ); asm( bne no_compare );skip_odd_last: asm( move.w N, Y0 );#if __m56800E_lmm__ asm(move.w Y0,A0); asm(clr.w A1);#else asm(nop); asm(nop);#endif asm( rts);no_compare:#if __m56800E_lmm__ asm(move.l #0xFFFFFFFF,A); asm(clr.w A1);#else asm( move.w #0xFFFF, Y0 ); asm(nop);#endif}/****************************************************************************** Module: ioctlFLASH_RAW_WRITE_PMEM* Description: write page from internal buffer* Arguments: page number* Range Issues: * Special Issues: *****************************************************************************/unsigned long LongReg;ssize_t flashFastWrite(handle_t hndl, const void * pBuffer, size_t n_bytes){#if __m56800E_lmm__ asm(move.w A0,A); asm(move.w A1,Y0);#else asm(nop); asm(nop);#endif asm( move.w #0x0002, X:(BSP_PERIPH_BASE + archoff_Flash_ModuleControlReg) ); /* select P Flash register bank */ asm( move.w #0, X:(BSP_PERIPH_BASE + archoff_Flash_ProtectionReg) ); /* unsecure data flash */ asm( move.w #0, X:(BSP_PERIPH_BASE + archoff_Flash_ProtectionBootReg) ); asm( clr A ); asm( clr B ); asm( move.w Y0, B0 ); asm( tfra R2, R1 ); asm( move.l X:(R1 + sFlash_offset_seek), R4 ); /* B - byte address */ asm( move.w R4, X0 ); /* dword address */ asm( asra R4 ); asm( asra R4 ); asm( asla R4 ); /* word address */ asm( and.w #3, X0 ); asm( move.l #LongReg, R2 ); asm( move.w X0, R0 ); asm( asla R2 ); asm( adda R2, R0, N ); asm( tfra N, R0 ); asm( moveu.w M01, N ); asm( moveu.w #0x3, M01 ); //asm( brclr #0x0003, X0, skip_filling ); /* first step */ asm( bra odd_filling ); /* first enter */loop1: asm( brclr #0x0003, X0, do_filling ); asm( bra skip_filling ); do_filling: asm( move.l LongReg, Y ); /* load -1 */ inc_loop: /* check if CBEIF is set */ asm( brclr #0x80, X:(BSP_PERIPH_BASE + archoff_Flash_UserStatusReg ), inc_loop ); repeat_loop: asm(bfset #0x0300,SR); /* dis isrs!!! */ asm( tfra R4, R2 ); asm( move.w Y0, P:(R2)+ ); /* select data flash programming */ asm( move.w Y1, P:(R2)+ ); /* select data flash programming(2) */ asm( move.w #0x20, X:(BSP_PERIPH_BASE + archoff_Flash_CommandReg) ); /* program command */ asm( move.w #0x80, X:(BSP_PERIPH_BASE + archoff_Flash_UserStatusReg) ); /* clear CBEIF flag */ asm( move.w X:(BSP_PERIPH_BASE + archoff_Flash_UserStatusReg ), Y0 ); asm(bfclr #0x0300,SR); asm( brclr #0x20, Y0, end_PVIOL ); /* wait until PVIOL flag is set */ asm( move.w #0x20, X:(BSP_PERIPH_BASE + archoff_Flash_UserStatusReg) ); /* clear PVIOL flag */ asm( bra repeat_loop ); end_PVIOL: asm( brclr #0x10, Y0, end_ACCERR ); /* wait until ACCERR flag is set */ asm( move.w #0x10, X:(BSP_PERIPH_BASE + archoff_Flash_UserStatusReg) ); /* clear ACCERR flag */ asm( bra repeat_loop ); end_ACCERR: wait_CCIF: /* check if CCIF is set */ asm( brclr #0x40, X:(BSP_PERIPH_BASE + archoff_Flash_UserStatusReg ), wait_CCIF ); asm( adda #2, R4 ); odd_filling: asm( cmp.l A, B ); asm( ble end_loop ); asm( tfra R4, R2 ); asm( move.w P:(R2)+, Y0 ); asm( move.w P:(R2)+, Y1 ); asm( move.l Y, LongReg ); /* load old value */ skip_filling: asm( cmp.l A, B ); asm( ble skip_copy ); asm( moveu.bp X:(R3)+, Y0 ); asm( move.bp Y0, X:(R0)+ ); asm( inc.l A ); /* use len as actual */ skip_copy: asm( inc.w X0 ); asm( bra loop1 );end_loop: asm( move.l X:(R1 + sFlash_offset_seek), B ); /* B - byte address */ asm( add A, B ); asm( move.l B10, X:(R1 + sFlash_offset_seek) ); asm( tfr A, Y );#if __m56800E_lmm__ asm(move.w Y0,A0); asm(clr.w A1);#else asm(nop); asm(nop);#endif asm( moveu.w N, M01 ); /* restore M0 */}/****************************************************************************** Module: copyToBuf* Description: copy to flash driver internal buffer* Returns: modified user buffer pointer* Arguments: offset in flash driver internal buffer* user buffer pointer* user buffer length to copy* Range Issues: * Special Issues: *****************************************************************************/#if 0char* copyToBuf( struct sflashDesc* hndl, char* buf, unsigned int len ){ int lim = hndl->toffs + len; int i; int foundfirst = 0; char tmp; int lastdif = 0; hndl->tdiflen = 0; hndl->tdifoff = 0; hndl->flags &= ~O_ERASE_FLAG; for( i = hndl->toffs; i < lim; i++ ) { if( flash_tmp_buf.buf8[i] != *buf ) { tmp = flash_tmp_buf.buf8[i] ^ *buf; /* transition */ if( *buf & tmp ) /* only flash(0->1) transition required */ { hndl->flags |= O_ERASE_FLAG; } if( !foundfirst ) { foundfirst = 1; hndl->tdifoff = i; } lastdif = i + 1; } flash_tmp_buf.buf8[i] = *buf++; } if( lastdif != 0 ) { hndl->tdiflen = lastdif - hndl->tdifoff; /* calculate real length */ } return buf;}#elsechar* copyToBuf( unsigned int off, char* buf, unsigned int len ){ asm( asr Y0 ); /* shift off to first words */ asm( adda #flash_tmp_buf.buf32, Y0, R3 ); /* load buffer address, c not changed */ asm( bcc skip_odd_first ); asm( move.w X:(R3)+, Y0 ); asm( bfclr #0xFF00, Y0 ); asm( deca R3 ); asm( move.bp X:(R2)+, X0 ); asm( asll.w #8, X0 ); asm( or.w X0, Y0 ); asm( move.w Y0, X:(R3)+ ); /* move first byte to word array */ asm( dec.w Y1 ); /* update length */skip_odd_first: asm( asr Y1 ); /* shift off to first words */ asm( rol.w A ); /* C ->B1:0 */ asm( do Y1, enddo ); asm( moveu.bp X:(R2)+, X0 ); asm( bfclr #0xFF00, X0 ); asm( moveu.bp X:(R2)+, Y0 ); asm( asll.w #8, Y0 ); asm( or.w X0, Y0 ); asm( move.w Y0, X:(R3)+ );enddo: asm( brclr #0x0001, A1, skip_odd_last ); asm( move.w X:(R3)+, X0 ); asm( bfclr #0x00FF, X0 ); asm( deca R3 ); asm( moveu.bp X:(R2)+, Y0 ); asm( bfclr #0xFF00, Y0 ); asm( or.w X0, Y0 ); asm( move.w Y0, X:(R3)+ );skip_odd_last: ;}#endif //0/****************************************************************************** Module: copyFromBuf* Description: copy from flash driver internal buffer* Returns: modified user buffer pointer* Arguments: offset in flash driver internal buffer* user buffer pointer* user buffer length to copy* Range Issues: * Special Issues: *****************************************************************************/char* copyFromBuf( unsigned int off, char* buf, unsigned int len ){ asm( asr Y0 ); /* shift off to first words */ asm( adda #flash_tmp_buf.buf32, Y0, R3 ); /* load buffer address, c not changed */ asm( bcc skip_odd_first ); asm( move.w X:(R3)+, X0 ); asm( asrr.w #8, X0 ); asm( dec.w Y1 ); /* update length */ asm( move.bp X0, X:(R2)+ );skip_odd_first: asm( asr Y1 ); /* shift off to first words */ asm( rol.w A ); /* C ->B1:0 */ asm( do Y1, enddo ); asm( move.w X:(R3)+, X0 ); asm( move.w X0, Y0 ); asm( asrr.w #8, X0 ); asm( move.bp Y0, X:(R2)+ ); asm( move.bp X0, X:(R2)+ ); asm( nop ); /* needed nops ? */ asm( nop );enddo: asm( brclr #0x0001, A1, skip_odd_last ); asm( move.w X:(R3)+, X0 ); asm( nop ); asm( nop ); asm( move.bp X0, X:(R2)+ );skip_odd_last: ;}/****************************************************************************** Module: copyFromBuf* Description: copy from flash driver internal buffer* Returns: modified user buffer pointer* Arguments: offset in flash driver internal buffer* user buffer pointer* user buffer length to copy* Range Issues: * Special Issues: *****************************************************************************/char* compareWithBuf( unsigned int off, char* buf, unsigned int len ){ asm( asr Y0 ); /* shift off to first words */ asm( adda #flash_tmp_buf.buf32, Y0, R3 ); /* load buffer address, c not changed */ asm( bcc skip_odd_first ); asm( move.w X:(R3)+, X0 ); asm( asrr.w #8, X0 ); asm( dec.w Y1 ); /* update length */ asm( moveu.bp X:(R2)+, Y0 ); asm( cmp.b X0, Y0 ); asm( bne no_compare );skip_odd_first: asm( asr Y1 ); /* shift off to first words */ asm( rol.w A ); /* C ->B1:0 */ asm( do Y1, enddo ); asm( moveu.bp X:(R2)+, X0 ); asm( moveu.bp X:(R2)+, Y0 ); asm( asll.w #8, Y0 ); asm( or.w X0, Y0 ); asm( move.w X:(R3)+, X0 ); asm( cmp.w X0, Y0 ); asm( beq continue_compare ); asm( enddo ); asm( bra no_compare );continue_compare: asm( nop ); /* 1 nop needed ? */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -