Jump to content
PTB

Stellaris fast analog reads

Recommended Posts

L.R.A.

 

You are the man !

 

Its working.

 

Number of Samples : 255
Sample Starttime : 3143376
Sample Endtime : 3143888
Sample Array Set Duration time in microseconds  : 512

=======================

 

Now this is only 0.5 MSPS instead of 1 BUT.... the old code would sometimes do that anyway. Sometimes it was 1MSPS sometimes it was 0.5MSPS.

At least now its consistent. ;)

 

1MSPS would be obviously nicer, but this is still pretty great.

 

I will splice this back into my main code and see how she goes.

 

I'll do further project based posts in another thread. I've made some priceless mistakes..... I'm not ashamed to share :lol:

 

Thanks heaps !!!! Really Appreciate it.

 

Cheers

 

PTB

 

P.S. BTW I tried with and without this line

        SysCtlDelay(3);

        It didn't seem to mind either way.

 

Working Code under Energia 15

// 
// LM4F_ADC 
// A Stellarisiti Collaborative effort 
// JKabat, Rei Vilo, reaper7,L.R.A. PTB.
//

// Include application, user and local libraries

// Define variables and constants
///
/// @file	Fast_Analog_Read.ino
/// @brief	Main sketch
///
/// @details	Fast Analog Read Investigations for Stellaris LM4F
///

//
// Stellaris Pin Assignments
// =========================
//PE_3    //Sensor Analog Read
//PA_5    //Trigger Analog Signal Pulse
//PF_4    //Push Button to Start

//
// Libraries
// =========
#include "Energia.h"
#include "SPI.h"
#include "inc/lm4f120h5qr.h"


#include "inc/hw_adc.h"
#include "inc/hw_gpio.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"

#include "driverlib/adc.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/rom.h"


//
// Constants from adc.c
// ====================
#define ADC_SEQ                 (ADC_O_SSMUX0)
#define ADC_SEQ_STEP            (ADC_O_SSMUX1 - ADC_O_SSMUX0)
#define ADC_SSFIFO              (ADC_O_SSFIFO0 - ADC_O_SSMUX0)
#define ADC_SSFSTAT             (ADC_O_SSFSTAT0 - ADC_O_SSMUX0)

#define SEQUENCER   0


//
// Global Constants
// ================
const byte SampleQty = 255;               // number of samples  
const uint16_t buttonPin = PUSH1;         // the number of the pushbutton pin
const uint16_t ledPin =  GREEN_LED;       // the number of the LED pin
const uint16_t TriggerPin = PA_5;         // Analog Signal Trigger connected to digital pin PA_5


//
// Global Variables
// ================

uint16_t SampleTest;
uint16_t buttonState = 0;         // variable for reading the pushbutton status
uint16_t Sample[SampleQty];       // Array variable to store the value coming from the sensor
//unsigned long SampleStartTime;
uint32_t SampleStartTime;
//unsigned long SampleEndTime;
uint32_t SampleEndTime;
//unsigned long SampleDuration;
uint32_t SampleDuration;

//unsigned long faBase;
uint32_t faBase;

//
// Prototypes
// ==========
  uint16_t fast_analogInit(uint8_t pin);
  uint16_t fast_analogRead(void);


///**************************************************************************
///
///                                   Setup code
///
///**************************************************************************
void setup() {
Serial.begin(9600) ;               //Debugging initialize the serial communication:
pinMode(ledPin, OUTPUT);           // initialize the LED pin as an output:    
pinMode(buttonPin, INPUT_PULLUP);  // initialize the pushbutton pin as an input:
pinMode(TriggerPin, OUTPUT);       // initialize the Trigger pin as an output: 
Serial.println("Stellaris Fast Analog Read");
Serial.println("==========================");
Serial.println("");
Serial.println("Press SW1 to commence test");
}//end setup

///**************************************************************************
///
///                                   Loop code
///
///**************************************************************************
void loop() {
buttonState = digitalRead(buttonPin);  // read the state of the pushbutton value:
if (buttonState == LOW) {     
digitalWrite(ledPin, HIGH);            // turn LED on:
Serial.println("Initialising Stellaris Fast Analog Read");
fast_analogInit(PE_3);
Serial.println("Stellaris Fast Analog Read Initialised");
SampleStartTime = micros();
digitalWrite(TriggerPin, HIGH);        // Start the Analog Signal 
for (uint16_t i=0;i<SampleQty;i++)
 {
Sample[i] = fast_analogRead();                                  
 } 
SampleEndTime = micros();
//Dump results to serial monitor
for (uint16_t i=0;i<SampleQty;i++)
{
  Serial.println(Sample[i]);
} 
Serial.print("Number of Samples : ");
Serial.println(SampleQty);
Serial.print("Sample Starttime : ");
Serial.println(SampleStartTime);
Serial.print("Sample Endtime : ");
Serial.println(SampleEndTime);
SampleDuration = SampleEndTime - SampleStartTime;
Serial.print("Sample Array Set Duration time in microseconds  : ");
Serial.println(SampleDuration);
}// end if 
delay(1000);
digitalWrite(ledPin, LOW);  // turn LED off:
}//end loop


