When I try to initialize the ADC and DAC in a same void function, the SDK shows me that 'Can't allocate DMAEnv for 40410000'. '40410000' is the address of DMA_DAC_BASE_ADDR. Because of that, DAC cannot generate the correct waveform when ADC works perfect. By the way, it works perfectly when I just use DAC or ADC.
My project is using the ADC collect the data and compare the data with the threshold, DAC will generate the different waveform according to the result of comparative.
Update 27th January
The problem has been solved!!!! Tanks to @artvvb
I will share some experience here to help others.
First, just like what @artvvb said you need change the size of heap and the default value is just 2000, if you hope to initialise the ADC and DAC at the same time.
Secondly, don't forget to use static to avoid the duplicate initialisation in loop, or the heap will overflow again.
By the way, in my code, I enable two I2C, so the I2C base address of ADC and ADC are different. If you use the default demo from the GitHub, please follow the answer from @artvvb.
Question
Tommy 777
Hi:
When I try to initialize the ADC and DAC in a same void function, the SDK shows me that 'Can't allocate DMAEnv for 40410000'. '40410000' is the address of DMA_DAC_BASE_ADDR. Because of that, DAC cannot generate the correct waveform when ADC works perfect. By the way, it works perfectly when I just use DAC or ADC.
Thanks for any suggestion.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <xil_printf.h>
#include "xparameters.h"
#include "D:\Gitbash\ADC-test\Eclypse-Z7\hw\proj\hw.sdk\zmodlib\ZmodADC1410\zmodadc1410.h"
#include "D:\Gitbash\DAC-test\Eclypse-Z7\hw\proj\hw.sdk\zmodlib\ZmodDAC1411\zmoddac1411.h"
#include "D:\Gitbash\ADC-test\Eclypse-Z7\hw\proj\hw.sdk\zmodlib\Zmod\zmod.h"
#define TRANSFER_LEN 0x1 /*100=2us*/
#define ZMOD_ADC_BASE_ADDR XPAR_ZMODADC_0_AXI_ZMODADC1410_1_S00_AXI_BASEADDR
#define DMA_ADC_BASE_ADDR XPAR_ZMODADC_0_AXI_DMA_0_BASEADDR
#define IIC_ADC_BASE_ADDR XPAR_PS7_I2C_0_BASEADDR
#define FLASH_ADDR_ADC 0x30
#define ZMOD_ADC_IRQ XPAR_FABRIC_ZMODADC_0_AXI_ZMODADC1410_1_LIRQOUT_INTR
#define DMA_ADC_IRQ XPAR_FABRIC_ZMODADC_0_AXI_DMA_0_S2MM_INTROUT_INTR
#define ZMOD_DAC_BASE_ADDR XPAR_ZMODDAC_0_AXI_ZMODDAC1411_V1_0_0_BASEADDR
#define DMA_DAC_BASE_ADDR XPAR_ZMODDAC_0_AXI_DMA_1_BASEADDR
#define FLASH_ADDR_DAC 0x31
#define DMA_DAC_IRQ XPAR_FABRIC_ZMODDAC_0_AXI_DMA_1_MM2S_INTROUT_INTR
#define IIC_DAC_BASE_ADDR XPAR_PS7_I2C_1_BASEADDR
uint8_t checkpoint;
void dacRampDemo(float offset, float amplitude, float step, uint8_t channel, uint8_t frequencyDivider, uint8_t gain, uint8_t checkpoint)
{
ZMODDAC1411 dacZmod(ZMOD_DAC_BASE_ADDR, DMA_DAC_BASE_ADDR, IIC_DAC_BASE_ADDR, FLASH_ADDR_DAC, DMA_DAC_IRQ);
uint32_t *buf;
float val;
uint32_t valBuf;
int16_t valRaw;
size_t length;
length = (size_t)(amplitude/step) << 2;
int i;
if (length > ((1<<14) - 1))
{
// limit the length to maximum buffer size (1<<14 - 1)
length = ((1<<14) - 1);
// adjust step
step = amplitude/(length>>2);
}
buf = dacZmod.allocChannelsBuffer(length);
dacZmod.setOutputSampleFrequencyDivider(frequencyDivider);
dacZmod.setGain(channel, gain);
if(checkpoint==0)
{
i = 0;
// ramp up
for(val = -amplitude; val < amplitude; val += step)
{
valRaw = dacZmod.getSignedRawFromVolt(val + offset, gain);
valBuf = dacZmod.arrangeChannelData(channel, valRaw);
buf[i++] = valBuf;
}
// ramp down
for(val = amplitude; val > -amplitude; val -= step)
{
valRaw = dacZmod.getSignedRawFromVolt(val + offset, gain);
valBuf = dacZmod.arrangeChannelData(channel, valRaw);
buf[i++] = valBuf;
}
// send data to DAC and start the instrument
dacZmod.setData(buf, length);// necessary
dacZmod.start(); //necessary
dacZmod.freeChannelsBuffer(buf, length);
dacZmod.stop();
}
if(checkpoint==1)
{
i = 0;
// ramp up
for(val = -amplitude; val < amplitude; val += step)
{
valRaw = dacZmod.getSignedRawFromVolt(amplitude + offset, gain);
valBuf = dacZmod.arrangeChannelData(channel, valRaw);
buf[i++] = valBuf;
}
// ramp down
for(val = amplitude; val > -amplitude; val -= step)
{
valRaw = dacZmod.getSignedRawFromVolt(-amplitude + offset, gain);
valBuf = dacZmod.arrangeChannelData(channel, valRaw);
buf[i++] = valBuf;
}
// send data to DAC and start the instrument
dacZmod.setData(buf, length);// necessary
dacZmod.start(); //necessary
dacZmod.freeChannelsBuffer(buf, length);
dacZmod.stop();
}
}
void formatADCDataOverUART(ZMODADC1410 *padcZmod, uint32_t *acqBuffer, uint8_t channel, uint8_t gain, size_t length)
{
char val_formatted[15];
char time_formatted[15];
char check[15];
uint32_t valBuf;
int16_t valCh;
float val;
for (size_t i = 0; i < length; i++)
{
valBuf = acqBuffer[i];
valCh = padcZmod->signedChannelData(channel, valBuf);
val = padcZmod->getVoltFromSignedRaw(valCh, gain);
padcZmod->formatValue(val_formatted, 1000.0*val, "mV");
if(1000.0*val<2400)
{
padcZmod->formatValue(check, 0, "L");
checkpoint=0;
}
else
{
padcZmod->formatValue(check, 1, "H");
checkpoint=1;
}
if (i < 100)
{
padcZmod->formatValue(time_formatted, i*10, "ns");
}
else
{
padcZmod->formatValue(time_formatted, (float)(i)/100.0, "us");
}
xil_printf("%s\t%x\t%s\t%s\n", val_formatted, (uint32_t)(valCh&0x3FFF), check, time_formatted );
}
}
void ADCBaremetalDemo(uint8_t channel,uint8_t gain)
{
// channel CH1
// gain LOW - Corresponds to HIGH input Range
// length 0x1
ZMODADC1410 adcZmod(ZMOD_ADC_BASE_ADDR, DMA_ADC_BASE_ADDR, IIC_ADC_BASE_ADDR, FLASH_ADDR_ADC,
ZMOD_ADC_IRQ, DMA_ADC_IRQ);
uint32_t *acqBuffer;
size_t acqbufferlength=TRANSFER_LEN;
adcZmod.setGain(channel, gain);
while(1)
{
acqBuffer = adcZmod.allocChannelsBuffer(acqbufferlength);
adcZmod.acquireImmediatePolling(acqBuffer, acqbufferlength);
formatADCDataOverUART(&adcZmod, acqBuffer, channel, gain, acqbufferlength);
adcZmod.freeChannelsBuffer(acqBuffer, acqbufferlength);
dacRampDemo(0, 5, 2, 0, 8, 1,checkpoint);
sleep(1);
}
}
/*
* ADC Baremetal Demo
*/
int main() {
ADCBaremetalDemo(0,0);
return 0;
}
Update 26th January
My project is using the ADC collect the data and compare the data with the threshold, DAC will generate the different waveform according to the result of comparative.
Update 27th January
The problem has been solved!!!! Tanks to @artvvb
I will share some experience here to help others.
First, just like what @artvvb said you need change the size of heap and the default value is just 2000, if you hope to initialise the ADC and DAC at the same time.
Secondly, don't forget to use static to avoid the duplicate initialisation in loop, or the heap will overflow again.
By the way, in my code, I enable two I2C, so the I2C base address of ADC and ADC are different. If you use the default demo from the GitHub, please follow the answer from @artvvb.
Edited by Tommy 777Link to comment
Share on other sites
4 answers to this question
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now