This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
I'm wondering if there is example code for an acquisition with a controllable number of samples from the adc12 then storing the data into FRAM memory via DMA. I've been piecing it together from multiple other examples but half the syntax doesn't work with my energia project and importing the required headers isn't working for some reason.
I'd prefer a project I can pull directly from the resource explorer if one exists for a different msp430. Does this adc->dma->fram example exist anywhere?
Thank you.
This program started life as TI example MSP430F55xx_dma_04.c, and required relatively few changes. It writes to SRAM, not FRAM. Writing to FRAM instead is a small program change, but requires understanding the Memory Protection Unit (MPU). I suggest you try this first.
/// // FR5969 ADC12->DMA demo // Started life as TI example MSP430F55xx_dma_04.c // #include <msp430.h> #include <stdint.h> #define DEMO_5969 1 // Specifics for FR5969 and/or Launchpad unsigned int DMA_DST; // ADC conversion result is stored in this variable int main(void) { WDTCTL = WDTPW+WDTHOLD; // Hold WDT P1OUT &= ~BIT0; // P1.0 clear P1DIR |= BIT0; // P1.0 output #if DEMO_5969 // FR5969 Launchpad P1SEL0 |= BIT2; // P1.2 as A2 per P1SEL1 |= BIT2; // SLAS704F Table 6-49 PM5CTL0 &= ~LOCKLPM5; // Needed for FR5969, not for F5529 #else // Original for F5529 P5SEL |= BIT7; // P5.7/TB1 option select P5DIR |= BIT7; // Output direction P6SEL |= BIT0; // Enable A/D channel A0 #endif //Setup Timer B0 TBCCR0 = 0xFFFE; TBCCR1 = 0x8000; TBCCTL1 = OUTMOD_3; // CCR1 set/reset mode TBCTL = TBSSEL_2+MC_1+TBCLR; // SMCLK, Up-Mode // Setup ADC12 ADC12CTL0 = ADC12SHT0_15+ADC12MSC+ADC12ON;// Sampling time, MSC, ADC12 on ADC12CTL1 = ADC12SHS_3+ADC12CONSEQ_2; // Use sampling timer; ADC12MEM0 // Sample-and-hold source = CCI0B = // TBCCR1 output // Repeated-single-channel #if DEMO_5969 // Use A2 since A0/A1 are taken on the Launchpad ADC12MCTL0 = ADC12VRSEL_0+ADC12INCH_2; // V+=AVcc V-=AVss, A0 channel #else ADC12MCTL0 = ADC12SREF_0+ADC12INCH_0; // V+=AVcc V-=AVss, A0 channel #endif ADC12CTL0 |= ADC12ENC; // Setup DMA0 #if DEMO_5969 // Different DMA trigger number DMACTL0 = DMA0TSEL_26; // ADC12IFGx trigger per DS Table 6-12 #else DMACTL0 = DMA0TSEL_24; // ADC12IFGx triggered #endif DMACTL4 = DMARMWDIS; // Read-modify-write disable DMA0CTL &= ~DMAIFG; DMA0CTL = DMADT_4+DMAEN+DMADSTINCR_0+DMAIE; // Rpt single tranfer, unchanged dst, Int DMA0SZ = 1; // DMA0 size = 1 __data20_write_long((uintptr_t) &DMA0SA,(uintptr_t) &ADC12MEM0); // Source block address __data20_write_long((uintptr_t) &DMA0DA,(uintptr_t) &DMA_DST); // Destination single address __bis_SR_register(LPM0_bits + GIE); // LPM0 w/ interrupts __no_operation(); // used for debugging } //------------------------------------------------------------------------------ // DMA Interrupt Service Routine //------------------------------------------------------------------------------ #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=DMA_VECTOR __interrupt void DMA_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(DMA_VECTOR))) DMA_ISR (void) #else #error Compiler not supported! #endif { switch(__even_in_range(DMAIV,16)) { case 0: break; case 2: // DMA0IFG = DMA Channel 0 P1OUT ^= BIT0; // Toggle P1.0 - PLACE BREAKPOINT HERE AND CHECK DMA_DST VARIABLE break; case 4: break; // DMA1IFG = DMA Channel 1 case 6: break; // DMA2IFG = DMA Channel 2 case 8: break; // DMA3IFG = DMA Channel 3 case 10: break; // DMA4IFG = DMA Channel 4 case 12: break; // DMA5IFG = DMA Channel 5 case 14: break; // DMA6IFG = DMA Channel 6 case 16: break; // DMA7IFG = DMA Channel 7 default: break; } }
[Edit: For reference, the original is here:
https://dev.ti.com/tirex/explore/node?node=ALkqBIa6R80LFOC7XAng.Q__IOGqZri__LATEST
]
Hi,
There are ADC and DMA academies which can help you on the coding. You can refer to the following link.
https://dev.ti.com/tirex/explore/node?node=AKzqA0IGyLAD2nwRN2jyTA__IOGqZri__LATEST
https://dev.ti.com/tirex/explore/node?node=AJAJEjm2KsURl3nLMsYpVw__IOGqZri__LATEST
Best regards,
Cash Hao
Thank you for that clue. I ended up needing to disable the MPU to get anything read back out of the FRAM. This probably isn't the right way to do this, which is why I was hoping there was a provided example.
Did you succeed with the SRAM version (above)?
CCS has a fairly handy MPU configurator in the Build-Settings->General->MPU tab. You'll probably want to declare your FRAM buffers as PERSISTENT so they're put in a predictable area of FRAM (down at the bottom).
I didn't try the SRAM version as I need FRAM since eventually the data needs to survive a power cycle.
The MPU tab is where I disabled the MPU. The 'Let compiler handle memory...' checkbox is on and the data can't be read from FRAM at the locations I've tried. I plan to manually specify the memory after working out the rest of the program details.
Unless that 'Let compiler handle memory...' checkbox needs the PERSISTENT flag and some associated code to work that isn't included in the Ti examples I've been working from?
I don't know if the MPU tab takes into account the size of the TI.persistent section, since I always came at it from the opposite direction. Try it. The .map file is usually a big help.
More generally: I think you're beyond the scope of the TI examples (I had to work over that example to provide something), so you may need to do some experiments.
**Attention** This is a public forum