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 support@ccsinfo.com

DSRPAG / DSWPAG - EDS mode in RAM for PIC24 / DSPIC33 parts

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



Joined: 14 Dec 2008
Posts: 21

View user's profile Send private message

DSRPAG / DSWPAG - EDS mode in RAM for PIC24 / DSPIC33 parts
PostPosted: Mon May 20, 2013 8:24 am     Reply with quote

Some large RAM parts such as PIC24EP and dsPIC33EP can handle (and has internal RAM well above) 32KB RAM, but these parts use a paginated RAM which requires handling the DSRPAG and DSWPAG registers.

When compiling any of these parts into any recent CCS compiler version, you get access to the first 32KB only, and apparently compiler has no support for declaring variables or accessing them in the paginated mode, therefore any address beyond 32KB is unavailable for the compiler.

Besides using ASM to interact and define variables in a manual way, does anyone has a better suggestion or prior experience on any CCS trick to do the job in C ?

TIA
Ttelmah



Joined: 11 Mar 2010
Posts: 19350

View user's profile Send private message

PostPosted: Mon May 20, 2013 8:58 am     Reply with quote

Potentially Addresmod.
Generic function that allows you to interface any form of memory and use it as if it is a variable for the compiler. Has worked in several compiler versions, but also has the habit of going faulty as CCS fiddle with something else.
There is no need to look at assembler. Remember you can access registers directly with #byte and #word.
So you'd need something like (guess only....).
Code:

#word DSRPAG=getenv("SFR:DSRPAG")
#word DSWPAG=getenv("SFR:DSWPAG")
void epage_Read(unsigned int32 addr, unsigned int8 * ram, unsigned int8 bytes)
{
   unsigned int16 page_number;
   unsigned int16 address_to_use;
   page_number=addr/0x8000;
   address_to_use=(addr & 0x7FFF) ! 0x8000; //low 15 bits with bit 15 set
   DSRPAG=page_number;
   memcpy(ram,address_to_use,bytes);
}

void epage_Write(unsigned int32 addr, unsigned int8 * ram, unsigned int bytes)
{
   unsigned int16 page_number;
   unsigned int16 address_to_use;
   page_number=addr/0x8000;
   address_to_use=(addr & 0x7FFF) ! 0x8000; //low 15 bits with bit 15 set
   DSWPAG=page_number;
   memcpy(address_to_use,ram,bytes);
}

addressmod (high_memory,epage_read,epage_write,0,0x7FFF);       

//Then you can declare variables with:
int32 high_memory test_variable;

test_variable=23;
//etc..

