CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

function execution time.

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
beaker404



Joined: 24 Jul 2012
Posts: 163

View user's profile Send private message

function execution time.
PostPosted: Fri May 31, 2019 1:35 pm     Reply with quote

Touched on this in an earlier post, continuing on here,
using a TI ADS8584S 16 bit ADC in parallel data mode, so using the following function to convert the outputs to digital values:

datasheet: http://www.ti.com/lit/ds/symlink/ads8584s.pdf
Code:

signed int16 ADS8584S_BUILD_CHANNEL_VALUE() {

signed int16 value=0;

//output_high(LED_BLINK);
if(input(ADC_D15) == 1) {      // 32768

   bit_set(value,15);
   
}

if(input(ADC_D14) == 1) {

   bit_set(value,14);
   
}

if(input(ADC_D13) == 1) {

   bit_set(value,13);
   
}

if(input(ADC_D12) == 1) {

   bit_set(value,12);
   
}

if(input(ADC_D11) == 1) {

   //value = value + 2048;
    bit_set(value,11);
    //value = value << 1;
}

if(input(ADC_D10) == 1) {

   bit_set(value,10);
   
}

if(input(ADC_D9) == 1) {

   bit_set(value,9);
   
}

if(input(ADC_D8) == 1) {

   bit_set(value,8);
   
}

if(input(ADC_D7) == 1) {

   bit_set(value,7);
   
}

if(input(ADC_D6) == 1) {

   bit_set(value,6);
   
}

if(input(ADC_D5) == 1) {

   bit_set(value,5);
   
}

if(input(ADC_D4) == 1) {

   bit_set(value,4);
   
}

if(input(ADC_D3) == 1) {

   bit_set(value,3);
   
}

if(input(ADC_D2) == 1) {

   bit_set(value,2);
   
}

if(input(ADC_D1) == 1) {

   bit_set(value,1);
   
}

if(input(ADC_D0) == 1) {

   bit_set(value,0);
   
}

return value;

}  // end BUILD_CHANNEL_VALUE()


The problem is, at 64MHz clock speed, this function takes 15uS to execute. Time I do not have. Is there a way to speed it up or do differently? I have configured the inputs as FAST_IO.

Code:

#USE FAST_IO(E)
SET_TRIS_E(0XFF);                  //All of Port E is FAST IO inputs.

#USE FAST_IO(F)
SET_TRIS_F(0XFF);

#USE FAST_IO(H)
SET_TRIS_H(0X00);

#USE FAST_IO(J)
SET_TRIS_J(0X00);

#USE FAST_IO(D)
SET_TRIS_D(0X4C);

shows the way I have all of my IO set up as FAST_IO.

Code:

#DEFINE      ADC_D0         PIN_E0   // LSb
#DEFINE      ADC_D1         PIN_E1
#DEFINE      ADC_D2         PIN_E2
#DEFINE      ADC_D3         PIN_E3
#DEFINE      ADC_D4         PIN_E4
#DEFINE      ADC_D5         PIN_E5
#DEFINE      ADC_D6         PIN_E6
#DEFINE      ADC_D7         PIN_E7
#DEFINE      ADC_D8          PIN_H6
#DEFINE      ADC_D9         PIN_H7
#DEFINE      ADC_D10         PIN_F2
#DEFINE      ADC_D11         PIN_F3
#DEFINE      ADC_D12         PIN_F4
#DEFINE      ADC_D13         PIN_F5
#DEFINE      ADC_D14         PIN_F6
#DEFINE      ADC_D15         PIN_F7   // MSb

shows what port pins on the PIC I am using for data lines.

Code:



#device PIC18f87k22
#include <18F87K22.h>

#fuses HSH, NOWDT, PUT, NOBROWNOUT, NOMCLR
#use delay(crystal=16M, clock=64M)
#use rs232(UART1, baud=57600, STREAM=SERIAL, errors)

above is how the PIC is set up.
using the UART1 vary rarely so it is not figured in my loop time.

any ideas or is it just the 8 bit core showing me down?

18F87K22 running at 64MHz
CCS 5.061
MPLAB 8.91
Windows 10
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Fri May 31, 2019 2:07 pm     Reply with quote

Maybe instead of testing each individual pin and assigning each one individually, grab the whole port and assign it right to value. That way you are checking 3 ports rather than doing checking 16 pins. It might be faster but I don't know...

Code:
value = 0;
value |= input_e();
value |= (input_h() >> 6) << 8;
value |= (input_f() >> 2) << 10;


I don't know if my bitwise math is right, but try something like this.
gaugeguy



Joined: 05 Apr 2011
Posts: 303

View user's profile Send private message

PostPosted: Fri May 31, 2019 2:09 pm     Reply with quote

