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.

cc2540 ADC sampling rate 4k?

Other Parts Discussed in Thread: CC2540

Dear all,

I am sending a four channel emg signal via bluetooth at sampling rate 900hz. That is in total 4*900 samples/s

In the stack function, i only find osal_starttimerex which i can only set a 1ms interval. This means i can only achieve less than 1k sampling rate if i want to use the ADC in cc2540 using the stack function.  Which is also indicated in the post below.

https://bluegiga.zendesk.com/entries/39332288--REFERENCE-ADC-sampling-performance-on-the-BLE11x-module

Is it possible that i use another timer to do the ADC conversion? 

Thank you in advance!

  • You can sample the ADC at greater than 1k samples/s. If you look at pg. 11 in data sheet it shows the typical conversion times for the number of bits which maxes out around 50k samples/s for 7 bits.

    You are also correct though that the minimum resolution of an OSAL timer is 1ms. So if you used this timer and wrote to ADCCON3 everytime you received a time out even then your max samples would be 1k samples/s.

    You don't have to use the OSAL timer to generate a sample. If you look in the adc system in the user's guide (http://www.ti.com/lit/ug/swru191e/swru191e.pdf) you can trigger on a timer 1 compare event. You won't find OSAL API calls for doing this because it is at a lower layer of abstraction than the OSAL. Check out the HAL files for ADC and timer subsystems and see if those get you closer to what you need than the OSAL APIs. You could also just write to subsystem registers worst case.

    -Matt

  • Hi Matt,

    Thank you for your reply. 1ksample/s is enough for me:) I need 4 channels of 1kB in total 4kB. ADC sequence is used. I wrote the code according to http://www.ti.com/litv/zip/swrc257, and when i add the code below, the chip only broadcast 1 package and then stops. I close the function hal_aes_dma and hal_dma so there is no init of dma registers. 

    /***********************************************************************************
    File name: adcDma.c
    
    ***********************************************************************************/
    #include "adcdma.h"
    
    void initDmaa(uint16 __xdata *ADCresult_adr){
    
    /****************************************************************************
    * I/O-Port configuration
    * PIN0_0 to P0_3 is configured as ADC input pins.
    * APCFG[7:0] select P0.7–P0.0 as analog I/O.
    */ 
    
    APCFG = 0x0F;
    
    
    // Set the DMA channel 0 configuration address registers.
    DMA0CFGL = ((uint16)&dma_channel[0]) & 0x00FF;
    DMA0CFGH = ((uint16)&dma_channel[0] >> 8);
    
    // Set the DMA channel 1-4 configuration address registers.
    DMA1CFGL = ((uint16)&dma_channel[1]) & 0x00FF;
    DMA1CFGH = ((uint16)&dma_channel[1] >> 8);
    
    /****************************************************************************
    * DMA configuration:
    * Set up DMA channel 1 and 2 for transfer from ADCL and ADCH to
    * the ADC result table. The ADC will generate the DMA trigger
    * on end of conversion.
    */
    
    // Configure DMA channel 0.
    dma_channel_init(&dma_channel[0], ADCresult_adr, 1, 21); //ch 0 21
    
    // Configure DMA channel 1.
    dma_channel_init(&dma_channel[1], &ADCresult_adr[1], 1, 22); // ch 1 22 .. 23 34
    
    // Configure DMA channel 2.
    dma_channel_init(&dma_channel[2], &ADCresult_adr[2], 1, 23);
    
    // Configure DMA channel 3.
    dma_channel_init(&dma_channel[3], &ADCresult_adr[3], 1, 24);
    
    }
    
    
    void startADCDma(void)
    {
    // Arm DMA channels, takes 36 clock cycles.
    DMAARM = 0x0F;
    ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP; // 9 NOPs
    ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP; // 9 NOPs
    ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP; // 9 NOPs
    ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP; // 9 NOPs
    
    
    /****************************************************************************
    * ADC configuration :
    * - Continous mode
    * - Single-ended sequence conversion
    * - Reference Voltage is VDD on the AVDD pin
    * - 9 bit resolution (128 dec rate)
    */
    
    /* ADC conversion :
    * reference voltage ACDD5 10
    * 9 bits ENOB settings 01
    * SCH from channel AIN0 to AIN3 0011
    */
    ADCCON2 = 0x93;
    
    // FULL SPEED continous ADC
    ADCCON1 = 0x13;
    
    
    /* 
    * Await all data transfers being completed. from dma channel 0 to 3
    */
    
    while( DMAIRQ != 0x0F );
    
    // reset the interrupt
    DMAIRQ = 0x00;
    // unarm
    DMAARM = 0x00;
    
    // Stop continuous mode.(ADC)
    ADCCON1 |= 0x40;
    
    
    }
    
    
    
    void dma_channel_init ( DMA_DESC __xdata *dma_p,
    uint16 __xdata *dest_adr,
    uint8 lenl,
    uint8 trig )
    {
    // Setup DMA configuration.-
    dma_p->SRCADDRH = (uint16)(&X_ADCL) >> 8;
    dma_p->SRCADDRL = (uint16)(&X_ADCL) & 0x00FF;
    dma_p->DESTADDRH = ((uint16)dest_adr) >> 8;
    dma_p->DESTADDRL = ((uint16)dest_adr);
    dma_p->VLEN = 0x00;
    dma_p->LENH = 0;
    dma_p->LENL = lenl; // Tranfer Count
    dma_p->WORDSIZE = 0x00;
    dma_p->TMODE = 0x01;
    dma_p->TRIG = trig; // Channel trigger
    dma_p->SRCINC = 0x01;
    dma_p->DESTINC = 0x01;
    dma_p->IRQMASK = 0x00;
    dma_p->M8 = 0x01;
    dma_p->PRIORITY = 0x02;
    }
    

    I call init in the simpleProfileInit(), and use startADCDma() every 1 ms.  Can you help me with it? Thanks in advance!