1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-11-29 07:24:13 +01:00

Added pios_eeprom for saving settings.

This commit is contained in:
Brian Webb 2012-04-28 19:29:25 -07:00
parent a7cec7c823
commit 1048eb7e2c
4 changed files with 337 additions and 1 deletions

View File

@ -29,6 +29,76 @@ static const uint8_t crc_table[256] = {
0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb, 0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3 0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb, 0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3
}; };
static const uint16_t CRC_Table16[] = { // HDLC polynomial
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};
static const uint32_t CRC_Table32[] = {
0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
};
/** /**
* Update the crc value with new data. * Update the crc value with new data.
* *
@ -52,7 +122,7 @@ uint8_t PIOS_CRC_updateByte(uint8_t crc, const uint8_t data)
return crc_table[crc ^ data]; return crc_table[crc ^ data];
} }
/* /**
* @brief Update a CRC with a data buffer * @brief Update a CRC with a data buffer
* @param[in] crc Starting CRC value * @param[in] crc Starting CRC value
* @param[in] data Data buffer * @param[in] data Data buffer
@ -72,3 +142,58 @@ uint8_t PIOS_CRC_updateCRC(uint8_t crc, const uint8_t* data, int32_t length)
return crc8; return crc8;
} }
/**
* Update the crc value with new data.
* \param crc The current crc value.
* \param data Pointer to a buffer of \a data_len bytes.
* \param length Number of bytes in the \a data buffer.
* \return The updated crc value.
*/
uint16_t PIOS_CRC16_updateByte(uint16_t crc, const uint8_t data)
{
return ((crc >> 8) ^ CRC_Table16[(crc & 0xff) ^ data]);
}
/**
* @brief Update a CRC with a data buffer
* @param[in] crc Starting CRC value
* @param[in] data Data buffer
* @param[in] length Number of bytes to process
* @returns Updated CRC
*/
uint16_t PIOS_CRC16_updateCRC(uint16_t crc, const uint8_t* data, int32_t length)
{
register uint8_t *p = (uint8_t *)data;
register uint16_t _crc = crc;
for (register uint32_t i = length; i > 0; i--)
_crc = (_crc >> 8) ^ CRC_Table16[(_crc ^ *p++) & 0xff];
return _crc;
}
/**
* Update the crc value with new data.
* \param crc The current crc value.
* \param data Pointer to a buffer of \a data_len bytes.
* \param length Number of bytes in the \a data buffer.
* \return The updated crc value.
*/
uint32_t PIOS_CRC32_updateByte(uint32_t crc, const uint8_t data)
{
return ((crc << 8) ^ CRC_Table32[(crc >> 24) ^ data]);
}
/**
* @brief Update a CRC with a data buffer
* @param[in] crc Starting CRC value
* @param[in] data Data buffer
* @param[in] length Number of bytes to process
* @returns Updated CRC
*/
uint32_t PIOS_CRC32_updateCRC(uint32_t crc, const uint8_t* data, int32_t length)
{
register uint8_t *p = (uint8_t *)data;
register uint32_t _crc = crc;
for (register uint32_t i = length; i > 0; i--)
_crc = (_crc << 8) ^ CRC_Table32[(_crc >> 24) ^ *p++];
return _crc;
}

View File

