作者:赵孝强,华清远见嵌入式培训中心讲师。
以下是s5pc100的不带系统SPI 操作m25p10的程序,需要map.lds,Makefile,s5pc100,文件,用v7交叉工具链,以上文件可在www.farsight.com.cn下载到。
#include "s5pc100.h"
#include "s5pc100.h"
#include "uart.h"
#define SPI0_CLK_GATE_ON (1<<6)
#define MAX 50
/* Flash opcodes. */
#define OPCODE_WREN 0x06 /* Write enable */
#define OPCODE_WRDA 0x04 /* Write disable */
#define OPCODE_RDSR 0x05 /* Read status register */
#define OPCODE_WRSR 0x01 /* Write status register 1 byte */
#define OPCODE_NORM_READ 0x03 /* Read data bytes (low frequency) */
#define OPCODE_FAST_READ 0x0b /* Read data bytes (high frequency) */
#define OPCODE_PP 0x02 /* Page Program (up to 256 bytes) */
#define OPCODE_BE_4K 0x20 /* Erase 4KiB block */
#define OPCODE_BE_32K 0x52 /* Erase 32KiB block */
#define OPCODE_CHIP_ERASE 0xc7 /* Erase whole flash chip */
#define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */
#define OPCODE_RDID 0x9f /* Read JEDEC ID */
/* Status Register bits. */
#define SR_WIP 1 /* Write in progress */
#define SR_WEL 2 /* Write enable latch */
extern void printf(const char *fmt, ...);
void cfg_gpio(void)
{
/* set GPB[0~3] to support spi0*/
GPB.GPBCON = (GPB.GPBCON & 0xffff0000) | 0x2222;
}
void set_clk(void)
{
/* enable clk_gate, spi_clksel = PCLK; spi_scaler = 0 */
CLK_GATE_D1.CLK_GATE_D1_4 |= SPI0_CLK_GATE_ON;
SPI0.CLKCFG &= 0x0;
}
void delay(int times)
{
volatile int i,j;
for (j = 0; j < times; j++){
for (i = 0; i < 100000; i++);
i = i + 1;}
}
void disable_chip(void)
{
/* disable chip*/
SPI0.SLAVESEL |= 0x1;
delay(1);
}
void enable_chip(void)
{
/* enable chip*/
SPI0.SLAVESEL &= ~0x1;
delay(1);
}
void soft_reset(void)
{
SPI0.CHCFG |= 0x1 << 5;
delay(1);
SPI0.CHCFG &= ~(0x1 << 5);
}
void cfg_spi0(void)
{
soft_reset();
SPI0.CHCFG &= ~((0x1 << 4) | (0x1 << 3) | (0x1 << 2));
SPI0.CHCFG &= ~0x3;
SPI0.MODECFG = (SPI0.MODECFG & ~((0x3 << 17) | (0x3 << 29))) | (0x0 << 17) | (0x0 << 29);
SPI0.SLAVESEL &= ~(0x1 << 1);
SPI0.CLKCFG |= 1 << 8;
}
void transfer(unsigned char *data, int len)
{
int i;
SPI0.CHCFG &= ~(0x1 << 1);
SPI0.CHCFG = SPI0.CHCFG | 0x1; // enable Tx and disable Rx
delay(1);
for (i = 0; i < len; i++){
SPI0.TXDATA = data[i];
while( !(SPI0.STATUS & (0x1 << 21)) );
delay(1); }
SPI0.CHCFG &= ~0x1;
}
void receive(unsigned char *buf, int len)
{
int i;
SPI0.CHCFG &= ~0x1; // disable Tx
SPI0.CHCFG |= 0x1 << 1; // enable Rx
delay(1);
for (i = 0; i < len; i++){
buf[i] = SPI0.RXDATA;
delay(1); }
SPI0.CHCFG &= ~(0x1 << 1);
}
void read_ID(void)
{
unsigned char buf[3];
int i;
buf[0] = OPCODE_RDID;
soft_reset();
enable_chip();
transfer(buf, 1);
receive(buf, 3);
disable_chip();
printf("MI = %x\tMT = %x\tMC = %x\t\n", buf[0], buf[1], buf[2]);
}
void erase_sector(int addr)
{
unsigned char buf[4];
buf[0] = OPCODE_SE;
buf[1] = addr >> 16;
buf[2] = addr >> 8;
buf[3] = addr;
enable_chip();
transfer(buf, 4);
disable_chip();
}
void erase_chip()
{
unsigned char buf[4];
buf[0] = OPCODE_CHIP_ERASE;
enable_chip();
transfer(buf, 1);
disable_chip();
}
void wait_till_write_finished()
{
unsigned char buf[1];
enable_chip();
buf[0] = OPCODE_RDSR;
transfer(buf, 1);
while(1) {
receive(buf, 1);
if(buf[0] & SR_WIP) {
// printf( "Write is still in progress\n" ); }
else {
printf( "Write is finished.\n" );
break;
}
}
disable_chip();
}
void enable_write()
{
unsigned char buf[1];
buf[0] = OPCODE_WREN;
enable_chip();
transfer(buf, 1);
disable_chip();
}
void write_spi(unsigned char *data, int len, int addr)
{
unsigned char buf[4];
//cfg_spi0();
soft_reset();
enable_write();
/* */
erase_chip();
wait_till_write_finished();
buf[0] = OPCODE_PP;
buf[1] = addr >> 16;
buf[2] = addr >> 8;
buf[3] = addr;
//cfg_spi0();
soft_reset();
enable_write();
enable_chip();
transfer(buf, 4);
transfer(data, len);
disable_chip();
wait_till_write_finished();
}
void read_spi(unsigned char *data, int len, int addr)
{
unsigned char buf[4];
//cfg_spi0();
soft_reset();
buf[0] = OPCODE_NORM_READ;
buf[1] = addr >> 16;
buf[2] = addr >> 8;
buf[3] = addr;
enable_chip();
transfer(buf, 4);
receive(data, len);
disable_chip();
}
int main()
{
unsigned char buf[10] = "home\n";
unsigned char data[10] = "morning\n";
uart0_init();
printf("aaaaa \n");
/* initialize spi0 */
cfg_gpio();
set_clk();
cfg_spi0();
while(1)
{
read_ID();
write_spi(buf, 4, 0);
read_spi(data, 4, 0);
printf("read from spi :%s", data);
}
return 0;
}
嵌入式及3G相关资源及学习请点击:嵌入式开发视频 android开发视频 android培训 3G培训 QT培训 QT开发视频 物联网培训 物联网技术视频 嵌入式学习