1 #include "projectconfig.h"
4 #include "core/ssp/ssp.h"
6 #include <r0ketports.h>
11 OP_READARRAY_SLOW
= 0x03,
13 OP_ERASE_BLOCK_4K
= 0x20,
14 OP_ERASE_BLOCK_32K
= 0x52,
15 OP_ERASE_BLOCK_64k
= 0xd8,
17 OP_ERASE_CHIP2
= 0xc7,
19 OP_PROGRAM_PAGE
= 0x02,
20 OP_PROGRAM_SEQ
= 0xad,
21 OP_PROGRAM_SEQ2
= 0xaf,
23 OP_WRITE_ENABLE
= 0x06,
24 OP_WRITE_DISABLE
= 0x04,
26 OP_SECTOR_PROTECT
= 0x36,
27 OP_SECTOR_UNPROTECT
= 0x39,
28 OP_SECTOR_STATUS
= 0x3c,
30 OP_STATUS_READ
= 0x05,
31 OP_STATUS_WRITE
= 0x01,
33 OP_DEVICEID_READ
= 0x9f,
40 STATUS_SPRL
= 1 << 7, // sector protection registers locked
41 STATUS_SPM
= 1 << 6, // sequential program mode
42 STATUS_EPE
= 1 << 5, // erase/program error
43 STATUS_WPP
= 1 << 4, // write protect pin
44 STATUS_SWP
= 3 << 2, // software protection
45 STATUS_WEL
= 1 << 1, // write enable latch
46 STATUS_BSY
= 1 << 0, // ready/busy
48 STATUS_SWP_NONE
= 0, // no sectors are software-protected
49 STATUS_SWP_SOME
= 1 << 2, // some sectors are software-protected
50 STATUS_SWP_ALL
= 3 << 2 // all sectors are software-protected
57 SECTOR_SIZE_FATFS
= 512
60 #define CS_LOW() gpioSetValue(RB_SPI_CS_DF, 0)
61 #define CS_HIGH() gpioSetValue(RB_SPI_CS_DF, 1)
63 static volatile DSTATUS status
= STA_NOINIT
;
65 BYTE
dataflash_read_status_register(void) {
66 BYTE reg_status
= 0xff;
69 xmit_spi(OP_STATUS_READ
);
70 rcvr_spi_m(®_status
);
77 static void dataflash_write_status_register(BYTE status) {
79 xmit_spi(OP_WRITE_ENABLE);
83 xmit_spi(OP_STATUS_WRITE);
88 static void wait_for_ready() {
89 while(dataflash_read_status_register() & STATUS_BSY
)
93 static void dataflash_powerdown() {
95 xmit_spi(OP_POWERDOWN
);
99 static void dataflash_resume() {
105 DSTATUS
dataflash_initialize() {
106 sspInit(0, sspClockPolarity_Low
, sspClockPhase_RisingEdge
);
108 gpioSetDir(RB_SPI_CS_DF
, gpioDirection_Output
);
111 // BYTE status = dataflash_read_status_register();
112 // dataflash_write_status_register((status & ~STATUS_SWP) | STATUS_SWP_NONE);
113 status
&= ~STA_NOINIT
;
118 DSTATUS
dataflash_status() {
122 DRESULT
dataflash_random_read(BYTE
*buff
, DWORD offset
, DWORD length
) {
123 if (!length
) return RES_PARERR
;
124 if (status
& STA_NOINIT
) return RES_NOTRDY
;
125 if (offset
+ length
> PAGE_MAX
* PAGE_SIZE
) return RES_PARERR
;
130 xmit_spi(OP_READARRAY
);
131 xmit_spi((BYTE
)(offset
>> 16));
132 xmit_spi((BYTE
)(offset
>> 8));
133 xmit_spi((BYTE
) offset
);
134 xmit_spi(0x00); // follow up with don't care byte
144 DRESULT
dataflash_read(BYTE
*buff
, DWORD sector
, BYTE count
) {
145 return dataflash_random_read(buff
, sector
* SECTOR_SIZE_FATFS
, count
* SECTOR_SIZE_FATFS
);
149 static void dataflash_sector_protect(DWORD addr
) {
152 addr
&= ~(PAGE_SIZE
- 1);
155 xmit_spi(OP_WRITE_ENABLE
);
159 xmit_spi(OP_SECTOR_PROTECT
);
160 xmit_spi((BYTE
)(addr
>> 16));
161 xmit_spi((BYTE
)(addr
>> 8));
162 xmit_spi((BYTE
) addr
);
168 static void dataflash_sector_unprotect(DWORD addr
) {
171 addr
&= ~(PAGE_SIZE
- 1);
174 xmit_spi(OP_WRITE_ENABLE
);
178 xmit_spi(OP_SECTOR_UNPROTECT
);
179 xmit_spi((BYTE
)(addr
>> 16));
180 xmit_spi((BYTE
)(addr
>> 8));
181 xmit_spi((BYTE
) addr
);
187 static DRESULT
dataflash_write_4k(const BYTE
*buff
, DWORD addr
) {
191 xmit_spi(OP_WRITE_ENABLE
);
195 xmit_spi(OP_ERASE_BLOCK_4K
);
196 xmit_spi((BYTE
)(addr
>> 16));
197 xmit_spi((BYTE
)(addr
>> 8));
198 xmit_spi((BYTE
) addr
);
202 xmit_spi(OP_WRITE_ENABLE
);
206 xmit_spi(OP_PROGRAM_PAGE
);
207 xmit_spi((BYTE
)(addr
>> 16));
208 xmit_spi((BYTE
)(addr
>> 8));
209 xmit_spi((BYTE
) addr
);
210 for(int i
= 0; i
< 4096; ++i
) {
216 DRESULT
dataflash_random_write(const BYTE
*buff
, DWORD offset
, DWORD length
) {
217 if (!length
) return RES_PARERR
;
218 if (status
& STA_NOINIT
) return RES_NOTRDY
;
219 if (offset
+ length
> PAGE_MAX
* PAGE_SIZE
) return RES_PARERR
;
225 DWORD blockaddr
= addr
& ~4095u;
226 DWORD remaining
= PAGE_SIZE
- offset
% PAGE_SIZE
;
229 dataflash_random_read(blockbuf
, blockaddr
, 4096);
231 if (remaining
> length
) {
238 dataflash_sector_unprotect(addr
);
241 xmit_spi(OP_WRITE_ENABLE
);
245 xmit_spi(OP_PROGRAM_PAGE
);
246 xmit_spi((BYTE
)(addr
>> 16));
247 xmit_spi((BYTE
)(addr
>> 8));
248 xmit_spi((BYTE
) addr
);
251 } while (--remaining
);
254 dataflash_sector_protect(addr
);
262 DRESULT
dataflash_write(const BYTE
*buff
, DWORD sector
, BYTE count
) {
263 return dataflash_random_write(buff
, sector
* SECTOR_SIZE_FATFS
, count
* SECTOR_SIZE_FATFS
);
265 #endif /* _READONLY */
268 DRESULT
dataflash_ioctl(BYTE ctrl
, void *buff
) {
274 if (ctrl
== CTRL_POWER
) {
276 case 0: /* Sub control code == 0 (POWER_OFF) */
277 dataflash_powerdown();
280 case 1: /* Sub control code == 1 (POWER_ON) */
284 case 2: /* Sub control code == 2 (POWER_GET) */
285 // TODO: figure out a way to retrieve the powerstate
293 if (status
& STA_NOINIT
) return RES_NOTRDY
;
300 case GET_SECTOR_COUNT
:
301 // TODO: read from device ID register
302 *(WORD
*)buff
= PAGE_MAX
* PAGE_SIZE
/ SECTOR_SIZE_FATFS
;
305 case GET_SECTOR_SIZE
:
306 *(WORD
*)buff
= SECTOR_SIZE_FATFS
;
320 #endif /* _USE_IOCTL != 0 */
322 DWORD
get_fattime () {
325 struct tm* tm=mygmtime(getSeconds());
326 DWORD t= (((tm->tm_year-80)<<9)|
This page took 0.056799 seconds and 5 git commands to generate.