News:

Let's find out together what makes a PIC Tick!

Main Menu

Addressing RAM directly

Started by kcsl, Nov 03, 2024, 04:34 PM

Previous topic - Next topic

kcsl

I'm experimenting with the CAN bus module on the 18F27Q83. Why did they have to change it from the 25K83 way I'd figured out.

Anyway, now you have to store your message object directly into the CAN module RAM. There doesn't seem to be any SFRs that give access to this area - possibly because this RAM area is configurable.
I've been through the Microchip C listing for the CAN example and they use "memcpy" to copy the message object from a structure into the CAN module RAM.

We don't have anything like memcpy do we ?
Any ideas how can I write to specific RAM addresses ?
A POKE command would be handy about now.

Regards,
Joe
There's no room for optimism in software or hardware engineering.

trastikata

Quote from: kcsl on Nov 03, 2024, 04:34 PMAny ideas how can I write to specific RAM addresses ?

Declare variable At specific address and load that variable with values you want. Or declare variables or arrays and get their address to load it as pointer for some other hardware (DMA, some buffers etc).

Device = 18F27Q83
Declare Xtal = 4


Dim bArray1[256] As Word At 0x0A00  'bArray1 at start of Bank2
Dim bArray2[256] As Byte            'bArray2 not important where   
Dim bByte As Byte At 0x0F00         'bByte at start of Bank3
Dim dwTemp As Dword                 'temp variable

Main:
    Clear
    'just an example of how to address RAM
    dwTemp = AddressOf(bArray2)     'get the address of bArray2 in memory
    DMANSSAU = dwTemp.Byte0         'use that array as source for DMA
    DMANSSAH = dwTemp.Byte1
    DMANSSAL = dwTemp.Byte2
   
    For bByte = 0 To 255            'load some values
        bArray2[bByte] = bByte
    Next
End 


kcsl

Thanks for that.
I never realised you can use "AT [address]" with a variable declaration.

Joe
There's no room for optimism in software or hardware engineering.

kcsl

I have a problem.

 Dim buf[16] As Byte At dwStartAddr

I need to declare a buffer at a variable location in RAM.
I'd assumed that the above line, would create the buffer at the address stored in dwStartAddress, but I think it's creating the buffer at the address that dwStartAddr resides in RAM.

When using the CAN bus module in the 18F27Q83 (which is a nightmare) you need to be able to store your messages at addresses that are specified in certain SFRs and move around.

Is there a way of doing this ?

Regards,
Joe




There's no room for optimism in software or hardware engineering.

trastikata

Hello kcsl,

as far as I know you can't dynamically create variables in Positron at run time. So Dim buf[16] As Byte At dwStartAddr will indeed share the same starting address in RAM i.e. dwStartAddr will be the first 4 bytes of buf[].

Quote"you need to be able to store your messages at addresses that are specified in certain SFRs and move around"

I am not sure what you mean. In SFR addresses are either pre-assigned thus you can hard code your Dim buf[16] As Byte At 0x0600 or you can change the SFR pointer to your buf[16] i.e. Dim buf[16] As Byte ..... MySFR = AddressOf(buf)

Can you elaborate with an example what do you try to achieve to have better understanding of the problem.

kcsl

Attached is a screen shot of page 861 from the datasheet for the PIC18F27Q83.

This register holds the memory address where the next message is to be read or written (depending on the mode).
So as I understand it, for a message write, I need to read this register to get the 32bit memory address, then I write a buffer containing the message to that address.
Unless I've gotten the wrong end of the stick which is very possible.

Joe.

Image2.jpg
There's no room for optimism in software or hardware engineering.

trastikata

I have no idea, there's some reading to be done  :).

But at first sight looks like based on settings and some formulae you need to reserve some RAM space at design time:
Dim FifoBuffer1[nnn] as Byte

Then at runtime you set the base fifo address in some registers:
CxFIFOBA = AddressOf(FifoBuffer1)

Check the RAM address where to read or write the next message:
dwAddress = FIFOUA

I'd assume, I only briefly read the CAN help, this is the RAM address within the FIFO limits that to read or write from. So to use the buffer offset, I'd assume, it would be offset = FIFOUA - CxFIFOBA 

The to easily access that part of the RAM buffer use from FifoBuffer1[offset] to message size or something like this.

Again I only skimmed the datasheet, maybe next weekend I can look more carefully datasheets and examples online.

kcsl

The datasheet is 100 pages just for the CAN bus :(

There is an amount of RAM reserved for the CAN module which I believe is located at the end of user RAM.

I have managed to partly reverse engineer the Microchip 'C' sample program which has driven me crazy for the last few days.
(I only managed to find one programming example).

They do some things with structures and memory pointers to make the code simpler and they are proving difficult to reproduce in Positron, but not impossible... so far.
Some of their program comments are misleading which threw me for a while.

The difficulties seem to be that you can read/write multiple messages into the FIFO areas, but messages can be of different lengths so the memory map layout can change at run time.

I've managed to get a program transmitting a message from Positron which is a result, but there's a lot more work required to make it anything like complete.

PEEK and POKE commands would be useful about now :)


Joe

 
There's no room for optimism in software or hardware engineering.

RGV250

Hi,
When I first read this I thought it must be for CAN FD or something but the CAN spec is nothing special. If it were me I would just bin them and go back to the old devices which work.
It would be nice if Microchip explained why they mess things up. Perhaps it is in the name, Micro$oft seem to find a good product and make a right mess of it.

Bob

kcsl

Bob,
If I could go back, I would. This project would have been completed by now if I could have stuck with the original PIC.
That CAN module is pretty easy once you get a handle on the basics.

However, I had to change PIC as I needed a lot more RAM than was available, and this series of PIC fits the bill.
It's also slightly cheaper.

Joe



There's no room for optimism in software or hardware engineering.

SeanG_65

I could have sworn there was a PEEK & POKE command..Who knew?

Dompie

A scan of the manual no poke and no peek commands. The only way is via INDF I think

Johan

Frizie

PEEK and POKE were used briefly in SUB ENDSUB a short time before PROC ENDPROC came along, PEEK and POKE were obsolete since then.
Ohm sweet Ohm | www.picbasic.nl

top204

#13
Please remember, the "At" directive is not an official part of the compiler language, and any standard variables or arrays will overwrite it if they reach that particular address.

The Peek and Poke commands were removed from the compiler quite a few year ago, and they can be easily replaced with two simple procedures:

'--------------------------------------------------------------------------
' Read a RAM address and return the 8-bit value contained in it
' Input     : pAddr holds the RAM address to read from
' Output    : Returns the 8-bit value read from RAM
' Notes     : Note the use of the parameter variable for the return variable as well
'             In order to save a bit of RAM.

Proc Peek(pAddr As Word), pAddr.Byte0
    Result = Ptr8(pAddr)
EndProc

'--------------------------------------------------------------------------
' Write an 8-bit value to a RAM address
' Input     : pAddr holds the RAM address to write too
'           : pValue holds the 8-bit value to write to RAM
' Output    : None
' Notes     : None
'
Proc Poke(pAddr As Word, pValue As Byte)
    Ptr8(pAddr) = pValue
EndProc

They can also be added too, and made to read or write other bit sizes, for example:

'--------------------------------------------------------------------------
' Read a RAM address and return the 16-bit value contained in it
' Input     : pAddr holds the RAM address to read from
' Output    : Returns the 16-bit value read from RAM
' Notes     : Note the use of the parameter variable for the return variable as well
'             In order to save a bit of RAM.

Proc Peek16(pAddr As Word), pAddr
    Result = Ptr16(pAddr)
EndProc