网站公告列表

  没有公告

加入收藏
设为首页
联系站长
您现在的位置: 61IC中国电子在线 >> DSP >> 代码示例 >> ADI DSP代码示例 >> TigerSHARC >> 文章正文
  ADP-TS101 EzFlash示例程序         ★★★ 【字体:
ADP-TS101 EzFlash示例程序
作者:61IC    文章来源:本站原创    点击数:    更新时间:2007-1-16    

///////////////////////////////////////////////////////////////
//
// TS101EzFlash.c
//
// Analog Devices, Inc. - 2002
//
// Rev - 1.00.0
//
// Fixes in this Release
//
//
// Change Log
//
//  1.00.0
//   - initial release
//
// VisualDSP++ "Flash Programmer" flash driver for use with the
// ADSP-TS101S EZ-KIT Lite containing the STMicroelectronics DSM2150
// flash device.
//
// NOTE: In order to use inline assembly the compiler otion
//       -flags-compiler --allow_asm must be added in project options.
//   Also, there are warnings for each line ofinline assembly, which
//       is supposed to be addressed in VisualDSP 3.0 for TigerSHARC.
//   The warnings should not affect the functionality of our driver.
//
///////////////////////////////////////////////////////////////

#include <signal.h>
#include <defts101.h>

// #defines
#define TRUE   0x1
#define FALSE   0x0
#define NULL   0x0
#define BUFFER_SIZE  0x2000

// Flash Programmer commands
#define NO_COMMAND  0
#define GET_CODES  1
#define RESET   2
#define WRITE   3
#define FILL   4
#define ERASE_ALL  5
#define ERASE_SECT  6
#define READ   7
#define GET_SECTNUM  8

// function prototypes
bool SetupForFlash();
bool GetCodes();
bool PollToggleBit(long lOffset, int nValue);
bool ResetFlash();
bool EraseFlash();
bool EraseBlock( int nBlock );
bool UnlockFlash(long lOffset);
bool WriteData( long lStart, long lCount, long lStride, int *pnData );
bool FillData( long lStart, long lCount, long lStride, int *pnData );
bool ReadData( long lStart, long lCount, long lStride, int *pnData );
bool ReadFlash( long lOffset, int *pnValue );
bool WriteFlash( long lOffset, int nValue );
bool GetSectorNumber( long lOffset, int *pnSector );

// used for debugging purposes
bool ReadToInternal(long lOffset, long lCount, long lStride);

// DMA interrupt handler
void dma_int_0( int nothing );

// sets up DMA registers
void do_dma();

// global data for use with the VisualDSP++ plug-in
char AFP_Title[] = "ADSP-TS101 MP SYSTEM";
char AFP_Description[] = "HY. 29LV160";
int AFP_Command = NO_COMMAND;
int AFP_ManCode = -1;    // 0x20 = STMicroelectronics
int AFP_DevCode = -1;    // 0xE8 = DSM2150V
long AFP_Offset = 0x0;
int *AFP_Buffer;
long AFP_Size = BUFFER_SIZE;
long AFP_Count = -1;
long AFP_Stride = -1;
int AFP_NumSectors = 34;
long AFP_SectorSize1 = 0x10000;
int AFP_Sector = -1;

// this is a temporary storage variable
section ("data1") int
temp_stor;

// exit flag
bool bExit = FALSE;

