Precise timing needed (ex. for IR decoding)

piotrva
Posts: 9
Joined: Mon Jan 05, 2015 7:45 am

Precise timing needed (ex. for IR decoding)

Postby piotrva » Sat Feb 14, 2015 6:52 am

Dear Espressif,

The os_timer has a resolution of one ms - it is too much for more precise operations, like IR signal (RC5 etc.) decoding.
Is there any way to get an interrupt at 50us resolution or to get a tick count at 50us resolution?

Now I am to design an IR signal repeater (aka universal IR pilot controlled by network) and I do not want to use any extra components (ex. microcnotroller, external timer).

Kind regards
Peter

jcmvbkbc
Posts: 13
Joined: Fri Oct 24, 2014 7:27 pm

Re: Precise timing needed (ex. for IR decoding)

Postby jcmvbkbc » Sat Feb 14, 2015 8:48 pm

piotrva wrote:Is there any way to get an interrupt at 50us resolution or to get a tick count at 50us resolution?

You can read CCOUNT special register. It increments every clock tick, i.e. every 12.5ns with 80MHz clock.
You can read it with the following function:

Code: Select all

static inline unsigned get_ccount(void)
{
        unsigned r;
        asm volatile ("rsr %0, ccount" : "=r"(r));
        return r;
}

piotrva
Posts: 9
Joined: Mon Jan 05, 2015 7:45 am

Re: Precise timing needed (ex. for IR decoding)

Postby piotrva » Sat Feb 14, 2015 11:40 pm

Thank you for the answer - it can be a kind of workaround - of course faster timer interrupt would be better, but maybe I will manage to capture IR data using this data & GPIO interrupt & timer interrupt as idle guard.

costaud
Posts: 138
Joined: Fri Oct 24, 2014 7:40 pm

Re: Precise timing needed (ex. for IR decoding)

Postby costaud » Sun Feb 15, 2015 11:43 am

piotrva wrote:Thank you for the answer - it can be a kind of workaround - of course faster timer interrupt would be better, but maybe I will manage to capture IR data using this data & GPIO interrupt & timer interrupt as idle guard.


uint32 system_get_time(void); CAN provide a relative time count in us. Use it to get the expire between two gpio interrupt .

piotrva
Posts: 9
Joined: Mon Jan 05, 2015 7:45 am

Re: Precise timing needed (ex. for IR decoding)

Postby piotrva » Sun Feb 15, 2015 6:35 pm

Also found something interesting in osapi.h:

Code: Select all

#ifdef USE_US_TIMER
#define os_timer_arm_us(a, b, c) ets_timer_arm_new(a, b, c, 0)
#endif
#define os_timer_arm(a, b, c) ets_timer_arm_new(a, b, c, 1)

Will test it.

piotrva
Posts: 9
Joined: Mon Jan 05, 2015 7:45 am

Re: Precise timing needed (ex. for IR decoding)

Postby piotrva » Sun Feb 15, 2015 10:18 pm

There is no difference between these functions - in both cases I got the same period.
EDIT:
Finally I decided to use STM32F05x as a IR controller - the ESP's PWM cannot achieve 26/38/40kHz and as I do not want to do it with os_delay_us() i will use STM32 as a slave SPI.

Maybe in next SDK's release there will be an option to generate interrupts at us resolution.

delong_z
Posts: 11
Joined: Fri Jan 23, 2015 4:11 pm

Re: Precise timing needed (ex. for IR decoding)

Postby delong_z » Thu Mar 05, 2015 5:15 pm

We need TIMER API

User avatar
rudi
Posts: 197
Joined: Fri Oct 24, 2014 7:55 pm

Re: Precise timing needed (ex. for IR decoding)

Postby rudi » Thu Mar 05, 2015 10:42 pm

jcmvbkbc wrote:
piotrva wrote:Is there any way to get an interrupt at 50us resolution or to get a tick count at 50us resolution?

You can read CCOUNT special register. It increments every clock tick, i.e. every 12.5ns with 80MHz clock.
You can read it with the following function:

Code: Select all

static inline unsigned get_ccount(void)
{
        unsigned r;
        asm volatile ("rsr %0, ccount" : "=r"(r));
        return r;
}


yes, played last time with this,
http://www.mikrocontroller.net/topic/358654#new

@jcmvbkbc
do you know how much / when overflow ( register bit ) can read , too?
have me a interupt for this?
can we trigger this?
:)



Code: Select all


..
static inline unsigned get_ccount(void);
..



