EmbeddedArtists AB
/
lpc812_exp_solution_spi-e2prom
Solutions for the SPI E2PROM experiments for LPC812 MAX
SPI25LC080.cpp@1:819f21483c01, 2013-11-28 (annotated)
- Committer:
- embeddedartists
- Date:
- Thu Nov 28 12:17:45 2013 +0000
- Revision:
- 1:819f21483c01
- Parent:
- SPI24LC080.cpp@0:aa38ad0bf51d
Renamed the SPI24LC080 class to SPI25LC080 as it is an interface to the 25LC080 chip.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
embeddedartists | 0:aa38ad0bf51d | 1 | #include "mbed.h" |
embeddedartists | 1:819f21483c01 | 2 | #include "SPI25LC080.h" |
embeddedartists | 0:aa38ad0bf51d | 3 | |
embeddedartists | 0:aa38ad0bf51d | 4 | /* SPI E2PROM command set */ |
embeddedartists | 0:aa38ad0bf51d | 5 | #define INST_WREN 0x06 /* MSB A8 is set to 0, simplifying test */ |
embeddedartists | 0:aa38ad0bf51d | 6 | #define INST_WRDI 0x04 |
embeddedartists | 0:aa38ad0bf51d | 7 | #define INST_RDSR 0x05 |
embeddedartists | 0:aa38ad0bf51d | 8 | #define INST_WRSR 0x01 |
embeddedartists | 0:aa38ad0bf51d | 9 | #define INST_READ 0x03 |
embeddedartists | 0:aa38ad0bf51d | 10 | #define INST_WRITE 0x02 |
embeddedartists | 0:aa38ad0bf51d | 11 | |
embeddedartists | 0:aa38ad0bf51d | 12 | /* RDSR status bit definition */ |
embeddedartists | 0:aa38ad0bf51d | 13 | #define RDSR_RDY 0x01 |
embeddedartists | 0:aa38ad0bf51d | 14 | #define RDSR_WEN 0x02 |
embeddedartists | 0:aa38ad0bf51d | 15 | |
embeddedartists | 0:aa38ad0bf51d | 16 | /* Page size of E2PROM */ |
embeddedartists | 0:aa38ad0bf51d | 17 | #define PAGE_SIZE 16 |
embeddedartists | 0:aa38ad0bf51d | 18 | |
embeddedartists | 0:aa38ad0bf51d | 19 | #define LOCAL_MIN(__a, __b) ( ((__a) < (__b)) ? (__a) : (__b) ) |
embeddedartists | 0:aa38ad0bf51d | 20 | |
embeddedartists | 1:819f21483c01 | 21 | SPI25LC080::SPI25LC080(PinName mosi, PinName sclk, PinName miso, PinName ssel) : |
embeddedartists | 0:aa38ad0bf51d | 22 | m_spi(mosi, miso, sclk), m_ssel(ssel) |
embeddedartists | 0:aa38ad0bf51d | 23 | { |
embeddedartists | 0:aa38ad0bf51d | 24 | } |
embeddedartists | 0:aa38ad0bf51d | 25 | |
embeddedartists | 1:819f21483c01 | 26 | void SPI25LC080::read(uint16_t address, uint8_t* pData, uint32_t length) |
embeddedartists | 0:aa38ad0bf51d | 27 | { |
embeddedartists | 0:aa38ad0bf51d | 28 | //pull SSEL/CS low |
embeddedartists | 0:aa38ad0bf51d | 29 | m_ssel = 0; |
embeddedartists | 0:aa38ad0bf51d | 30 | |
embeddedartists | 0:aa38ad0bf51d | 31 | //output read command and address |
embeddedartists | 0:aa38ad0bf51d | 32 | m_spi.write(INST_READ); |
embeddedartists | 0:aa38ad0bf51d | 33 | m_spi.write((address >> 8) & 0xff); |
embeddedartists | 0:aa38ad0bf51d | 34 | m_spi.write(address & 0xff); |
embeddedartists | 0:aa38ad0bf51d | 35 | |
embeddedartists | 0:aa38ad0bf51d | 36 | //read bytes from E2PROM |
embeddedartists | 0:aa38ad0bf51d | 37 | for (uint32_t i = 0; i < length; i++) { |
embeddedartists | 0:aa38ad0bf51d | 38 | pData[i] = m_spi.write(0x00); // write dummy byte to get read next value |
embeddedartists | 0:aa38ad0bf51d | 39 | } |
embeddedartists | 0:aa38ad0bf51d | 40 | |
embeddedartists | 0:aa38ad0bf51d | 41 | //pull SSEL/CS high |
embeddedartists | 0:aa38ad0bf51d | 42 | m_ssel = 1; |
embeddedartists | 0:aa38ad0bf51d | 43 | } |
embeddedartists | 0:aa38ad0bf51d | 44 | |
embeddedartists | 1:819f21483c01 | 45 | uint8_t SPI25LC080::status() |
embeddedartists | 0:aa38ad0bf51d | 46 | { |
embeddedartists | 0:aa38ad0bf51d | 47 | //pull SSEL/CS low |
embeddedartists | 0:aa38ad0bf51d | 48 | m_ssel = 0; |
embeddedartists | 0:aa38ad0bf51d | 49 | |
embeddedartists | 0:aa38ad0bf51d | 50 | uint8_t status = m_spi.write(INST_RDSR); |
embeddedartists | 0:aa38ad0bf51d | 51 | |
embeddedartists | 0:aa38ad0bf51d | 52 | //pull SSEL/CS high |
embeddedartists | 0:aa38ad0bf51d | 53 | m_ssel = 1; |
embeddedartists | 0:aa38ad0bf51d | 54 | |
embeddedartists | 0:aa38ad0bf51d | 55 | return status; |
embeddedartists | 0:aa38ad0bf51d | 56 | } |
embeddedartists | 0:aa38ad0bf51d | 57 | |
embeddedartists | 1:819f21483c01 | 58 | void SPI25LC080::write_enable() |
embeddedartists | 0:aa38ad0bf51d | 59 | { |
embeddedartists | 0:aa38ad0bf51d | 60 | //pull SSEL/CS low |
embeddedartists | 0:aa38ad0bf51d | 61 | m_ssel = 0; |
embeddedartists | 0:aa38ad0bf51d | 62 | |
embeddedartists | 0:aa38ad0bf51d | 63 | //output write command and address |
embeddedartists | 0:aa38ad0bf51d | 64 | m_spi.write(INST_WREN); |
embeddedartists | 0:aa38ad0bf51d | 65 | |
embeddedartists | 0:aa38ad0bf51d | 66 | //pull SSEL/CS high |
embeddedartists | 0:aa38ad0bf51d | 67 | m_ssel = 1; |
embeddedartists | 0:aa38ad0bf51d | 68 | } |
embeddedartists | 0:aa38ad0bf51d | 69 | |
embeddedartists | 1:819f21483c01 | 70 | void SPI25LC080::write(uint16_t address, uint8_t* pData, uint32_t length) |
embeddedartists | 0:aa38ad0bf51d | 71 | { |
embeddedartists | 0:aa38ad0bf51d | 72 | uint32_t left = length; |
embeddedartists | 0:aa38ad0bf51d | 73 | uint32_t offset = address; |
embeddedartists | 0:aa38ad0bf51d | 74 | uint32_t len = 0; |
embeddedartists | 0:aa38ad0bf51d | 75 | |
embeddedartists | 0:aa38ad0bf51d | 76 | // find length of first page write |
embeddedartists | 0:aa38ad0bf51d | 77 | if ((address / PAGE_SIZE) != ((address + length) / PAGE_SIZE)) { |
embeddedartists | 0:aa38ad0bf51d | 78 | //spans across at least one boundary |
embeddedartists | 0:aa38ad0bf51d | 79 | len = PAGE_SIZE - (address % PAGE_SIZE); |
embeddedartists | 0:aa38ad0bf51d | 80 | } else { |
embeddedartists | 0:aa38ad0bf51d | 81 | // ends inside same page => use normal length |
embeddedartists | 0:aa38ad0bf51d | 82 | len = length % PAGE_SIZE; |
embeddedartists | 0:aa38ad0bf51d | 83 | } |
embeddedartists | 0:aa38ad0bf51d | 84 | |
embeddedartists | 0:aa38ad0bf51d | 85 | //insert code here to break up large write operation into several |
embeddedartists | 0:aa38ad0bf51d | 86 | //page write operations (16 or 32 byte pages) |
embeddedartists | 0:aa38ad0bf51d | 87 | while (left > 0) { |
embeddedartists | 0:aa38ad0bf51d | 88 | |
embeddedartists | 0:aa38ad0bf51d | 89 | //Enable write latch |
embeddedartists | 0:aa38ad0bf51d | 90 | write_enable(); |
embeddedartists | 0:aa38ad0bf51d | 91 | |
embeddedartists | 0:aa38ad0bf51d | 92 | //pull SSEL/CS low |
embeddedartists | 1:819f21483c01 | 93 | m_ssel = 0; |
embeddedartists | 0:aa38ad0bf51d | 94 | |
embeddedartists | 0:aa38ad0bf51d | 95 | //output write command and address |
embeddedartists | 0:aa38ad0bf51d | 96 | m_spi.write(INST_WRITE); |
embeddedartists | 0:aa38ad0bf51d | 97 | m_spi.write((offset >> 8) & 0xff); |
embeddedartists | 0:aa38ad0bf51d | 98 | m_spi.write(offset & 0xff); |
embeddedartists | 0:aa38ad0bf51d | 99 | |
embeddedartists | 0:aa38ad0bf51d | 100 | //send bytes to write E2PROM |
embeddedartists | 0:aa38ad0bf51d | 101 | for (uint32_t i = 0; i < len; i++) { |
embeddedartists | 0:aa38ad0bf51d | 102 | m_spi.write(pData[offset + i]); |
embeddedartists | 0:aa38ad0bf51d | 103 | } |
embeddedartists | 0:aa38ad0bf51d | 104 | |
embeddedartists | 0:aa38ad0bf51d | 105 | //pull SSEL/CS high |
embeddedartists | 1:819f21483c01 | 106 | m_ssel = 1; |
embeddedartists | 0:aa38ad0bf51d | 107 | |
embeddedartists | 0:aa38ad0bf51d | 108 | offset += len; |
embeddedartists | 0:aa38ad0bf51d | 109 | left -= len; |
embeddedartists | 0:aa38ad0bf51d | 110 | len = LOCAL_MIN(left, PAGE_SIZE); |
embeddedartists | 0:aa38ad0bf51d | 111 | |
embeddedartists | 0:aa38ad0bf51d | 112 | //wait until write operations is done |
embeddedartists | 0:aa38ad0bf51d | 113 | //for now, just wait. A more sophisticated method is to poll the status register |
embeddedartists | 0:aa38ad0bf51d | 114 | wait_ms(5); |
embeddedartists | 0:aa38ad0bf51d | 115 | } |
embeddedartists | 0:aa38ad0bf51d | 116 | } |
embeddedartists | 0:aa38ad0bf51d | 117 |