tag 标签: spi-flash

相关博文
  • 热度 22
    2010-8-16 08:49
    4321 次阅读|
    3 个评论
    Perhaps any people from earth knows that the atmel dataflash is short. I do NOT know why. Somebody said atmel isnot so good company that she is planing to rise the chip price by this way. The others said that many people in this market are crasy to buy and store so mang chips for grasping unnomal money... We don't know whose opion is right... ; ( Drive the flash from other company. The OLD Chinese Aphorism said: "After Butcher Zhang die, we have to eat the pork with full hair?"("死了张屠户, 我们就得吃带毛的猪?") Searching some weeks, we found the spi flash from winbond seemed to satify us. The 4M bit flash W25Q16xx is enough in current market. We uploaded our simple driver source code here. I wish it will help some engineer or company to replant new winbond flash for their case. Anyway, the price of winbond spi-flash from my provider is good. ; ) Of course, if you touch me then I will tell u... But it is not appropriate to paste the price in the public topic. Right? ; The important different issue from the other spi memory chip is: ADD BUSY DELAY FUNCITON! If not, we will found some fails at our reading event. The source are written with C, running NXP arm7 chip. // flash size #define     W25Q16_TOTAL_SIZE                   0x200000        // 256*8192 bytes = 2048k = 2M = 0x200000 #define     REAL_PAGE_SIZE                      256             // 256 bytes/page // command opcode #define     RSR1_INST                   0x05  // Read Status Register-1 #define     DEID_INST                   0xab  // Read Device ID #define     MDID_INST                   0x90  // Read Manufacturer/Device ID #define     JEID_INST                   0x9f  // Read Manufacturer/Memory Type/Capacity #define     FTRD_INST                   0x0b  // Fast Read #define     WREN_INST                   0x06  // Write Enable #define     STER_INST                   0x20  // Sector Erase #define     PGWR_INST                   0x02  // Page Program // init void w25q16_init(void) {         IO0DIR |= SPI0CS;                                        IO0SET = SPI0CS;              delay_ms(10); } // read status register, default return we read is 0x00, that means none of the array protected U8 w25q16_rdsr_cmd(void) {         U8 data;                 IO0CLR = SPI0CS;         spi0_send_U8(RSR1_INST);         data = spi0_read_U8();         IO0SET = SPI0CS;         return data;        } /*  *      Status Register Format:  *      Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0  *           | SEC  |  TB  | BP2  | BP1  | BP0  | WEL  | BUSY  */ void w25q16_busy_delay(void) {         U8 status;                 do {             status = w25q16_rdsr_cmd();         } while ((status 0x01) == 0x01); } // read device id, return must be 0x14 for W25Q16BV U8 w25q16_deid_cmd(void) {         U8 data;             w25q16_busy_delay();                        IO0CLR = SPI0CS;         spi0_send_U8(DEID_INST);         spi0_send_U8(0x00);                             // dummy         spi0_send_U8(0x00);                             // dummy         spi0_send_U8(0x00);                             // dummy         data = spi0_read_U8();         IO0SET = SPI0CS;                  return data; } W25Q16BV driver sample(I) W25Q16BV driver sample(II)
  • 热度 18
    2010-8-16 08:29
    2666 次阅读|
    0 个评论
    // read Manufacturer /device id, return must be 0xef/0x14 is for winbond/W25Q16BV void w25q16_mdid_cmd(void) {         U8 data1, data2;                 w25q16_busy_delay();             IO0CLR = SPI0CS;         spi0_send_U8(MDID_INST);         spi0_send_U8(0x00);                             // dummy         spi0_send_U8(0x00);                             // dummy         spi0_send_U8(0x00);                                     data1 = spi0_read_U8();         data2 = spi0_read_U8();                IO0SET = SPI0CS;                  // show read data for debug         uart0_putchar(0xff);         uart0_putchar(data1);         uart0_putchar(data2);                uart0_putchar(0xff); } // read Manufacturer/Memory Type/Capacity, return must be 0xef/0x40/0x15 is for winbond/W25Q16BV void w25q16_jeid_cmd(void) {         U8 data1, data2, data3;                 w25q16_busy_delay();             IO0CLR = SPI0CS;         spi0_send_U8(JEID_INST);         data1 = spi0_read_U8();         data2 = spi0_read_U8();         data3 = spi0_read_U8();                IO0SET = SPI0CS;                  // show read data for debug         uart0_putchar(0xff);         uart0_putchar(data1);         uart0_putchar(data2);                uart0_putchar(data3);                        uart0_putchar(0xff); } // Write enable void w25q16_wren_cmd(void) {         w25q16_busy_delay();             IO0CLR = SPI0CS;         spi0_send_U8(WREN_INST);         IO0SET = SPI0CS;        } // fast read void w25q16_read(U8* buf, U32 buf_len, U32 address) {         w25q16_busy_delay();                IO0CLR = SPI0CS;         spi0_send_U8(FTRD_INST);                                spi0_send_U8((U8)(address16));         spi0_send_U8((U8)(address8));         spi0_send_U8((U8)(address));         spi0_send_U8(0x00);                             // dummy              for(U32 i=0; i     buf = spi0_read_U8();         }           IO0SET = SPI0CS; } // sector erase for 16 page void w25q16_erase_sector(U32 address) {         //datasheet say sector erase's typ time is 30ms, max time is 200/400ms         watchdog_soft_hard_feed();                 w25q16_wren_cmd();         w25q16_busy_delay();         IO0CLR = SPI0CS;         spi0_send_U8(STER_INST);                                spi0_send_U8((U8)(address16));         spi0_send_U8((U8)(address8));         spi0_send_U8((U8)(address));         IO0SET = SPI0CS; } // page program with fix page size, datasheet say its typ time is 0.7ms, max time is 3ms void w25q16_page_program(U8* buf, U32 address) {         w25q16_wren_cmd();         w25q16_busy_delay();                 IO0CLR = SPI0CS;         spi0_send_U8(PGWR_INST);                                spi0_send_U8((U8)(address16));         spi0_send_U8((U8)(address8));         spi0_send_U8((U8)(address));         spi0_send_data(buf, REAL_PAGE_SIZE);         IO0SET = SPI0CS; } Allen 2010.08.15 OVER W25Q16BV driver sample(I) W25Q16BV driver sample(II)