mirror of https://github.com/ARMmbed/mbed-os.git
Removing SPIBlockDevice module as present in spiflash-driver repository.
parent
c7dba87363
commit
e2fc4fcc44
455
README.md
455
README.md
|
@ -262,7 +262,7 @@ is described in more detail in the [Testing with an SDCard on Target XYZ](#testi
|
|||
|
||||
Next, build the example application:
|
||||
|
||||
simhug01@E107851:/d/demo_area/sd_ex1$ mbed compile -m K64F -t GCC_ARM 2>&1 | tee build_log.txt
|
||||
simhug01@E107851:/d/demo_area/sd_ex1$ mbed compile -m K64F -t GCC_ARM
|
||||
|
||||
|
||||
#### WARNING: "mbed new ." command and possible mbed-os sd-driver versioning incompatibilities
|
||||
|
@ -617,7 +617,7 @@ and is discussed in the [Testing with an SDCard on Target XYZ](#testing-with-an-
|
|||
|
||||
Build the test cases for the K64F target using the following command:
|
||||
|
||||
simhug01@E107851:/d/demo_area/ex_app1$ mbed -v test --compile -t GCC_ARM -m K64F --app-config mbed_app.json 2>&1 | tee build_tests_gcc_20161219_1007.txt
|
||||
simhug01@E107851:/d/demo_area/ex_app1$ mbed -v test --compile -t GCC_ARM -m K64F --app-config mbed_app.json
|
||||
<trace removed>
|
||||
simhug01@E107851:/d/demo_area/ex_app1$
|
||||
|
||||
|
@ -696,11 +696,11 @@ The names of the tests can be listed using:
|
|||
|
||||
For example, to run the basic test use:
|
||||
|
||||
simhug01@E107851:/d/demo_area/ex_app1$ mbedgt -VS --test-by-names=sd-driver-features-tests-filesystem-basic 2>&1 | tee run_tests_basic.txt
|
||||
simhug01@E107851:/d/demo_area/ex_app1$ mbedgt -VS --test-by-names=sd-driver-features-tests-filesystem-basic
|
||||
|
||||
To run the fopen test use:
|
||||
|
||||
simhug01@E107851:/d/demo_area/ex_app1$ mbedgt -VS --test-by-names=sd-driver-features-tests-filesystem-fopen 2>&1 | tee run_tests_fopen.txt
|
||||
simhug01@E107851:/d/demo_area/ex_app1$ mbedgt -VS --test-by-names=sd-driver-features-tests-filesystem-fopen
|
||||
|
||||
On a successful run, results similar to the following will be shown:
|
||||
|
||||
|
@ -823,449 +823,16 @@ Basic errno reporting is supported, tested and known to be working.
|
|||
|
||||
The following are related mbed storage projects and useful resources:
|
||||
|
||||
- The [mbed-os repository](https://github.com/ARMmbed/mbed-os). This is the main mbed OS repository.
|
||||
- The [mbed-os-example-fat-filesystem repository](https://github.com/ARMmbed/mbed-os-example-fat-filesystem).
|
||||
- The [mbed-os](https://github.com/ARMmbed/mbed-os) main repository.
|
||||
- The [mbed-os-example-fat-filesystem](https://github.com/ARMmbed/mbed-os-example-fat-filesystem) repository.
|
||||
This is an example project for the mbed OS FAT filesystem.
|
||||
- The [spiflash-driver repository](https://github.com/armmbed/spiflash-driver)
|
||||
- The [i2ceeprom-driver repository](https://github.com/ARMmbed/i2ceeprom-driver.git)
|
||||
- The [ci-test-shield repository](https://github.com/ARMmbed/ci-test-shield). This is the project describing
|
||||
- The [spiflash-driver](https://github.com/armmbed/spiflash-driver) repository.
|
||||
- The [i2ceeprom-driver](https://github.com/ARMmbed/i2ceeprom-driver.git) repository.
|
||||
- The [ci-test-shield](https://github.com/ARMmbed/ci-test-shield) repository. This is the project describing
|
||||
the mbed-os Continuous Integration test shield, together with standard tests.
|
||||
- The [mbed-HDK](https://github.com/ARMmbed/mbed-HDK) repository containing Hardware Development Kit resources
|
||||
including the schematics for the CI test shield.
|
||||
- [POSIX File Interface ISO/IEC 9899:TC2 Documentation](http://www.eng.utah.edu/~cs5785/slides-f10/n1124.pdf).
|
||||
- [FATFS: Generic FAT File System Module used in mbed OS](http://elm-chan.org/fsw/ff/00index_e.html)
|
||||
|
||||
|
||||
# Appendix 1: Getting Started with SPIFlash-Driver Example
|
||||
|
||||
## Overview
|
||||
|
||||
This example describes how to build and run the spiflash-driver SPIFBlockDevice examples to
|
||||
read and write data to a SPI NOR flash part connected to a K64F.
|
||||
|
||||
Hardware required:
|
||||
|
||||
- K64F.
|
||||
- CI test shield.
|
||||
- SPI NOR Flash Device wired to Arduino header pins e.g. the Macronix MX25R2035F. The datasheet is available
|
||||
from the [Macronix website](http://www.macronix.com/).
|
||||
- Micro USB cable.
|
||||
|
||||
Software required:
|
||||
|
||||
- mbed CLI (with all other dependencies installed).
|
||||
- ARMCC / GCC_ARM / IAR compiler.
|
||||
- mbed greentea.
|
||||
- git account.
|
||||
|
||||
Github repos to use:
|
||||
|
||||
- The [mbed OS repository](https://github.com/armmbed/mbed-os)
|
||||
- The [SPI Flash Driver repository](https://github.com/armmbed/spiflash-driver)
|
||||
|
||||
## Simple SPIFBlockDevice Example
|
||||
|
||||
This section describes how to create an application project combining the
|
||||
mbed-os and spiflash-driver repositories into a single project.
|
||||
In summary the following steps will be covered in this section:
|
||||
|
||||
- A top level application project directory is created. The directory name is ex_app2.
|
||||
- In the ex_app2 directory, the mbed-os repository is cloned.
|
||||
- In the ex_app2 directory at the same level as the mbed-os directory, the spiflash-driver repository is cloned.
|
||||
|
||||
First create the top level application directory ex_app2 and move into it:
|
||||
|
||||
simhug01@E107851:/d/demo_area$ mkdir ex_app2
|
||||
simhug01@E107851:/d/demo_area$ pushd ex_app2
|
||||
|
||||
Next, get a clone of public mbed OS repository in the following way:
|
||||
|
||||
simhug01@E107851:/d/demo_area/ex_app2$ git clone git@github.com:/armmbed/mbed-os
|
||||
<trace removed>
|
||||
simhug01@E107851:/d/demo_area/ex_app2$
|
||||
|
||||
Next, get a clone of the spiflash-driver repository:
|
||||
|
||||
simhug01@E107851:/d/demo_area/ex_app2$ git clone git@github.com:/armmbed/spiflash-driver
|
||||
<trace removed>
|
||||
simhug01@E107851:/d/demo_area/ex_app2$
|
||||
|
||||
In the top level directory create the example2.cpp:
|
||||
|
||||
simhug01@E107851:/d/demo_area/ex_app2$ touch example2.cpp
|
||||
|
||||
Copy the [spiflash-driver example code](https://github.com/armmbed/spiflash-driver)
|
||||
and paste into example2.cpp (reproduced here for convenience and corrected to build for
|
||||
GCC_ARM):
|
||||
|
||||
// Here's an example using the MX25R SPI flash device on the K82F
|
||||
#include "mbed.h"
|
||||
#include "SPIFBlockDevice.h"
|
||||
|
||||
/* This is the original configuration of the SPI Flash Driver
|
||||
* pins for Freescale K82F development board. We're not using
|
||||
* this as we're using the CI Test Shield
|
||||
*/
|
||||
// Create flash device on SPI bus with PTE5 as chip select
|
||||
//SPIFBlockDevice spif(PTE2, PTE4, PTE1, PTE5);
|
||||
|
||||
/* This configuration of the SPI Flash Driver pins is for
|
||||
* the Freescale K64F connecting the SPI pins on the
|
||||
* Arduino header to the SPI NOR part.
|
||||
*/
|
||||
SPIFBlockDevice spif(D11, D12, D13, D10);
|
||||
|
||||
|
||||
int main() {
|
||||
printf("spif test\n");
|
||||
|
||||
// Initialize the SPI flash device and print the memory layout
|
||||
spif.init();
|
||||
printf("spif size: %llu\n", spif.size());
|
||||
printf("spif read size: %llu\n", spif.get_read_size());
|
||||
printf("spif program size: %llu\n", spif.get_program_size());
|
||||
printf("spif erase size: %llu\n", spif.get_erase_size());
|
||||
|
||||
// Write "Hello World!" to the first block
|
||||
char *buffer = (char*) malloc(spif.get_erase_size());
|
||||
sprintf(buffer, "Hello World!\n");
|
||||
spif.erase(0, spif.get_erase_size());
|
||||
spif.program(buffer, 0, spif.get_erase_size());
|
||||
|
||||
// Read back what was stored
|
||||
spif.read(buffer, 0, spif.get_erase_size());
|
||||
printf("%s", buffer);
|
||||
|
||||
// Deinitialize the device
|
||||
spif.deinit();
|
||||
}
|
||||
|
||||
Note the following modifications to the original code sample:
|
||||
|
||||
- The SPI Flash Driver instance `spif` is given the pin configuration
|
||||
for the SPI bus from the Arduino header pins D11, D12, D13 and D10,
|
||||
as noted in the comments.
|
||||
- The buffer type has been modified to char* to (see line with malloc() above).
|
||||
|
||||
The application can be built with the following command:
|
||||
|
||||
simhug01@E107851:/d/demo_area/ex_app2$ mbed compile -m K64F -t GCC_ARM 2>&1 | tee build_app_ex_app2_log.txt
|
||||
|
||||
Once the binary is built, copy the binary from `/d/demo_area/ex_app2/BUILD/K64F/GCC_ARM/example2.bin` to the K64F.
|
||||
After connecting a serial console and resetting the target, the following trace should be seen:
|
||||
|
||||
spif test
|
||||
spif size: 2097152
|
||||
spif read size: 1
|
||||
spif program size: 1
|
||||
spif erase size: 4096
|
||||
Hello World!
|
||||
|
||||
|
||||
## Build the mbed OS Test Cases
|
||||
|
||||
If you have completed the previous section "Simple SPIFBlockDevice Example" then first prepare the environment by removing the BUILD
|
||||
directory and hiding or removing the example2.cpp:
|
||||
|
||||
simhug01@E107851:/d/demo_area/ex_app2$ rm -fR BUILD
|
||||
simhug01@E107851:/d/demo_area/ex_app2$ cp example2.cpp example2_cpp
|
||||
|
||||
Build the test cases for the K64F target using the following command:
|
||||
|
||||
simhug01@E107851:/d/demo_area/ex_app2$ mbed -v test --compile -t GCC_ARM -m K64F 2>&1 | tee build_tests_gcc_20170322_1007.txt
|
||||
<trace removed>
|
||||
simhug01@E107851:/d/demo_area/ex_app2$
|
||||
|
||||
The build trace is quite extensive but on a successful build you should see the following output at the end of the log:
|
||||
|
||||
Build successes:
|
||||
* K64F::GCC_ARM::MBED-BUILD
|
||||
* K64F::GCC_ARM::MBED-OS-FEATURES-FEATURE_LWIP-TESTS-MBEDMICRO-NET-CONNECTIVITY
|
||||
<trace removed>
|
||||
* K64F::GCC_ARM::MBED-OS-FEATURES-TESTS-FILESYSTEM-FAT_FILE_SYSTEM
|
||||
* K64F::GCC_ARM::MBED-OS-FEATURES-TESTS-FILESYSTEM-HEAP_BLOCK_DEVICE
|
||||
* K64F::GCC_ARM::MBED-OS-FEATURES-TESTS-FILESYSTEM-UTIL_BLOCK_DEVICE
|
||||
<trace removed>
|
||||
* K64F::GCC_ARM::MBED-OS-TESTS-STORAGE_ABSTRACTION-BASICAPI
|
||||
* K64F::GCC_ARM::SPIFLASH-DRIVER-TESTS-BLOCK_DEVICE-SPIF
|
||||
|
||||
|
||||
Build skips:
|
||||
* K64F::GCC_ARM::MBED-OS-FEATURES-FEATURE_LWIP-TESTS-MBEDMICRO-NET-TCP_PACKET_PRESSURE
|
||||
<trace removed>
|
||||
|
||||
Notice the following test in the spiflash-driver tree listed above:
|
||||
|
||||
- `K64F::GCC_ARM::SPIFLASH-DRIVER-TESTS-BLOCK_DEVICE-SPIF`
|
||||
|
||||
|
||||
The SPIFBlockDevice test case is at following locations in the source code tree:
|
||||
|
||||
/d/demo_area/ex_app2/spiflash-driver/TESTS/block_device/spif/main.cpp
|
||||
|
||||
This provides an example of reading and writing data blocks to the block device interface for the SPI NOR part.
|
||||
|
||||
Run the test using the following command:
|
||||
|
||||
simhug01@E107851:/d/demo_area/ex_app2$ mbedgt -VS --test-by-names=spiflash-driver-tests-block_device-spif 2>&1 | tee run_test_gcc_20170322_1007.txt
|
||||
|
||||
The test output should look similar to the following trace:
|
||||
|
||||
(mx_env1) simhug01@E107851:/d/datastore/public/jobs/yr2017/2278/sdh_dev_mx1/ex_app5$ mbedgt -VS --test-by-names=spiflash-driver-tests-block_device-sp
|
||||
if 2>&1 | tee 2278_run_test_ex_app5_br_master_time_20170322_1207_spif.txt
|
||||
mbedgt: greentea test automation tool ver. 1.2.5
|
||||
mbedgt: using multiple test specifications from current directory!
|
||||
using 'BUILD\tests\K64F\GCC_ARM\test_spec.json'
|
||||
mbedgt: detecting connected mbed-enabled devices...
|
||||
mbedgt: detected 1 device
|
||||
+---------------+----------------------+-------------+-------------+--------------------------------------------------+
|
||||
| platform_name | platform_name_unique | serial_port | mount_point | target_id |
|
||||
+---------------+----------------------+-------------+-------------+--------------------------------------------------+
|
||||
| K64F | K64F[0] | COM46 | E: | 0240000029304e450023500878a3001df131000097969900 |
|
||||
+---------------+----------------------+-------------+-------------+--------------------------------------------------+
|
||||
mbedgt: processing target 'K64F' toolchain 'GCC_ARM' compatible platforms... (note: switch set to --parallel 1)
|
||||
+---------------+----------------------+-------------+-------------+--------------------------------------------------+
|
||||
| platform_name | platform_name_unique | serial_port | mount_point | target_id |
|
||||
+---------------+----------------------+-------------+-------------+--------------------------------------------------+
|
||||
| K64F | K64F[0] | COM46:9600 | E: | 0240000029304e450023500878a3001df131000097969900 |
|
||||
+---------------+----------------------+-------------+-------------+--------------------------------------------------+
|
||||
mbedgt: test case filter (specified with -n option)
|
||||
test filtered in 'spiflash-driver-tests-block_device-spif'
|
||||
mbedgt: running 1 test for platform 'K64F' and toolchain 'GCC_ARM'
|
||||
use 1 instance of execution threads for testing
|
||||
mbedgt: checking for 'host_tests' directory above image directory structure
|
||||
'host_tests' directory not found: two directory levels above image path checked
|
||||
mbedgt: selecting test case observer...
|
||||
calling mbedhtrun: mbedhtrun -m K64F -p COM46:9600 -f "BUILD/tests/K64F/GCC_ARM/spiflash-driver/TESTS/block_device/spif/spif.bin" -d E: -C 4 -
|
||||
c shell -t 0240000029304e450023500878a3001df131000097969900
|
||||
mbedgt: mbed-host-test-runner: started
|
||||
[1490184626.50][HTST][INF] host test executor ver. 1.1.6
|
||||
[1490184626.50][HTST][INF] copy image onto target...
|
||||
[1490184626.50][COPY][INF] Waiting up to 60 sec for '0240000029304e450023500878a3001df131000097969900' mount point (current is 'E:')...
|
||||
1 file(s) copied.
|
||||
[1490184635.79][HTST][INF] starting host test process...
|
||||
[1490184636.10][CONN][INF] starting connection process...
|
||||
[1490184636.10][CONN][INF] notify event queue about extra 60 sec timeout for serial port pooling
|
||||
[1490184636.10][CONN][INF] initializing serial port listener...
|
||||
[1490184636.10][PLGN][INF] Waiting up to 60 sec for '0240000029304e450023500878a3001df131000097969900' serial port (current is 'COM46')...
|
||||
[1490184636.12][HTST][INF] setting timeout to: 60 sec
|
||||
[1490184636.24][SERI][INF] serial(port=COM46, baudrate=9600, timeout=0.01)
|
||||
<lines deleted to save space>
|
||||
[1490184649.90][CONN][INF] found KV pair in stream: {{__testcase_name;Testing read write random blocks}}, queued...
|
||||
[1490184649.97][CONN][RXD] >>> Running case #1: 'Testing read write random blocks'...
|
||||
[1490184650.02][CONN][INF] found KV pair in stream: {{__testcase_start;Testing read write random blocks}}, queued...
|
||||
[1490184650.05][CONN][RXD] read size: 1bytes (1bytes)
|
||||
[1490184650.08][CONN][RXD] program size: 1bytes (1bytes)
|
||||
[1490184650.12][CONN][RXD] erase size: 4kbytes (4096bytes)
|
||||
[1490184650.13][CONN][RXD] total size: 2Mbytes (2097152bytes)
|
||||
[1490184650.17][CONN][RXD] test 002d000:4096...
|
||||
[1490184650.36][CONN][RXD] write 002d000:4096 aad8573abd84e79e5e3684fa5519aabb...
|
||||
[1490184650.50][CONN][RXD] read 002d000:4096 aad8573abd84e79e5e3684fa5519aabb...
|
||||
[1490184650.56][CONN][RXD] error 002d000:4096 00000000000000000000000000000000
|
||||
[1490184650.58][CONN][RXD] test 0036000:4096...
|
||||
[1490184650.77][CONN][RXD] write 0036000:4096 92fc08f5b4113047225a8d3b855e5460...
|
||||
[1490184650.91][CONN][RXD] read 0036000:4096 92fc08f5b4113047225a8d3b855e5460...
|
||||
[1490184650.97][CONN][RXD] error 0036000:4096 00000000000000000000000000000000
|
||||
[1490184650.99][CONN][RXD] test 00c6000:4096...
|
||||
[1490184651.16][CONN][RXD] write 00c6000:4096 89a030a34b17ca3545c7b007001ef74f...
|
||||
[1490184651.32][CONN][RXD] read 00c6000:4096 89a030a34b17ca3545c7b007001ef74f...
|
||||
[1490184651.38][CONN][RXD] error 00c6000:4096 00000000000000000000000000000000
|
||||
[1490184651.40][CONN][RXD] test 00da000:4096...
|
||||
[1490184651.60][CONN][RXD] write 00da000:4096 446fd0232a3d053af820b69c614b3662...
|
||||
[1490184651.73][CONN][RXD] read 00da000:4096 446fd0232a3d053af820b69c614b3662...
|
||||
[1490184651.79][CONN][RXD] error 00da000:4096 00000000000000000000000000000000
|
||||
[1490184651.81][CONN][RXD] test 0188000:4096...
|
||||
[1490184652.00][CONN][RXD] write 0188000:4096 9a36d3c6d4034958cade542a9f1e22c2...
|
||||
[1490184652.14][CONN][RXD] read 0188000:4096 9a36d3c6d4034958cade542a9f1e22c2...
|
||||
[1490184652.20][CONN][RXD] error 0188000:4096 00000000000000000000000000000000
|
||||
[1490184652.21][CONN][RXD] test 015f000:4096...
|
||||
[1490184652.42][CONN][RXD] write 015f000:4096 70f83b9cc6713736c60089a0fa55f12d...
|
||||
[1490184652.55][CONN][RXD] read 015f000:4096 70f83b9cc6713736c60089a0fa55f12d...
|
||||
[1490184652.61][CONN][RXD] error 015f000:4096 00000000000000000000000000000000
|
||||
[1490184652.63][CONN][RXD] test 005c000:4096...
|
||||
[1490184652.82][CONN][RXD] write 005c000:4096 47a0f043fda26135877bb11c7b7016dc...
|
||||
[1490184652.96][CONN][RXD] read 005c000:4096 47a0f043fda26135877bb11c7b7016dc...
|
||||
[1490184653.02][CONN][RXD] error 005c000:4096 00000000000000000000000000000000
|
||||
[1490184653.04][CONN][RXD] test 0177000:4096...
|
||||
[1490184653.24][CONN][RXD] write 0177000:4096 174f13941b6385d4a829f2d066a1e375...
|
||||
[1490184653.37][CONN][RXD] read 0177000:4096 174f13941b6385d4a829f2d066a1e375...
|
||||
[1490184653.42][CONN][RXD] error 0177000:4096 00000000000000000000000000000000
|
||||
[1490184653.45][CONN][RXD] test 0173000:4096...
|
||||
[1490184653.65][CONN][RXD] write 0173000:4096 383f0ca8cc86e3225362805329e0d659...
|
||||
[1490184653.78][CONN][RXD] read 0173000:4096 383f0ca8cc86e3225362805329e0d659...
|
||||
[1490184653.84][CONN][RXD] error 0173000:4096 00000000000000000000000000000000
|
||||
[1490184653.86][CONN][RXD] test 01d9000:4096...
|
||||
[1490184654.05][CONN][RXD] write 01d9000:4096 73f32decf08112f271131f9837b76f28...
|
||||
[1490184654.19][CONN][RXD] read 01d9000:4096 73f32decf08112f271131f9837b76f28...
|
||||
[1490184654.24][CONN][RXD] error 01d9000:4096 00000000000000000000000000000000
|
||||
[1490184654.31][CONN][INF] found KV pair in stream: {{__testcase_finish;Testing read write random blocks;1;0}}, queued...
|
||||
[1490184654.38][CONN][RXD] >>> 'Testing read write random blocks': 1 passed, 0 failed
|
||||
[1490184654.38][CONN][RXD]
|
||||
[1490184654.41][CONN][RXD] >>> Test cases: 1 passed, 0 failed
|
||||
[1490184654.44][CONN][INF] found KV pair in stream: {{__testcase_summary;1;0}}, queued...
|
||||
[1490184654.47][CONN][INF] found KV pair in stream: {{max_heap_usage;0}}, queued...
|
||||
[1490184654.48][CONN][INF] found KV pair in stream: {{end;success}}, queued...
|
||||
[1490184654.48][HTST][ERR] orphan event in main phase: {{max_heap_usage;0}}, timestamp=1490184654.467000
|
||||
[1490184654.48][HTST][INF] __notify_complete(True)
|
||||
[1490184654.50][CONN][INF] found KV pair in stream: {{__exit;0}}, queued...
|
||||
[1490184654.51][HTST][INF] __exit(0)
|
||||
[1490184654.52][HTST][INF] __exit_event_queue received
|
||||
[1490184654.52][HTST][INF] test suite run finished after 4.75 sec...
|
||||
[1490184654.53][CONN][INF] received special even '__host_test_finished' value='True', finishing
|
||||
[1490184654.53][HTST][INF] CONN exited with code: 0
|
||||
[1490184654.53][HTST][INF] No events in queue
|
||||
[1490184654.53][HTST][INF] stopped consuming events
|
||||
[1490184654.53][HTST][INF] host test result() call skipped, received: True
|
||||
[1490184654.53][HTST][INF] calling blocking teardown()
|
||||
[1490184654.53][HTST][INF] teardown() finished
|
||||
[1490184654.53][HTST][INF] {{result;success}}
|
||||
mbedgt: checking for GCOV data...
|
||||
mbedgt: mbed-host-test-runner: stopped and returned 'OK'
|
||||
mbedgt: test on hardware with target id: 0240000029304e450023500878a3001df131000097969900
|
||||
mbedgt: test suite 'spiflash-driver-tests-block_device-spif' ......................................... OK in 28.42 sec
|
||||
test case: 'Testing read write random blocks' ................................................ OK in 4.29 sec
|
||||
mbedgt: test case summary: 1 pass, 0 failures
|
||||
mbedgt: all tests finished!
|
||||
mbedgt: shuffle seed: 0.0217829158
|
||||
mbedgt: test suite report:
|
||||
+--------------+---------------+-----------------------------------------+--------+--------------------+-------------+
|
||||
| target | platform_name | test suite | result | elapsed_time (sec) | copy_method |
|
||||
+--------------+---------------+-----------------------------------------+--------+--------------------+-------------+
|
||||
| K64F-GCC_ARM | K64F | spiflash-driver-tests-block_device-spif | OK | 28.42 | shell |
|
||||
+--------------+---------------+-----------------------------------------+--------+--------------------+-------------+
|
||||
mbedgt: test suite results: 1 OK
|
||||
mbedgt: test case report:
|
||||
+--------------+---------------+-----------------------------------------+----------------------------------+--------+--------+--------+--------------------+
|
||||
| target | platform_name | test suite | test case | passed | failed | result | elapsed_time (sec) |
|
||||
+--------------+---------------+-----------------------------------------+----------------------------------+--------+--------+--------+--------------------+
|
||||
| K64F-GCC_ARM | K64F | spiflash-driver-tests-block_device-spif | Testing read write random blocks | 1 | 0 | OK | 4.29 |
|
||||
+--------------+---------------+-----------------------------------------+----------------------------------+--------+--------+--------+--------------------+
|
||||
mbedgt: test case results: 1 OK
|
||||
mbedgt: completed in 35.04 sec
|
||||
(mx_env1) simhug01@E107851:/d/datastore/public/jobs/yr2017/2278/sdh_dev_mx1/ex_app5$
|
||||
|
||||
|
||||
|
||||
# Appendix 2: Getting Started With The I2C EEPROM Driver
|
||||
|
||||
Hardware required:
|
||||
|
||||
- K64F.
|
||||
- CI test shield.
|
||||
- Micro USB cable.
|
||||
|
||||
Software required:
|
||||
|
||||
- mbed CLI (with all other dependencies installed).
|
||||
- ARMCC / GCC / IAR compiler.
|
||||
- mbed greentea.
|
||||
- git account.
|
||||
|
||||
Github repos to use:
|
||||
|
||||
- The [mbed OS repository](https://github.com/armmbed/mbed-os)
|
||||
- The [I2C EEPROM driver repository](https://github.com/ARMmbed/i2ceeprom-driver.git)
|
||||
- The [CI test shield repository](https://github.com/ARMmbed/ci-test-shield.git) for `mbed_app.json` application configuration file.
|
||||
|
||||
Steps to follow:
|
||||
|
||||
- Create an empty example project in a suitable directory. Move into it.
|
||||
- Download mbed OS into the example directory via `mbed new .`
|
||||
- Add the I2C EEPROM driver via `mbed add i2ceeprom-driver`
|
||||
- Clone the CI test shield repository to another suitable directory. Copy the mbed_app.json
|
||||
from the CI test shield directory to the top level of the newly created example directory.
|
||||
- Make sure the I2C pins are SDA on D14 and SCL on D15 and the I2C EEPROM slave address is
|
||||
0xA0 in the mbed_app.json that you just copied.
|
||||
- Connect the target to the host machine. Run `mbed detect` to make sure the target is detected.
|
||||
- Now we are ready to run the greentea tests on this target with
|
||||
`mbed test -t ARM -m K64F -n i2ceeprom-driver-tests-block_device-i2cee -v`
|
||||
- Note that the greentea test above makes use of the main.cpp supplied in the
|
||||
`TESTS\block_device\i2cee` directory. You can customize this if required or use your own test
|
||||
application via main.cpp. Be sure to have only 1 main(). If using a custom main() then you
|
||||
can either have this in the TESTS directory or at the top level example directory.
|
||||
- The tests should pass. If not, time to debug!!
|
||||
- For other targets, please change the target ID string in the test command above to the
|
||||
appropriate one. You can check the supported targets from mbed CLI using `mbed target --supported`.
|
||||
|
||||
The output should be like this:
|
||||
|
||||
|
||||
Building library mbed-build (K64F, ARM)
|
||||
Scan: i2c_ex1
|
||||
Scan: FEATURE_BLE
|
||||
Scan: FEATURE_COMMON_PAL
|
||||
Scan: FEATURE_LWIP
|
||||
Scan: FEATURE_UVISOR
|
||||
Scan: FEATURE_ETHERNET_HOST
|
||||
Scan: FEATURE_LOWPAN_BORDER_ROUTER
|
||||
Scan: FEATURE_LOWPAN_HOST
|
||||
Scan: FEATURE_LOWPAN_ROUTER
|
||||
Scan: FEATURE_NANOSTACK
|
||||
Scan: FEATURE_NANOSTACK_FULL
|
||||
Scan: FEATURE_THREAD_BORDER_ROUTER
|
||||
Scan: FEATURE_THREAD_END_DEVICE
|
||||
Scan: FEATURE_THREAD_ROUTER
|
||||
Scan: FEATURE_STORAGE
|
||||
Scan: ARM
|
||||
Scan: FEATURE_LWIP
|
||||
Scan: FEATURE_STORAGE
|
||||
Building project i2cee (K64F, ARM)
|
||||
Scan: ARM
|
||||
Scan: FEATURE_LWIP
|
||||
Scan: FEATURE_STORAGE
|
||||
Scan: i2cee
|
||||
+-----------+-------+-------+-------+
|
||||
| Module | .text | .data | .bss |
|
||||
+-----------+-------+-------+-------+
|
||||
| Misc | 49473 | 420 | 11628 |
|
||||
| Subtotals | 49473 | 420 | 11628 |
|
||||
+-----------+-------+-------+-------+
|
||||
Allocated Heap: unknown
|
||||
Allocated Stack: unknown
|
||||
Total Static RAM memory (data + bss): 12048 bytes
|
||||
Total RAM memory (data + bss + heap + stack): 12048 bytes
|
||||
Total Flash memory (text + data + misc): 49893 bytes
|
||||
Image: BUILD/tests/K64F/ARM/i2ceeprom-driver/TESTS/block_device/i2cee/i2cee.bin
|
||||
|
||||
|
||||
Memory map breakdown for built projects (values in Bytes):
|
||||
+-------+--------+-----------+------------+-------+------+-----------+-------------+
|
||||
| name | target | toolchain | static_ram | stack | heap | total_ram | total_flash |
|
||||
+-------+--------+-----------+------------+-------+------+-----------+-------------+
|
||||
| i2cee | K64F | ARM | 12048 | 0 | 0 | 12048 | 49893 |
|
||||
+-------+--------+-----------+------------+-------+------+-----------+-------------+
|
||||
|
||||
|
||||
Build successes:
|
||||
* K64F::ARM::I2CEEPROM-DRIVER-TESTS-BLOCK_DEVICE-I2CEE
|
||||
* K64F::ARM::MBED-BUILD
|
||||
mbedgt: greentea test automation tool ver. 1.2.5
|
||||
mbedgt: test specification file 'C:\Ashok\SiPWorkshop\Filesystem\i2c_ex1\BUILD\tests\K64F\ARM\test_spec.json' (specified with --test-spec option)
|
||||
mbedgt: using 'C:\Ashok\SiPWorkshop\Filesystem\i2c_ex1\BUILD\tests\K64F\ARM\test_spec.json' from current directory!
|
||||
mbedgt: detecting connected mbed-enabled devices...
|
||||
mbedgt: detected 1 device
|
||||
mbedgt: processing target 'K64F' toolchain 'ARM' compatible platforms... (note: switch set to --parallel 1)
|
||||
mbedgt: test case filter (specified with -n option)
|
||||
test filtered in 'i2ceeprom-driver-tests-block_device-i2cee'
|
||||
mbedgt: running 1 test for platform 'K64F' and toolchain 'ARM'
|
||||
mbedgt: mbed-host-test-runner: started
|
||||
mbedgt: checking for GCOV data...
|
||||
mbedgt: test on hardware with target id: 0240000034544e45002600048e3800285a91000097969900
|
||||
mbedgt: test suite 'i2ceeprom-driver-tests-block_device-i2cee' ....................................... OK in 11.79 sec
|
||||
test case: 'Testing read write random blocks' ................................................ OK in 1.23 sec
|
||||
mbedgt: test case summary: 1 pass, 0 failures
|
||||
mbedgt: all tests finished!
|
||||
mbedgt: shuffle seed: 0.1529521449
|
||||
mbedgt: test suite report:
|
||||
+----------+---------------+-------------------------------------------+--------+--------------------+-------------+
|
||||
| target | platform_name | test suite | result | elapsed_time (sec) | copy_method |
|
||||
+----------+---------------+-------------------------------------------+--------+--------------------+-------------+
|
||||
| K64F-ARM | K64F | i2ceeprom-driver-tests-block_device-i2cee | OK | 11.79 | shell |
|
||||
+----------+---------------+-------------------------------------------+--------+--------------------+-------------+
|
||||
mbedgt: test suite results: 1 OK
|
||||
mbedgt: test case report:
|
||||
+----------+---------------+-------------------------------------------+----------------------------------+--------+--------+--------+--------------------+
|
||||
| target | platform_name | test suite | test case | passed | failed | result | elapsed_time (sec) |
|
||||
+----------+---------------+-------------------------------------------+----------------------------------+--------+--------+--------+--------------------+
|
||||
| K64F-ARM | K64F | i2ceeprom-driver-tests-block_device-i2cee | Testing read write random blocks | 1 | 0 | OK | 1.23 |
|
||||
+----------+---------------+-------------------------------------------+----------------------------------+--------+--------+--------+--------------------+
|
||||
mbedgt: test case results: 1 OK
|
||||
mbedgt: completed in 13.30 sec
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
# SPI Flash Driver
|
||||
|
||||
Block device driver for NOR based SPI flash devices that support SFDP.
|
||||
|
||||
NOR based SPI flash supports byte-sized read and writes, with an erase size of around 4kbytes. An erase sets a block to all 1s, with successive writes clearing set bits.
|
||||
|
||||
More info on NOR flash can be found on wikipedia:
|
||||
https://en.wikipedia.org/wiki/Flash_memory#NOR_memories
|
||||
|
||||
``` cpp
|
||||
// Here's an example using the MX25R SPI flash device on the K82F
|
||||
#include "mbed.h"
|
||||
#include "SPIFBlockDevice.h"
|
||||
|
||||
// Create flash device on SPI bus with PTE5 as chip select
|
||||
SPIFBlockDevice spif(PTE2, PTE4, PTE1, PTE5);
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("spif test\n");
|
||||
|
||||
// Initialize the SPI flash device and print the memory layout
|
||||
spif.init();
|
||||
printf("spif size: %llu\n", spif.size());
|
||||
printf("spif read size: %llu\n", spif.get_read_size());
|
||||
printf("spif program size: %llu\n", spif.get_program_size());
|
||||
printf("spif erase size: %llu\n", spif.get_erase_size());
|
||||
|
||||
// Write "Hello World!" to the first block
|
||||
uint8_t *buffer = malloc(spif.get_erase_size());
|
||||
sprintf(buffer, "Hello World!\n");
|
||||
spif.erase(0, spif.get_erase_size());
|
||||
spif.program(buffer, 0, spif.get_erase_size());
|
||||
|
||||
// Read back what was stored
|
||||
spif.read(buffer, 0, spif.get_erase_size());
|
||||
printf("%s", buffer);
|
||||
|
||||
// Deinitialize the device
|
||||
spif.deinit();
|
||||
}
|
||||
```
|
||||
|
|
@ -1,348 +0,0 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2016 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "SPIFBlockDevice.h"
|
||||
|
||||
|
||||
// Read/write/erase sizes
|
||||
#define SPIF_READ_SIZE 1
|
||||
#define SPIF_PROG_SIZE 1
|
||||
#define SPIF_SE_SIZE 4096
|
||||
#define SPIF_TIMEOUT 10000
|
||||
|
||||
// Debug available
|
||||
#define SPIF_DEBUG 0
|
||||
|
||||
#define SPIF_BLOCK_DEVICE_ERROR_WOULD_BLOCK -5001 /*!< operation would block */
|
||||
#define SPIF_BLOCK_DEVICE_ERROR_UNSUPPORTED -5002 /*!< unsupported operation */
|
||||
#define SPIF_BLOCK_DEVICE_ERROR_PARAMETER -5003 /*!< invalid parameter */
|
||||
#define SPIF_BLOCK_DEVICE_ERROR_NO_INIT -5004 /*!< uninitialized */
|
||||
#define SPIF_BLOCK_DEVICE_ERROR_NO_DEVICE -5005 /*!< device is missing or not connected */
|
||||
#define SPIF_BLOCK_DEVICE_ERROR_WRITE_PROTECTED -5006 /*!< write protected */
|
||||
|
||||
// MX25R Series Register Command Table.
|
||||
enum ops {
|
||||
SPIF_NOP = 0x00, // No operation
|
||||
SPIF_READ = 0x03, // Read data
|
||||
SPIF_PROG = 0x02, // Program data
|
||||
SPIF_SE = 0x20, // 4KB Sector Erase
|
||||
SPIF_CE = 0xc7, // Chip Erase
|
||||
SPIF_SFDP = 0x5a, // Read SFDP
|
||||
SPIF_WREN = 0x06, // Write Enable
|
||||
SPIF_WRDI = 0x04, // Write Disable
|
||||
SPIF_RDSR = 0x05, // Read Status Register
|
||||
SPIF_RDID = 0x9f, // Read Manufacturer and JDEC Device ID
|
||||
};
|
||||
|
||||
// Status register from RDSR
|
||||
// [- stuff -| wel | wip ]
|
||||
// [- 6 -| 1 | 1 ]
|
||||
#define SPIF_WEL 0x2
|
||||
#define SPIF_WIP 0x1
|
||||
|
||||
|
||||
SPIFBlockDevice::SPIFBlockDevice(
|
||||
PinName mosi, PinName miso, PinName sclk, PinName cs, int freq)
|
||||
: _spi(mosi, miso, sclk), _cs(cs), _size(0)
|
||||
{
|
||||
_cs = 1;
|
||||
_spi.frequency(freq);
|
||||
}
|
||||
|
||||
int SPIFBlockDevice::init()
|
||||
{
|
||||
// Check for vendor specific hacks, these should move into more general
|
||||
// handling when possible. RDID is not used to verify a device is attached.
|
||||
uint8_t id[3];
|
||||
_cmdread(SPIF_RDID, 0, 3, 0x0, id);
|
||||
|
||||
switch (id[0]) {
|
||||
case 0xbf:
|
||||
// SST devices come preset with block protection
|
||||
// enabled for some regions, issue gbpu instruction to clear
|
||||
_wren();
|
||||
_cmdwrite(0x98, 0, 0, 0x0, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
// Check that device is doing ok
|
||||
int err = _sync();
|
||||
if (err) {
|
||||
return SPIF_BLOCK_DEVICE_ERROR_NO_DEVICE;
|
||||
}
|
||||
|
||||
// Check JEDEC serial flash discoverable parameters for device
|
||||
// specific info
|
||||
uint8_t header[16];
|
||||
_cmdread(SPIF_SFDP, 4, 16, 0x0, header);
|
||||
|
||||
// Verify SFDP signature for sanity
|
||||
// Also check that major/minor version is acceptable
|
||||
if (!(memcmp(&header[0], "SFDP", 4) == 0 && header[5] == 1)) {
|
||||
return BD_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
// The SFDP spec indicates the standard table is always at offset 0
|
||||
// in the parameter headers, we check just to be safe
|
||||
if (!(header[8] == 0 && header[10] == 1)) {
|
||||
return BD_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
// Parameter table pointer, spi commands are BE, SFDP is LE,
|
||||
// also sfdp command expects extra read wait byte
|
||||
uint32_t table_addr = (
|
||||
(header[14] << 24) |
|
||||
(header[13] << 16) |
|
||||
(header[12] << 8 ));
|
||||
uint8_t table[8];
|
||||
_cmdread(SPIF_SFDP, 4, 8, table_addr, table);
|
||||
|
||||
// Check erase size, currently only supports 4kbytes
|
||||
// TODO support erase size != 4kbytes?
|
||||
// TODO support other erase opcodes from the sector descriptions
|
||||
if ((table[0] & 0x3) != 0x1 || table[1] != SPIF_SE) {
|
||||
return BD_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
// Check address size, currently only supports 3byte addresses
|
||||
// TODO support address > 3bytes?
|
||||
// TODO check for devices larger than 2Gbits?
|
||||
if ((table[2] & 0x4) != 0 || (table[7] & 0x80) != 0) {
|
||||
return BD_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
// Get device density, stored as size in bits - 1
|
||||
uint32_t density = (
|
||||
(table[7] << 24) |
|
||||
(table[6] << 16) |
|
||||
(table[5] << 8 ) |
|
||||
(table[4] << 0 ));
|
||||
_size = (density/8) + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SPIFBlockDevice::deinit()
|
||||
{
|
||||
// Latch write disable just to keep noise
|
||||
// from changing the device
|
||||
_cmdwrite(SPIF_WRDI, 0, 0, 0x0, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SPIFBlockDevice::_cmdread(
|
||||
uint8_t op, uint32_t addrc, uint32_t retc,
|
||||
uint32_t addr, uint8_t *rets)
|
||||
{
|
||||
_cs = 0;
|
||||
_spi.write(op);
|
||||
|
||||
for (uint32_t i = 0; i < addrc; i++) {
|
||||
_spi.write(0xff & (addr >> 8*(addrc-1 - i)));
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < retc; i++) {
|
||||
rets[i] = _spi.write(0);
|
||||
}
|
||||
_cs = 1;
|
||||
|
||||
if (SPIF_DEBUG) {
|
||||
printf("spif <- %02x", op);
|
||||
for (uint32_t i = 0; i < addrc; i++) {
|
||||
if (i < addrc) {
|
||||
printf("%02lx", 0xff & (addr >> 8*(addrc-1 - i)));
|
||||
} else {
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
printf(" ");
|
||||
for (uint32_t i = 0; i < 16 && i < retc; i++) {
|
||||
printf("%02x", rets[i]);
|
||||
}
|
||||
if (retc > 16) {
|
||||
printf("...");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void SPIFBlockDevice::_cmdwrite(
|
||||
uint8_t op, uint32_t addrc, uint32_t argc,
|
||||
uint32_t addr, const uint8_t *args)
|
||||
{
|
||||
_cs = 0;
|
||||
_spi.write(op);
|
||||
|
||||
for (uint32_t i = 0; i < addrc; i++) {
|
||||
_spi.write(0xff & (addr >> 8*(addrc-1 - i)));
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < argc; i++) {
|
||||
_spi.write(args[i]);
|
||||
}
|
||||
_cs = 1;
|
||||
|
||||
if (SPIF_DEBUG) {
|
||||
printf("spif -> %02x", op);
|
||||
for (uint32_t i = 0; i < addrc; i++) {
|
||||
if (i < addrc) {
|
||||
printf("%02lx", 0xff & (addr >> 8*(addrc-1 - i)));
|
||||
} else {
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
printf(" ");
|
||||
for (uint32_t i = 0; i < 16 && i < argc; i++) {
|
||||
printf("%02x", args[i]);
|
||||
}
|
||||
if (argc > 16) {
|
||||
printf("...");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
int SPIFBlockDevice::_sync()
|
||||
{
|
||||
for (int i = 0; i < SPIF_TIMEOUT; i++) {
|
||||
// Read status register until write not-in-progress
|
||||
uint8_t status;
|
||||
_cmdread(SPIF_RDSR, 0, 1, 0x0, &status);
|
||||
|
||||
// Check WIP bit
|
||||
if (!(status & SPIF_WIP)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
wait_ms(1);
|
||||
}
|
||||
|
||||
return BD_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
int SPIFBlockDevice::_wren()
|
||||
{
|
||||
_cmdwrite(SPIF_WREN, 0, 0, 0x0, NULL);
|
||||
|
||||
for (int i = 0; i < SPIF_TIMEOUT; i++) {
|
||||
// Read status register until write latch is enabled
|
||||
uint8_t status;
|
||||
_cmdread(SPIF_RDSR, 0, 1, 0x0, &status);
|
||||
|
||||
// Check WEL bit
|
||||
if (status & SPIF_WEL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
wait_ms(1);
|
||||
}
|
||||
|
||||
return BD_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
int SPIFBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
|
||||
{
|
||||
// Check the address and size fit onto the chip.
|
||||
if (!is_valid_read(addr, size)) {
|
||||
return SPIF_BLOCK_DEVICE_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
_cmdread(SPIF_READ, 3, size, addr, static_cast<uint8_t *>(buffer));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SPIFBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size)
|
||||
{
|
||||
// Check the address and size fit onto the chip.
|
||||
if (!is_valid_program(addr, size)) {
|
||||
return SPIF_BLOCK_DEVICE_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
while (size > 0) {
|
||||
int err = _wren();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// Write up to 256 bytes a page
|
||||
// TODO handle unaligned programs
|
||||
uint32_t off = addr % 256;
|
||||
uint32_t chunk = (off + size < 256) ? size : (256-off);
|
||||
_cmdwrite(SPIF_PROG, 3, chunk, addr, static_cast<const uint8_t *>(buffer));
|
||||
buffer = static_cast<const uint8_t*>(buffer) + chunk;
|
||||
addr += chunk;
|
||||
size -= chunk;
|
||||
|
||||
wait_ms(1);
|
||||
|
||||
err = _sync();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SPIFBlockDevice::erase(bd_addr_t addr, bd_size_t size)
|
||||
{
|
||||
// Check the address and size fit onto the chip.
|
||||
if (!is_valid_erase(addr, size)) {
|
||||
return SPIF_BLOCK_DEVICE_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
while (size > 0) {
|
||||
int err = _wren();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// Erase 4kbyte sectors
|
||||
// TODO support other erase sizes?
|
||||
uint32_t chunk = 4096;
|
||||
_cmdwrite(SPIF_SE, 3, 0, addr, NULL);
|
||||
addr += chunk;
|
||||
size -= chunk;
|
||||
|
||||
err = _sync();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bd_size_t SPIFBlockDevice::get_read_size() const
|
||||
{
|
||||
return SPIF_READ_SIZE;
|
||||
}
|
||||
|
||||
bd_size_t SPIFBlockDevice::get_program_size() const
|
||||
{
|
||||
return SPIF_PROG_SIZE;
|
||||
}
|
||||
|
||||
bd_size_t SPIFBlockDevice::get_erase_size() const
|
||||
{
|
||||
return SPIF_SE_SIZE;
|
||||
}
|
||||
|
||||
bd_size_t SPIFBlockDevice::size() const
|
||||
{
|
||||
return _size;
|
||||
}
|
|
@ -1,155 +0,0 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2016 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef MBED_SPIF_BLOCK_DEVICE_H
|
||||
#define MBED_SPIF_BLOCK_DEVICE_H
|
||||
|
||||
/* If the target has no SPI support then SPIF is not supported */
|
||||
#ifdef DEVICE_SPI
|
||||
|
||||
#include <mbed.h>
|
||||
#include "BlockDevice.h"
|
||||
|
||||
|
||||
/** BlockDevice for SPI based flash devices
|
||||
* such as the MX25R or SST26F016B
|
||||
*
|
||||
* @code
|
||||
* #include "mbed.h"
|
||||
* #include "SPIFBlockDevice.h"
|
||||
*
|
||||
* // Create mx25r on SPI bus with PTE5 as chip select
|
||||
* SPIFBlockDevice mx25r(PTE2, PTE4, PTE1, PTE5);
|
||||
*
|
||||
* int main() {
|
||||
* printf("mx25r test\n");
|
||||
* mx52r.init();
|
||||
* printf("mx25r size: %llu\n", mx25r.size());
|
||||
* printf("mx25r read size: %llu\n", mx25r.get_read_size());
|
||||
* printf("mx25r program size: %llu\n", mx25r.get_program_size());
|
||||
* printf("mx25r erase size: %llu\n", mx25r.get_erase_size());
|
||||
*
|
||||
* uint8_t *buffer = malloc(mx25r.get_erase_size());
|
||||
* sprintf(buffer, "Hello World!\n");
|
||||
* mx25r.erase(0, mx25r.get_erase_size());
|
||||
* mx25r.program(buffer, 0, mx25r.get_erase_size());
|
||||
* mx25r.read(buffer, 0, mx25r.get_erase_size());
|
||||
* printf("%s", buffer);
|
||||
*
|
||||
* mx25r.deinit();
|
||||
* }
|
||||
*/
|
||||
class SPIFBlockDevice : public BlockDevice
|
||||
{
|
||||
public:
|
||||
/** Creates a SPIFBlockDevice on a SPI bus specified by pins
|
||||
*
|
||||
* @param mosi SPI master out, slave in pin
|
||||
* @param miso SPI master in, slave out pin
|
||||
* @param sclk SPI clock pin
|
||||
* @param csel SPI chip select pin
|
||||
* @param freq Clock speed of the SPI bus (defaults to 40MHz)
|
||||
*/
|
||||
SPIFBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName csel, int freq=4000000);
|
||||
|
||||
/** Initialize a block device
|
||||
*
|
||||
* @return 0 on success or a negative error code on failure
|
||||
*/
|
||||
virtual int init();
|
||||
|
||||
/** Deinitialize a block device
|
||||
*
|
||||
* @return 0 on success or a negative error code on failure
|
||||
*/
|
||||
virtual int deinit();
|
||||
|
||||
/** Read blocks from a block device
|
||||
*
|
||||
* @param buffer Buffer to write blocks to
|
||||
* @param addr Address of block to begin reading from
|
||||
* @param size Size to read in bytes, must be a multiple of read block size
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual int read(void *buffer, bd_addr_t addr, bd_size_t size);
|
||||
|
||||
/** Program blocks to a block device
|
||||
*
|
||||
* The blocks must have been erased prior to being programmed
|
||||
*
|
||||
* @param buffer Buffer of data to write to blocks
|
||||
* @param addr Address of block to begin writing to
|
||||
* @param size Size to write in bytes, must be a multiple of program block size
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual int program(const void *buffer, bd_addr_t addr, bd_size_t size);
|
||||
|
||||
/** Erase blocks on a block device
|
||||
*
|
||||
* The state of an erased block is undefined until it has been programmed
|
||||
*
|
||||
* @param addr Address of block to begin erasing
|
||||
* @param size Size to erase in bytes, must be a multiple of erase block size
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual int erase(bd_addr_t addr, bd_size_t size);
|
||||
|
||||
/** Get the size of a readable block
|
||||
*
|
||||
* @return Size of a readable block in bytes
|
||||
*/
|
||||
virtual bd_size_t get_read_size() const;
|
||||
|
||||
/** Get the size of a programable block
|
||||
*
|
||||
* @return Size of a programable block in bytes
|
||||
* @note Must be a multiple of the read size
|
||||
*/
|
||||
virtual bd_size_t get_program_size() const;
|
||||
|
||||
/** Get the size of a eraseable block
|
||||
*
|
||||
* @return Size of a eraseable block in bytes
|
||||
* @note Must be a multiple of the program size
|
||||
*/
|
||||
virtual bd_size_t get_erase_size() const;
|
||||
|
||||
/** Get the total size of the underlying device
|
||||
*
|
||||
* @return Size of the underlying device in bytes
|
||||
*/
|
||||
virtual bd_size_t size() const;
|
||||
|
||||
private:
|
||||
// Master side hardware
|
||||
SPI _spi;
|
||||
DigitalOut _cs;
|
||||
|
||||
// Device configuration discovered through sfdp
|
||||
bd_size_t _size;
|
||||
|
||||
// Internal functions
|
||||
int _wren();
|
||||
int _sync();
|
||||
void _cmdread(uint8_t op, uint32_t addrc, uint32_t retc,
|
||||
uint32_t addr, uint8_t *rets);
|
||||
void _cmdwrite(uint8_t op, uint32_t addrc, uint32_t argc,
|
||||
uint32_t addr, const uint8_t *args);
|
||||
};
|
||||
|
||||
|
||||
#endif /* DEVICE_SPI */
|
||||
|
||||
#endif /* MBED_SPIF_BLOCK_DEVICE_H */
|
Loading…
Reference in New Issue