static inline unsigned get_ccount(void)
{
        unsigned r;
        asm volatile ("rsr %0, ccount" : "=r"(r));
        return r;
}



void user_init(void)

{

while(1)

{

char ticks1 [32];
char ticks2 [32];

unsigned tick1;
unsigned tick2;
unsigned tickdiff;


tick1 = get_ccount();       // Spezial Register CCOUNT call and save
tick2 = get_ccount();       // Spezial Register CCOUNT call and save
tickdiff = tick2 - tick1;   // how much ticks was used

// 1. Register CCOUNT formated transfer to Variable
os_sprintf(ticks1, "%lu", tick1);
// 2. Register CCOUNT formated transfer to Variable + Diff Value
os_sprintf(ticks2, "%lu %lu", tick2, tickdiff);


// ich hab neben dem OLED am SPI auch ein MCP23S17 über SPI am ESP8266
// und betreibe ein einfaches 16 Zeichen x 2 Display daran
// daher ganz simple LCD Ausgabe anstatt Uart

// i have used a MCP23S17 ( SPI Portexpander ) with ESP8266 and use a 8bit LCD for Display
// LCD output for ticks, uart0 for Debug prints
//

lcdCmd(clearDisplay);       // LCD Command Clear Display
lcdGoto(0);                 // LCD Command Go Postion 0
lcdWriteString(ticks1);     // LCD Print Register CCOUNT Total Ticks
lcdGoto(0x40);              // LCD Command Go Postion 0x40 (second row)
lcdWriteString(ticks2);     // LCD Print Register CCOUNT total Ticks

os_delay_us(10 *1000*1000); // Pause : for me to read value at LCD

lcdCmd(ClearDisplay);       // LCD Command Clear Display


} // while
} // user_init








little playing how good optimize compiler..

Code: Select all


..
tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
os_delay_us(1);
tick2 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht
..

// tickdiff 122




..

Code: Select all



..

tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
os_delay_us(2);
tick2 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht

..

//tickdiff 194





makes fun

Code: Select all


..

tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
os_delay_us(1);
os_delay_us(1);
tick2 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht

..

// tickdiff 243





1 Mikrosekunden [µs] = 1 000 Nanosekunden [ns]
http://www.einheiten-umrechnen.de/einheiten-rechne...

test 1
one delay 1µs between = 122 ticks
122 ticks zu je 12.5 ns = 1525 µs

./. + 525 µs


test 2
one delay 2µs between = 194 ticks
144 ticks zu je 12.5 ns = 1800 µs

./. - 200 µs


test 3
2 delays with each delay 1µs between = 243 ticks
243 ticks zu je 12.5 ns = 3037,5 µs


./. + 1037.5 µs



more tests:
http://www.mikrocontroller.net/topic/358654#4014599


best wishes
;-)
Attachments
_1_praezisestimingccount_controll_system_get_time.jpg
_1_praezisestimingccount_controll_system_get_time.jpg (32.79 KiB) Viewed 22780 times
_1_praezisestimingccount_controll_system_get_time_ASM.jpg
_1_praezisestimingccount_controll_system_get_time_ASM.jpg (47.85 KiB) Viewed 22780 times

-------------------------------------
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪

jcmvbkbc
Posts: 13
Joined: Fri Oct 24, 2014 7:27 pm

Re: Precise timing needed (ex. for IR decoding)

Postby jcmvbkbc » Fri Mar 06, 2015 12:58 am

rudi wrote:@jcmvbkbc
do you know how much / when overflow ( register bit ) can read , too?
have me a interupt for this?
can we trigger this?

I'm not sure what you're asking, my guess is the questions are
- how long is CCOUNT SR? -- it's 32 bits
- is overflow of CCOUNT detectable? -- no, there's nothing that can tell you about an overflow. No interrupt, no overflow bit.
- is there an interrupt for CCOUNT? Yes, there is a number of CCOMPARE SRs. You can write a value there and then an IRQ will be raised once CCOUNT reaches that value.

