* Added support for I2C EEPROM OTA * EEPROM OTA now uses extEEPROM as driver * Compiler warning fix * Style check fixes * Fix doxygen warnings of I2CEeprom * Use bool instead of boolean in I2CEeprom shim * Fix re-merged style problem
This commit is contained in:
+13
@@ -261,6 +261,19 @@
|
|||||||
// requires the MYSBootloader and disabled MY_OTA_FIRMWARE_FEATURE
|
// requires the MYSBootloader and disabled MY_OTA_FIRMWARE_FEATURE
|
||||||
//#define MY_OTA_FIRMWARE_FEATURE
|
//#define MY_OTA_FIRMWARE_FEATURE
|
||||||
|
|
||||||
|
// Define or uncomment MY_OTA_USE_I2C_EEPROM below if you want I2C EEPROM instead
|
||||||
|
// of a SPI flash. Used EEPROM needs to be large enough, an 24(L)C256 will do as minimum.
|
||||||
|
// HW I2C assumed. This will exclude the SPI flash code.
|
||||||
|
// Note that you also need an updated DualOptiboot supporting I2C EEPROM!
|
||||||
|
//#define MY_OTA_USE_I2C_EEPROM
|
||||||
|
|
||||||
|
#ifdef MY_OTA_USE_I2C_EEPROM
|
||||||
|
// I2C address of EEPROM. Wire will shift this left, i.e. 0x50->0xA0
|
||||||
|
#ifndef MY_OTA_I2C_ADDR
|
||||||
|
#define MY_OTA_I2C_ADDR 0x50
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @def MY_OTA_FLASH_SS
|
* @def MY_OTA_FLASH_SS
|
||||||
* @brief Slave select pin for external flash.
|
* @brief Slave select pin for external flash.
|
||||||
|
|||||||
@@ -172,7 +172,11 @@ MY_DEFAULT_RX_LED_PIN in your sketch instead to enable LEDs
|
|||||||
|
|
||||||
// FLASH
|
// FLASH
|
||||||
#if defined(MY_OTA_FIRMWARE_FEATURE)
|
#if defined(MY_OTA_FIRMWARE_FEATURE)
|
||||||
|
#if defined(MY_OTA_USE_I2C_EEPROM)
|
||||||
|
#include "drivers/I2CEeprom/I2CEeprom.cpp"
|
||||||
|
#else
|
||||||
#include "drivers/SPIFlash/SPIFlash.cpp"
|
#include "drivers/SPIFlash/SPIFlash.cpp"
|
||||||
|
#endif
|
||||||
#include "core/MyOTAFirmwareUpdate.cpp"
|
#include "core/MyOTAFirmwareUpdate.cpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,11 @@ extern MyMessage _msg;
|
|||||||
extern MyMessage _msgTmp;
|
extern MyMessage _msgTmp;
|
||||||
|
|
||||||
// local variables
|
// local variables
|
||||||
|
#ifdef MY_OTA_USE_I2C_EEPROM
|
||||||
|
I2CEeprom _flash(MY_OTA_I2C_ADDR);
|
||||||
|
#else
|
||||||
SPIFlash _flash(MY_OTA_FLASH_SS, MY_OTA_FLASH_JDECID);
|
SPIFlash _flash(MY_OTA_FLASH_SS, MY_OTA_FLASH_JDECID);
|
||||||
|
#endif
|
||||||
nodeFirmwareConfig_t _nodeFirmwareConfig;
|
nodeFirmwareConfig_t _nodeFirmwareConfig;
|
||||||
bool _firmwareUpdateOngoing;
|
bool _firmwareUpdateOngoing;
|
||||||
uint32_t _firmwareLastRequest;
|
uint32_t _firmwareLastRequest;
|
||||||
@@ -110,6 +114,21 @@ bool firmwareOTAUpdateProcess(void)
|
|||||||
firmwareResponse->data, FIRMWARE_BLOCK_SIZE);
|
firmwareResponse->data, FIRMWARE_BLOCK_SIZE);
|
||||||
// wait until flash written
|
// wait until flash written
|
||||||
while (_flash.busy()) {}
|
while (_flash.busy()) {}
|
||||||
|
#ifdef OTA_EXTRA_FLASH_DEBUG
|
||||||
|
{
|
||||||
|
char prbuf[8];
|
||||||
|
uint32_t addr = ((_firmwareBlock - 1) * FIRMWARE_BLOCK_SIZE) + FIRMWARE_START_OFFSET;
|
||||||
|
OTA_DEBUG(PSTR("OTA:FWP:FL DUMP "));
|
||||||
|
sprintf_P(prbuf,PSTR("%04X:"), (uint16_t)addr);
|
||||||
|
MY_SERIALDEVICE.print(prbuf);
|
||||||
|
for(uint8_t i=0; i<FIRMWARE_BLOCK_SIZE; i++) {
|
||||||
|
uint8_t data = _flash.readByte(addr + i);
|
||||||
|
sprintf_P(prbuf,PSTR("%02X"), (unsigned int)data);
|
||||||
|
MY_SERIALDEVICE.print(prbuf);
|
||||||
|
}
|
||||||
|
OTA_DEBUG(PSTR("\n"));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
_firmwareBlock--;
|
_firmwareBlock--;
|
||||||
if (!_firmwareBlock) {
|
if (!_firmwareBlock) {
|
||||||
// We're done! Do a checksum and reboot.
|
// We're done! Do a checksum and reboot.
|
||||||
|
|||||||
@@ -70,6 +70,7 @@
|
|||||||
|
|
||||||
#if defined(MY_DEBUG_VERBOSE_OTA_UPDATE)
|
#if defined(MY_DEBUG_VERBOSE_OTA_UPDATE)
|
||||||
#define OTA_DEBUG(x,...) hwDebugPrint(x, ##__VA_ARGS__) //!< debug
|
#define OTA_DEBUG(x,...) hwDebugPrint(x, ##__VA_ARGS__) //!< debug
|
||||||
|
//#define OTA_EXTRA_FLASH_DEBUG //!< Dumps flash after each FW block
|
||||||
#else
|
#else
|
||||||
#define OTA_DEBUG(x,...) //!< debug NULL
|
#define OTA_DEBUG(x,...) //!< debug NULL
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
// Copyright (C) 2016 Krister W. <kisse66@hobbylabs.org>
|
||||||
|
//
|
||||||
|
// Original SPI flash driver this is based on:
|
||||||
|
// Copyright (c) 2013-2015 by Felix Rusu, LowPowerLab.com
|
||||||
|
// **********************************************************************************
|
||||||
|
// License
|
||||||
|
// **********************************************************************************
|
||||||
|
// 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// Licence can be viewed at
|
||||||
|
// http://www.gnu.org/licenses/gpl-3.0.txt
|
||||||
|
//
|
||||||
|
// Please maintain this license information along with authorship
|
||||||
|
// and copyright notices in any redistribution of this code
|
||||||
|
|
||||||
|
#include <Wire.h>
|
||||||
|
#include "I2CEeprom.h"
|
||||||
|
|
||||||
|
I2CEeprom::I2CEeprom(uint8_t addr) : extEEPROM(I2CEEPROM_CHIP_SIZE, 1, I2CEEPROM_PAGE_SIZE)
|
||||||
|
{
|
||||||
|
m_addr = addr; // we only need this for busy()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// setup
|
||||||
|
bool I2CEeprom::initialize()
|
||||||
|
{
|
||||||
|
return extEEPROM::begin(I2CEEPROM_TWI_CLK) ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// read 1 byte
|
||||||
|
uint8_t I2CEeprom::readByte(uint32_t addr)
|
||||||
|
{
|
||||||
|
uint8_t val;
|
||||||
|
readBytes(addr, &val, 1);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// read multiple bytes
|
||||||
|
void I2CEeprom::readBytes(uint32_t addr, void* buf, uint16_t len)
|
||||||
|
{
|
||||||
|
extEEPROM::read((unsigned long)addr, (byte *)buf, (unsigned int) len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// check if the chip is busy
|
||||||
|
bool I2CEeprom::busy()
|
||||||
|
{
|
||||||
|
Wire.beginTransmission(m_addr);
|
||||||
|
Wire.write(0);
|
||||||
|
Wire.write(0);
|
||||||
|
if (Wire.endTransmission() == 0) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true; // busy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write 1 byte
|
||||||
|
void I2CEeprom::writeByte(uint32_t addr, uint8_t byt)
|
||||||
|
{
|
||||||
|
writeBytes(addr, &byt, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// write multiple bytes
|
||||||
|
void I2CEeprom::writeBytes(uint32_t addr, const void* buf, uint16_t len)
|
||||||
|
{
|
||||||
|
extEEPROM::write((unsigned long) addr, (byte *)buf, (unsigned int) len);
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
// Copyright (C) 2016 Krister W. <kisse66@hobbylabs.org>
|
||||||
|
//
|
||||||
|
// Original SPI flash driver this is based on:
|
||||||
|
// Copyright (c) 2013-2015 by Felix Rusu, LowPowerLab.com
|
||||||
|
//
|
||||||
|
// I2C EEPROM library for MySensors OTA. Based on SPI Flash memory library for
|
||||||
|
// arduino/moteino.
|
||||||
|
// This driver is made to look like the SPI flash driver so changes needed to
|
||||||
|
// MySensors OTA code is minimized.
|
||||||
|
// This works with 32 or 64kB I2C EEPROM like an 24(L)C256. AVR HW I2C is assumed
|
||||||
|
// and error handling is quite minimal. Uses extEEPROM as the underlying driver.
|
||||||
|
// DEPENDS ON: Arduino Wire library, extEEPROM
|
||||||
|
// **********************************************************************************
|
||||||
|
// License
|
||||||
|
// **********************************************************************************
|
||||||
|
// 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// Licence can be viewed at
|
||||||
|
// http://www.gnu.org/licenses/gpl-3.0.txt
|
||||||
|
//
|
||||||
|
// Please maintain this license information along with authorship
|
||||||
|
// and copyright notices in any redistribution of this code
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @file I2CEeprom.h
|
||||||
|
///
|
||||||
|
/// @brief I2CEeprom provides access to a I2C EEPROM IC for OTA update or storing data
|
||||||
|
///
|
||||||
|
/// This is a wrapper over extEEPROM to make it look like a flash chip.
|
||||||
|
///
|
||||||
|
#ifndef _I2CEeprom_H_
|
||||||
|
#define _I2CEeprom_H_
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <extEEPROM.h>
|
||||||
|
|
||||||
|
/// I2C speed
|
||||||
|
// 400kHz clock as default. Use extEEPROM type
|
||||||
|
#ifndef I2CEEPROM_TWI_CLK
|
||||||
|
#define I2CEEPROM_TWI_CLK twiClock400kHz
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// EEPROM page size
|
||||||
|
//Typically 64 (see data sheet for your EEPROM)
|
||||||
|
// Some 512kbit chips use 128 byte pages (e.g. Atmel AT24C512)
|
||||||
|
#ifndef I2CEEPROM_PAGE_SIZE
|
||||||
|
#define I2CEEPROM_PAGE_SIZE 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// EEPROM size
|
||||||
|
// 24C256 is 32kB, minimum that fits code for ATmega328
|
||||||
|
// Use extEEPROM type
|
||||||
|
#ifndef I2CEEPROM_CHIP_SIZE
|
||||||
|
#define I2CEEPROM_CHIP_SIZE kbits_256
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** I2CEeprom class */
|
||||||
|
class I2CEeprom : extEEPROM
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit I2CEeprom(uint8_t addr); //!< Constructor
|
||||||
|
bool initialize(); //!< setup
|
||||||
|
uint8_t readByte(uint32_t addr); //!< read 1 byte from flash memory
|
||||||
|
void readBytes(uint32_t addr, void* buf, uint16_t len); //!< read multiple bytes
|
||||||
|
void writeByte(uint32_t addr, uint8_t byt); //!< Write 1 byte to flash memory
|
||||||
|
void writeBytes(uint32_t addr, const void* buf,
|
||||||
|
uint16_t len); //!< write multiple bytes to flash memory (up to 64K), if define SPIFLASH_SST25TYPE is set AAI Word Programming will be used
|
||||||
|
bool busy(); //!< check if the chip is busy erasing/writing
|
||||||
|
|
||||||
|
// the rest not needed for EEPROMs, but kept so SPI flash code compiles as is (functions are NOP)
|
||||||
|
|
||||||
|
/// dummy function for SPI flash compatibility
|
||||||
|
uint16_t readDeviceId()
|
||||||
|
{
|
||||||
|
return 0xDEAD;
|
||||||
|
};
|
||||||
|
/// dummy function for SPI flash compatibility
|
||||||
|
void chipErase() {};
|
||||||
|
/// dummy function for SPI flash compatibility
|
||||||
|
void blockErase4K(uint32_t address)
|
||||||
|
{
|
||||||
|
(void)address;
|
||||||
|
};
|
||||||
|
/// dummy function for SPI flash compatibility
|
||||||
|
void blockErase32K(uint32_t address)
|
||||||
|
{
|
||||||
|
(void)address;
|
||||||
|
};
|
||||||
|
/// dummy function for SPI flash compatibility
|
||||||
|
void sleep() {};
|
||||||
|
/// dummy function for SPI flash compatibility
|
||||||
|
void wakeup() {};
|
||||||
|
/// dummy function for SPI flash compatibility
|
||||||
|
void end() {};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
uint8_t m_addr; ///< I2C address for busy()
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user