/
main.c
135 lines (116 loc) · 3.49 KB
/
main.c
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
/*
* main.c
*
* Created on: Jun 19, 2018
* Author: Erol
*/
/******************************************************************************/
/* INCLUDES */
/******************************************************************************/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include "project.h"
#include "USART.h"
#include "main.h"
#include "rx.h"
#include "timer.h"
/******************************************************************************/
/* GLOBAL VARIABLES & DECLARATIONS */
/******************************************************************************/
uint32_t thr_r = 50, thr_g = 0, thr_b = 0; // pwm levels
static int uart_putchar(char c, FILE *stream);
static FILE uart_fd = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_RW);
/******************************************************************************/
/* FUNCTIONS */
/******************************************************************************/
int main()
{
#ifdef PROJECT_BOARD_LCD // specific to my board
#include "LCD.h"
LCD_init();
LCD_put_string(" [www.netb.st] github.com/ergor/rgb");
LCD_send_cmd(LCD_CMD_SEL_LINE_2);
LCD_put_string(" clone the project github.com/ergor/rgb");
LCD_send_cmd(LCD_CMD_CURSOR_OFF);
#endif
stdout = &uart_fd;
stdin = &uart_fd;
USART_init(recv);
DIR_REG |= PIN_R | PIN_G | PIN_B;
// oc_val=100: refresh rate > 50 HZ (156 for ~50Hz)
timer0_isr_init(100, CS_8x_PRESCALE);
uint32_t text_cycle = 0;
while (1) {
// case: timer has overflowed and swapped bank,
// the old bank is now available for generating new pwm sequence:
if (t_ov) {
gen_pwm();
t_ov = 0;
}
// a complete string is ready for reading
if (data_ready) {
parse_val();
data_ready = 0;
}
// else poll the receive done flag in rx.c
if (rx_done) {
//printf("\n%s OK\n", rx_data);
//UDR0 = rx_char;
uart_putchar(rx_char, NULL);
recv();
rx_done = 0;
}
#ifdef PROJECT_BOARD_LCD
if (text_cycle == 150000) {
LCD_send_cmd(LCD_CMD_SHIFTLEFT);
text_cycle = 0;
}
text_cycle++;
#endif
}
}
static int uart_putchar(char c, FILE *stream)
{
if (c == '\n')
uart_putchar('\r', stream);
//c = '\r';
#ifdef __AVR_ATmega16__
loop_until_bit_is_set(UCSRA, UDRE);
UDR = c;
#elif __AVR_ATmega328p__
loop_until_bit_is_set(UCSR0A, UDRE0);
UDR0 = c;
#else
#error "Target implementation needed"
#endif
return 0;
}
void parse_val()
{
char* data = rx_data;
thr_r = /*k * */ strtol(data, &data, 16);
thr_g = /*k * */ strtol(data, &data, 16);
thr_b = /*k * */ strtol(data, &data, 16);
//thr_r = thr_r == 0 ? 255 : 0;
printf("r: %03lu, g: %03lu, b: %03lu\n", thr_r, thr_g, thr_b);
}
void gen_pwm()
{
// lut_bank is the current bank in use; we must use the opposite bank
uint8_t bank = lut_bank ^ 1;
uint8_t* ptr = pwm_lut + (bank * RESL);
uint8_t mask;
for (uint16_t i = 0; i < RESL; i++) {
mask = 0;
if (i < thr_r)
mask |= PIN_R;
if (i < thr_g)
mask |= PIN_G;
if (i < thr_b)
mask |= PIN_B;
ptr[i] = mask;
}
}