vineetp 0 Posted December 13, 2015 Share Posted December 13, 2015 I'm using a Tiva C series launchpad (TM4C123G) to sample analog data using an external ADC (ADC0804). The ADC is clocked at 1.4MHz. The SysCtlClockSet command was used to set clock freq to 80MHz. A square wave is being generated on a pin, with a frequency same as the sampling rate, using the code given below. So this gives us the sampling rate on an oscilloscope. For some reason the sampling rate is TOO low. It is only ~330KHz with NO command in the loop. It drops to about ~280KHz with one digitalRead and to just a few hundred Hz with a SerialPrintln(). What is causing it to run so slow and how can it be improved? #include <tm4c123ge6pm.h> #include <stdint.h> #include <stdbool.h> #include <pin_map.h> #include <sysctl.h> int db0 = PB_3; int db1 = PC_4; int db2 = PC_5; int db3 = PC_6; int db4 = PC_7; int db5 = PD_6; int db6 = PD_7; int db7 = PF_4; int cs = PB_5; int rd = PD_1; int wr = PD_0; int intr = PE_4; int out = PD_3; int a = 0; int count = 1; int b; boolean flag = 0; void setup() { SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ); //SysCtlClockSet(SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ|SYSCTL_SYSDIV_2_5); pinMode(db0, INPUT); pinMode(db1, INPUT); pinMode(db2, INPUT); pinMode(db3, INPUT); pinMode(db4, INPUT); pinMode(db5, INPUT); pinMode(db6, INPUT); pinMode(db7, INPUT); pinMode(out, OUTPUT); pinMode(cs, OUTPUT); pinMode(rd, OUTPUT); pinMode(wr, OUTPUT); pinMode(out, OUTPUT); pinMode(intr, INPUT); pinMode(db0, INPUT); pinMode(db1, INPUT); pinMode(db2, INPUT); pinMode(db3, INPUT); pinMode(db4, INPUT); pinMode(db5, INPUT); pinMode(db6, INPUT); pinMode(db7, INPUT); Serial.begin(9600); //Code of initialzation... //Step C digitalWrite(cs, LOW); delay(100); //has to be type unsigned long digitalWrite(out,HIGH); b=1; } void loop() { flag = !flag; digitalWrite(out,flag); a= digitalRead(db0); count = 1; a = 0; a = a+ digitalRead(db0)*count; count = count*2; a = a+ digitalRead(db1)*count; count = count*2; a = a+ digitalRead(db2)*count; count = count*2; a = a+ digitalRead(db3)*count; count = count*2; a = a+ digitalRead(db4)*count; count = count*2; a = a+ digitalRead(db5)*count; count = count*2; a = a+ digitalRead(db6)*count; count = count*2; a = a+ digitalRead(db7)*count; count = count*2; Serial.println(a); //Serial.println(SysCtlClockGet()); } Quote Link to post Share on other sites
L.R.A 78 Posted December 13, 2015 Share Posted December 13, 2015 How to improve? Don't use any Energia function.What sampling rate? How to do you test that if there is not a single command according to you.Serial print is really slow. Not sure how it handles just 1 variable but still.digitalRead is also really slow when compared to alternatives. Let's see the function: int digitalRead(uint8_t pin) { uint8_t bit = digitalPinToBitMask(pin); uint8_t port = digitalPinToPort(pin); uint32_t portBase = (uint32_t) portBASERegister(port); if (port == NOT_A_PORT) return LOW; if(ROM_GPIOPinRead(portBase, bit)){ return HIGH; } return LOW; } I would estimate your addition of 1 digital read (it seems you add some math too, not only the reading) takes about 43 cycles! If you want the full potential of the MCU capabilities, you have to be go lower and lower until you reach your desired performance. This would be so much faster with register programming or Tivaware. tripwire 1 Quote Link to post Share on other sites
vineetp 0 Posted December 14, 2015 Author Share Posted December 14, 2015 Thanks for the reply. The following code was used for the same effect. But the Serial.println() was returning no value on the serial monitor. So we used a DAC to convert the bits back and see the output on an oscilloscope. There was no output at all. No hardware faults were found. #include <tm4c123ge6pm.h> volatile int In = 0; // input from PF4 int cs = PA_2; int rd = PA_3; int wr = PA_4; // The above pins are connected to ADC for initialization. #define ldata (*((volatile unsigned long *)0x400053FC)) void PortB_Init(void){ volatile unsigned long delay; SYSCTL_RCGC2_R |= 0x02; // 1) activate clock for Port F delay = SYSCTL_RCGC2_R; // allow time for clock to start // GPIO_PORTB_LOCK_R = 0x4C4F434B; // 2) unlock GPIO Port F // GPIO_PORTB_CR_R = 0x1F; // allow changes to PF4-0 // only PF0 needs to be unlocked, other bits can't be locked GPIO_PORTB_AMSEL_R &= 0x00; // 3) disable analog on PF GPIO_PORTB_PCTL_R &= 0x00; // 4) PCTL GPIO on PF4-0 GPIO_PORTB_DIR_R &= 0x00; // 5) PF4,PF0 in, PF3-1 out GPIO_PORTB_AFSEL_R &= 0x00; // 6) disable alt funct on PF7-0 //GPIO_PORTB_PUR_R = 0x11; // enable pull-up on PF0 and PF4 GPIO_PORTB_DEN_R |= 0xFF; // 7) enable digital I/O on PF4-0void setup() { // put your setup code here, to run once: } void PortA_Init(void){ volatile unsigned long delay; SYSCTL_RCGC2_R |= 0x01; // 1) activate clock for Port A delay = SYSCTL_RCGC2_R; // allow time for clock to start // 2) no need to unlock PA2 GPIO_PORTA_PCTL_R &= ~0x00000F00; // 3) regular GPIO GPIO_PORTA_AMSEL_R &= ~0x1C; // 4) disable analog function on PA2 GPIO_PORTA_DIR_R |= 0x1C; // 5) set direction to output GPIO_PORTA_AFSEL_R &= ~0x1C; // 6) regular port function GPIO_PORTA_DEN_R |= 0x1C; // 7) enable digital port PA2 GPIO_PORTA_DATA_R &= 0xEF; // wr GPIO_PORTA_DATA_R |= 0x10; // wr GPIO_PORTA_DATA_R |= 0x08; //rd GPIO_PORTA_DATA_R &= 0x07; //rd } void setup() { Serial.begin(9600); PortB_Init(); digitalWrite(cs, LOW); delay(1000); } void loop() { PortA_Init(); //Initialization commands in the loop. delayMicroseconds(10); } Quote Link to post Share on other sites
L.R.A 78 Posted December 14, 2015 Share Posted December 14, 2015 That's because you are constantly initializing it, probably, maybe.Still, you should try to use Tivaware, for at least the initialization, in the future. It will allow you for faster coding and it's easier to help you.Why not make a simpler test first? And slower so you can analyze it better. Quote Link to post Share on other sites
igor 163 Posted December 16, 2015 Share Posted December 16, 2015 Once you get this going if you need to make it even faster the Tiva C has some nice features for reading/writing GPIO pins - if you read/write from an address that is at an offset from the base port address the offset acts as a mask - so you don't have to suffer the overhead of read/modify/write, or have to mask the read value. See the Tiva C documentation. I posted some macros that help with this someplace on 43oh, (think it is in the thread about porting arduino libraries) but don't have time now to find the post. Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.