From ad3d470f40cb9b7c86cfbeda412dce1e69e7061d Mon Sep 17 00:00:00 2001 From: James Cotton Date: Thu, 26 Jan 2012 12:39:35 -0600 Subject: [PATCH] Flashfs and Flash: Add new function to write a series of blocks in one flash write transaction to improve efficieny. --- flight/PiOS/Common/pios_flash_jedec.c | 74 ++++++++++++++++++- flight/PiOS/Common/pios_flashfs_objlist.c | 36 ++++----- flight/PiOS/inc/pios_flash_jedec.h | 6 ++ .../OpenPilotOSX.xcodeproj/project.pbxproj | 33 --------- 4 files changed, 97 insertions(+), 52 deletions(-) diff --git a/flight/PiOS/Common/pios_flash_jedec.c b/flight/PiOS/Common/pios_flash_jedec.c index 8d6994e5f..b6f1ec930 100644 --- a/flight/PiOS/Common/pios_flash_jedec.c +++ b/flight/PiOS/Common/pios_flash_jedec.c @@ -386,11 +386,81 @@ int32_t PIOS_Flash_Jedec_WriteData(uint32_t addr, uint8_t * data, uint16_t len) PIOS_Flash_Jedec_ReleaseBus(); // Keep polling when bus is busy too - while(PIOS_Flash_Jedec_Busy() != 0) { #if defined(FLASH_FREERTOS) + while(PIOS_Flash_Jedec_Busy() != 0) { vTaskDelay(1); -#endif } +#else + + // Query status this way to prevent accel chip locking us out + if(PIOS_Flash_Jedec_ClaimBus() < 0) + return -1; + + PIOS_SPI_TransferByte(flash_dev->spi_id, JEDEC_READ_STATUS); + while(PIOS_SPI_TransferByte(flash_dev->spi_id, JEDEC_READ_STATUS) & JEDEC_STATUS_BUSY); + + PIOS_Flash_Jedec_ReleaseBus(); + +#endif + return 0; +} + +/** + * @brief Write multiple chunks of data in one transaction + * @param[in] addr Address in flash to write to + * @param[in] data Pointer to data to write to flash + * @param[in] len Length of data to write (max 256 bytes) + * @return Zero if success or error code + * @retval -1 Unable to claim SPI bus + * @retval -2 Size exceeds 256 bytes + * @retval -3 Length to write would wrap around page boundary + */ +int32_t PIOS_Flash_Jedec_WriteChunks(uint32_t addr, struct pios_flash_chunk * p_chunk, uint32_t num) +{ + if(PIOS_Flash_Jedec_Validate(flash_dev) != 0) + return -1; + + uint8_t ret; + uint8_t out[4] = {JEDEC_PAGE_WRITE, (addr >> 16) & 0xff, (addr >> 8) & 0xff , addr & 0xff}; + + /* Can only write one page at a time */ + uint32_t len = 0; + for(uint32_t i = 0; i < num; i++) + len += p_chunk[i].len; + + if(len > 0x100) + return -2; + + /* Ensure number of bytes fits after starting address before end of page */ + if(((addr & 0xff) + len) > 0x100) + return -3; + + if((ret = PIOS_Flash_Jedec_WriteEnable()) != 0) + return ret; + + /* Execute write page command and clock in address. Keep CS asserted */ + if(PIOS_Flash_Jedec_ClaimBus() != 0) + return -1; + + if(PIOS_SPI_TransferBlock(flash_dev->spi_id,out,NULL,sizeof(out),NULL) < 0) { + PIOS_Flash_Jedec_ReleaseBus(); + return -1; + } + + for(uint32_t i = 0; i < num; i++) { + struct pios_flash_chunk * chunk = &p_chunk[i]; + + /* Clock out data to flash */ + if(PIOS_SPI_TransferBlock(flash_dev->spi_id,chunk->addr,NULL,chunk->len,NULL) < 0) { + PIOS_Flash_Jedec_ReleaseBus(); + return -1; + } + + } + PIOS_Flash_Jedec_ReleaseBus(); + + // Skip checking for busy with this to get OS running again fast + return 0; } diff --git a/flight/PiOS/Common/pios_flashfs_objlist.c b/flight/PiOS/Common/pios_flashfs_objlist.c index 3879e62da..7b6af564d 100644 --- a/flight/PiOS/Common/pios_flashfs_objlist.c +++ b/flight/PiOS/Common/pios_flashfs_objlist.c @@ -247,28 +247,30 @@ int32_t PIOS_FLASHFS_ObjSave(UAVObjHandle obj, uint16_t instId, uint8_t * data) .instId = instId, .size = UAVObjGetNumBytes(obj) }; + + // Update CRC + crc = PIOS_CRC_updateCRC(crc, (uint8_t *) data, UAVObjGetNumBytes(obj)); if(PIOS_Flash_Jedec_EraseSector(addr) != 0) return -2; - // Save header - // This information IS redundant with the object table id. Oh well. Better safe than sorry. - if(PIOS_Flash_Jedec_WriteData(addr, (uint8_t *) &header, sizeof(header)) != 0) - return -3; + struct pios_flash_chunk chunks[3] = { + { + .addr = (uint8_t *) &header, + .len = sizeof(header), + }, + { + .addr = (uint8_t *) data, + .len = UAVObjGetNumBytes(obj) + }, + { + .addr = (uint8_t *) &crc, + .len = sizeof(crc) + } + }; - // Update CRC - crc = PIOS_CRC_updateCRC(0, (uint8_t *) &header, sizeof(header)); - - // Save data - if(PIOS_Flash_Jedec_WriteData(addr + sizeof(header), data, UAVObjGetNumBytes(obj)) != 0) - return -4; - - // Update CRC - crc = PIOS_CRC_updateCRC(crc, (uint8_t *) data, UAVObjGetNumBytes(obj)); - - // Save CRC (written so will work when CRC changes to uint16) - if(PIOS_Flash_Jedec_WriteData(addr + sizeof(header) + UAVObjGetNumBytes(obj), (uint8_t *) &crc, sizeof(crc)) != 0) - return -4; + if(PIOS_Flash_Jedec_WriteChunks(addr, chunks, NELEMENTS(chunks)) != 0) + return -1; if(PIOS_Flash_Jedec_EndTransaction() != 0) return -1; diff --git a/flight/PiOS/inc/pios_flash_jedec.h b/flight/PiOS/inc/pios_flash_jedec.h index 61da951b8..4fc5d2fdf 100644 --- a/flight/PiOS/inc/pios_flash_jedec.h +++ b/flight/PiOS/inc/pios_flash_jedec.h @@ -33,6 +33,11 @@ struct pios_flash_jedec_cfg { uint32_t chip_erase; }; +struct pios_flash_chunk { + uint8_t * addr; + uint32_t len; +}; + int32_t PIOS_Flash_Jedec_Init(uint32_t spi_id, uint32_t slave_num, const struct pios_flash_jedec_cfg * cfg); int32_t PIOS_Flash_Jedec_ReadStatus(); int32_t PIOS_Flash_Jedec_ReadID(); @@ -40,5 +45,6 @@ int32_t PIOS_Flash_Jedec_EraseChip(); int32_t PIOS_Flash_Jedec_EraseSector(uint32_t add); int32_t PIOS_Flash_Jedec_WriteData(uint32_t addr, uint8_t * data, uint16_t len); int32_t PIOS_Flash_Jedec_ReadData(uint32_t addr, uint8_t * data, uint16_t len); +int32_t PIOS_Flash_Jedec_WriteChunks(uint32_t addr, struct pios_flash_chunk * p_chunk, uint32_t num); int32_t PIOS_Flash_Jedec_StartTransaction(); int32_t PIOS_Flash_Jedec_EndTransaction(); diff --git a/flight/Project/OpenPilotOSX/OpenPilotOSX.xcodeproj/project.pbxproj b/flight/Project/OpenPilotOSX/OpenPilotOSX.xcodeproj/project.pbxproj index eeab13979..a8b3d16df 100644 --- a/flight/Project/OpenPilotOSX/OpenPilotOSX.xcodeproj/project.pbxproj +++ b/flight/Project/OpenPilotOSX/OpenPilotOSX.xcodeproj/project.pbxproj @@ -76,10 +76,7 @@ 6534B55B1476D3A8003DF47C /* pios_ms5611.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pios_ms5611.h; sourceTree = ""; }; 6536D47B1307962C0042A298 /* stabilizationdesired.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = stabilizationdesired.xml; sourceTree = ""; }; 65408AA812BB1648004DACC5 /* i2cstats.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = i2cstats.xml; sourceTree = ""; }; - 6543A04314CF1823004EEC4C /* board_hw_defs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = board_hw_defs.c; sourceTree = ""; }; 6543A04514CF1823004EEC4C /* board_hw_defs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = board_hw_defs.c; sourceTree = ""; }; - 6543A04714CF1823004EEC4C /* board_hw_defs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = board_hw_defs.c; sourceTree = ""; }; - 6543A04914CF1823004EEC4C /* board_hw_defs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = board_hw_defs.c; sourceTree = ""; }; 6543A04B14CF1823004EEC4C /* board_hw_defs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = board_hw_defs.c; sourceTree = ""; }; 6543A04C14CF717E004EEC4C /* pios_usb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pios_usb.c; sourceTree = ""; }; 6543A04D14CF9F5E004EEC4C /* pios_usb_priv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pios_usb_priv.h; sourceTree = ""; }; @@ -3763,24 +3760,12 @@ isa = PBXGroup; children = ( 652A445414D1169E00835B68 /* revolution */, - 6543A04214CF1823004EEC4C /* ahrs */, 6543A04414CF1823004EEC4C /* coptercontrol */, - 6543A04614CF1823004EEC4C /* ins */, - 6543A04814CF1823004EEC4C /* openpilot */, 6543A04A14CF1823004EEC4C /* pipxtreme */, ); name = board_hw_defs; sourceTree = ""; }; - 6543A04214CF1823004EEC4C /* ahrs */ = { - isa = PBXGroup; - children = ( - 6543A04314CF1823004EEC4C /* board_hw_defs.c */, - ); - name = ahrs; - path = ../../board_hw_defs/ahrs; - sourceTree = ""; - }; 6543A04414CF1823004EEC4C /* coptercontrol */ = { isa = PBXGroup; children = ( @@ -3790,24 +3775,6 @@ path = ../../board_hw_defs/coptercontrol; sourceTree = ""; }; - 6543A04614CF1823004EEC4C /* ins */ = { - isa = PBXGroup; - children = ( - 6543A04714CF1823004EEC4C /* board_hw_defs.c */, - ); - name = ins; - path = ../../board_hw_defs/ins; - sourceTree = ""; - }; - 6543A04814CF1823004EEC4C /* openpilot */ = { - isa = PBXGroup; - children = ( - 6543A04914CF1823004EEC4C /* board_hw_defs.c */, - ); - name = openpilot; - path = ../../board_hw_defs/openpilot; - sourceTree = ""; - }; 6543A04A14CF1823004EEC4C /* pipxtreme */ = { isa = PBXGroup; children = (