~ruther/vhdl-spi-2

ref: 53794430bb76a0986d8c96ef81c3135217ee23dc vhdl-spi-2/stm_spi_funduino/src/display.c -rw-r--r-- 3.9 KiB
53794430 — Rutherther fix(stm_spi_funduino): reception of spi numbers 3 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include "display.h"
#include "registers.h"

#define CYCLES 17

const char numbers_seven_segments[11] = {
  0x3F, /* 0 */
  0x06, /* 1 */
  0x5B, /* 2 */
  0x4F, /* 3 */
  0x66, /* 4 */
  0x6D, /* 5 */
  0x7D, /* 6 */
  0x07, /* 7 */
  0x7F, /* 8 */
  0x6F, /* 9 */
  0x40, /* - */
};

uint16_t pow16(uint16_t num, uint8_t pow) {
  for (uint16_t i = 0; i < pow; i++) {
    num *= num;
  }
  return num;
}


void display_init(display_t *display, uint16_t digits, pin_t pin_data,
                  pin_t pin_sftclk, pin_t pin_strobe) {
  display->digits_count = digits;

  for (uint8_t i = 0; i < display->digits_count; i++) {
    display->digits[i] = '\0';
  }

  display->digits_en = ~0;
  display->digit_dots = 0;

  display->pin_data = pin_data;
  display->pin_sftclk = pin_sftclk;
  display->pin_strobe = pin_strobe;

  display->max_value = pow16(10, digits);
  display->current_cycle = 0;
  display->current_shifter = 0;
  display->current_digit = 0;
}

uint16_t seven_segment_convert(char character, uint16_t digit, uint8_t dot);
uint16_t convert_num_digit(char character, uint8_t digits_count, uint8_t digit, uint8_t dot);

uint16_t seven_segment_convert(char character, uint16_t digit, uint8_t dot) {
  uint8_t data;

  if (character >= '0' && character <= '9') {
    data = numbers_seven_segments[character - '0'];
  } else {
    switch (character) {
    case 'E':
      data = 0b01111001;
      break;
    case 'r':
      data = 0b01010000;
      break;
    default:
      data = 0;
      break;
    }
  }

  return ~(data | dot << 7);
}

uint16_t convert_num_digit(char character, uint8_t digits_count, uint8_t digit, uint8_t dot) {
  uint16_t seven_segments = seven_segment_convert(character, digits_count - 1 - digit, dot);
  uint16_t digits = 1 << digit;

  return (seven_segments << 8) | digits;
}

void display_dots(display_t* display, uint8_t dots) {
  display->digit_dots = dots;
}

void display_convert_number(display_t *display, uint32_t number) {
  uint32_t digit = 0;
  for (uint8_t i = 0; i < display->digits_count; i++) {
    digit = (number % 10);
    display->digits[display->digits_count - 1 - i] = digit + '0';
    number /= 10;
  }
}

void display_enable_digit(display_t *display, uint8_t digit, uint8_t enable) {
  uint16_t digits = 1 << digit;
  if (enable != 0) {
    display->digits_en |= digits;
  } else {
    display->digits_en &= ~digits;
  }
}

void display_digits_set(display_t *display, char* digits) {
  for (uint8_t digit = 0; digit < display->digits_count; digit++) {
    display->digits[digit] = digits[digit];
  }
}

void display_digit_set(display_t *display, uint8_t digit, uint8_t number) {
  display->digits[digit] = number;
}

display_update_state_t display_update(display_t *display) {
  display_update_state_t state = DISPLAY_UPDATE_SHIFT;

  if (display->current_cycle == 0) {
    // Set up.
    display->current_digit = (display->current_digit + 1) % display->digits_count;

    if (display->digits_en & (1 << display->current_digit)) {
      display->current_shifter = convert_num_digit(
          display->digits[display->current_digit], display->digits_count, display->current_digit,
          (display->digit_dots >> display->current_digit) & 1);
    } else {
      // Still send the data even for disabled digits,
      // to prevent display having different brightness
      // depending on how many digits are currently on.
      display->current_shifter = 0;
    }

    state = DISPLAY_UPDATE_NEW_DIGIT;
  }

  if (display->current_cycle < CYCLES - 1) {
    pin_write(&display->pin_data,
              reg_read_bits_pos(&display->current_shifter,
                                15 - display->current_cycle,
                                1));

    pin_set(&display->pin_sftclk);
    pin_reset(&display->pin_sftclk);
  } else {
    // Send strobe
    pin_set(&display->pin_strobe);
    pin_reset(&display->pin_strobe);

    state = DISPLAY_UPDATE_DISPLAY_DIGIT;
  }

  display->current_cycle = (display->current_cycle + 1) % CYCLES;

  return state;
}
Do not follow this link