CROSS Technical Documentation User Manual and Technical Doc.
INFN Milano Bicocca
Loading...
Searching...
No Matches
Preamplifier_Offset_Drift_Correcttion.c
Go to the documentation of this file.
1#include "tutti_gli_header.h"
2
3
4/*****DOCUMENTAZIONE DOXYGEN (premi il - a sinistra per ridurla a icona) il manuale html \'e nella cartella************/
5/// \file
6
7/*! \page Preamplifier_Offset_Drift_Correcttion_page The preamplifier Offset Drift Correcttion
8\brief <span style="color:red;"> <b> Preamplifier Offset Drift Correcttion </b> </span>
9*\tableofcontents
10
11 \b SUMMARY:
12<ul>
13<li> \ref introduction_to_preamplifier_corrections </li>
14<li> \ref Effects_of_trimmers_on_preamplifier </li>
15<li> \ref Preamplifier_PGA_offset_setting
16 <ul>
17 <li> \ref SAR_procedure </li>
18 <li> \ref FAST_SAR_procedure </li>
19 </ul>
20</li>
21<li> \ref Node_measurements_with_internal_external_ADC</li>
22<li> \ref sw_detail_pre </li>
23</ul>
24
25*\section introduction_to_preamplifier_corrections Trimmer usage with preamplifier
26<hr width="90%" size="10" align="left">
27
28\n The preamplifier has a quad trimmer <a href="./File_pdf/AD5263.pdf" target=_blank><b>AD5263</b></a>.
29Two of the 4 trimmers are exploited to adjust the output offset voltage, coarse ancd fine. The third trimmer
30is for drift compensation while the last trimmer is for CMRR mitigation.
31The 4 trimmers are defined this way:
32
33<ol start="0">
34 <li> #trimmer_CMRR_compensation
35 <li> #trimmer_fine_offset
36 <li> #trimmer_thermal_compensation
37 <li> #trimmer_coarse_offset
38 </li>
39</ol>
40\n To write or read any trimmer we use only one function:
41preamplifier_scrittura_lettura_trimmer(uint8_t scheda_su_scheda_giu, uint8_t canale, uint8_t trimmer,uint8_t valore, uint8_t scrivi_1_leggi_0 )
42where:
43- \b scheda_su_scheda_giu is the board where the trimmer is;
44- \b canale is the preamplifier channel (0 to 5);
45- \b trimmer is one of the 4 trimmers to write or to read (0 to 3 of the list above);
46- \b valore is the value to write, a unsigned int8 (0 to 255);
47- \b scrivi_1_leggi_0 is boolean: when true a write of \b valore is done, if 0 a reading of the content is done. For both cases
48the values of the trimmers are in the global matrix #contenuto_trimmer_preamplifier[6][4] .
49
50\n An example of writing of the value 158 in the trimmer for coarse offset compensation of the second channel is:
51<span style="color:orange;"> <I>
52\code {.c}
53preamplifier_scrittura_lettura_trimmer( scheda_su_scheda_giu, canale1, trimmer_coarse_offset, 158, preamplifier_scrivi_il_trimmer );
54\endcode
55</I> </span>
56
57In the example above:
58- #preamplifier_scrivi_il_trimmer is defined as 1 for trimmer writing
59- #preamplifier_leggi_il_trimmer is defined as 0 for trimmer reading
60
61*\section Effects_of_trimmers_on_preamplifier Effects of trimmers on preamplifier
62<hr width="90%" size="10" align="left">
63\n The effects of the trimmers on the output or input of the preamplifier are summarized in
64\ref Table_trimmer_Effects "Table" below:
65
66\n
67<center>
68\anchor Table_trimmer_Effects \b Table \b 1: Effects of the trimmers on preamplifier
69Trimmer | Output Change per step | Input Change per step |
70:-------------------------------| :---------------------:| :---------------------:|
71#trimmer_CMRR_compensation | Not Applicable | Not Applicable |
72#trimmer_fine_offset | 0.985 mV | xxx &micro;V |
73#trimmer_coarse_offset | 121,3 mV | xxx &micro;V |
74#trimmer_thermal_compensation | x mV/&deg;C | y &micro;V/&deg;C |
75</center>
76
77\section Preamplifier_PGA_offset_setting Preamplifier/PGA offset setting
78<hr width="90%" size="10" align="left">
79
80\n Amplifer offset can be set with an accuracy of sligtly less than 16 bits via the 2 trimmers #trimmer_coarse_offset and
81#trimmer_fine_offset.
82Offset is implemented with 2 different modalities with the aim of speed up the process of correction and details are given below.
83\n There are some common initial settings. We use 2 trimmers that are initialized. A few steps are adopted
84in order to minimize disturbances.
85First the PGA gains of all the channles of the board are set to 1 V/V. Then the offsets, for those channles that must be adjusted,
86being set at PGA gain of 1 V/V, are scaled by the gain factor. The same is done for the expected final error. This is done channel
87by channel.
88As an example if we need an output offset of 0.5 V at a PGA gain of 10, then, the PGA gain is set to 1 V/V and the offset
89adjusted at 0.05 V.
90Since some error can be introduced when the gain is returned at its value, the gain of every channel is not recovered at the end
91of the process, but a few bits before, 2 or 3 depending on the difference between the target value and the acyual value.
92This way possible errors are compensated.
93\n The offset is adjusted in pseudo-paralalel way. Pseudo-parallel is intended for the fact the the ADC measurement is the only action
94that is made channel after channel, since only one ADC is present.
95\n The ADC to perform the measurement can be that on the post-board or can be external.
96In the latter case every time the measurement is needed the &micro;-controller asks from the CAN bus the measurement.
97This is done in a way similar to the
98<a href="_instruction_set.html#instr_ouput_offset_we_want_to_set_option">instr_output_offset_to_be_set</a>.
99\n The modalities for doing an adjustment can be set with the
100<a href="_instruction_set.html#instr_readback_node_voltages_option">instr_preamplifier_scrittura_lettura_trimmer_offset</a>
101\n The main function to adjust the offset is instr_Vbias_to_be_set_function():
102*\snippetlineno .\Preamplifier_Offset_Drift_Correcttion.c fun_instr_Vbias_to_be_set_function
103
104\n From it, after setting some variables, we go to preamplifier_normalize_gain_offset_error(), where the gain of all
105the channels are set to 1 V/V, the target offsets and the final target errors are normalized to 1 V/V, too:
106*\snippetlineno .\Preamplifier_Offset_Drift_Correcttion.c fun_preamplifier_normalize_gain_offset_error
107
108\n At this point if the standard SAR procedure is chosen we go to \ref SAR_procedure, while if the Fast SAR procedure is adopted,
109a first measurement of the outputs is done from which a guess for the coarse trimmers is determined. Then, we go to
110\ref FAST_SAR_procedure.
111
112\note Both SAR and Fast SAR procedures work rigtly if the calibration of the steps effects determined by the fine and coarse trimmers
113are known and stored in the preamplifier EPROM. This must be done during preampleifers initial test and the 2 instructions
114XXXXXXX and YYYYYY are dedicated to this.
115
116\subsection SAR_procedure SAR_procedure
117\n SAR is implemented in standard way and both fine and coarse trimmers are initialized to 0. The function called by
118instr_Vbias_to_be_set_function() is preamplifier_aggiusta_offset_SAR():
119*\snippetlineno .\Preamplifier_Offset_Drift_Correcttion.c fun_preamplifier_aggiusta_offset_SAR
120
121\n Note that the function preamplifier_ritorno_al_gain_originale()
122is called to verify if it is the time to come back to the original gain. Normally this is done when 2 or 3 bits of the fine trimmer
123are those remaining to test and set, for compensanting any possible small error introducd by the gain change.
124
125\subsection FAST_SAR_procedure FAST_SAR_procedure
126
127\n The Fats SAR procedure tries to reduce the numeber of SAR steps from 16 to between 4 and 6.
128\n When the gains are set to 1 V/V
129the PGA output voltages are read and a tentative calculation of the 8 MSB for target offset is done (in
130instr_Vbias_to_be_set_function()). Then, depending on how far is the new measured offset from the target, the 2 or 3 LSb of the MSB,
131or coarse trimmer, are set to 0 and the SAR is applied from here to the end of the MSB. At this point, the final adjustment
132part is left to the LSB, or fine trimmer, that was set to 0.
133\n The first step with the setting of the LSB is to recover to the original value the gains. Then, the target values
134for the LSB are calculated from the measured offset and, depending on how far the new offset is from the final value,
135the 2 or 3 LSb are set to 0 and the SAR is applied to them.
136\n The Fast SAR function preamplifier_aggiusta_offset_FastSAR() is this:
137*\snippetlineno .\Preamplifier_Offset_Drift_Correcttion.c fun_preamplifier_aggiusta_offset_FastSAR.
138
139\note If, when the gain is set to 1 V/V, the output voltage of any channel is found outside the saturation levels (high and low),
140the procedure is set to standard SAR, for those channels.
141
142\section Node_measurements_with_internal_external_ADC Node measurements with internal or external ADC
143<hr width="90%" size="10" align="left">
144\n Node reading can be made with the internal or external ADC. In case an external ADC is chosen, the function called
145is the preamplifier_ADC_external_measured_node_function():
146*\snippetlineno .\Preamplifier_Offset_Drift_Correcttion.c fun_preamplifier_ADC_external_measured_node_function
147
148\n The function invokes the reading from an external ADC from the CAN.
149\n In case the internal ADC is used, the function to call is the XXXXXXXX():
150
151\section sw_detail_pre Sw details
152<hr width="90%" size="10" align="left">
153\n Let's see the function preamplifier_scrittura_lettura_trimmer() for writing, reading the trimmer:
154 *\snippetlineno Trimmer.c fun_preamplifier_scrittura_lettura_trimmer
155
156\n The identification of the trimmers is done with the structure #address_preamplifier_trimmer[6]:
157\snippet Memoria_pre_M24CXX.h fun_EPROM_I2C
158
159\n The I2C addresses are 2 less than those of the detector trimmer (remember that to communicate with the 6
160trimmers we use 3 different I2C):
161- #I2C_address_ch_dispari -2
162- #I2C_address_ch_pari -2
163
164\n The codes for mamnaging the trimmer are:
165 - \ref Preamplifier_Offset_Drift_Correcttion.c
166 - \ref Preamplifier_Offset_Drift_Correcttion.h
167
168*/
169
170
171// CROSS INIZIO
172
173volatile uint16_t preamplifier_attesa_tra_le_misure = 10; //attesa tra le misure per aggiustamento offset
174
175int32_t preamplifier_error_voltage= 10000; //errore tollerato in microV
176
177uint8_t preamplifier_canali_da_regolare= 0; //i canali da agiustare
178
179uint8_t preamplifier_externalADC_1_onboardADC_0 ; //ADC selection for offset adjustment
180//uint8_t preamplifier_SAR_1_no_SAR_0; //SAR / no SAR in offset adjustment.
181//uint8_t preamplifier_fastSAR_1_no_fastSAR_0; //fast SAR in offset adjustment
182volatile int32_t preamplifier_Output_offset_target_at_the_moment[12] ;
183volatile uint8_t termalizzazione_fatta[12];
184
185
186int32_t preamplifier_error_voltage_at_the_moment[12];
187int32_t preamplifier_error_voltage_at_PGA_gain[12];
188int32_t ADC_misura_fatta_old[12]={0,0,0,0,0,0,0,0,0,0,0,0};
189
190int32_t preamplifier_coarse_step_trimmer[]={preamplifier_coarse_step_trimmer_default,preamplifier_coarse_step_trimmer_default,preamplifier_coarse_step_trimmer_default, \
191 preamplifier_coarse_step_trimmer_default, preamplifier_coarse_step_trimmer_default,preamplifier_coarse_step_trimmer_default, \
192 preamplifier_coarse_step_trimmer_default,preamplifier_coarse_step_trimmer_default, preamplifier_coarse_step_trimmer_default,
193 preamplifier_coarse_step_trimmer_default,preamplifier_coarse_step_trimmer_default,preamplifier_coarse_step_trimmer_default,}; //Value in microV
194int32_t preamplifier_fine_step_trimmer[]={preamplifier_fine_step_trimmer_default,preamplifier_fine_step_trimmer_default,preamplifier_fine_step_trimmer_default, \
195 preamplifier_fine_step_trimmer_default,preamplifier_fine_step_trimmer_default,preamplifier_fine_step_trimmer_default, \
196 preamplifier_fine_step_trimmer_default,preamplifier_fine_step_trimmer_default,preamplifier_fine_step_trimmer_default, \
197 preamplifier_fine_step_trimmer_default,preamplifier_fine_step_trimmer_default,preamplifier_fine_step_trimmer_default,}; //Value in microV
198
200 uint8_t starting_value;
201 uint8_t starting_exp_value;
202}*/ preamplifier_SAR_ini[12];
203
204uint8_t PGA_settled_gain_old[12] , preamplifier_canali_da_regolare_old;
205
206/*! \brief Offset target values
207*\snippet Preamplifier_Offset_Drift_Correcttion.c vec_preamplifier_Output_offset_target
208*/
209//! <!-- [vec_preamplifier_Output_offset_target] -->
210int32_t preamplifier_Output_offset_target[12]={0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0}; //in microV
211//! <!-- [vec_preamplifier_Output_offset_target] -->
212
213/*! \brief The preamplifier offset will be set at the value passed from the CAN with this function if,
214after this setting, it is launched instr_Vbias_to_be_set_function().
215
216The first 2 bytes of the CAN bus message are the voltage setting in mV. Byte_6 is for which channel the voltage is to be set.
217The same voltage can be the same for several channels. The voltage is applied if the corresponding bit of Byte_6 is 1, ie if bit_2
218is 1, than the voltage is applied to channel 1, if bit_1 and bit_5 are 1 then the same voltage is applied for both channles 1 and 5.
219Run the command several times if the targety is different among the channles.
220These values are stored in the vector #Detector_bias_target[12].
221Only positive values are accepted and the voltage is considered the total bias voltage, namely Voltage==Vbias_pos - Vbias_neg, symmetric.
222*\return No Parameters, the actual result is sent to the CAN bus output throught \ref tx_data.
223
224*\snippetlineno .\Preamplifier_Offset_Drift_Correcttion.c instr_ouput_offset_we_want_to_set_function
225*/
226//! <!-- [instr_ouput_offset_we_want_to_set_function] -->
228uint8_t canali_ , canali_input=vettore_istruzioni[istruzione_byte_4_e_scelta_canale];
229 uint8_t scheda_su_giu = (canali_input >> 7) & 1;
230 uint8_t offset_scheda=0;
231 if (scheda_su_giu){
232 offset_scheda=6;
233 }
234 for( canali_=0; canali_ <6; canali_ ++){
235 if( (canali_input >> canali_) & 1){
236 preamplifier_Output_offset_target[offset_scheda + canali_]= ( ( *(int16_t *)vettore_istruzioni ) *1000);
237 }
238 }
240}
241//! <!-- [instr_ouput_offset_we_want_to_set_function] -->
242
243/*! \brief Content of the preamplifier trimmers can be read/write.
244
245*\return No Parameters, the actual result is sent to the CAN bus output throught \ref tx_data.
246
247*\snippetlineno .\Preamplifier_Offset_Drift_Correcttion.c fun_instr_preamplifier_scrittura_lettura_trimmer_offset_function
248*/
249//! <!-- [fun_instr_preamplifier_scrittura_lettura_trimmer_offset_function] -->
252 uint8_t contenuto_trimmer= vettore_istruzioni[byte_istr_dati_0];
253 uint8_t trimmer_da_scrivere= vettore_istruzioni[istruzione_byte_3];
254 uint8_t scrivere_leggere= (canale >> 6) & 1;
255 uint8_t scheda_su_giu= ((canale >> 7) & 1)*6;
256 ERROR_codifica_errore(0,0,0,0); //Reset_ch0 errori
257 for ( canale_=0; canale_ <6; canale_++){
258 if ( (canale >> canale_) & 1){
259 preamplifier_scrittura_lettura_trimmer( scheda_su_giu, canale_, trimmer_da_scrivere, \
260 contenuto_trimmer, scrivere_leggere );
261 tx_data[byte_istr_dati_0]= contenuto_trimmer_preamplifier[canale_ + scheda_su_giu][trimmer_da_scrivere] ;
262 break ;
263 }
264 }
266}
267//! <!-- [fun_instr_preamplifier_scrittura_lettura_trimmer_offset_function] -->
268
269/*! \brief The detector bias will be set at the value set with the function instr_detector_Vbias_we_want_to_set_function()
270with which the target values are stored in the vector #Detector_bias_target[].
271
272*\return No Parameters, the actual result is sent to the CAN bus output throught \ref tx_data.
273
274*\snippetlineno .\Preamplifier_Offset_Drift_Correcttion.c fun_instr_Vbias_to_be_set_function
275*/
276//! <!-- [fun_instr_Vbias_to_be_set_function] -->
278uint8_t iii,canale, indice;
279uint8_t volatile tx_data_buffer[8],fai_fai=1;
280int8_t variazione;
281 LED_rosso_fondo_scala=LED_lungo;
282
283 ERROR_codifica_errore(0,0,0,0); //Reset_ch0 errori
284 for(iii=0;iii < 8;iii++){// Potrebbe essere richiesto qualcosa sul can,
285 //bufferizziamo l'istruzione
286 tx_data_buffer[iii]= tx_data[iii];
287 }
288
289 //La funzione va sviluppata per ora si ritrona il fw
290 //verificare le modalit\'a di misura:
294 //attesa tra le misure
295 preamplifier_attesa_tra_le_misure = vettore_istruzioni[4] *100;
296 if ( preamplifier_attesa_tra_le_misure <100) preamplifier_attesa_tra_le_misure=100;
297 if (preamplifier_attesa_tra_le_misure > 10000) preamplifier_attesa_tra_le_misure=10000;
298 //errore tollerato
299 preamplifier_error_voltage= vettore_istruzioni[5] *1000;
300 //i canali da agiustare
301 preamplifier_canali_da_regolare= vettore_istruzioni[6] & 0x7F;
302 preamplifier_canali_da_regolare_old=preamplifier_canali_da_regolare;
303 scheda_su_scheda_giu = ((vettore_istruzioni[6] >> 7) & 1)*6;
304 //l'adc da usare, interno o esterno
305 preamplifier_externalADC_1_onboardADC_0 = vettore_istruzioni[3] & 1;
306// preamplifier_SAR_1_no_SAR_0 = ( vettore_istruzioni[3] >> 1 ) & 1;
307// preamplifier_fastSAR_1_no_fastSAR_0 = ( vettore_istruzioni[3] >> 2 ) & 1;
308
310 vettore_istruzioni[3] =0; //Non si fa altro
311 fai_fai=0;
312 EPROM_store_recover_state_M24C32_64(scheda_su_scheda_giu, vettore_istruzioni[6],0,0);
313 }
314
316 //Offset recalled from startup
317 EPROM_store_recover_state_M24C32_64(scheda_su_scheda_giu,preamplifier_canali_da_regolare,1,1);
318 fai_fai=0;
319 }
321 //Offset recalled from user location
322 EPROM_store_recover_state_M24C32_64(scheda_su_scheda_giu,preamplifier_canali_da_regolare,1,0);
323 fai_fai=0;
324 }
325
326 //Leggiamo le pendenze
327 uint8_t dati_scambio[4] , scheda=scheda_su_scheda_giu;
328 for( canale=0;canale<6;canale++){
329// if(canale==6) scheda =1;
330 EPROM_lettura_M24C32_64(scheda, I2C_mainboard, canale, Memory_preamplifier_slope_calibration_ON_0_OFF_ff <<2,dati_scambio);
331 if(dati_scambio[0] ==0){//solo se la misura \'e stata fatta si aggiornano le pendenze, altrimenti vale il fedault
332 EPROM_lettura_M24C32_64(scheda, I2C_mainboard, canale, Memory_preamplifier_address_coarse_trimmer_slope_offset <<2,dati_scambio);
333 preamplifier_coarse_step_trimmer[canale+scheda]=*(int32_t *)dati_scambio;
334 EPROM_lettura_M24C32_64(scheda, I2C_mainboard, canale, Memory_preamplifier_address_fine_trimmer_slope_offset <<2,dati_scambio);
335 preamplifier_fine_step_trimmer[canale+scheda]= *(int32_t *)dati_scambio;
336 }
337 preamplifier_error_voltage_at_the_moment[canale+scheda]= preamplifier_coarse_step_trimmer[canale+scheda] >>1; //mezzo bit di errore sul coarse all'inizio
338 }
339
340 if(fai_fai){
341//Initialization for default SAR
343 for( canale=0;canale<12;canale++){
344 preamplifier_SAR_ini[canale].starting_value =128;
345 preamplifier_SAR_ini[canale].starting_exp_value[0]=7;
346 preamplifier_SAR_ini[canale].starting_exp_value[1]=7;
347 }
348 }
349 for( canale=0;canale<6;canale++){ //a met\'a scala i trimmer fine che ci interssano
350 if((preamplifier_canali_da_regolare >> canale) & 1){
351 preamplifier_scrittura_lettura_trimmer( scheda_su_scheda_giu, canale,\
352 trimmer_fine_offset, 128, preamplifier_scrivi_il_trimmer );//Trimmer fine inizializzato met\'a scala
353 }
354 }
355
356//Ora impostiamo ad 1 tutti i guadagni, normalizziamo gli errori ed i target
357preamplifier_normalize_gain_offset_error(scheda_su_scheda_giu) ;
358
359//FINE: Initialization for default SAR, changes are applied in fastSAR, eventually
360
361 for( canale=0;canale<6;canale++){ //impostiamo la compensazione termica di default, se \'e stata fatta.
362 if((preamplifier_canali_da_regolare >> canale) & 1){
363 preamplifier_determina_trimmer_therma_comp( scheda_su_scheda_giu, canale, 0, 1);
364 termalizzazione_fatta[canale + scheda_su_scheda_giu]=0;
365 }
366 }
367
368
371
372 //Ora aggiustiamo il controllo termico per quei canali che inizialmente erano saturi
373 uint8_t ri_misuriamo=0;preamplifier_canali_da_regolare_old=preamplifier_canali_da_regolare;
374 for( canale=0;canale<6;canale++){ //impostiamo la compensazione termica di default, se \'e stata fatta.
375 if((preamplifier_canali_da_regolare_old >> canale) & 1){
376 if (termalizzazione_fatta[canale + scheda_su_scheda_giu]==0){
377 preamplifier_canali_da_regolare=1 <<canale;
378 ri_misuriamo=1;
379 }
380 }
381 }
382 //Se c'erano canali inizalmente saturi riaggiustiamo
383 if(ri_misuriamo){
386 }
387
388
389//Ora vediamo qualche setting
391 //Offset to be stored at memory location for sturtup
392 EPROM_store_recover_state_M24C32_64(scheda_su_scheda_giu,vettore_istruzioni[6],0,1);
393 }
395 //Offset to be stored at user memory location for sturtup
396 EPROM_store_recover_state_M24C32_64(scheda_su_scheda_giu, vettore_istruzioni[6],0,0);
397 }
398 }
399 for(iii=0;iii < 8 ;iii++){
400 tx_data[iii]= tx_data_buffer[iii];
401 }
402 tx_data[6] = preamplifier_canali_da_regolare; //i canali non in tolleranza hanno un 1 in corrispondenza
403 int32_t somma=0;
404 for( iii=0;iii<6;iii++){
405 somma += preamplifier_error_voltage_at_PGA_gain[iii+scheda_su_scheda_giu];
406 }
407 somma = somma / 6000;
408 if( somma >255) somma=255;
409 tx_data[5] = somma;
411}
412//! <!-- [fun_instr_Vbias_to_be_set_function] -->
413
414
415/*! \brief The ouput offset will be set at the value that was given with the #instr_ouput_offset_we_want_to_set instruction.
416
417*\return No Parameters, the actual result is sent to the CAN bus output throught \ref tx_data.
418
419*\snippetlineno .\Preamplifier_Offset_Drift_Correcttion.c fun_preamplifier_trova_il_guess
420*/
421//! <!-- [fun_preamplifier_trova_il_guess] -->
422void preamplifier_trova_il_guess(uint8_t trimmer_da_usare){
423 #define numero_ripetizioni 3
424 uint8_t canale, indice , ripetizioni, preamplifier_canali_da_regolare_locale=preamplifier_canali_da_regolare_old,trimmer_per_ini;
425 uint8_t scheda_su_scheda_giu = ((vettore_istruzioni[6]>>7 &1)*6);
426 uint16_t iii,media_prov; //medie=20;
427 int16_t delta;
428 int32_t ADC_misura_fatta_prov,ADC_misura_fatta_prov_vet[200],ADC_misura_fatta_[12], *pendenza_trimmer;
429
430 if( trimmer_da_usare == trimmer_coarse_offset){
431 pendenza_trimmer = preamplifier_coarse_step_trimmer;
432 trimmer_per_ini = 0;
433 }else if (trimmer_da_usare == trimmer_fine_offset){
434 pendenza_trimmer = preamplifier_fine_step_trimmer;
435 trimmer_per_ini=1;
436 }
437
438 if(scheda_su_scheda_giu==1) scheda_su_scheda_giu=6;
439
440 //le condizioni di lavoro devono essere gi\'a impostate
441 //ripetiamo qualche volta
442 for(ripetizioni= 0; ripetizioni < numero_ripetizioni ;ripetizioni++){
443 //prima di tutto leggere tutte le uscite
444 Aspetta_tanti_ms(preamplifier_attesa_tra_le_misure);
445 for(canale=0; canale<6;canale++){ // Scansoniamo tutti i possibili canali sulla scheda selezionata
446 indice= canale + scheda_su_scheda_giu; //Solito 2 schede possibili, la prima schede ha indirizzi da 0 a 5, la seconda da 6 a 11
447
448 if( (preamplifier_canali_da_regolare_locale >> canale) & 1){//Selezionaiamo solo i canali indicati
449
450// ADC_misura_fatta_[indice]= ADC_misura_differenziale_con_media_at_PGA(scheda_su_scheda_giu, preamplifier_externalADC_1_onboardADC_0, canale, preamplifier_error_voltage_at_the_moment);
451 ADC_misura_fatta_[indice]=ADC_misura_differenziale_con_media_generico(scheda_su_scheda_giu,preamplifier_externalADC_1_onboardADC_0,canale,1);
452 //Attenzione che le uscite non siano sature
453 }//chiusura canali da considerare
454 }//chiusura Canali
455 for(canale=0; canale<6;canale++){ // Scansoniamo tutti i possibili canali sulla scheda selezionata
456 indice= canale + scheda_su_scheda_giu; //Solito 2 schede possibili, la prima schede ha indirizzi da 0 a 5, la seconda da 6 a 11
457
458 if( (preamplifier_canali_da_regolare_locale >> canale) & 1){//Selezionaiamo solo i canali indicati
459 if( (ADC_misura_fatta_[indice]<preamplifier_positive_saturation) && (ADC_misura_fatta_[indice]> preamplifier_negative_saturation)){
460
461 delta = ( preamplifier_Output_offset_target_at_the_moment[indice] - ADC_misura_fatta_[indice] ) / pendenza_trimmer[indice] ;
462 delta += (( preamplifier_Output_offset_target_at_the_moment[indice] - ADC_misura_fatta_[indice] ) % pendenza_trimmer[indice] ) / (pendenza_trimmer[indice]>>1); //mezzo bit recuperato
463
464 if( (delta + contenuto_trimmer_preamplifier[indice][trimmer_da_usare])<0){
465 contenuto_trimmer_preamplifier[indice][trimmer_da_usare] =0;
466 }else if( (delta +contenuto_trimmer_preamplifier[indice][trimmer_da_usare]) >0xff) {
467 contenuto_trimmer_preamplifier[indice][trimmer_da_usare] =0xff;
468 }else{
469 contenuto_trimmer_preamplifier[indice][trimmer_da_usare] += delta;
470 }
471 //Aggiungiamoci il valore della correzione della temperatura aggiustato al valore del trimmer dell'offset
472 if ( (trimmer_da_usare ==trimmer_coarse_offset)){
473 termalizzazione_fatta[indice]=1;
474 preamplifier_determina_trimmer_therma_comp( scheda_su_scheda_giu, canale, contenuto_trimmer_preamplifier[indice][trimmer_da_usare], 0);
475 }
476
477 preamplifier_scrittura_lettura_trimmer(scheda_su_scheda_giu, canale, trimmer_da_usare, contenuto_trimmer_preamplifier[indice][trimmer_da_usare],1);
478 if ( (delta<3) && (delta>-3)){// siamo giusti, con errore contenuto
479 preamplifier_canali_da_regolare_locale -= 1<<canale ;
480// preamplifier_SAR_ini[indice].starting_value = ( contenuto_trimmer_preamplifier[indice][trimmer_da_usare] ) & 0xFC;
481 }
482 if (delta<0)delta=-delta;
483 if( contenuto_trimmer_preamplifier[indice][trimmer_da_usare] >= delta){
484 preamplifier_SAR_ini[indice].starting_value = contenuto_trimmer_preamplifier[indice][trimmer_da_usare] -delta ;
485 }else{
486 preamplifier_SAR_ini[indice].starting_value=0;
487 }
488 if (delta<=1){
489 preamplifier_SAR_ini[indice].starting_exp_value[ trimmer_per_ini]= 1;
490 }else if (delta <= 3) {
491 preamplifier_SAR_ini[indice].starting_exp_value[ trimmer_per_ini]= 2;
492 }else if (delta <= 10){
493 preamplifier_SAR_ini[indice].starting_exp_value[ trimmer_per_ini]= 3;
494 }else if (delta > 10){
495 preamplifier_SAR_ini[indice].starting_exp_value[ trimmer_per_ini]= 5;
496 }
497
498 }/* chiusura saturazione rispettata */ else{
499 preamplifier_canali_da_regolare_locale -= 1<<canale ; //rimane il default
500 preamplifier_SAR_ini[indice].starting_value=0;
501 }//chiusura saturazione non rispettata
502 }//chiusura canali da considerare
503 }//chiusura Canali
504 }//chiusura ripetiamo qualche volta
505 for(canale=0; canale<6;canale++){ // Scansoniamo tutti i possibili canali sulla scheda selezionata
506 indice= canale + scheda_su_scheda_giu; //Solito 2 schede possibili, la prima schede ha indirizzi da 0 a 5, la seconda da 6 a 11
507
508 if( (preamplifier_canali_da_regolare_locale >> canale) & 1){
509 contenuto_trimmer_preamplifier[indice][trimmer_da_usare]= preamplifier_SAR_ini[indice].starting_value;
510 }
511 }
512}
513//! <!-- [fun_preamplifier_trova_il_guess] -->
514
515
516
517/*! \brief The ouput offset will be set at the value that was given with the #instr_ouput_offset_we_want_to_set instruction.
518
519*\return No Parameters, the actual result is sent to the CAN bus output throught \ref tx_data.
520
521*\snippetlineno .\Preamplifier_Offset_Drift_Correcttion.c fun_preamplifier_aggiusta_offset
522*/
523//! <!-- [fun_preamplifier_normalize_gain_offset_error] -->
524static void preamplifier_normalize_gain_offset_error(uint8_t scheda_su_scheda_giu_){
525 //First of all we set the PGA gain to minimum
526 //Then the offset is normalized to PGA at unity gain
527// uint8_t limitatore;
528 int32_t max_error=0;
529 uint8_t canale=0, indice;
530 if(scheda_su_scheda_giu_>=1) scheda_su_scheda_giu_=6;
531// int16_t pre_variazione;
532// int32_t variazione ;
533// int32_t variazione_1;
534 preamplifier_canali_da_regolare_old = preamplifier_canali_da_regolare;
535 //The PGA gain of all channells of the board are set to 1 V/V
536 for(canale=0; canale< 6; canale++){
537 indice= canale + scheda_su_scheda_giu_;
538 PGA_settled_gain_old[indice]= PGA_settled_gain[indice];
539 preamplifier_Output_offset_target_at_the_moment[indice] = preamplifier_Output_offset_target[indice] / PGA_settled_gain[indice];
540 if ( preamplifier_error_voltage < ((PGA_settled_gain[indice] * preamplifier_fine_step_trimmer[indice] *3 )/2) ){
541 //risoluzione minima di 1.5 bit LSb (*3/2)
542 preamplifier_error_voltage_at_PGA_gain[indice] =(3 * PGA_settled_gain[indice] * preamplifier_fine_step_trimmer[indice] )/2;
543 }else{
544 preamplifier_error_voltage_at_PGA_gain[indice] = preamplifier_error_voltage;
545 }
546 if( preamplifier_error_voltage_at_PGA_gain[indice] > max_error) max_error = preamplifier_error_voltage_at_PGA_gain[indice];
547// preamplifier_error_voltage_at_the_moment[indice]= (preamplifier_error_voltage_at_PGA_gain[indice]) / PGA_settled_gain[indice];
548
549 PGA_GAIN_CROSS( scheda_su_scheda_giu_ , canale , guadagno_minimo_PGA );
550 }
551 vettore_istruzioni[5] = max_error / 1000;
552}
553//! <!-- [fun_preamplifier_normalize_gain_offset_error] -->
554
555
556
557/*! \brief This function provide the output offset with the standard SAR method.
558
559*\return No Parameters, the actual result is sent to the CAN bus output throught \ref tx_data.
560
561*\snippetlineno .\Preamplifier_Offset_Drift_Correcttion.c fun_preamplifier_aggiusta_offset_SAR
562*/
563//! <!-- [fun_preamplifier_aggiusta_offset_SAR] -->
565 uint8_t canale;
566 uint8_t indice;
567 uint8_t i_2_trimmer[]={trimmer_coarse_offset , trimmer_fine_offset}, indice_trimmer,scalata,confronto;
568 uint8_t target_raggiunto_1_non_raggiunto_0[]={0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0}; // si misura fino a che non diventa 1
569 int32_t ADC_misura_fatta_prov,ADC_misura_fatta_prov_vet[200];
570 uint16_t iii, media_prov; //medie=10;
571
572 if( scheda_su_scheda_giu>=1) scheda_su_scheda_giu=6;
573
574//Inizializzazione dei trimmer che servono alla regolazione
575//for(canale=0; canale<6;canale++){
576// if( (preamplifier_canali_da_regolare >> canale) & 1){
577// preamplifier_scrittura_lettura_trimmer( scheda_su_scheda_giu, canale, trimmer_coarse_offset, \
578// preamplifier_SAR_ini[canale + scheda_su_scheda_giu].starting_value, preamplifier_scrivi_il_trimmer );//Trimmer inizializzato a zero
579// preamplifier_scrittura_lettura_trimmer( scheda_su_scheda_giu, canale, trimmer_fine_offset, 128, preamplifier_scrivi_il_trimmer );//Trimmer inizializzato a zero
580// }
581//}
582//FINE Inizializzazione dei trimmer che servono alla regolazione
583
584// Esploriamo i 2 trimmer, a partie dal+ significativo, cio\'e il SAR veroe e proprio
585 preamplifier_canali_da_regolare_old= preamplifier_canali_da_regolare;
586 for(indice_trimmer=0; indice_trimmer<2;indice_trimmer++){//Facciamo 2 giri, uno per ogni trimmer
587
588 if( indice_trimmer) {
589 preamplifier_canali_da_regolare = preamplifier_canali_da_regolare_old;
590 for(canale=0; canale<6;canale++){
591 indice= canale + scheda_su_scheda_giu;
592 preamplifier_error_voltage_at_the_moment[indice]= preamplifier_error_voltage_at_PGA_gain[indice] / PGA_settled_gain_old[indice]; //Ripristiniamo l'errore
593 target_raggiunto_1_non_raggiunto_0[indice]=0;
594 }
595 preamplifier_trova_il_guess( i_2_trimmer[indice_trimmer]);
596 }
597
598 for(scalata=0; scalata<8; scalata++){
599 //SAR a guadagno 1 fino agli ultimi bit, per non creare sconquasso
600 preamplifier_ritorno_al_gain_originale(scalata , indice_trimmer, target_raggiunto_1_non_raggiunto_0);
601
602 confronto= 1 << (7-scalata); //Impostiamo il valore di prova da aggiungere al trimmer
603 for(canale=0; canale<6;canale++){ // Scansoniamo tutti i possibili canali sulla scheda selezionata
604 indice= canale + scheda_su_scheda_giu; //Solito 2 schede possibili, la prima schede ha indirizzi da 0 a 5, la seconda da 6 a 11
605 if( (preamplifier_SAR_ini[indice].starting_exp_value[indice_trimmer] >= (7-scalata))){ //Job starts just with the minimal cheks, always for the lower 8 bits
606 if( (preamplifier_canali_da_regolare >> canale) & 1){//Selezionaiamo solo i canali indicati
607 contenuto_trimmer_preamplifier[indice][i_2_trimmer[indice_trimmer]] += confronto;
608 preamplifier_scrittura_lettura_trimmer( scheda_su_scheda_giu, canale, i_2_trimmer[indice_trimmer], \
609 contenuto_trimmer_preamplifier[indice][i_2_trimmer[indice_trimmer]], preamplifier_scrivi_il_trimmer );
610 }
611 }
612 }
613 Aspetta_tanti_ms( preamplifier_attesa_tra_le_misure );
614
615 for(canale=0; canale<6;canale++){ // Scansoniamo tutti i possibili canali sulla scheda selezionata
616 indice= canale + scheda_su_scheda_giu; //Solito 2 schede possibili, la prima schede ha indirizzi da 0 a 5, la seconda da 6 a 11
617 if( (preamplifier_SAR_ini[indice].starting_exp_value[indice_trimmer] >= (7-scalata)) ){ //Job is done just with the minimal cheks
618 if( (preamplifier_canali_da_regolare >> canale) & 1){//Selezionaiamo solo i canali indicati
619 if( target_raggiunto_1_non_raggiunto_0[indice]==0){//Se non abbiamo ancora raggiunto la tolleranza continuamo, per i canali fuori target
620 ADC_misura_fatta =ADC_misura_differenziale_con_media_generico(scheda_su_scheda_giu,preamplifier_externalADC_1_onboardADC_0,canale,1);
621
622 if( ( ADC_misura_fatta - preamplifier_Output_offset_target_at_the_moment[indice] ) < \
623 ( - preamplifier_error_voltage_at_the_moment[indice]) ){
624 //siamo fuori tolleranza
625 target_raggiunto_1_non_raggiunto_0[indice]=0;
626 ADC_misura_fatta_old[indice]= ADC_misura_fatta; //
627 }else if ( ( ADC_misura_fatta - preamplifier_Output_offset_target_at_the_moment[indice] ) < \
628 (0 ) ){
629 //Siamo in tolleranza e dobbiamo fermarci
630 target_raggiunto_1_non_raggiunto_0[indice]=1;
631 preamplifier_canali_da_regolare -= 1 << canale ;
632 ADC_misura_fatta_old[indice]= ADC_misura_fatta; //
633 }else if ( ( ADC_misura_fatta - preamplifier_Output_offset_target_at_the_moment[indice] ) >\
634 ( preamplifier_error_voltage_at_the_moment[indice])){
635 //siamo fuori tolleranza
636 target_raggiunto_1_non_raggiunto_0[indice]=0;
637
638 contenuto_trimmer_preamplifier[indice][ i_2_trimmer[indice_trimmer]] -= confronto;
639 preamplifier_scrittura_lettura_trimmer( scheda_su_scheda_giu, canale, i_2_trimmer[indice_trimmer], \
640 contenuto_trimmer_preamplifier[indice][i_2_trimmer[indice_trimmer]], preamplifier_scrivi_il_trimmer );
641 }else if ( ( ADC_misura_fatta - preamplifier_Output_offset_target_at_the_moment[indice] ) >\
642 (0 ) ){
643 //siamo in tolleranza
644 target_raggiunto_1_non_raggiunto_0[indice]=1;
645 ADC_misura_fatta_old[indice]= ADC_misura_fatta; //
646 preamplifier_canali_da_regolare -= 1 << canale ;
647 }
648 }
649 }
650 }
651 }
652 }
653
654 }
655}
656//! <!-- [fun_preamplifier_aggiusta_offset_SAR] -->
657
658
659
660/*! \brief This function sets the original gain when a few LSb have to be determined. The umber of bits
661is bit_to_go.
662
663*\param[in] indice_trimmer the offset trimmer under usage
664*\param[in] scalata The value 1<<(7-scalata) is the SAR test weigth
665*\param[in] target_raggiunto_1_non_raggiunto_0 vector for target offset got or not got
666
667*\return No Parameters, the actual result is sent to the CAN bus output throught \ref tx_data.
668
669*\snippetlineno .\Preamplifier_Offset_Drift_Correcttion.c fun_preamplifier_ritorno_al_gain_originale
670*/
671//! <!-- [fun_preamplifier_ritorno_al_gain_originale] -->
672void preamplifier_ritorno_al_gain_originale(uint8_t scalata, uint8_t indice_trimmer, uint8_t * target_raggiunto_1_non_raggiunto_0){
673#define bit_to_go 3
674uint8_t canale, indice;
675 if( scheda_su_scheda_giu >=1) scheda_su_scheda_giu=6;
676 //***************Questo solo al secondo giro per impostare il secondo trimmer inizio**************************************************
677 if( (indice_trimmer == 1) && ((7-scalata)==bit_to_go) ){
678 preamplifier_canali_da_regolare_old = preamplifier_canali_da_regolare;
679
680 //Ritorno al guadagno originale per tutti i canali inizio
681 for(canale=0; canale< 6; canale++){
682 indice = canale + scheda_su_scheda_giu;
683 if( (preamplifier_SAR_ini[indice].starting_exp_value[1]<2) && (PGA_settled_gain_old[indice] > 1) ){
684 //Siamo un po' pessimisti e aggiungiamo bit di test a guadagni grandi
685 preamplifier_SAR_ini[indice].starting_exp_value[1]=2;
687 preamplifier_scrittura_lettura_trimmer( scheda_su_scheda_giu, canale, trimmer_fine_offset, \
689 }
690 PGA_GAIN_CROSS( scheda_su_scheda_giu , canale , PGA_settled_gain_old[indice] );
691 if ( (PGA_settled_gain_old[indice] ==1) && (((preamplifier_canali_da_regolare >> canale)&1)==0)){
692 preamplifier_canali_da_regolare_old &= ~(1 << canale); //In this case nothing changes
693 }
694 //Recuperiamo errore e target iniziale
695 preamplifier_Output_offset_target_at_the_moment[indice] = preamplifier_Output_offset_target[indice];
696 preamplifier_error_voltage_at_the_moment[indice] = preamplifier_error_voltage_at_PGA_gain[indice];
697 }
698 //Ritorno al guadagno originale per tutti i fine
699 preamplifier_canali_da_regolare =preamplifier_canali_da_regolare_old;
700 Aspetta_tanti_ms( preamplifier_attesa_tra_le_misure ); //Measure with the new values
701 }
702}
703//! <!-- [fun_preamplifier_ritorno_al_gain_originale] -->
704
705/*! \brief This function provide node reading from an external ADC.
706
707*\return No Parameters, the actual result is sent to the CAN bus output throught \ref tx_data.
708
709*\snippetlineno .\Preamplifier_Offset_Drift_Correcttion.c fun_preamplifier_ADC_external_measured_node_function
710*/
711//! <!-- [fun_preamplifier_ADC_external_measured_node_function] -->
712int32_t preamplifier_ADC_external_measured_node_function(uint8_t scheda_su_scheda_giu, uint8_t indice){
713 //richiedere sul CAN la misura
714 //In questo caso scheda su o gi\'u non ha importanza perch\'e l'ADC esterno sar\'a connesso direttamente ad una sola scheda
715 uint8_t ii=0;
716 int32_t valore_mis;
717 evento_CAN=10;
718 uint8_t buffer_istruzione[8],iii;
719 for(iii=0;iii<8;iii++){
720 buffer_istruzione[iii]=tx_data[iii];
721 }
722 if ( (indice >= node_voltage_Analog_Mux_0_offset ) ){
723 //Misura su uno dei 2 nodi dei mux
724 Analog_mux_line_to_select_deselect(scheda_su_scheda_giu, indice , 1);
725 }
726 tx_data[5]= indice; //The node to be measured, the code includes also the selected board
727 tx_data[6]= 1; //This must be "1" and says that the node voltage read must be returned here
728 tx_data[7]= instr_readback_node_voltages ; //instr code
729 tx_msg_info.id = ARM_CAN_EXTENDED_ID(indirizzo_CAN_della_scheda);
730 CANdrv->MessageSend(tx_obj_idx, &tx_msg_info, tx_data, 8U);//msg to CAN back to the control room
731 Aspetta_tanti_ms(100); //From here we wait the answer or generate an error
732 //Aspettare che la misura sia fatta, o generare errore
733 //! [CAN error marker]
734 //Before here a CAN message has been sent with success, we hope
735 while( (ii <50) && ( evento_CAN != ARM_CAN_EVENT_RECEIVE ) ){
736 Aspetta_tanti_ms(200);
737 ii++;
738 }
740 //! [CAN error marker]
741 if( (indice >= node_voltage_Analog_Mux_0_offset ) ){
742 //Reset di uno dei 2 mux usati per la misura
743 Analog_mux_line_to_select_deselect(scheda_su_scheda_giu, indice , 0);
744 }
745
746 valore_mis= ( ( ( *(int32_t *)rx_data ) & 0xFFFFFFFF ) ) ;
747 //Convertiamo in funzione del nodo dal leggere
748 valore_mis = (valore_mis * ADC_coefficiente[indice / ADC_molteplicita_node_to_read].numeratore )\
749 / ADC_coefficiente[indice / ADC_molteplicita_node_to_read].denominatore ;
750 for(iii=0;iii<8;iii++){
751 tx_data[iii]=buffer_istruzione[iii];
752 }
753 return valore_mis; //The value returned is the voltage in microV
754}
755//! <!-- [fun_preamplifier_ADC_external_measured_node_function] -->
756
757
758/*! \brief This function determines and set the thermal compensation trimmer
759
760\param[in] scheda_su_scheda_giu : which board
761\param[in] canale : which channel
762\param[in] valore_previsto_trimmer_offset : the possible value to set in the offset trimmer
763\param[in] solo_recupero_default_comp_se_1 : only if the offset trimmer is recovered
764
765*\return No Parameters, the preamplfier trimmer is set within the function.
766
767*\snippetlineno .\Preamplifier_Offset_Drift_Correcttion.c fun_preamplifier_determina_trimmer_therma_comp
768*/
769//! <!-- [fun_preamplifier_determina_trimmer_therma_comp] -->
770void preamplifier_determina_trimmer_therma_comp(uint8_t scheda_su_scheda_giu,uint8_t canale, \
771 uint8_t valore_previsto_trimmer_offset, uint8_t solo_recupero_default_comp_se_1){
772
773 uint8_t dati_da_leggere_o_scrivere[]={0,0,0,0},trimmer_comp_di_default;
774 int32_t differenza_trimmer_offset, variazione_trimmer_termico, pendenza_deriva_trimmer_offset,pendenza_deriva_trimmer_compensazione;
775
776 if (scheda_su_scheda_giu) scheda_su_scheda_giu=6;
777
778 // Verifico dalla emoria se ci sono calibrazioni
779 EPROM_lettura_M24C32_64(scheda_su_scheda_giu, I2C_mainboard, canale, \
780 Memory_preamplifier_drift_ON_0_OFF_ff <<2 , dati_da_leggere_o_scrivere);
781 if(*(uint32_t *)dati_da_leggere_o_scrivere ==0){
782 //se ci sono calibrazioni le leggo. Si tratta di:
783 // leggere il trimmer offset di base e leggere il trimmer termico di base:
784 // questi 2 fanno parte della stessa locazione di memoria.
785 // leggere la pendenza del trimmer offset
786 // leggere la pendenza del trimmer compensazione
787 //POssiamo valutare il nuovo valore del trimmer termico
788 EPROM_lettura_M24C32_64(scheda_su_scheda_giu, I2C_mainboard, canale, \
789 Memory_preamplifier_trimmers_for_drift <<2 , dati_da_leggere_o_scrivere);
790 // A questo punto serve la differenza tra il trimmer target e quello di base, entrambi offset
791 trimmer_comp_di_default= dati_da_leggere_o_scrivere[trimmer_thermal_compensation];
792 if (solo_recupero_default_comp_se_1){
793 //Se vogliamo solo impostare il solo trimmer compensazione offset di default lo facciamo qui
794 dati_da_leggere_o_scrivere[0] =trimmer_comp_di_default;
795 }else{
796 differenza_trimmer_offset = valore_previsto_trimmer_offset - dati_da_leggere_o_scrivere[trimmer_coarse_offset];
797
798 // questa differenza moltipllicata per la pendenza offset e diviso per la pendenda termica
799 // con segno cambiato ci fornisce la variazione che deve subire il trimmer termico.
800 EPROM_lettura_M24C32_64(scheda_su_scheda_giu, I2C_mainboard, canale, \
801 Memory_preamplifier_offset_slope_trimmer_with_temp <<2 , dati_da_leggere_o_scrivere);
802 pendenza_deriva_trimmer_offset =*(int32_t *)dati_da_leggere_o_scrivere;
803 EPROM_lettura_M24C32_64(scheda_su_scheda_giu, I2C_mainboard, canale, \
804 Memory_preamplifier_compensation_slope_trimmer_with_temp <<2 , dati_da_leggere_o_scrivere);
805 pendenza_deriva_trimmer_compensazione=-(*(int32_t *)dati_da_leggere_o_scrivere); //Segno "-" perch\'e la variazione deve essere opposta.
806 variazione_trimmer_termico = (differenza_trimmer_offset * pendenza_deriva_trimmer_offset) / pendenza_deriva_trimmer_compensazione ;
807 variazione_trimmer_termico += (((differenza_trimmer_offset * pendenza_deriva_trimmer_offset) % pendenza_deriva_trimmer_compensazione )*2 )/(pendenza_deriva_trimmer_compensazione)\
808 + trimmer_comp_di_default ; //Vediamo anche il mezzo bit
809 }
810 // Il nuov valore del trimmer termico sar\'a il risultato precedente sommato a quello di base.
811 if ( variazione_trimmer_termico >0xff){
812 dati_da_leggere_o_scrivere[0] =0xff;
813 }else if ( variazione_trimmer_termico <0 ){
814 dati_da_leggere_o_scrivere[0] =0;
815 }else{
816 dati_da_leggere_o_scrivere[0] = variazione_trimmer_termico & 0xff;
817 }
818 }else{
819 //se non ci sono ccalibrazioni imposto il trimmer termico a 128
820 //Impostiamo il trimmer termico a 128
821 dati_da_leggere_o_scrivere[0]=128;
822 }
823
824 // Questo nuovo valore viene scritto nel trimmer
826 dati_da_leggere_o_scrivere[0], preamplifier_scrivi_il_trimmer );
827}
828//! <!-- [fun_preamplifier_determina_trimmer_therma_comp] -->
829
830// CROSS FINE
831
832
int32_t ADC_misura_differenziale_con_media_generico(uint8_t scheda_su_scheda_giu_, uint8_t preamplifier_externalADC_1_onboardADC_0, uint8_t nodo_da_misurare, uint8_t differenziale_1_single_0)
This function sets the original gain when a few LSb have to be determined. The umber of bits is bit_t...
Definition: Adc.c:899
volatile uint16_t ADC_medie_per_misura
the number of ADC readings to average, the maximum is 400
Definition: Adc.c:206
const struct ADC_coefficiente_type ADC_coefficiente[]
Node normalizing coeficinets used in ADC_lettura_24bit()
Definition: Adc.c:210
#define ADC_molteplicita_node_to_read
Definition: Adc.h:64
@ instr_readback_node_voltages
Nodes voltage read from external ADC.
uint8_t tx_data[8]
Transmission data vector.
Definition: Can.c:321
uint32_t volatile evento_CAN
This is the variable which resembles the flags from the communication.
Definition: Can.c:326
uint32_t tx_obj_idx
This is the variable which resembles the flags from the communication.
Definition: Can.c:323
unsigned int indirizzo_CAN_della_scheda
Per ora lo assegnamo cos\i l'indirizzo della scheda.
Definition: Can.c:335
volatile uint8_t rx_data[8]
Received data vector.
Definition: Can.c:318
ARM_DRIVER_CAN * CANdrv
Definition: Can.c:333
void PGA_GAIN_CROSS(uint8_t scheda_su_scheda_giu, uint8_t canale, uint8_t PGA_gain_to_set)
Here the 2 digital signals from the trimmer are exploited to set the gain of the input stage of the P...
Definition: DAC_PGA.c:109
uint8_t guadagno_minimo_PGA
Definition: DAC_PGA.c:88
uint8_t PGA_settled_gain[12]
PGA set gain.
Definition: DAC_PGA.c:95
#define detector_bit_per_storing_startup
#define detector_bit_per_storing_user_state
#define detector_bit_recall_user_defined
#define detector_bit_recall_startup
#define detector_bit_store_state_in_user_as_it_is
#define detector_offset_from_half_scale
void Error_imposta_la_istruzione(void)
Function to be located at the end of every instruction to mark the error, if any.
void ERROR_codifica_errore(uint8_t scheda_su_scheda_giu, unsigned char error_addres, unsigned char code_to_shift, uint8_t reset_count_se_0)
If an error is found its flag is codified here.
@ CAN_error_comunichiamo_qualche_dato_timeout_on_transmission
Transmission CAN error.
@ error_address_CAN
Error register for CAN bus
#define istruzione_byte_3
Definition: Istruzioni.h:23
#define byte_istr_dati_0
Definition: Istruzioni.h:25
#define istruzione_byte_4_e_scelta_canale
Definition: Istruzioni.h:24
volatile uint16_t LED_rosso_fondo_scala
Definition: Led.c:56
void EPROM_lettura_M24C32_64(uint8_t scheda_su_scheda_giu_, uint8_t mainboard_postmainboard, uint8_t canale, short indirizzo_memoria, uint8_t *dati_letti)
Read from preamplifier and on-board flashes.
void EPROM_store_recover_state_M24C32_64(uint8_t scheda_su_scheda_giu, uint8_t canali_da_regolare, uint8_t set_1_store_0, uint8_t startup_1_user_0)
Store the system state or recover and apply the system state.
@ Memory_preamplifier_slope_calibration_ON_0_OFF_ff
slope trimmer active if zero
@ Memory_preamplifier_compensation_slope_trimmer_with_temp
thermal compensation trimmer temperature drift
@ Memory_preamplifier_trimmers_for_drift
preamplifier trimmer at default
@ Memory_preamplifier_address_fine_trimmer_slope_offset
fine slope for trimmer offset
@ Memory_preamplifier_offset_slope_trimmer_with_temp
offset trimmer temperature drift, this number is in nV
@ Memory_preamplifier_address_coarse_trimmer_slope_offset
coarse slope for trimmer offset
@ Memory_preamplifier_drift_ON_0_OFF_ff
offset drift correction active if zero
void Analog_mux_line_to_select_deselect(uint8_t scheda_su_scheda_giu, uint8_t line_to_select, uint8_t select_1_deselect_0)
Selection of the line to mesure with the analog MUX of the mainboard, driven by the I2C->parallel mux...
@ node_voltage_Analog_Mux_0_offset
Starting Offset for this set of nodes, 32.
void instr_preamplifier_scrittura_lettura_trimmer_offset_function(void)
Content of the preamplifier trimmers can be read/write.
void preamplifier_trova_il_guess(uint8_t trimmer_da_usare)
static void preamplifier_normalize_gain_offset_error(uint8_t scheda_su_scheda_giu_)
The ouput offset will be set at the value that was given with the instr_ouput_offset_we_want_to_set i...
void instr_output_offset_to_be_set_function(void)
The detector bias will be set at the value set with the function instr_detector_Vbias_we_want_to_set_...
void preamplifier_ritorno_al_gain_originale(uint8_t scalata, uint8_t indice_trimmer, uint8_t *target_raggiunto_1_non_raggiunto_0)
This function sets the original gain when a few LSb have to be determined. The umber of bits is bit_t...
void instr_ouput_offset_we_want_to_set_function(void)
The preamplifier offset will be set at the value passed from the CAN with this function if,...
void preamplifier_determina_trimmer_therma_comp(uint8_t scheda_su_scheda_giu, uint8_t canale, uint8_t valore_previsto_trimmer_offset, uint8_t solo_recupero_default_comp_se_1)
This function determines and set the thermal compensation trimmer.
int32_t preamplifier_Output_offset_target[12]
Offset target values.
void preamplifier_aggiusta_offset_SAR(void)
This function provide the output offset with the standard SAR method.
int32_t preamplifier_ADC_external_measured_node_function(uint8_t scheda_su_scheda_giu, uint8_t indice)
This function provide node reading from an external ADC.
#define preamplifier_scrivi_il_trimmer
void Aspetta_tanti_ms(int millisecondi)
The timing function.
Definition: Timer.c:52
uint8_t volatile contenuto_trimmer_preamplifier[12][4]
Definition: Trimmer.c:179
void preamplifier_scrittura_lettura_trimmer(uint8_t scheda_su_scheda_giu, uint8_t canale, uint8_t trimmer, uint8_t valore, uint8_t scrivi_1_leggi_0)
Setting the value of any trimmer for preamplifier trimmer, the contents of the trimmers are stored in...
Definition: Trimmer.c:283
#define trimmer_fine_offset
Definition: Trimmer.h:80
#define trimmer_coarse_offset
Definition: Trimmer.h:82
#define trimmer_thermal_compensation
Definition: Trimmer.h:81
volatile int8_t vettore_istruzioni[8]
This is a copy of the received 8 bytes from the CAN.