DIY Auto-Correlator 1.0
Auto-Correlator Card implementation using Teensy 4.x microcontrollers.
featureline1.hpp
Go to the documentation of this file.
1#pragma once
2#include <Arduino.h>
3#include <imxrt.h>
4
5#include "global.hpp"
6#include "./../code/software/monitor_channel.hpp"
7#include "./../code/software/histogram.hpp"
8
9
10#include "./../code/hardware/pins.hpp"
11#include "./../code/hardware/utilities.hpp"
12#include "./../code/hardware/ledpanel.hpp"
13#include "./../code/hardware/errors.hpp"
14#include "./../code/hardware/pit.hpp"
15#include "./../code/hardware/qtmr1.hpp"
16#include "./../code/hardware/perf_counter.hpp"
17
18
19
20//======================================================
21
22// /$$$$$$ /$$$$$$ /$$$$$$$
23// |_ $$_/ /$$__ $$| $$__ $$
24// | $$ | $$ \__/| $$ \ $$
25// | $$ | $$$$$$ | $$$$$$$/
26// | $$ \____ $$| $$__ $$
27// | $$ /$$ \ $$| $$ \ $$
28// /$$$$$$| $$$$$$/| $$ | $$
29// |______/ \______/ |__/ |__/
31void isr_fn() //__attribute__((interrupt ("FIQ")))
32{
33 //1. PIT Starts Counting
34 IMXRT_PIT_CHANNELS[PIT_CHANNEL_IN_USE].TFLG = 1;
35
36 //2. Starts counting again after reset
37 IMXRT_TMR1.CH[0].SCTRL &= ~TMR_SCTRL_IEF; //Clear Edge Flag
38
39 //3. Read Counter Value
40 Counter_val = IMXRT_TMR1.CH[0].CNTR;
41
42 //4. Reset Couter
43 IMXRT_TMR1.CH[0].CNTR = 0; //Reset Counter to 0.
44
45 //5. Assert Update Flag
46 Update_flag = true;
47
48 asm volatile ("dsb");
49 //-6. Toggle Pin for debugging
50 #if ISR_PIN_TOGGLE == 1
51 digitalToggleFast(ISR_TEST_TOOGLE_PIN);
52 #endif
53}
54
55
56// /$$ /$$
57// |__/ | $$
58// /$$$$$$$ /$$$$$$ /$$$$$$ /$$ /$$$$$$ | $$
59// /$$_____/ /$$__ $$ /$$__ $$| $$ |____ $$| $$
60// | $$$$$$ | $$$$$$$$| $$ \__/| $$ /$$$$$$$| $$
61// \____ $$| $$_____/| $$ | $$ /$$__ $$| $$
62// /$$$$$$$/| $$$$$$$| $$ | $$| $$$$$$$| $$
63// |_______/ \_______/|__/ |__/ \_______/|__/
65void inline serial_out()
66{
67
68 //0. Start performance counting when enabled
69 #if ENABLE_PERFORMANCE_COUNTERS == 1
70 Serialpf.start();
71 #endif
72
73 //1.0 Sync Code
74 #if ENABLE_SYNC_CODE == 1
75 Serial.write((uint8_t*)&(sync_code), sizeof(int32_t));
76 #endif
77
78 //2. Count Rate
79 #if ENABLE_COUNT_RATE == 1
80 float mean = count_rate_mon.output();
81 Serial.write((uint8_t*)&(mean), sizeof(float));
82 #endif
83
84 //3. Points FED
85 #if (ENABLE_POINTS_NORM == 1) && (ENABLE_ACF_CALC == 1)
86 Serial.write((uint8_t*)&(multitau.MeanMonitor.Count), sizeof(float));
87 #endif
88
89 //4. Mean/Accumulate
90 #if ENABLE_MEAN_NORM == 1
91 float_t accumulate = multitau.MeanMonitor.accumulate();
92 Serial.write((uint8_t*)&(accumulate), sizeof(float_t));
93 #endif
94
95 //5. ACF
96 #if ENABLE_ACF_CALC == 1
97 multitau.ch_out(); // Initial output of zeroes to check the channel fields.
98 #endif
99
100
101 //6. Histogram
102 #if ENABLE_PC_HISTOGRAM == 1
103 hist.output();
104 #endif
105
106
107 //7. Performance counters
108 #if ENABLE_PERFORMANCE_COUNTERS == 1
109 float_t pf_serial = Serialpf.mean();
110 Serial.write((uint8_t*)&(pf_serial), sizeof(float_t));
111
112 #if ENABLE_ACF_CALC == 1
113 float_t pf_acf = ACFpf.mean();
114 Serial.write((uint8_t*)&(pf_acf), sizeof(float_t));
115 #endif
116
117 Serialpf.end();
118 #endif
119
120 //-.
121 //Serial.flush()
122}
123
124
125
126// /$$$$$$ /$$
127// /$$__ $$ | $$
128// | $$ \__/ /$$$$$$ /$$$$$$ /$$ /$$ /$$$$$$
129// | $$$$$$ /$$__ $$|_ $$_/ | $$ | $$ /$$__ $$
130// \____ $$| $$$$$$$$ | $$ | $$ | $$| $$ \ $$
131// /$$ \ $$| $$_____/ | $$ /$$| $$ | $$| $$ | $$
132// | $$$$$$/| $$$$$$$ | $$$$/| $$$$$$/| $$$$$$$/
133// \______/ \_______/ \___/ \______/ | $$____/
134// | $$
135// | $$
136// |__/
139{
140 //1. LEDPanel Indicator Setup
141 LEDPanel.init(); //Set Pinmode for all LEDs.
142 LEDPanel.set(SETUP_LED);
143 LEDPanel.toggle_twice(SETUP_LED, 2000);
144
145 //2. Pin Modes
146 #if ISR_PIN_TOGGLE == 1
147 pinMode(ISR_TEST_TOOGLE_PIN, OUTPUT);
148 #endif
149 pinMode(TTL_C_PULSE_INPUT_PIN, INPUT);
150
151 // 3.1. PIT_t Setup
152 PI_t.enable_PITs(); //Enable all PITs
153 PI_t.sel_FBUS_clock(); //Select 150MHz clock
154 PI_t.interrupt(); //Enable Interrupts
155 PI_t.set_interrupt(isr_fn, 255); //Set interrupt
156 // 3.2. Colllect Errors
157 Error_t er_invalid_gt = PI_t.set_gate_time(Gate_time_us);
158 Error_t er_period_precision = Errors::Precison_Threshold(PI_t.period_error_us(), Allowed_period_error_us);
159
160 //4. TTL_C Setup
161 TTL_c.init();
163
164
165 //5. Set Serial Sampling Time
166 extern uint32_t serial_max_count(double Gate_time_u, double Serial_out_time_ms);
167 SerialOut_After = serial_max_count(GATE_TIME_US, SAMPLING_TIME_MS);
168
169 //6. Error Validation Validation
170 Errors::Validate(er_invalid_gt);
171 Errors::Validate(er_period_precision);
172 Errors::Validate(Errors::Auto_MultiTau_Input_Validator<LIN_CORRS, SERIES_SIZE, BIN_RATIO>());
173 LEDPanel.assert_errors();
174
175
176 //7. Serial Setup
177 Serial.begin(115200);
178 while(!Serial){}
179
180 //7.1 Serial Output of zeroes
181 serial_out();
182
183 //8.
184 LEDPanel.unset(SETUP_LED);
185 asm volatile ("dsb");
186
187 for(unsigned int i = 0; i < CHANNEL_SIZE; i++)
188 {
189 array[i] = i;
190 }
191} // End of setup()
192
193
194
195// /$$
196// | $$
197// | $$ /$$$$$$ /$$$$$$ /$$$$$$
198// | $$ /$$__ $$ /$$__ $$ /$$__ $$
199// | $$ | $$ \ $$| $$ \ $$| $$ \ $$
200// | $$ | $$ | $$| $$ | $$| $$ | $$
201// | $$$$$$$$| $$$$$$/| $$$$$$/| $$$$$$$/
202// |________/ \______/ \______/ | $$____/
203// | $$
204// | $$
205// |__/
206
209{
210 // Assert Loop LED Indicator if the device is not in error state
211 if(!LEDPanel.Error_State)
212 {
213 LEDPanel.set(LOOP_LED);
214 LEDPanel.dim(LOOP_LED, 124);
215 }
216
217 //Entropy.Initialize();
218 TTL_c.start();
219 PI_t.start();
220 asm volatile ("dsb");
221
222 while(1)
223 {
224 if(Update_flag) //Calculate Multi-tau correlation
225 {
226 noInterrupts(); //Disable all interrupts
227
228 Update_flag = false;
229 Update_count++;
230
231 // Push Backs ↓
232 #if ENABLE_COUNT_RATE == 1
233 count_rate_mon.push_back(Counter_val);
234 #endif
235
236 #if ENABLE_PC_HISTOGRAM == 1
237 hist.push_back(Counter_val);
238 #endif
239
240 #if ENABLE_ACF_CALC == 1
241 #if ENABLE_PERFORMANCE_COUNTERS == 1
242 ACFpf.start();
243 #endif
244
245 multitau.push_datum(Counter_val);
246
247 #if ENABLE_PERFORMANCE_COUNTERS == 1
248 ACFpf.end();
249 #endif
250 #endif
251
252
254 { Update_count = 0; //Reset Update_count
255
256 serial_out();
257
258 }//Serial Block
259
260 }//Update Block
261 interrupts(); //Enable all interrupts
262
263 }//While Loop
264
265
266 // <<while loop breaks>> (rare case)↓
267 LEDPanel.unset(LOOP_LED);
268 LEDPanel.set_all();
269 abort();
270} //End of loop()
static Error_t Precison_Threshold(double error_val, double error_limit)
Receives error value and error threshold and returns an appropriate error state.
Definition: errors.hpp:44
static void Validate(const Error_t error)
Receives an error state and sets up the corresponding LED indicator.
Definition: errors.hpp:31
void init_pins() __attribute__((always_inline))
Sets the Primary and Secondary inputs for Capture Mode, routed through XBAR. Reference XBAR and IOMUX...
Definition: qtmr1.hpp:185
void start() __attribute__((always_inline))
Starts up-counting from the set counter value.
Definition: qtmr1.hpp:24
void init() __attribute__((always_inline))
Definition: qtmr1.hpp:107
Error_t
Enumarates the error codes thrown by the different modules.
Definition: errors.hpp:17
#define PIT_CHANNEL_IN_USE
Definition: types.hpp:12
void gt_setup()
Setup function for Initalization and setup.
Definition: featureline1.hpp:138
void isr_fn()
ISR function used for processing counter values.
Definition: featureline1.hpp:31
void gt_loop()
Loop function that processes the updates from the counters.
Definition: featureline1.hpp:208
void serial_out()
Outputs the data struct to the serial buffer.
Definition: featureline1.hpp:65
const double Gate_time_us
Serial output is done after these many updates (default → overriden in the setup function).
Definition: global.cpp:29
TMR1Controller TTL_c
TTL_c Resource.
Definition: global.cpp:19
uint32_t SerialOut_After
Definition: global.cpp:28
const int32_t sync_code
Gate time precision error due to finite precision of timers.
Definition: global.cpp:31
float array[CHANNEL_SIZE]
Definition: global.cpp:33
const double Allowed_period_error_us
The gate time of TTL_C in microseconds (us)
Definition: global.cpp:30
volatile unsigned int Update_count
Stores the number of updates made on the correlator channels since the last serialout.
Definition: global.cpp:25
PITController< PIT_CHANNEL_IN_USE > PI_t
PI_t Resource.
Definition: global.cpp:18
volatile bool Update_flag
Indicates if a new value has arrived from the counting module.
Definition: global.cpp:24
volatile counter_t Counter_val
Stores the value read from the counter.
Definition: global.cpp:23
LEDSet< 5 > LEDPanel({LED_BUILTIN, LED_RED, LED_GREEN, LED_WHITE, LED_BLUE})
Definition: multitau.py:1
const int LOOP_LED
Definition: pins.hpp:30
const int SETUP_LED
Definition: pins.hpp:29
const int TTL_C_PULSE_INPUT_PIN
Definition: pins.hpp:19
uint32_t serial_max_count(double Gate_time_us, double Serial_out_time_ms)
Definition: utilities.cpp:7