📄 spirom.c
字号:
/*
* Copyright 2007 b7 Spectrum Digital Incorporated.
* All rights reserved. Property of Spectrum Digital Incorporated.
*/
/*
* SPI ROM interface
*
*/
#include "spirom.h"
static Uint8 spirombuf[spirom_PAGESIZE + 5];
static Uint8 statusbuf[8];
static Uint32 spidat1;
/* ------------------------------------------------------------------------ *
* spirom_init( ) *
* ------------------------------------------------------------------------ */
void spirom_init( )
{
/* Reset SPI */
SPI_SPIGCR0 = 0;
_wait( 1000 );
/* Release SPI */
SPI_SPIGCR0 = 1;
/* SPI 4-Pin Mode setup */
SPI_SPIGCR1 = 0
| ( 0 << 24 )
| ( 0 << 16 )
| ( 1 << 1 )
| ( 1 << 0 );
SPI_SPIPC0 = 0
| ( 1 << 11 ) // DI
| ( 1 << 10 ) // DO
| ( 1 << 9 ) // CLK
| ( 1 << 1 ) // EN1
| ( 1 << 0 ); // EN0
SPI_SPIFMT0 = 0
| ( 0 << 20 ) // SHIFTDIR
| ( 0 << 17 ) // Polarity
| ( 1 << 16 ) // Phase
| ( 50 << 8 ) // Prescale
| ( 8 << 0 ); // Char Len
spidat1 = 0
| ( 1 << 28 ) // CSHOLD
| ( 0 << 24 ) // Format [0]
| ( 2 << 16 ) // CSNR [only CS0 enbled]
| ( 0 << 0 ); //
SPI_SPIDAT1 = spidat1;
SPI_SPIDELAY = 0
| ( 8 << 24 ) // C2TDELAY
| ( 8 << 16 ); // T2CDELAY
SPI_SPIDEF = 0
| ( 1 << 1 ) // EN1 inactive high
| ( 1 << 0 ); // EN0 inactive high
SPI_SPIINT = 0
| ( 0 << 16 ) //
| ( 0 << 8 ) //
| ( 0 << 6 ) //
| ( 1 << 4 ); //
SPI_SPILVL = 0
| ( 0 << 8 ) // EN0
| ( 0 << 6 ) // EN0
| ( 0 << 4 ); // EN0
/* Enable SPI */
SPI_SPIGCR1 |= ( 1 << 24 );
}
/* ------------------------------------------------------------------------ *
* spirom_cycle(buf, len) *
* *
* Execute a SPI spirom data transfer cycle. Each byte in buf is shifted *
* out and replaced with data coming back from the spirom. *
* ------------------------------------------------------------------------ */
void spirom_cycle(Uint8 *buf, Uint16 len)
{
Uint16 i;
/* Clear any old data */
SPI_SPIBUF;
/* spirom access cycle */
for (i = 0; i <= len; i++)
{
// Wait for transmit ready
while( SPI_SPIBUF & 0x10000000 );
if (i == len )
SPI_SPIDAT1 = (spidat1 & 0x0ffcffff) | buf[i] ;
else
SPI_SPIDAT1 = spidat1 | buf[i];
// Wait for receive data ready
while ( SPI_SPIBUF & ( 0x80000000 ) );
/* Read 1 byte */
buf[i] = SPI_SPIBUF;
}
}
/* ------------------------------------------------------------------------ *
* spirom_status( ) *
* ------------------------------------------------------------------------ */
Uint8 spirom_status( )
{
/* Issue read status command */
statusbuf[0] = spirom_CMD_RDSR;
statusbuf[1] = 0;
spirom_cycle(statusbuf, 2);
return statusbuf[1];
}
/* ------------------------------------------------------------------------ *
* spirom_read( src, dst, len ) *
* ------------------------------------------------------------------------ */
void spirom_read( Uint16 src, Uint32 dst, Uint32 length )
{
Int32 i;
Uint8 *psrc, *pdst;
// Setup command
spirombuf[0] = spirom_CMD_READ;
spirombuf[1] = ( src >> 8 );
spirombuf[2] = ( src >> 0 );
// Execute spirom read cycle
spirom_cycle(spirombuf, length + 3);
// Copy returned data
pdst = ( Uint8 * )dst;
psrc = spirombuf + 3;
for ( i = 0 ; i < length ; i++ )
*pdst++ = *psrc++;
}
/* ------------------------------------------------------------------------ *
* spirom_write( src, dst, len ) *
* ------------------------------------------------------------------------ */
void spirom_write( Uint32 src, Uint16 dst, Uint32 length )
{
Int32 i;
Int32 bytes_left;
Int32 bytes_to_program;
Uint8 *psrc;
/* Establish source */
psrc = ( Uint8 * )src;
bytes_left = length;
while ( bytes_left > 0 )
{
bytes_to_program = bytes_left;
/* Most to program is spirom_CMD_BLOCKSIZE */
if ( bytes_to_program > spirom_PAGESIZE )
bytes_to_program = spirom_PAGESIZE;
/* Make sure you don't run off the end of a block */
if ( ( dst & spirom_PAGEMASK ) != ( ( dst + bytes_to_program ) & spirom_PAGEMASK ) )
bytes_to_program -= ( dst + bytes_to_program ) - ( ( dst + bytes_to_program ) & spirom_PAGEMASK );
/* Issue WPEN */
spirombuf[0] = spirom_CMD_WREN;
spirom_cycle(spirombuf, 0);
/* Create command block for program operation */
spirombuf[0] = spirom_CMD_WRITE;
spirombuf[1] = ( Uint8 )( dst >> 8 );
spirombuf[2] = ( Uint8 )( dst );
for ( i = 0 ; i < bytes_to_program ; i++ )
spirombuf[3+i] = *psrc++;
/* Execute write command */
spirom_cycle(spirombuf, bytes_to_program + 2 );
/* Wait while busy */
while( ( spirom_status( ) & 0x01 ) );
/* Get ready for next iteration */
bytes_left -= bytes_to_program;
dst += bytes_to_program;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -