S5pc100裸板全攻略之SPI

作者:赵孝强,华清远见嵌入式培训中心讲师。

以下是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开发视频 物联网培训 物联网技术视频 嵌入式学习    

你可能感兴趣的:(SPI)