2020-05-20 04:11 AM
uint32_t REG_INIT[32];//// i dont think it is necessery that only for explanation
#define MainAddr ((uint64_t)0x801FEC0)
#define step 0x8
#define BiasRefInit *(uint64_t *)(MainAddr+0*step)
#define BiasRefFinal *(uint64_t *)(MainAddr+1*step)
#define PowerRecycles *(uint64_t *)(MainAddr+2*step)
#define REG_INIT[32] *(uint64_t *)(MainAddr+3*step)/// i wont to set a 32 regs range to "reg init".
2020-05-20 04:48 AM
Assuming GCC.
And many other places.
Specifying the address in the C source code is poor practice. Especially if text or rom data could be placed there. Better to create a section for it in your link command file.
The variables you place in the section may be scalars, arrays or structures.
2020-05-20 05:41 AM
In C++, you can just create variable references to those memory locations:
const uint32_t MainAddr = 0x801FEC0;
const uint32_t step = 0x08;
uint64_t & BiasRefInit = (uint64_t *) (MainAddr + 0 * step);
uint64_t & BiasRefFinal = (uint64_t *) (MainAddr + 1 * step);
uint64_t & PowerRecycles = (uint64_t *) (MainAddr + 2 * step);
uint64_t * REG_INIT = (uint64_t *) (MainAddr + 3 * step);
// for example:
BiasRefInit = 1;
BiasRefFinal = 2;
PowerRecycles = 3;
REG_INIT[0] = 4;
REG_INIT[1] = 5;
In C you have to use pointers:
const uint32_t MainAddr = 0x801FEC0;
const uint32_t step = 0x08;
uint64_t * BiasRefInitPtr = (uint64_t *) (MainAddr + 0 * step);
uint64_t * BiasRefFinalPtr = (uint64_t *) (MainAddr + 1 * step);
uint64_t * PowerRecyclesPtr = (uint64_t *) (MainAddr + 2 * step);
uint64_t * REG_INIT = (uint64_t *) (MainAddr + 3 * step);
// for example:
*BiasRefInitPtr = 1;
*BiasRefFinalPtr = 2;
*PowerRecyclesPtr = 3;
REG_INIT[0] = 4;
REG_INIT[1] = 5;
2020-05-20 05:50 AM
thank you very much, so for example if i want to set more uint64_t vars after that, do i need to skip on the next 32 addresses?
example:
uint64_t * REG_INIT = (uint64_t *) (MainAddr + 3 * step);
uint64_t * example = (uint64_t *) (MainAddr + (3+32) * step);
and one more ques,
why did u changed the pointer, i want the parameters be the content of the given address, isnt it needs to be written like the follow?
#define BiasRefInit *(uint64_t *)(MainAddr+0*step)
(C- language)
2020-05-20 05:55 AM
It is important to mention that i writing it in main.h!!
2020-05-20 06:19 AM
> so for example if i want to set more uint64_t vars after that, do i need to skip on the next 32 addresses?
A uint64_t is 8 bytes in length, so you would need to skip 32*8=128 bytes.
Some processors will require uint64_t to be aligned to 8-byte boundaries. Yours is not, so this may be an issue. Handing of uint64_t is done in software as it's not natively supported on most STM32 chips. Use uint32_t instead if you can.
> why did u changed the pointer, i want the parameters be the content of the given address, isnt it needs to be written like the follow?
Using #defines also works. I don't like to use #defines unless absolutely necessary. Your choice. I would add parenthesis to avoid potential order of operations issues.
#define BiasRefInit (*(uint64_t *)(MainAddr+0*step))
2020-05-20 08:09 AM
Do I get it correctly: you want to give pointer constants to some HW registers?
Then the point is to add step count to a uint64_t POINTER, not the address value.
(uint64_t *)(1000 + 1) points to address 1001
((uint64_t *) 1000) + 1 points to address 1008 (0ne uint64 forward from 1000).
like
#define BiasRefFinal *((uint64_t *)MainAddr)+1)
or
just change the base value to pointer
#define MainAddr ((uint64_t *)0x801FEC0)
#define BiasRefFinal *(MainAddr+1)
(I take it that the step was supposed to take care of the size of uint64_t.)
This:
#define REG_INIT[32] ...
probably doesn't do what you expect. You don't #define variables. The definitions are all (text substitution) macros.
If, what you really are after, is an array of adjacent 64-bit registers:
uint64_t *reg_init = ((uint64_t *)0x801FEC0); // 'reg_init' is pointer to uint64_t.
now 'reg_init points to the first 64-bit entity - that is reg_init[0] is the 64-bit contents of address 0x801FEC0.
reg_init[i] is the 64-bit contents of address 0x801FEC0 + i*sizeof(uint64_t).
Note that in C array[i] is a syntactic construction that is DEFINED to be *(array + i) and like for any pointer to type, pointer + integer is the same as
pointer + offset to i:th element of the size of the type.
Also array name is the pointer to the first element of the array.
*array is the same as array[0]
Whatever they say, C is pretty much based on the architecture of PDP computers.
:D
2020-05-20 02:23 PM
Why not something like:
typedef struct
{
uint64_t BiasRefInit ;
uint64_t BiasRefFinal ;
uint64_t PowerRecycles ;
uint32_t REG_INIT[32] ;
} myStruct_t ;
myStruct_t * pMyStruct = (myStruct_t *) 0x801FEC0 ;
void fn ()
{
pMyStruct->BiasRefFinal = 0 ;
}
2020-05-21 01:34 AM
No need. The REG_INIT also refers to 64-bit entities.
It was supposed to be array of 32 registers (I guess).
2020-05-21 02:15 AM
273/5000
I presented this as an alternative to using #define and to manual offset calculation based on "step" and multiplication: not easy to understand and maintain.
For the type of REG_INIT it is enough to change its type in the structure: easy and no computation.