*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
#include "ao.h"
/* Total bytes of available storage */
-__pdata uint32_t ao_storage_total;
+uint32_t ao_storage_total;
/* Block size - device is erased in these units. At least 256 bytes */
-__pdata uint32_t ao_storage_block;
+uint32_t ao_storage_block;
/* Byte offset of config block. Will be ao_storage_block bytes long */
-__pdata uint32_t ao_storage_config;
+uint32_t ao_storage_config;
/* Storage unit size - device reads and writes must be within blocks of this size. Usually 256 bytes. */
-__pdata uint16_t ao_storage_unit;
+uint16_t ao_storage_unit;
+#define M25_DEBUG 0
/*
* Each flash chip is arranged in 64kB sectors; the
* chip cannot erase in units smaller than that.
*/
#if M25_MAX_CHIPS > 1
-static uint8_t ao_m25_size[M25_MAX_CHIPS]; /* number of sectors in each chip */
-static uint8_t ao_m25_pin[M25_MAX_CHIPS]; /* chip select pin for each chip */
+static uint32_t ao_m25_size[M25_MAX_CHIPS]; /* number of sectors in each chip */
+static ao_port_t ao_m25_pin[M25_MAX_CHIPS]; /* chip select pin for each chip */
static uint8_t ao_m25_numchips; /* number of chips detected */
#endif
-static uint8_t ao_m25_total; /* total sectors available */
-static uint8_t ao_m25_wip; /* write in progress */
+static uint32_t ao_m25_total; /* total sectors available */
+static ao_port_t ao_m25_wip; /* write in progress */
-static __xdata uint8_t ao_m25_mutex;
+static uint8_t ao_m25_mutex;
/*
* This little array is abused to send and receive data. A particular
* of which touch those last three bytes.
*/
-static __xdata uint8_t ao_m25_instruction[4];
+static uint8_t ao_m25_instruction[4];
-#define M25_SELECT(cs) ao_spi_get_mask(AO_M25_SPI_CS_PORT,cs,AO_M25_SPI_BUS)
+#define AO_M25_SPI_SPEED ao_spi_speed(10000000) /* this seems like a reasonable minimum speed to require */
+
+#define M25_SELECT(cs) ao_spi_get_mask(AO_M25_SPI_CS_PORT,cs,AO_M25_SPI_BUS,AO_M25_SPI_SPEED)
#define M25_DESELECT(cs) ao_spi_put_mask(AO_M25_SPI_CS_PORT,cs,AO_M25_SPI_BUS)
#define M25_BLOCK_SHIFT 16
#define M25_BLOCK 65536L
-#define M25_POS_TO_SECTOR(pos) ((uint8_t) ((pos) >> M25_BLOCK_SHIFT))
+#define M25_POS_TO_SECTOR(pos) ((uint32_t) ((pos) >> M25_BLOCK_SHIFT))
#define M25_SECTOR_TO_POS(sector) (((uint32_t) (sector)) << M25_BLOCK_SHIFT)
/*
* Block until the specified chip is done writing
*/
static void
-ao_m25_wait_wip(uint8_t cs)
+ao_m25_wait_wip(ao_port_t cs)
{
if (ao_m25_wip & cs) {
M25_SELECT(cs);
* so that future operations will block until the WIP bit goes off
*/
static void
-ao_m25_write_enable(uint8_t cs)
+ao_m25_write_enable(ao_port_t cs)
{
M25_SELECT(cs);
ao_m25_instruction[0] = M25_WREN;
/*
* Returns the number of 64kB sectors
*/
-static uint8_t
-ao_m25_read_capacity(uint8_t cs)
+static uint32_t
+ao_m25_read_capacity(ao_port_t cs)
{
uint8_t capacity;
M25_SELECT(cs);
return 1 << (capacity - 0x10);
}
-static uint8_t
+static ao_port_t
ao_m25_set_address(uint32_t pos)
{
- uint8_t chip;
+ ao_port_t mask;
#if M25_MAX_CHIPS > 1
- uint8_t size;
+ uint32_t size;
+ uint8_t chip;
for (chip = 0; chip < ao_m25_numchips; chip++) {
size = ao_m25_size[chip];
if (chip == ao_m25_numchips)
return 0xff;
- chip = ao_m25_pin[chip];
+ mask = ao_m25_pin[chip];
#else
- chip = AO_M25_SPI_CS_MASK;
+ mask = AO_M25_SPI_CS_MASK;
#endif
- ao_m25_wait_wip(chip);
+ ao_m25_wait_wip(mask);
ao_m25_instruction[1] = pos >> 16;
ao_m25_instruction[2] = pos >> 8;
ao_m25_instruction[3] = pos;
- return chip;
+ return mask;
}
/*
ao_m25_scan(void)
{
#if M25_MAX_CHIPS > 1
- uint8_t pin, size;
+ uint8_t pin;
+ uint32_t size;
#endif
if (ao_m25_total)
* Erase the specified sector
*/
uint8_t
-ao_storage_erase(uint32_t pos) __reentrant
+ao_storage_device_erase(uint32_t pos)
{
- uint8_t cs;
+ ao_port_t cs;
if (pos >= ao_storage_total || pos + ao_storage_block > ao_storage_total)
return 0;
cs = ao_m25_set_address(pos);
- ao_m25_wait_wip(cs);
ao_m25_write_enable(cs);
ao_m25_instruction[0] = M25_SE;
* Write to flash
*/
uint8_t
-ao_storage_device_write(uint32_t pos, __xdata void *d, uint16_t len) __reentrant
+ao_storage_device_write(uint32_t pos, void *d, uint16_t len)
{
- uint8_t cs;
+ ao_port_t cs;
if (pos >= ao_storage_total || pos + len > ao_storage_total)
return 0;
* Read from flash
*/
uint8_t
-ao_storage_device_read(uint32_t pos, __xdata void *d, uint16_t len) __reentrant
+ao_storage_device_read(uint32_t pos, void *d, uint16_t len)
{
- uint8_t cs;
+ ao_port_t cs;
if (pos >= ao_storage_total || pos + len > ao_storage_total)
return 0;
}
void
-ao_storage_flush(void) __reentrant
+ao_storage_flush(void)
{
}
}
void
-ao_storage_device_info(void) __reentrant
+ao_storage_device_info(void)
{
- uint8_t cs;
+#if M25_DEBUG
+ ao_port_t cs;
+#endif
#if M25_MAX_CHIPS > 1
uint8_t chip;
#endif
ao_mutex_put(&ao_m25_mutex);
#if M25_MAX_CHIPS > 1
- printf ("Detected chips %d size %d\n", ao_m25_numchips, ao_m25_total);
+ printf ("Detected chips %d size %ld\n", ao_m25_numchips, ao_m25_total);
for (chip = 0; chip < ao_m25_numchips; chip++)
printf ("Flash chip %d select %02x size %d\n",
chip, ao_m25_pin[chip], ao_m25_size[chip]);
#else
- printf ("Detected chips 1 size %d\n", ao_m25_total);
+ printf ("Detected chips 1 size %ld\n", ao_m25_total);
#endif
+#if M25_DEBUG
printf ("Available chips:\n");
for (cs = 1; cs != 0; cs <<= 1) {
if ((AO_M25_SPI_CS_MASK & cs) == 0)
ao_m25_instruction[M25_UID_OFFSET]);
ao_mutex_put(&ao_m25_mutex);
}
+#endif
}
void