mac-rom-simm-programmer/drivers/parallel_flash.h

67 lines
2.3 KiB
C
Raw Normal View History

Break out code into a HAL, optimize flash operations This makes the code pretty easily portable to other architectures if someone wants to make a more modern SIMM programmer. I also was pretty careful to split responsibilities of the different components and give the existing components better names. I'm pretty happy with the organization of the code now. As part of this change I have also heavily optimized the code. In particular, the read and write cycle routines are very important to the overall performance of the programmer. In these routines I had to make some tradeoffs of code performance versus prettiness, but the overall result is much faster programming. Some of these performance changes are the result of what I discovered when I upgraded my AVR compiler. I discovered that it is smarter at looking at 32-bit variables when I use a union instead of bitwise operations. I also shaved off more CPU cycles by carefully making a few small tweaks. I added a bypass for the "program only some chips" mask, because it was adding unnecessary CPU cycles for a feature that is rarely used. I removed the verification feature from the write routine, because we can always verify the data after the write chunk is complete, which is more efficient. I also added assumptions about the initial/final state of the CS/OE/WE pins, which allowed me to remove more valuable CPU cycles from the read/write cycle routines. There are also a few enormous performance optimizations I should have done a long time ago: 1) The code was only handling one received byte per main loop iteration. Reading every byte available cut nearly a minute off of the 8 MB programming time. 2) The code wasn't taking advantage of the faster programming command available in the chips used on the 8 MB SIMM. The end result of all of these optimizations is I have programming time of the 8 MB SIMM down to 3:31 (it used to be 8:43). Another minor issue I fixed: the Micron SIMM chip identification wasn't working properly. It was outputting the manufacturer ID again instead of the device ID.
2020-11-18 05:03:32 +00:00
/*
* parallel_flash.h
*
* Created on: Nov 25, 2011
* Author: Doug
*/
#ifndef DRIVERS_PARALLEL_FLASH_H_
#define DRIVERS_PARALLEL_FLASH_H_
#include "../hal/parallel_bus.h"
/// The number of chips we are simultaneously addressing
#define PARALLEL_FLASH_NUM_CHIPS 4
/// Masks for functions that want a chip mask...
#define IC1 (1 << 3)
#define IC2 (1 << 2)
#define IC3 (1 << 1)
#define IC4 (1 << 0)
#define ALL_CHIPS (IC1 | IC2 | IC3 | IC4)
/// Holds info about the chip (retrieved with JEDEC standards)
typedef struct ParallelFlashChipID
{
/// The manufacturer ID
uint8_t manufacturer;
/// The device ID
uint8_t device;
} ParallelFlashChipID;
/// Type/layout of chips currently being addressed
typedef enum ParallelFlashChipType
{
/// Four SST39SF040 chips, 512 KB each, for a total of 2 MB
ParallelFlash_SST39SF040_x4,
/// Four M29F160FB5AN6E2 chips, 2 MB each, in 8-bit mode, for a total of 8 MB
ParallelFlash_M29F160FB5AN6E2_x4,
} ParallelFlashChipType;
// Tells which type of flash chip we are communicating with
void ParallelFlash_SetChipType(ParallelFlashChipType type);
ParallelFlashChipType ParallelFlash_ChipType(void);
// Reads a set of data from all 4 chips simultaneously
void ParallelFlash_Read(uint32_t startAddress, uint32_t *buf, uint16_t len);
// Does an unlock sequence on the chips requested
void ParallelFlash_UnlockChips(uint8_t chipsMask);
// Identifies all four chips
void ParallelFlash_IdentifyChips(ParallelFlashChipID *chips);
// Erases the chips/sectors requested
void ParallelFlash_EraseChips(uint8_t chipsMask);
bool ParallelFlash_EraseSectors(uint32_t address, uint32_t length, uint8_t chipsMask);
// Writes a buffer to all 4 chips simultaneously (each uint32_t contains an 8-bit portion for each chip).
// Optimized variant of this function if we know we're writing to all 4 chips simultaneously.
// Allows us to bypass a lot of operations involving "chipsMask".
void ParallelFlash_WriteAllChips(uint32_t startAddress, uint32_t const *buf, uint16_t len);
// Writes a buffer to a mask of requested chips (each uint32_t contains an 8-bit portion for each chip).
void ParallelFlash_WriteSomeChips(uint32_t startAddress, uint32_t const *buf, uint16_t len, uint8_t chipsMask);
#endif /* DRIVERS_PARALLEL_FLASH_H_ */