diff options
Diffstat (limited to 'src/ao_flash.c')
| -rw-r--r-- | src/ao_flash.c | 166 | 
1 files changed, 34 insertions, 132 deletions
diff --git a/src/ao_flash.c b/src/ao_flash.c index bc8b56ad..1201a0e5 100644 --- a/src/ao_flash.c +++ b/src/ao_flash.c @@ -27,6 +27,9 @@ __xdata uint32_t	ao_storage_block;  /* Byte offset of config block. Will be ao_storage_block bytes long */  __xdata uint32_t	ao_storage_config; +/* Storage unit size - device reads and writes must be within blocks of this size. Usually 256 bytes. */ +__xdata uint16_t	ao_storage_unit; +  #define FLASH_CS		P1_1  #define FLASH_CS_INDEX		1 @@ -162,9 +165,11 @@ ao_storage_setup(void)  		ao_panic(AO_PANIC_FLASH);  	}  	ao_flash_block_size = 1 << ao_flash_block_shift; +	ao_flash_block_mask = ao_flash_block_size - 1;  	ao_storage_block = ao_flash_block_size;  	ao_storage_config = ao_storage_total - ao_storage_block; +	ao_storage_unit = ao_flash_block_size;  	ao_flash_setup_done = 1;  	ao_mutex_put(&ao_flash_mutex); @@ -238,79 +243,38 @@ ao_flash_fill(uint16_t block)  }  uint8_t -ao_storage_write(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant +ao_storage_device_write(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant  { -	uint16_t block; -	uint16_t this_len; -	uint16_t	this_off; +	uint16_t block = (uint16_t) (pos >> ao_flash_block_shift); -	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 & 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 != ao_flash_block_size) -				ao_flash_fill(block); -			else { -				ao_flash_flush_internal(); -				ao_flash_block = block; -			} -			memcpy(ao_flash_data + this_off, buf, this_len); -			ao_flash_block_dirty = 1; -		} ao_mutex_put(&ao_flash_mutex); - -		/* See how much is left */ -		buf += this_len; -		len -= this_len; -		pos += this_len; -	} +	/* Transfer the data */ +	ao_mutex_get(&ao_flash_mutex); { +		if (len != ao_flash_block_size) +			ao_flash_fill(block); +		else { +			ao_flash_flush_internal(); +			ao_flash_block = block; +		} +		memcpy(ao_flash_data + (uint16_t) (pos & ao_flash_block_mask), +		       buf, +		       len); +		ao_flash_block_dirty = 1; +	} ao_mutex_put(&ao_flash_mutex);  	return 1;  }  uint8_t -ao_storage_read(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant +ao_storage_device_read(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant  { -	uint16_t block; -	uint16_t this_len; -	uint16_t this_off; +	uint16_t block = (uint16_t) (pos >> ao_flash_block_shift); -	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 & 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); { -			ao_flash_fill(block); -			memcpy(buf, ao_flash_data + this_off, this_len); -		} ao_mutex_put(&ao_flash_mutex); - -		/* See how much is left */ -		buf += this_len; -		len -= this_len; -		pos += this_len; -	} +	/* Transfer the data */ +	ao_mutex_get(&ao_flash_mutex); { +		ao_flash_fill(block); +		memcpy(buf, +		       ao_flash_data + (uint16_t) (pos & ao_flash_block_mask), +		       len); +	} ao_mutex_put(&ao_flash_mutex);  	return 1;  } @@ -325,8 +289,9 @@ ao_storage_flush(void) __reentrant  uint8_t  ao_storage_erase(uint32_t pos) __reentrant  { +	uint16_t block = (uint16_t) (pos >> ao_flash_block_shift); +  	ao_mutex_get(&ao_flash_mutex); { -		uint16_t block = (uint16_t) (pos >> ao_flash_block_shift);  		ao_flash_fill(block);  		memset(ao_flash_data, 0xff, ao_flash_block_size);  		ao_flash_block_dirty = 1; @@ -334,63 +299,8 @@ ao_storage_erase(uint32_t pos) __reentrant  	return 1;  } -static void -flash_dump(void) __reentrant -{ -	static __xdata uint8_t	b; -	uint16_t block; -	uint8_t i; - -	ao_cmd_hex(); -	block = ao_cmd_lex_i; -	if (ao_cmd_status != ao_cmd_success) -		return; -	i = 0; -	do { -		if ((i & 7) == 0) { -			if (i) -				putchar('\n'); -			ao_cmd_put16((uint16_t) i); -		} -		putchar(' '); -		ao_storage_read(((uint32_t) block << 8) | i, &b, 1); -		ao_cmd_put8(b); -		++i; -	} while (i != 0); -	putchar('\n'); -} - -static void -flash_store(void) __reentrant -{ -	uint16_t block; -	uint8_t i; -	uint16_t len; -	static __xdata uint8_t b; -	uint32_t addr; - -	ao_cmd_hex(); -	block = ao_cmd_lex_i; -	ao_cmd_hex(); -	i = ao_cmd_lex_i; -	addr = ((uint32_t) block << 8) | i; -	ao_cmd_hex(); -	len = ao_cmd_lex_i; -	if (ao_cmd_status != ao_cmd_success) -		return; -	while (len--) { -		ao_cmd_hex(); -		if (ao_cmd_status != ao_cmd_success) -			return; -		b = ao_cmd_lex_i; -		ao_storage_write(addr, &b, 1); -		addr++; -	} -	ao_storage_flush(); -} - -static void -flash_status(void) __reentrant +void +ao_storage_device_info(void) __reentrant  {  	uint8_t	status; @@ -405,23 +315,15 @@ flash_status(void) __reentrant  	} ao_mutex_put(&ao_flash_mutex);  } -__code struct ao_cmds ao_flash_cmds[] = { -	{ 'e', flash_dump, 	"e <block>                          Dump a block of flash data" }, -	{ 'w', flash_store,	"w <block> <start> <len> <data> ... Write data to flash" }, -	{ 'f', flash_status,	"f                                  Show flash status register" }, -	{ 0,   flash_store, NULL }, -}; -  /*   * To initialize the chip, set up the CS line and   * the SPI interface   */  void -ao_storage_init(void) +ao_storage_device_init(void)  {  	/* set up CS */  	FLASH_CS = 1;  	P1DIR |= (1 << FLASH_CS_INDEX);  	P1SEL &= ~(1 << FLASH_CS_INDEX); -	ao_cmd_register(&ao_flash_cmds[0]);  }  | 