///**************************************************************************
///
///                                   Fast Analog Read Routine
///
///**************************************************************************
uint16_t fast_analogRead(void) {
//  #define DEBUG        



  #ifdef DEBUG
  Serial.println("1");
  #endif
    uint32_t value[8];
    #ifdef DEBUG
    Serial.println("2");
    #endif
    //unsigned long *pulBuffer = &value[0];
    uint32_t *pulBuffer = &value[0];
    #ifdef DEBUG
    Serial.println("3");
    #endif
    //unsigned long ulCount;
    uint32_t ulCount;
    #ifdef DEBUG
    Serial.println("4");
    #endif
    //unsigned long ulBase = faBase;
     uint32_t ulBase = faBase;
    #ifdef DEBUG
    Serial.println("5");
    #endif
    HWREG(ADC0_BASE + ADC_O_ISC) = 1 << SEQUENCER; //<==== Hangs on this line here
    #ifdef DEBUG
    Serial.println("6");
    #endif
    HWREG(ADC0_BASE + ADC_O_PSSI) |= ((SEQUENCER & 0xffff0000) | (1 << (SEQUENCER & 0xf)));
    #ifdef DEBUG
    Serial.println("7");
    #endif
    while (!(HWREG(ADC0_BASE + ADC_O_RIS) & (0x10000 | (1 << SEQUENCER)))) {}
    #ifdef DEBUG
    Serial.println("8");
    #endif
    HWREG(ADC0_BASE + ADC_O_ISC) = 1 << SEQUENCER;
    #ifdef DEBUG
    Serial.println("9");
    #endif
    ulBase = ADC0_BASE + (ADC_SEQ + (ADC_SEQ_STEP * SEQUENCER));
    #ifdef DEBUG
    Serial.println("10");
    #endif
    ulCount = 0;
    #ifdef DEBUG
    Serial.println("11");
    #endif
    while(!(HWREG(ulBase + ADC_SSFSTAT) & ADC_SSFSTAT0_EMPTY) && (ulCount < 8)) {
    #ifdef DEBUG
    Serial.println("12");
    #endif
    value[ulCount] = HWREG(ulBase + ADC_SSFIFO);
    #ifdef DEBUG
    Serial.println("13");
    #endif
    ulCount++;
    }
    return value[0];
}    

///**************************************************************************
///
///                                   Fast Analog Init Routine
///
///**************************************************************************
    uint16_t fast_analogInit(uint8_t pin) {
    uint8_t port = digitalPinToPort(pin);
    uint16_t value[1];
    uint32_t channel = digitalPinToADCIn(pin);
    if (pin == NOT_ON_ADC) {                    //invalid ADC pin
        return(0);
    }
    faBase = (uint32_t)portBASERegister(port);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
 //   SysCtlDelay(3);// <= New addition
    ROM_GPIOPinTypeADC((uint32_t)portBASERegister(port), digitalPinToBitMask(pin));
    ROM_ADCSequenceConfigure(ADC0_BASE, SEQUENCER, ADC_TRIGGER_PROCESSOR, 0);
    ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 0, channel | ADC_CTL_IE);
    ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 1, channel | ADC_CTL_IE);
    ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 2, channel | ADC_CTL_IE);
    ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 3, channel | ADC_CTL_IE);
    ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 4, channel | ADC_CTL_IE);
    ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 5, channel | ADC_CTL_IE);
    ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 6, channel | ADC_CTL_IE);
    ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 7, channel | ADC_CTL_IE | ADC_CTL_END);
    ROM_ADCSequenceEnable(ADC0_BASE, SEQUENCER);
    //ROM_SysCtlADCSpeedSet(SYSCTL_ADCSPEED_1MSPS);//<= Identified By L.R.A. as problem line
    //HWREG(SYSCTL_RCGC0) &= ~SYSCTL_RCGC0_ADC0SPD_M; // change if you want ADC1
    //HWREG(SYSCTL_RCGC0) |= SYSCTL_RCGC0_ADC0SPD_1M; // change for the desired speed with the macros and the ADC module
    HWREG(ADC0_BASE+0xFC0) &= ~0xF;
    HWREG(ADC0_BASE+0xFC0) |= 0x7;


    return(1);
}

Share this post


Link to post
Share on other sites

Well, just be mindful about that problem with the ADC being at 16Mhz and the system clock over that (the sysctldelay thing). Just in case in the future it comes back to bite you.

I don't think you can ever reach 1MSPS with just one ADC. You need both ADCs. In the datasheet it describes the processes, although I don't think it's completely. 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...