Chihiro H
/
Microchip23K256_demo
Microchip 23K256 (SPI SRAM) sample code for https://www.switch-science.com/catalog/1072/ module.
Embed:
(wiki syntax)
Show/hide line numbers
main.cpp
00001 /* 00002 * sample for Microchip 23K256 (SRAM, SPI 20MHz) 00003 */ 00004 00005 #include "mbed.h" 00006 00007 /** Serial port for DEBUG */ 00008 Serial pc(USBTX, USBRX); 00009 00010 DigitalIn user_button(USER_BUTTON); 00011 00012 /** */ 00013 SPI spi(SPI_MOSI, SPI_MISO, SPI_SCK); 00014 00015 /** */ 00016 DigitalOut cs(SPI_CS); 00017 00018 /** 00019 * USERボタンが押されるまで待つ。 00020 */ 00021 void 00022 wait_until_user_button_pressed() { 00023 while (user_button) { 00024 __nop(); 00025 } 00026 pc.printf("USER button is pressed\r\n"); 00027 wait(0.2); 00028 } 00029 00030 /* 00031 * SPI COMMAND (Microchip 23K256 SRAM) 00032 * 1byte read/write 00033 * page read/write 00034 * sequential read/write 00035 * status/configuration register read/write 00036 */ 00037 enum Microchip23K256Commnd { 00038 READ = 0x03u, 00039 WRITE = 0x02u, 00040 RDSR = 0x05u, 00041 WRSR = 0x01u, 00042 }; 00043 00044 /** SRAM Mode (Microchip 23K256 SRAM) */ 00045 enum Microchip23K256Mode { 00046 MODE_MASK = 0xc0u, 00047 BYTE = 0x00u, 00048 PAGE = 0x80u, 00049 SEQUENTIAL = 0x40u, 00050 }; 00051 00052 /** 00053 * assert CS 00054 */ 00055 inline void 00056 assert_CS() { 00057 cs = 0; 00058 } 00059 00060 /** 00061 * negate CS 00062 */ 00063 inline void 00064 negate_CS() { 00065 cs = 1; 00066 } 00067 00068 /** 00069 * ステータスレジスタ読みだし 00070 * @return レジスタ値 00071 */ 00072 inline uint8_t 00073 read_status_register() { 00074 assert_CS(); 00075 spi.write(RDSR); 00076 const uint8_t status = spi.write(0x00); 00077 negate_CS(); 00078 00079 return status; 00080 } 00081 00082 /** 00083 * ステータスレジスタ書き込み 00084 * @param[in] status 00085 */ 00086 inline void 00087 write_status_register(const uint8_t status) { 00088 assert_CS(); 00089 spi.write(WRSR); 00090 spi.write(status); 00091 negate_CS(); 00092 } 00093 00094 /** 00095 * モードを切り替える。 00096 * @param[in] mode モード 00097 * @return 切替前のモード 00098 * @invariant ステータスレジスタ中のモード以外のフラグは変更しない。 00099 */ 00100 inline uint8_t 00101 change_mode(const unsigned int next_mode) { 00102 const uint8_t previous_status = read_status_register(); 00103 const uint8_t previous_mode = previous_status & MODE_MASK; 00104 if (next_mode != previous_mode) { 00105 const uint8_t next_status = (previous_status & ~MODE_MASK) | uint8_t(next_mode); 00106 write_status_register(next_status); 00107 } 00108 return previous_mode; 00109 } 00110 00111 /** 00112 * 1byte read 00113 * @param[in] address アドレス 16bit。容量32KBなので、MSBは無視する 00114 * @return データ 00115 * @pre byteモードに切り替えていること。 00116 */ 00117 uint8_t 00118 read_byte(const uint16_t address) { 00119 const uint8_t address_high = (address >> (8 * 1)) & 0xFFu; 00120 const uint8_t address_low = (address >> (8 * 0)) & 0xFFu; 00121 00122 assert_CS(); 00123 spi.write(READ); 00124 spi.write(address_high); 00125 spi.write(address_low); 00126 const uint8_t data = spi.write(0); 00127 negate_CS(); 00128 00129 return data; 00130 } 00131 00132 /** 00133 * 1byte write 00134 * @param[in] address アドレス 16bit。容量32KBなので、MSBは無視する 00135 * @param[in] data データ 00136 * @pre byteモードに切り替えていること。 00137 */ 00138 void 00139 write_byte(const uint16_t address, const uint8_t data) { 00140 const uint8_t address_high = (address >> (8 * 1)) & 0xFFu; 00141 const uint8_t address_low = (address >> (8 * 0)) & 0xFFu; 00142 00143 assert_CS(); 00144 spi.write(WRITE); 00145 spi.write(address_high); 00146 spi.write(address_low); 00147 spi.write(data); 00148 negate_CS(); 00149 } 00150 00151 /** 00152 * 連続読み出し 00153 * @pre pageモードかbyteモードに切り替えていること。 00154 */ 00155 void 00156 read_bytes(const uint16_t address, uint8_t __restrict data[], const uint16_t size) { 00157 const uint8_t address_high = (address >> (8 * 1)) & 0xFFu; 00158 const uint8_t address_low = (address >> (8 * 0)) & 0xFFu; 00159 00160 assert_CS(); 00161 spi.write(READ); 00162 spi.write(address_high); 00163 spi.write(address_low); 00164 for (uint16_t i = 0; i < size; ++i) { 00165 data[i] = spi.write(0x00); 00166 } 00167 negate_CS(); 00168 } 00169 00170 /** 00171 * 連続書き込み 00172 * @pre pageモードかbyteモードに切り替えていること。 00173 */ 00174 void 00175 write_bytes(const uint16_t address, const uint8_t __restrict data[], const uint16_t size) { 00176 const uint8_t address_high = (address >> (8 * 1)) & 0xFFu; 00177 const uint8_t address_low = (address >> (8 * 0)) & 0xFFu; 00178 00179 assert_CS(); 00180 spi.write(WRITE); 00181 spi.write(address_high); 00182 spi.write(address_low); 00183 for (uint16_t i = 0; i < size; ++i) { 00184 spi.write(data[i]); 00185 } 00186 negate_CS(); 00187 } 00188 00189 /* 00190 * 00191 */ 00192 00193 00194 /** 動作確認用 SPI buffer */ 00195 uint8_t buf[256] = {}; 00196 00197 /** 00198 * 動作確認用。TODO: テストコードにすること。 00199 */ 00200 void 00201 try_byte_access() { 00202 const uint8_t size = 16; 00203 00204 change_mode(BYTE); 00205 00206 // write data 00207 for (int i = 0; i < size; i++) { 00208 write_byte(i, i); 00209 } 00210 00211 // read data 00212 for (int i = 0; i < size; i++) { 00213 buf[i] = read_byte(i); 00214 } 00215 00216 // show data (to SERIAL) 00217 pc.printf("byte access test: result\r\n"); 00218 for (int i = 0; i < size; i++) { 00219 pc.printf(" %04x : %02x %s\r\n", i, buf[i], (buf[i] ==i)?"OK":"BAD"); 00220 } 00221 } 00222 00223 /** 00224 * 動作確認用。TODO: テストコードにすること。 00225 */ 00226 void 00227 try_page_access() { 00228 const uint16_t address = 0x1000; 00229 const uint16_t size = 32; 00230 00231 change_mode(PAGE); 00232 00233 // write 00234 for (uint16_t i = 0; i < size; ++i) { 00235 buf[i] = i; 00236 } 00237 write_bytes(address, buf, size); 00238 00239 // read 00240 for (uint16_t i = 0; i < size; ++i) { 00241 buf[i] = 0; 00242 } 00243 00244 read_bytes(address, buf, size); 00245 00246 // show data (to SERIAL) 00247 pc.printf("page access test: result\r\n"); 00248 for (int i = 0; i < size; i++) { 00249 pc.printf(" %04x : %02x %s\r\n", address + i, buf[i], (buf[i] ==i)?"OK":"BAD"); 00250 } 00251 } 00252 00253 /** 00254 * 動作確認用。TODO: テストコードにすること。 00255 */ 00256 void 00257 try_sequential_access() { 00258 const uint16_t address = 0x2000; 00259 const uint16_t size = 256; 00260 00261 change_mode(SEQUENTIAL); 00262 00263 // write 00264 for (uint16_t i = 0; i < size; ++i) { 00265 buf[i] = i; 00266 } 00267 00268 write_bytes(address, buf, size); 00269 00270 // read 00271 for (uint16_t i = 0; i < size; ++i) { 00272 buf[i] = 0; 00273 } 00274 00275 read_bytes(address, buf, size); 00276 00277 // show data (to SERIAL) 00278 pc.printf("sequential access test: result\r\n"); 00279 for (int i = 0; i < size; i++) { 00280 pc.printf(" %04x : %02x %s\r\n", address + i, buf[i], (buf[i] ==i)?"OK":"BAD"); 00281 } 00282 } 00283 00284 00285 /** 00286 * 00287 * @pre SPI初期化済初期和美であること。バイトモードであること 00288 */ 00289 void 00290 try_single_byte_access() { 00291 const uint8_t address_high = (0x12 >> (8 * 1)) & 0xFFu; 00292 const uint8_t address_low = (0x13 >> (8 * 0)) & 0xFFu; 00293 00294 const uint8_t command_write = 0x02u; 00295 const uint8_t command_read = 0x03u; 00296 00297 const uint8_t data = 0x55; 00298 00299 // 1byte write 00300 cs = 0; 00301 spi.write(command_write); 00302 spi.write(address_high); 00303 spi.write(address_low); 00304 spi.write(data); 00305 cs = 1; 00306 00307 // 1byte read 00308 cs = 0; 00309 spi.write(command_read); 00310 spi.write(address_high); 00311 spi.write(address_low); 00312 const uint8_t value = spi.write(0); 00313 cs = 1; 00314 00315 pc.printf("write: %02x -> read: %02x\r\n", data, value); 00316 } 00317 00318 00319 /** 00320 * 動作確認用。TODO: テストコードにすること。 00321 */ 00322 int 00323 main() 00324 { 00325 pc.baud(115200); 00326 pc.printf("CPU SystemCoreClock is %.2f MHz\r\n", (float)SystemCoreClock/1.0e6f); 00327 00328 // initialize SPI 00329 spi.format(8, 0); // 8bit, mode=0 00330 spi.frequency(20 * 1000 * 1000); // max 20MHz 00331 negate_CS(); 00332 00333 // test 00334 pc.printf("\r\npush user button to start: try_single_byte_access\r\n"); 00335 wait_until_user_button_pressed(); 00336 try_single_byte_access(); 00337 00338 pc.printf("\r\npush user button to start: try_byte_access\r\n"); 00339 wait_until_user_button_pressed(); 00340 try_byte_access(); 00341 00342 pc.printf("\r\npush user button to start: try_page_access\r\n"); 00343 wait_until_user_button_pressed(); 00344 try_page_access(); 00345 00346 pc.printf("\r\npush user button to start: try_sequential_access\r\n"); 00347 wait_until_user_button_pressed(); 00348 try_sequential_access(); 00349 00350 pc.printf("\r\nTEST END\r\n\r\n"); 00351 00352 for(;;) { 00353 } 00354 }
Generated on Fri Aug 26 2022 21:48:19 by 1.7.2