Just put this together quick, but should be correct.

value = make16(input_f(),input_e());
bit_clear(value,8);
bit_clear(value,9);
if(input(PIN_H6)) bit_set(value,8);
if(input(PIN_H7)) bit_set(value,9);
beaker404



Joined: 24 Jul 2012
Posts: 163

View user's profile Send private message

PostPosted: Fri May 31, 2019 2:17 pm     Reply with quote

Thanks all, Gaugeguy, pasted your code suggestion and it helped.
my execute time went down and decreased my acquisition loop time.
I was at 40KHz, now up to 71KHz.

still would like to get some more speed though.

one problem I think is doing the signed math, no way out of that right now.
also, if I average any data I have to sum with a signed INT32 so I suspect that is expensive as well.
Ttelmah



Joined: 11 Mar 2010
Posts: 19549

View user's profile Send private message

PostPosted: Fri May 31, 2019 2:26 pm     Reply with quote

64Mhz=16MIPS.

15uSec is then just 240 instruction times.

Looking at your posted code, it should not take this long.

A quick test shows it doesn't. Just compiled the code. Put it into a chip at 64Mhz, and pulsed a line high before calling the routine and low after the
return.
4.5uSec between the line changing.

Sounds to me as if you perhaps have not actually got the PLL enabled
so the chip is only running at 16Mhz, not 64....
beaker404



Joined: 24 Jul 2012
Posts: 163

View user's profile Send private message

PostPosted: Fri May 31, 2019 2:29 pm     Reply with quote

Code:

#fuses HSH, NOWDT, PUT, NOBROWNOUT, NOMCLR
#use delay(crystal=16M, clock=64M)


I was thinking the above code let me run at 64MHz. Is there additional code to set the PLL?

I am using a 16MHz crystal and setting my clock to 64MHz.
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Fri May 31, 2019 8:13 pm     Reply with quote

According to the datasheet (Section 3.1):
The PLL is enabled by setting the PLLCFG bit (CON-FIG1H<4>) or the PLLEN bit (OSCTUNE<6>).

It looks like you will need to explicitly enable PLL. Both PLLEN and PLLCFG are disabled by default.
Ttelmah



Joined: 11 Mar 2010
Posts: 19549

View user's profile Send private message

PostPosted: Sat Jun 01, 2019 1:39 am     Reply with quote

OK. You definitely seem to be 'off' by a factor of about 4. The question is
'why'?.

I am testing with:
Code:

   signed int16 temp;
   SET_TRIS_E(0XFF); 
   SET_TRIS_F(0XFF);
   SET_TRIS_H(0X00);
   SET_TRIS_D(0X4C);
   SET_TRIS_J(0X00);   
   output_high(PIN_A0); //diagnostic
   temp=ADS8584S_BUILD_CHANNEL_VALUE();
   output_low(PIN_A0); //second marker


And with a logic analyser, rather than the scope (more accurate), it gives
4.4uSec between the edges on the pulse.

Now tested with your compiler, and with your fuses:
Code:

#include <18F87K22.h>

#fuses HSH, NOWDT, PUT, NOBROWNOUT, NOMCLR, NOXINST
#use delay(crystal=16M, clock=64M)
#use rs232(UART1, baud=57600, STREAM=SERIAL, errors)

The compiler is correctly setting the PLLEN fuse:
Code:

Configuration Fuses:
   Word  1: D215   VREGSLEEP INTRC_HP SOSC_DIG NOXINST HSH PLLEN FCMEN IESO
   Word  2: 7C78   PUT NOBROWNOUT BORV18 ZPBORM NOWDT WDT1048576
   Word  3: 0BF9   RTCOSC_T1 EXTADDRSFT ABW8 BW16 NOWAIT CCP2C1 ECCPE MSSPMSK7 NOMCLR
   Word  4: 0091   STVREN BBSIZ2K NODEBUG
   Word  5: C0FF   NOPROTECT NOCPB NOCPD
   Word  6: E0FF   NOWRT NOWRTC NOWRTB NOWRTD
   Word  7: 40FF   NOEBTR NOEBTRB


If your serial is working, then it has to be running at 64MHz.

How are you measuring your 15uSec figure?.

The routine codes as:
Code:

