int cmd_spi(int argc, char * const argv[]) { struct w25qxx_init_t init; uint32_t i, buf_size; static uint8_t buf[256]; struct w25qxx_attr_t w25qxx; init.delayms = DelayMs; init.get_reamin = _get_reamin; init.xfer = xfer; SPI_QuickInit(SPI0_MOSI_PA7_MISO_PA6, kSPI_CPOL1_CPHA1, 100*1000);//配置PTA7为MOSI PTA6为MISO, 波特率为100K,但是实际波特率要根据匹配出来的寄存器值算,有些误差 GPIO_QuickInit(HW_GPIOA, 5, kGPIO_Mode_OPP); //PTA5 SS GPIO_WriteBit(HW_GPIOA, 5, 1); PORT_PinMuxConfig(HW_GPIOB,0,kPinAlt3); //PTB0 SCK w25qxx_init(&init); //外部flash初始化 w25qxx_get_attr(&w25qxx); buf_size = sizeof(buf); /*读取外部flash256个字节*/ printf("reading page...\n"); w25qxx_read(0, buf, buf_size); print_buf(buf,PAGE_SIZE); /*擦除整个外部flash芯片*/ printf("erase all chips...\r\n"); w25qxx_erase_chip(); printf("erase complete\r\n"); /*读取外部flash256个字节*/ printf("reading page...\n"); w25qxx_read(0, buf, buf_size); print_buf(buf,PAGE_SIZE); /*编程外部flash256个字节*/ printf("programing a page...\n"); for(i=0;i<256;i++) buf[i] = i; w25qxx_write(0, buf, buf_size); printf("clearing buffer..\n"); for(i=0;i<256;i++) buf[i] = 0; /*读取外部flash256个字节*/ printf("reading page...\n"); w25qxx_read(0, buf, buf_size); print_buf(buf,PAGE_SIZE); printf("demo end.\n"); return 0; }
//向芯片写数据 int w25qxx_write(uint32_t addr, uint8_t *buf, uint32_t len) { uint32_t secpos; uint16_t secoff; uint16_t secremain; uint16_t i; uint8_t * mem_pool; mem_pool = SPI_FLASH_BUFFER; secpos = addr/4096;//扇区地址 secoff = addr%4096;//在扇区内的偏移 secremain = 4096-secoff;//扇区剩余空间大小 if(len <= secremain)secremain = len;//不大于4096个字节 while(1) { w25qxx_read(secpos*4096, mem_pool, 4096); //读出整个扇区的内容 for(i = 0; i < secremain; i++)//校验数据 { if(mem_pool[secoff+i]!=0XFF)break;//需要擦除 } if(i<secremain)//需要擦除 { w25qxx_erase_sector(secpos*4096); //擦除这个扇区 for(i=0;i<secremain;i++) //复制原来的数据 { mem_pool[i+secoff]=buf[i]; } w25qxx_write_no_check(secpos*4096, mem_pool,4096); //写入整个扇区 }else { W25QXX_TRACE("no need to erase -addr:%d\r\n", addr); w25qxx_write_no_check(addr, buf, secremain);//写已经擦除了的,直接写入扇区剩余区间. } if(len == secremain)break;//写入结束了 else//写入未结束 { secpos++;//扇区地址增1 secoff=0;//偏移位置为0 buf += secremain; //指针偏移 addr += secremain;//写地址偏移 len -= secremain; //字节数递减 if(len > 4096) secremain = 4096; //下一个扇区还是写不完 else secremain = len; //下一个扇区可以写完了 } } return SPI_EOK; }