Hello, I'm currently using uVision 2.33. I've written the following function in the function editor to simulate an RC5 signal which I want to detect on P1.1:
define button "Start P1.1 Toggle", "p11_toggle()" define button "Stop P1.1 Toggle" , "signal kill p11_toggle" signal void Generate0() { P1 &= ~0x02; /* pull T2EX(P1.1) low and generate interrupt */ twatch( 889 ); P1 |= 0x02; /* pull T2EX(P1.1) high */ twatch (889); } signal void Generate1() { P1 |= 0x02; /* pull T2EX(P1.1) high */ twatch( 889 ); P1 &= ~0x02; /* pull T2EX(P1.1) low and generate interrupt */ twatch (889); } signal void p11_toggle() { while (1) { // Bit1: start Generate1(); // Bit2: indication Generate1(); // Bit3: toggle Generate0(); // Bit4: system5 Generate0(); // Bit5: system4 Generate0(); // Bit6: system3 Generate0(); // Bit7: system2 Generate0(); // Bit8: system1 Generate1(); // Bit9: command6 Generate1(); // Bit10: command5 Generate0(); // Bit11: command4 Generate0(); // Bit12: command3 Generate0(); // Bit13: command2 Generate1(); // Bit14: command1 Generate0(); swatch( 1 ); } }
*** function 'p11_toggle', error 99, line 27: signal() already activated p11_toggle() *** error 99: signal() already activated
*** error 34, line 9: undefined identifier
When you call a signal function from within another signal function the debugger actually starts a separate "thread" of execution for the new signal function. In other words, the signal function you call runs separate from the calling signal. So, when the following code executes in p11_toggle:
// Bit1: start Generate1(); // Bit2: indication Generate1();
define button "Start P1.1 Toggle", "p11_toggle()" define button "Stop P1.1 Toggle" , "signal kill p11_toggle" signal void Generate0(void) { printf ("Gen0: %lu\n", states); P1 &= ~0x02; /* pull T2EX(P1.1) low and generate interrupt */ twatch( 889 ); P1 |= 0x02; /* pull T2EX(P1.1) high */ twatch (889); } signal void Generate1(void) { printf ("Gen1: %lu\n", states); P1 |= 0x02; /* pull T2EX(P1.1) high */ twatch( 889 ); P1 &= ~0x02; /* pull T2EX(P1.1) low and generate interrupt */ twatch (889); } signal void p11_toggle(void) { while (1) { // Bit1: start Generate1(); twatch(2000); // Bit2: indication Generate1(); twatch(2000); // Bit3: toggle Generate0(); twatch(2000); // Bit4: system5 Generate0(); twatch(2000); // Bit5: system4 Generate0(); twatch(2000); // Bit6: system3 Generate0(); twatch(2000); // Bit7: system2 Generate0(); twatch(2000); // Bit8: system1 Generate1(); twatch(2000); // Bit9: command6 Generate1(); twatch(2000); // Bit10: command5 Generate0(); twatch(2000); // Bit11: command4 Generate0(); twatch(2000); // Bit12: command3 Generate0(); twatch(2000); // Bit13: command2 Generate1(); twatch(2000); // Bit14: command1 Generate0(); twatch(2000); swatch( 1 ); } }
Jon, The problem is, if I add some extra wait time between to Generate calls, I don't comply with the RC standard anymore. As you can see in my script, the Generate0() and Generate1() functions have their own wait time. twatch( 889 ) (or a multipe of it) is exactly the RC5 standard time of a bi-phased pulse width, if the level (a 1 or a 0) doesn't change. With your improvements, I add immediately some time to it and the chance exists that I don't comply anymore with the RC5 standard. Since I also want to make my driver 'universal' (meaning in a later stage being able to automatically detect if the incoming signal is RC5 or RC6), things will result only in even smaller periods of time between two consecutive pulses. Any idea how to solve this issue? Rgds, --Geert
I can think of several ways to do this. The first one is a simple substitution. Just put the Generate0 and Generate1 functions in-line:
/* Gen 0 on P1.1: P1 &= ~0x02; twatch (889); P1 |= 0x02; twatch (889); */ /* Gen 1 on P1.1: P1 |= 0x02; twatch (889); P1 &= ~0x02; twatch (889); */ signal void p11_toggle (void) { while (1) { // Bit1: start P1 |= 0x02; twatch (889); P1 &= ~0x02; twatch (889); // Bit2: indication P1 |= 0x02; twatch (889); P1 &= ~0x02; twatch (889); // Bit3: toggle P1 &= ~0x02; twatch (889); P1 |= 0x02; twatch (889); // Bit4: system5 P1 &= ~0x02; twatch (889); P1 |= 0x02; twatch (889); // Bit5: system4 P1 &= ~0x02; twatch (889); P1 |= 0x02; twatch (889); // Bit6: system3 P1 &= ~0x02; twatch (889); P1 |= 0x02; twatch (889); // Bit7: system2 P1 &= ~0x02; twatch (889); P1 |= 0x02; twatch (889); // Bit8: system1 P1 |= 0x02; twatch (889); P1 &= ~0x02; twatch (889); // Bit9: command6 P1 |= 0x02; twatch (889); P1 &= ~0x02; twatch (889); // Bit10: command5 P1 &= ~0x02; twatch (889); P1 |= 0x02; twatch (889); // Bit11: command4 P1 &= ~0x02; twatch (889); P1 |= 0x02; twatch (889); // Bit12: command3 P1 &= ~0x02; twatch (889); P1 |= 0x02; twatch (889); // Bit13: command2 P1 |= 0x02; twatch (889); P1 &= ~0x02; twatch (889); // Bit14: command1 P1 &= ~0x02; twatch (889); P1 |= 0x02; twatch (889); swatch( 1 ); } }
signal void send_p11_info (unsigned int val) { unsigned char i; while (1) { for (i = 0; i < 14; i++) { if (val & (1 << i)) /* Send 1 */ { P1 |= 0x02; twatch (889); P1 &= ~0x02; twatch (889); } else /* Send 0 */ { P1 &= ~0x02; twatch (889); P1 |= 0x02; twatch (889); } } swatch( 1 ); } } /*** Assign this function call to a button or whatever ***/ send_p11_info (0x1183); /* 0x1183 = 01 0001 1000 0011 = the values transmitted by the original signal */
The second one is a real nice solution. Thanks for this input, Jon! Rgds, --Geert