.................... signed int16 ADS8584S_BUILD_CHANNEL_VALUE(void) {
00004:  CLRF   08
00006:  CLRF   07
.................... 
.................... signed int16 value=0;
.................... 
.................... 
.................... 
.................... //output_high(LED_BLINK);
.................... if(input(ADC_D15) == 1) {      // 32768
00008:  BTFSS  F85.7
0000A:  BRA    000E
.................... 
....................    bit_set(value,15);
0000C:  BSF    08.7
....................     
.................... }
.................... 
.................... if(input(ADC_D14) == 1) {
0000E:  BTFSS  F85.6
00010:  BRA    0014
.................... 
....................    bit_set(value,14);
00012:  BSF    08.6
....................     
.................... }
.................... 
.................... if(input(ADC_D13) == 1) {
00014:  BTFSS  F85.5
00016:  BRA    001A
.................... 
....................    bit_set(value,13);
00018:  BSF    08.5
....................     
.................... }
.................... 
.................... if(input(ADC_D12) == 1) {
0001A:  BTFSS  F85.4
0001C:  BRA    0020
.................... 
....................    bit_set(value,12);
0001E:  BSF    08.4
....................     
.................... }
.................... 
.................... if(input(ADC_D11) == 1) {
00020:  BTFSS  F85.3
00022:  BRA    0026
.................... 
....................    //value = value + 2048;
....................     bit_set(value,11);
00024:  BSF    08.3
....................     //value = value << 1;
.................... }
.................... 
.................... if(input(ADC_D10) == 1) {
00026:  BTFSS  F85.2
00028:  BRA    002C
.................... 
....................    bit_set(value,10);
0002A:  BSF    08.2
....................     
.................... }
.................... 
.................... if(input(ADC_D9) == 1) {
0002C:  BTFSS  F87.7
0002E:  BRA    0032
.................... 
....................    bit_set(value,9);
00030:  BSF    08.1
....................     
.................... }
.................... 
.................... if(input(ADC_D8) == 1) {
00032:  BTFSS  F87.6
00034:  BRA    0038
.................... 
....................    bit_set(value,8);
00036:  BSF    08.0
....................     
.................... }
.................... 
.................... if(input(ADC_D7) == 1) {
00038:  BTFSS  F84.7
0003A:  BRA    003E
.................... 
....................    bit_set(value,7);
0003C:  BSF    07.7
....................     
.................... }
.................... 
.................... if(input(ADC_D6) == 1) {
0003E:  BTFSS  F84.6
00040:  BRA    0044
.................... 
....................    bit_set(value,6);
00042:  BSF    07.6
....................     
.................... }
.................... 
.................... if(input(ADC_D5) == 1) {
00044:  BTFSS  F84.5
00046:  BRA    004A
.................... 
....................    bit_set(value,5);
00048:  BSF    07.5
....................     
.................... }
.................... 
.................... if(input(ADC_D4) == 1) {
0004A:  BTFSS  F84.4
0004C:  BRA    0050
.................... 
....................    bit_set(value,4);
0004E:  BSF    07.4
....................     
.................... }
.................... 
.................... if(input(ADC_D3) == 1) {
00050:  BTFSS  F84.3
00052:  BRA    0056
.................... 
....................    bit_set(value,3);
00054:  BSF    07.3
....................     
.................... }
.................... 
.................... if(input(ADC_D2) == 1) {
00056:  BTFSS  F84.2
00058:  BRA    005C
.................... 
....................    bit_set(value,2);
0005A:  BSF    07.2
....................     
.................... }
.................... 
.................... if(input(ADC_D1) == 1) {
0005C:  BTFSS  F84.1
0005E:  BRA    0062
.................... 
....................    bit_set(value,1);
00060:  BSF    07.1
....................     
.................... }
.................... 
.................... if(input(ADC_D0) == 1) {
00062:  BTFSS  F84.0
00064:  BRA    0068
.................... 
....................    bit_set(value,0);
00066:  BSF    07.0
....................     
.................... }
.................... 
.................... return value;
00068:  MOVFF  07,01
0006C:  MOVFF  08,02
00070:  GOTO   00C2 (RETURN)
.................... }


Which is just 53 instructions. Allowing for the 16 BTFS instructions (which
take two machine cycles), we have 69 instruction times which at 16MIPS
is 4.3125uSec. Spot on.

So how are you measuring the 15uSec?.
beaker404



Joined: 24 Jul 2012
Posts: 163

View user's profile Send private message

PostPosted: Sat Jun 01, 2019 6:10 am     Reply with quote

Well my mistake, I call this function four times, once per channel. I am using a scope to time it. Y'all's calculations are correct, factor of four off due to where I put my pin toggle, around ALL four calls.
Pic is running 64MHz and my serial does work so sorry for the confusion.
Ttelmah



Joined: 11 Mar 2010
Posts: 19549

View user's profile Send private message

PostPosted: Sat Jun 01, 2019 7:39 am     Reply with quote

Calling it four times rather explains things...
Well, as you can see, it is just 53 instructions. Won't be faster on a 16bit
processor (nothing here uses things like 16bit arithmetic). Only thing
that will make it faster is clock rate. Normal DsPIC's have versions going
to 70MIPS.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group