Skip to content

Commit

Permalink
Adds SPIFFs driver for Tiva 129 (#569)
Browse files Browse the repository at this point in the history
Generalizes the SPIFFs driver form the CC32xxSF to run on a
Tiva 129 device as well using the same driverlib calls.

===

* Renames cc32xxspiffs to TiSPIFFS.

* Generalizes the SPIFFs driver form the CC32xxSF to run on a
Tiva 129 device as well using the same driverlib calls.
  • Loading branch information
balazsracz authored Sep 1, 2021
1 parent 8c52743 commit bc8162e
Show file tree
Hide file tree
Showing 10 changed files with 445 additions and 222 deletions.
6 changes: 4 additions & 2 deletions src/freertos_drivers/sources
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ SUBDIRS += mbed_lpc1768 drivers_lpc1768 tivaware lpc_chip_175x_6x \
stm32cubel431xx stm32cubel432xx stm32cubef767xx \
cc3220sdk net_cc3220 cc3220 \
net_freertos_tcp freertos_tcp ti_grlib \
spiffs_cc32x0sf spiffs_stm32f303xe spiffs_stm32f767xx \

spiffs_cc32x0sf spiffs_tm4c129 \
spiffs_stm32f303xe spiffs_stm32f767xx \

#spiffs_tm4c123 \

ifdef BUILDTIVAWARE
SUBDIRS += tivadriverlib tivausblib
Expand Down
180 changes: 6 additions & 174 deletions src/freertos_drivers/spiffs/cc32x0sf/CC32x0SFSPIFFS.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -31,188 +31,20 @@
* @date 1 January 2018
*/

// #define LOGLEVEL INFO

// This define is needed to call any ROM_xx function in the driverlib.
#define USE_CC3220_ROM_DRV_API

#include "utils/logging.h"

#include "CC32x0SFSPIFFS.hxx"
#define TI_DUAL_BANK_FLASH

#include "spiffs.h"
#include "inc/hw_types.h"
#include "driverlib/flash.h"
#include "driverlib/rom.h"
#include "driverlib/cpu.h"

/// Flash configuration register.
#define FLASH_CONF 0x400FDFC8
/// This bit in the FLASH_CONF register means that the banks are reversed by
/// their address mapping.
#define FCMME 0x40000000
/// This value defines up to one bit that needs to be XOR-ed to the flash
/// address before calling the flash APIs to cover for reversed flash banks.
static const unsigned addr_mirror = (HWREG(FLASH_CONF) & FCMME) ? 0x80000 : 0;

// Different options for what to set for flash write locking. These are only
// needed to debug when the operating system is misbehaving during flash
// writes.

// Global disable interrupts.
//
// #define DI() asm("cpsid i\n")
// #define EI() asm("cpsie i\n")

// Critical section (interrupts better than MIN_SYSCALL_PRIORITY are still
// running).
//
// #define DI() portENTER_CRITICAL()
// #define EI() portEXIT_CRITICAL()

// Disable interrupts with a custom priority limit (must not be zero).
//
// unsigned ppri;
// constexpr unsigned minpri = 0x40;
// #define DI() ppri = CPUbasepriGet(); CPUbasepriSet(minpri); HWREG(FLASH_CONF) |= 0x20110000;
// #define EI() CPUbasepriSet(ppri);

// No write locking.
#define DI()
#define EI()

// This ifdef decides whether we use the ROM or the flash based implementations
// for Flash write and erase. It also supports correcting for the reversed bank
// addresses.
#if 1
#define FPG(data, addr, size) ROM_FlashProgram(data, (addr) ^ addr_mirror, size)
#define FER(addr) ROM_FlashErase((addr) ^ addr_mirror)
#else
#define FPG(data, addr, size) FlashProgram(data, (addr) ^ addr_mirror, size)
#define FER(addr) FlashErase((addr) ^ addr_mirror)
#endif

//
// CC32x0SFSPIFFS::flash_read()
//
int32_t CC32x0SFSPIFFS::flash_read(uint32_t addr, uint32_t size, uint8_t *dst)
{
HASSERT(addr >= fs_->cfg.phys_addr &&
(addr + size) <= (fs_->cfg.phys_addr + fs_->cfg.phys_size));

memcpy(dst, (void*)addr, size);

return 0;
}

//
// CC32x0SFSPIFFS::flash_write()
//
int32_t CC32x0SFSPIFFS::flash_write(uint32_t addr, uint32_t size, uint8_t *src)
{
LOG(INFO, "Write %x sz %d", (unsigned)addr, (unsigned)size);
union WriteWord
{
uint8_t data[4];
uint32_t data_word;
};

HASSERT(addr >= fs_->cfg.phys_addr &&
(addr + size) <= (fs_->cfg.phys_addr + fs_->cfg.phys_size));

if ((addr % 4) && ((addr % 4) + size) < 4)
{
// single unaligned write in the middle of a word.
WriteWord ww;
ww.data_word = 0xFFFFFFFF;

memcpy(ww.data + (addr % 4), src, size);
ww.data_word &= *((uint32_t*)(addr & (~0x3)));
DI();
HASSERT(FPG(&ww.data_word, addr & (~0x3), 4) == 0);
EI();
LOG(INFO, "Write done1");
return 0;
}

int misaligned = (addr + size) % 4;
if (misaligned != 0)
{
// last write unaligned data
WriteWord ww;
ww.data_word = 0xFFFFFFFF;

memcpy(&ww.data_word, src + size - misaligned, misaligned);
ww.data_word &= *((uint32_t*)((addr + size) & (~0x3)));
DI();
HASSERT(FPG(&ww.data_word, (addr + size) & (~0x3), 4) == 0);
EI();

size -= misaligned;
}

misaligned = addr % 4;
if (size && misaligned != 0)
{
// first write unaligned data
WriteWord ww;
ww.data_word = 0xFFFFFFFF;

memcpy(ww.data + misaligned, src, 4 - misaligned);
ww.data_word &= *((uint32_t*)(addr & (~0x3)));
DI();
HASSERT(FPG(&ww.data_word, addr & (~0x3), 4) == 0);
EI();
addr += 4 - misaligned;
size -= 4 - misaligned;
src += 4 - misaligned;
}

HASSERT((addr % 4) == 0);
HASSERT((size % 4) == 0);

if (size)
{
// the rest of the aligned data
uint8_t *flash = (uint8_t*)addr;
for (uint32_t i = 0; i < size; i += 4)
{
src[i + 0] &= flash[i + 0];
src[i + 1] &= flash[i + 1];
src[i + 2] &= flash[i + 2];
src[i + 3] &= flash[i + 3];
}

DI();
HASSERT(FPG((unsigned long *)src, addr, size) == 0);
EI();
}

LOG(INFO, "Write done2");

return 0;
}

//
// CC32x0SFSPIFFS::flash_erase()
//
int32_t CC32x0SFSPIFFS::flash_erase(uint32_t addr, uint32_t size)
{
LOG(INFO, "Erasing %x sz %d", (unsigned)addr, (unsigned)size);
HASSERT(addr >= fs_->cfg.phys_addr &&
(addr + size) <= (fs_->cfg.phys_addr + fs_->cfg.phys_size));
HASSERT((size % ERASE_PAGE_SIZE) == 0);

while (size)
{
DI();
HASSERT(FER(addr) == 0);
EI();
addr += ERASE_PAGE_SIZE;
size -= ERASE_PAGE_SIZE;
}

LOG(INFO, "Erasing %x done", (unsigned)addr);
return 0;
}
#include "CC32x0SFSPIFFS.hxx"
#include "../cc32x0sf/TiSPIFFSImpl.hxx"

/// Explicit instantion of the template so that the functions get compiled and
/// into this .o file and the linker would find them.
template class TiSPIFFS<CC32xxSF_ERASE_PAGE_SIZE>;
50 changes: 4 additions & 46 deletions src/freertos_drivers/spiffs/cc32x0sf/CC32x0SFSPIFFS.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -34,53 +34,11 @@
#ifndef _FREERTOS_DRIVERS_SPIFFS_CC3220SF_CC32X0SFSPIFFS_HXX_
#define _FREERTOS_DRIVERS_SPIFFS_CC3220SF_CC32X0SFSPIFFS_HXX_

#include <cstdint>
#include "../cc32x0sf/TiSPIFFS.hxx"

#include "SPIFFS.hxx"
static constexpr unsigned CC32xxSF_ERASE_PAGE_SIZE = 2 * 1024;

/// Specialization of Serial SPIFFS driver for CC32xx devices.
class CC32x0SFSPIFFS : public SPIFFS
{
public:
/// Constructor.
CC32x0SFSPIFFS(size_t physical_address, size_t size_on_disk,
size_t logical_block_size, size_t logical_page_size,
size_t max_num_open_descriptors = 16, size_t cache_pages = 8,
std::function<void()> post_format_hook = nullptr)
: SPIFFS(physical_address, size_on_disk, ERASE_PAGE_SIZE,
logical_block_size, logical_page_size,
max_num_open_descriptors, cache_pages, post_format_hook)
{
}

/// Destructor.
~CC32x0SFSPIFFS()
{
unmount();
}

private:
/// size of an erase page in FLASH
static constexpr size_t ERASE_PAGE_SIZE = 2 * 1024;

/// SPIFFS callback to read flash, in context.
/// @param addr adddress location to read
/// @param size size of read in bytes
/// @param dst destination buffer for read
int32_t flash_read(uint32_t addr, uint32_t size, uint8_t *dst) override;

/// SPIFFS callback to write flash, in context.
/// @param addr adddress location to write
/// @param size size of write in bytes
/// @param src source buffer for write
int32_t flash_write(uint32_t addr, uint32_t size, uint8_t *src) override;

/// SPIFFS callback to erase flash, in context.
/// @param addr adddress location to erase
/// @param size size of erase region in bytes
int32_t flash_erase(uint32_t addr, uint32_t size) override;

DISALLOW_COPY_AND_ASSIGN(CC32x0SFSPIFFS);
};
using CC32x0SFSPIFFS = TiSPIFFS<CC32xxSF_ERASE_PAGE_SIZE>;

#endif // _FREERTOS_DRIVERS_SPIFFS_CC3220SF_CC32X0SFSPIFFS_HXX_

85 changes: 85 additions & 0 deletions src/freertos_drivers/spiffs/cc32x0sf/TiSPIFFS.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/** @copyright
* Copyright (c) 2018, Stuart W Baker
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @file TiSPIFFS.hxx
* This file implements a SPIFFS FLASH driver using the TI driverlib abstraction.
*
* @author Stuart W. Baker
* @date 1 January 2018
*/

#ifndef _FREERTOS_DRIVERS_SPIFFS_CC3220SF_TISPIFFS_HXX_
#define _FREERTOS_DRIVERS_SPIFFS_CC3220SF_TISPIFFS_HXX_

#include <cstdint>

#include "freertos_drivers/spiffs/SPIFFS.hxx"

/// Specialization of Serial SPIFFS driver for TI driverlib devices.
/// @param ERASE_PAGE_SIZE size of an erase page in FLASH
template<unsigned ERASE_PAGE_SIZE>
class TiSPIFFS : public SPIFFS
{
public:
/// Constructor.
TiSPIFFS(size_t physical_address, size_t size_on_disk,
size_t logical_block_size, size_t logical_page_size,
size_t max_num_open_descriptors = 16, size_t cache_pages = 8,
std::function<void()> post_format_hook = nullptr)
: SPIFFS(physical_address, size_on_disk, ERASE_PAGE_SIZE,
logical_block_size, logical_page_size,
max_num_open_descriptors, cache_pages, post_format_hook)
{
}

/// Destructor.
~TiSPIFFS()
{
unmount();
}

private:
/// SPIFFS callback to read flash, in context.
/// @param addr adddress location to read
/// @param size size of read in bytes
/// @param dst destination buffer for read
int32_t flash_read(uint32_t addr, uint32_t size, uint8_t *dst) override;

/// SPIFFS callback to write flash, in context.
/// @param addr adddress location to write
/// @param size size of write in bytes
/// @param src source buffer for write
int32_t flash_write(uint32_t addr, uint32_t size, uint8_t *src) override;

/// SPIFFS callback to erase flash, in context.
/// @param addr adddress location to erase
/// @param size size of erase region in bytes
int32_t flash_erase(uint32_t addr, uint32_t size) override;

DISALLOW_COPY_AND_ASSIGN(TiSPIFFS);
};

#endif // _FREERTOS_DRIVERS_SPIFFS_CC3220SF_TISPIFFS_HXX_
Loading

0 comments on commit bc8162e

Please sign in to comment.