| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- #include <stdio.h>
- #include <stdlib.h>
- #include "pico/stdlib.h"
- #include "hardware/pio.h"
- #include "TM1637.h"
- #include "tm1637out.pio.h"
- const uint8_t digit_seg[] = {
- 0b00111111, // 0
- 0b00000110, // 1
- 0b01011011, // 2
- 0b01001111, // 3
- 0b01100110, // 4
- 0b01101101, // 5
- 0b01111101, // 6
- 0b00000111, // 7
- 0b01111111, // 8
- 0b01101111, // 9
- };
- const uint8_t letter_seg[] = {
- 0b01110111, // A
- 0b01111100, // b
- 0b00111001, // C
- 0b01011110, // d
- 0b01111001, // E
- 0b01110001, // F
- 0b00111101, // G
- 0b01110110, // H
- 0b00000100, // i
- 0b00001110, // J
- 0b00000000, // K
- 0b00111000, // L
- 0b00000000, // M
- 0b01010100, // n
- 0b01011100, // o
- 0b01110011, // P
- 0b01100111, // q
- 0b01010000, // r
- 0b01101101, // S
- 0b01111000, // t
- 0b00011100, // u
- 0b00000000, // V
- 0b00000000, // W
- 0b00000000, // X
- 0b01101110, // y
- 0b00000000, // z
- };
- // 先頭のTM1637_tのポインタ
- static TM1637_t *first = NULL;
- // 文字コード→セグメントコード
- uint32_t chr_to_seg(char c)
- {
- if(c >= '0' && c <= '9')
- return digit_seg[c - '0'];
- if(c >= 'a' && c <= 'z')
- return letter_seg[c - 'a'];
- if( c >= 'A' && c <= 'Z')
- return letter_seg[c - 'A'];
- if( c == ':' || c == '.')
- return DOT_SEG;
- if( c == '-' )
- return MINUS_SEG;
- return 0;
- }
- // TM1637を追加する
- int TM1637_add(TM1637_t *next)
- {
- if (first == NULL) {
- first = next;
- return 0;
- }
- TM1637_t *p = first;
- while(p->next != NULL)
- p = p->next;
-
- p->next = next;
- return 0;
- }
- TM1637_t *TM1637_init(uint8_t sda_base_pin, uint8_t col, uint8_t cont)
- {
- uint8_t colmns, contrast;
- PIO pio;
- uint sm, pio_offset;
- TM1637_t *p;
- // デフォルト値の設定
- if(col <= TM1637_MAX_COL && col > 0)
- colmns = col;
- else
- return NULL;
-
- if(cont <= TM1637_MAX_CONTRAST)
- contrast = cont;
- else
- return NULL;
-
- if(pio_claim_free_sm_and_add_program(&tm1637out_program, &pio, &sm, &pio_offset)) {
- // PIO初期化
- tm1637out_program_init(pio, sm, pio_offset, sda_base_pin, sda_base_pin+1);
- // SM起動
- pio_sm_set_enabled(pio, sm, true);
- }
- else // PIOを確保できなかった
- return NULL;
-
- // ここまでできたら初期化成功と見て構造体を作成する
- p = (TM1637_t *)malloc(sizeof(TM1637_t));
- p->colmns = colmns;
- p->contrast = contrast;
- p->pio = pio;
- p->sm = sm;
- p->offset = pio_offset;
- p->next = NULL;
- p->initialized = true;
- // 末尾に追加
- TM1637_add(p);
-
- // TM1637初期化
- // データセット(自動アドレスインクリメント)
- pio_sm_put_blocking(pio, sm, TM1637_AUTOINC | STOP_COND);
- // アドレス0からカラム数分を0で初期化
- pio_sm_put_blocking(pio, sm, TM1637_ADDRSET| 0 );
- for(int i = 0; i < colmns; i++) {
- uint32_t data = 0;
- if( i == (colmns - 1) )
- data = STOP_COND;
- pio_sm_put_blocking(pio, sm, data);
- }
- // コントラスト値で表示オン
- TM1637_set_contrast(p, contrast);
- return p;
- }
- int TM1637_set_contrast(TM1637_t *p, uint8_t cont)
- {
- if(cont <= TM1637_MAX_CONTRAST)
- p->contrast = cont;
- else
- return TM1637_ERR_INVALID_PARAM;
- pio_sm_put_blocking(p->pio, p->sm, TM1637_DISPON | cont | STOP_COND);
- return 0;
- }
- int TM1637_putchar(TM1637_t *p, char c, bool dot,uint8_t col)
- {
- if(col >= p->colmns)
- return TM1637_ERR_INVALID_PARAM;
- // 固定アドレスデータセット
- pio_sm_put_blocking(p->pio, p->sm, TM1637_DATASET | STOP_COND);
- // アドレス
- pio_sm_put_blocking(p->pio, p->sm, TM1637_ADDRSET | col);
- // セグメントデータ
- pio_sm_put_blocking(p->pio, p->sm, chr_to_seg(c) | (dot ? DOT_SEG : 0) | STOP_COND);
- return 0;
- }
- int TM1637_putstr(TM1637_t *t, char *str)
- {
- int col = 0, p = 0;
- // データセット(自動アドレスインクリメント)
- pio_sm_put_blocking(t->pio, t->sm, TM1637_AUTOINC | STOP_COND);
- // アドレス0セット
- pio_sm_put_blocking(t->pio, t->sm, TM1637_ADDRSET| 0 );
- // 文字数分を出力
- while(str[col] != '\0') {
- uint32_t data = chr_to_seg(str[col++]);
- // ドットマーク
- if(str[col] == '.' || str[col] == ':') {
- data |= DOT_SEG;
- col++;
- }
- // 最後はStop Condition
- if(str[col] == '\0' || ++p >= t->colmns) data |= STOP_COND;
- pio_sm_put_blocking(t->pio, t->sm, data);
- // カラム数に達したら終わり
- if( p >= t->colmns )
- break;
- }
- return 0;
- }
|