tm1637out.pio 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. ; CLOCK = 2MHz
  2. .program tm1637out
  3. .side_set 1 opt
  4. .wrap_target ; Start Condition
  5. pull block
  6. set pindirs,0b00 ; SDA/SCL input
  7. nop [7] ; 8 Clocks
  8. set pindirs,0b01 ; SDA output/SCL input
  9. set pins,0 ; SDA is Low
  10. nop [7] ; 8 Clocks
  11. set pindirs,0b11 ; SDA/SCL output
  12. set x,7 side 0 ; CLK is Low
  13. jmp output
  14. ; 1バイト出力
  15. byte_loop:
  16. set x, 7 side 0 ; Clock Low
  17. pull block
  18. output:
  19. nop [7] ; 8 Clock
  20. out pins,1 ; LSB output
  21. nop side 1 ; CLK is High
  22. nop [7] ; 8 clocks
  23. nop side 0 ; CLK is Low
  24. jmp x-- output ;
  25. ; ACK判定
  26. set pindirs,0b10 [7] ; SDA input/SCL output
  27. nop side 1 ; SCL = High
  28. jmp pin nack ; if SDA == 0 then ACK
  29. jmp ack
  30. nack:
  31. irq 0 rel ; NACK
  32. ; Stop判定
  33. ack:
  34. nop [6]
  35. nop side 0 ; CLK is Low (ACK cycle end)
  36. set pindirs, 0b11 [7] ; SDA/SCL Output (next byte or stop)
  37. out x, 1 ; 9bit目
  38. jmp !x byte_loop ; 0ならStopせずにループ
  39. ; Stop Condition
  40. stop:
  41. set pins, 0 [7] ; SDA is Low
  42. nop side 1 ; SCL is High
  43. nop [7]
  44. set pindirs, 0b00 ; SDA/SCL Input (pull-up makes it High) -> STOP
  45. nop [7]
  46. .wrap
  47. % c-sdk {
  48. #include "hardware/clocks.h"
  49. #define SM_CLOCK 2000000.0
  50. void tm1637out_program_init(PIO pio, uint sm, uint offset, uint sda, uint clk) {
  51. // pull up
  52. gpio_pull_up(sda);
  53. gpio_pull_up(clk);
  54. // SDA & CLK
  55. pio_gpio_init(pio, sda);
  56. pio_gpio_init(pio, clk);
  57. pio_sm_set_consecutive_pindirs(pio, sm, clk, 1, false); // 初期状態はInput
  58. pio_sm_set_consecutive_pindirs(pio, sm, sda, 1, false); // 同上
  59. pio_sm_config c = tm1637out_program_get_default_config(offset);
  60. // out = set = jmp = SDA
  61. sm_config_set_out_pin_base(&c, sda);
  62. sm_config_set_out_pin_count(&c, 1);
  63. sm_config_set_set_pin_base(&c, sda);
  64. sm_config_set_set_pin_count(&c, 2);
  65. sm_config_set_jmp_pin(&c, sda);
  66. // sideset = clk
  67. sm_config_set_sideset_pin_base(&c, clk);
  68. // out = Right shift
  69. sm_config_set_out_shift(&c, true, false, 0);
  70. // SM Clock = 2MHz
  71. float clkdiv = (float)clock_get_hz(clk_sys) / SM_CLOCK;
  72. sm_config_set_clkdiv(&c, clkdiv);
  73. // TX FIFO join
  74. sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
  75. pio_sm_init(pio, sm, offset, &c);
  76. }
  77. %}