WIP accelerometer logging to flash
This commit is contained in:
		
							parent
							
								
									0c59c972e7
								
							
						
					
					
						commit
						df2cc7e94f
					
				@ -28,6 +28,10 @@ static void cb_tick(void) {
 | 
				
			|||||||
    bool overrun = lis2dw_read_fifo(&fifo);
 | 
					    bool overrun = lis2dw_read_fifo(&fifo);
 | 
				
			||||||
    printf("FIFO captured %d readings.\n", fifo.count);
 | 
					    printf("FIFO captured %d readings.\n", fifo.count);
 | 
				
			||||||
    if (overrun) printf("\tThere was an overrun!\n\n");
 | 
					    if (overrun) printf("\tThere was an overrun!\n\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("%d, %d, %d\n", fifo.readings[0].x, fifo.readings[0].y, fifo.readings[0].z);
 | 
				
			||||||
 | 
					    printf("%d, %d, %d\n", fifo.readings[10].x, fifo.readings[10].y, fifo.readings[10].z);
 | 
				
			||||||
 | 
					    printf("%d, %d, %d\n", fifo.readings[20].x, fifo.readings[20].y, fifo.readings[20].z);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void app_init(void) {
 | 
					void app_init(void) {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,35 @@
 | 
				
			|||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <peripheral_clk_config.h>
 | 
					#include <peripheral_clk_config.h>
 | 
				
			||||||
#include "watch.h"
 | 
					#include "watch.h"
 | 
				
			||||||
 | 
					#include "watch_utility.h"
 | 
				
			||||||
#include "spiflash.h"
 | 
					#include "spiflash.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_TRAINING_RECORD_DELETED ((uint64_t)(0b00))
 | 
				
			||||||
 | 
					#define ACCELEROMETER_TRAINING_RECORD_DATA ((uint64_t)(0b01))
 | 
				
			||||||
 | 
					#define ACCELEROMETER_TRAINING_RECORD_HEADER ((uint64_t)(0b10))
 | 
				
			||||||
 | 
					#define ACCELEROMETER_TRAINING_RECORD_INVALID ((uint64_t)(0b11))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef union {
 | 
				
			||||||
 | 
					    struct {
 | 
				
			||||||
 | 
					        int16_t temperature : 16;
 | 
				
			||||||
 | 
					        int8_t char1 : 8;
 | 
				
			||||||
 | 
					        int8_t char2 : 8;
 | 
				
			||||||
 | 
					        int32_t timestamp : 32;
 | 
				
			||||||
 | 
					    } header;
 | 
				
			||||||
 | 
					    struct {
 | 
				
			||||||
 | 
					        int16_t x_accel : 16;
 | 
				
			||||||
 | 
					        int16_t y_accel : 16;
 | 
				
			||||||
 | 
					        int16_t z_accel : 16;
 | 
				
			||||||
 | 
					        int32_t counter : 16;
 | 
				
			||||||
 | 
					    } data;
 | 
				
			||||||
 | 
					    uint64_t value;
 | 
				
			||||||
 | 
					} acceleromter_training_record_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void cb_alarm_pressed(void) {
 | 
				
			||||||
 | 
					    printf("Alarm button was pressed!\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool wait_for_flash_ready(void) {
 | 
					static bool wait_for_flash_ready(void) {
 | 
				
			||||||
    watch_set_pin_level(A3, false);
 | 
					    watch_set_pin_level(A3, false);
 | 
				
			||||||
@ -12,14 +37,96 @@ static bool wait_for_flash_ready(void) {
 | 
				
			|||||||
    uint8_t read_status_response[1] = {0x00};
 | 
					    uint8_t read_status_response[1] = {0x00};
 | 
				
			||||||
    do {
 | 
					    do {
 | 
				
			||||||
        ok = spi_flash_read_command(CMD_READ_STATUS, read_status_response, 1);
 | 
					        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(10);
 | 
				
			||||||
    watch_set_pin_level(A3, true);
 | 
					    watch_set_pin_level(A3, true);
 | 
				
			||||||
    return ok;
 | 
					    return ok;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void print_records_at_page(uint16_t page) {
 | 
				
			||||||
 | 
					    if (page < 477) return;
 | 
				
			||||||
 | 
					    acceleromter_training_record_t records[32];
 | 
				
			||||||
 | 
					    static uint32_t timestamp;
 | 
				
			||||||
 | 
					    static uint16_t temperature;
 | 
				
			||||||
 | 
					    wait_for_flash_ready();
 | 
				
			||||||
 | 
					    spi_flash_read_data(page * 256, (void *)records, 256);
 | 
				
			||||||
 | 
					    for(int i = 0; i < 32; i++) {
 | 
				
			||||||
 | 
					        switch (records[i].header.temperature >> 14) {
 | 
				
			||||||
 | 
					            case ACCELEROMETER_TRAINING_RECORD_DELETED:
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case ACCELEROMETER_TRAINING_RECORD_DATA:
 | 
				
			||||||
 | 
					                printf("%ld,%d,%d,%d,%d\n", timestamp + records[i].data.counter, records[i].data.x_accel, records[i].data.y_accel, records[i].data.z_accel, temperature);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case ACCELEROMETER_TRAINING_RECORD_HEADER:
 | 
				
			||||||
 | 
					                printf("=== BEGIN %c%c EVENT AT %d ===\n", records[i].header.char1, records[i].header.char2, records[i].header.timestamp);
 | 
				
			||||||
 | 
					                printf("timestamp,x_raw,y_raw,z_raw,temperature\n");
 | 
				
			||||||
 | 
					                timestamp = records[i].header.timestamp;
 | 
				
			||||||
 | 
					                temperature = records[i].header.temperature & 0x3FFF;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case ACCELEROMETER_TRAINING_RECORD_INVALID:
 | 
				
			||||||
 | 
					                printf(",,,,\n");
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void print_records() {
 | 
				
			||||||
 | 
					    printf("printing records\n");
 | 
				
			||||||
 | 
					    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 < 7; k++) {
 | 
				
			||||||
 | 
					                if ((pages_written & 0x80) == 0) {
 | 
				
			||||||
 | 
					                    print_records_at_page(i * 2048 + j * 8 + k);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                pages_written <<= 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void app_init(void) {
 | 
					void app_init(void) {
 | 
				
			||||||
    spi_flash_init();
 | 
					 | 
				
			||||||
    delay_ms(5000);
 | 
					    delay_ms(5000);
 | 
				
			||||||
 | 
					    spi_flash_init();
 | 
				
			||||||
 | 
					    watch_register_extwake_callback(BTN_ALARM, cb_alarm_pressed, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint8_t buf[256] = {0xFF};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    wait_for_flash_ready();
 | 
				
			||||||
 | 
					    spi_flash_read_data(0, buf, 256);
 | 
				
			||||||
 | 
					    printf("byte 0 was %02x\n", buf[0]);
 | 
				
			||||||
 | 
					    if (buf[0] & 0xF0) {
 | 
				
			||||||
 | 
					        buf[0] = 0x0F;
 | 
				
			||||||
 | 
					        printf("setting it to 0x0F\n");
 | 
				
			||||||
 | 
					        wait_for_flash_ready();
 | 
				
			||||||
 | 
					        watch_set_pin_level(A3, false);
 | 
				
			||||||
 | 
					        spi_flash_command(CMD_ENABLE_WRITE);
 | 
				
			||||||
 | 
					        wait_for_flash_ready();
 | 
				
			||||||
 | 
					        spi_flash_write_data(0, buf, 256);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    print_records();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void app_wake_from_backup(void) {
 | 
					void app_wake_from_backup(void) {
 | 
				
			||||||
@ -34,20 +141,122 @@ void app_prepare_for_standby(void) {
 | 
				
			|||||||
void app_wake_from_standby(void) {
 | 
					void app_wake_from_standby(void) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int16_t get_next_available_page(void) {
 | 
				
			||||||
 | 
					    uint8_t buf[256] = {0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool app_loop(void) {
 | 
					    uint16_t page = 0;
 | 
				
			||||||
    uint8_t buf[3] = {0};
 | 
					    for(int16_t i = 0; i < 4; i++) {
 | 
				
			||||||
    printf("loop\n");
 | 
					        wait_for_flash_ready();
 | 
				
			||||||
 | 
					        spi_flash_read_data(i * 256, buf, 256);
 | 
				
			||||||
 | 
					        for(int16_t j = 0; j < 256; j++) {
 | 
				
			||||||
 | 
					            if(buf[j] == 0) {
 | 
				
			||||||
 | 
					                page += 8;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                page += __builtin_clz(((uint32_t)buf[j]) << 24);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (page >= 8192) return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return page;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void write_buffer_to_page(uint8_t *buf, uint16_t page) {
 | 
				
			||||||
 | 
					    uint32_t address = 256 * page;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    wait_for_flash_ready();
 | 
					    wait_for_flash_ready();
 | 
				
			||||||
    watch_set_pin_level(A3, false);
 | 
					    watch_set_pin_level(A3, false);
 | 
				
			||||||
    spi_flash_read_command(CMD_READ_JEDEC_ID, buf, 3);
 | 
					    spi_flash_command(CMD_ENABLE_WRITE);
 | 
				
			||||||
    printf("ident: %x, %x, %x\n", buf[0], buf[1], buf[2]);
 | 
					    wait_for_flash_ready();
 | 
				
			||||||
 | 
					    watch_set_pin_level(A3, false);
 | 
				
			||||||
    watch_set_pin_level(A3, true);
 | 
					    spi_flash_write_data(address, buf, 256);
 | 
				
			||||||
    wait_for_flash_ready();
 | 
					    wait_for_flash_ready();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    delay_ms(10000);
 | 
					    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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("\tWe wrote 256 bytes to address %ld, which was page %d.\n", address, page);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(int i = 0; i < 256; i++) {
 | 
				
			||||||
 | 
					        if (buf[i] != buf2[i]) {
 | 
				
			||||||
 | 
					            printf("\tData mismatch detected at offset  %d: %d != %d.\n", i, buf[i], buf2[i]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool app_loop(void) {
 | 
				
			||||||
 | 
					    // delay_ms(5000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    // simulate logging 15 seconds of data
 | 
				
			||||||
 | 
					    watch_date_time date_time = watch_rtc_get_date_time();
 | 
				
			||||||
 | 
					    acceleromter_training_record_t record;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    record.header.temperature = 0xC30;
 | 
				
			||||||
 | 
					    record.header.temperature |= (ACCELEROMETER_TRAINING_RECORD_HEADER << 14);
 | 
				
			||||||
 | 
					    record.header.char1 = 'W';
 | 
				
			||||||
 | 
					    record.header.char2 = 'A';
 | 
				
			||||||
 | 
					    record.header.timestamp = watch_utility_date_time_to_unix_time(date_time, 0);;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    acceleromter_training_record_t records[32];
 | 
				
			||||||
 | 
					    memset(records, 0xFF, sizeof(records));
 | 
				
			||||||
 | 
					    records[0] = record;
 | 
				
			||||||
 | 
					    uint16_t pos = 1;
 | 
				
			||||||
 | 
					    uint32_t counter = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("logging 15*25 data points for timestamp %ld\n", record.header.timestamp);
 | 
				
			||||||
 | 
					    for(uint8_t i = 0; i < 15; i++) {
 | 
				
			||||||
 | 
					        for(uint8_t j = 0; j < 25; j++) {
 | 
				
			||||||
 | 
					            record.data.x_accel = arc4random() & 0x3FFF;
 | 
				
			||||||
 | 
					            record.data.x_accel |= ACCELEROMETER_TRAINING_RECORD_DATA << 14;
 | 
				
			||||||
 | 
					            record.data.y_accel = arc4random() & 0x3FFF;
 | 
				
			||||||
 | 
					            record.data.z_accel = arc4random() & 0x3FFF;
 | 
				
			||||||
 | 
					            record.data.counter = i;
 | 
				
			||||||
 | 
					            records[pos++] = record;
 | 
				
			||||||
 | 
					            if (pos >= 32) {
 | 
				
			||||||
 | 
					                printf("pos overflowed at counter %ld\n", counter);
 | 
				
			||||||
 | 
					                int16_t next_available_page = get_next_available_page();
 | 
				
			||||||
 | 
					                if (next_available_page > 0) {
 | 
				
			||||||
 | 
					                    write_buffer_to_page((uint8_t *)records, next_available_page);
 | 
				
			||||||
 | 
					                    wait_for_flash_ready();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                pos = 0;
 | 
				
			||||||
 | 
					                memset(records, 0xFF, sizeof(records));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (records[0].header.temperature >> 14 != ACCELEROMETER_TRAINING_RECORD_INVALID) {
 | 
				
			||||||
 | 
					        int16_t next_available_page = get_next_available_page();
 | 
				
			||||||
 | 
					        if (next_available_page > 0) {
 | 
				
			||||||
 | 
					            printf("Partial write\n");
 | 
				
			||||||
 | 
					            write_buffer_to_page((uint8_t *)records, next_available_page);
 | 
				
			||||||
 | 
					            wait_for_flash_ready();
 | 
				
			||||||
 | 
					            delay_ms(10);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    delay_ms(60000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -172,7 +172,7 @@
 | 
				
			|||||||
// <i> The SPI data transfer rate
 | 
					// <i> The SPI data transfer rate
 | 
				
			||||||
// <id> spi_master_baud_rate
 | 
					// <id> spi_master_baud_rate
 | 
				
			||||||
#ifndef CONF_SERCOM_3_SPI_BAUD
 | 
					#ifndef CONF_SERCOM_3_SPI_BAUD
 | 
				
			||||||
#define CONF_SERCOM_3_SPI_BAUD 50000
 | 
					#define CONF_SERCOM_3_SPI_BAUD 1000000
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// </h>
 | 
					// </h>
 | 
				
			||||||
 | 
				
			|||||||
@ -33,6 +33,8 @@
 | 
				
			|||||||
#define CMD_FAST_READ_DATA 0x0B
 | 
					#define CMD_FAST_READ_DATA 0x0B
 | 
				
			||||||
#define CMD_SECTOR_ERASE 0x20
 | 
					#define CMD_SECTOR_ERASE 0x20
 | 
				
			||||||
// #define CMD_SECTOR_ERASE CMD_READ_JEDEC_ID
 | 
					// #define CMD_SECTOR_ERASE CMD_READ_JEDEC_ID
 | 
				
			||||||
 | 
					#define CMD_CHIP_ERASE 0xC7
 | 
				
			||||||
 | 
					// #define CMD_CHIP_ERASE CMD_READ_JEDEC_ID
 | 
				
			||||||
#define CMD_DISABLE_WRITE 0x04
 | 
					#define CMD_DISABLE_WRITE 0x04
 | 
				
			||||||
#define CMD_ENABLE_WRITE 0x06
 | 
					#define CMD_ENABLE_WRITE 0x06
 | 
				
			||||||
#define CMD_PAGE_PROGRAM 0x02
 | 
					#define CMD_PAGE_PROGRAM 0x02
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user