parent
9fd96aa5e3
commit
7cf4b57bc6
@ -1,87 +1,196 @@ |
||||
/*
|
||||
* ExtMemoryManagement.h |
||||
/**************************************************************************//**
|
||||
* @file |
||||
* @author Steve Lascos |
||||
* @company Blackaddr Audio |
||||
* |
||||
* Created on: Dec 23, 2017 |
||||
* Author: slascos |
||||
*/ |
||||
* LibMemoryManagment is a class for providing access to external SPI based |
||||
* 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_ |
||||
#define SRC_LIBMEMORYMANAGEMENT_H_ |
||||
#ifndef __LIBMEMORYMANAGEMENT_H |
||||
#define __LIBMEMORYMANAGEMENT_H |
||||
|
||||
#include <cstddef> |
||||
|
||||
|
||||
//#include "Audio.h"
|
||||
|
||||
#include "BAHardware.h" |
||||
#include "BASpiMemory.h" |
||||
//#include "LibBasicFunctions.h"
|
||||
|
||||
namespace BAGuitar { |
||||
|
||||
/**************************************************************************//**
|
||||
* MemConfig contains the configuration information associated with a particular |
||||
* SPI interface. |
||||
*****************************************************************************/ |
||||
struct MemConfig { |
||||
size_t size; |
||||
size_t totalAvailable; |
||||
size_t nextAvailable; |
||||
BASpiMemory *m_spi = nullptr; |
||||
size_t size; ///< the total size of the external SPI memory
|
||||
size_t totalAvailable; ///< the number of bytes available (remaining)
|
||||
size_t nextAvailable; ///< the starting point for the next available slot
|
||||
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 { |
||||
public: |
||||
|
||||
/// clear the entire contents of the slot by writing zeros
|
||||
/// @returns true on success
|
||||
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; } |
||||
|
||||
bool setReadPosition(size_t offset) { m_currentRdPosition = m_start + offset; return true;} // TODO add range check
|
||||
size_t getReadPosition() const { return m_currentRdPosition-m_start; } |
||||
/// set a new read position (in bytes) for circular operation
|
||||
/// @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); |
||||
bool zero16(size_t offset, size_t numData); |
||||
bool read16(int16_t *dest, size_t srcOffset, size_t numData); |
||||
/// returns the currently set read pointer pointer
|
||||
/// @returns the read position value
|
||||
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(); |
||||
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 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; } |
||||
|
||||
/// Ensures the underlying SPI interface is enabled
|
||||
/// @returns true on success, false on error
|
||||
bool enable() const; |
||||
|
||||
/// Checks whether underlying SPI interface is enabled
|
||||
/// @returns true if enabled, false if not enabled
|
||||
bool isEnabled() const; |
||||
|
||||
/// DEBUG USE: prints out the slot member variables
|
||||
void printStatus(void) const; |
||||
|
||||
private: |
||||
friend ExternalSramManager; |
||||
bool m_valid = false; |
||||
size_t m_start = 0; |
||||
size_t m_end = 0; |
||||
size_t m_currentWrPosition = 0; |
||||
size_t m_currentRdPosition = 0; |
||||
size_t m_size = 0; |
||||
SpiDeviceId m_spiId; |
||||
BASpiMemory *m_spi = nullptr; |
||||
friend ExternalSramManager; ///< gives the manager access to the private variables
|
||||
bool m_valid = false; ///< After a slot is successfully configured by the manager it becomes valid
|
||||
size_t m_start = 0; ///< the external memory address in bytes where this slot starts
|
||||
size_t m_end = 0; ///< the external memory address in bytes where this slot ends (inclusive)
|
||||
size_t m_currentWrPosition = 0; ///< current write pointer for circular operation
|
||||
size_t m_currentRdPosition = 0; ///< current read pointer for circular operation
|
||||
size_t m_size = 0; ///< size of this slot in bytes
|
||||
SpiDeviceId m_spiId; ///< the SPI Device ID
|
||||
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 { |
||||
public: |
||||
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(); |
||||
|
||||
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); |
||||
|
||||
/// 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); |
||||
|
||||
private: |
||||
static bool m_configured; |
||||
static MemConfig m_memConfig[BAGuitar::NUM_MEM_SLOTS]; |
||||
static bool m_configured; ///< there should only be one instance of ExternalSramManager in the whole project
|
||||
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