summaryrefslogtreecommitdiffstats
path: root/apps/spi-test/app.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/spi-test/app.c')
-rw-r--r--apps/spi-test/app.c207
1 files changed, 189 insertions, 18 deletions
diff --git a/apps/spi-test/app.c b/apps/spi-test/app.c
index 428f55d3..f45c783b 100644
--- a/apps/spi-test/app.c
+++ b/apps/spi-test/app.c
@@ -1,10 +1,45 @@
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <peripheral_clk_config.h>
#include "watch.h"
+#include "watch_utility.h"
#include "spiflash.h"
+#include "lis2dw.h"
-// this is a very basic app to confirm that SPI is working, tested with board OSO-MISC-21-017 and a GD25Q16C Flash chip.
+#define ACCELEROMETER_DATA_ACQUISITION_INVALID ((uint64_t)(0b11)) // all bits are 1 when the flash is erased
+#define ACCELEROMETER_DATA_ACQUISITION_HEADER ((uint64_t)(0b10))
+#define ACCELEROMETER_DATA_ACQUISITION_DATA ((uint64_t)(0b01))
+#define ACCELEROMETER_DATA_ACQUISITION_DELETED ((uint64_t)(0b00)) // You can always write a 0 to any 1 bit
+
+typedef union {
+ struct {
+ struct {
+ uint16_t record_type : 2; // see above, helps us identify record types when reading back
+ uint16_t range : 2; // accelerometer range (see lis2dw_range_t)
+ uint16_t temperature : 12; // raw value from the temperature sensor
+ } info;
+ uint8_t char1 : 8; // First character of the activity type
+ uint8_t char2 : 8; // Second character of the activity type
+ uint32_t timestamp : 32; // UNIX timestamp for the measurement
+ } header;
+ struct {
+ struct {
+ uint16_t record_type : 2; // duplicate; this is the same field as info above
+ uint16_t accel : 14; // X acceleration value, raw, offset by 8192
+ } x;
+ struct {
+ uint16_t lpmode : 2; // low power mode (see lis2dw_low_power_mode_t)
+ uint16_t accel : 14; // Y acceleration value, raw, offset by 8192
+ } y;
+ struct {
+ uint16_t filter : 2; // bandwidth filtering selection (see lis2dw_bandwidth_filtering_mode_t)
+ uint16_t accel : 14; // Z acceleration value, raw, offset by 8192
+ } z;
+ uint32_t counter : 16; // number of centiseconds since timestamp in header
+ } data;
+ uint64_t value;
+} accelerometer_data_acquisition_record_t;
static bool wait_for_flash_ready(void) {
watch_set_pin_level(A3, false);
@@ -12,20 +47,168 @@ static bool wait_for_flash_ready(void) {
uint8_t read_status_response[1] = {0x00};
do {
ok = spi_flash_read_command(CMD_READ_STATUS, read_status_response, 1);
- } while (ok && (read_status_response[0] & 0x3) != 0);
+ } while ((read_status_response[0] & 0x3) != 0);
+ delay_ms(1); // why do i need this?
watch_set_pin_level(A3, true);
return ok;
}
+static void write_buffer_to_page(uint8_t *buf, uint16_t page) {
+ uint32_t address = 256 * page;
+
+ wait_for_flash_ready();
+ watch_set_pin_level(A3, false);
+ spi_flash_command(CMD_ENABLE_WRITE);
+ wait_for_flash_ready();
+ watch_set_pin_level(A3, false);
+ spi_flash_write_data(address, buf, 256);
+ wait_for_flash_ready();
+
+ uint8_t buf2[256];
+ watch_set_pin_level(A3, false);
+ spi_flash_read_data(address, buf2, 256);
+ wait_for_flash_ready();
+
+ uint8_t used_pages[256] = {0xFF};
+ uint16_t address_to_mark_used = page / 8;
+ uint8_t header_page = address_to_mark_used / 256;
+ uint8_t used_byte = 0x7F >> (page % 8);
+ uint8_t offset_in_buf = address_to_mark_used % 256;
+
+ watch_set_pin_level(A3, false);
+ spi_flash_read_data(header_page * 256, used_pages, 256);
+ used_pages[offset_in_buf] = used_byte;
+ watch_set_pin_level(A3, false);
+ spi_flash_command(CMD_ENABLE_WRITE);
+ wait_for_flash_ready();
+ watch_set_pin_level(A3, false);
+ spi_flash_write_data(header_page * 256, used_pages, 256);
+ wait_for_flash_ready();
+}
+
+static void print_records_at_page(uint16_t page) {
+ accelerometer_data_acquisition_record_t records[32];
+ static uint64_t timestamp = 0;
+ // static uint16_t temperature = 0;
+ static lis2dw_range_t range = LIS2DW_RANGE_2_G;
+ static double lsb_value = 1;
+ static bool printing_header = false;
+
+ wait_for_flash_ready();
+ spi_flash_read_data(page * 256, (void *)records, 256);
+ for(int i = 0; i < 32; i++) {
+ switch (records[i].header.info.record_type) {
+ case ACCELEROMETER_DATA_ACQUISITION_HEADER:
+ printing_header = true;
+ timestamp = records[i].header.timestamp;
+ // temperature = records[i].header.info.temperature;
+ printf("%c%c.%lld.", records[i].header.char1, records[i].header.char2, timestamp);
+ range = records[i].header.info.range;
+ break;
+ case ACCELEROMETER_DATA_ACQUISITION_DATA:
+ if (printing_header) {
+ printing_header = false;
+ uint8_t filter = 0;
+ switch (records[i].data.z.filter) {
+ case LIS2DW_BANDWIDTH_FILTER_DIV2:
+ filter = 2;
+ break;
+ case LIS2DW_BANDWIDTH_FILTER_DIV4:
+ filter = 4;
+ break;
+ case LIS2DW_BANDWIDTH_FILTER_DIV10:
+ filter = 10;
+ break;
+ case LIS2DW_BANDWIDTH_FILTER_DIV20:
+ filter = 20;
+ break;
+ }
+ switch (range) {
+ case LIS2DW_RANGE_16_G:
+ lsb_value = (records[i].data.y.lpmode == LIS2DW_LP_MODE_1) ? 7.808 : 1.952;
+ range = 16;
+ break;
+ case LIS2DW_RANGE_8_G:
+ lsb_value = (records[i].data.y.lpmode == LIS2DW_LP_MODE_1) ? 3.904 : 0.976;
+ range = 8;
+ break;
+ case LIS2DW_RANGE_4_G:
+ lsb_value = (records[i].data.y.lpmode == LIS2DW_LP_MODE_1) ? 1.952 : 0.488;
+ range = 4;
+ break;
+ case LIS2DW_RANGE_2_G:
+ lsb_value = (records[i].data.y.lpmode == LIS2DW_LP_MODE_1) ? 0.976 : 0.244;
+ range = 2;
+ break;
+ }
+ printf("RANGE%d_LP%d_FILT%d.CSV\n", range, records[i].data.y.lpmode + 1, filter);
+ printf("timestamp,accX,accY,accZ\n");
+ }
+ printf("%lld,%f,%f,%f\n",
+ (timestamp * 100 + records[i].data.counter) * 10,
+ 9.80665 * ((double)(records[i].data.x.accel - 8192)) * lsb_value / 1000,
+ 9.80665 * ((double)(records[i].data.y.accel - 8192)) * lsb_value / 1000,
+ 9.80665 * ((double)(records[i].data.z.accel - 8192)) * lsb_value / 1000);
+ break;
+ case ACCELEROMETER_DATA_ACQUISITION_INVALID:
+ case ACCELEROMETER_DATA_ACQUISITION_DELETED:
+ // don't print anything
+ break;
+ }
+ records[i].header.info.record_type = ACCELEROMETER_DATA_ACQUISITION_DELETED;
+ }
+
+ // uncomment this to mark all pages deleted
+ // write_buffer_to_page((uint8_t *)records, page);
+}
+
+static void print_records() {
+ uint8_t buf[256];
+ for(int16_t i = 0; i < 4; i++) {
+ wait_for_flash_ready();
+ spi_flash_read_data(i * 256, buf, 256);
+ for(int16_t j = 0; j < 256; j++) {
+ uint8_t pages_written = buf[j];
+ uint8_t start = 0;
+ if (i == 0 && j == 0) {
+ pages_written <<= 4;
+ start = 4;
+ }
+ for(int k = start; k < 8; k++) {
+ if ((pages_written & 0x80) == 0) {
+ print_records_at_page(i * 2048 + j * 8 + k);
+ }
+ pages_written <<= 1;
+ }
+ }
+ }
+
+ printf("=== END ===\n");
+}
+
void app_init(void) {
- spi_flash_init();
- delay_ms(5000);
}
void app_wake_from_backup(void) {
}
void app_setup(void) {
+ spi_flash_init();
+ delay_ms(5000);
+
+ // bool erase = false;
+ // if (erase) {
+ // printf("Erasing...\n");
+ // wait_for_flash_ready();
+ // watch_set_pin_level(A3, false);
+ // spi_flash_command(CMD_ENABLE_WRITE);
+ // wait_for_flash_ready();
+ // watch_set_pin_level(A3, false);
+ // spi_flash_command(CMD_CHIP_ERASE);
+ // delay_ms(10000);
+ // }
+
+ print_records();
}
void app_prepare_for_standby(void) {
@@ -34,20 +217,8 @@ void app_prepare_for_standby(void) {
void app_wake_from_standby(void) {
}
-
bool app_loop(void) {
- uint8_t buf[3] = {0};
- printf("loop\n");
-
- wait_for_flash_ready();
- watch_set_pin_level(A3, false);
- spi_flash_read_command(CMD_READ_JEDEC_ID, buf, 3);
- printf("ident: %x, %x, %x\n", buf[0], buf[1], buf[2]);
-
- watch_set_pin_level(A3, true);
- wait_for_flash_ready();
-
- delay_ms(10000);
+ delay_ms(5000);
- return false;
+ return true;
}