; CLOCK = 2MHz .program tm1637out .side_set 1 opt .wrap_target ; Start Condition pull block set pindirs,0b00 ; SDA/SCL input nop [7] ; 8 Clocks set pindirs,0b01 ; SDA output/SCL input set pins,0 ; SDA is Low nop [7] ; 8 Clocks set pindirs,0b11 ; SDA/SCL output set x,7 side 0 ; CLK is Low jmp output ; 1バイト出力 byte_loop: set x, 7 side 0 ; Clock Low pull block output: nop [3] ; 4 Clock out pins,1 [4] ; LSB output nop side 1 ; CLK is High nop [7] ; 8 clocks nop side 0 ; CLK is Low jmp x-- output ; ; ACK判定 set pindirs,0b10 [7] ; SDA input/SCL output nop side 1 ; SCL = High jmp pin nack ; if SDA == 0 then ACK jmp ack nack: irq 0 rel ; NACK ; Stop判定 ack: nop [6] nop side 0 ; CLK is Low (ACK cycle end) set pindirs, 0b11 [7] ; SDA/SCL Output (next byte or stop) out x, 1 ; 9bit目 jmp !x byte_loop ; 0ならStopせずにループ ; Stop Condition stop: set pins, 0 [7] ; SDA is Low nop side 1 ; SCL is High nop [7] set pindirs, 0b00 ; SDA/SCL Input (pull-up makes it High) -> STOP nop [7] .wrap % c-sdk { #include "hardware/clocks.h" #define SM_CLOCK 2000000.0 void tm1637out_program_init(PIO pio, uint sm, uint offset, uint sda, uint clk) { // pull up gpio_pull_up(sda); gpio_pull_up(clk); // SDA & CLK pio_gpio_init(pio, sda); pio_gpio_init(pio, clk); pio_sm_set_consecutive_pindirs(pio, sm, clk, 1, false); // 初期状態はInput pio_sm_set_consecutive_pindirs(pio, sm, sda, 1, false); // 同上 pio_sm_config c = tm1637out_program_get_default_config(offset); // out = set = jmp = SDA sm_config_set_out_pin_base(&c, sda); sm_config_set_out_pin_count(&c, 1); sm_config_set_set_pin_base(&c, sda); sm_config_set_set_pin_count(&c, 2); sm_config_set_jmp_pin(&c, sda); // sideset = clk sm_config_set_sideset_pin_base(&c, clk); // out = Right shift sm_config_set_out_shift(&c, true, false, 0); // SM Clock = 2MHz float clkdiv = (float)clock_get_hz(clk_sys) / SM_CLOCK; sm_config_set_clkdiv(&c, clkdiv); // TX FIFO join sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX); pio_sm_init(pio, sm, offset, &c); } %}