/
app_main.c
214 lines (180 loc) · 6.31 KB
/
app_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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2017, DUKELEC, Inc.
* All rights reserved.
*
* Author: Duke Fong <d@d-l.io>
*/
#include "math.h"
#include "app_main.h"
int CDCTL_SYS_CLK = 150000000; // 150MHz for cdctl01a
gpio_t led_r = { .group = LED_R_GPIO_Port, .num = LED_R_Pin };
gpio_t led_g = { .group = LED_G_GPIO_Port, .num = LED_G_Pin };
static gpio_t led_cam = { .group = LED_CAM_GPIO_Port, .num = LED_CAM_Pin };
uart_t debug_uart = { .huart = &huart1 };
static gpio_t r_int = { .group = CD_INT_GPIO_Port, .num = CD_INT_Pin };
static gpio_t r_cs = { .group = CD_CS_GPIO_Port, .num = CD_CS_Pin };
static spi_t r_spi = { .hspi = &hspi1, .ns_pin = &r_cs };
gpio_t pga_rst = { .group = PGA_RST_GPIO_Port, .num = PGA_RST_Pin };
static gpio_t pga_int = { .group = PGA_INT_GPIO_Port, .num = PGA_INT_Pin };
gpio_t pga_cs = { .group = PGA_CS_GPIO_Port, .num = PGA_CS_Pin };
static spi_t pga_spi = { .hspi = &hspi2, .ns_pin = &pga_cs };
cd_frame_t frame_alloc[FRAME_MAX];
list_head_t frame_free_head = {0};
static cdn_pkt_t packet_alloc[PACKET_MAX];
list_head_t packet_free_head = {0};
cdctl_dev_t r_dev = {0}; // CDBUS
cdn_ns_t dft_ns = {0}; // CDNET
camctl_dev_t cam_dev = {0}; // Camera Controller
static void device_init(void)
{
int i;
cdn_init_ns(&dft_ns, &packet_free_head);
for (i = 0; i < FRAME_MAX; i++)
list_put(&frame_free_head, &frame_alloc[i].node);
for (i = 0; i < PACKET_MAX; i++)
list_put(&packet_free_head, &packet_alloc[i].node);
cdctl_dev_init(&r_dev, &frame_free_head, &csa.bus_cfg, &r_spi, NULL, &r_int);
if (r_dev.version >= 0x10) {
// 16MHz / (2 + 2) * (73 + 2) / 2^1 = 150MHz
cdctl_write_reg(&r_dev, REG_PLL_N, 0x2);
d_info("pll_n: %02x\n", cdctl_read_reg(&r_dev, REG_PLL_N));
cdctl_write_reg(&r_dev, REG_PLL_ML, 0x49); // 0x49: 73
d_info("pll_ml: %02x\n", cdctl_read_reg(&r_dev, REG_PLL_ML));
d_info("pll_ctrl: %02x\n", cdctl_read_reg(&r_dev, REG_PLL_CTRL));
cdctl_write_reg(&r_dev, REG_PLL_CTRL, 0x10); // enable pll
d_info("clk_status: %02x\n", cdctl_read_reg(&r_dev, REG_CLK_STATUS));
cdctl_write_reg(&r_dev, REG_CLK_CTRL, 0x01); // select pll
d_info("clk_status after select pll: %02x\n", cdctl_read_reg(&r_dev, REG_CLK_STATUS));
d_info("version after select pll: %02x\n", cdctl_read_reg(&r_dev, REG_VERSION));
} else {
d_info("fallback to cdctl-b1 module, ver: %02x\n", r_dev.version);
CDCTL_SYS_CLK = 40000000; // 40MHz
cdctl_set_baud_rate(&r_dev, csa.bus_cfg.baud_l, csa.bus_cfg.baud_h);
}
cdn_add_intf(&dft_ns, &r_dev.cd_dev, csa.bus_net, csa.bus_cfg.mac);
camctl_dev_init(&cam_dev, &frame_free_head, &pga_spi, &pga_int);
}
void set_led_state(led_state_t state)
{
static bool is_err = false;
if (is_err)
return;
switch (state) {
case LED_POWERON:
gpio_set_value(&led_r, 0);
gpio_set_value(&led_g, 1);
break;
case LED_WARN:
gpio_set_value(&led_r, 1);
gpio_set_value(&led_g, 0);
break;
default:
case LED_ERROR:
is_err = true;
gpio_set_value(&led_r, 1);
gpio_set_value(&led_g, 1);
break;
}
}
extern uint32_t end; // end of bss
#define STACK_CHECK_SKIP 0x200
#define STACK_CHECK_SIZE (16 + STACK_CHECK_SKIP)
static void stack_check_init(void)
{
int i;
printf("stack_check_init: skip: %p ~ %p, to %p\n",
&end, &end + STACK_CHECK_SKIP, &end + STACK_CHECK_SIZE);
for (i = STACK_CHECK_SKIP; i < STACK_CHECK_SIZE; i+=4)
*(uint32_t *)(&end + i) = 0xababcdcd;
}
static void stack_check(void)
{
int i;
for (i = STACK_CHECK_SKIP; i < STACK_CHECK_SIZE; i+=4) {
if (*(uint32_t *)(&end + i) != 0xababcdcd) {
printf("stack overflow %p (skip: %p ~ %p): %08lx\n",
&end + i, &end, &end + STACK_CHECK_SKIP, *(uint32_t *)(&end + i));
d_error("stack overflow %p (skip: %p ~ %p): %08lx\n",
&end + i, &end, &end + STACK_CHECK_SKIP, *(uint32_t *)(&end + i));
while (true);
}
}
}
#if 1
static void dump_hw_status(void)
{
static int t_l = 0;
if (get_systick() - t_l > 8000) {
t_l = get_systick();
d_debug("ctl: state %d, t_len %d, r_len %d, irq %d\n",
r_dev.state, r_dev.tx_head.len, r_dev.rx_head.len,
!gpio_get_value(r_dev.int_n));
d_debug(" r_cnt %d (lost %d, err %d, no-free %d), t_cnt %d (cd %d, err %d)\n",
r_dev.rx_cnt, r_dev.rx_lost_cnt, r_dev.rx_error_cnt,
r_dev.rx_no_free_node_cnt,
r_dev.tx_cnt, r_dev.tx_cd_cnt, r_dev.tx_error_cnt);
d_debug("cam: state %d, r_len %d, irq %d | r_cnt %d (lost %d, no-free %d)\n",
cam_dev.state, cam_dev.rx_head.len, !gpio_get_value(cam_dev.int_n),
cam_dev.rx_cnt, cam_dev.rx_lost_cnt, cam_dev.rx_no_free_node_cnt);
}
}
#endif
void app_main(void)
{
printf("\nstart app_main (cam)...\n");
stack_check_init();
load_conf();
pga_config();
debug_init(&dft_ns, &csa.dbg_dst, &csa.dbg_en);
device_init();
debug_flush(true);
common_service_init();
d_info("conf (cam): %s\n", csa.conf_from ? "load from flash" : "use default");
csa_list_show();
app_cam_init();
set_led_state(LED_POWERON);
while (true) {
stack_check();
dump_hw_status();
app_cam_routine();
cdn_routine(&dft_ns); // handle cdnet
common_service_routine();
gpio_set_value(&led_cam, csa.led_en);
debug_flush(false);
}
}
void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == r_int.num) {
cdctl_int_isr(&r_dev);
} else if (GPIO_Pin == pga_int.num) {
camctl_int_isr(&cam_dev);
}
}
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
if (hspi == &hspi1)
cdctl_spi_isr(&r_dev);
else
camctl_spi_isr(&cam_dev);
}
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
if (hspi == &hspi1)
cdctl_spi_isr(&r_dev);
else
camctl_spi_isr(&cam_dev);
}
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
if (hspi == &hspi1)
cdctl_spi_isr(&r_dev);
else
camctl_spi_isr(&cam_dev);
}
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
{
printf("spi error... [%08lx]\n", hspi->ErrorCode);
}