Now not sure if memcpy, will work with the page registers selected, or if addressmod is working in the current compiler (haven't had cause to use it recently).

Might be worth an experiment!.....

Best Wishes
arocholl



Joined: 14 Dec 2008
Posts: 21

View user's profile Send private message

PostPosted: Tue May 21, 2013 6:47 am     Reply with quote

Good input, I didn't think on Addresmod this way before your post, but more like a EEPROM or External RAM interface... Assuming it works as advertised, it could be a good workaround for some uses of upper RAM pages, albeit with some noticeable overhead for accessing it.

As I perceive it, the limitation of this approach is - except I am not interpreting the proposed functionality correctly - it will work fine to move data in and out of a given page to / from lower RAM, but hardly being any effective for storing data from RS232 or SPI directly.

I used your code template, made some corrections and gave addressmod a try with recent 4.140 compiler. Results are disappointing.

Code:

void epage_Read(unsigned int32 nAddr, unsigned int8 * pBuffer, unsigned int8 nSyze)
{
   unsigned int16 page_number;
   unsigned int16 address_to_use;
   page_number=nAddr/0x8000;
   address_to_use=(nAddr & 0x7FFF) | 0x8000; //low 15 bits with bit 15 set
   DSRPAG=page_number;
   memcpy(pBuffer,address_to_use,nSyze);
}

void epage_Write(unsigned int32 addr, unsigned int8 * ram, unsigned int bytes)
{
   unsigned int16 page_number;
   unsigned int16 address_to_use;
   page_number=addr/0x8000;
   address_to_use=(addr & 0x7FFF) | 0x8000; //low 15 bits with bit 15 set
   DSWPAG=page_number;
   memcpy(address_to_use,ram,bytes);
}

addressmod (high_memory,epage_read,epage_write,0x8000,0xFFFF);

void main()
{
    int nInd=0;
    for (nInd=0; nInd<sizeof(arrData); nInd++)
    {
        arrData[nInd]=nInd;
    }

    //Then you can declare variables with:
    int32 high_memory test_variable;

    test_variable=23;

}


The major problem comes with the simple "test_variable=23", the compiler generates complete bogus code. It considers the int32 being a 8 byte buffer, not sure why, but more importantly it calls the "read" function, rather than the "write" function.

Code:

56:                    test_variable=23;
00027E  200175     MOV #0x17, W5
000280  200006     MOV #0x0, W6
000282  B3C080     MOV #0x8, W0     <--- this is wrong
000284  B7F0D6     MOV.B WREG, nSyze
000286  280004     MOV #0x8000, W4
000288  888684     MOV W4, nAddr
00028A  EF30D2     CLR 0x10D2
00028C  2000A4     MOV #0xA, W4
00028E  8886A4     MOV W4, pBuffer
000290  020200     CALL epage_Read  <--- this is *very* wrong


Maybe with some tweaks this may end up working, somehow (e.g. reverse the function definition so writes call read on purpose, so end code is correct, etc) but this seems to be too unreliable for production code.
arocholl



Joined: 14 Dec 2008
Posts: 21

View user's profile Send private message

PostPosted: Tue May 21, 2013 7:00 am     Reply with quote

As a side note, as you may expect #locate doesn't work either. It generates code for the assigned address with no care or extra code to handle pages, just tries to go to that location with raw code, which does nothing.

Code:


int32 nVarInEDS;
#locate nVarInEDS=0x8100

...

    nVarInEDS=32;
    nVarInEDS=45;



will generate bogus code like this

Code:

50:                    nVarInEDS=32;
00023E  200204     MOV #0x20, W4
000240  781F84     MOV W4, [W15++]
000242  F98100     POP nVarInEDS
000244  200004     MOV #0x0, W4
000246  781F84     MOV W4, [W15++]
000248  F98102     POP 0x8102
arocholl



Joined: 14 Dec 2008
Posts: 21

View user's profile Send private message

PostPosted: Tue May 21, 2013 7:51 am     Reply with quote

Just for reference of anyone interested, this is the code I will end up using, short of any other higher level suggestion.

Code:


    //Required: Set write page register to the right value,
    //no need to change further for systems with less than 64KB RAM, as one page is enough
    DSWPAG=1;
    //Ideally, this should be enough for standard C assignment to work from this point on but
    //CCS compiler uses push/pop for value assignment, whereas the CPU needs a MOV to work on
    //EDS page areas, so you have no choice but assign with ASM entry like this (make sure bit 15 is 1)
    //This code below sets 7 in the byte address at 0x8100.
#asm asis
    MOV #7,W0
    MOV #0x8100,W1  //Bit 15=1, therefore DSWPAG is used, EDS address is accesible. Note this is actually address 0x0100 in page 1.
    MOV W0,[W1]

    MOV #0x7F00,W1  //Bit 15=0, therefore DSWPAG is not used, EDS address is not accesible
    MOV W0,[W1]
#endasm


Last edited by arocholl on Tue May 21, 2013 6:01 pm; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19350

View user's profile Send private message

PostPosted: Tue May 21, 2013 2:01 pm     Reply with quote

Unfortunately, addressmod, was working a few compiler versions ago, and went faulty when I last tried it. Hadn't tested with recent compilers....

Best Wishes
jeremiah



Joined: 20 Jul 2010
Posts: 1326

View user's profile Send private message

PostPosted: Tue May 21, 2013 7:44 pm     Reply with quote

When the compiler generates data lengths twice their normal size, that is normally for reading from program memory (32bits would take 64bits in program memory for these types of chips). You might pass along an example to the CCS support team (via email) and see if they can give you an idea about why it is doing that.

The example using #locate does generate correct assembly for the code written. The compiler isn't going to know enough to implement ESD automatically so it will simply implement moving a 32bit value to address 0x8100. Remember that "MOV W4, [W15++] " is the same calling PUSH with the contents of W4 for a PIC24/dsPIC33 chip.

So the steps are:
Load 0x20 into W4
PUSH W4 onto the stack
POP to nVarInEDS
Load 0x00 into W4
PUSH W4 onto the stack
POP to (nVarInEDS+2)

Which is what the assembly is doing

Which PIC are you using specifically? I was going to play around with it but couldn't figure out which PIC you were using.
arocholl



Joined: 14 Dec 2008
Posts: 21

View user's profile Send private message

PostPosted: Wed May 22, 2013 3:26 am     Reply with quote

jeremiah wrote:
When the compiler generates data lengths twice their normal size, that is normally for reading from program memory (32bits would take 64bits in program memory for these types of chips). You might pass along an example to the CCS support team (via email) and see if they can give you an idea about why it is doing that.


That may be it. I know how it works if you try to use PSV or normal FLASH memory access. My point was that if the compiler was smart enough to know you are accessing an EDS RAM area, it shouldn't access memory that way. So clearly addressmod assumes reading from FLASH only. That format will not work for EEPROM or external RAM either (where you do not need to double size in bytes) so addressmod doesn't seem to account for EEPROM access even though documentation seems to point to that in the example code.

jeremiah wrote:
The example using #locate does generate correct assembly for the code written. The compiler isn't going to know enough to implement ESD automatically so it will simply implement moving a 32bit value to address 0x8100. Remember that "MOV W4, [W15++] " is the same calling PUSH with the contents of W4 for a PIC24/dsPIC33 chip.


Right. That is my point. The compiler doesn't know, but it could. The compiler should know, for these chips, that bit 15 of the EA is 1 in this address, and based on that understand it is beyond the normal memory region accessible without EDS and therefore handle DSxPAG. But it doesn't. If you play with #locate address 0x8100, the interesting thing is the compiler doesn't generate code for a 0x8100 address, because that will actually work for a <64KB part (only one extra EDS page). However, the ASM generated code clears the bit 15 and you get a 0x0100 address - and that is SFR TMR1 - nothing to do with the intended 0x8100 address.

I am not saying #locate would be the correct way to handle EDS, but in case someone was tempted to use #locate, it doesn't work.

One could argue a simplified EDS is not too different than near and far RAM memory region, which the compiler actually handles ok (generates compact instructions for near region, and larger instructions for far region).

jeremiah wrote:
So the steps are:
Load 0x20 into W4
PUSH W4 onto the stack
POP to nVarInEDS
Load 0x00 into W4
PUSH W4 onto the stack
POP to (nVarInEDS+2)

Which is what the assembly is doing


It is, but again that is not compatible with any possible us of EDS. The EDS works with MOV only (not with push), and you need to force the bit 15 to 1 in order for the EDS to work. None of the generated CCS code is compatible with that.

jeremiah wrote:
Which PIC are you using specifically? I was going to play around with it but couldn't figure out which PIC you were using.


You can use any of the PIC24EP512xxx or DSPIC33EP512xxx parts, such as DSPIC33EP512GP806.
jeremiah



Joined: 20 Jul 2010
Posts: 1326

View user's profile Send private message

PostPosted: Wed May 22, 2013 6:19 am     Reply with quote

On the first issue: Did you send CCS support an example and tell them what isn't working? Hopefully they can fix it. Make sure you specify that both addressmod and EDS are not working correctly.

On the second issue: Yes, but the point was that CCS wasn't creating bogus assembly, it was generating correct assembly. Bogus code would indicate incorrect assembly. I agree though that they should add in support for EDS for ya. I am hoping your email from the first issue will get that ball rolling so you can get this resolved.
arocholl



Joined: 14 Dec 2008
Posts: 21

View user's profile Send private message

PostPosted: Wed May 22, 2013 6:26 am     Reply with quote

I will send this to CCS, but they will probably put it in the same queue other of my (old) requests are waiting for any attention, so not very optimistic.

In the second topic, it is still bogus code IMHO. Here is the reason: you are coding for a 0x8100 address, which is not part of the standard addressable RAM, but the ASM code generated by CCS is done as if it was. If the compiler doesn't support EDS, that is fine, then it should generate an error because the underlying MCU targeted for that assembler code will not work as expected. I would consider a "Out of valid RAM range" or the like as the valid, minimally safe approach, reported by the compiler, not silent wrong generated ASM.
jeremiah



Joined: 20 Jul 2010
Posts: 1326

View user's profile Send private message

PostPosted: Wed May 22, 2013 6:31 am     Reply with quote

If they don't respond in a day, give them a call. It's generally better if you call and use the customer service extenstion (I thnk it is 35) if you aren't getting responses. The CCS tech guys are generally pretty good when you talk with them.
miro



Joined: 15 Jan 2011
Posts: 62

View user's profile Send private message

PostPosted: Sun Jul 14, 2013 3:16 am     Reply with quote

Addressmod is quite interesting feature, the issues with it I addressed few times in this forum already.

A friend of mine escalated the issue to CCS per email (the issue with not compiling the write function) in Feb2013, they got details with an example code (they got everything they asked for), a ticket has been risen, but nothing happened.

I saw 5.009 version and still the "write" function is not being compiled, instead it points to "read" function within the code. My understanding is it is maybe 5 minutes of work for them to fix that (as it worked somewhere around 4.13x).

Maybe a native speaker may call the guys and explain verbally, when the source code, disassembly, etc. (and other files they asked for) and detail description is not enough for them Crying or Very sad

BTW, they call it a "Feature Exclusive to CCS Compiler"

PS: this has been received from them when asked on status (Feb2013, July2013):

Quote:
Your e-mail has been assigned to someone in Tech Support.
As of yet, we have not had time to further review your e-mail.
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