Ha ha. The trouble is, that looks like a valid UEI protocol ID, it would be better to pick something in the 01 F? or 01 E? range.zkidz wrote:P.S. I'm calling dibs on protocol ID # 01 3D
Controlling 3D IR shutter glasses
Moderator: Moderators
-
The Robman
- Site Owner
- Posts: 21949
- Joined: Fri Aug 01, 2003 9:37 am
- Location: Chicago, IL
- Contact:
Rob
www.hifi-remote.com
Please don't PM me with remote questions, post them in the forums so all the experts can help!
www.hifi-remote.com
Please don't PM me with remote questions, post them in the forums so all the experts can help!
Some implementation notes...
Here's a start at explaining how to do this for anyone else interested in this application. I may be back with some more info, if it doesn't start to bore me...
1) Vectors 0x14C 0x16D 0x167 explained:
First I thought it would be good to explain more exactly what vectors 0x14C, 0x16D and 0x167 do -- at least, this is what they do on the S3F80-based remotes. This set of vectors can be used to send IR signals "by hand" by controlling whether the carrier signal is sent to the IR emitter or not. To do this, they use one of the chipset's timer circuits. We will call this timer the envelope timer.
Vector 0x16D does one very simple thing. It looks to see if the envelope timer is running. It waits for the envelope timer to expire. However, unlike the other two vectors, it does not use the low-power IDLE mode of the chipset, so it will burn up more battery power than necessary.
Vector 0x167 also waits for the envelope timer to expire, however, it waits in IDLE mode. After the timer has expired, it reprograms the timer to wait again. How long it programs the timer to wait for depends on a word stored in the register set. Register
RC7 tells which two registers to find this word in. After vector 0x167 returns, RC7 has been incremented by 2 and the envelope timer is still running with the programmed delay.
Vector 0x14C does almost exactly the same thing as vector 0x167, with two differences. First, after the envelope timer has expired, it turns on the carrier generator, waits a bit for it to rev up, and then gates the carrier generator through to the emitter's IR LED. It also sets things up so that the next time the envelop timer expires, the IR emmitter LED will be automatically turned off by an interrupt handler.
Second, instead of returning, vector 0x14C "tailcalls" vector 0x167. So the IR carrier will run for the amount of time specified by the two registers pointed to by RC7, then the IR generator is turned off, then RC7 will be incremented by 2, then the envelope timer will be programmed to run by two more registers now pointed to by RC7, then RC7 will be incremented again by 2. So by the time vector 0x14C has returned, RC7 has been incremented by 4.
The important thing not to miss here is that both vectors 0x167 and 0x14C return with the envelope timer running. It is not until the NEXT time one of these vectors is called
that the remote waits for the envelope timer to expire.
That means that as long as there is enough time programmed into the envelope timer, we can do other things without affecting the accuracy of our timing signal. This is important when dealing with 3D timing signals which are continuous and have more precise timing needs than the IR codes used by AV equipment.
2) Detecting the sync signal:
For this application, the JP-1 connector, pin 4, must be connected to either a 2-pin phototransistor's collector or to a Vesa Stereo cable. Of course, you also need to connect to Ground on pin 3 as well.
JP1.3 pin 4 is wired (on my S3F80 44-pin remote) to the chipset's "P3.0" pin. In addition to normal IO funtions, this pin should be the T0 capture input on both 33-pin and 42-pin S3F80 chipsets. It is very likely that this pin is wired the same way on 32-pin S3F80 based remotes as well, since the 44-pin chip is retrofitted onto a 32-pin layout on my remote. On the S3C80 the T0CAP pin is on P0.4 instead -- whether this is usually connected to JP1 pin 4 on S3C80 remotes has yet to be investigated.
This means code for the S3C80 will differ from the S3F80, which is a problem because the tools do not distinguish between the two, and expect generic code which applies to both CPUs. It may be possible to choose codepaths based on runtime probes of the hardware. Having no S3C80 to play with I won't be able to provide that.
On 32-pin S3F80 chipsets, additional capture functions are also on the "P3.0" pin, most notably the T2 capture input. T2 is a 16-bit counter where T0 is 8-bit, so there may be a more flexibility for this application on the 32-pin chipsets. Also T2 supports detecting both rising and falling edges at the same time.
Unfortunately there are no syscall ABI vectors that manipulate the "P3.0" pin. There is a non-ABI function (at 0x1f7) that reads this pin 3 times and counts the number of 1s read. It is part of the JP1 serial protocol implementation. However its address is likely to change between software revisions. It is possible that in remotes that have learning capabilities, such ABI vectors may exist.
The most direct way to detect a rising/falling edge on S3F80 P3.0 is the following:
46 EF 03 OR REF #03 ; put P3.0 in pull-up input mode
08 E3 LD RC0 RE3 ; read P3 data register
B4 E3 C0 XOR RC0 RE3 ; check P3 data register for changes
76 C0 01 TM RC0 #01 ; see if state of P3.0 state has changed
6B F8 JRZ -#08 ; no change, try again
The disadvantage to this approach is that it does not utilize the processor's IDLE mode to save power. Should we desire to do that, we would have to use the T0 capture function. Here we have a choice of setting the fast IRQ handler to IRQ0, or using the slow handler which is already installed in the manufacturer firmware. Using the slow handler would allow us to avoid messing with the fast handler, which is used by the T1 hardware for the envelope timer. The installed T0 slow handler does nothing but to re-arm the IRQ (and we can hope that is the same across various remotes.)
Unfortunately, unlike the T1 capture function, the T0 capture function only allows us to set up for rising or falling edge, not both. IR signals will generally be happy triggering on one or the other, but Vesa Stereo uses alternating rising/falling edges once each eye. So we try setting the port to rising edge, then sample to make sure we are primed to catch an edge. If not we retry this procedure setting the opposite edge, until we get the desired results. This is still not perfect: either there is a gap in the S3F80 design, or an undocumented feature -- there seems to be no way at all to be sure that the edge you are triggering on will not occur (and be handled) before you enter IDLE mode. (Perhaps the IDLE instruction will also perform an EI? Needs testing.) Anyway, this should not be a problem as long as we are careful to time our use of the following procedure to avoid the potential race condition.
The following is code to detect edges using the T0 capture feature:
46 EF 07 OR REF #07 ; put P3.0 in pull-up T0CAP input mode
E6 D2 1A LD RD2 #1A ; T0 fOSC/8 no oflow irq, yes match irq, rise, clear
66 E3 01 TM RE3 #01 ; test value at P3.0 pin
6B 08 JRZ +#08 ; we are prepared for next edge
E6 D2 2A LD RD2 #2A ; T0 fOSC/8 no oflow irq, yes match irq, fall, clear
66 E3 01 TM RE3 #01 ; test value at P3.0 pin
6B F0 JRZ -#10 ; we are not prepared for next edge
6F IDLE ; wait for any IRQ
E6 D2 18 LD RD2 #18 ; T0 fOSC/8 no oflow irq, no match irq, rise, clear
Again note that this code may be reduced somewhat on 33-pin chips by using the "both edges" feature of T2CAP.
1) Vectors 0x14C 0x16D 0x167 explained:
First I thought it would be good to explain more exactly what vectors 0x14C, 0x16D and 0x167 do -- at least, this is what they do on the S3F80-based remotes. This set of vectors can be used to send IR signals "by hand" by controlling whether the carrier signal is sent to the IR emitter or not. To do this, they use one of the chipset's timer circuits. We will call this timer the envelope timer.
Vector 0x16D does one very simple thing. It looks to see if the envelope timer is running. It waits for the envelope timer to expire. However, unlike the other two vectors, it does not use the low-power IDLE mode of the chipset, so it will burn up more battery power than necessary.
Vector 0x167 also waits for the envelope timer to expire, however, it waits in IDLE mode. After the timer has expired, it reprograms the timer to wait again. How long it programs the timer to wait for depends on a word stored in the register set. Register
RC7 tells which two registers to find this word in. After vector 0x167 returns, RC7 has been incremented by 2 and the envelope timer is still running with the programmed delay.
Vector 0x14C does almost exactly the same thing as vector 0x167, with two differences. First, after the envelope timer has expired, it turns on the carrier generator, waits a bit for it to rev up, and then gates the carrier generator through to the emitter's IR LED. It also sets things up so that the next time the envelop timer expires, the IR emmitter LED will be automatically turned off by an interrupt handler.
Second, instead of returning, vector 0x14C "tailcalls" vector 0x167. So the IR carrier will run for the amount of time specified by the two registers pointed to by RC7, then the IR generator is turned off, then RC7 will be incremented by 2, then the envelope timer will be programmed to run by two more registers now pointed to by RC7, then RC7 will be incremented again by 2. So by the time vector 0x14C has returned, RC7 has been incremented by 4.
The important thing not to miss here is that both vectors 0x167 and 0x14C return with the envelope timer running. It is not until the NEXT time one of these vectors is called
that the remote waits for the envelope timer to expire.
That means that as long as there is enough time programmed into the envelope timer, we can do other things without affecting the accuracy of our timing signal. This is important when dealing with 3D timing signals which are continuous and have more precise timing needs than the IR codes used by AV equipment.
2) Detecting the sync signal:
For this application, the JP-1 connector, pin 4, must be connected to either a 2-pin phototransistor's collector or to a Vesa Stereo cable. Of course, you also need to connect to Ground on pin 3 as well.
JP1.3 pin 4 is wired (on my S3F80 44-pin remote) to the chipset's "P3.0" pin. In addition to normal IO funtions, this pin should be the T0 capture input on both 33-pin and 42-pin S3F80 chipsets. It is very likely that this pin is wired the same way on 32-pin S3F80 based remotes as well, since the 44-pin chip is retrofitted onto a 32-pin layout on my remote. On the S3C80 the T0CAP pin is on P0.4 instead -- whether this is usually connected to JP1 pin 4 on S3C80 remotes has yet to be investigated.
This means code for the S3C80 will differ from the S3F80, which is a problem because the tools do not distinguish between the two, and expect generic code which applies to both CPUs. It may be possible to choose codepaths based on runtime probes of the hardware. Having no S3C80 to play with I won't be able to provide that.
On 32-pin S3F80 chipsets, additional capture functions are also on the "P3.0" pin, most notably the T2 capture input. T2 is a 16-bit counter where T0 is 8-bit, so there may be a more flexibility for this application on the 32-pin chipsets. Also T2 supports detecting both rising and falling edges at the same time.
Unfortunately there are no syscall ABI vectors that manipulate the "P3.0" pin. There is a non-ABI function (at 0x1f7) that reads this pin 3 times and counts the number of 1s read. It is part of the JP1 serial protocol implementation. However its address is likely to change between software revisions. It is possible that in remotes that have learning capabilities, such ABI vectors may exist.
The most direct way to detect a rising/falling edge on S3F80 P3.0 is the following:
46 EF 03 OR REF #03 ; put P3.0 in pull-up input mode
08 E3 LD RC0 RE3 ; read P3 data register
B4 E3 C0 XOR RC0 RE3 ; check P3 data register for changes
76 C0 01 TM RC0 #01 ; see if state of P3.0 state has changed
6B F8 JRZ -#08 ; no change, try again
The disadvantage to this approach is that it does not utilize the processor's IDLE mode to save power. Should we desire to do that, we would have to use the T0 capture function. Here we have a choice of setting the fast IRQ handler to IRQ0, or using the slow handler which is already installed in the manufacturer firmware. Using the slow handler would allow us to avoid messing with the fast handler, which is used by the T1 hardware for the envelope timer. The installed T0 slow handler does nothing but to re-arm the IRQ (and we can hope that is the same across various remotes.)
Unfortunately, unlike the T1 capture function, the T0 capture function only allows us to set up for rising or falling edge, not both. IR signals will generally be happy triggering on one or the other, but Vesa Stereo uses alternating rising/falling edges once each eye. So we try setting the port to rising edge, then sample to make sure we are primed to catch an edge. If not we retry this procedure setting the opposite edge, until we get the desired results. This is still not perfect: either there is a gap in the S3F80 design, or an undocumented feature -- there seems to be no way at all to be sure that the edge you are triggering on will not occur (and be handled) before you enter IDLE mode. (Perhaps the IDLE instruction will also perform an EI? Needs testing.) Anyway, this should not be a problem as long as we are careful to time our use of the following procedure to avoid the potential race condition.
The following is code to detect edges using the T0 capture feature:
46 EF 07 OR REF #07 ; put P3.0 in pull-up T0CAP input mode
E6 D2 1A LD RD2 #1A ; T0 fOSC/8 no oflow irq, yes match irq, rise, clear
66 E3 01 TM RE3 #01 ; test value at P3.0 pin
6B 08 JRZ +#08 ; we are prepared for next edge
E6 D2 2A LD RD2 #2A ; T0 fOSC/8 no oflow irq, yes match irq, fall, clear
66 E3 01 TM RE3 #01 ; test value at P3.0 pin
6B F0 JRZ -#10 ; we are not prepared for next edge
6F IDLE ; wait for any IRQ
E6 D2 18 LD RD2 #18 ; T0 fOSC/8 no oflow irq, no match irq, rise, clear
Again note that this code may be reduced somewhat on 33-pin chips by using the "both edges" feature of T2CAP.