|
|
View previous topic :: View next topic |
Author |
Message |
Rocket
Joined: 29 Aug 2005 Posts: 27
|
Variable declaration in external memory |
Posted: Thu Feb 14, 2013 7:18 am |
|
|
I need to write a driver for the AX5043 RF ic, which has many registers which need setting, and was looking for a way to declare variables in external memory and in specific places, using something like "addressmod".
The problem I have is that the file I need to port looks like:
Code: |
/* Radio Registers, X Address Space */
SFRX(AX5043_CRCINIT0, 0x0017) /* CRC Initial Value 0 */
SFRX(AX5043_CRCINIT1, 0x0016) /* CRC Initial Value 1 */
SFRX(AX5043_CRCINIT2, 0x0015) /* CRC Initial Value 2 */
SFRX(AX5043_CRCINIT3, 0x0014) /* CRC Initial Value 3 */ |
Changing it to something like:
Code: |
int AX5043_CRCINIT0, 0x0017 /* CRC Initial Value 0 */
int AX5043_CRCINIT1, 0x0016 /* CRC Initial Value 1 */
int AX5043_CRCINIT2, 0x0015 /* CRC Initial Value 2 */
int AX5043_CRCINIT3, 0x0014 /* CRC Initial Value 3 */
|
where the 0x0017 would indicate the address in external ram, as declared with the addressmod command.
The AX5043 registers range from adress 0x0000 to 0x0FFF, and the values are all over the show.
Please advise. _________________ J.I.L. |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Thu Feb 14, 2013 9:22 am |
|
|
ehhh...
I dunno.. the way I've always done it (and is portable) is to build an internal structure set that's duplicate to the external chip. Then I set my local stuff and then send it out to the IC via read/write routines.
really, the CPU doesn't consider this external chip's memory any sort of memory of it's own. Anything done to make it look like internal memory in the PIC is just code trickery/abstraction.
Either method is going to be some amount of work -- but one is simple to understand and the other is complex.
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Thu Feb 14, 2013 12:48 pm |
|
|
It is technically possible to do this with addressmod, but it'll be very difficult to map the registers to the right locations, without using a lot of complexity. I'd suggest that just using #defines for where you want the register blocks to appear, then as bkamen says a local structure holding a duplicate of what you want to put there, is probably the simplest route.
Best Wishes |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Thu Feb 14, 2013 12:56 pm |
|
|
For example:
Code: | #define MAX7315 0x40
#define MAX7315_inputs 0x00
#define MAX7315_phase0 0x01
#define MAX7315_pconf 0x03
#define MAX7315_phase1 0x09
#define MAX7315_ginten 0x0E
#define MAX7315_config 0x0F
#define MAX7315_inten0 0x10
#define MAX7315_inten1 0x11
#define MAX7315_inten2 0x12
#define MAX7315_inten3 0x13
static struct MAX7315_REG_MAP {
unsigned int inputs;
unsigned int phase0;
unsigned int pconf;
unsigned int phase1;
unsigned int O8_intensity:4;
unsigned int global_intensity:4;
short blink_en;
short blink_flip;
short global_intensity_en;
short irq_en;
int int_as_gpo:2; // maybe set this for 0x00 (low, no blink) when error, else 0x01 = Hi-Z
short bit6;
short irq_stat; // Set this for one, all the time.
unsigned int led0:4;
unsigned int led1:4;
unsigned int led2:4;
unsigned int led3:4;
unsigned int led4:4;
unsigned int led5:4;
unsigned int led6:4;
unsigned int led7:4;
} max7315_reg;
unsigned int const MAX7315_ADDR_MAP [] = {0x00,0x01,0x03,0x09,0x0E,0x0F,0x10,0x11,0x12,0x13};
|
There's some duplication of the register map for documentation and convenience when needed...
but you can literally run that through a loop based on the byte size of the structure using the loop counter to rattle through the string const MAX7315_ADDR_MAP to get the right device register.
It's not so horrible to write out.
Every device is different though. _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
miro
Joined: 15 Jan 2011 Posts: 62
|
|
Posted: Sat Feb 16, 2013 1:19 pm |
|
|
The addressmod works such it defines the external space and functions for accessing the external space, ie.:
Code: | addressmod (CHIP, chip_rd, chip_wr, 0x00, 0xff); |
Then you may define for example:
Code: |
#type default= CHIP
unsigned int8 chip_reg[256];
#type default=
|
The main issue I see is that the last ccs version with "working" addressmod is 4.134, afaik. Even the newest 4.140 still includes a bug - the chip_wr() function is not being compiled..
PS: "working" means partially working
Last edited by miro on Sat Feb 16, 2013 1:25 pm; edited 1 time in total |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Sat Feb 16, 2013 1:23 pm |
|
|
miro wrote: | The addressmod works such it defines the external space and functions for accessing the external space, ie.:
Code: | addressmod (CHIP, chip_rd, chip_wr, 0x00, 0xff); |
Then you may define for example:
Code: |
#type default= CHIP
unsigned int8 chip_reg[256];
#type default=
|
The main issue I see is that the last ccs version with "working" addressmod is 4.134, afaik. Even the newest 4.140 has got a bug - the chip_wr() function is not being compiled..
PS: "working" means partially working |
And it's non-portable CCS specific trickery.
Just because the CODE looks all clean and neat because of these special functions doesn't mean the work isn't being done "under the hood".
I'm not saying "don't do it" -- Just be informed about what the task is at hand and then go from there.
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
miro
Joined: 15 Jan 2011 Posts: 62
|
|
Posted: Sat Feb 16, 2013 1:36 pm |
|
|
Quote: | And it's non-portable CCS specific trickery. |
CCS pages: "Part of the IEEE Embedded C standard (ISO/IEC TR 18037), addressmod allows you to create custom qualifiers to create variables in any kind of memory device. The identifier can be used with any data types, including structures, unions, arrays, and pointers."..
Frankly, if working properly it would be a great stuff to have! I do not understand the CCS people do not care much about it.. |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Sat Feb 16, 2013 1:50 pm |
|
|
miro wrote: | Quote: | And it's non-portable CCS specific trickery. |
CCS pages: "Part of the IEEE Embedded C standard (ISO/IEC TR 18037), addressmod allows you to create custom qualifiers to create variables in any kind of memory device. The identifier can be used with any data types, including structures, unions, arrays, and pointers."..
Frankly, if working properly it would be a great stuff to have! I do not understand the CCS people do not care much about it.. |
Right -- but the part where it gets sticky is those read/write functions.
If they aren't already written for you, you have to do it... and the compiler has to support it.
hiding one complexity for another. _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
miro
Joined: 15 Jan 2011 Posts: 62
|
|
Posted: Sat Feb 16, 2013 2:01 pm |
|
|
Quote: | Right -- but the part where it gets sticky is those read/write functions.
If they aren't already written for you, you have to do it... and the compiler has to support it. |
r/w functions - that is the easiest part, of course you have to write them, the framework is simple:
Code: |
void chip_rd(unsigned int32 address, unsigned int8 *dat, unsigned int nbytes);
void chip_wr(unsigned int32 address, unsigned int8 *dat, unsigned int nbytes);
|
For example a read/write to Serial SPI 256kB large FRAM:
Code: |
// read procedure for reading n bytes from the memory starting at location addr
void fram_rd(unsigned int32 address, unsigned int8 *dat, unsigned int nbytes)
{
FRAM_CS_L;
// write opcode, address
spi_x(FRAM_READ);
spi_x(address>>16);
spi_x(address>>8);
spi_x(address);
while (nbytes--) *dat++ = spi_x(0xAA);
FRAM_CS_H;
}
//write procedure for writing n bytes to the memory starting at location addr
void fram_wr(unsigned int32 address, unsigned int8 *dat, unsigned int nbytes)
{
FRAM_CS_L;
spi_x(FRAM_WREN);
FRAM_CS_H;
// write opcode, address, data
FRAM_CS_L;
spi_x(FRAM_WRITE);
spi_x(address>>16);
spi_x(address>>8);
spi_x(address);
while (nbytes--) spi_x( *dat++ );
FRAM_CS_H;
} |
And with:
Code: | addressmod (FRAM, fram_rd, fram_wr, 0x0000, 0x3ffff);
|
the compiler may access ie. 256kBytes of RAM from a pic16F84
Code: | FRAM int16 my_array[128000]; |
or
Code: | FRAM int16 my_array1[64000];
FRAM int32 my_array2[32000]; |
It works with 4.134. Tested with a pic24 and FM25H20 SPI FRAM ;)
PS: if somebody has direct access to ccs people, pls ask them to fix the bug in 4.135++ - the rd and wr functions point to rd function only.. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1346
|
|
Posted: Sat Feb 16, 2013 8:15 pm |
|
|
Just send them an email at their support email (located the top right of your forum page). That's how they take bug reports. If you have the IDE, it also has a bug report feature, but I like the support email for my own records. |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Tue Feb 26, 2013 5:07 pm |
|
|
miro wrote: |
PS: if somebody has direct access to ccs people, pls ask them to fix the bug in 4.135++ - the rd and wr functions point to rd function only.. |
sorry for the delay,
at some point, I'm going to try this with the XC compilers from Microchip -- but in a sense, you've made some of my case for keeping it simple when Compiler providers break stuff.
Frustrating.
But I'll concede it looks nice and *should* work provided the compiler follows the IEEE recommendations you mentioned above.
Cheers,
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
|
|
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
|