Microchip 23K256 (SPI SRAM) sample code for https://www.switch-science.com/catalog/1072/ module.

Dependencies:   mbed

Committer:
discypus
Date:
Sat Nov 01 13:58:50 2014 +0000
Revision:
2:0248049e65f1
Parent:
1:793321f410a9
Child:
3:65a33de8fa08
USER??????????????1?????????????

Who changed what in which revision?

UserRevisionLine numberNew contents of line
discypus 2:0248049e65f1 1 /*
discypus 2:0248049e65f1 2 * test for
discypus 2:0248049e65f1 3 * - Microchip SRAM 23K256 (SPI)
discypus 2:0248049e65f1 4 * - Intersil Red/Green/Blue Color Light Sensor (I2C, address = 1000 100x, hard-wires)
discypus 2:0248049e65f1 5 * - ISL29125 data sheet, p.7, Device Adressing
discypus 2:0248049e65f1 6 * -
discypus 2:0248049e65f1 7 */
discypus 2:0248049e65f1 8
discypus 0:82c01bfc06e1 9 #include "mbed.h"
discypus 0:82c01bfc06e1 10
discypus 2:0248049e65f1 11 /** Serial port for DEBUG */
discypus 2:0248049e65f1 12 Serial pc(USBTX, USBRX);
discypus 2:0248049e65f1 13
discypus 2:0248049e65f1 14 InterruptIn mybutton(USER_BUTTON);
discypus 2:0248049e65f1 15
discypus 2:0248049e65f1 16 /** ユーザーボタンが押されたらtrue */
discypus 2:0248049e65f1 17 volatile bool is_pressed = false;
discypus 2:0248049e65f1 18
discypus 2:0248049e65f1 19 /**
discypus 2:0248049e65f1 20 * USERボタン 割り込みハンドラ
discypus 2:0248049e65f1 21 */
discypus 2:0248049e65f1 22 void
discypus 2:0248049e65f1 23 pressed() {
discypus 2:0248049e65f1 24 is_pressed = true;
discypus 2:0248049e65f1 25 }
discypus 2:0248049e65f1 26
discypus 2:0248049e65f1 27 /**
discypus 2:0248049e65f1 28 * USERボタンが押されるまで待つ。
discypus 2:0248049e65f1 29 */
discypus 2:0248049e65f1 30 void
discypus 2:0248049e65f1 31 wait_until_user_button_pressed() {
discypus 2:0248049e65f1 32 while (!is_pressed) {
discypus 2:0248049e65f1 33 __nop();
discypus 2:0248049e65f1 34 }
discypus 2:0248049e65f1 35 is_pressed = false;
discypus 2:0248049e65f1 36 pc.printf("USER button is pressed\r\n");
discypus 2:0248049e65f1 37 }
discypus 2:0248049e65f1 38
discypus 0:82c01bfc06e1 39 /** */
discypus 0:82c01bfc06e1 40 SPI spi(SPI_MOSI, SPI_MISO, SPI_SCK);
discypus 0:82c01bfc06e1 41
discypus 0:82c01bfc06e1 42 /** */
discypus 0:82c01bfc06e1 43 DigitalOut cs(SPI_CS);
discypus 0:82c01bfc06e1 44
discypus 0:82c01bfc06e1 45 /*
discypus 0:82c01bfc06e1 46 * SPI COMMAND (Microchip 23K256 SRAM)
discypus 0:82c01bfc06e1 47 * 1byte read/write
discypus 0:82c01bfc06e1 48 * page read/write
discypus 0:82c01bfc06e1 49 * sequential read/write
discypus 0:82c01bfc06e1 50 * status/configuration register read/write
discypus 0:82c01bfc06e1 51 */
discypus 0:82c01bfc06e1 52 enum Microchip23K256Commnd {
discypus 0:82c01bfc06e1 53 READ = 0x03u,
discypus 0:82c01bfc06e1 54 WRITE = 0x02u,
discypus 0:82c01bfc06e1 55 RDSR = 0x05u,
discypus 0:82c01bfc06e1 56 WRSR = 0x01u,
discypus 0:82c01bfc06e1 57 };
discypus 0:82c01bfc06e1 58
discypus 0:82c01bfc06e1 59 /** SRAM Mode */
discypus 0:82c01bfc06e1 60 enum Microchip23K256Mode {
discypus 0:82c01bfc06e1 61 MODE_MASK = 0xc0u,
discypus 0:82c01bfc06e1 62 BYTE = 0x00u,
discypus 0:82c01bfc06e1 63 PAGE = 0x80u,
discypus 0:82c01bfc06e1 64 SEQUENTIAL = 0x40u,
discypus 0:82c01bfc06e1 65 };
discypus 0:82c01bfc06e1 66
discypus 0:82c01bfc06e1 67 /**
discypus 0:82c01bfc06e1 68 * assert CS
discypus 0:82c01bfc06e1 69 */
discypus 0:82c01bfc06e1 70 inline void
discypus 0:82c01bfc06e1 71 assert_CS() {
discypus 0:82c01bfc06e1 72 cs = 0;
discypus 0:82c01bfc06e1 73 }
discypus 0:82c01bfc06e1 74
discypus 0:82c01bfc06e1 75 /**
discypus 0:82c01bfc06e1 76 * negate CS
discypus 0:82c01bfc06e1 77 */
discypus 0:82c01bfc06e1 78 inline void
discypus 0:82c01bfc06e1 79 negate_CS() {
discypus 0:82c01bfc06e1 80 cs = 1;
discypus 0:82c01bfc06e1 81 }
discypus 0:82c01bfc06e1 82
discypus 0:82c01bfc06e1 83 /**
discypus 0:82c01bfc06e1 84 * レジスタ読みだし
discypus 0:82c01bfc06e1 85 * @return レジスタ値
discypus 0:82c01bfc06e1 86 */
discypus 0:82c01bfc06e1 87 inline uint8_t
discypus 0:82c01bfc06e1 88 read_status_register() {
discypus 0:82c01bfc06e1 89 assert_CS();
discypus 0:82c01bfc06e1 90 spi.write(RDSR);
discypus 0:82c01bfc06e1 91 const uint8_t status = spi.write(0x00);
discypus 0:82c01bfc06e1 92 negate_CS();
discypus 0:82c01bfc06e1 93
discypus 0:82c01bfc06e1 94 return status;
discypus 0:82c01bfc06e1 95 }
discypus 0:82c01bfc06e1 96
discypus 0:82c01bfc06e1 97 /**
discypus 0:82c01bfc06e1 98 * レジスタ書き込み
discypus 0:82c01bfc06e1 99 * @param[in] status
discypus 0:82c01bfc06e1 100 */
discypus 0:82c01bfc06e1 101 inline void
discypus 0:82c01bfc06e1 102 write_status_register(const uint8_t status) {
discypus 0:82c01bfc06e1 103 assert_CS();
discypus 0:82c01bfc06e1 104 spi.write(WRSR);
discypus 0:82c01bfc06e1 105 spi.write(status);
discypus 0:82c01bfc06e1 106 negate_CS();
discypus 0:82c01bfc06e1 107 }
discypus 0:82c01bfc06e1 108
discypus 0:82c01bfc06e1 109 /**
discypus 0:82c01bfc06e1 110 * モードを切り替える。
discypus 0:82c01bfc06e1 111 * @param[in] mode モード
discypus 0:82c01bfc06e1 112 * @return 切替前のモード
discypus 0:82c01bfc06e1 113 * @invariant モード以外のフラグは変更しない。
discypus 0:82c01bfc06e1 114 */
discypus 0:82c01bfc06e1 115 inline uint8_t
discypus 0:82c01bfc06e1 116 change_mode(const unsigned int next_mode) {
discypus 0:82c01bfc06e1 117 const uint8_t previous_status = read_status_register();
discypus 0:82c01bfc06e1 118 const uint8_t previous_mode = previous_status & MODE_MASK;
discypus 0:82c01bfc06e1 119 if (next_mode != previous_mode) {
discypus 0:82c01bfc06e1 120 const uint8_t next_status = (previous_status & ~MODE_MASK) | uint8_t(next_mode);
discypus 0:82c01bfc06e1 121 write_status_register(next_status);
discypus 0:82c01bfc06e1 122 }
discypus 0:82c01bfc06e1 123 return previous_mode;
discypus 0:82c01bfc06e1 124 }
discypus 0:82c01bfc06e1 125
discypus 0:82c01bfc06e1 126 /**
discypus 0:82c01bfc06e1 127 * 1byte読み出し
discypus 0:82c01bfc06e1 128 * @param[in] address アドレス 16bit。容量32KBなので、MSBは無視する
discypus 0:82c01bfc06e1 129 * @return データ
discypus 0:82c01bfc06e1 130 * @pre byteモードに切り替えていること。
discypus 0:82c01bfc06e1 131 */
discypus 0:82c01bfc06e1 132 uint8_t
discypus 0:82c01bfc06e1 133 read_byte(const uint16_t address) {
discypus 1:793321f410a9 134 const uint8_t address_high = (address >> (8 * 1)) & 0xFFu;
discypus 1:793321f410a9 135 const uint8_t address_low = (address >> (8 * 0)) & 0xFFu;
discypus 1:793321f410a9 136
discypus 0:82c01bfc06e1 137 assert_CS();
discypus 0:82c01bfc06e1 138 spi.write(READ);
discypus 1:793321f410a9 139 spi.write(address_high);
discypus 1:793321f410a9 140 spi.write(address_low);
discypus 0:82c01bfc06e1 141 const uint8_t data = spi.write(0x00);
discypus 0:82c01bfc06e1 142 negate_CS();
discypus 0:82c01bfc06e1 143
discypus 0:82c01bfc06e1 144 return data;
discypus 0:82c01bfc06e1 145 }
discypus 0:82c01bfc06e1 146
discypus 0:82c01bfc06e1 147 /**
discypus 0:82c01bfc06e1 148 * 1byte書き込み
discypus 0:82c01bfc06e1 149 * @param[in] address アドレス 16bit。容量32KBなので、MSBは無視する
discypus 0:82c01bfc06e1 150 * @param[in] data データ
discypus 0:82c01bfc06e1 151 * @pre byteモードに切り替えていること。
discypus 0:82c01bfc06e1 152 */
discypus 0:82c01bfc06e1 153 void
discypus 0:82c01bfc06e1 154 write_byte(const uint16_t address, const uint8_t data) {
discypus 1:793321f410a9 155 const uint8_t address_high = (address >> (8 * 1)) & 0xFFu;
discypus 1:793321f410a9 156 const uint8_t address_low = (address >> (8 * 0)) & 0xFFu;
discypus 1:793321f410a9 157
discypus 0:82c01bfc06e1 158 assert_CS();
discypus 0:82c01bfc06e1 159 spi.write(WRITE);
discypus 1:793321f410a9 160 spi.write(address_high);
discypus 1:793321f410a9 161 spi.write(address_low);
discypus 0:82c01bfc06e1 162 spi.write(data);
discypus 0:82c01bfc06e1 163 negate_CS();
discypus 0:82c01bfc06e1 164 }
discypus 0:82c01bfc06e1 165
discypus 0:82c01bfc06e1 166 /**
discypus 0:82c01bfc06e1 167 * 連続読み出し
discypus 0:82c01bfc06e1 168 * @pre pageモードかbyteモードに切り替えていること。
discypus 0:82c01bfc06e1 169 */
discypus 0:82c01bfc06e1 170 void
discypus 0:82c01bfc06e1 171 read_bytes(const uint16_t address, uint8_t __restrict data[], const uint16_t size) {
discypus 1:793321f410a9 172 const uint8_t address_high = (address >> (8 * 1)) & 0xFFu;
discypus 1:793321f410a9 173 const uint8_t address_low = (address >> (8 * 0)) & 0xFFu;
discypus 1:793321f410a9 174
discypus 0:82c01bfc06e1 175 assert_CS();
discypus 0:82c01bfc06e1 176 spi.write(READ);
discypus 1:793321f410a9 177 spi.write(address_high);
discypus 1:793321f410a9 178 spi.write(address_low);
discypus 0:82c01bfc06e1 179 for (uint16_t i = 0; i < size; ++i) {
discypus 0:82c01bfc06e1 180 data[i] = spi.write(0x00);
discypus 0:82c01bfc06e1 181 }
discypus 0:82c01bfc06e1 182 negate_CS();
discypus 0:82c01bfc06e1 183 }
discypus 0:82c01bfc06e1 184
discypus 0:82c01bfc06e1 185 /**
discypus 0:82c01bfc06e1 186 * 連続書き込み
discypus 0:82c01bfc06e1 187 * @pre pageモードかbyteモードに切り替えていること。
discypus 0:82c01bfc06e1 188 */
discypus 0:82c01bfc06e1 189 void
discypus 0:82c01bfc06e1 190 write_bytes(const uint16_t address, const uint8_t __restrict data[], const uint16_t size) {
discypus 1:793321f410a9 191 const uint8_t address_high = (address >> (8 * 1)) & 0xFFu;
discypus 1:793321f410a9 192 const uint8_t address_low = (address >> (8 * 0)) & 0xFFu;
discypus 1:793321f410a9 193
discypus 0:82c01bfc06e1 194 assert_CS();
discypus 0:82c01bfc06e1 195 spi.write(WRITE);
discypus 1:793321f410a9 196 spi.write(address_high);
discypus 1:793321f410a9 197 spi.write(address_low);
discypus 0:82c01bfc06e1 198 for (uint16_t i = 0; i < size; ++i) {
discypus 0:82c01bfc06e1 199 spi.write(data[i]);
discypus 0:82c01bfc06e1 200 }
discypus 0:82c01bfc06e1 201 negate_CS();
discypus 0:82c01bfc06e1 202 }
discypus 0:82c01bfc06e1 203
discypus 0:82c01bfc06e1 204 /*
discypus 0:82c01bfc06e1 205 *
discypus 0:82c01bfc06e1 206 */
discypus 0:82c01bfc06e1 207
discypus 0:82c01bfc06e1 208
discypus 0:82c01bfc06e1 209 /** 動作確認用 SPI buffer */
discypus 0:82c01bfc06e1 210 uint8_t buf[256] = {};
discypus 0:82c01bfc06e1 211
discypus 0:82c01bfc06e1 212 /**
discypus 0:82c01bfc06e1 213 * 動作確認用。TODO: テストコードにすること。
discypus 0:82c01bfc06e1 214 */
discypus 0:82c01bfc06e1 215 void
discypus 0:82c01bfc06e1 216 try_byte_access() {
discypus 0:82c01bfc06e1 217 const uint8_t size = 16;
discypus 0:82c01bfc06e1 218
discypus 0:82c01bfc06e1 219 change_mode(BYTE);
discypus 0:82c01bfc06e1 220
discypus 0:82c01bfc06e1 221 // write data
discypus 0:82c01bfc06e1 222 for (int i = 0; i < size; i++) {
discypus 0:82c01bfc06e1 223 write_byte(i, i);
discypus 0:82c01bfc06e1 224 }
discypus 0:82c01bfc06e1 225
discypus 0:82c01bfc06e1 226 // read data
discypus 0:82c01bfc06e1 227 for (int i = 0; i < size; i++) {
discypus 0:82c01bfc06e1 228 buf[i] = read_byte(i);
discypus 0:82c01bfc06e1 229 }
discypus 0:82c01bfc06e1 230
discypus 0:82c01bfc06e1 231 // show data (to SERIAL)
discypus 0:82c01bfc06e1 232 pc.printf("byte access test: result\r\n");
discypus 0:82c01bfc06e1 233 for (int i = 0; i < size; i++) {
discypus 0:82c01bfc06e1 234 pc.printf(" %04x : %02x\r\n", i, buf[i]);
discypus 0:82c01bfc06e1 235 }
discypus 0:82c01bfc06e1 236 }
discypus 0:82c01bfc06e1 237
discypus 0:82c01bfc06e1 238 /**
discypus 0:82c01bfc06e1 239 * 動作確認用。TODO: テストコードにすること。
discypus 0:82c01bfc06e1 240 */
discypus 0:82c01bfc06e1 241 void
discypus 0:82c01bfc06e1 242 try_page_access() {
discypus 1:793321f410a9 243 const uint16_t address = 0x1000;
discypus 0:82c01bfc06e1 244 const uint16_t size = 32;
discypus 0:82c01bfc06e1 245
discypus 1:793321f410a9 246 change_mode(PAGE);
discypus 1:793321f410a9 247
discypus 0:82c01bfc06e1 248 // write
discypus 0:82c01bfc06e1 249 for (uint16_t i = 0; i < size; ++i) {
discypus 0:82c01bfc06e1 250 buf[i] = i;
discypus 0:82c01bfc06e1 251 }
discypus 1:793321f410a9 252 write_bytes(address, buf, size);
discypus 0:82c01bfc06e1 253
discypus 0:82c01bfc06e1 254 // read
discypus 0:82c01bfc06e1 255 for (uint16_t i = 0; i < size; ++i) {
discypus 0:82c01bfc06e1 256 buf[i] = 0;
discypus 0:82c01bfc06e1 257 }
discypus 0:82c01bfc06e1 258
discypus 1:793321f410a9 259 read_bytes(address, buf, size);
discypus 0:82c01bfc06e1 260
discypus 0:82c01bfc06e1 261 // show data (to SERIAL)
discypus 0:82c01bfc06e1 262 pc.printf("page access test: result\r\n");
discypus 0:82c01bfc06e1 263 for (int i = 0; i < size; i++) {
discypus 1:793321f410a9 264 pc.printf(" %04x : %02x\r\n", address + i, buf[i]);
discypus 0:82c01bfc06e1 265 }
discypus 0:82c01bfc06e1 266 }
discypus 0:82c01bfc06e1 267
discypus 0:82c01bfc06e1 268 /**
discypus 0:82c01bfc06e1 269 * 動作確認用。TODO: テストコードにすること。
discypus 0:82c01bfc06e1 270 */
discypus 0:82c01bfc06e1 271 void
discypus 0:82c01bfc06e1 272 try_sequential_access() {
discypus 1:793321f410a9 273 const uint16_t address = 0x2000;
discypus 0:82c01bfc06e1 274 const uint16_t size = 256;
discypus 0:82c01bfc06e1 275
discypus 1:793321f410a9 276 change_mode(SEQUENTIAL);
discypus 1:793321f410a9 277
discypus 0:82c01bfc06e1 278 // write
discypus 0:82c01bfc06e1 279 for (uint16_t i = 0; i < size; ++i) {
discypus 0:82c01bfc06e1 280 buf[i] = i;
discypus 0:82c01bfc06e1 281 }
discypus 0:82c01bfc06e1 282
discypus 1:793321f410a9 283 write_bytes(address, buf, size);
discypus 0:82c01bfc06e1 284
discypus 0:82c01bfc06e1 285 // read
discypus 0:82c01bfc06e1 286 for (uint16_t i = 0; i < size; ++i) {
discypus 0:82c01bfc06e1 287 buf[i] = 0;
discypus 0:82c01bfc06e1 288 }
discypus 0:82c01bfc06e1 289
discypus 1:793321f410a9 290 read_bytes(address, buf, size);
discypus 0:82c01bfc06e1 291
discypus 0:82c01bfc06e1 292 // show data (to SERIAL)
discypus 0:82c01bfc06e1 293 pc.printf("sequential access test: result\r\n");
discypus 0:82c01bfc06e1 294 for (int i = 0; i < size; i++) {
discypus 1:793321f410a9 295 pc.printf(" %04x : %02x\r\n", address + i, buf[i]);
discypus 0:82c01bfc06e1 296 }
discypus 0:82c01bfc06e1 297 }
discypus 0:82c01bfc06e1 298
discypus 0:82c01bfc06e1 299
discypus 0:82c01bfc06e1 300 void
discypus 0:82c01bfc06e1 301 try_single_byte_access() {
discypus 0:82c01bfc06e1 302 cs = 0;
discypus 0:82c01bfc06e1 303 spi.write(0x02u);
discypus 0:82c01bfc06e1 304 spi.write(0);
discypus 0:82c01bfc06e1 305 spi.write(0);
discypus 0:82c01bfc06e1 306 spi.write(0x5a);
discypus 0:82c01bfc06e1 307 cs = 1;
discypus 0:82c01bfc06e1 308
discypus 0:82c01bfc06e1 309 cs = 0;
discypus 0:82c01bfc06e1 310 spi.write(0x03u);
discypus 0:82c01bfc06e1 311 spi.write(0);
discypus 0:82c01bfc06e1 312 spi.write(0);
discypus 1:793321f410a9 313 const uint8_t value = spi.write(0);
discypus 0:82c01bfc06e1 314 cs = 1;
discypus 0:82c01bfc06e1 315
discypus 0:82c01bfc06e1 316 pc.printf("read: 0x%02x\r\n", value);
discypus 0:82c01bfc06e1 317 }
discypus 0:82c01bfc06e1 318
discypus 2:0248049e65f1 319
discypus 0:82c01bfc06e1 320 /**
discypus 0:82c01bfc06e1 321 * 動作確認用。TODO: テストコードにすること。
discypus 0:82c01bfc06e1 322 */
discypus 0:82c01bfc06e1 323 int
discypus 0:82c01bfc06e1 324 main()
discypus 0:82c01bfc06e1 325 {
discypus 2:0248049e65f1 326 mybutton.fall(&pressed);
discypus 2:0248049e65f1 327
discypus 2:0248049e65f1 328 wait_until_user_button_pressed();
discypus 2:0248049e65f1 329
discypus 0:82c01bfc06e1 330 // initialize
discypus 0:82c01bfc06e1 331 spi.format(8, 0); // 8bit, mode=0
discypus 0:82c01bfc06e1 332 spi.frequency(20 * 1000 * 1000); // max 20MHz
discypus 0:82c01bfc06e1 333 negate_CS();
discypus 0:82c01bfc06e1 334
discypus 0:82c01bfc06e1 335 // test
discypus 0:82c01bfc06e1 336 pc.printf("TEST START\r\n");
discypus 2:0248049e65f1 337
discypus 2:0248049e65f1 338 wait_until_user_button_pressed();
discypus 0:82c01bfc06e1 339 try_single_byte_access();
discypus 2:0248049e65f1 340
discypus 2:0248049e65f1 341 wait_until_user_button_pressed();
discypus 0:82c01bfc06e1 342 try_byte_access();
discypus 2:0248049e65f1 343
discypus 0:82c01bfc06e1 344 try_page_access();
discypus 2:0248049e65f1 345
discypus 2:0248049e65f1 346 wait_until_user_button_pressed();
discypus 0:82c01bfc06e1 347 try_sequential_access();
discypus 2:0248049e65f1 348
discypus 0:82c01bfc06e1 349 pc.printf("TEST END\r\n\r\n");
discypus 0:82c01bfc06e1 350
discypus 0:82c01bfc06e1 351 return 0;
discypus 0:82c01bfc06e1 352 }