diff options
Diffstat (limited to 'apps/spi-test/app.c')
-rw-r--r-- | apps/spi-test/app.c | 207 |
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; } |