Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Audio refactor #56

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion inc/NRF52ADC.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ class NRF52ADC;
class NRF52ADCChannel : public DataSource
{
private:

NRF52ADC &adc;
ManagedBuffer buffer;
volatile int16_t lastSample;
Expand All @@ -72,6 +71,7 @@ class NRF52ADCChannel : public DataSource
uint8_t channel;
uint8_t gain;
uint8_t bias;
uint8_t startupDelay;

public:
DataStream output;
Expand All @@ -98,6 +98,10 @@ class NRF52ADCChannel : public DataSource
*/
int isEnabled();

/**
* Indicates a downstream channel may want to start/stop the flow of data
*/
virtual void dataWanted(int wanted);

/**
* Update our reference to a downstream component.
Expand Down Expand Up @@ -195,6 +199,11 @@ class NRF52ADCChannel : public DataSource
*
*/
void configureGain();

/**
* Define the startup delay associated with this channel
*/
void setStartDelay(uint8_t value);

/**
* Demultiplexes the current DMA output buffer into the buffer of this channel.
Expand Down
53 changes: 48 additions & 5 deletions source/NRF52ADC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,34 @@ extern "C" void SAADC_IRQHandler()
* @param adc reference to the ADC hardware used by this channel
* @param channel The analog identifier of this channel
*/
NRF52ADCChannel::NRF52ADCChannel(NRF52ADC &adc, uint8_t channel) : adc(adc), output(*this)
NRF52ADCChannel::NRF52ADCChannel(NRF52ADC &adc, uint8_t channel) : adc(adc), status(0), output(*this)
{
this->channel = channel;
this->size = buffer.length();
this->bufferSize = NRF52_ADC_DMA_SIZE;
this->gain = 2;
this->bias = 0;
this->status = 0;
this->lastSample = 0;
this->startupDelay = 0;

// Define our output stream as non-blocking.
output.setBlocking(false);
}

/**
* Indicates a downstream channel may want to start/stop the flow of data
*/
void NRF52ADCChannel::dataWanted(int wanted)
{
bool enabled = (status & NRF52_ADC_CHANNEL_STATUS_ENABLED);

if (wanted == DATASTREAM_WANTED && !enabled)
enable();

if ((wanted == DATASTREAM_NOT_WANTED || wanted == DATASTREAM_DONT_CARE) && enabled)
disable();
}

/**
* Determine the data format of the buffers streamed out of this component.
*/
Expand All @@ -100,7 +114,8 @@ int NRF52ADCChannel::setFormat(int format)
}

float NRF52ADCChannel::getSampleRate() {
return 1000000 / this->adc.getSamplePeriod(); // Note: getSamplePeriod returns in uS.
int v = 1000000 / this->adc.getSamplePeriod(); // Note: getSamplePeriod returns in uS.
return v;
}

float NRF52ADCChannel::requestSampleRate( float sampleRate )
Expand Down Expand Up @@ -161,15 +176,17 @@ int NRF52ADCChannel::isEnabled()
return status & NRF52_ADC_CHANNEL_STATUS_ENABLED;
}


/**
* Update our reference to a downstream component.
*
* @param component The new downstream component for this ADC.
*/
void NRF52ADCChannel::connect(DataSink& component)
{
DMESG("ADCChannel: %p Connected to: %p", this, &component);
this->status |= NRF52_ADC_CHANNEL_STATUS_CONNECTED;
DMESG("ADCChannel: status [%x]", this->status);
DMESG("ADCChannel: [%p]: %s\n", this, this->isConnected() ? "CONNECTED" : "NOT CONNECTED");
}

bool NRF52ADCChannel::isConnected()
Expand Down Expand Up @@ -299,6 +316,14 @@ int NRF52ADCChannel::getBias()
return bias;
}

/**
* Define the startup delay associated with this channel
*/
void NRF52ADCChannel::setStartDelay(uint8_t value)
{
this->startupDelay = value;
}

/**
* Demultiplexes the current DMA output buffer into the buffer of this channel.
*
Expand All @@ -314,8 +339,12 @@ void NRF52ADCChannel::demux(ManagedBuffer dmaBuffer, int offset, int skip, int o
int16_t *end = data + length;
data += offset;

if ((status & NRF52_ADC_CHANNEL_STATUS_ENABLED) == 0)
// If we're not enabled, or in a warm-up period, then nothing to do.
if ((status & NRF52_ADC_CHANNEL_STATUS_ENABLED) == 0 || startupDelay)
{
if(startupDelay) startupDelay--;
return;
}

// If this buffer is too shot to contain information for us, ignore it.
// n.b. The above test is safe, as a short buffer implies that our lastSample is already up to date.
Expand Down Expand Up @@ -502,6 +531,7 @@ void NRF52ADC::enable()
*/
void NRF52ADC::disable()
{
DMESG("NRF52ADC: DISABLING....");
stopRunning();
NRF_SAADC->ENABLE = 0;

Expand Down Expand Up @@ -529,6 +559,8 @@ int NRF52ADC::getSamplePeriod()
*/
int NRF52ADC::setSamplePeriod(int samplePeriod)
{
DMESG("NRF52ADC: setSamplePeriod()....");

bool wasRunning = stopRunning();
// Store the sample rate for later.
this->samplePeriod = samplePeriod;
Expand Down Expand Up @@ -621,6 +653,7 @@ int NRF52ADC::getDmaBufferSize()
*/
int NRF52ADC::setDmaBufferSize(int bufferSize)
{
DMESG("NRF52ADC: SET_DMA_BUFFERSIZE....");
bool wasRunning = stopRunning();
this->bufferSize = bufferSize;
if (wasRunning)
Expand Down Expand Up @@ -711,6 +744,7 @@ int NRF52ADC::activateChannel(NRF52ADCChannel *channel)
channel->enable();
startRunning();
}

return DEVICE_OK;
}

Expand All @@ -723,6 +757,8 @@ int NRF52ADC::releaseChannel(Pin& pin)
{
int c;

DMESG("RELEASING CHANNEL");

if (!nrf52_saadc_id.hasKey(pin.name))
return DEVICE_INVALID_PARAMETER;

Expand All @@ -748,6 +784,8 @@ int NRF52ADC::releaseChannel(Pin& pin)
int
NRF52ADC::releasePin(Pin &pin)
{
DMESG("RELEASING PIN");

NRF52ADCChannel *c = getChannel(pin, false);

if (c != NULL)
Expand All @@ -765,6 +803,8 @@ NRF52ADC::releasePin(Pin &pin)

bool NRF52ADC::stopRunning()
{
DMESG("ADC: STOPPING");

if ( !running)
return false;

Expand All @@ -782,6 +822,8 @@ bool NRF52ADC::stopRunning()

bool NRF52ADC::startRunning()
{
DMESG("ADC: STARTING");

if ( running)
return true;

Expand Down Expand Up @@ -873,6 +915,7 @@ int NRF52ADC::setSleep(bool doSleep)

if (doSleep)
{
DMESG("NRF52ADC: SLEEPING....");
wasRunning = stopRunning();
wasEnabled = NVIC_GetEnableIRQ(SAADC_IRQn);
if (wasEnabled)
Expand Down