parent
9fd96aa5e3
commit
7cf4b57bc6
@ -1,87 +1,196 @@ |
|||||||
/*
|
/**************************************************************************//**
|
||||||
* ExtMemoryManagement.h |
* @file |
||||||
|
* @author Steve Lascos |
||||||
|
* @company Blackaddr Audio |
||||||
* |
* |
||||||
* Created on: Dec 23, 2017 |
* LibMemoryManagment is a class for providing access to external SPI based |
||||||
* Author: slascos |
* SRAM with the optional convience of breaking it up into 'slots' which are smaller |
||||||
*/ |
* memory entities. |
||||||
|
* @details This class treats an external memory as a pool from which the user requests |
||||||
|
* a block. When using that block, the user need not be concerned with where the pool |
||||||
|
* it came from, they only deal with offsets from the start of their memory block. Ie. |
||||||
|
* Your particular slot of memory appears to you to start at 0 and end at whatever size |
||||||
|
* was requested. |
||||||
|
* |
||||||
|
* @copyright 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/>.
|
||||||
|
*****************************************************************************/ |
||||||
|
|
||||||
#ifndef SRC_LIBMEMORYMANAGEMENT_H_ |
#ifndef __LIBMEMORYMANAGEMENT_H |
||||||
#define SRC_LIBMEMORYMANAGEMENT_H_ |
#define __LIBMEMORYMANAGEMENT_H |
||||||
|
|
||||||
#include <cstddef> |
#include <cstddef> |
||||||
|
|
||||||
|
|
||||||
//#include "Audio.h"
|
|
||||||
|
|
||||||
#include "BAHardware.h" |
#include "BAHardware.h" |
||||||
#include "BASpiMemory.h" |
#include "BASpiMemory.h" |
||||||
//#include "LibBasicFunctions.h"
|
|
||||||
|
|
||||||
namespace BAGuitar { |
namespace BAGuitar { |
||||||
|
|
||||||
|
/**************************************************************************//**
|
||||||
|
* MemConfig contains the configuration information associated with a particular |
||||||
|
* SPI interface. |
||||||
|
*****************************************************************************/ |
||||||
struct MemConfig { |
struct MemConfig { |
||||||
size_t size; |
size_t size; ///< the total size of the external SPI memory
|
||||||
size_t totalAvailable; |
size_t totalAvailable; ///< the number of bytes available (remaining)
|
||||||
size_t nextAvailable; |
size_t nextAvailable; ///< the starting point for the next available slot
|
||||||
BASpiMemory *m_spi = nullptr; |
BASpiMemory *m_spi = nullptr; ///< handle to the SPI interface
|
||||||
}; |
}; |
||||||
|
|
||||||
class ExternalSramManager; // forward declare so ExtMemSlot can setup friendship
|
class ExternalSramManager; // forward declare so ExtMemSlot can declared friendship with it
|
||||||
|
|
||||||
|
/**************************************************************************//**
|
||||||
|
* ExtMemSlot provides a convenient interface to a particular slot of an |
||||||
|
* external memory. |
||||||
|
* @details the memory can be access randomly, as a single word, as a block of |
||||||
|
* data, or as circular queue. |
||||||
|
*****************************************************************************/ |
||||||
class ExtMemSlot { |
class ExtMemSlot { |
||||||
public: |
public: |
||||||
|
|
||||||
|
/// clear the entire contents of the slot by writing zeros
|
||||||
|
/// @returns true on success
|
||||||
bool clear(); |
bool clear(); |
||||||
bool setWritePosition(size_t offset) { m_currentWrPosition = m_start + offset; return true;} // TODO add range check
|
|
||||||
|
/// set a new write position (in bytes) for circular operation
|
||||||
|
/// @param offsetBytes moves the write pointer to the specified offset from the slot start
|
||||||
|
/// @returns true on success, else false if offset is beyond slot boundaries.
|
||||||
|
bool setWritePosition(size_t offsetBytes); |
||||||
|
|
||||||
|
/// returns the currently set write pointer pointer
|
||||||
|
/// @returns the write position value
|
||||||
size_t getWritePosition() const { return m_currentWrPosition-m_start; } |
size_t getWritePosition() const { return m_currentWrPosition-m_start; } |
||||||
|
|
||||||
bool setReadPosition(size_t offset) { m_currentRdPosition = m_start + offset; return true;} // TODO add range check
|
/// set a new read position (in bytes) for circular operation
|
||||||
size_t getReadPosition() const { return m_currentRdPosition-m_start; } |
/// @param offsetBytes moves the read pointer to the specified offset from the slot start
|
||||||
|
/// @returns true on success, else false if offset is beyond slot boundaries.
|
||||||
|
bool setReadPosition(size_t offsetBytes); |
||||||
|
|
||||||
bool write16(size_t offset, int16_t *dataPtr, size_t numData); |
/// returns the currently set read pointer pointer
|
||||||
bool zero16(size_t offset, size_t numData); |
/// @returns the read position value
|
||||||
bool read16(int16_t *dest, size_t srcOffset, size_t numData); |
size_t getReadPosition() const { return m_currentRdPosition-m_start; } |
||||||
|
|
||||||
|
/// Write a block of 16-bit data to the memory at the specified offset
|
||||||
|
/// @param offsetBytes offset in bytes from start of slot
|
||||||
|
/// @param dataPtr pointer to start of block of 16-bit data
|
||||||
|
/// @param numWords number of 16-bit words to transfer
|
||||||
|
/// @returns true on success, else false on error
|
||||||
|
bool write16(size_t offsetBytes, int16_t *dest, size_t numWords); |
||||||
|
|
||||||
|
/// Write a block of zeros (16-bit) to the memory at the specified offset
|
||||||
|
/// @param offsetBytes offset in bytes from start of slot
|
||||||
|
/// @param numWords number of 16-bit words to transfer
|
||||||
|
/// @returns true on success, else false on error
|
||||||
|
bool zero16(size_t offsetBytes, size_t numWords); |
||||||
|
|
||||||
|
/// Read a block of 16-bit data from the memory at the specified location
|
||||||
|
/// @param dest pointer to destination for the read data
|
||||||
|
/// @param offsetBytes offset in bytes from start of slot
|
||||||
|
/// @param numWords number of 16-bit words to transfer
|
||||||
|
/// @returns true on success, else false on error
|
||||||
|
bool read16(int16_t *dest, size_t offsetBytes, size_t numWords); |
||||||
|
|
||||||
|
/// Read the next in memory during circular operation
|
||||||
|
/// @returns the next 16-bit data word in memory
|
||||||
uint16_t readAdvance16(); |
uint16_t readAdvance16(); |
||||||
bool writeAdvance16(int16_t *dataPtr, size_t numData); |
|
||||||
|
/// Write a block of 16-bit data from the specified location in circular operation
|
||||||
|
/// @param src pointer to the start of the block of data to write to memory
|
||||||
|
/// @param numWords number of 16-bit words to transfer
|
||||||
|
/// @returns true on success, else false on error
|
||||||
|
bool writeAdvance16(int16_t *src, size_t numWords); |
||||||
|
|
||||||
|
/// Write a single 16-bit data to the next location in circular operation
|
||||||
|
/// @param data the 16-bit word to transfer
|
||||||
|
/// @returns true on success, else false on error
|
||||||
bool writeAdvance16(int16_t data); // write just one data
|
bool writeAdvance16(int16_t data); // write just one data
|
||||||
bool zeroAdvance16(size_t numData); |
|
||||||
//void read16FromPast(int16_t *dest, size_t Offset, size_t numData);
|
/// Write a block of 16-bit data zeros in circular operation
|
||||||
|
/// @param numWords number of 16-bit words to transfer
|
||||||
|
/// @returns true on success, else false on error
|
||||||
|
bool zeroAdvance16(size_t numWords); |
||||||
|
|
||||||
|
|
||||||
|
/// Get the size of the memory slot
|
||||||
|
/// @returns size of the slot in bytes
|
||||||
size_t size() const { return m_size; } |
size_t size() const { return m_size; } |
||||||
|
|
||||||
|
/// Ensures the underlying SPI interface is enabled
|
||||||
|
/// @returns true on success, false on error
|
||||||
bool enable() const; |
bool enable() const; |
||||||
|
|
||||||
|
/// Checks whether underlying SPI interface is enabled
|
||||||
|
/// @returns true if enabled, false if not enabled
|
||||||
bool isEnabled() const; |
bool isEnabled() const; |
||||||
|
|
||||||
|
/// DEBUG USE: prints out the slot member variables
|
||||||
void printStatus(void) const; |
void printStatus(void) const; |
||||||
|
|
||||||
private: |
private: |
||||||
friend ExternalSramManager; |
friend ExternalSramManager; ///< gives the manager access to the private variables
|
||||||
bool m_valid = false; |
bool m_valid = false; ///< After a slot is successfully configured by the manager it becomes valid
|
||||||
size_t m_start = 0; |
size_t m_start = 0; ///< the external memory address in bytes where this slot starts
|
||||||
size_t m_end = 0; |
size_t m_end = 0; ///< the external memory address in bytes where this slot ends (inclusive)
|
||||||
size_t m_currentWrPosition = 0; |
size_t m_currentWrPosition = 0; ///< current write pointer for circular operation
|
||||||
size_t m_currentRdPosition = 0; |
size_t m_currentRdPosition = 0; ///< current read pointer for circular operation
|
||||||
size_t m_size = 0; |
size_t m_size = 0; ///< size of this slot in bytes
|
||||||
SpiDeviceId m_spiId; |
SpiDeviceId m_spiId; ///< the SPI Device ID
|
||||||
BASpiMemory *m_spi = nullptr; |
BASpiMemory *m_spi = nullptr; ///< pointer to an instance of the BASpiMemory interface class
|
||||||
}; |
}; |
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************//**
|
||||||
|
* ExternalSramManager provides a class to handle dividing an external SPI RAM |
||||||
|
* into independent slots for general use. |
||||||
|
* @details the class does not support deallocated memory because this would cause |
||||||
|
* fragmentation. |
||||||
|
*****************************************************************************/ |
||||||
class ExternalSramManager final { |
class ExternalSramManager final { |
||||||
public: |
public: |
||||||
ExternalSramManager() = delete; |
ExternalSramManager() = delete; |
||||||
ExternalSramManager(unsigned numMemories); |
|
||||||
|
/// The manager is constructed by specifying how many external memories to handle allocations for
|
||||||
|
/// @param numMemories the number of external memories
|
||||||
|
ExternalSramManager(unsigned numMemories = 1); |
||||||
virtual ~ExternalSramManager(); |
virtual ~ExternalSramManager(); |
||||||
|
|
||||||
size_t availableMemory(BAGuitar::MemSelect mem); |
/// Query the amount of available (unallocated) memory
|
||||||
|
/// @details note that currently, memory cannot be allocated.
|
||||||
|
/// @param mem specifies which memory to query, default is memory 0
|
||||||
|
/// @returns the available memory in bytes
|
||||||
|
size_t availableMemory(BAGuitar::MemSelect mem = BAGuitar::MemSelect::MEM0); |
||||||
|
|
||||||
|
/// Request memory be allocated for the provided slot
|
||||||
|
/// @param slot a pointer to the global slot object to which memory will be allocated
|
||||||
|
/// @param delayMilliseconds request the amount of memory based on required time for audio samples, rather than number of bytes.
|
||||||
|
/// @param mem specify which external memory to allocate from
|
||||||
|
/// @returns true on success, otherwise false on error
|
||||||
bool requestMemory(ExtMemSlot *slot, float delayMilliseconds, BAGuitar::MemSelect mem = BAGuitar::MemSelect::MEM0); |
bool requestMemory(ExtMemSlot *slot, float delayMilliseconds, BAGuitar::MemSelect mem = BAGuitar::MemSelect::MEM0); |
||||||
|
|
||||||
|
/// Request memory be allocated for the provided slot
|
||||||
|
/// @param slot a pointer to the global slot object to which memory will be allocated
|
||||||
|
/// @param sizeBytes request the amount of memory in bytes to request
|
||||||
|
/// @param mem specify which external memory to allocate from
|
||||||
|
/// @returns true on success, otherwise false on error
|
||||||
bool requestMemory(ExtMemSlot *slot, size_t sizeBytes, BAGuitar::MemSelect mem = BAGuitar::MemSelect::MEM0); |
bool requestMemory(ExtMemSlot *slot, size_t sizeBytes, BAGuitar::MemSelect mem = BAGuitar::MemSelect::MEM0); |
||||||
|
|
||||||
private: |
private: |
||||||
static bool m_configured; |
static bool m_configured; ///< there should only be one instance of ExternalSramManager in the whole project
|
||||||
static MemConfig m_memConfig[BAGuitar::NUM_MEM_SLOTS]; |
static MemConfig m_memConfig[BAGuitar::NUM_MEM_SLOTS]; ///< store the configuration information for each external memory
|
||||||
|
|
||||||
}; |
}; |
||||||
|
|
||||||
|
|
||||||
} |
} |
||||||
|
|
||||||
#endif /* SRC_LIBMEMORYMANAGEMENT_H_ */ |
#endif /* __LIBMEMORYMANAGEMENT_H */ |
||||||
|
Loading…
Reference in new issue