-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdisplay.c
More file actions
140 lines (116 loc) · 4.26 KB
/
display.c
File metadata and controls
140 lines (116 loc) · 4.26 KB
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
#include "display.h"
#include "system_config.h"
#include <string.h>
#include <math.h>
#include <stdio.h>
// Seven-segment display patterns for digits 0-9
// Common cathode: segments a,b,c,d,e,f,g (bit 0-6), decimal point (bit 7)
static const uint8_t segment_patterns[] = {
0x3F, // 0: a,b,c,d,e,f
0x06, // 1: b,c
0x5B, // 2: a,b,d,e,g
0x4F, // 3: a,b,c,d,g
0x66, // 4: b,c,f,g
0x6D, // 5: a,c,d,f,g
0x7D, // 6: a,c,d,e,f,g
0x07, // 7: a,b,c
0x7F, // 8: a,b,c,d,e,f,g
0x6F // 9: a,b,c,d,f,g
};
// Initialize display
void display_init(display_t *display) {
if (display == NULL) return;
display->mode = DISPLAY_MODE_IDLE;
display->value_to_display = 0.0f;
display->led_indicator_on = false;
memset(display->segment_data, 0, sizeof(display->segment_data));
}
// Update display with measurement value
void display_update(display_t *display, float value_mm, bool object_detected) {
if (display == NULL) return;
// Update LED indicator
display_set_led_indicator(display, object_detected);
// Update display mode
if (object_detected) {
display->mode = DISPLAY_MODE_MEASURING;
} else if (value_mm > 0.0f) {
display->mode = DISPLAY_MODE_RESULT;
display_show_value(display, value_mm);
} else {
display->mode = DISPLAY_MODE_IDLE;
display_clear(display);
}
}
// Set LED indicator state
void display_set_led_indicator(display_t *display, bool on) {
if (display == NULL) return;
display->led_indicator_on = on;
// In real implementation, this would write to GPIO pin
// gpio_write(LED_INDICATOR_PIN, on ? 1 : 0);
}
// Convert float value to seven-segment display
void display_show_value(display_t *display, float value_mm) {
if (display == NULL) return;
display->value_to_display = value_mm;
// Convert float to integer (multiply by 10 to show one decimal place)
int value_tenths = (int)(value_mm * 10.0f + 0.5f);
// Extract digits (assuming 4-digit display: XXX.X)
int thousands = (value_tenths / 10000) % 10;
int hundreds = (value_tenths / 1000) % 10;
int tens = (value_tenths / 100) % 10;
int ones = (value_tenths / 10) % 10;
int tenths = value_tenths % 10;
// Determine how many digits to display
int digits_to_show = 0;
if (thousands > 0) digits_to_show = 5;
else if (hundreds > 0) digits_to_show = 4;
else if (tens > 0) digits_to_show = 3;
else digits_to_show = 2;
// Prepare segment data
int seg_idx = 0;
if (digits_to_show >= 5) {
display->segment_data[seg_idx++] = display_digit_to_segments(thousands);
}
if (digits_to_show >= 4) {
display->segment_data[seg_idx++] = display_digit_to_segments(hundreds);
}
if (digits_to_show >= 3) {
display->segment_data[seg_idx++] = display_digit_to_segments(tens) | 0x80; // Add decimal point
}
if (digits_to_show >= 2) {
display->segment_data[seg_idx++] = display_digit_to_segments(ones);
}
if (digits_to_show >= 1) {
display->segment_data[seg_idx++] = display_digit_to_segments(tenths);
}
// Clear remaining segments
for (int i = seg_idx; i < 4; i++) {
display->segment_data[i] = 0;
}
// Write to display hardware
display_write_segments(display->segment_data, seg_idx);
}
// Clear display
void display_clear(display_t *display) {
if (display == NULL) return;
memset(display->segment_data, 0, sizeof(display->segment_data));
display_write_segments(display->segment_data, 0);
display->value_to_display = 0.0f;
}
// Convert digit to seven-segment code
uint8_t display_digit_to_segments(uint8_t digit) {
if (digit < 10) {
return segment_patterns[digit];
}
return 0; // Blank for invalid digits
}
// Write to display hardware (to be implemented based on hardware)
void display_write_segments(uint8_t *segments, uint8_t count) {
// In real implementation, this would interface with FPGA display controller
// This could use SPI, I2C, or parallel GPIO depending on the display hardware
// Example: spi_write(DISPLAY_SPI_BUS, segments, count);
// Placeholder: Print to console for debugging
(void)segments;
(void)count;
// printf("Display: %d segments\n", count);
}