POSQE001 feature request

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
User6793
Level 4
Level 4
Hello.

We are in need of a POSQE001_SetPosition() function, needed in order to initialize POSQE with a value read from an absolute encoder at start-up.

In the mean time, could you please advice on the best method to code this manually?

Cheers
0 Likes
4 Replies
Arno
Employee
Employee
25 replies posted 10 replies posted 5 replies posted
Hi OMR,

please have a look to the following code. It should do its job, although I did not test it. Could you please check and give feedback? Thanks a lot.

Best Regards,
Arno

status_t POSQE001_SetPosition
(
const POSQE001_HandleType* HandlePtr,
uint16_t* Position,
POSQE001_ReadRegType ReadMethod
)
{
uint32_t* PosTimerRegPtr = (uint32_t*) HandlePtr->PosCounterRegPtr[1];

status_t Status = (uint32_t)POSQE001_OPER_NOT_ALLOWED_ERROR;
DBG002_FUNCTION_ENTRY(DBG002_GID_POSQE001, POSQE001_FUNCTION_ENTRY);

if(HandlePtr->DynamicHandlePtr->AppState == POSQE001_UNINITIALIZED)
{
DBG002_ERROR(DBG002_GID_POSQE001, (uint8_t)Status, 0, (uint8_t*) NULL);
}
else
{
*PosTimerRegPtr = *Position;
Status =(uint32_t) DAVEApp_SUCCESS;
}
DBG002_FUNCTION_EXIT(DBG002_GID_POSQE001, POSQE001_FUNCTION_EXIT);
return (Status);
}
0 Likes
User6793
Level 4
Level 4
Thank you for your answer Arno.

We have tried the code, but the writing to *PosTimerRegPtr seems to have no effect.
The address of the pointer is 0x4000c270, we try to write the value of position (160) into *0x4000c270, but its value does not change (4351)

Found this:
Field Bits Type Description
TVAL [15:0] rwh Timer Value
This field contains the actual value of the timer.
A write access is only possible when the timer is
stopped.
0 [31:16] r Reserved
A read access always returns 0

Might need to figure out how to stop the timer prior to writing, and then start it again.

Tried this, did not work:
POSQE001_Stop(HandlePtr);
*PosTimerRegPtr = position;
POSQE001_Start(HandlePtr);

Tested some more:

uint32_t *TCSET = (uint32_t *)0x4000c20c;
uint32_t *TCCLR = (uint32_t *)0x4000c210;
uint32_t *TCST = (uint32_t *)0x4000c208;

*TCCLR = 1;
*PosTimerRegPtr = position;
*TCSET = 1; // setting this, clears/reloads the timer, so that value written is lost.

If I don't do the *TCSET=1; the SW reads the correct angle, but the counter is of course stuck.

Is there a way to prevent the reload after starting the timer again?

I have tested by single stepping in the debugger.
Another issue arises when running at full speed:
http://www.infineonforums.com/threads/410-Can-t-update-CCU4-timer-without-adding-nops-between-start-...
0 Likes
User6793
Level 4
Level 4
Now it is working 🙂
The way to avoid reload when restarting the timer was to reset the TC.STRM and TC.ENDM bits.
The 'quick & dirty' code then looks like this: (maybe you can clean it up Arno?)

uint32_t position;
uint32_t* PosTimerRegPtr = (uint32_t*) posQeHandle_->PosCounterRegPtr[1];
uint32_t *TCSET = (uint32_t *)0x4000c20c;
uint32_t *TCCLR = (uint32_t *)0x4000c210;
uint32_t *TCTC = (uint32_t *)0x4000c214;

*TCCLR = 1; // stop the timer
__DSB(); // flush pipeline
*PosTimerRegPtr = position; // write to TIMER register
*TCTC = 0x1000; // reset extended start/stop control bits
*TCSET = 1; // start timer again
0 Likes
User6793
Level 4
Level 4
Well, since Arno was not in a hurry, here we go:

posQeHandle_->CCUSliceConfigPtr[0]->SliceAddress->TCCLR = 1;
__DSB();
*PosTimerRegPtr = position;
posQeHandle_->CCUSliceConfigPtr[0]->SliceAddress->TC = 0x1000;
posQeHandle_->CCUSliceConfigPtr[0]->SliceAddress->TCSET = 1;
0 Likes