mirror of
https://github.com/afska/gba-link-connection.git
synced 2026-09-14 11:57:48 -05:00
Implementing things more close to spec
This commit is contained in:
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user