-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.c
executable file
·261 lines (237 loc) · 9.81 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
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
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
//================================================================//
// //
// AUTHOR : Martin Garaj <[email protected]> //
// PROJECT : Cyclone V Quadcopter (2017) //
// //
//================================================================//
//==============================================================================================//
// COMMENTS //
//==============================================================================================//
// LED Patterns
// | ON | ON | ON | - Reset state
#define RESET_STATE (0b00000111)
// | OFF| ON | OFF| - Initialization done
#define INITIALIZATION (0b00000010)
// | ON | OFF| ON | - Packet's checksum correct
#define CHECKSUM_CORRECT (0b00000101)
// | ON | OFF| ON | - Packet's checksum incorrect
#define CHECKSUM_INCORRECT (0b00000011)
// | ON | OFF| OFF| - Stalling
#define STALLING (0b00000100)
//==============================================================================================//
// #INCLUDEs //
//==============================================================================================//
#include <string.h>
#include <unistd.h> // usleep()
#include <io.h> // low-level Avalon MM access : IOWR_8DIRECT(), ...
#include "system.h" // FPGA memory mapping
#include "sys/alt_irq.h" // interrupt NIOS II functions
#include "config.h" // configuration file
#include "uart_0_interrupt_handler.h" // low-level uart register functions
#include "mem_functions.h" // shared memory functions2
#include "AUX_RADIO_constants.h" // shared memory composition & constants
#include "AUX_RADIO.h" // sensor function declarations
//==============================================================================================//
// #DEFINEs //
//==============================================================================================//
//==============================================================================================//
// MAIN //
//==============================================================================================//
int main(){
//==============================================================================================//
// DECLARATIONS //
//==============================================================================================//
// CONSTANTS
aux_radio_memory_map radio;
init_aux_radio(&radio, AUX_RADIO_0_MEM_BASE);
// VARIABLES
// UART variables for Radio communication
unsigned char byte = 0x00;
unsigned char previous_byte = 0x00;
unsigned char checksum = 0x00;
int packet_pointer = 0;
// Memory pointer
int pointer = 0;
// Data delivered to AUX_IMU
// UART baud-rate
uint32_t UART_baude_rate = 0;
// number of channels
uint32_t number_of_channels = 0; // NOT USED IN CURRENT DESIGN
// check-sum initial value
uint32_t checksum_init = 0;
// control_reg value
uint32_t control_reg = 0;
uint32_t routine_control_reg = 0;
// bool for initialization, to prevent repeating
bool init_done = false;
// FUNCTION CALLS
// register UART interrupt
void* uart_0_context;
alt_ic_isr_register( UART_0_IRQ_INTERRUPT_CONTROLLER_ID,
UART_0_IRQ,
uart_0_ISR,
uart_0_context,
NULL);
alt_ic_irq_enable( UART_0_IRQ_INTERRUPT_CONTROLLER_ID,
UART_0_IRQ);
#ifdef _DEBUG_
alt_printf("AUX_RADIO\n");
#endif
//==============================================================================================//
// MAIN LOOP //
//==============================================================================================//
while(true){
control_reg = get_control_reg(radio);
//==============================================================================================//
// RESET STATE //
//==============================================================================================//
if( !((control_reg&radio.control.reset_n)==radio.control.reset_n) ){
// Routine control register
routine_control_reg = 0;
// UART variables for Radio communication
byte = 0x00;
previous_byte = 0x00;
checksum = 0x00;
packet_pointer = 0;
// Memory pointer
pointer = 0;
// hps2aux data
// UART baud-rate
UART_baude_rate = 0;
// number of channels
number_of_channels = 0;
// check-sum initial value
checksum_init = 0;
// Initialization bool
init_done = false;
// set status flag : reset
set_status_flag_reset(radio);
// Reset state
SET_32REGISTER(AUX_RADIO_0_LED_BASE, 0x00, RESET_STATE);
#ifdef _DEBUG_
alt_printf("R");
#endif
//==============================================================================================//
// EXECUTION STATE //
//==============================================================================================//
}else if( (control_reg & radio.control.enable)==radio.control.enable ){
// set status flag : enable
set_status_flag_enable(radio);
#ifdef _DEBUG_
alt_printf("E");
#endif
//==============================================================================================//
// INITIALIZATION //
//==============================================================================================//
if( !init_done ){
#ifdef _DEBUG_
alt_printf("Initialization ...");
#endif
// Receive initialization data
// UART baud-rate
UART_baude_rate = get_hps2aux_reg(radio, 0);
// number of channels
number_of_channels = get_hps2aux_reg(radio, 1);
// check-sum initial value
checksum_init = get_hps2aux_reg(radio, 2);
// UART initialization
uart_0_initialize(UART_0_BASE, UART_baude_rate, ALT_CPU_FREQ);
// set initialization bool, to stop looping
init_done = true;
// set status flag : init
set_status_flag_init(radio);
// Initialization
SET_32REGISTER(AUX_RADIO_0_LED_BASE, 0x00, INITIALIZATION);
#ifdef _DEBUG_
alt_printf("Initialization DONE");
#endif
//==============================================================================================//
// ROUTINES //
//==============================================================================================//
}else{
routine_control_reg = get_routine_control_reg(radio);
//==============================================================================================//
// GENERAL ROUTINE //
//==============================================================================================//
// this routine is executed if AUX is not in reset and is enabled
#ifdef _DEBUG_
alt_printf("GR");
#endif
//
// ENTER ROUTINE HERE
//
//==============================================================================================//
// ENABLE-SPECIFIC ROUTINE //
//==============================================================================================//
// routines executed only when specific enable-bit is set
// RADIO ROUTINE-------------------------------------------------------//
if((routine_control_reg & radio.routine.control.enable[0]) == radio.routine.control.enable[0]){
set_routine_status_flag_enable(radio, 0);
// check RX fifo
if(!uart_0_fifo_empty()) {
// new char received
previous_byte = byte;
byte = uart_0_get_fifo_char();
packet_pointer++;
// detect start of the radio packet
if( (previous_byte == 0x20) && (byte == 0x40) ){
packet_pointer = 1; // previous byte was the first one, with byte order 0
checksum = checksum_init; // initial value of checksum is ~0x20 = 0xDF
};
// current_char inside radio packet
if( (packet_pointer>=1) && (packet_pointer<=29) ){
// calculate checksum
checksum = checksum + (~byte) + 1;
// bytes including CHANNEL values
if( (packet_pointer>=2) && (packet_pointer<=21) ){
// store in shared memory
pointer = packet_pointer - 2;
IOWR_8DIRECT(radio.base_address, radio.routine.packet.offset[0] + pointer, byte);
}
}
// checksum control, status register update, set LED
if( (packet_pointer==30) ){
if (checksum == byte){
#ifdef _DEBUG_
alt_printf("r+");
#endif
set_routine_status_flag_valid(radio, 0);
set_routine_status_flag_pkt_rdy(radio, 0);
// set LED | ON | ON |
SET_32REGISTER(AUX_RADIO_0_LED_BASE, 0x00, CHECKSUM_CORRECT);
}else{
#ifdef _DEBUG_
alt_printf("r-");
#endif
clear_routine_status_flag_valid(radio, 0);
set_routine_status_flag_pkt_rdy(radio, 0);
// set LED | ON | OFF|
SET_32REGISTER(AUX_RADIO_0_LED_BASE, 0x00, CHECKSUM_INCORRECT);
}
}
}
}
// OTHER ROUTINE-------------------------------------------------------//
// other routine goes below this line
//
// ENTER ROUTINE HERE
//
}
// NO CODE BELOW THIS LINE---------------------------------------------//
//==============================================================================================//
// STALLING //
//==============================================================================================//
}else{
#ifdef _DEBUG_
alt_printf("S");
#endif
clear_status_flag_enable(radio);
// set LED | OFF| OFF|
SET_32REGISTER(AUX_RADIO_0_LED_BASE, 0x00, STALLING);
}// control : enable
#ifdef _DEBUG_
alt_printf("\n");
#endif
}// while
return 0;
}// main