Implementing things more close to spec

This commit is contained in:
Rodrigo Alfonso
2025-02-10 02:13:20 -03:00
parent 4a685f5d5f
commit 57e8fb5b7b
2 changed files with 11 additions and 10 deletions

View File

@@ -4,21 +4,18 @@
// 38kHz signal => 38000/second =>
// period = 1000000µs / 38000 = 26.31µs
// halfPeriod = 13.15µs
// LED ON => RCNT = 0x8098 (GPIO mode, SC and SO as OUTPUT, SO=HIGH)
// LED OFF => RCNT = 0x8090 (GPIO mode, SC and SO as OUTPUT, SO=LOW)
// LED ON => RCNT = 0x80BA (GPIO mode, SC, SD, SO as OUTPUT, SD=HIGH, SO=HIGH)
// LED OFF => RCNT = 0x80B2 (GPIO mode, SC, SD, SO as OUTPUT, SD=HIGH, SO=LOW)
LINK_CODE_IWRAM void LinkIR::generate38kHzSignal(u32 microseconds) {
// halfPeriods = ceil(microseconds / 13.15 µs) (in fixed-point math)
u32 halfPeriods = (microseconds * 100 + 1315) / 1316;
// force an odd count so the final value will be 0x8090 (LED OFF)
if ((halfPeriods & 1) == 0)
halfPeriods++;
u32 halfPeriods = Link::_max((microseconds * 100 + 1315) / 1316, 1);
// the GBA is 16.776MHz => 13.15 µs ~= 220 cycles per half-period
asm volatile(
"mov r0, %0 \n" // r0 = address of REG_RCNT
"ldr r1, =0x8098 \n" // r1 = initial value 0x8098 (LED ON)
"ldr r1, =0x80BA \n" // r1 = initial value 0x80BA (LED ON)
"mov r2, %1 \n" // r2 = main loop count (halfPeriods)
"1: \n" // --- main loop ---
"strh r1, [r0] \n" // write current value to REG_RCNT
@@ -32,11 +29,11 @@ LINK_CODE_IWRAM void LinkIR::generate38kHzSignal(u32 microseconds) {
// [first 53 iterations (branch taken): 53 * ~4 cycles = ~212 cycles]
// [final iteration (branch not taken): ~2 cycles]
// [overhead: ~6 cycles]
"eor r1, r1, #8 \n" // toggle r1: 0x8098^8 = 0x8090 (& viceversa)
"eor r1, r1, #8 \n" // toggle r1: 0x80BA^8 = 0x80B2 (& viceversa)
"subs r2, r2, #1 \n" // decrement main loop count
"bne 1b \n" // repeat main loop if needed
"ldr r1, =0x8090 \n" // ensure we end with 0x8090
"strh r1, [r0] \n" // write REG_RCNT = 0x8090 (LED OFF)
"ldr r1, =0x80B2 \n" // ensure we end with 0x80B2
"strh r1, [r0] \n" // write REG_RCNT = 0x80B2 (LED OFF)
:
: "r"(&Link::_REG_RCNT), "r"(halfPeriods)
: "r0", "r1", "r2", "r3");

View File

@@ -103,6 +103,8 @@ class LinkIR {
linkGPIO.setMode(Pin::SC, Direction::OUTPUT);
linkGPIO.writePin(Pin::SC, false);
linkGPIO.setMode(Pin::SD, Direction::OUTPUT);
linkGPIO.writePin(Pin::SD, true);
linkGPIO.setMode(Pin::SO, Direction::OUTPUT);
linkGPIO.writePin(Pin::SO, false);
linkGPIO.setSIInterrupts(true);
@@ -166,10 +168,12 @@ class LinkIR {
bool receiveNEC(u8& address, u8& command) {
// TODO: IMPLEMENT
return false;
}
bool receive(u16 pulses[], u32 maxEntries, u32 timeout) {
// TODO: IMPLEMENT
return false;
}
/**