sylveos

Toy Operating System
Log | Files | Refs

sw-uart.zig (1644B)


      1 const std = @import("std");
      2 
      3 const interrupts = @import("../interrupts.zig");
      4 const mem = @import("../mem.zig");
      5 
      6 const clock = @import("./clock.zig");
      7 const gpio = @import("./gpio.zig");
      8 const pi = @import("../root.zig");
      9 
     10 pub const Error = error{ AlreadyInitialized, NotInitialized, InvalidBaud } || gpio.Error;
     11 
     12 var initialized = false;
     13 var interrupts_enabled = false;
     14 
     15 pub var delay: u32 = undefined;
     16 var tx: u8 = undefined;
     17 var rx: u8 = undefined;
     18 
     19 pub fn initialize(baud: u32, tx_pin: u8, rx_pin: u8) Error!void {
     20     if (initialized) return Error.AlreadyInitialized;
     21 
     22     try gpio.fn_sel(tx_pin, .output);
     23     // try gpio.set_pull(tx_pin, .Up);
     24     tx = tx_pin;
     25 
     26     try gpio.fn_sel(rx_pin, .input);
     27     // try gpio.set_pull(rx_pin, .Up);
     28     rx = rx_pin;
     29 
     30     try gpio.set_on(tx_pin);
     31 
     32     mem.barrier(.Write);
     33 
     34     // Cycles to delay
     35     delay = (@divFloor(700_000_000, baud));
     36     if (delay == 0) return Error.InvalidBaud;
     37 
     38     initialized = true;
     39 }
     40 
     41 pub fn write_byte(byte: u8) !void {
     42     if (!initialized) return Error.NotInitialized;
     43 
     44     gpio.set_off(tx) catch {};
     45     mem.barrier(.Write);
     46 
     47     var deadline = pi.cycle_counter_read() + delay;
     48     pi.cycle_wait_until(deadline);
     49 
     50     for (0..8) |n| {
     51         const state = (byte & (@as(u8, 1) << @truncate(n))) != 0;
     52         gpio.write(tx, state) catch {};
     53         mem.barrier(.Write);
     54 
     55         deadline += delay;
     56         pi.cycle_wait_until(deadline);
     57     }
     58 
     59     gpio.set_on(tx) catch {};
     60     mem.barrier(.Write);
     61 
     62     deadline += delay;
     63     pi.cycle_wait_until(deadline);
     64 }
     65 
     66 pub fn write_slice(bytes: []const u8) !void {
     67     for (bytes) |b| {
     68         try write_byte(b);
     69     }
     70 }