Sled, you can use the Injection feature to insert a marker. So when you get to the start of your sinewave, you inject a single sample of say channel 5. You tie the channel 5 input put to a voltage such that it will saturate the ADC to get 0xFFFF. As soon as the injected sequence finishes, the programmed conversion will continue. NOW, you have a marker in your recieved data (a saturated value of 0xFFFF to indicate the zero point of the generated waveform......
Announcement
Collapse
No announcement yet.
Direct I/Q demodulation
Collapse
X
-
Originally posted by scrungy_doolittle View PostSled, you can use the Injection feature to insert a marker. So when you get to the start of your sinewave, you inject a single sample of say channel 5. You tie the channel 5 input put to a voltage such that it will saturate the ADC to get 0xFFFF. As soon as the injected sequence finishes, the programmed conversion will continue. NOW, you have a marker in your recieved data (a saturated value of 0xFFFF to indicate the zero point of the generated waveform......
Ideally you should not have to mark anything as you know the timing of the TX signal ... if you have to "mark" a conversion sequence a simple ring buffer is made to wait till the required sample arrives and then stored at location "zero" ... the start of the conversion sequence will always start at the "zero" location without injecting any markers ( which is a code overhead ). Alternatively use a correlation / cross correlation function to synchronise the sample buffers.
Comment
-
Originally posted by moodz View PostIdeally you should not have to mark anything as you know the timing of the TX signal ... if you have to "mark" a conversion sequence a simple ring buffer is made to wait till the required sample arrives and then stored at location "zero" ... the start of the conversion sequence will always start at the "zero" location without injecting any markers ( which is a code overhead ). Alternatively use a correlation / cross correlation function to synchronise the sample buffers.
Comment
-
Originally posted by sled View PostAt the moment everything is running synchronously, no need for markers. However theoretically I could have the TX spinning freely and start to sample the RX anywhere in the TX cycle since I'm only interest in the relative change of the phase? This assumes every RX sample is 90degrees apart with respect to the TX frequency.
However because of no fixed reference phase ... would you still be able to discriminate correctly ??
hmm.
Comment
-
Originally posted by moodz View PostIdeally you should not have to mark anything as you know the timing of the TX signal ... if you have to "mark" a conversion sequence a simple ring buffer is made to wait till the required sample arrives and then stored at location "zero" ... the start of the conversion sequence will always start at the "zero" location without injecting any markers ( which is a code overhead ). Alternatively use a correlation / cross correlation function to synchronise the sample buffers.
You are assuming that you would start the transmission of one cycle, arm the ADC and capture data for one full cycle, then process it and repeat. That was the idea with the golden goose, that I got
involved in, but did not have time to do anything with.
While that will work, it does not model an analog transmit and receive very well.
My concept is that the transmit and receive happen contentiously, and you are looking at a window in a rolling buffer of data, that is always aligned on some start address. So you need a way
to mark the timing between the transmit and receive, so you can determine the phase shift simply.
The transmit is running on interrupts, as it is stepping through the buffer at some fixed rate. The buffers get out of sync. I knowI do reatime programming for a living....
These are asynchronous operations, so you really have to have some marker to correlate things.
Comment
-
Originally posted by scrungy_doolittle View PostThis assumes that you trigger the adc in sync with the TX signal. However, if you just let the adc run, using DMA to move the data to the buffer, without marking some kind of synchronization signal you don't have a correlation. So the adc is rolling along sampling continuously, and putting the data into memory. That is running with no interrupts, or at most one at the end of the buffer. of you want to trigger another DMA channel to move the acquired data.
You are assuming that you would start the transmission of one cycle, arm the ADC and capture data for one full cycle, then process it and repeat. That was the idea with the golden goose, that I got
involved in, but did not have time to do anything with.
While that will work, it does not model an analog transmit and receive very well.
My concept is that the transmit and receive happen contentiously, and you are looking at a window in a rolling buffer of data, that is always aligned on some start address. So you need a way
to mark the timing between the transmit and receive, so you can determine the phase shift simply.
The transmit is running on interrupts, as it is stepping through the buffer at some fixed rate. The buffers get out of sync. I knowI do reatime programming for a living....
These are asynchronous operations, so you really have to have some marker to correlate things.
Comment
-
>>"Couldn't this be done using the op-amp as comparator to detect the zero crossing, triggering an interrupt and then look up at what angle the transmitter is at?"
Simple TX oscillator + Schmitt trigger + STM32 comparator generating IRQ to start ADC -> DMA buffer batch cycle maybe could be used; It could be simpler, less noise than DAC based TX
Comment
-
Stm32f103 is good but if you want to get more power go to f4 I just get 1 from arrow with free shipping with cirrus logic 24 bit ADC and cortex m4 if you want easy and fast programming get 1 with mbed support minimaple is supported with mbed you can after using mbed export your work to Kiel and you can use debugging tool like stlink .or You switch to Texas Instrument had a good software like arduino his name is energia and had a good customer support and good examples
Comment
-
Originally posted by chafik View PostStm32f103 is good but if you want to get more power go to f4 I just get 1 from arrow with free shipping with cirrus logic 24 bit ADC and cortex m4 if you want easy and fast programming get 1 with mbed support minimaple is supported with mbed you can after using mbed export your work to Kiel and you can use debugging tool like stlink .or You switch to Texas Instrument had a good software like arduino his name is energia and had a good customer support and good examples
Cirrus Logic have really nice codecs but they're quite power hungry. AKM offers good codecs with low power capabilities: http://www.akm.com/akm/en/product/detail/0020/
Comment
-
Originally posted by moodz View PostI see where you are coming from ... I recently had a similiar problem where the ADC could not be synced to the "TX" because there was no ADC sync input to sync the ADC with the CPU .. the solution was to take the "sample ready" clock from the ADC as the reference sync signal for the TX .... thus the TX was synced to the RX clock ( ie ADC sampler ). The ADC was driven by a crystal based clocked so the TX effectively slave referenced.
In that case, when you triggered the injection from within the DDS transmit routine, the ADC stops it's normal conversion, and converts the injected channel, then resumes converting it's normal
channel. The result is you can inject a saturated marker in the ADC stream even though it is being put into memory by the DMA engine. We don't want the ADC Synched to the TX because then you would not be able to measure the phase shift in the signal relative to the TX, so you would not be able to sample relative to the TX, which is how the X and Y demodulators work in an analog system.
Comment
-
To sync ADC with DAC:
0) set acqDone = false;
1) setup DAC in circular DMA mode; it will generate IRQ every time on hitting the end of the buffer; start DAC DMA
2) in the IRQ handler for the DAC DMA done: if acqDone == false then -> start the ADC DMA buffer acquisition; Make sure to enable end of the end of the ADC conversion IRQ in setup
3) in the IRQ handler for end of ADC sampling set flag acqDone = true;
4) in the main:
while(1)
{
if(acqDone)
{
//process buffer
acqDone = false;
}
}
this will sync ADC to DAC
Comment
-
Originally posted by Daren View PostTo sync ADC with DAC:
0) set acqDone = false;
1) setup DAC in circular DMA mode; it will generate IRQ every time on hitting the end of the buffer; start DAC DMA
2) in the IRQ handler for the DAC DMA done: if acqDone == false then -> start the ADC DMA buffer acquisition; Make sure to enable end of the end of the ADC conversion IRQ in setup
3) in the IRQ handler for end of ADC sampling set flag acqDone = true;
4) in the main:
while(1)
{
if(acqDone)
{
//process buffer
acqDone = false;
}
}
this will sync ADC to DAC
- half full ADC, sets adcReady=true
- half empty DAC
- full ADC, sets adcReady=true
- empty DAC
The main loop just waits for adcReady==true and then does the processing, the processing must be done before the next interrupt happens. The DMA never stops.
Comment
-
Originally posted by sled View Postthe processing must be done before the next interrupt happens.
Using double buffer is a good idea. Concurrent sample acquisition using ADC->DMA and processing previous samples with CPU will almost double data throughput. The CPU processed buffer can't be updated by ADC->DMA; logic for it can be handled in the IRQ handler (looking a the acqDone flag.. and pointing DMA for the next cycle to correct DMA buffer) This sometimes called ping-pong buffering. The flag signaling is not needed if you can guarantee that you can always finish processing before buffer switch, but unless you have another CPU to do user interaction that can't be the case.
Comment
-
Originally posted by Daren View PostThe scheme I posted does not make this assumption. You can take as long as you need to process, and you signal that you are ready to accept more samples using flag when you done. When display needs to be updated processing can take a while...
Using double buffer is a good idea. Concurrent sample acquisition using ADC->DMA and processing previous samples with CPU will almost double data throughput. The CPU processed buffer can't be updated by ADC->DMA; logic for it can be handled in the IRQ handler (looking a the acqDone flag.. and pointing DMA for the next cycle to correct DMA buffer) This sometimes called ping-pong buffering. The flag signaling is not needed if you can guarantee that you can always finish processing before buffer switch, but unless you have another CPU to do user interaction that can't be the case.
dac-----buffer 1
change to buffer 2, dma into rolling buffer r1 r2 wb where R1 is a buffer the same size the ADC buffer, as are R2 and wb. They are consecutive in memory.
set DMA channel to transfer buffer in the R1.
when that is finished, set DMA to shift r1,r2, wb in memory such that R2 overwrites wb, r1 overwrites r2, freeing r1 up for the next buffer, at the end of that DMA, trigger a call to a buffering routine that moves
wb into your WORK_BUFFER (NOTE: you do NOT want that under control of dma. The danger of working in buffer wb, is that DMA can come along and clobber your data. You want the data in your working buffer to
change only when you need it to, but when it does, it will always be at least one sample block behind the current buffering.
If you need more time, simply increase the buffer size to the max you can use., r1,r2,r3,r4 etc. OR You don't want to get it to deep of a delay, otherwise your user indications will be wrong (i.e. you will be off the target before you notify the user.) Set the ADC to sample two channels and interleave them. Also set the hardware oversampling. for a 12 bit ADC, you need to oversample 256 times the frequency to get 16 bits
using the 16 bit delta sigma in the PIC24GJ128GC010) you can oversample by 0 SDOSR<2:0>: S/D Oversampling Ratio (OSR) Selection bits111 = Reserved110 = 16 (fastest result, lowest quality)101 = 32100 = 64011 = 128010 = 256001 = 512000 = 1024 (slowest result, best quality) at 1024, you get only 244 samples per second. 16-Bit Sigma-Delta A/DConverter” (DS30687) at 16x oversampling, your sample rate us 62 khz, which is more than sufficient for up to 20 khz.
The STM32 family, I believe also has automatic oversampling.
But in either case, you use pingpong buffering and DMA to move memory around.
There are at least 3 philosophies to approaching this:
1. transmit, sample, process and repeat. While you are processing, the transmit, and sample process are not working, so you will cover ground with your swing, and you will miss areas of the ground based on your swing and processing time. Assume that you can process things in 100 msec, and your swing rate is 1 second across 5 feet you are getting 10 samples in that time, so you are only getting the signal once every 6 inches.
The better option in this cse, is to continuously transmit and sample, and process as you can. so if you have 100 msec processing time, you will at least have captured the ground between your processing blocks.
2. Continuously transmit, sample and process. This emulates the operation of a true analog detector, where the processing is in real time. Here everything runs in the background on interrupts and DMA, and all you are
doing is processing. in a loop. Your processing time can only be 2 dma buffers worth of time, before the data in the window changes. There is nothing to prevent you from taking 100 msec to process, but you need to move the wb buffer to a different working area so DMA doesn't change it on you.
3. continuously transmit, burst sample, process and repeat the burst sampling and processing.
Comment
Comment