CROSS Technical Documentation User Manual and Technical Doc.
INFN Milano Bicocca
Loading...
Searching...
No Matches
Detector_Bias.c
Go to the documentation of this file.
1#include "tutti_gli_header.h"
2
3/// \file
4
5/*! \page Detector_Bias The Detector Bias
6\anchor Detector_Bias_ref
7*\brief <span style="color:red;"> <b> Managing of the detctor bias </b> </span>
8*\tableofcontents
9
10 \b SUMMARY:
11*\arg \ref introduction_to_detector_bias
12*\arg \ref user_use_of_detector
13*\arg \ref offset_set_approach
14
15*\section introduction_to_detector_bias Detector bias: general
16<hr width="90%" size="10" align="left">
17
18\n Every channel has one quad-trimmer chip, the <a href="./File_pdf/AD5263.pdf" target=_blank><b>AD5263 datasheet</b></a>, to set the positive and negative bias
19applied to the load resitor in simmetric way. A scheme of the AD5263 is in figure \ref Figure_Trimmer_AD5263.
20\n The bias channels are 2 to allow to power in asymmetric way the 2 OAs: from +5 V up to +30 V and -5 V the OA for positive generation and from -5 V down to -30 V and +5 V
21the OA for negative generation of the bias. The amount of generating bias depends on the value of the pair of trimmers, coarse and fine, used at the input of each channel.
22The function to use is detector_scrittura_lettura_trimmer_bias() (refer to the \ref Trimmer page for datail). Here an example:
23
24<span style="color:orange;"> <I>
25\code {.c}
26detector_scrittura_lettura_trimmer_bias( scheda_su_scheda_giu_provvisorio, canale_, detector_trimmer_bias_coarse_pos, 118, 1);
27detector_scrittura_lettura_trimmer_bias( scheda_su_scheda_giu_provvisorio, canale_, detector_trimmer_bias_coarse_neg, 138, 1);
28\endcode
29</I> </span>
30\n From the example above we can extract 2 important rules. The first is the selection of the trimmer to use
31that can be done by the definitions, the value of the definition is its bullet:
32<ol start="0">
33 <li> #Detector_trimmer_coarse_bias_pos
34 <li> #Detector_trimmer_coarse_bias_neg
35 <li> #Detector_trimmer_fine_bias_pos
36 <li> #Detector_trimmer_fine_bias_neg
37 </li>
38</ol>
39
40\n The second regards the value that the trimmers should take. The middle value is at \b 128. The coarse trimmer has a negative gain so for positive output voltages
41the trimmer must take values smaller than \b 128, the inverse happens for negative output volatges.
42\n Considering the present hw setting we expect that the wiper, as a consequence of the trimmer attenuation (1k + 1k with the 20k trimmer, #detector_trimmer_attenuation_x_1000),
43a \b step of about \b 35 \b mV. This gives, at the OA output a valu of (the gain is 2M / 270k,
44#detector_OA_inverting_gain_x_1000) \b 0.2604 \b V \b per \b step.
45\n Now the effect of the fine trimmer, starting with an example:
46<span style="color:orange;"> <I>
47\code {.c}
48detector_scrittura_lettura_trimmer_bias( scheda_su_scheda_giu_provvisorio, canale_, detector_trimmer_bias_fine_pos, 148, 1);
49detector_scrittura_lettura_trimmer_bias( scheda_su_scheda_giu_provvisorio, canale_, detector_trimmer_bias_fine_neg, 108, 1);
50\endcode
51</I> </span>
52
53\n This trimmer has an attenuation at its output of \b 101 ( 10K over 1M, its inverse is this: #detector_fine_trimmer_attenuation). It is applied to the non-inevrting
54input of the OA and therefore, its gain is one unit larger than that for the coarse gain (= 2M/270K +1, #detector_OA_non_inverting_gain_x_1000). Important: for obatining a positive
55variation of the output voltage the trimmer value must exceed \b 128, the opposit for obtaining a negative output voltage.
56\n Every wiper step is expected one hundred smaller than before, or \b 0.378 \b mV, while the OA output \b 2.96 \b mV \b per \b step.
57\n Summary:
58
59\n
60<center>
61\anchor Table_slopes_and_trimmers \b Table \b slopes \b and \b trimmers
62Reading node | Detector bias slope | trimmer /gain |
63:-----------------| :----------------------:| :--------------------------------------------------|
64Bias positive | corse: 0.264 V/step | #Detector_trimmer_coarse_bias_pos / negative gain |
65^ | fine: 2.99 mV/step | #Detector_trimmer_fine_bias_pos / positive gain |
66Bias Negative | corse: 0.2604 V/step | #Detector_trimmer_coarse_bias_neg /negative gain |
67^ | fine: 2.99 mV/step | #Detector_trimmer_fine_bias_neg / positive gain |
68</center>
69
70\note The OA outputs are read with an attenuation of 16k / 100k or \b 1/7.25, #detector_attenuazione_della_lettura_x_1000. The same attenuation is applied to the reading of the
71external bias.
72
73*\anchor Figure_Trimmer_AD5263
74*\image html Trimmer_AD5263.png "FigureTrimmer_AD5263: simplified" width=30%
75*\image latex Trimmer_AD5263.png "FigureTrimmer_AD5263: simplified" width=30%
76
77*\section user_use_of_detector User use with CAN bus of the detector bias
78<hr width="90%" size="10" align="left">
79
80\n Every channel can have adjusted its detector bias with 4 trimmers. The bias is given differential and the positive
81value equals the absolute negative value.
82For each branch 2 trimmers are dedicated, the MS 8 bits and the LS 8 bits for each. The resolution is almost 16 bits.
83The content of each trimmer is in the matrix 12 x 4
84#contenuto_trimmer_detector[12][4]. There is another vector where the content of the target voltage to be set, in mV,
85are stored. This is the #Detector_bias_target[12]. In both the matrix and the vector the positions are 12 to account
86for the lower and upper board.
87\n When we need to set a bias we have to consider 2 instructions. The first allows to set the target voltage
88for each channels. This voltage can be the same or different for each channel.
89The function to do this is instr_detector_Vbias_we_want_to_set_function():
90*\snippetlineno Detector_Bias.c fun_instruction_Vbias_target
91The bias, stored in the first 2 Bytes of the instruction data received, is applied to the channel(s)
92for which there is a "1" in the corresponding position at Byte<SUB>6</SUB>.
93\n After that the target bias have been set it must be adjusted. This can be done by calling the
94function instr_Vbias_to_be_set_function().
95These 2 commands are called in sequence over the CAN.
96\n Trimmer contents can be readback with the CAN command <a href="_instruction_set.html#instr_detector_scrittura_lettura_trimmer_bias_option">da instr_detector_scrittura_lettura_trimmer_bias</a>.
97
98\anchor Vbias_explanation
99*\section offset_set_approach The approach to the detector bias setting
100<hr width="90%" size="10" align="left">
101
102\n The approach to the bias setting considers independent the positive and negative branches of the bias,
103and avoids suddend voltages changes typical of the Successive Aapproximation procedure.
104\n One of the OA feedback resistances and the load resistances have a good relative matching, but a few % of absolute matching.
105There are 2 fed backed OAs, \ref Figure_detector_bias_setup, and, to minimize common mode settings, the bias for them
106is provided in an independent way and the detector resistances, R<sub>Lxy</sub> in \ref Figure_detector_bias_setup are calibrated.
107
108*\anchor Figure_detector_bias_setup
109*\image html Bias_setup.png "Figure_detector_bias_setup 1: Bias setup system for detector bias." width=60%
110*\image latex Bias_setup.png "Figure_detector_bias_setup 1: Bias setup system for detector bias." width=60%
111
112\n The branch that provides the positive bias, V<SUB>HV+</SUB>, or more generically called V<SUB>bias</SUB>,
113is supplied from -5 V up to 30 V, while the that providing the negative bias, V<SUB>HV-</SUB>, or more generically called V<SUB>bias</SUB>, is supplied
114from +5 V down to -30 V.
115\n The trimmers are biased from a precise pair of &plusmn;5 V and the setting of the wiper is independent from the OA power supplies.
116\n The resistance, hence the slopes at the wipers, are previously calibrated and stored in the preamplifier
117<a href="_flash__m24_c_x_x.html"> EPROM</a>. If calibration is not already provided it is measured, once, before the bias setting.
118\n The knowledge of the slope is important to limit the use of the Successive Approxiamtion Registre, SAR, technique.
119The first step for setting the bias is to calculate the gues value for the trimmer. Then the residual error is measured and the SAR is applied to
1202 or 3 bits only. This avoid the first steps of the classical SAR that consist of try with half the full scale
121of the ouput value, that can be 15 V even if the bias to apply is a few hundreds of mV.
122\n The adjusting is done by a function that has embedded 2 other static functions. They are:
123
124<ol style="list-style-type:none">
125<li> \b &rArr; \n
126 instr_Vbias_to_be_set_function() sets some starting value for the parameters to use and retrieve the calibrations
127for the load and refernce resistors from the preamplifier EPROM. If the calibrations have not yet done
128they are evaluated at this moment and stored in the EPROM at the proper location. After that this initial procedure ends
129the Detector_aggiusta_offset_SAR() is called.</li>
130<li> \b &rArr; \n
131 The fisrt step Detector_aggiusta_offset_SAR() does is to call misura_il_valore_trimmer_detector() for evaluating
132the gues values and the erros, namely the minimum number of LS bits to evaluate in SAR, for the MSB of both the positive
133and negative branches. At this point the SAR is applied to thebits, minimum 2, of the MSB. At the end of this procedure
134misura_il_valore_trimmer_detector() is called again to find the gues value for the LSB. To the LS bits from the residual error, minimum
1352, the SAR is applied. In this way the SAR is applied to a minimum of 4 bits, against 16 bits.</li>
136<li> \b &rArr; \n
137 misura_il_valore_trimmer_detector() determines the gues value for the MSB and LSB. It measures
138the bias a fisrt time and determines the gues value for the trimmer, either MSB or LSB. Then a new
139measure is done to evaluate the residual error.</li>
140</ol>
141
142\sa <a href="_instruction_set.html#instr_Vbias_to_be_set_option">instr_Vbias_to_be_set_option</a> is the CAN
143isntruction to set the bias voltage value and
144<a href="_instruction_set.html#instr_Vbias_to_be_set_option">instr_Vbias_to_be_set_option</a> is the CAN isntruction
145to adjust the bias at the target value set with the previous instruction.
146
147
148 The codes for managing the bias are:
149 - \ref Detector_Bias.c
150 - \ref Detector_Bias.h
151
152
153<!-- pappa -->
154
155*/
156
157//INIZIO CROSS
158
159volatile uint16_t Detector_attesa_tra_le_misure=10;
160int32_t Detector_error_voltage=10000;
161uint8_t Detector_canali_da_regolare=0;
162uint8_t Detector_externalADC_1_onboardADC_0=0;
163uint8_t Detector_SAR_1_no_SAR_0=1;
164uint8_t Detector_fastSAR_1_no_fastSAR_0=1;
165uint8_t Detector_PGA_settled_gain_old[12];
166int32_t Detector_misura_fatta_old[12];
167int32_t Detector_bias_target_negativo[12];
168
169
170
171//! Large Load resistor, negative side, normalizing factor with repect to the positive resistors
172const struct Detector_coefficiente_type /*{
173 int16_t numeratore;
174 int16_t denominatore;
176 1 ,1,
177 1 ,1,
178 1 ,1,
179 1 ,1,
180 1 ,1,
181 1 ,1,
182 1 ,1,
183 1 ,1,
184 1 ,1,
185 1 ,1,
186 1 ,1 };
187
188//! Small Load resistor, negative side, normalizing factor with repect to the positive resistors
189const struct Detector_coefficiente_type /*{
190 int16_t numeratore;
191 int16_t denominatore;
193 1 ,1,
194 1 ,1,
195 1 ,1,
196 1 ,1,
197 1 ,1,
198 1 ,1,
199 1 ,1,
200 1 ,1,
201 1 ,1,
202 1 ,1,
203 1 ,1 };
204
205//! Coarse trimmer, negative side, normalizing factor with repect to the positive side
206const struct Detector_coefficiente_type /*{
207 int16_t numeratore;
208 int16_t denominatore;
210 1 ,1,
211 1 ,1,
212 1 ,1,
213 1 ,1,
214 1 ,1,
215 1 ,1,
216 1 ,1,
217 1 ,1,
218 1 ,1,
219 1 ,1,
220 1 ,1 };
221
222const int32_t Detector_positive_coarse_step_trimmer[]={Detector_default_coarse_trimmer,Detector_default_coarse_trimmer,Detector_default_coarse_trimmer,
223 Detector_default_coarse_trimmer,Detector_default_coarse_trimmer,Detector_default_coarse_trimmer,
224 Detector_default_coarse_trimmer,Detector_default_coarse_trimmer,Detector_default_coarse_trimmer,
225 Detector_default_coarse_trimmer,Detector_default_coarse_trimmer,Detector_default_coarse_trimmer};
226
227const int32_t Detector_positive_fine_step_trimmer[]={ Detector_default_fine_trimmer,Detector_default_fine_trimmer,Detector_default_fine_trimmer,
228 Detector_default_fine_trimmer,Detector_default_fine_trimmer,Detector_default_fine_trimmer,
229 Detector_default_fine_trimmer,Detector_default_fine_trimmer,Detector_default_fine_trimmer,
230 Detector_default_fine_trimmer,Detector_default_fine_trimmer,Detector_default_fine_trimmer};
231
232const int32_t Detector_negative_coarse_step_trimmer[]={Detector_default_coarse_trimmer,Detector_default_coarse_trimmer,Detector_default_coarse_trimmer,
233 Detector_default_coarse_trimmer,Detector_default_coarse_trimmer,Detector_default_coarse_trimmer,
234 Detector_default_coarse_trimmer,Detector_default_coarse_trimmer,Detector_default_coarse_trimmer,
235 Detector_default_coarse_trimmer,Detector_default_coarse_trimmer,Detector_default_coarse_trimmer};
236
237const int32_t Detector_negative_fine_step_trimmer[]={ Detector_default_fine_trimmer,Detector_default_fine_trimmer,Detector_default_fine_trimmer,
238 Detector_default_fine_trimmer,Detector_default_fine_trimmer,Detector_default_fine_trimmer,
239 Detector_default_fine_trimmer,Detector_default_fine_trimmer,Detector_default_fine_trimmer,
240 Detector_default_fine_trimmer,Detector_default_fine_trimmer,Detector_default_fine_trimmer};
241
242/*! \brief Detector bias target values
243*\snippet Detector_Bias.c vec_Detector_bias_target
244*/
245//! <!-- [vec_Detector_bias_target] -->
246int32_t Detector_bias_target[12]={1000, 1000, 1000, 1000, 1000, 1000,
247 1000, 1000, 1000, 1000, 1000, 1000}; //!< This is the detector bias target, not the bias set.
248 //The value is in microV
249//! <!-- [vec_Detector_bias_target] -->
250
251volatile struct detector_SAR_ini_type /*{ // SAR ini register
252 uint8_t starting_value_pos;
253 uint8_t starting_value_neg;
254 uint8_t starting_exp_value_pos;
255 uint8_t starting_exp_value_neg;
256 uint8_t target_non_raggiunto_pos;
257 uint8_t target_non_raggiunto_neg;
258}*/ Detector_SAR_ini[12];
259
260
261
262
263/*! \brief The state of the Detector realis is considerede. Note that this is the wanted working condition. The position of
264 the relays could be unpredictable after a power cut.
265*\snippet Detector_Bias.c vec_detector_Relay_state
266*/
267//! <!-- [vec_detector_Relay_state] -->
268uint8_t detector_Relay_state[12]; /*!< this are the replica of the flags used of the relay at detector_Relay_flags_setting*/
269//! <!-- [vec_detector_Relay_state] -->
270
271/*! \brief The detector bias will be set at the value passed from the CAN with this function if,
272after this setting, it is launched instr_Vbias_to_be_set_function().
273
274The 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.
275The 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
276is 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.
277Run the command several times if the targety is different among the channles.
278These values are stored in the vector #Detector_bias_target[12].
279Only positive values are accepted and the voltage is considered the total bias voltage, namely Voltage==Vbias_pos - Vbias_neg, symmetric.
280*\return No Parameters, the actual result is sent to the CAN bus output throught \ref tx_data.
281
282*\snippetlineno Detector_Bias.c fun_instruction_Vbias_target
283*/
284//! <!-- [fun_instruction_Vbias_target] -->
286uint8_t canali_ , canali_input=vettore_istruzioni[istruzione_byte_4_e_scelta_canale];
287 uint8_t scheda_su_giu = ((canali_input >> 7) & 1)*6;
288 uint8_t offset_scheda=0;
289 int32_t bias_to_apply,ADC_max_bias_pos, ADC_min_bias_neg;
290 if (scheda_su_giu){
291 offset_scheda=6;
292 }
299 bias_to_apply=(( *(uint16_t *)vettore_istruzioni ) & 0xFFFF) *1000;
300
301 if(ADC_max_bias_pos > ADC_min_bias_neg){
302 ADC_max_bias_pos=ADC_min_bias_neg; //prendiamo la pi\'u piccola delle 2 tensioni
303 }
304
305 if(bias_to_apply > ADC_max_bias_pos){
306 bias_to_apply=ADC_max_bias_pos;
307 }
308 ADC_max_bias_pos =bias_to_apply/1000;
309 tx_data[0]= ADC_max_bias_pos & 0xff;
310 tx_data[1]= (ADC_max_bias_pos >>8) & 0xff; //Ritorniamo il valore effettivo impostato
311
312
313 for( canali_=0; canali_ <6; canali_ ++){
314 if( (canali_input >> canali_) & 1){
315// Detector_bias_target[offset_scheda + canali_]= (( *(uint16_t *)vettore_istruzioni ) & 0xFFFF) *1000 ;
316
317 Detector_bias_target[canali_ + scheda_su_giu]= bias_to_apply ; //Lasciamo il limite a 6
318 }
319 }
321}
322//! <!-- [fun_instruction_Vbias_target] -->
323
324
325/*! \brief The detector bias will be set at the value set with the function instr_detector_Vbias_we_want_to_set_function()
326with which the target values are stored in the vector #Detector_bias_target[].
327
328*\return No Parameters, the actual result is sent to the CAN bus output throught \ref tx_data.
329
330*\snippetlineno Detector_Bias.c fun_instr_Vbias_to_be_set_function
331*/
332//! <!-- [fun_instr_Vbias_to_be_set_function] -->
334uint8_t iii,canale, indice, dati_scambio[4], Detector_pre_out_offset_no_change, no_slope=0;
335uint8_t volatile tx_data_buffer[8],fai_fai=1;
336int8_t variazione, scheda_su_scheda_giu,Detector_offset_starts_at_half_scale;
337int32_t delta;
338
340//uint8_t non_toccare_il_gain_del_pre= vettore_istruzioni[3] & 0x2;
341
342 for(iii=0;iii < 8;iii++){// Potrebbe essere richiesto qualcosa sul can,
343 //bufferizziamo l'istruzione
344 tx_data_buffer[iii]= tx_data[iii];
345 }
346// Ora interpretiamo l'istruzione
347 //attesa tra le misure
348 Detector_attesa_tra_le_misure = vettore_istruzioni[4] *100;
349 if (Detector_attesa_tra_le_misure==0) Detector_attesa_tra_le_misure=100;
350 //errore tollerato
351 Detector_error_voltage= vettore_istruzioni[5] *1000;
352 if (Detector_error_voltage==0) Detector_error_voltage=200e3;
353 if( Detector_error_voltage < minimum_error_detector_voltage) Detector_error_voltage = minimum_error_detector_voltage;
354 //i canali da agiustare
355 Detector_canali_da_regolare= vettore_istruzioni[6];
356 uint8_t Detector_canali_da_regolare_iniziali = Detector_canali_da_regolare;
357 scheda_su_scheda_giu = ((vettore_istruzioni[6] >> 7) & 1)*6;
358
359//Flags dal byte 3 dell'istruzione
360 Detector_externalADC_1_onboardADC_0 = vettore_istruzioni[3] & 1; //l'adc da usare, interno o esterno
361 Detector_pre_out_offset_no_change = (vettore_istruzioni[3]>>3 ) & 1; //pre output offset no change
362 Detector_offset_starts_at_half_scale = ( vettore_istruzioni[3] >> 4 ) & 1; //
363
364// struct EPROM_detector_{
365// int32_t slope_coarse_positiva;
366//// int32_t coefficiente_raccordo_slope_coarse; //=(slope_coarse_pos<<10)/(slope_coarse_neg), ricordarsi di dividere per 2^10 quando si usa
367// int32_t slope_coarse_negativa;
368// int32_t slope_fine_positiva;
369//// int32_t coefficiente_raccordo_slope_fine; //=(slope_fine_pos<<10)/(slope_fine_neg), ricordarsi di dividere per 2^10 quando si usa
370// int32_t slope_fine_negativa;
371//// int8_t offset_coarse_neg;
372//// int8_t offset_fine_neg;
373//};
374
375#define det_slope_default_coarse (int32_t) -264000
376#define det_slope_default_fine (int32_t) 3000
377EPROM_detector__ EPROM_detector[6]={det_slope_default_coarse,det_slope_default_coarse,det_slope_default_fine,det_slope_default_fine,
378 det_slope_default_coarse,det_slope_default_coarse,det_slope_default_fine,det_slope_default_fine,
379 det_slope_default_coarse,det_slope_default_coarse,det_slope_default_fine,det_slope_default_fine,
380 det_slope_default_coarse,det_slope_default_coarse,det_slope_default_fine,det_slope_default_fine,
381 det_slope_default_coarse,det_slope_default_coarse,det_slope_default_fine,det_slope_default_fine,
382 det_slope_default_coarse,det_slope_default_coarse,det_slope_default_fine,det_slope_default_fine};
383
384ERROR_codifica_errore( 0, 0, 0, 0 ); // In caso il canale 0 non sia compreso resettiamo qui
385
386//Leggiamo le memorie
387//Inganniamo e prepariamo l'istruzione per l'eventuale valutazione della pendenza qui sotto
388for(iii=0;iii<4;iii++){
389 tx_data[iii]=0;
390}
391tx_data[4]= (tx_data_buffer[3] & 1 )+ (vettore_istruzioni[2] << 2);
392
393 for(canale=0;canale<6;canale++){//Carichiamo o determiniamo le pendenze
394 if( (Detector_canali_da_regolare >> canale) &1){
395 EPROM_lettura_M24C32_64(scheda_su_scheda_giu, I2C_mainboard, canale, Memory_detector_coarse_slope_calibration_ON_0_OFF_ff <<2,dati_scambio);
396
397 if(flag_error_verified) Detector_canali_da_regolare =0; //Lettura fallita, non facciamo pi\'u niente
398
399 if(dati_scambio[0] & (flag_error_verified ==0)){// Calibrazione non ancora fatta.
400 //Se non c'e' calibrazione usiamo il default e segnaliamo l'errore
402 flag_error_verified=0; //Forziamo la misura
403 no_slope =0xFF; //Segnaliamo per l'errore
404// tx_data[5]=2; //coarse measurement
405// tx_data[6] = canale;
406// tx_data[4]= (tx_data_buffer[3] & 1 )+ (vettore_istruzioni[2] << 2);
407// if (scheda_su_scheda_giu) tx_data[6] += 0x80;
408// instr_DetBias_trimmer_calibration_function(); //Si misura e si mette nella eprom la pendenza coarse
409// if(flag_error_verified) Detector_canali_da_regolare =0; //Lettura fallita, non facciamo pi\'u niente
410 }
411// if ( (flag_error_verified ==0)){ //provvisorio, poi si toglie
412 if( dati_scambio[0] ==0){
413 EPROM_lettura_M24C32_64(scheda_su_scheda_giu, I2C_mainboard, canale, Memory_detector_positive_address_coarse_trimmer_slope_bias <<2,dati_scambio);
414 EPROM_detector[canale].slope_coarse_positiva=*(int32_t *)dati_scambio;
415 EPROM_lettura_M24C32_64(scheda_su_scheda_giu, I2C_mainboard, canale, Memory_detector_negative_address_coarse_trimmer_slope_bias <<2,dati_scambio);
416 EPROM_detector[canale].slope_coarse_negativa= *(int32_t *)dati_scambio;
417// EPROM_detector[canale].coefficiente_raccordo_slope_coarse = (EPROM_detector[canale].slope_coarse_positiva << 10) / EPROM_detector[canale].slope_coarse_negativa ;
418 }
419
420 EPROM_lettura_M24C32_64(scheda_su_scheda_giu,I2C_mainboard, canale, Memory_detector_fine_slope_calibration_ON_0_OFF_ff <<2,dati_scambio);
421 if(flag_error_verified) Detector_canali_da_regolare =0; //Lettura fallita, non facciamo pi\'u niente
422
423 if(flag_error_verified) Detector_canali_da_regolare =0; //Lettura fallita, non facciamo pi\'u niente
424 if(dati_scambio[0] & (flag_error_verified ==0)){
425 tx_data[5]=1; //fine measurement
426 tx_data[6] = canale ;
427 tx_data[4]= (tx_data_buffer[3] & 1 )+ (vettore_istruzioni[2] << 2);
428 if(scheda_su_scheda_giu) tx_data[6] += 0x80;
429 instr_DetBias_trimmer_calibration_function(); //Si misura e si mette nella eprom la pendenza fine
430 if(flag_error_verified) Detector_canali_da_regolare =0;
431 }
432 if ( (flag_error_verified ==0)){ //provvisorio, poi si toglie
433 EPROM_lettura_M24C32_64(scheda_su_scheda_giu, I2C_mainboard, canale, Memory_detector_positive_address_fine_trimmer_slope_bias <<2,dati_scambio);
434 EPROM_detector[canale].slope_fine_positiva=*(int32_t *)dati_scambio;
435 EPROM_lettura_M24C32_64(scheda_su_scheda_giu, I2C_mainboard, canale, Memory_detector_negative_address_fine_trimmer_slope_bias <<2,dati_scambio);
436 EPROM_detector[canale].slope_fine_negativa= *(int32_t *)dati_scambio;
437// EPROM_detector[canale].coefficiente_raccordo_slope_fine = (EPROM_detector[canale].slope_fine_positiva << 10) / EPROM_detector[canale].slope_fine_negativa ;
438 }
439 }
440 }
441 for(iii=0;iii<8;iii++){
442 tx_data[iii]= tx_data_buffer[iii]; //recuperiamo l'istruzione
443 }
444
445if (Detector_offset_starts_at_half_scale){
446//Initialization for default SAR, changes are applied in fastSAR, eventually
447 for( canale=0;canale<12;canale++){
448 Detector_SAR_ini[canale].starting_value_pos =128;
449 Detector_SAR_ini[canale].starting_value_neg =128;
450 }
451 }else{//Si inizia ad aggiustare da dove si \'e
452 for( canale=0;canale<6;canale++){
453 Detector_SAR_ini[canale + scheda_su_scheda_giu].starting_value_pos =contenuto_trimmer_detector[canale + scheda_su_scheda_giu][Detector_trimmer_coarse_bias_pos];
454 Detector_SAR_ini[canale + scheda_su_scheda_giu].starting_value_neg =contenuto_trimmer_detector[canale + scheda_su_scheda_giu][Detector_trimmer_coarse_bias_neg];
455 }
456 }
457
458 for( canale=0;canale<6;canale++){
459 if( (Detector_canali_da_regolare >> canale) &1 ){
460 Detector_SAR_ini[canale + scheda_su_scheda_giu].target_non_raggiunto_neg=true;
461 Detector_SAR_ini[canale +scheda_su_scheda_giu].target_non_raggiunto_pos=true;
462 Detector_SAR_ini[canale +scheda_su_scheda_giu].starting_exp_value_pos=7;
463 Detector_SAR_ini[canale +scheda_su_scheda_giu].starting_exp_value_neg=7;
464 }
465 }
466
467//FINE: Initialization for default SAR, changes are applied in fastSAR, eventually
468
469//Se vogliamo conservare l'offset dobbiamo misurarlo.
470 if(Detector_pre_out_offset_no_change){
471 for( canale=0;canale<6;canale++){
472 if( (Detector_canali_da_regolare >> canale) &1 ){
473 preamplifier_Output_offset_target[scheda_su_scheda_giu + canale] = ADC_misura_differenziale_con_media_generico(scheda_su_scheda_giu,preamplifier_externalADC_1_onboardADC_0,canale,1);
474 }
475 }
476 }
477//Impostiamo tutti i guadagni del PGA ad 1 e del pre a 20
478if(flag_error_verified==0){
479 for(canale=0; canale< 6; canale++){
480 preamplifier_set_reset_pre_gain ( scheda_su_scheda_giu, canale, preamplifier_Gain_basso );
481 indice= canale + scheda_su_scheda_giu;
482 Detector_PGA_settled_gain_old[indice]= PGA_settled_gain[indice];
483 PGA_GAIN_CROSS( scheda_su_scheda_giu , canale , guadagno_minimo_PGA );
484 if(flag_error_verified) Detector_canali_da_regolare =0;
485 //Inserire test errori qui
486 }
487}
488
489
490 //SAR ottimizzato
491 Detector_aggiusta_offset_SAR( EPROM_detector, scheda_su_scheda_giu);
492
493
494//Riportiamo i guadagni al valore nominale
495
496 for(canale=0; canale< 6; canale++){
497 preamplifier_set_reset_pre_gain ( scheda_su_scheda_giu, canale, preamplifier_Gain_alto );
498 indice= canale + scheda_su_scheda_giu;
499 if(Detector_pre_out_offset_no_change==0) PGA_GAIN_CROSS( scheda_su_scheda_giu , canale , Detector_PGA_settled_gain_old[indice] );
500 }
501
502 if(Detector_pre_out_offset_no_change){
503 uint8_t istruzione_old[8];
504 for(iii=0;iii<8;iii++){
505 istruzione_old[iii]=vettore_istruzioni[iii];
506 }
507 for(iii=0;iii<6;iii++){
508 PGA_settled_gain[iii+scheda_su_scheda_giu]= Detector_PGA_settled_gain_old[iii+scheda_su_scheda_giu];
509 }
511 vettore_istruzioni[2]=istruzione_old[2];vettore_istruzioni[3]=0;
512 if(vettore_istruzioni[2] ==0) vettore_istruzioni[2]=10;
513 vettore_istruzioni[4]=istruzione_old[4];
515 vettore_istruzioni[5]=istruzione_old[5];
516 if(vettore_istruzioni[5]==0) vettore_istruzioni[5] =50;
517 vettore_istruzioni[6]=istruzione_old[6];
519 instr_output_offset_to_be_set_function(); //Lanciamo la funzione di aggiustamento offset, che alla fine imposter\'a i guadagni corretti finali
520 for(iii=0;iii<8;iii++){
521 vettore_istruzioni[iii]=istruzione_old[iii];
522 }
523 }
524
525 for(iii=0;iii < 8 ;iii++){
526 tx_data[iii]= tx_data_buffer[iii];
527 }
528 tx_data[0] = no_slope; //Se la slope non nella rom la notifichiamo
529 tx_data[6] = Detector_canali_da_regolare & 0x3F; //i canali non in tolleranza hanno un 1 in corrispondenza
530 tx_data[5] = Detector_error_voltage / 1000;
532
533 //Dobbiamo scrivere in memoria se richiesto, da abilitare
534// EPROM_store_recover_detector_voltage_M24C32_64( scheda_su_scheda_giu, Detector_canali_da_regolare_iniziali, \
535// Detector_Voltage_Bias[3 + scheda_su_scheda_giu] , 0 );
536
537}
538//! <!-- [fun_instr_Vbias_to_be_set_function] -->
539
540
541
542/*! \brief This function provides the guess values and the error about the detector trimmers. This function is static.
543
544\param[in] EPROM_detector is a struct with the necessary information about trimmer calibration retrievd from memory.
545\param[in] scheda_su_scheda_giu_ the selcted board
546\param[in] canali_da_regolare is a byte which has 1's in correspondaance of the channels whos bias has to be set
547\param[in] trimmer_da_scrivere is the trimmer, coarse, positive and negatice, of fine, positive and negative, to be worked on
548*\return No Parameters, except for the global variables such as the trimmers contents.
549
550*\snippetlineno .\Detector_Bias.c fun_misura_il_valore_trimmer_detector
551*/
552//! <!-- [fun_misura_il_valore_trimmer_detector] -->
553static void misura_il_valore_trimmer_detector(EPROM_detector__ *EPROM_detector, uint8_t scheda_su_scheda_giu_,\
554 uint8_t canali_da_regolare, uint8_t trimmer_da_scrivere){
555uint8_t canale,indice=0,iii;
556 int32_t delta, delto, EPROM_detector_slope_pos[6],EPROM_detector_slope_neg[6],ADC_misura_fatta_neg,ADC_misura_fatta_pos,risul_vof;
557 uint8_t misura_da_fare_pos[6], misura_da_fare_neg[6];
558 if(scheda_su_scheda_giu_) scheda_su_scheda_giu_=6;
559 for( canale=0;canale<6;canale++){
560 if( (canali_da_regolare >> canale) & 1){//Selezionaiamo solo i canali indicati
561 indice= canale + scheda_su_scheda_giu_;
562 misura_da_fare_pos[canale] = Detector_SAR_ini[indice].target_non_raggiunto_pos;
563 misura_da_fare_neg[canale] = Detector_SAR_ini[indice].target_non_raggiunto_neg;
564// Detector_SAR_ini[indice ].starting_value_pos =128; //Questo serve col fine se si \'e gi\'a in tolleranza
565// Detector_SAR_ini[indice ].starting_value_neg =128; //Questo serve col fine se si \'e gi\'a in tolleranza
566 if( trimmer_da_scrivere == Detector_trimmer_coarse_bias_pos){
567 EPROM_detector_slope_pos[canale] = EPROM_detector[canale].slope_coarse_positiva;
568 EPROM_detector_slope_neg[canale] = EPROM_detector[canale].slope_coarse_negativa;
569 }else{
570 EPROM_detector_slope_pos[canale] = EPROM_detector[canale].slope_fine_positiva;
571 EPROM_detector_slope_neg[canale] = EPROM_detector[canale].slope_fine_negativa ;
572 }
573 }
574 }
575
576if(trimmer_da_scrivere == Detector_trimmer_coarse_bias_pos){
577 for( canale=0;canale<6;canale++){
578 if( (canali_da_regolare >> canale) & 1){//Selezionaiamo solo i canali indicati
580 Detector_SAR_ini[canale + scheda_su_scheda_giu_].starting_value_pos, Detector_scrivi_il_trimmer );//Trimmer inizializzato a zero fine pos
582 Detector_SAR_ini[canale + scheda_su_scheda_giu_].starting_value_neg, Detector_scrivi_il_trimmer );//Trimmer inizializzato a zero fine neg
583 detector_scrittura_lettura_trimmer_bias( scheda_su_scheda_giu_, canale, Detector_trimmer_fine_bias_pos, 0x80, Detector_scrivi_il_trimmer );//Trimmer inizializzato a zero fine pos
584 detector_scrittura_lettura_trimmer_bias( scheda_su_scheda_giu_, canale, Detector_trimmer_fine_bias_neg, 0x80, Detector_scrivi_il_trimmer );//Trimmer inizializzato a zero fine neg
585 if ( flag_error_verified ){ ERROR_codifica_errore( scheda_su_scheda_giu_, error_address_PGA_DetectorTrimmer_down , DetectorTrimmer_error_0 + canale, 1);
586 canali_da_regolare=0;
587 }
588 }
589 }
590}
591if(trimmer_da_scrivere == Detector_trimmer_fine_bias_pos){
592 for( canale=0;canale<12;canale++){
593 Detector_SAR_ini[canale].starting_value_pos =128;
594 Detector_SAR_ini[canale].starting_value_neg =128;
595 }
596 }
597 Aspetta_tanti_ms(Detector_attesa_tra_le_misure);
598//Calcoliamo il valore target e lo impostiamo
599for( canale=0;canale<6;canale++){
600 if( (canali_da_regolare >> canale) & 1){//Selezionaiamo solo i canali indicati
601 if( Detector_externalADC_1_onboardADC_0){
602 //Misura con adc esterno
603 if(misura_da_fare_pos[canale]){
604 ADC_misura_fatta_pos = preamplifier_ADC_external_measured_node_function(scheda_su_scheda_giu_ ,\
606 Aspetta_tanti_ms(100);
607 if(misura_da_fare_neg[canale]){
608 ADC_misura_fatta_neg = preamplifier_ADC_external_measured_node_function(scheda_su_scheda_giu_ ,\
609 node_voltage_Analog_Mux_0_offset + canale *2 +1);
610 }
611 }else{
612 //Misuro con adc interno
613 if(misura_da_fare_pos[canale]){
614
615 ADC_misura_fatta_pos = ADC_misura_differenziale_con_media_generico(scheda_su_scheda_giu_,\
616 Detector_externalADC_1_onboardADC_0,node_voltage_Analog_Mux_0_offset + canale *2,0);
617 }
618 Aspetta_tanti_ms(100);
619 if(misura_da_fare_neg[canale]){
620
621 ADC_misura_fatta_neg = ADC_misura_differenziale_con_media_generico(scheda_su_scheda_giu_,\
622 Detector_externalADC_1_onboardADC_0,node_voltage_Analog_Mux_0_offset + canale *2+1,0);
623 }
624 }
625 if(misura_da_fare_pos[canale]){
626 delta = Detector_SAR_ini[canale + scheda_su_scheda_giu_].starting_value_pos + ( (Detector_bias_target[canale + scheda_su_scheda_giu_]\
627 - ADC_misura_fatta_pos) / EPROM_detector_slope_pos[canale ] ) ;
628 delta += ( (Detector_bias_target[canale + scheda_su_scheda_giu_] - ADC_misura_fatta_pos) %\
629 EPROM_detector_slope_pos[canale ] )\
630 / (EPROM_detector_slope_pos[canale]>>1);
631 if (delta <0) delta=0;
632 if (delta >0xff) delta=0xff;
633 Detector_SAR_ini[canale + scheda_su_scheda_giu_].starting_value_pos = delta;
634 detector_scrittura_lettura_trimmer_bias( scheda_su_scheda_giu_, canale, trimmer_da_scrivere, \
635 Detector_SAR_ini[canale+scheda_su_scheda_giu_ ].starting_value_pos, Detector_scrivi_il_trimmer );//Trimmer inizializzato a zero coarse pos
636 }
637
638 if(misura_da_fare_neg[canale]){
639 delta =Detector_SAR_ini[canale+scheda_su_scheda_giu_ ].starting_value_neg + ( (-Detector_bias_target[canale + scheda_su_scheda_giu_] -\
640 ADC_misura_fatta_neg) / EPROM_detector_slope_neg[canale ] ) ;
641 delta += ( (-Detector_bias_target[canale + scheda_su_scheda_giu_] - ADC_misura_fatta_neg) %\
642 EPROM_detector_slope_neg[canale + scheda_su_scheda_giu_] )\
643 / (EPROM_detector_slope_neg[canale + scheda_su_scheda_giu_] >> 1);
644 if (delta <0) delta=0;
645 if (delta >0xff) delta=0xff;
646 Detector_SAR_ini[canale+scheda_su_scheda_giu_ ].starting_value_neg = delta;
647 detector_scrittura_lettura_trimmer_bias( scheda_su_scheda_giu_, canale, trimmer_da_scrivere +1, \
648 Detector_SAR_ini[canale +scheda_su_scheda_giu_].starting_value_neg, Detector_scrivi_il_trimmer );//Trimmer inizializzato a zero coarse neg
649 }
650 }
651}
652Aspetta_tanti_ms(Detector_attesa_tra_le_misure);
653//qui invece determiniamo l'errore per capire che SAR applicare
654for( canale=0;canale<6;canale++){
655 if( (canali_da_regolare >> canale) & 1){//Selezionaiamo solo i canali indicati
656 if( Detector_externalADC_1_onboardADC_0){
657 //Misura con adc esterno
658 if(misura_da_fare_pos[canale]){
659 Aspetta_tanti_ms(100);
660 ADC_misura_fatta_pos = preamplifier_ADC_external_measured_node_function(scheda_su_scheda_giu_ ,\
662 }
663 Aspetta_tanti_ms(100);
664 if(misura_da_fare_neg[canale]){
665 ADC_misura_fatta_neg = preamplifier_ADC_external_measured_node_function(scheda_su_scheda_giu_ ,\
666 node_voltage_Analog_Mux_0_offset + canale *2 +1);
667 }
668 }else{
669 //Misuro con adc interno
670 if(misura_da_fare_pos[canale]){
671
672 ADC_misura_fatta_pos = ADC_misura_differenziale_con_media_generico(scheda_su_scheda_giu_,\
673 Detector_externalADC_1_onboardADC_0,node_voltage_Analog_Mux_0_offset + canale *2,0);
674 }
675 Aspetta_tanti_ms(100);
676 if(misura_da_fare_neg[canale]){
677
678 ADC_misura_fatta_neg = ADC_misura_differenziale_con_media_generico(scheda_su_scheda_giu_,\
679 Detector_externalADC_1_onboardADC_0,node_voltage_Analog_Mux_0_offset + canale *2+1,0);
680 }
681 }
682 if(misura_da_fare_pos[canale]){//Si determina il minimo valore di SAR
683 delta = ( (Detector_bias_target[canale + scheda_su_scheda_giu_] - ADC_misura_fatta_pos) / EPROM_detector_slope_pos[canale ] ) ;
684 delta += ( (Detector_bias_target[canale + scheda_su_scheda_giu_] - ADC_misura_fatta_pos) % EPROM_detector_slope_pos[canale ] )\
685 /(EPROM_detector_slope_pos[canale]>>1);
686 delto= delta;
687 if( delto < 0) delto=-1*delto;
688 if (delto <=1){
689 Detector_SAR_ini[canale +scheda_su_scheda_giu_].starting_exp_value_pos=1;
690 }else if (delto <=2){
691 Detector_SAR_ini[canale +scheda_su_scheda_giu_].starting_exp_value_pos=2;
692 }else if( delto<=4){
693 Detector_SAR_ini[canale +scheda_su_scheda_giu_].starting_exp_value_pos=3;
694 }else{
695 Detector_SAR_ini[canale +scheda_su_scheda_giu_].starting_exp_value_pos=7;
696 }
697// delta += Detector_SAR_ini[canale +scheda_su_scheda_giu_].starting_value_pos;
698 if(delta==0) delta =1;
699 delta = Detector_SAR_ini[canale +scheda_su_scheda_giu_].starting_value_pos - delto;
700 if(delta<0) Detector_SAR_ini[canale +scheda_su_scheda_giu_].starting_value_pos=0;
701 if( delta > 255) Detector_SAR_ini[canale +scheda_su_scheda_giu_].starting_value_pos=0xff;
702 Detector_SAR_ini[canale +scheda_su_scheda_giu_].starting_value_pos =delta;
703// for(iii=0;iii<Detector_SAR_ini[canale +scheda_su_scheda_giu_].starting_exp_value_pos;iii++){
704// Detector_SAR_ini[canale +scheda_su_scheda_giu_].starting_value_pos &= ~(1<<iii); //tolgo
705// }
706 }
707
708if(misura_da_fare_neg[canale]){
709 delta =( (-Detector_bias_target[canale + scheda_su_scheda_giu_] - ADC_misura_fatta_neg) / EPROM_detector_slope_neg[canale] ) ;
710 delta +=( (-Detector_bias_target[canale + scheda_su_scheda_giu_] - ADC_misura_fatta_neg) % EPROM_detector_slope_neg[canale] )\
711 / (EPROM_detector_slope_neg[canale]>>1);
712 delto= delta;
713 if( delto < 0) delto=-1*delto;
714 if (delto <=1){
715 Detector_SAR_ini[canale +scheda_su_scheda_giu_].starting_exp_value_neg=1;
716 }else if (delto <=2){
717 Detector_SAR_ini[canale +scheda_su_scheda_giu_].starting_exp_value_neg=2;
718 }else if( delto<=4){
719 Detector_SAR_ini[canale +scheda_su_scheda_giu_].starting_exp_value_neg=3;
720 }else{
721 Detector_SAR_ini[canale +scheda_su_scheda_giu_].starting_exp_value_neg=7;
722 }
723 if(delta==0) delta=1;
724 delta = Detector_SAR_ini[canale +scheda_su_scheda_giu_].starting_value_neg - delto;
725 if(delta<0) Detector_SAR_ini[canale +scheda_su_scheda_giu_].starting_value_neg=0;
726 if( delta > 255) Detector_SAR_ini[canale +scheda_su_scheda_giu_].starting_value_neg=0xff;
727 Detector_SAR_ini[canale +scheda_su_scheda_giu_].starting_value_neg = delta;
728// for(iii=0;iii<Detector_SAR_ini[canale +scheda_su_scheda_giu_].starting_exp_value_neg;iii++){
729// Detector_SAR_ini[canale +scheda_su_scheda_giu_].starting_value_neg &= ~(1<<iii); //tolgo
730// }
731 }
732 }
733}
734
735}
736//! <!-- [fun_misura_il_valore_trimmer_detector] -->
737
738
739/*! \brief This function provide the output offset with the fast SAR method: only a few LS bits are left for this.
740
741\param[in] EPROM_detector_sar is a struct with the necessary information about trimmer calibration retrievd from memory.
742\param[in] scheda_su_scheda_giu_ the selected board
743*\return No Parameters, except ffor the global variables such as the trimmers contents.
744
745*\snippetlineno .\Detector_Bias.c fun_Detector_aggiusta_offset_SAR
746*/
747//! <!-- [fun_Detector_aggiusta_offset_SAR] -->
748static void Detector_aggiusta_offset_SAR(EPROM_detector__ *EPROM_detector_sar, uint8_t scheda_su_scheda_giu_){
749 uint8_t canale, non_misuro;
750 uint8_t indice,iii;
751 int32_t variabile_ponte,ADC_misura_fatta_pos,ADC_misura_fatta_neg,mezzo_bit;
752 uint8_t i_2_trimmer[]={Detector_trimmer_coarse_bias_pos , Detector_trimmer_fine_bias_pos}, indice_trimmer,scalata,confronto;
753 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
754 int32_t risul_vof;
755
756
757 if(scheda_su_scheda_giu_>=1) scheda_su_scheda_giu_=6;
758 misura_il_valore_trimmer_detector( EPROM_detector_sar , scheda_su_scheda_giu_, Detector_canali_da_regolare, Detector_trimmer_coarse_bias_pos);
759 mezzo_bit=0;
760 iii=0;
761 for (canale=0;canale<6;canale++){
762 if( (Detector_canali_da_regolare >> canale ) & 1) {
763 // si usa il meno perch\'e la pendenza \'e negativa, mentre vogliamo un valore positivo
764 iii ++;
765 mezzo_bit = mezzo_bit - EPROM_detector_sar[canale].slope_coarse_positiva - EPROM_detector_sar[canale].slope_coarse_negativa;
766 //Qui invece inizializziamo i trimmer MS
768 Detector_SAR_ini[canale +scheda_su_scheda_giu_ ].starting_value_pos , Detector_scrivi_il_trimmer );//Trimmer inizializzato a zero coarse pos
770 Detector_SAR_ini[canale +scheda_su_scheda_giu_ ].starting_value_neg, Detector_scrivi_il_trimmer );//Trimmer inizializzato a zero coarse neg
771 if ( flag_error_verified ){ ERROR_codifica_errore( scheda_su_scheda_giu_, error_address_PGA_DetectorTrimmer_down , DetectorTrimmer_error_0 + canale, 1);
772 Detector_canali_da_regolare=0;
773 }
774 }
775 }
776 mezzo_bit = mezzo_bit / (4*iii) ; // mezzo_bit medio, il / 4 \'e /2 perch\'e ad ogni iii abbiamo 2 somme e /2 perch\'e vogliamo mezzo bit
777// if( Detector_error_voltage > mezzo_bit) mezzo_bit = Detector_error_voltage;
778
779//FINE Inizializzazione dei trimmer che servono alla regolazione
780
781// Esploriamo i 2 trimmer, a partie dal+ significativo, cio\'e il SAR veroe e proprio
782 for(indice_trimmer=0; indice_trimmer<2;indice_trimmer++){
783
784 if( i_2_trimmer[indice_trimmer] == Detector_trimmer_fine_bias_pos) {
785 for(canale=0;canale<6;canale++){//Al secondo giro fine si pu\'o ancora migliorare, di principio
786 if( (Detector_canali_da_regolare >> canale ) & 1){
787 Detector_SAR_ini[canale + scheda_su_scheda_giu_].target_non_raggiunto_neg=true;
788 Detector_SAR_ini[canale +scheda_su_scheda_giu_].target_non_raggiunto_pos=true;
789 }
790 }
791 misura_il_valore_trimmer_detector( EPROM_detector_sar, scheda_su_scheda_giu_, Detector_canali_da_regolare, Detector_trimmer_fine_bias_pos);
792 mezzo_bit=0;
793 iii=0;
794 for (canale=0;canale<6;canale++){
795 if( (Detector_canali_da_regolare >> canale ) & 1) {
796 indice= canale + scheda_su_scheda_giu_;
797 //determiniamo il mezzo bit per il LS
798 mezzo_bit = mezzo_bit + EPROM_detector_sar[canale].slope_fine_negativa + EPROM_detector_sar[canale].slope_fine_positiva;
799 iii++;
800 //Condizioni iniziali per i trimmer
801 //Qui invece inizializziamo i trimmer MS
803 Detector_SAR_ini[indice ].starting_value_pos, Detector_scrivi_il_trimmer );//Trimmer inizializzato a zero fine pos
805 Detector_SAR_ini[indice ].starting_value_neg, Detector_scrivi_il_trimmer );//Trimmer inizializzato a zero fine neg
806 }
807 }
808 mezzo_bit = mezzo_bit / (4*iii) ; //Determiniamo il nuovo mezzo bit medio
809 if( Detector_error_voltage > mezzo_bit) mezzo_bit = Detector_error_voltage;
810 }
811
812// for (canale=0;canale<6;canale++){
813// if( (Detector_canali_da_regolare >> canale ) & 1) {
814//
815// }
816// }
817 for(scalata=0; scalata<8; scalata++){
818 confronto= 1 << (7-scalata); //Impostiamo il valore di prova da aggiungere al trimmer
819 non_misuro =0;
820 for(canale=0; canale<6;canale++){ // Scansoniamo tutti i possibili canali sulla scheda selezionata
821 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
822 if( (Detector_canali_da_regolare >> canale) & 1){//Selezionaiamo solo i canali indicati
823 if( ((Detector_SAR_ini[indice].starting_exp_value_pos >= (7-scalata))) &&\
824 Detector_SAR_ini[indice].target_non_raggiunto_pos){ //Job starts just with the minimal cheks, always for the lower 8 bits
825 contenuto_trimmer_detector[indice][i_2_trimmer[indice_trimmer]] += confronto;
826 detector_scrittura_lettura_trimmer_bias( scheda_su_scheda_giu_, canale, i_2_trimmer[indice_trimmer], \
827 contenuto_trimmer_detector[indice][i_2_trimmer[indice_trimmer]], Detector_scrivi_il_trimmer );
828 non_misuro=1;
829 }
830 if( ((Detector_SAR_ini[indice].starting_exp_value_neg >= (7-scalata))) && \
831 Detector_SAR_ini[indice].target_non_raggiunto_neg){ //Job starts just with the minimal cheks, always for the lower 8 bits
832 contenuto_trimmer_detector[indice][i_2_trimmer[indice_trimmer]+1] |= confronto;
833 detector_scrittura_lettura_trimmer_bias( scheda_su_scheda_giu_, canale, i_2_trimmer[indice_trimmer]+1, \
834 contenuto_trimmer_detector[indice][i_2_trimmer[indice_trimmer]+1], Detector_scrivi_il_trimmer );
835 non_misuro=1;
836 }
837 }
838 }
839 if( non_misuro){ //Inutile perdere tempo se non c'e' niente di selezionato da misurare
840 Aspetta_tanti_ms( Detector_attesa_tra_le_misure );
841
842 for(canale=0; canale<6;canale++){ // Scansoniamo tutti i possibili canali sulla scheda selezionata
843 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
844 if( (Detector_canali_da_regolare >> canale) & 1){//Selezionaiamo solo i canali indicati
845 //Misuro con ADC
846// if( Detector_externalADC_1_onboardADC_0){
847// //Misura con adc esterno
848// if( (Detector_SAR_ini[indice].target_non_raggiunto_pos) && \
849// (Detector_SAR_ini[indice].starting_exp_value_pos >= (7-scalata))){
850// ADC_misura_fatta_pos = preamplifier_ADC_external_measured_node_function(scheda_su_scheda_giu_, \
851// node_voltage_Analog_Mux_0_offset + canale *2 );}
852// Aspetta_tanti_ms(100);
853// if( (Detector_SAR_ini[indice].target_non_raggiunto_neg) && \
854// (Detector_SAR_ini[indice].starting_exp_value_neg >= (7-scalata))){
855// ADC_misura_fatta_neg = preamplifier_ADC_external_measured_node_function(scheda_su_scheda_giu_, \
856// node_voltage_Analog_Mux_0_offset + canale *2+1 ); }
857// Aspetta_tanti_ms(100);
858// if( flag_error_verified){
859// ERROR_codifica_errore(scheda_su_scheda_giu_, error_address_reg_ADC0 , ADC_external_fails , 1);
860// Detector_canali_da_regolare=0;
861// }
862// }else{
863 {
864 //Misuro con adc interno
865 if( (Detector_SAR_ini[indice].target_non_raggiunto_pos) && \
866 (Detector_SAR_ini[indice].starting_exp_value_pos >= (7-scalata))){
867// ADC_misura_fatta_pos = ADC_lettura(scheda_su_scheda_giu_, node_voltage_Analog_Mux_0_offset + canale *2, 2 );
868// risul_vof= (ADC_lettura_24bit( node_voltage_Analog_Mux_0_offset + canale *2,scheda_su_scheda_giu_, 2) ) ;
869// ADC_misura_fatta_pos = ADC_compensazione_al_nodo(node_voltage_Analog_Mux_0_offset + canale *2,ADC_misura_fatta_pos, risul_vof);
870
871// ADC_misura_fatta_pos = ADC_misura_differenziale_single_ended(scheda_su_scheda_giu_, node_voltage_Analog_Mux_0_offset + canale *2,0);
872
873 ADC_misura_fatta_pos = ADC_misura_differenziale_con_media_generico(scheda_su_scheda_giu_,Detector_externalADC_1_onboardADC_0,node_voltage_Analog_Mux_0_offset + canale *2,0);
874 }
875 Aspetta_tanti_ms(100);
876 if( (Detector_SAR_ini[indice].target_non_raggiunto_neg) && \
877 (Detector_SAR_ini[indice].starting_exp_value_neg >= (7-scalata))){
878// ADC_misura_fatta_neg = ADC_lettura(scheda_su_scheda_giu_, node_voltage_Analog_Mux_0_offset + canale *2+1, 2 );
879// risul_vof= (ADC_lettura_24bit( node_voltage_Analog_Mux_0_offset + canale *2+1,scheda_su_scheda_giu_, 2) ) ;
880// ADC_misura_fatta_neg = ADC_compensazione_al_nodo(node_voltage_Analog_Mux_0_offset + canale *2+1, ADC_misura_fatta_neg, risul_vof);
881
882// ADC_misura_fatta_neg= ADC_misura_differenziale_single_ended(scheda_su_scheda_giu_, node_voltage_Analog_Mux_0_offset + canale *2+1,0);
883 ADC_misura_fatta_neg= ADC_misura_differenziale_con_media_generico(scheda_su_scheda_giu_,Detector_externalADC_1_onboardADC_0,node_voltage_Analog_Mux_0_offset + canale *2+1,0);
884 }
885 Aspetta_tanti_ms(100);
886 if( flag_error_verified){ ERROR_codifica_errore(scheda_su_scheda_giu_, error_address_reg_ADC0 , ADC_internal_General_fails , 1);
887 Detector_canali_da_regolare=0;
888 }
889 }
890//Inizio Test sulla parte positiva *****************************************************************************************
891 if( (Detector_SAR_ini[indice].target_non_raggiunto_pos) && (Detector_SAR_ini[indice].starting_exp_value_pos >= (7-scalata))){
892 if( ( ADC_misura_fatta_pos - Detector_bias_target[indice] ) < ( - mezzo_bit) ){
893 //siamo fuori tolleranza
894 if(i_2_trimmer[indice_trimmer] == Detector_trimmer_coarse_bias_pos){//Gain opposto per coarse rispetto a fine
895 contenuto_trimmer_detector[indice][ i_2_trimmer[indice_trimmer]] -= confronto;
896 detector_scrittura_lettura_trimmer_bias( scheda_su_scheda_giu_, canale, i_2_trimmer[indice_trimmer], \
897 contenuto_trimmer_detector[indice][i_2_trimmer[indice_trimmer]], Detector_scrivi_il_trimmer );
898 }
899 }else if ( (( ADC_misura_fatta_pos - Detector_bias_target[indice] ) <= 0 ) && \
900 (( ADC_misura_fatta_pos - Detector_bias_target[indice] ) >= -Detector_error_voltage ) ){
901 //Siamo in tolleranza e dobbiamo fermarci
902 Detector_SAR_ini[indice].target_non_raggiunto_pos =false;
903 }else if ( ( ADC_misura_fatta_pos - Detector_bias_target[indice] ) > ( mezzo_bit)){
904 //siamo fuori tolleranza
905 //Cerchiamo di stare entro mezzo bit
906 if( (confronto ==1) && (i_2_trimmer[indice_trimmer] == Detector_trimmer_coarse_bias_pos)){
907 contenuto_trimmer_detector[indice][i_2_trimmer[indice_trimmer]] ++;
908 detector_scrittura_lettura_trimmer_bias( scheda_su_scheda_giu_, canale, i_2_trimmer[indice_trimmer], \
909 contenuto_trimmer_detector[indice][i_2_trimmer[indice_trimmer]], Detector_scrivi_il_trimmer );
910 }
911// Detector_misura_fatta_old[indice]= ADC_misura_fatta; //
912 if(i_2_trimmer[indice_trimmer] == Detector_trimmer_fine_bias_pos){//Gain opposto per coarse rispetto a fine
913 contenuto_trimmer_detector[indice][ i_2_trimmer[indice_trimmer]] -= confronto;
914 detector_scrittura_lettura_trimmer_bias( scheda_su_scheda_giu_, canale, i_2_trimmer[indice_trimmer], \
915 contenuto_trimmer_detector[indice][i_2_trimmer[indice_trimmer]], Detector_scrivi_il_trimmer );
916 }
917 }else if ( (( ADC_misura_fatta_pos - Detector_bias_target[indice] ) >=0) &&\
918 (( ADC_misura_fatta_pos - Detector_bias_target[indice] ) <= Detector_error_voltage) ){
919 //siamo in tolleranza
920 Detector_SAR_ini[indice].target_non_raggiunto_pos =false;
921 }
922 }
923//Fine Test sulla parte positiva *****************************************************************************************
924
925//Inizio Test sulla parte negativa *****************************************************************************************
926 if( (Detector_SAR_ini[indice].target_non_raggiunto_neg) && \
927 (Detector_SAR_ini[indice].starting_exp_value_neg >= (7-scalata))){
928 if( ( -ADC_misura_fatta_neg - Detector_bias_target[indice] ) < \
929 ( - mezzo_bit) ){
930 //siamo fuori tolleranza
931 if(i_2_trimmer[indice_trimmer] == Detector_trimmer_fine_bias_pos){//Gain opposto per coarse rispetto a fine
932 contenuto_trimmer_detector[indice][ i_2_trimmer[indice_trimmer]+1] -= confronto;
933 detector_scrittura_lettura_trimmer_bias( scheda_su_scheda_giu_, canale, i_2_trimmer[indice_trimmer]+1, \
934 contenuto_trimmer_detector[indice][i_2_trimmer[indice_trimmer]+1], Detector_scrivi_il_trimmer );
935 }
936 //Crechiamo di stare entro mezzo bit
937 if( (confronto ==1) && (i_2_trimmer[indice_trimmer ] == Detector_trimmer_coarse_bias_pos)){
938 contenuto_trimmer_detector[indice][i_2_trimmer[indice_trimmer]+1] ++;
939 detector_scrittura_lettura_trimmer_bias( scheda_su_scheda_giu_, canale, i_2_trimmer[indice_trimmer]+1, \
940 contenuto_trimmer_detector[indice][i_2_trimmer[indice_trimmer]+1], Detector_scrivi_il_trimmer );
941 }
942
943 }else if ( (( -ADC_misura_fatta_neg - Detector_bias_target[indice] ) <=0) && \
944 (( -ADC_misura_fatta_neg - Detector_bias_target[indice] ) >= -Detector_error_voltage) ){
945 //Siamo in tolleranza e dobbiamo fermarci
946 Detector_SAR_ini[indice].target_non_raggiunto_neg =false;
947 }else if ( ( -ADC_misura_fatta_neg - Detector_bias_target[indice] ) >\
948 ( mezzo_bit)){
949 //siamo fuori tolleranza
950 if(i_2_trimmer[indice_trimmer] == Detector_trimmer_coarse_bias_pos){//Gain opposto per coarse rispetto a fine
951 contenuto_trimmer_detector[indice][ i_2_trimmer[indice_trimmer]+1] -= confronto;
952 detector_scrittura_lettura_trimmer_bias( scheda_su_scheda_giu_, canale, i_2_trimmer[indice_trimmer]+1, \
953 contenuto_trimmer_detector[indice][i_2_trimmer[indice_trimmer]+1], Detector_scrivi_il_trimmer );
954 }
955 }else if ( (( -ADC_misura_fatta_neg - Detector_bias_target[indice] ) >= 0 ) && \
956 (( -ADC_misura_fatta_neg - Detector_bias_target[indice] ) <= Detector_error_voltage ) ){
957 //siamo in tolleranza
958 Detector_SAR_ini[indice].target_non_raggiunto_neg =false;
959 }
960 }
961//Fine Test sulla parte negativa *****************************************************************************************
962 if( (Detector_SAR_ini[indice].target_non_raggiunto_neg || Detector_SAR_ini[indice].target_non_raggiunto_pos)==false){
963 //sia parte positiva che negativa sono ok
964 Detector_canali_da_regolare -= 1 << canale ;
965 }
966 }
967 }
968 }//non misuro
969 }
970 }
971}
972//! <!-- [fun_Detector_aggiusta_offset_SAR] -->
973
974/*! \brief This is an instruction via CAN bus to read/write the detector trimmers. It calls the
975detector_scrittura_lettura_trimmer_bias(). A copy of the trimmers values is in the array
976#contenuto_trimmer_detector[][].
977
978*\return No Parameters, the actual result is sent to the CAN bus output throught \ref tx_data.
979
980*\snippetlineno Detector_Bias.c fun_instr_detector_scrittura_lettura_trimmer_bias_function
981*/
982//! <!-- [fun_instr_detector_scrittura_lettura_trimmer_bias_function] -->
985 uint8_t contenuto_trimmer= vettore_istruzioni[byte_istr_dati_0];
986 uint8_t trimmer_da_scrivere= vettore_istruzioni[istruzione_byte_3];
987 uint8_t scrivere_leggere= (canale >> 6) & 1;
988 uint8_t scheda_su_giu= ((canale >> 7) & 1)*6;
989 ERROR_codifica_errore(0,0,0,0); //Reset_ch0 errori
990
991 for ( canale_=0; canale_ <6; canale_++){
992 if ( (canale >> canale_) & 1){
993 detector_scrittura_lettura_trimmer_bias( scheda_su_giu, canale_, trimmer_da_scrivere, \
994 contenuto_trimmer, scrivere_leggere );
995 tx_data[byte_istr_dati_0]= contenuto_trimmer_detector[canale_ + scheda_su_giu][trimmer_da_scrivere] ;
996 break ;
997 }
998 }
1000}
1001//! <!-- [fun_instr_detector_scrittura_lettura_trimmer_bias_function] -->
1002
1003/*! \brief Function to set the relais for detector bias
1004
1005*\return No Parameters, the actual result is sent to the CAN bus output throught \ref tx_data.
1006
1007*\snippetlineno Detector_Bias.c fun_instr_Relays_driver_set_reset_channel_function
1008*/
1009//! <!-- [fun_instr_Relays_driver_set_reset_channel_function] -->
1011 uint8_t canale_, canale= vettore_istruzioni[istruzione_byte_4_e_scelta_canale];
1012 uint8_t switch_relay= vettore_istruzioni[istruzione_byte_3];
1013 uint8_t scheda_su_giu= (canale >> 7) & 1;
1014 ERROR_codifica_errore(0,0,0,0); //Reset_ch0 errori
1015 int32_t ADC_misura_fatta;
1016 bool si_commuta;
1017
1018 for ( canale_=0; canale_ <6; canale_++){
1019 if( (canale >> canale_) & 1){
1020 if ( (switch_relay & Detector_bias_invertito) ) { //(switch_relay >> select_external_bias)
1021 //Then external bias
1022 Relays_driver_set_reset_channel( scheda_su_giu, canale_ , Detector_bias_invertito);
1023 }
1024 if ((switch_relay &Detector_bias_diretto) ){
1025 //Direct bias
1026 Relays_driver_set_reset_channel( scheda_su_giu, canale_ , Detector_bias_diretto);
1027 }
1028 if ((switch_relay & Detector_large_RLOAD) ) {
1029 //Then bias unchanged
1030 Relays_driver_set_reset_channel( scheda_su_giu, canale_ , Detector_large_RLOAD );
1031 }
1032 if ((switch_relay & Detector_small_RLOAD)){
1033 Relays_driver_set_reset_channel( scheda_su_giu, canale_ , Detector_small_RLOAD);
1034 }
1035 if ((switch_relay & Detector_prea_to_GND) ) {
1036 //Then detector large RLOAD
1037 Relays_driver_set_reset_channel( scheda_su_giu, canale_ , Detector_prea_to_GND);
1038 }
1039 if ((switch_relay & Detector_prea_to_det)){
1040 Relays_driver_set_reset_channel( scheda_su_giu, canale_ , Detector_prea_to_det);
1041 }
1042 if ((switch_relay & Detector_external_bias) ) {
1043 //Then preamplifier to detector
1044 si_commuta=Detector_verifica_Vbias( scheda_su_giu, si_commuta);
1045 if (si_commuta){ //Vbias is within the limits
1047 }
1048 }
1049 if ((switch_relay & Detector_internal_bias)){
1050 si_commuta=Detector_verifica_Vbias( scheda_su_giu, si_commuta);
1051 if (si_commuta){ //Vbias is within the limits
1052 Relays_driver_set_reset_channel( scheda_su_giu, canale_ , Detector_internal_bias);
1053 }
1054 }
1055 }
1056}
1057 if( flag_error_verified){
1058
1059 }
1061}
1062//! <!-- [fun_instr_Relays_driver_set_reset_channel_function] -->
1063
1064/*! \brief Function to verify if the Vbias voltage is within the limit to be swtitched
1065\param[in] scheda_su_giu : which board
1066\param[in] si_commuta : if true Vbias can be switched
1067
1068*\return No Parameters, the actual result is sent to the CAN bus output throught \ref tx_data.
1069
1070*\snippetlineno Detector_Bias.c fun_instr_Relays_driver_set_reset_channel_function
1071*/
1072//! <!-- [fun_instr_Relays_driver_set_reset_channel_function] -->
1073static bool Detector_verifica_Vbias(uint8_t scheda_su_giu, bool si_commuta){
1074
1078 si_commuta= ADC_misura_fatta > Detector_min_voltage_for_switch ;
1080 si_commuta &= ADC_misura_fatta < Detector_max_voltage_for_switch ;
1083 si_commuta &= ADC_misura_fatta < -Detector_min_voltage_for_switch ;
1085 si_commuta &= ADC_misura_fatta > -Detector_max_voltage_for_switch;
1087 return si_commuta;
1088}
1089
1090
1091//fine cross
1092
1093
1094
1095int Detector_Voltage_Bias[]={0,0}; //!< The bias voltage applied to the detectors
1096
1097
1098struct detector_trimmer_type /*struct detector_trimmer_type{
1099 int16_t coarse_pos;
1100 int16_t fine_pos ;
1101 int16_t coarse_neg;
1102 int16_t fine_neg;
1103}*/ detector_Trimmer_bias[2] ;
1104
1105
1106
1107int trimmer_bias_coarse_step_actual[]={trimmer_bias_coarse_step,trimmer_bias_coarse_step};
1108int trimmer_bias_fine_step_actual[]={trimmer_bias_fine_step,trimmer_bias_fine_step};
1109
1110/*! \brief The detector bias will be set at the value passed from the CAN if,
1111after this setting, it is launched instruction_Detector_bias().
1112
1113The first 4 bytes of the CAN bus message are the 2 voltage setting in mV.
1114*\return No Parameters, the actual result is sent to the CAN bus output throught \ref tx_data.
1115
1116*\snippetlineno Detector_Bias.c fun_instruction_Vbias_target
1117*/
1118//! <!-- [fun_instruction_Vbias_target] -->
1122 }
1125 }
1127 tx_data[byte_istr_dati_1]= ((Detector_Voltage_Bias[0]/1000)>>8) & 0xFF;
1129 tx_data[byte_istr_dati_3]= ((Detector_Voltage_Bias[1]/1000)>>8) & 0xFF;
1130}
1131//! <!-- [fun_instruction_Vbias_target] -->
1132
1133
1134/*! \brief The detector bias is set at the value passed from the CAN
1135
1136
1137This instruction needs to know which channel to set
1138at byte istruzione_byte_4_e_scelta_canale and the the setting value, in mV,
1139byte_istr_dati_0 and byte_istr_dati_1 of the CAN message.
1140*\return No Parameters, the actual result is sent to the CAN bus output throught \ref tx_data.
1141
1142*\snippetlineno Detector_Bias.c fun_instruction_Detector_bias
1143*/
1144//! <!-- [fun_instruction_Detector_bias] -->
1146{
1147 //Per la positiva
1148// long int vout_pos, vout_neg;
1149 #define offset_adjusted_at_the_pre_bias_set 0 /*Byte_1*/
1150 #define bias_adjustement_start_from_half_scale 1 /*Byte_1*/
1151 bool errore_pos[2]={true,true}, errore_neg[2]={true,true},errore_generale=true;
1152// int valore_positivo,valore_negativo, tolleranza=((vettore_istruzioni[istruzione_byte_3]*1000)/bias_reading_attenuation)/2;//diviso 2 perch\'e \'e sulle 2 tensioni che si determina l'errore
1153 int valore_positivo,valore_negativo, tolleranza=((vettore_istruzioni[istruzione_byte_3]*1000))/2;//diviso 2 perch\'e \'e sulle 2 tensioni che si determina l'errore
1154 unsigned int attesa;
1155 long int discrepanza;
1156 char canale=0, troppe_misure=0,ii;
1157// int tensione_target_attenuata[]={(Detector_Voltage_Bias[0]>>1)/bias_reading_attenuation, (Detector_Voltage_Bias[1]>>1)/bias_reading_attenuation};
1158 int tensione_target_attenuata[]={(Detector_Voltage_Bias[0]>>1), (Detector_Voltage_Bias[1]>>1)};
1159// vout_pos = ( vettore_istruzioni[byte_istr_dati_0] & 0xFF+ ((vettore_istruzioni[byte_istr_dati_1] & 0xFF) << 8) ); // Viene letto il valore scelto da remoto
1160// vout_pos = ((vout_pos>>1) * 1000)/ bias_reading_attenuation ;
1161 int offset;
1162 char nodo_di_misura_1[]={ADC_ADC_PGA_neg_out_ch0, ADC_ADC_PGA_neg_out_ch1};
1163 char nodo_di_misura_2[]={ADC_ADC_PGA_pos_out_ch0, ADC_ADC_PGA_pos_out_ch1};
1164// int coarse_trimmer_step = coarse_Trimmer_offset_step * guadagno_minimo_PGA ; //*********************************************
1165// int fine_trimmer_step = fine_Trimmer_offset_step * guadagno_minimo_PGA ; //*********************************************
1166
1167// vout_neg=-vout_pos;
1168// int16_t Valori_per_i_trimmer_pos[2],Valori_per_i_trimmer_neg[2]; // Qui verranno inseriti i valori per i trimmer
1169 struct canale_ADC_type{
1170 unsigned char att_pos;
1171 unsigned char att_neg;
1172 }canale_ADC[]={ADC_Misura_bias_10_att_ch0_p,ADC_Misura_bias_10_att_ch0_n,ADC_Misura_bias_10_att_ch1_p,ADC_Misura_bias_10_att_ch1_n} ;
1173
1174 //PGA a 1 per evitare sconquassi
1175 if( vettore_istruzioni[istruzione_byte_1] >> offset_adjusted_at_the_pre_bias_set) {
1176 //Vogliamo lacsiare l'offset inalterato
1177 for( canale=0;canale<2;canale++){
1178 if( ((vettore_istruzioni[istruzione_byte_4_e_scelta_canale]&3) >> canale) & 1){
1179// offset=lettura_ADC( nodo_di_misura_1[canale]) - lettura_ADC( nodo_di_misura_2[canale]); //Il <<1 \'e per renderlo differenziale
1180 valore_target_per_offset[canale]=correzione_misura_ADC(coeffcienti_misura_ADC_nodi[nodo_di_misura_1[canale]], offset);
1181 //Voglim mantenere la tenione allo stesso livello se \'e in scala, altrimenti aggiustiamo a zero
1182 if( (valore_target_per_offset[canale] >= saturazione_positiva) || ( valore_target_per_offset[canale] <= saturazione_negativa ) ) {
1183 valore_target_per_offset[canale]=0;
1184 }
1185 //L'offset all'uscita del pga che vorremo avere a guadagno 1
1186 valore_target_per_offset[canale] = ( valore_target_per_offset[canale] * (int)guadagno_minimo_PGA ) / (int)PGA_Gain_V_su_V[canale] ;
1187 }
1188 }
1189 }
1190 char PGA_Gain_V_su_V_old[]={PGA_Gain_V_su_V[0], PGA_Gain_V_su_V[1]};
1191 PGA_GAIN_set(3,1);
1192
1193// if ( vettore_istruzioni[istruzione_byte_4_e_scelta_canale]) canale=1;
1194
1195
1197 attesa =1000;
1198 }else {
1200 }
1201 for(ii =0; ii<2;ii++){
1202 if( ( ((vettore_istruzioni[istruzione_byte_4_e_scelta_canale]) >> ii) & 1) == 0) {
1203 errore_pos[ii]=false;
1204 errore_neg[ii]=false;
1205 }
1206 }
1207
1208 if( (vettore_istruzioni[istruzione_byte_1] >> bias_adjustement_start_from_half_scale) ){
1209 for(canale =0; canale<2;canale++){
1210 if ( errore_pos[canale] ){
1211 Imposta_canale_del_trimmer_ennesimo_al_valore_I2CB (canale, trimmer_bias_coarse_pos, 0x80); // Viene fatta una misura con entrambi i trimmer a met\'a scala per ricavare l'offset
1212 detector_Trimmer_bias[canale].coarse_pos=0x80;
1213 detector_Trimmer_bias[canale].fine_pos=0x80;
1214 Imposta_canale_del_trimmer_ennesimo_al_valore_I2CB (canale, trimmer_bias_fine_pos, 0x80);
1215 Imposta_canale_del_trimmer_ennesimo_al_valore_I2CB (canale, trimmer_bias_coarse_neg, 0x80); // Viene fatta una misura con entrambi i trimmer a met\'a scala per ricavare l'offset
1216 detector_Trimmer_bias[canale].coarse_neg=0x80;
1217 detector_Trimmer_bias[canale].fine_neg=0x80;
1218 Imposta_canale_del_trimmer_ennesimo_al_valore_I2CB (canale, trimmer_bias_fine_neg , 0x80);
1219 }
1220 }
1221 Aspetta_tanti_ms(attesa);
1222}
1223
1224 for(canale =0; canale<2;canale++){
1225 if ( errore_pos[canale] ){
1226// offset = lettura_ADC( canale_ADC[canale].att_pos); // Viene misurato l'offset per usscita pos e valutato il nuvo valore dei trimmer
1227 offset = correzione_misura_ADC(indice_Vbias, offset);
1228 discrepanza = tensione_target_attenuata[canale] - offset;
1229// Trova_valori_trimmer_per_la_Vbias_del_rivelatore_per_la_tensione_in_uscita_uguale_a_vout ( tensione_target_attenuata[canale], &detector_Trimmer_bias[canale].coarse_pos, offset);
1230 imposta_il_trimmer_del_bias(&detector_Trimmer_bias[canale].coarse_pos, discrepanza, trimmer_bias_coarse_step_actual[canale], trimmer_bias_fine_step_actual[canale]);
1231
1232
1233// offset = lettura_ADC( canale_ADC[canale].att_neg); // Viene misurato l'offset per uscita neg e valutato il nuovo valore dei trimmer
1234 offset = correzione_misura_ADC(indice_Vbias, offset);
1235 discrepanza = -tensione_target_attenuata[canale] - offset;
1236// Trova_valori_trimmer_per_la_Vbias_del_rivelatore_per_la_tensione_in_uscita_uguale_a_vout ( -tensione_target_attenuata[canale], &detector_Trimmer_bias[canale].coarse_neg, offset);
1237 imposta_il_trimmer_del_bias(&detector_Trimmer_bias[canale].coarse_neg, discrepanza, trimmer_bias_coarse_step_actual[canale], trimmer_bias_fine_step_actual[canale]);
1238 Imposta_canale_del_trimmer_ennesimo_al_valore_I2CB (canale, trimmer_bias_coarse_neg, detector_Trimmer_bias[canale].coarse_neg);
1239 Imposta_canale_del_trimmer_ennesimo_al_valore_I2CB (canale, trimmer_bias_fine_neg, detector_Trimmer_bias[canale].fine_neg);
1240
1241 Imposta_canale_del_trimmer_ennesimo_al_valore_I2CB (canale, trimmer_bias_coarse_pos, detector_Trimmer_bias[canale].coarse_pos);
1242 Imposta_canale_del_trimmer_ennesimo_al_valore_I2CB (canale, trimmer_bias_fine_pos, detector_Trimmer_bias[canale].fine_pos);
1243 }
1244 }
1245 Aspetta_tanti_ms(attesa);
1246
1247while( errore_generale && (troppe_misure<5) ){
1248 errore_generale=false;
1249 troppe_misure++;
1250 for( canale=0;canale<2;canale++){
1251 if(errore_pos[canale]){
1252
1253// risultato= lettura_ADC( canale_ADC[canale].att_pos); // Viene misurato il Vbias Pos
1254 risultato = correzione_misura_ADC(indice_Vbias, risultato);
1255 discrepanza = tensione_target_attenuata[canale] - risultato; // Si itera finch\'e |discrepanza| < tot
1256 errore_pos[canale]=(discrepanza < -tolleranza || discrepanza > tolleranza);
1257 imposta_il_trimmer_del_bias(&detector_Trimmer_bias[canale].coarse_pos, discrepanza, trimmer_bias_coarse_step_actual[canale], trimmer_bias_fine_step_actual[canale]);
1258 Imposta_canale_del_trimmer_ennesimo_al_valore_I2CB (canale, trimmer_bias_coarse_pos,detector_Trimmer_bias[canale].coarse_pos);
1259 Imposta_canale_del_trimmer_ennesimo_al_valore_I2CB (canale, trimmer_bias_fine_pos, detector_Trimmer_bias[canale].fine_pos);
1260 }
1261 if (errore_neg[canale]){
1262// risultato= lettura_ADC( canale_ADC[canale].att_neg);
1263 risultato = correzione_misura_ADC(indice_Vbias, risultato);
1264 discrepanza = -tensione_target_attenuata[canale] - risultato; // Si itera finch\'e |discrepanza| <1
1265 errore_neg[canale]=(discrepanza <= -tolleranza || discrepanza >= tolleranza);
1266 imposta_il_trimmer_del_bias(&detector_Trimmer_bias[canale].coarse_neg, discrepanza, trimmer_bias_coarse_step_actual[canale], trimmer_bias_fine_step_actual[canale]);
1267 Imposta_canale_del_trimmer_ennesimo_al_valore_I2CB (canale, trimmer_bias_coarse_neg, detector_Trimmer_bias[canale].coarse_neg);
1268 Imposta_canale_del_trimmer_ennesimo_al_valore_I2CB (canale, trimmer_bias_fine_neg, detector_Trimmer_bias[canale].fine_neg);
1269 }
1270 errore_generale |=errore_neg[canale] | errore_pos[canale] ;
1271 }
1272 Aspetta_tanti_ms(attesa);
1273 }
1274
1275 //Ristabiliamo l'offset se richiesto
1276 if( vettore_istruzioni[istruzione_byte_1] >> offset_adjusted_at_the_pre_bias_set) {
1277 //Il bias viene riaggiustato al valore originale
1279 vettore_istruzioni[istruzione_byte_1]=0x40; //Offset target from elsewhere
1282 }
1283
1285 for ( canale=0;canale<2;canale++){
1286// risultato= lettura_ADC( canale_ADC[canale].att_pos); // Viene misurato il Vbias Pos
1287 risultato = correzione_misura_ADC(indice_Vbias, risultato);
1288// valore_positivo = (risultato*bias_reading_attenuation)/1000;
1289 valore_positivo = (int)(((risultato)/1000) & 0xFFFFFFFF);
1290// tx_data[byte_istr_dati_0] = valore_positivo & 0xFF;
1291// tx_data[byte_istr_dati_1] = (valore_positivo >>8) & 0xFF;
1292
1293// risultato= lettura_ADC( canale_ADC[canale].att_neg);
1294 risultato = correzione_misura_ADC(indice_Vbias, risultato);
1295// valore_negativo = (risultato*bias_reading_attenuation)/1000;
1296 valore_negativo = (int)(((risultato)/1000) & 0xFFFFFFFF);
1297 valore_negativo =valore_positivo - valore_negativo;
1298 tx_data[byte_istr_dati_0 + 2*canale] = (unsigned char)(valore_negativo & 0xFF);
1299 tx_data[byte_istr_dati_1+ 2*canale] = (unsigned char)((valore_negativo >>8) & 0xFF);
1300 tx_data[istruzione_byte_4_e_scelta_canale] = ( errore_neg[canale] | errore_pos[canale] ) << canale;
1301 }
1302 //PGA ristabilito
1303 PGA_GAIN_set(1,PGA_Gain_V_su_V_old[0]);
1304 PGA_GAIN_set(2,PGA_Gain_V_su_V_old[1]);
1305
1306
1307}
1308//! <!-- [fun_instruction_Detector_bias] -->
1309
1310
1311/*! \brief Trimmer settings for the function instruction_Detector_bias()
1312
1313
1314*\param[in,out] Valori_per_i_trimmer pointer to vector with the trimmer values
1315*\param[in] discrepanza is the error voltage from which to construct the new trimmer value.
1316*\param[in] trimmer_bias_coarse_step_singolo coarse trimmer step
1317*\param[in] trimmer_bias_fine_step_singolo fine trimmer step
1318*\return No Parameters, a parte the vector Valori_per_i_trimmer.
1319
1320*\snippetlineno Detector_Bias.c fun_imposta_il_trimmer_del_bias
1321*/
1322//! <!-- [fun_imposta_il_trimmer_del_bias] -->
1323void imposta_il_trimmer_del_bias(int16_t *Valori_per_i_trimmer, long int discrepanza, int trimmer_bias_coarse_step_singolo, int trimmer_bias_fine_step_singolo){
1324 if (abs( discrepanza ) > trimmer_bias_coarse_step)
1325 {
1326 //The "-" is because this trimmer is input to the inverting input
1327 int8_t n = -discrepanza / trimmer_bias_coarse_step_singolo; // Passo trimmer grezzo, ogni passo sono 39 mV
1328 Valori_per_i_trimmer[0]= Valori_per_i_trimmer[0] + n;
1329 if (Valori_per_i_trimmer[0] > 0xFF) Valori_per_i_trimmer[0]=0xFF;
1330 if (Valori_per_i_trimmer[0] <0) Valori_per_i_trimmer[0] =0;
1331 }
1332 else
1333 {
1334 int8_t n = discrepanza / trimmer_bias_fine_step_singolo; // Passo trimmer fine, ogni passo sono 0.39 mV
1335 Valori_per_i_trimmer[1]= Valori_per_i_trimmer[1] + n;
1336 if (Valori_per_i_trimmer[1]>0xFF) Valori_per_i_trimmer[1]=0xFF;
1337 if(Valori_per_i_trimmer[1]<0) Valori_per_i_trimmer[1]=0;
1338 }
1339}
1340//! <!-- [fun_imposta_il_
1341
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
volatile bool ADC_non_leggi_lo_offset_se_true
if not necessary, the ADC input offset from buffer is not read
Definition: Adc.c:200
@ instr_output_offset_to_be_set
Adjust the ouput voltage that was previously set at instr_ouput_offset_we_want_to_set.
uint8_t tx_data[8]
Transmission data vector.
Definition: Can.c:321
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
void PGA_GAIN_set(char canale, unsigned int guadagno_da_impostare)
It sets the new gain irrespective of the offset.
Definition: DAC_PGA.c:443
static void misura_il_valore_trimmer_detector(EPROM_detector__ *EPROM_detector, uint8_t scheda_su_scheda_giu_, uint8_t canali_da_regolare, uint8_t trimmer_da_scrivere)
void instr_detector_scrittura_lettura_trimmer_bias_function(void)
This is an instruction via CAN bus to read/write the detector trimmers. It calls the detector_scrittu...
void imposta_il_trimmer_del_bias(int16_t *Valori_per_i_trimmer, long int discrepanza, int trimmer_bias_coarse_step_singolo, int trimmer_bias_fine_step_singolo)
Trimmer settings for the function instruction_Detector_bias()
void instruction_Detector_bias(void)
The detector bias is set at the value passed from the CAN.
int Detector_Voltage_Bias[]
The bias voltage applied to the detectors.
static void Detector_aggiusta_offset_SAR(EPROM_detector__ *EPROM_detector_sar, uint8_t scheda_su_scheda_giu_)
This function provide the output offset with the fast SAR method: only a few LS bits are left for thi...
int32_t Detector_bias_target[12]
Detector bias target values.
void instr_detector_Vbias_we_want_to_set_function(void)
void instr_Vbias_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_...
const struct Detector_coefficiente_type Detector_coarse_trimmer_normalizing_factor[]
Coarse trimmer, negative side, normalizing factor with repect to the positive side.
void instruction_Vbias_target(void)
The detector bias will be set at the value passed from the CAN if, after this setting,...
static bool Detector_verifica_Vbias(uint8_t scheda_su_giu, bool si_commuta)
Function to verify if the Vbias voltage is within the limit to be swtitched.
const struct Detector_coefficiente_type Detector_small_res_normalizing_factor[]
Small Load resistor, negative side, normalizing factor with repect to the positive resistors.
void instr_Relays_driver_set_reset_channel_function(void)
Function to set the relais for detector bias.
uint8_t detector_Relay_state[12]
The state of the Detector realis is considerede. Note that this is the wanted working condition....
const struct Detector_coefficiente_type Detector_large_res_normalizing_factor[]
Large Load resistor, negative side, normalizing factor with repect to the positive resistors.
#define trimmer_bias_coarse_step
Trimmer fine step in microV/step
Definition: Detector_Bias.h:13
#define Detector_max_limit_to_rail
Definition: Detector_Bias.h:24
#define Detector_min_voltage_for_switch
Definition: Detector_Bias.h:22
#define minimum_error_detector_voltage
< Minimum settbale voltage error for detector bias above
Definition: Detector_Bias.h:30
#define Detector_trimmer_fine_bias_pos
#define Detector_trimmer_coarse_bias_pos
Definition: Detector_Bias.h:98
#define Detector_trimmer_fine_bias_neg
#define Detector_max_voltage_for_switch
Definition: Detector_Bias.h:23
#define Detector_trimmer_coarse_bias_neg
Definition: Detector_Bias.h:99
#define Detector_scrivi_il_trimmer
Definition: Detector_Bias.h:94
void Relays_driver_set_reset_channel(uint8_t scheda_su_giu, uint8_t numero_canale, uint8_t valore_da_trasmettere)
Setting the state of the detector realis: pre connected to detector or intrnal resistor,...
#define Detector_small_RLOAD
#define Detector_prea_to_det
#define Detector_bias_invertito
#define Detector_external_bias
#define Detector_internal_bias
#define Detector_prea_to_GND
#define Detector_bias_diretto
#define Detector_large_RLOAD
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.
@ Vbol_neg_large_for_switching
Negative Vbol too large for switching from internal to external power or vice-versa.
@ Vbol_neg_small_for_switching
Negative Vbol too small for switching from internal to external power or vice-versa.
@ Vbol_pos_large_for_switching
Positive Vbol too large for switching from internal to external power or vice-versa.
@ Vbol_pos_small_for_switching
Positive Vbol too small for switching from internal to external power or vice-versa.
@ ADC_internal_General_fails
ADC general fault.
@ Detector_bias_slopes_not_available
One or more channels have not the slope set.
@ error_address_reg_ADC0
Error register for ADC0.
@ error_address_Bias_adjustment
Error register for channel detector bias adjustment.
@ error_address_PGA_DetectorTrimmer_down
Error register for on board PGA/detector trimmer
@ error_address_Power_Supply_in_General
Error register for channel power supplies.
@ DetectorTrimmer_error_0
detector trimmer setting error for CH0
void instruction_Offset_compensation(void)
Output offset voltage compensation.
Definition: Istruzioni.c:902
#define istruzione_byte_1
Definition: Istruzioni.h:21
#define istruzione_byte_3
Definition: Istruzioni.h:23
#define istruzione_byte_2
Definition: Istruzioni.h:22
#define ADC_Misura_bias_10_att_ch0_p
mux 4
Definition: Istruzioni.h:193
#define byte_istr_dati_1
Definition: Istruzioni.h:26
#define byte_istr_dati_2
Definition: Istruzioni.h:27
#define byte_istr_dati_0
Definition: Istruzioni.h:25
#define byte_istr_dati_3
Definition: Istruzioni.h:28
#define istruzione_byte_4_e_scelta_canale
Definition: Istruzioni.h:24
#define ADC_Misura_bias_10_att_ch1_p
mux 2
Definition: Istruzioni.h:175
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.
@ Memory_detector_negative_address_coarse_trimmer_slope_bias
coarse slope for detector negative trimmer bias
@ Memory_detector_positive_address_coarse_trimmer_slope_bias
coarse slope for detector positive trimmer bias
@ Memory_detector_negative_address_fine_trimmer_slope_bias
fine slope for detector negative trimmer bias
@ Memory_detector_fine_slope_calibration_ON_0_OFF_ff
slope detector negative trimmer active if zero
@ Memory_detector_coarse_slope_calibration_ON_0_OFF_ff
slope detector positive trimmer active if zero
@ Memory_detector_positive_address_fine_trimmer_slope_bias
fine slope for detector positive trimmer bias
@ node_voltage_Analog_Mux_0_offset
Starting Offset for this set of nodes, 32.
void preamplifier_set_reset_pre_gain(uint8_t scheda_su_scheda_giu, uint8_t canale, uint8_t set_2_reset_1_idle_0)
Here the 2 digital signals of the preamplifier's trimmer are exploited to set the gain of the preampl...
#define preamplifier_Gain_basso
. *‍/
#define preamplifier_Gain_alto
. *‍/
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_...
int32_t preamplifier_Output_offset_target[12]
Offset target values.
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.
void Aspetta_tanti_ms(int millisecondi)
The timing function.
Definition: Timer.c:52
void instr_DetBias_trimmer_calibration_function(void)
The fine and coarse trimmers for Detector bias adjustment are calibrated here
Definition: Trimmer.c:480
uint8_t contenuto_trimmer_detector[12][4]
Content of the trimmer for detector bias system.
Definition: Trimmer.c:161
void detector_scrittura_lettura_trimmer_bias(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 detector biasing, the contents of the trimmers are stored in the...
Definition: Trimmer.c:238
volatile int8_t vettore_istruzioni[8]
This is a copy of the received 8 bytes from the CAN.