Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 22:37 29 Apr 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : CFuncGen V1.21 : Testers Required Please

Author Message
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 03:58pm 26 Nov 2014
Copy link to clipboard 
Print this post

Hi

A New Version of CFuncGen has been released which eliminates some bugs highlighted by DATA CFunctions including elimination of the 'NOP' bug, ie you should now be able to safely use multiple NOPs in delay loops.

2014-11-27_014425_CFuncGen_V1.0.21.zip

This new CFuncGen is attached to this post. Please unzip, and copy CFuncGen.exe into the directory where you currently have CFuncGen installed. I would really appreciate if you could please test this version of CFuncGen before I make it available for general consumption.

Using CFunctions to hold Constant Data Arrays

Peter Mather aka @matherp on the Back Shed, has been very active producing all kinds of useful code, eg the OLED driver library. As part of Peter's activities, he wanted to use the C construct

const vartype varname[]={value1,value2,value3.... valueN};

Unfortunately due to the way xc32/gcc generates code for this construct when more than 4 values are involved, this 'C' construct is rendered unusable for MMBasic CFunctions purposes when used INSIDE a 'C' function. However, there is a way to take advantage of CFunctions to store data, the 'DATA CFunction, and then using PEEK(CFUNADDR CfuncName) to access the individual data items in an almost array like fashion within your MMBasic program.

Formatting the Data for a DATA CFunction.
This turns out to be surprisingly very easy.

Create a new MPLabX project. Add a new C Main File, delete the template provided and type in


void main(){}


XC32/gcc expects to find a function main() so this keeps the compiler from complaining.

Next above main(), declare the Const Array in the usual 'C' manner, in the case of this tutorial;


const long long font[] ={0x0000000000,0x3EB54F5B3E00,0x3E6B4F6B3E00,0x1C3E7C3E1C00,
0x1C577D571C00,0x1C5E7F5E1C00,0x183C180000,
0xFFE7C3E7FF00,0x1824180000,0xFFE7DBE7FF00,0x30483A060E00,0x 262979292600,0x407F05050700,0x407F05253F00,0x5A3CE73C5A00,
0x7F3E1C1C0800,0x081C1C3E7F00,0x14227F221400,0x5F5F005F5F00, 0x06097F017F00,0x6689956A00,0x606060606000,0x94A2FFA29400,
0x08047E040800,0x10207E201000,0x08082A1C0800,0x081C2A080800, 0x1E1010101000,0x0C1E0C1E0C00,0x30383E383000,0x060E3E0E0600,
0x0000000000,0x005F000000,0x0700070000,0x147F147F1400,0x242A 7F2A1200,0x231308646200,0x364956205000,0x0807030000,
0x1C22410000,0x41221C0000,0x2A1C7F1C2A00,0x08083E080800,0x80 70300000,0x080808080800,0x0060600000,0x201008040200,
0x3E5149453E00,0x427F400000,0x724949494600,0x2141494D3300,0x 1814127F1000,0x274545453900,0x3C4A49493100,0x412111090700,
0x364949493600,0x464949291E00,0x0014000000,0x4034000000,0x08 14224100,0x141414141400,0x4122140800,0x020159090600};


Click the Blue Hammer to build the C code. Start up CFuncGen, and select the .ELF file generated by the Build you've just executed. Next check 'Show All Funcs' and look for 'font' in the 'Functions Found' pane. Check the 'font' function, and click Make CFunction(s). CfuncGen will generate a CFunction called font.

In your MMBasic program, use Ctrl+V to paste in the 'font' DATA CFunction

'
'K:\Programming\PICProgramming\Micromite\DataCFunction.X\dis t\default\production\font.bas
'
'DATA CFunction:font 2014-11-27 01:52:45 CFuncGen Ver 1.0.21 by user=Peter
'
CFunction font
00000000
00000000 00000000
4f5b3e00 00003e5b 4f6b3e00 00003e6b 7c3e1c00 00001c3e 7d571c00 00001c57
7f5e1c00 00001c5e 3c180000 00000018 c3e7ff00 0000ffe7 24180000 00000018
dbe7ff00 0000ffe7 3a060e00 00003048 79292600 00002629 05050700 0000407f
05253f00 0000407f e73c5a00 00005a3c 1c1c0800 00007f3e 1c3e7f00 0000081c
7f221400 00001422 005f5f00 00005f5f 7f017f00 00000609 89956a00 00000066
60606000 00006060 ffa29400 000094a2 7e040800 00000804 7e201000 00001020
2a1c0800 00000808 2a080800 0000081c 10101000 00001e10 0c1e0c00 00000c1e
3e383000 00003038 3e0e0600 0000060e 5f000000 00000000 00070000 00000007
147f1400 0000147f 7f2a1200 0000242a 08646200 00002313 56205000 00003649
07030000 00000008 22410000 0000001c 221c0000 00000041 7f1c2a00 00002a1c
3e080800 00000808 70300000 00000080 08080800 00000808 60600000 00000000
08040200 00002010 49453e00 00003e51 7f400000 00000042 49494600 00007249
494d3300 00002141 127f1000 00001814 45453900 00002745 49493100 00003c4a
11090700 00004121 49493600 00003649 49291e00 00004649 14000000 00000000
34000000 00000040 14224100 00000008 14141400 00001414 22140800 00000041
59090600 00000201
End CFunction