For more details please see xtensa ISA book (e.g. http://0x04.net/~mwk/doc/xtensa.pdf ), 4.4.6 Timer interrupt option.

User avatar
rudi
Posts: 197
Joined: Fri Oct 24, 2014 7:55 pm

Re: Precise timing needed (ex. for IR decoding)

Postby rudi » Fri Mar 06, 2015 3:43 am

jcmvbkbc wrote:
rudi wrote:@jcmvbkbc
do you know how much / when overflow ( register bit ) can read , too?
have me a interupt for this?
can we trigger this?


I'm not sure what you're asking, my guess is the questions are

- how long is CCOUNT SR? -- it's 32 bits



ok, i take %lu for this 32bit value

jcmvbkbc wrote:
- is overflow of CCOUNT detectable? -- no, there's nothing that can tell you about an overflow. No interrupt, no overflow bit.



ok, i understand

jcmvbkbc wrote:
- is there an interrupt for CCOUNT? Yes, there is a number of CCOMPARE SRs. You can write a value there and then an IRQ will be raised once CCOUNT reaches that value.



this is the point, txs,
then thinked right,
i helped me with primitive counter and compare the ticks time to time
i have try to make a interupt to a variable , if change , then trigger
i was not sure, is there an interupt or other

thank you!

jcmvbkbc wrote:
For more details please see xtensa ISA book (e.g. http://0x04.net/~mwk/doc/xtensa.pdf ), 4.4.6 Timer interrupt option.


ok - yes know from the book - will study the point again and try to go on over CCOMPARE SRs and IRQ's
thank you jcmvbkbc!

btw,
if you have an example for CCOMPARE SRs and IRQ's like you think how to do this will helpfull.
i will try too - will update here if i have a functionally work

Best wishes!
rudi ;-)

btw

i test, because was searching a trigger, counter, overflow...
with this as primitive code
and note all values in a shema


Code: Select all


..
t1 = system_get_time();     // API get time
// start
tick1 = get_ccount();       // Spezial Register CCOUNT get and save
while (mtick < 10 )
{
asm ("nop");
mtick++;
}

t2 = system_get_time();     // API get time
tickdiff = tick2 - tick1;   // How much Ticks used
..
..




and my shema was
"loops" x 2 x 2 = value + while "loops - 1 " = ticks

so i test..

while (mtick < 30 )
30 x 2 x 2 = 120 + while 30 - 1 = 149
Bingo! calculated was right..

40 x 2 x 2 = 160 + while 40 - 1 = 199
Bingo!

50 x 2 x 2 = 200 + while 50 - 1 = 249
Bingo!

60 x 2 x 2 = 240 + while 60 - 1 = 299
Bingo!

70 x 2 x 2 = 280 + while 70 - 1 = 349
Bingo!

80 x 2 x 2 = 320 + while 80 - 1 = 399
Bingo!

90 x 2 x 2 = 360 + while 90 - 1 = 449
Bingo!



100 x 2 x 2 = 400 + while 100 - 1 = 499

UPS! calculated was 499 but ticks was 598

so i have think, have we a overrun / trigger ?

so i make step by step

in ( ) this is the calculated soll

91 = 454 ticks (91*2*2+while 91-1=454)
92 = 459 ticks (92*2*2+while 92-1=459)
93 = 464 ticks (93*2*2+while 93-1=464)
94 = 469 ticks (94*2*2+while 94-1=469)
95 = 474 ticks (95*2*2+while 95-1=474)

~~~~~~~~~~~~~~~ ok ~~~~~~~~~~~~~
then..

96 = 574 ticks (96*2*2+while 96-1=479)
97 = 580 ticks (97*2*2+while 97-1=484)
98 = 586 ticks (98*2*2+while 98-1=489)
99 = 592 ticks (99*2*2+while 99-1=494)
100 = 598 ticks (100*2*2+while 100-1=499)

in this case allways 6 ticks more like value before
in paste time, allways 5 ticks more.

between 95 and 96 loops there is a swap / more ticks

96*2*2+while 96-1 + 100-1

a overflow from 100 ticks and a difference from 6 ticks

so i test again:

will it be difference if test will be 95 + 96 = 191 loops?
test

190 = 1138 ticks (190*2*2+while 190-1 + 190 - 1 = 1038 )
195 = 1168 ticks (195*2*2+while 195-1 + 195 - 1 = 1168 )
200 = 1198 ticks (200*2*2+while 200-1 + 200 - 1 = 1198 )
..
1200 ....= 7198 ( = 7198 )

no all ok, but why is a difference betwenn
95 and 96

while.. true ticks ,,,,,,,,,,,,,,,calculated ticks
95 = 474 ticks (95*2*2+while 95-1=474)
96 = 574 ticks (96*2*2+while 96-1=479)

i have think - then perhabs a possible way for a register bit

sorry for many text :)
i test many things / think's
:)

-------------------------------------
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪

Who is online

Users browsing this forum: No registered users and 67 guests