123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- //w25x20cl.c
- #include "w25x20cl.h"
- #include <avr/io.h>
- #include <avr/pgmspace.h>
- #include "spi.h"
- #include "fastio.h"
- #define _MFRID 0xEF
- #define _DEVID 0x11
- #define _CMD_ENABLE_WR 0x06
- #define _CMD_ENABLE_WR_VSR 0x50
- #define _CMD_DISABLE_WR 0x04
- #define _CMD_RD_STATUS_REG 0x05
- #define _CMD_WR_STATUS_REG 0x01
- #define _CMD_RD_DATA 0x03
- #define _CMD_RD_FAST 0x0b
- #define _CMD_RD_FAST_D_O 0x3b
- #define _CMD_RD_FAST_D_IO 0xbb
- #define _CMD_PAGE_PROGRAM 0x02
- #define _CMD_SECTOR_ERASE 0x20
- #define _CMD_BLOCK32_ERASE 0x52
- #define _CMD_BLOCK64_ERASE 0xd8
- #define _CMD_CHIP_ERASE 0xc7
- #define _CMD_CHIP_ERASE2 0x60
- #define _CMD_PWR_DOWN 0xb9
- #define _CMD_PWR_DOWN_REL 0xab
- #define _CMD_MFRID_DEVID 0x90
- #define _CMD_MFRID_DEVID_D 0x92
- #define _CMD_JEDEC_ID 0x9f
- #define _CMD_RD_UID 0x4b
- #define _CS_LOW() WRITE(W25X20CL_PIN_CS, 0)
- #define _CS_HIGH() WRITE(W25X20CL_PIN_CS, 1)
- //#define _SPI_TX swspi_tx
- //#define _SPI_RX swspi_rx
- #define _SPI_TX(b) spi_txrx(b)
- #define _SPI_RX() spi_txrx(0xff)
- int w25x20cl_mfrid_devid(void);
- int8_t w25x20cl_init(void)
- {
- _CS_HIGH();
- SET_OUTPUT(W25X20CL_PIN_CS);
- W25X20CL_SPI_ENTER();
- if (!w25x20cl_mfrid_devid()) return 0;
- return 1;
- }
- void w25x20cl_enable_wr(void)
- {
- _CS_LOW();
- _SPI_TX(_CMD_ENABLE_WR); // send command 0x06
- _CS_HIGH();
- }
- void w25x20cl_disable_wr(void)
- {
- _CS_LOW();
- _SPI_TX(_CMD_DISABLE_WR); // send command 0x04
- _CS_HIGH();
- }
- uint8_t w25x20cl_rd_status_reg(void)
- {
- _CS_LOW();
- _SPI_TX(_CMD_RD_STATUS_REG); // send command 0x90
- uint8_t val = _SPI_RX(); // receive value
- _CS_HIGH();
- return val;
- }
- void w25x20cl_wr_status_reg(uint8_t val)
- {
- _CS_LOW();
- _SPI_TX(_CMD_WR_STATUS_REG); // send command 0x90
- _SPI_TX(val); // send value
- _CS_HIGH();
- }
- void w25x20cl_rd_data(uint32_t addr, uint8_t* data, uint16_t cnt)
- {
- _CS_LOW();
- _SPI_TX(_CMD_RD_DATA); // send command 0x03
- _SPI_TX(((uint8_t*)&addr)[2]); // send addr bits 16..23
- _SPI_TX(((uint8_t*)&addr)[1]); // send addr bits 8..15
- _SPI_TX(((uint8_t*)&addr)[0]); // send addr bits 0..7
- while (cnt--) // receive data
- *(data++) = _SPI_RX();
- _CS_HIGH();
- }
- void w25x20cl_page_program(uint32_t addr, uint8_t* data, uint16_t cnt)
- {
- _CS_LOW();
- _SPI_TX(_CMD_PAGE_PROGRAM); // send command 0x02
- _SPI_TX(((uint8_t*)&addr)[2]); // send addr bits 16..23
- _SPI_TX(((uint8_t*)&addr)[1]); // send addr bits 8..15
- _SPI_TX(((uint8_t*)&addr)[0]); // send addr bits 0..7
- while (cnt--) // send data
- _SPI_TX(*(data++));
- _CS_HIGH();
- }
- void w25x20cl_page_program_P(uint32_t addr, uint8_t* data, uint16_t cnt)
- {
- _CS_LOW();
- _SPI_TX(_CMD_PAGE_PROGRAM); // send command 0x02
- _SPI_TX(((uint8_t*)&addr)[2]); // send addr bits 16..23
- _SPI_TX(((uint8_t*)&addr)[1]); // send addr bits 8..15
- _SPI_TX(((uint8_t*)&addr)[0]); // send addr bits 0..7
- while (cnt--) // send data
- _SPI_TX(pgm_read_byte(data++));
- _CS_HIGH();
- }
- void w25x20cl_erase(uint8_t cmd, uint32_t addr)
- {
- _CS_LOW();
- _SPI_TX(cmd); // send command 0x20
- _SPI_TX(((uint8_t*)&addr)[2]); // send addr bits 16..23
- _SPI_TX(((uint8_t*)&addr)[1]); // send addr bits 8..15
- _SPI_TX(((uint8_t*)&addr)[0]); // send addr bits 0..7
- _CS_HIGH();
- }
- void w25x20cl_sector_erase(uint32_t addr)
- {
- return w25x20cl_erase(_CMD_SECTOR_ERASE, addr);
- }
- void w25x20cl_block32_erase(uint32_t addr)
- {
- return w25x20cl_erase(_CMD_BLOCK32_ERASE, addr);
- }
- void w25x20cl_block64_erase(uint32_t addr)
- {
- return w25x20cl_erase(_CMD_BLOCK64_ERASE, addr);
- }
- void w25x20cl_chip_erase(void)
- {
- _CS_LOW();
- _SPI_TX(_CMD_CHIP_ERASE); // send command 0xc7
- _CS_HIGH();
- }
- void w25x20cl_rd_uid(uint8_t* uid)
- {
- _CS_LOW();
- _SPI_TX(_CMD_RD_UID); // send command 0x4b
- uint8_t cnt = 4; // 4 dummy bytes
- while (cnt--) // receive dummy bytes
- _SPI_RX();
- cnt = 8; // 8 bytes UID
- while (cnt--) // receive UID
- uid[7 - cnt] = _SPI_RX();
- _CS_HIGH();
- }
- int w25x20cl_mfrid_devid(void)
- {
- _CS_LOW();
- _SPI_TX(_CMD_MFRID_DEVID); // send command 0x90
- uint8_t cnt = 3; // 3 address bytes
- while (cnt--) // send address bytes
- _SPI_TX(0x00);
- uint8_t w25x20cl_mfrid = _SPI_RX(); // receive mfrid
- uint8_t w25x20cl_devid = _SPI_RX(); // receive devid
- _CS_HIGH();
- return ((w25x20cl_mfrid == _MFRID) && (w25x20cl_devid == _DEVID));
- }
- void w25x20cl_wait_busy(void)
- {
- while (w25x20cl_rd_status_reg() & W25X20CL_STATUS_BUSY) ;
- }
|