mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-02-19 09:54:15 +01:00
Flashfs and Flash: Add new function to write a series of blocks in one flash
write transaction to improve efficieny.
This commit is contained in:
parent
80705cdba1
commit
ad3d470f40
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -76,10 +76,7 @@
|
||||
6534B55B1476D3A8003DF47C /* pios_ms5611.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pios_ms5611.h; sourceTree = "<group>"; };
|
||||
6536D47B1307962C0042A298 /* stabilizationdesired.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = stabilizationdesired.xml; sourceTree = "<group>"; };
|
||||
65408AA812BB1648004DACC5 /* i2cstats.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = i2cstats.xml; sourceTree = "<group>"; };
|
||||
6543A04314CF1823004EEC4C /* board_hw_defs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = board_hw_defs.c; sourceTree = "<group>"; };
|
||||
6543A04514CF1823004EEC4C /* board_hw_defs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = board_hw_defs.c; sourceTree = "<group>"; };
|
||||
6543A04714CF1823004EEC4C /* board_hw_defs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = board_hw_defs.c; sourceTree = "<group>"; };
|
||||
6543A04914CF1823004EEC4C /* board_hw_defs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = board_hw_defs.c; sourceTree = "<group>"; };
|
||||
6543A04B14CF1823004EEC4C /* board_hw_defs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = board_hw_defs.c; sourceTree = "<group>"; };
|
||||
6543A04C14CF717E004EEC4C /* pios_usb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pios_usb.c; sourceTree = "<group>"; };
|
||||
6543A04D14CF9F5E004EEC4C /* pios_usb_priv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pios_usb_priv.h; sourceTree = "<group>"; };
|
||||
@ -3763,24 +3760,12 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
652A445414D1169E00835B68 /* revolution */,
|
||||
6543A04214CF1823004EEC4C /* ahrs */,
|
||||
6543A04414CF1823004EEC4C /* coptercontrol */,
|
||||
6543A04614CF1823004EEC4C /* ins */,
|
||||
6543A04814CF1823004EEC4C /* openpilot */,
|
||||
6543A04A14CF1823004EEC4C /* pipxtreme */,
|
||||
);
|
||||
name = board_hw_defs;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6543A04214CF1823004EEC4C /* ahrs */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6543A04314CF1823004EEC4C /* board_hw_defs.c */,
|
||||
);
|
||||
name = ahrs;
|
||||
path = ../../board_hw_defs/ahrs;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6543A04414CF1823004EEC4C /* coptercontrol */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -3790,24 +3775,6 @@
|
||||
path = ../../board_hw_defs/coptercontrol;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6543A04614CF1823004EEC4C /* ins */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6543A04714CF1823004EEC4C /* board_hw_defs.c */,
|
||||
);
|
||||
name = ins;
|
||||
path = ../../board_hw_defs/ins;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6543A04814CF1823004EEC4C /* openpilot */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6543A04914CF1823004EEC4C /* board_hw_defs.c */,
|
||||
);
|
||||
name = openpilot;
|
||||
path = ../../board_hw_defs/openpilot;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6543A04A14CF1823004EEC4C /* pipxtreme */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
Loading…
x
Reference in New Issue
Block a user