ao_mutex_put(__xdata uint8_t *ao_mutex) __reentrant;
/*
- * ao_ee.c
+ * Storage interface, provided by one of the eeprom or flash
+ * drivers
*/
-/*
- * We reserve the last block on the device for
- * configuration space. Writes and reads in this
- * area return errors.
- */
+/* Total bytes of available storage */
+extern __xdata uint32_t ao_storage_total;
-#define AO_EE_BLOCK_SIZE ((uint16_t) (256))
-#define AO_EE_DEVICE_SIZE ((uint32_t) 128 * (uint32_t) 1024)
-#define AO_EE_DATA_SIZE (AO_EE_DEVICE_SIZE - (uint32_t) AO_EE_BLOCK_SIZE)
-#define AO_EE_CONFIG_BLOCK ((uint16_t) (AO_EE_DATA_SIZE / AO_EE_BLOCK_SIZE))
+/* Block size - device is erased in these units. At least 256 bytes */
+extern __xdata uint32_t ao_storage_block;
-void
-ao_ee_flush(void) __reentrant;
+/* Byte offset of config block. Will be ao_storage_block bytes long */
+extern __xdata uint32_t ao_storage_config;
-/* Write to the eeprom */
-uint8_t
-ao_ee_write(uint32_t pos, uint8_t *buf, uint16_t len) __reentrant;
+/* Initialize above values. Can only be called once the OS is running */
+void
+ao_storage_setup(void);
-/* Read from the eeprom */
-uint8_t
-ao_ee_read(uint32_t pos, uint8_t *buf, uint16_t len) __reentrant;
+/* Flush any pending write data */
+void
+ao_storage_flush(void) __reentrant;
-/* Write the config block (at the end of the eeprom) */
+/* Write data. Returns 0 on failure, 1 on success */
uint8_t
-ao_ee_write_config(uint8_t *buf, uint16_t len) __reentrant;
+ao_storage_write(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant;
-/* Read the config block (at the end of the eeprom) */
+/* Read data. Returns 0 on failure, 1 on success */
uint8_t
-ao_ee_read_config(uint8_t *buf, uint16_t len) __reentrant;
+ao_storage_read(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant;
-/* Initialize the EEPROM code */
+/* Initialize the storage code */
void
-ao_ee_init(void);
+ao_storage_init(void);
/*
* ao_log.c
static void
_ao_config_put(void)
{
- ao_ee_write_config((uint8_t *) &ao_config, sizeof (ao_config));
+ ao_storage_setup();
+ ao_storage_write(ao_storage_config, &ao_config, sizeof (ao_config));
+ ao_storage_flush();
}
#endif
if (ao_config_loaded)
return;
#if HAS_EEPROM
- ao_ee_read_config((uint8_t *) &ao_config, sizeof (ao_config));
+ ao_storage_setup();
+ ao_storage_read(ao_storage_config, &ao_config, sizeof (ao_config));
#endif
if (ao_config.major != AO_CONFIG_MAJOR) {
ao_config.major = AO_CONFIG_MAJOR;
#include "ao.h"
#include "25lc1024.h"
+#define EE_BLOCK_SIZE ((uint16_t) (256))
+#define EE_DEVICE_SIZE ((uint32_t) 128 * (uint32_t) 1024)
+
+/* Total bytes of available storage */
+__xdata uint32_t ao_storage_total;
+
+/* Block size - device is erased in these units. At least 256 bytes */
+__xdata uint32_t ao_storage_block;
+
+/* Byte offset of config block. Will be ao_storage_block bytes long */
+__xdata uint32_t ao_storage_config;
+
/*
* Using SPI on USART 0, with P1_2 as the chip select
*/
#define EE_CS P1_2
#define EE_CS_INDEX 2
-__xdata uint8_t ao_ee_mutex;
+static __xdata uint8_t ao_ee_mutex;
#define ao_ee_delay() do { \
_asm nop _endasm; \
_asm nop _endasm; \
} while(0)
-void ao_ee_cs_low(void)
+static void ao_ee_cs_low(void)
{
ao_ee_delay();
EE_CS = 0;
ao_ee_delay();
}
-void ao_ee_cs_high(void)
+static void ao_ee_cs_high(void)
{
ao_ee_delay();
EE_CS = 1;
ao_ee_delay();
}
-
-#define EE_BLOCK 256
-
struct ao_ee_instruction {
uint8_t instruction;
uint8_t address[3];
#define EE_BLOCK_NONE 0xffff
-static __xdata uint8_t ao_ee_data[EE_BLOCK];
+static __xdata uint8_t ao_ee_data[EE_BLOCK_SIZE];
static __pdata uint16_t ao_ee_block = EE_BLOCK_NONE;
static __pdata uint8_t ao_ee_block_dirty;
ao_ee_instruction.address[1] = ao_ee_block;
ao_ee_instruction.address[2] = 0;
ao_spi_send(&ao_ee_instruction, 4);
- ao_spi_send(ao_ee_data, EE_BLOCK);
+ ao_spi_send(ao_ee_data, EE_BLOCK_SIZE);
ao_ee_cs_high();
for (;;) {
uint8_t status = ao_ee_rdsr();
ao_ee_instruction.address[1] = ao_ee_block;
ao_ee_instruction.address[2] = 0;
ao_spi_send(&ao_ee_instruction, 4);
- ao_spi_recv(ao_ee_data, EE_BLOCK);
+ ao_spi_recv(ao_ee_data, EE_BLOCK_SIZE);
ao_ee_cs_high();
}
}
uint8_t
-ao_ee_write(uint32_t pos, uint8_t *buf, uint16_t len) __reentrant
+ao_storage_write(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant
{
uint16_t block;
uint16_t this_len;
uint8_t this_off;
- if (pos >= AO_EE_DATA_SIZE || pos + len > AO_EE_DATA_SIZE)
+ if (pos >= ao_storage_total || pos + len > ao_storage_total)
return 0;
while (len) {
* a single block
*/
this_off = pos;
- this_len = 256 - (uint16_t) this_off;
+ this_len = EE_BLOCK_SIZE - (uint16_t) this_off;
block = (uint16_t) (pos >> 8);
if (this_len > len)
this_len = len;
/* Transfer the data */
ao_mutex_get(&ao_ee_mutex); {
- if (this_len != 256)
+ if (this_len != EE_BLOCK_SIZE)
ao_ee_fill(block);
else {
ao_ee_flush_internal();
}
uint8_t
-ao_ee_read(uint32_t pos, uint8_t *buf, uint16_t len) __reentrant
+ao_storage_read(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant
{
uint16_t block;
uint16_t this_len;
uint8_t this_off;
- if (pos >= AO_EE_DATA_SIZE || pos + len > AO_EE_DATA_SIZE)
+ if (pos >= ao_storage_total || pos + len > ao_storage_total)
return 0;
while (len) {
* a single block
*/
this_off = pos;
- this_len = 256 - (uint16_t) this_off;
+ this_len = EE_BLOCK_SIZE - (uint16_t) this_off;
block = (uint16_t) (pos >> 8);
if (this_len > len)
this_len = len;
}
void
-ao_ee_flush(void) __reentrant
-{
- ao_mutex_get(&ao_ee_mutex); {
- ao_ee_flush_internal();
- } ao_mutex_put(&ao_ee_mutex);
-}
-
-/*
- * Read/write the config block, which is in
- * the last block of the ao_eeprom
- */
-uint8_t
-ao_ee_write_config(uint8_t *buf, uint16_t len) __reentrant
+ao_storage_flush(void) __reentrant
{
- if (len > AO_EE_BLOCK_SIZE)
- return 0;
ao_mutex_get(&ao_ee_mutex); {
- ao_ee_fill(AO_EE_CONFIG_BLOCK);
- memcpy(ao_ee_data, buf, len);
- ao_ee_block_dirty = 1;
ao_ee_flush_internal();
} ao_mutex_put(&ao_ee_mutex);
- return 1;
-}
-
-uint8_t
-ao_ee_read_config(uint8_t *buf, uint16_t len) __reentrant
-{
- if (len > AO_EE_BLOCK_SIZE)
- return 0;
- ao_mutex_get(&ao_ee_mutex); {
- ao_ee_fill(AO_EE_CONFIG_BLOCK);
- memcpy(buf, ao_ee_data, len);
- } ao_mutex_put(&ao_ee_mutex);
- return 1;
}
static void
ee_dump(void) __reentrant
{
- uint8_t b;
+ static __xdata uint8_t b;
uint16_t block;
uint8_t i;
ao_cmd_put16((uint16_t) i);
}
putchar(' ');
- ao_ee_read(((uint32_t) block << 8) | i, &b, 1);
+ ao_storage_read(((uint32_t) block << 8) | i, &b, 1);
ao_cmd_put8(b);
++i;
} while (i != 0);
uint16_t block;
uint8_t i;
uint16_t len;
- uint8_t b;
+ static __xdata uint8_t b;
uint32_t addr;
ao_cmd_hex();
if (ao_cmd_status != ao_cmd_success)
return;
b = ao_cmd_lex_i;
- ao_ee_write(addr, &b, 1);
+ ao_storage_write(addr, &b, 1);
addr++;
}
- ao_ee_flush();
+ ao_storage_flush();
}
__code struct ao_cmds ao_ee_cmds[] = {
{ 0, ee_store, NULL },
};
+void
+ao_storage_setup(void)
+{
+ if (ao_storage_total == 0) {
+ ao_storage_total = EE_DEVICE_SIZE;
+ ao_storage_block = EE_BLOCK_SIZE;
+ ao_storage_config = EE_DEVICE_SIZE - EE_BLOCK_SIZE;
+ }
+}
+
/*
* To initialize the chip, set up the CS line and
* the SPI interface
*/
void
-ao_ee_init(void)
+ao_storage_init(void)
{
/* set up CS */
EE_CS = 1;
#include "ao.h"
#include "at45db161d.h"
+/* Total bytes of available storage */
+__xdata uint32_t ao_storage_total;
+
+/* Block size - device is erased in these units. At least 256 bytes */
+__xdata uint32_t ao_storage_block;
+
+/* Byte offset of config block. Will be ao_storage_block bytes long */
+__xdata uint32_t ao_storage_config;
+
#define FLASH_CS P1_1
#define FLASH_CS_INDEX 1
+#define FLASH_BLOCK_SIZE_MAX 512
+
__xdata uint8_t ao_flash_mutex;
#define ao_flash_delay() do { \
static __pdata uint8_t ao_flash_block_dirty;
static __pdata uint8_t ao_flash_write_pending;
static __pdata uint8_t ao_flash_setup_done;
-static __data uint32_t ao_flash_device_size;
static __data uint8_t ao_flash_block_shift;
static __data uint16_t ao_flash_block_size;
+static __data uint16_t ao_flash_block_mask;
-static void
-ao_flash_setup(void)
+void
+ao_storage_setup(void)
{
uint8_t status;
/* AT45DB321D */
case 0x34:
ao_flash_block_shift = 9;
- ao_flash_device_size = ((uint32_t) 4 * (uint32_t) 1024 * (uint32_t) 1024);
+ ao_storage_total = ((uint32_t) 4 * (uint32_t) 1024 * (uint32_t) 1024);
break;
/* AT45DB161D */
case 0x2c:
ao_flash_block_shift = 9;
- ao_flash_device_size = ((uint32_t) 2 * (uint32_t) 1024 * (uint32_t) 1024);
+ ao_storage_total = ((uint32_t) 2 * (uint32_t) 1024 * (uint32_t) 1024);
break;
/* AT45DB081D */
case 0x24:
ao_flash_block_shift = 8;
- ao_flash_device_size = ((uint32_t) 1024 * (uint32_t) 1024);
+ ao_storage_total = ((uint32_t) 1024 * (uint32_t) 1024);
break;
/* AT45DB041D */
case 0x1c:
ao_flash_block_shift = 8;
- ao_flash_device_size = ((uint32_t) 512 * (uint32_t) 1024);
+ ao_storage_total = ((uint32_t) 512 * (uint32_t) 1024);
break;
/* AT45DB021D */
case 0x14:
ao_flash_block_shift = 8;
- ao_flash_device_size = ((uint32_t) 256 * (uint32_t) 1024);
+ ao_storage_total = ((uint32_t) 256 * (uint32_t) 1024);
break;
/* AT45DB011D */
case 0x0c:
ao_flash_block_shift = 8;
- ao_flash_device_size = ((uint32_t) 128 * (uint32_t) 1024);
+ ao_storage_total = ((uint32_t) 128 * (uint32_t) 1024);
break;
default:
ao_panic(AO_PANIC_FLASH);
}
ao_flash_block_size = 1 << ao_flash_block_shift;
+
+ ao_storage_block = ao_flash_block_size;
+ ao_storage_config = ao_storage_total - ao_storage_block;
+
ao_flash_setup_done = 1;
ao_mutex_put(&ao_flash_mutex);
}
ao_flash_instruction.address[1] = ao_flash_block << (ao_flash_block_shift - 8);
ao_flash_instruction.address[2] = 0;
ao_spi_send(&ao_flash_instruction, 4);
- ao_spi_send(ao_flash_data, FLASH_BLOCK_SIZE);
+ ao_spi_send(ao_flash_data, ao_storage_block);
ao_flash_cs_high();
ao_flash_write_pending = 1;
}
ao_flash_instruction.address[1] = ao_flash_block << (ao_flash_block_shift - 8);
ao_flash_instruction.address[2] = 0;
ao_spi_send(&ao_flash_instruction, 4);
- ao_spi_recv(ao_flash_data, FLASH_BLOCK_SIZE);
+ ao_spi_recv(ao_flash_data, ao_flash_block_size);
ao_flash_cs_high();
}
}
uint8_t
-ao_ee_write(uint32_t pos, uint8_t *buf, uint16_t len) __reentrant
+ao_storage_write(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant
{
uint16_t block;
uint16_t this_len;
uint16_t this_off;
- ao_flash_setup();
- if (pos >= FLASH_DATA_SIZE || pos + len > FLASH_DATA_SIZE)
+ ao_storage_setup();
+ if (pos >= ao_storage_total || pos + len > ao_storage_total)
return 0;
while (len) {
/* Compute portion of transfer within
* a single block
*/
- this_off = (uint16_t) pos & FLASH_BLOCK_MASK;
- this_len = FLASH_BLOCK_SIZE - this_off;
- block = (uint16_t) (pos >> FLASH_BLOCK_SHIFT);
+ this_off = (uint16_t) pos & ao_flash_block_mask;
+ this_len = ao_flash_block_size - this_off;
+ block = (uint16_t) (pos >> ao_flash_block_shift);
if (this_len > len)
this_len = len;
/* Transfer the data */
ao_mutex_get(&ao_flash_mutex); {
- if (this_len != FLASH_BLOCK_SIZE)
+ if (this_len != ao_flash_block_size)
ao_flash_fill(block);
else {
ao_flash_flush_internal();
}
uint8_t
-ao_ee_read(uint32_t pos, uint8_t *buf, uint16_t len) __reentrant
+ao_storage_read(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant
{
uint16_t block;
uint16_t this_len;
uint16_t this_off;
- ao_flash_setup();
- if (pos >= FLASH_DATA_SIZE || pos + len > FLASH_DATA_SIZE)
+ ao_storage_setup();
+ if (pos >= ao_storage_total || pos + len > ao_storage_total)
return 0;
while (len) {
/* Compute portion of transfer within
* a single block
*/
- this_off = (uint16_t) pos & FLASH_BLOCK_MASK;
- this_len = FLASH_BLOCK_SIZE - this_off;
- block = (uint16_t) (pos >> FLASH_BLOCK_SHIFT);
+ this_off = (uint16_t) pos & ao_flash_block_mask;
+ this_len = ao_flash_block_size - this_off;
+ block = (uint16_t) (pos >> ao_flash_block_shift);
if (this_len > len)
this_len = len;
}
void
-ao_ee_flush(void) __reentrant
-{
- ao_mutex_get(&ao_flash_mutex); {
- ao_flash_flush_internal();
- } ao_mutex_put(&ao_flash_mutex);
-}
-
-/*
- * Read/write the config block, which is in
- * the last block of the flash
- */
-
-uint8_t
-ao_ee_write_config(uint8_t *buf, uint16_t len) __reentrant
+ao_storage_flush(void) __reentrant
{
- ao_flash_setup();
- if (len > FLASH_BLOCK_SIZE)
- return 0;
ao_mutex_get(&ao_flash_mutex); {
- ao_flash_fill(FLASH_CONFIG_BLOCK);
- memcpy(ao_flash_data, buf, len);
- ao_flash_block_dirty = 1;
ao_flash_flush_internal();
} ao_mutex_put(&ao_flash_mutex);
- return 1;
-}
-
-uint8_t
-ao_ee_read_config(uint8_t *buf, uint16_t len) __reentrant
-{
- ao_flash_setup();
- if (len > FLASH_BLOCK_SIZE)
- return 0;
- ao_mutex_get(&ao_flash_mutex); {
- ao_flash_fill(FLASH_CONFIG_BLOCK);
- memcpy(buf, ao_flash_data, len);
- } ao_mutex_put(&ao_flash_mutex);
- return 1;
}
static void
flash_dump(void) __reentrant
{
- uint8_t b;
+ static __xdata uint8_t b;
uint16_t block;
uint8_t i;
ao_cmd_put16((uint16_t) i);
}
putchar(' ');
- ao_ee_read(((uint32_t) block << 8) | i, &b, 1);
+ ao_storage_read(((uint32_t) block << 8) | i, &b, 1);
ao_cmd_put8(b);
++i;
} while (i != 0);
uint16_t block;
uint8_t i;
uint16_t len;
- uint8_t b;
+ static __xdata uint8_t b;
uint32_t addr;
ao_cmd_hex();
if (ao_cmd_status != ao_cmd_success)
return;
b = ao_cmd_lex_i;
- ao_ee_write(addr, &b, 1);
+ ao_storage_write(addr, &b, 1);
addr++;
}
- ao_ee_flush();
-}
-
-void
-ao_ee_dump_config(void) __reentrant
-{
- uint16_t i;
- printf("Configuration block %d\n", FLASH_CONFIG_BLOCK);
- ao_mutex_get(&ao_flash_mutex); {
- ao_flash_flush_internal();
- ao_flash_block = FLASH_BLOCK_NONE;
- ao_flash_fill(FLASH_CONFIG_BLOCK);
- i = 0;
- do {
- if ((i & 7) == 0) {
- if (i)
- putchar('\n');
- ao_cmd_put16((uint16_t) i);
- }
- putchar(' ');
- ao_cmd_put8(ao_flash_data[i]);
- ++i;
- } while (i < sizeof (ao_config));
- } ao_mutex_put(&ao_flash_mutex);
+ ao_storage_flush();
}
static void
{
uint8_t status;
- ao_flash_setup();
+ ao_storage_setup();
ao_mutex_get(&ao_flash_mutex); {
status = ao_flash_read_status();
printf ("Flash status: 0x%02x\n", status);
- printf ("Flash block shift: %d\n", FLASH_BLOCK_SHIFT);
- printf ("Flash block size: %d\n", FLASH_BLOCK_SIZE);
- printf ("Flash block mask: %d\n", FLASH_BLOCK_MASK);
- printf ("Flash device size: %ld\n", FLASH_DEVICE_SIZE);
- printf ("Flash data size: %ld\n", FLASH_DATA_SIZE);
- printf ("Flash config block: %d\n", FLASH_CONFIG_BLOCK);
+ printf ("Flash block shift: %d\n", ao_flash_block_shift);
+ printf ("Flash block size: %d\n", ao_flash_block_size);
+ printf ("Flash block mask: %d\n", ao_flash_block_mask);
+ printf ("Flash device size: %ld\n", ao_storage_total);
} ao_mutex_put(&ao_flash_mutex);
- ao_ee_dump_config();
}
__code struct ao_cmds ao_flash_cmds[] = {
* the SPI interface
*/
void
-ao_ee_init(void)
+ao_storage_init(void)
{
/* set up CS */
FLASH_CS = 1;
#include "ao.h"
static __pdata uint32_t ao_log_current_pos;
+static __pdata uint32_t ao_log_end_pos;
static __pdata uint32_t ao_log_start_pos;
static __xdata uint8_t ao_log_running;
static __xdata uint8_t ao_log_mutex;
log->csum = 0;
log->csum = ao_log_csum((__xdata uint8_t *) log);
ao_mutex_get(&ao_log_mutex); {
+ if (ao_log_current_pos >= ao_log_end_pos)
+ ao_log_running = 0;
if (ao_log_running) {
wrote = 1;
- ao_ee_write(ao_log_current_pos,
- (uint8_t *) log,
- sizeof (struct ao_log_record));
+ ao_storage_write(ao_log_current_pos,
+ log,
+ sizeof (struct ao_log_record));
ao_log_current_pos += sizeof (struct ao_log_record);
- if (ao_log_current_pos >= AO_EE_DATA_SIZE)
- ao_log_current_pos = 0;
- if (ao_log_current_pos == ao_log_start_pos)
- ao_log_running = 0;
}
} ao_mutex_put(&ao_log_mutex);
return wrote;
void
ao_log_flush(void)
{
- ao_ee_flush();
+ ao_storage_flush();
}
__xdata struct ao_log_record log;
static void
ao_log_scan(void)
{
- if (!ao_ee_read(0, (uint8_t *) &log, sizeof (struct ao_log_record)))
+ if (!ao_storage_read(0, &log, sizeof (struct ao_log_record)))
ao_panic(AO_PANIC_LOG);
if (ao_log_dump_check_data() && log.type == AO_LOG_FLIGHT) {
ao_flight_number = log.u.flight.flight + 1;
void
ao_log(void)
{
+ ao_storage_setup();
+
+ /* For now, use all of the available space */
+ ao_log_current_pos = 0;
+ ao_log_end_pos = ao_storage_config;
+
ao_log_scan();
while (!ao_log_running)
ao_log_running = 0;
/* For now, just log the flight starting at the begining of eeprom */
- ao_log_start_pos = 0;
- ao_log_current_pos = ao_log_start_pos;
ao_log_state = ao_flight_invalid;
/* Create a task to log events to eeprom */
ao_beep_init();
ao_cmd_init();
ao_spi_init();
- ao_ee_init();
+ ao_storage_init();
ao_flight_init();
ao_log_init();
ao_report_init();
* area return errors.
*/
-#define FLASH_BLOCK_SIZE_MAX 512
-#define FLASH_BLOCK_SHIFT (ao_flash_block_shift)
-#define FLASH_BLOCK_SIZE (ao_flash_block_size)
-#define FLASH_BLOCK_MASK (FLASH_BLOCK_SIZE - 1)
-#define FLASH_DEVICE_SIZE (ao_flash_device_size)
-#define FLASH_DATA_SIZE (FLASH_DEVICE_SIZE - (uint32_t) FLASH_BLOCK_SIZE)
-#define FLASH_CONFIG_BLOCK ((uint16_t) (FLASH_DATA_SIZE / FLASH_BLOCK_SIZE))
#define FLASH_READ 0x03
#define FLASH_WRITE 0x82