update: 重构libgnss,解决air530z-bd及air780epvg出现的问题
[LuatOS.git] / components / sfd / luat_sfd_w25q.c
blob6a72fe7b8d5dbda91577b86e5aa30f36409f546b
2 #include "luat_base.h"
3 #include "luat_spi.h"
4 #include "luat_gpio.h"
6 #include "luat_sfd.h"
8 #define LUAT_LOG_TAG "sfd"
9 #include "luat_log.h"
11 #define CS_H(pin) luat_gpio_set(pin, 1)
12 #define CS_L(pin) luat_gpio_set(pin, 0)
14 // 针对drv的实现
15 static int sfd_w25q_init (void* userdata);
16 static int sfd_w25q_status (void* userdata);
17 static int sfd_w25q_read (void* userdata, char* buff, size_t offset, size_t len);
18 static int sfd_w25q_write (void* userdata, const char* buff, size_t offset, size_t len);
19 static int sfd_w25q_erase (void* userdata, size_t offset, size_t len);
20 static int sfd_w25q_ioctl (void* userdata, size_t cmd, void* buff);
22 const sdf_opts_t sfd_w25q_opts = {
23 .initialize = sfd_w25q_init,
24 .status = sfd_w25q_status,
25 .read = sfd_w25q_read,
26 .write = sfd_w25q_write,
27 .erase = sfd_w25q_erase,
28 .ioctl = sfd_w25q_ioctl,
31 static int sfd_w25q_init (void* userdata) {
32 sfd_drv_t *drv = (sfd_drv_t *)userdata;
33 uint8_t cmd = 0x9F;
34 // 发送CMD 9F, 读取容量信息
35 luat_gpio_set(drv->cfg.spi.cs, 0);
36 luat_spi_send(drv->cfg.spi.id, (const char*)&cmd, 1);
37 char buff[3] = {0};
38 luat_spi_recv(drv->cfg.spi.id, buff, 3);
39 luat_gpio_set(drv->cfg.spi.cs, 1);
40 if (buff[0] != 0xEF) {
41 LLOGW("can't read spi flash: cmd 9F");
42 return -1;
44 LLOGD("spi flash %02X %02X %02X", buff[0], buff[1], buff[2]);
45 if (buff[1] == 0x40) {
46 switch(buff[2]) {
47 case 0x13:
48 drv->sector_count = 8*256;// drv80, 8M
49 break;
50 case 0x14:
51 drv->sector_count = 16*256;// drv16, 16M
52 break;
53 case 0x15:
54 drv->sector_count = 32*256;// drv32, 32M
55 break;
56 case 0x16:
57 drv->sector_count = 64*256;// drv64, 64M
58 break;
59 case 0x17:
60 drv->sector_count = 128*256;// drv128, 128M
61 break;
62 case 0x18:
63 drv->sector_count = 256*256;// drv256, 256M
64 break;
65 case 0x19:
66 drv->sector_count = 512*256;// drv512, 512M
67 break;
68 default :
69 drv->sector_count = 16*256;// 默认当16M吧
70 break;
73 else {
74 drv->sector_count = 16*256;// 默认当16M吧
76 //drv->flash_id[0] = buff[1];
77 //drv->flash_id[1] = buff[2];
79 // 读设备唯一id
80 luat_gpio_set(drv->cfg.spi.cs, 0);
81 char chip_id_cmd[] = {0x4B, 0x00, 0x00, 0x00, 0x00};
82 luat_spi_send(drv->cfg.spi.id, chip_id_cmd, sizeof(chip_id_cmd));
83 luat_spi_recv(drv->cfg.spi.id, drv->chip_id, 8);
84 luat_gpio_set(drv->cfg.spi.cs, 1);
86 return 0;
89 static int sfd_w25q_status (void* userdata) {
90 sfd_drv_t *drv = (sfd_drv_t *)userdata;
91 return drv->sector_count == 0 ? 0 : 1; // TODO 根据BUSY 状态返回
94 static int sfd_w25q_read (void* userdata, char* buff, size_t offset, size_t len) {
95 sfd_drv_t *drv = (sfd_drv_t *)userdata;
96 char cmd[4] = {0x03, offset >> 16, (offset >> 8) & 0xFF, offset & 0xFF};
97 luat_gpio_set(drv->cfg.spi.cs, 0);
98 luat_spi_send(drv->cfg.spi.id, (const char*)&cmd, sizeof(cmd));
99 luat_spi_recv(drv->cfg.spi.id, buff, len);
100 luat_gpio_set(drv->cfg.spi.cs, 1);
101 return 0;
104 void sfd_w25q_write_enable(sfd_drv_t *drv) {
105 luat_gpio_set(drv->cfg.spi.cs, 0);
106 uint8_t cmd = 0x06;
107 luat_spi_send(drv->cfg.spi.id, (const char*)&cmd, sizeof(cmd));
108 luat_gpio_set(drv->cfg.spi.cs, 1);
111 static int sfd_w25q_write (void* userdata, const char* buff, size_t offset, size_t len) {
112 sfd_drv_t *drv = (sfd_drv_t *)userdata;
113 sfd_w25q_write_enable(drv);
114 char cmd[4] = {0x02, offset >> 16, (offset >> 8) & 0xFF, offset & 0xFF};
115 luat_gpio_set(drv->cfg.spi.cs, 0);
116 luat_spi_send(drv->cfg.spi.id, (const char*)&cmd, sizeof(cmd));
117 luat_spi_send(drv->cfg.spi.id, buff, len);
118 luat_gpio_set(drv->cfg.spi.cs, 1);
119 return 0;
122 static int sfd_w25q_erase (void* userdata, size_t offset, size_t len) {
123 sfd_drv_t *drv = (sfd_drv_t *)userdata;
124 sfd_w25q_write_enable(drv);
125 char cmd[4] = {0x20, offset >> 16, (offset >> 8) & 0xFF, offset & 0xFF};
126 luat_gpio_set(drv->cfg.spi.cs, 0);
127 luat_spi_send(drv->cfg.spi.id, (const char*)&cmd, sizeof(cmd));
128 luat_gpio_set(drv->cfg.spi.cs, 1);
129 return 0;
132 static int sfd_w25q_ioctl (void* userdata, size_t cmd, void* buff) {
133 return -1;