This DATA CFunction contains NO executable code, it is 100% pure data. Notice that the data is stored in Little Endian form, ie 0x3EB54F5B3E00 has been stored as two 32bit words, 4f5b3e00 00003e5b.

Using the DATA CFunction
To access the data in this DATA CFunction, use the PEEK(CFUNADDR CFuncName) function. Here is a code fragment which shows how to load the 32 bit data items into a 64 bit array.
OPTION EXPLICIT

DIM AddrOfFont AS Integer
AddrOfFont=PEEK(CFunAddr FONT)

DIM I AS integer
DIM FontArray(124) AS integer
DIM J AS Integer
J=0

'NB the Data in the CFunction is in Little Endian Form
FOR I=AddrOfFont TO AddrOfFont + 496 STEP 8
FontArray(J) = PEEK(WORD I) + (PEEK(WORD I+4)<<32)
J=J+1
NEXT I

FOR I= 0 TO 61
PRINT HEX$(FontArray(I),16);" ";
IF (I+1) MOD 8 = 0 THEN PRINT
NEXT I

END

and here is a CFunction to do the same thing, only much faster !
long long loadarray(long long *src_m, long long dest[], int *count){
int i;
int j=0;

//Pointer to lolng vars
long *src;
src= *src_m;
for(i=0;i<*count;i+=2){
dest[j]=src[i+1];
dest[j]<<=32;
dest[j++]|= src;
}
return j;
}

'Call loadarray from MMBasic as follows

DIM AddrOfFont AS Integer
AddrOfFont=PEEK(CFunAddr FONT)

DIM FontArray(124) AS integer
DIM Result AS integer

Result=loadarray(AddrOfFont,FontArray(),124)

DIM I AS integer

FOR I= 0 TO 61
PRINT HEX$(FontArray(I),16);" ";
IF (I+1) MOD 8 = 0 THEN PRINT
NEXT I

You don't need to load the data into an MMBasic array to use it, you can directly access elements in the DATA CFunction using an MMBasic function such as
FUNCTION GetElement%(AddrOfCFunc%, Index%)

'8 bytes per element
index%=index%<<3

GetElement%=PEEK(WORD AddrOfCFunc%+Index%) + (PEEK(WORD AddrOfCFunc%+Index%+4)<<32)

END FUNCTION

which returns a single 64 bit element from the DATA CFunction, eg
DIM AddrOfFont AS Integer
OPTION EXPLICIT

DIM AddrOfFont AS Integer
AddrOfFont=PEEK(CFunAddr FONT)

'Get value of FONT[3]
PRINT HEX$(GetElement%(AddrOfFont,3),16)

END

which when run will display
> RUN
00001C3E7C3E1C00
>

which is the 3rd element from const long long font[]

Things to remember.
1) DATA CFunctions always starts with a dummy 32 bit offset and it must be 00000000.

2) The DATA CFunction items must be 32 bit words, formatted precisely as 8 AsciiHex digits, without any &H prefix, and separated by at least a single space. This formatting will be automatically carried out by CFuncGen, but if you use other methods such as EXCEL, then it is vital to ensure that the 32bit words in the CFunction are correctly formatted.

3) PEEK function(s) work on byte boundaries, so to access the Nth 32 bit element, you need to multiply the element index by 4 to calculate the actual offset to be added to the CFunction's base address to arrive at the physical address of the 32 bit word .

4) The address used in a PEEK (WORD Addr%) function must lie on a 32 bit boundary, ie Addr MOD 4 must be 0 otherwise you will generate a bus exception which will usually reset your uMite.

5) You can use PEEK(BYTE Addr%) to treat the items in a DATA CFunction as a byte array, but remember the data is stored in LITTLE ENDIAN format.

6) You cannot POKE values into a DATA CFunction because the CFunction lies in Flash.

Anyway, I hope this explanation of how to use CFunctions to store CONSTANT data will prove useful. This may also provide a sort of 'Named DATA' statement as requested by others on TBS.

Thanks are due to Peter Mather for asking the original question which prompted the investigation and subsequent discovery of this approach of using CFunctions as a means of holding Constant data.

The CFunction Tutorial document will be updated with this tutorial.

Peter
The only Konstant is Change
 
plasma
Guru

Joined: 08/04/2012
Location: Germany
Posts: 437
Posted: 03:33am 28 Nov 2014
Copy link to clipboard 
Print this post

Hi Peter,

Unfortunately my laptop is crashed since some days.
Bought a new one but no time until sunday :(
I have restored the most source , also the led things for odbc.
 
plasma
Guru

Joined: 08/04/2012
Location: Germany
Posts: 437
Posted: 03:35am 28 Nov 2014
Copy link to clipboard 
Print this post

And can you create a full setup for ?
If you have problems like me you need to
Search the first install and the threads are long.
Thx for patience.
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 05:32am 28 Nov 2014
Copy link to clipboard 
Print this post

Hi Plasma

Sorry to hear the bad news, a right pain even with backups available.

The original full install is available from http://www.g8jcf.dyndns.org/mmbasicmkii/CFuncGen.msi, install that first then copy in the new CFuncGen.exe

Also, I will create a full setup.exe over the next few days.

Good luck

Peter
The only Konstant is Change
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024