display.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #include "display.h"
  2. #include <stdlib.h>
  3. #include "pico/stdlib.h"
  4. #include "pico/binary_info.h"
  5. #include "hardware/i2c.h"
  6. #include "pico/util/queue.h"
  7. #include "pico/multicore.h"
  8. #include "pico/util/queue.h"
  9. uint8_t display_buffer[OLED_BUF_LEN];
  10. // ディスプレイコマンドqueue
  11. queue_t command_queue;
  12. void _d_putchar(char c, uint8_t col_x, uint8_t col_y, bool reverse)
  13. {
  14. uint32_t offset = col_x * FONT_WIDTH + OLED_WIDTH * col_y + FONT_WIDTH;
  15. if( c < 0 ) return;
  16. if(col_x > 15 || col_y > 3) return;
  17. // フォントの縦横変換
  18. for(int i = 0; i < 8 ; i++ ) {
  19. volatile uint8_t f;
  20. f = ((font8x8[(int)c][reverse ? 0 : 7] << (reverse ? 7 - i : i)) & 0x80) >> 0;
  21. f |= ((font8x8[(int)c][reverse ? 1 : 6] << (reverse ? 7 - i : i)) & 0x80) >> 1;
  22. f |= ((font8x8[(int)c][reverse ? 2 : 5] << (reverse ? 7 - i : i)) & 0x80) >> 2;
  23. f |= ((font8x8[(int)c][reverse ? 3 : 4] << (reverse ? 7 - i : i)) & 0x80) >> 3;
  24. f |= ((font8x8[(int)c][reverse ? 4 : 3] << (reverse ? 7 - i : i)) & 0x80) >> 4;
  25. f |= ((font8x8[(int)c][reverse ? 5 : 2] << (reverse ? 7 - i : i)) & 0x80) >> 5;
  26. f |= ((font8x8[(int)c][reverse ? 6 : 1] << (reverse ? 7 - i : i)) & 0x80) >> 6;
  27. f |= ((font8x8[(int)c][reverse ? 7 : 0] << (reverse ? 7 - i : i)) & 0x80) >> 7;
  28. display_buffer[offset - i] = f;
  29. }
  30. }
  31. void _d_putstr(char *str, uint8_t col_x, uint8_t col_y, bool reverse)
  32. {
  33. int i = 0;
  34. while(str[i] != '\0') {
  35. _d_putchar(str[i++], col_x++, col_y, reverse);
  36. }
  37. }
  38. void _d_clear(void)
  39. {
  40. fill(display_buffer, 0x00);
  41. }
  42. bool display_putstr(char *str, uint8_t col_x, uint8_t col_y, bool reverse)
  43. {
  44. display_cmd_t cmd;
  45. putstr_t *p;
  46. cmd.command = DISPLAY_CMD_PUTSTR;
  47. p = (putstr_t *)malloc(sizeof(putstr_t));
  48. p->col = col_x;
  49. p->row = col_y;
  50. p->reverse = reverse;
  51. strcpy(p->str, str);
  52. cmd.data = (void *)p;
  53. return queue_try_add(&command_queue, &cmd);
  54. }
  55. bool display_clear(void)
  56. {
  57. display_cmd_t cmd;
  58. cmd.command = DISPLAY_CMD_CLEAR;
  59. return queue_try_add(&command_queue, &cmd);
  60. }
  61. // ゴミ捨て
  62. inline void disposer(void *garbage)
  63. {
  64. multicore_fifo_push_blocking((uint32_t)garbage);
  65. }
  66. void display_main(void)
  67. {
  68. // I2C初期化
  69. i2c_init(i2c_default, 800 * 1000);
  70. // I2Cピン初期化
  71. gpio_set_function(PICO_DEFAULT_I2C_SDA_PIN, GPIO_FUNC_I2C);
  72. gpio_set_function(PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C);
  73. gpio_pull_up(PICO_DEFAULT_I2C_SDA_PIN);
  74. gpio_pull_up(PICO_DEFAULT_I2C_SCL_PIN);
  75. // OLED初期化
  76. oled_init();
  77. struct render_area frame_area = {start_col: 0,
  78. end_col : OLED_WIDTH - 1,
  79. start_page : 0,
  80. end_page : OLED_NUM_PAGES - 1,
  81. buflen : 0 };
  82. calc_render_area_buflen(&frame_area);
  83. // ディスプレイクリア
  84. fill(display_buffer, 0x00);
  85. // ディスプレイメインループ
  86. while(true) {
  87. display_cmd_t cmd;
  88. render(display_buffer, &frame_area);
  89. while(! queue_is_empty(&command_queue)) {
  90. queue_remove_blocking(&command_queue, &cmd);
  91. switch(cmd.command) {
  92. case DISPLAY_CMD_CLEAR:
  93. _d_clear();
  94. break;
  95. case DISPLAY_CMD_PUTSTR:
  96. putstr_t *p = (putstr_t *)cmd.data;
  97. _d_putstr(p->str, p->col, p->row, p->reverse);
  98. disposer((void *)p);
  99. break;
  100. default:
  101. break;
  102. };
  103. }
  104. sleep_us(4*1000);
  105. }
  106. }
  107. // FIFO割り込み
  108. void sio_irq_handler(void)
  109. {
  110. while(multicore_fifo_rvalid()) {
  111. void *garbage = (void *)multicore_fifo_pop_blocking();
  112. free(garbage);
  113. }
  114. multicore_fifo_clear_irq();
  115. }
  116. // ディスプレイサブシステム初期化
  117. void display_init(void)
  118. {
  119. //queue初期化
  120. queue_init(&command_queue, sizeof(display_cmd_t), 8);
  121. // display_main起動
  122. multicore_launch_core1(display_main);
  123. // FIFO割り込みEnable
  124. irq_set_exclusive_handler(SIO_FIFO_IRQ_NUM(0), sio_irq_handler);
  125. irq_set_enabled(SIO_FIFO_IRQ_NUM(0), true);
  126. }