Skip to content

Commit

Permalink
Add delayMicroseconds
Browse files Browse the repository at this point in the history
This isn't a good version of it, but it has the capability of delaying a
lot shorter times than `delay` can. We could use the register too, but
right now this is fine. Really just need to find a better way to get the
necessary assembly and a nice way to measure 16MHz pulses.
  • Loading branch information
evantypanski committed Feb 27, 2023
1 parent 088fad5 commit 36990ba
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/LiquidCrystal.zig
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ pub fn LiquidCrystal(comptime rs: u8, comptime enable: u8, comptime d0: u8, comp
write4bits(0x03);
time.delay(5);
write4bits(0x03);
time.delay(1);
time.delayMicroseconds(150);
write4bits(0x02);

command(function_set | lcd_config.functionBits());
Expand Down Expand Up @@ -292,10 +292,10 @@ pub fn LiquidCrystal(comptime rs: u8, comptime enable: u8, comptime d0: u8, comp
fn pulseEnable() void {
gpio.digitalWrite(enable_pin, .low);
// TODO: This should be 1 us.. but we're slow here.
time.delay(1);
time.delayMicroseconds(1);
gpio.digitalWrite(enable_pin, .high);
// Enable just needs to be high for >450 ns so we good.
time.delay(1);
time.delayMicroseconds(1);
gpio.digitalWrite(enable_pin, .low);
// This'll be 100us not 1us like others to settle
time.delay(1);
Expand Down
30 changes: 30 additions & 0 deletions src/time.zig
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,33 @@ pub fn delay(ms: u64) void {
}
}
}

// u32 not u64 to easily get signed version so we can have more efficient
// loop later. This is really trial and error and should be done better when
// I am able.
pub fn delayMicroseconds(us: u32) void {
// TODO: Care about clock frequency
// We'll assume <= 1us overhead of function call is enough
if (us <= 1) return;

// This is signed so later we can subtract an amount larger than 1
// and check if it's greater than 0 without underflow.
var us_var: i64 = us;

// Trying to get the loop later exactly right... and this x4 to get
// us to actually be us and not ms, but this was trial and error anyway
us_var <<= 2;
// Subtract an amount of time. Arduino libraries have 5 so I'll do that,
// but I think copying the variable will add a load in there. But then
// we aren't doing the shift first at the moment so it may even out.
us_var -= 5;

// After messing around with inline ASM for forever, I think Zig/LLVM
// don't fully work with AVR inline assembly constraints like =w - or
// probably any 32 bit or 64 bit types. Instead, just try out a busy
// wait with a loop.
while (us_var > 0) {
us_var -= 9;
asm volatile ("nop");
}
}

0 comments on commit 36990ba

Please sign in to comment.