@ -0,0 +1,155 @@
/**
******************************************************************************
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_EEPROM EEPROM reading/writing functions
* @brief PIOS EEPROM reading/writing functions
* @{
*
* @file pios_eeprom.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
* @brief COM layer functions
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* 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; either version 3 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 MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Project Includes */
#include <pios.h>
#include <pios_crc.h>
#include <stm32f10x_flash.h>
#include <pios_board_info.h>
#include <pios_eeprom.h>
static struct pios_eeprom_cfg config;
/**
* Initialize the flash eeprom device
* \param cfg The configuration structure.
*/
void PIOS_EEPROM_Init(const struct pios_eeprom_cfg *cfg)
{
config = *cfg;
}
/**
* Save a block of data to the flash eeprom device.
* \param data A pointer to the data to write.
* \param len The length of data to write.
* \return 0 on sucess
*/
int32_t PIOS_EEPROM_Save(uint8_t *data, uint32_t len)
{
// We need to write 32 bit words, so extend the length to be an even multiple of 4 bytes,
// and include 4 bytes for the 32 bit CRC.
uint32_t nwords = (len / 4) + 1 + (len % 4 ? 1 : 0);
uint32_t size = nwords * 4;
// Ensure that the length is not longer than the max size.
if (size > config.max_size)
return -1;
// Calculate a 32 bit CRC of the data.
uint32_t crc = PIOS_CRC32_updateCRC(0xffffffff, data, len);
// Unlock the Flash Program Erase controller
FLASH_Unlock();
// See if we have to write the data.
if ((memcmp(data, (uint8_t*)config.base_address, len) == 0) &&
(memcmp((uint8_t*)crc, (uint8_t*)config.base_address + size - 4, 4) == 0))
return 0;
// TODO: Check that the area isn't already erased
// Erase page
FLASH_Status fs = FLASH_ErasePage(config.base_address);
if (fs != FLASH_COMPLETE)
{ // error
FLASH_Lock();
return -2;
}
// write 4 bytes at a time into program flash area (emulated EEPROM area)
uint8_t *p1 = data;
uint32_t *p3 = (uint32_t *)config.base_address;
for (int32_t i = 0; i < size; p3++)
{
uint32_t value = 0;
if (i == (size - 4))
{
// write the CRC.
value = crc;
i += 4;
}
else
{
if (i < len) value |= (uint32_t)*p1++ << 0; else value |= 0x000000ff; i++;
if (i < len) value |= (uint32_t)*p1++ << 8; else value |= 0x0000ff00; i++;
if (i < len) value |= (uint32_t)*p1++ << 16; else value |= 0x00ff0000; i++;
if (i < len) value |= (uint32_t)*p1++ << 24; else value |= 0xff000000; i++;
}
// write a 32-bit value
fs = FLASH_ProgramWord((uint32_t)p3, value);
if (fs != FLASH_COMPLETE)
{
FLASH_Lock();
return -3;
}
}
// Lock the Flash Program Erase controller
FLASH_Lock();
return 0;
}
/**
* Reads a block of data from the flash eeprom device.
* \param data A pointer to the output data buffer.
* \param len The length of data to read.
* \return 0 on sucess
*/
int32_t PIOS_EEPROM_Load(uint8_t *data, uint32_t len)
{
// We need to write 32 bit words, so the length should have been extended
// to an even multiple of 4 bytes, and should include 4 bytes for the 32 bit CRC.
uint32_t nwords = (len / 4) + 1 + (len % 4 ? 1 : 0);
uint32_t size = nwords * 4;
// Ensure that the length is not longer than the max size.
if (size > config.max_size)
return -1;
// Read the data from flash.
memcpy(data, (uint8_t*)config.base_address, len);
// Read the CRC.
uint32_t crc_flash = *((uint32_t*)(config.base_address + size - 4));
// Calculate a 32 bit CRC of the data.
uint32_t crc = PIOS_CRC32_updateCRC(0xffffffff, data, len);
if(crc != crc_flash)
return -2;
return 0;
}

View File

@ -29,3 +29,9 @@
uint8_t PIOS_CRC_updateByte(uint8_t crc, const uint8_t data); uint8_t PIOS_CRC_updateByte(uint8_t crc, const uint8_t data);
uint8_t PIOS_CRC_updateCRC(uint8_t crc, const uint8_t* data, int32_t length); uint8_t PIOS_CRC_updateCRC(uint8_t crc, const uint8_t* data, int32_t length);
uint16_t PIOS_CRC16_updateByte(uint16_t crc, const uint8_t data);
uint16_t PIOS_CRC16_updateCRC(uint16_t crc, const uint8_t* data, int32_t length);
uint32_t PIOS_CRC32_updateByte(uint32_t crc, const uint8_t data);
uint32_t PIOS_CRC32_updateCRC(uint32_t crc, const uint8_t* data, int32_t length);

View File

@ -0,0 +1,50 @@
/**
******************************************************************************
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_EEPROM EEPROM reading/writing functions
* @brief PIOS EEPROM reading/writing functions
* @{
*
* @file pios_eeprom.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
* @brief COM layer functions
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* 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; either version 3 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 MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef PIOS_EEPROM_H
#define PIOS_EEPROM_H
/* Public Structures */
struct pios_eeprom_cfg {
uint32_t base_address;
uint32_t max_size;
};
/* Public Functions */
extern void PIOS_EEPROM_Init(const struct pios_eeprom_cfg *cfg);
extern int32_t PIOS_EEPROM_Save(uint8_t *data, uint32_t len);
extern int32_t PIOS_EEPROM_Load(uint8_t *data, uint32_t len);
#endif /* PIOS_EEPROM_H */
/**
* @}
* @}
*/