main()
{
 // by making AFP_Buffer as big as possible the plug-in can send and
 // receive more data at a time making the data transfer quicker
 //
 // by allocating it on the heap the compiler does not create an
 // initialized array therefore making the driver image smaller
 // and faster to load
 //
 // we have modified the linker description file (LDF) so that the heap
 // is large enough to store BUFFER_SIZE elements at this point

 AFP_Buffer = (int *)malloc(BUFFER_SIZE);

 // AFP_Buffer will be NULL if we could not allocate storage for the
 // buffer

 // setup the flash so the DSP can access it
 SetupForFlash();

 // command processing loop
 while ( !bExit )
 {
  // the plug-in will set a breakpoint at "AFP_BreakReady" so it knows
  // when we are ready for a new command because the DSP will halt
  //
  // the jump is used so that the label will be part of the debug
  // information in the driver image otherwise it may be left out
  // since the label is not referenced anywhere
  asm("AFP_BreakReady:");
  if ( FALSE )
   asm("jump AFP_BreakReady;;");

  // switch on the command
  switch ( AFP_Command )
  {
   // get manufacturer and device codes
   case GET_CODES:
    GetCodes();
    break;

   // reset
   case RESET:
    ResetFlash();
    break;

   // write
   case WRITE:
    WriteData( AFP_Offset, AFP_Count, AFP_Stride, AFP_Buffer );
    ReadToInternal(AFP_Offset, AFP_Count, AFP_Stride);
    break;

   // fill
   case FILL:
    FillData( AFP_Offset, AFP_Count, AFP_Stride, AFP_Buffer );
    ReadToInternal(AFP_Offset, AFP_Count, AFP_Stride);
    break;

   // erase all
   case ERASE_ALL:
    EraseFlash();
    break;

   // erase sector
   case ERASE_SECT:
    EraseBlock( AFP_Sector );
    break;

   // read
   case READ:
    ReadData( AFP_Offset, AFP_Count, AFP_Stride, AFP_Buffer );
    break;

   // get sector number based on address
   case GET_SECTNUM:
    GetSectorNumber( AFP_Offset, &AFP_Sector );

   // no command or unknown command do nothing
   case NO_COMMAND:
   default:
    break;
  }

  // clear the command
  AFP_Command = NO_COMMAND;
 }

 // free the buffer if we were able to allocate one
 if ( AFP_Buffer )
  free( AFP_Buffer );

 // all done
 return 0;
}


//////////////////////////////////////////////////////////////
// bool SetupForFlash()
//
// Perform necessary setup for the processor to talk to the
// flash such as external memory interface registers, etc.
//
//////////////////////////////////////////////////////////////

bool SetupForFlash()
{
 asm("#include <defines.h>");

 asm("xr0 = IMASKL;;");     // read current value
 asm("xr0 = bset r0 by INTDMA0;;");  // set DMA0 interrupt mask
 asm("IMASKL = xr0;;");     // set new value in IMASKL
 asm("xr0 = IMASKH;;");     // read current value
 asm("xr0 = bset r0 by INTGLOBAL;;"); // set global interrupts
 asm("IMASKH = xr0;;");     // set new value in IMASKH

 interrupt( SIGDMA0, dma_int_0 );  // set DMA interrupt vector

 return TRUE;
}


//////////////////////////////////////////////////////////////
// bool WriteData()
//
// Write a buffer to flash.
//
// Inputs: long lStart - offset in flash to start the writes at
//   long lCount - number of elements to write, in this case bytes
//   long lStride - number of locations to skip between writes
//   int *pnData - pointer to data buffer
//
//////////////////////////////////////////////////////////////

bool WriteData( long lStart, long lCount, long lStride, int *pnData )
{
 long i = 0;    // loop counter
 long lOffset = lStart; // current offset to write

 long temp = 0;

 // write the buffer up to BUFFER_SIZE items
 for (i = 0; (i < lCount) && (i < BUFFER_SIZE); i++, lOffset += lStride)
 {
  // unlock the flash, do the write, and wait for completion
  UnlockFlash( lOffset );
  WriteFlash( lOffset, pnData[i] );
  PollToggleBit( lOffset, pnData[i] );
 }

 // ok
 return TRUE;
}


//////////////////////////////////////////////////////////////
// bool FillData()
//
// Fill flash with a value.
//
// Inputs: long lStart - offset in flash to start the writes at
//   long lCount - number of elements to write, in this case bytes
//   long lStride - number of locations to skip between writes
//   int *pnData - pointer to data buffer
//
//////////////////////////////////////////////////////////////

bool FillData( long lStart, long lCount, long lStride, int *pnData )
{
 long i = 0;    // loop counter
 long lOffset = lStart; // current offset to write

 // fill the value
 for (i = 0; i < lCount; i++, lOffset += lStride)
 {
  // unlock the flash, do the write, and wait for completion
  UnlockFlash( lOffset );
  WriteFlash( lOffset, pnData[0] );
  PollToggleBit( lOffset, pnData[0] );
 }

 // ok
 return TRUE;
}


//////////////////////////////////////////////////////////////
// bool ReadData()
//
// Read a buffer from flash.
//
// Inputs: long lStart - offset in flash to start the reads at
//   long lCount - number of elements to read, in this case bytes
//   long lStride - number of locations to skip between reads
//   int *pnData - pointer to data buffer to fill
//
//////////////////////////////////////////////////////////////

bool ReadData( long lStart, long lCount, long lStride, int *pnData )
{
 long i = 0;    // loop counter
 long lOffset = lStart; // current offset to write

 // read the buffer up to BUFFER_SIZE items
 for (i = 0; (i < lCount) && (i < BUFFER_SIZE); i++, lOffset += lStride)
 {
  // do the read
  ReadFlash( lOffset, &pnData[i] );
 }

 // ok
 return TRUE;
}


//////////////////////////////////////////////////////////////
// bool WriteFlash()
//
// Write a value to an offset in flash.
//
// Inputs: long lOffset - offset to write to
//   int nValue - value to write
//
//////////////////////////////////////////////////////////////

bool WriteFlash( long lOffset, int nValue )
{

 asm("[j31 + _temp_stor] = j5;;"); // put the data into _temp_stor

 asm("xr0 = _temp_stor;;");   // xr0 = source index
 asm("xr1 = 0x00010001;;");   // count = 1, modify = 1
 asm("xr2 = 0x0;;");     // not used
 asm("xr3 = 0x43000000;;");   // int mem,prio=norm,2D=no,word=norm,int=yes,RQ=dsbl,chain=no
 asm("xr4 = j4;;");     // xr4 = destination index
 asm("xr5 = 0x00010001;;");   // count = 1, modify = 1
 asm("xr6 = 0x0;;");     // not used
 asm("xr7 = 0xc3000000;;");   // boot rom,prio=norm,2D=no,word=norm,int=yes,RQ=dsbl,chain=no


 do_dma();       // do dma transfer

 // ok
 return TRUE;
}


//////////////////////////////////////////////////////////////
// bool ReadFlash()
//
// Read a value from an offset in flash.
//
// Inputs: long lOffset - offset to read from
//   int pnValue - pointer to store value read from flash
//
//////////////////////////////////////////////////////////////

bool ReadFlash( long lOffset, int *pnValue )
{
 // temp holder
 int nValue = 0x0;

 asm("xr0 = j4;;");     // xr0 = source index, j4 = nOffset
 asm("xr1 = 0x00010001;;");   // count = 1, modify = 1
 asm("xr2 = 0x0;;");     // not used
 asm("xr3 = 0xc3000000;;");   // boot rom,prio=norm,2D=no,word=norm,int=yes,RQ=dsbl,chain=no
 asm("xr4 = _temp_stor;;");   // xr4 = destination index
 asm("xr5 = 0x00010001;;");   // count = 1, modify = 1
 asm("xr6 = 0x0;;");     // not used
 asm("xr7 = 0x43000000;;");   // int mem,prio=norm,2D=no,word=norm,int=yes,RQ=dsbl,chain=no

 do_dma();

 // put the value at the location passed in
 *pnValue = temp_stor;

 // ok
 return TRUE;
}


//////////////////////////////////////////////////////////////
// bool PollToggleBit()
//
// Polls to see if the value read equals the value written
//
// Inputs: int nOffset - offset to read from
//   int nValue - value of data written
//
//////////////////////////////////////////////////////////////

bool PollToggleBit(long lOffset, int nValue )
{
 bool bError = FALSE; // flag to indicate error

 // read valid address in the range written to
 asm ("POLL_TOGGLE_BIT:");
 asm("xr0 = j4;;");     // xr0 = source index, j4 = lOffset
 asm("xr1 = 0x00010001;;");   // count = 1, modify = 1
 asm("xr2 = 0x0;;");     // not used
 asm("xr3 = 0xc3000000;;");   // boot rom,prio=norm,2D=no,word=norm,int=yes,RQ=dsbl,chain=no
 asm("xr4 = _temp_stor;;");   // xr4 = destination index
 asm("xr5 = 0x00010001;;");   // count = 1, modify = 1
 asm("xr6 = 0x0;;");     // not used
 asm("xr7 = 0x43000000;;");   // int mem,prio=norm,2D=no,word=norm,int=yes,RQ=dsbl,chain=no

 do_dma();       // read the value

 asm("j0 = [j31 + _temp_stor];;"); // get data that was read

 asm("xr0 = j0;;");     // need to be in compute block regs
 asm("xr1 = j5;;");     // put data being set into xr1

 asm("r1 = r0 xor r1;;");   // find out what bits toggled

 // see if the data is toggling
 asm ("BITEST r1 by 7;;");
 asm("if xSEQ, jump DONE_TOGGLE_BIT; nop; nop; nop;;");

 // see if there was an error
 asm ("BITEST r0 by 5;;");
 asm("if xSEQ, jump POLL_TOGGLE_BIT; nop; nop; nop;;");

 // do another read
 asm("xr0 = j4;;");     // xr0 = source index, j4 = lOffset
 asm("xr1 = 0x00010001;;");   // count = 1, modify = 1
 asm("xr2 = 0x0;;");     // not used
 asm("xr3 = 0xc3000000;;");   // boot rom,prio=norm,2D=no,word=norm,int=yes,RQ=dsbl,chain=no
 asm("xr4 = _temp_stor;;");   // xr4 = destination index
 asm("xr5 = 0x00010001;;");   // count = 1, modify = 1
 asm("xr6 = 0x0;;");     // not used
 asm("xr7 = 0x43000000;;");   // int mem,prio=norm,2D=no,word=norm,int=yes,RQ=dsbl,chain=no

 do_dma();       // read the value

 asm("j0 = [j31 + _temp_stor];;"); // get data read

 asm("xr0 = j0;;");     // need to be in compute block regs
 asm("xr1 = j5;;");     // put data being set into xr1

 asm("r1 = r0 xor r1;;");   // find out what bits toggled

 // see if data is still toggling
 asm ("BITEST r1 by 7;;");
 asm("if xSEQ, jump DONE_TOGGLE_BIT; nop; nop; nop;;");

 // else we have failed, restore page, set error flag, and reset
 bError = TRUE;
 ResetFlash();

 asm ("DONE_TOGGLE_BIT:");

 // we can return
 return !bError;
}


//////////////////////////////////////////////////////////////
// bool ResetFlash()
//
// Sends a "reset" command to the flash.
//
//////////////////////////////////////////////////////////////

bool ResetFlash()
{
 // send the reset command to the flash
 WriteFlash( 0x0AAA, 0xf0 );

 // reset should be complete
 return TRUE;
}


//////////////////////////////////////////////////////////////
// bool EraseFlash()
//
// Sends an "erase all" command to the flash.
//
//////////////////////////////////////////////////////////////

bool EraseFlash()
{
 // erase contents in Main Flash Array
 WriteFlash( 0x0aaa, 0xaa );
 WriteFlash( 0x0555, 0x55 );
 WriteFlash( 0x0aaa, 0x80 );
 WriteFlash( 0x0aaa, 0xaa );
 WriteFlash( 0x0555, 0x55 );
 WriteFlash( 0x0aaa, 0x10 );

 // poll until the command has completed
 PollToggleBit(0x0000, 0x80);

 // erase should be complete
 return TRUE;
}


//////////////////////////////////////////////////////////////
// bool EraseBlock()
//
// Sends an "erase block" command to the flash.
//
// Inputs: int nBlock - block to erase
//
//////////////////////////////////////////////////////////////

bool EraseBlock( int nBlock )
{
 long lSectorOff = 0x0;

 // if the block is invalid just return
 if ( (nBlock < 0) || (nBlock > AFP_NumSectors) )
  return FALSE;

 // block is in valid Flash Array
 if ( (nBlock >= 0) && (nBlock < 34) )
 {
  // send the erase block command to the flash
  WriteFlash( 0x0aaa, 0xaa );
  WriteFlash( 0x0555, 0x55 );
  WriteFlash( 0x0aaa, 0x80 );
  WriteFlash( 0x0aaa, 0xaa );
  WriteFlash( 0x0555, 0x55 );

  // the last write has to be at an address in the block
  // we want to erase
  lSectorOff = (nBlock * AFP_SectorSize1);
  WriteFlash( lSectorOff, 0x30 );

  // poll until the command has completed
  PollToggleBit(lSectorOff, 0x80);
 }
 // block is in Boot Flash Array
 else
 {
  
 }

 // block erase should be complete
 return TRUE;
}


//////////////////////////////////////////////////////////////
// bool UnlockFlash()
//
// Sends an "unlock" command to the flash to allow the flash
// to be programmed.
//
// Inputs: long lOffset - offset to unlock
//
//////////////////////////////////////////////////////////////

bool UnlockFlash(long lOffset)
{
 long lOffsetAddr = lOffset;
 lOffsetAddr &= 0x000F0000;

 // send the unlock command to the flash
 // ORed with lOffsetAddr so we know what block we are in
 WriteFlash( (0x0aaa | lOffsetAddr), 0xaa );
 WriteFlash( (0x0555 | lOffsetAddr), 0x55 );
 WriteFlash( (0x0aaa | lOffsetAddr), 0xa0 );

 // ok
 return TRUE;
}


//////////////////////////////////////////////////////////////
// bool GetCodes()
//
// Sends an "auto select" command to the flash which will allow
// us to get the manufacturer and device codes.
//
//////////////////////////////////////////////////////////////

bool GetCodes()
{
 int tmp;
 // send the auto select command to the flash
 WriteFlash( 0x0aaa, 0xaa );
 WriteFlash( 0x0555, 0x55 );
 WriteFlash( 0x0aaa, 0x90 );
 // now we can read the codes
 ReadFlash( 0x0000, &AFP_DevCode );
 tmp = AFP_DevCode;
 AFP_DevCode = (tmp>>16) & 0x00FF;

 // there is no ManCode that can be read so make it 0x20
 AFP_ManCode = tmp & 0x00FF;

 // we need to issue another command to get the part out
 // of auto select mode so issue a reset which just puts
 // the device back in read mode
 ResetFlash();

 // ok
 return TRUE;
}


//////////////////////////////////////////////////////////////
// bool GetSectorNumber()
//
// Gets a sector number based on the offset.
//
// Inputs: long lOffset - offset in the sector
//   int *pnSector - sector number
//
//////////////////////////////////////////////////////////////

bool GetSectorNumber( long lOffset, int *pnSector )
{
 int nSector = 0;

 // determine the sector
 
 nSector = lOffset & 0xffff0000;
 nSector = lOffset >> 16;
 nSector = nSector & 0x00007;

 // if it is a valid sector, set it
 if ( (nSector >= 0) && (nSector < AFP_NumSectors) )
  *pnSector = nSector;

 // else it is an invalid sector
 else
  return FALSE;

 // ok
 return TRUE;
}

//////////////////////////////////////////////////////////////
// void dma_int_0( int nothing )
//
// DMA interrupt handler, we come in here after the data block
// is done being DMAed
//
//////////////////////////////////////////////////////////////
void dma_int_0( int nothing )
{
 return;
}

//////////////////////////////////////////////////////////////
// void do_dma()
//
// sets up our DMA registers and does the DMA
//
//////////////////////////////////////////////////////////////
void do_dma()
{
 asm("DCS0 = xr3:0;;");  // setup DMA sourse
 asm("DCD0 = xr7:4;;");  // setup DMA destination
 asm("idle;;");    // wait for dma to finish
}


//////////////////////////////////////////////////////////////
// bool ReadToInternal()
//
// Used to DMA flash memory to internal memory so that the
// contents of flash can be viewed because the flash is not
// memory mapped
//
// Inputs: long lOffset - offset in flash to start the reads at
//   long lCount - number of elements to read, in this case bytes
//   long lStride - number of locations to skip between writes
//
//////////////////////////////////////////////////////////////
bool ReadToInternal(long lOffset, long lCount, long lStride)

 // we only allocate 0x8FFF locations for debugging so
 // check count to make sure we don't overwrite memory
 if( lCount > 0x1FFF )
  asm("j5 = 0x1FFF;;");
 
 asm("xr1 = j5;;");     // j5 is the count
 asm("xr1 = ashift r1 by 16;;");  // shift the count to upper 16
 asm("xr2 = j6;;");     // j6 is the stride
 asm("xr1 = r1 OR r2;;");   // OR in stride
 asm("xr5 = xr1;;");     // set destination register the same

 asm("xr0 = j4;;");     // xr0 = source index, j4 = nOffset
 asm("xr2 = 0x0;;");     // not used
 asm("xr3 = 0xc3000000;;");   // boot rom,prio=norm,2D=no,word=norm,int=yes,RQ=dsbl,chain=no
 asm("xr4 = 0x83000;;");    // xr4 = destination index / needs to change if debug section moves
 asm("xr6 = 0x0;;");     // not used
 asm("xr7 = 0x43000000;;");   // int mem,prio=norm,2D=no,word=norm,int=yes,RQ=dsbl,chain=no

 do_dma();       // set up dma registers

 // ok
 return TRUE;
}

               欢迎点击进入:TI德州中文网   (国内唯一针对TI应用的中文技术网站)    文章录入:admin    责任编辑:admin 
  • 上一篇文章: 没有了

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
    没有相关文章
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    站长:61IC 湘ICP备05002478号