CROSS Technical Documentation User Manual and Technical Doc.
INFN Milano Bicocca
Loading...
Searching...
No Matches
Adc.c
Go to the documentation of this file.
1
2
3#include "tutti_gli_header.h"
4//#include "math.h"
5/*****DOCUMENTAZIONE DOXYGEN (premi il - a sinistra per ridurla a icona) il manuale html \'e nella cartella************/
6/// \file
7
8/*!
9\page ADC_page Adc
10\brief <span style="color:red;"> <b> ADC managing </b> </span> \anchor ADC_managing
11*\tableofcontents
12
13 \b SUMMARY:
14*\arg \ref introduction_to_ADC
15*\arg \ref ADC_settings
16*\arg \ref ADC_operation
17*\arg \ref OffBoard_ADC
18*\arg \ref ADC_conclusion
19
20
21*\section introduction_to_ADC On Board Adc usage
22<hr width="90%" size="10" align="left">
23
24\n The ADC on board is the 24 bits <a href="./File_pdf/AD7732BRU.pdf" target=_blank><b>AD7732BRU datasheet</b></a>. It has some
25parameters that can be set with flags in its instruction. Its main function to be called is
26ADC_lettura(), whose code is the following:
27*\snippetlineno Adc.c fun_ADC_lettura
28
29\n Reading result has to be multiplied by numeratore, then divided by denominatore. This to work with integer numbers: remember
30that our voltages are in &micro;V.
31\n Each node to be read has its own identity; as an instance, the detector bias is read after a voltage attenuator. The reading nodes
32are organized in groups of 6, there is a vector structure whose locations are retreived by node_number/6:
33*\snippetlineno Adc.h struct_ADC_coefficiente_type
34
35\n Here is the vector #ADC_coefficiente and here we see the coefficient values:
36- #ADC_numeratore_PGA
37- #ADC_denominatore_PGA
38- #ADC_numeratore_PreOut
39- #ADC_denominatore_PreOut
40- #ADC_numeratore_PowerSupply
41- #ADC_denominatore_PowerSupply
42- #ADC_numeratore_Vreg
43- #ADC_denominatore_Vreg
44- #ADC_numeratore_Bias
45- #ADC_denominatore_Bias
46- #ADC_numeratore_Res_fisse
47- #ADC_denominatore_Res_fisse
48- #ADC_numeratore_Bias_p
49- #ADC_denominatore_Bias_p
50
51\n These number are exploited by the function ADC_compensazione_al_nodo()
52that needs as input parameters the node that is being measured by \b line_to_read. Then, from the ADc measured value, \b lettura_ADC and offset \b lettura_offset
53the actual node voltage is obtained. The above coefficiennts take into account the attanuator factors at the buffer inputs according to the following figure:
54
55*\anchor Figure_ADC_Buffer_attenuation_input
56*\image html ADC_buffer_input.png "Figure_ADC_Buffeattenuation 1: ADC buffer in switchable resistor" width=50%
57*\image latex ADC_buffer_input.png "Figure_ADC_Buffeattenuation 1: ADC buffer in switchable resistor" width=50%
58
59\note During the developing phase the board can be connected to an external ADC rather than that of the postfrontend, or mainboard B.
60Dscrimination between internal and external ADC can be made at the instruction level.
61
62*\section ADC_settings On Board ADC settings
63<hr width="90%" size="10" align="left">
64
65\n At startup, within instr_inizializza_tutto_da_zero_function(), both ADC's are initialized. The first action done on ADC is the settings of its configuration pins. This is done at startup by the function ADC_pin_configurations(void).
66Soon after that the SPI protool is set, SPI_Inizialize(), the ADC's zero scale calibration is done, with ADC_selfcal_zero_scale(uint8_t up_down) invoked 2 times, one for each ADC present,
67than, the ADC's are sent into powerdown state with the function ADC_Sleep_fun(uint8_t up_down), invoked 2 times, too.
68
69*\section ADC_operation ADC Operation
70<hr width="90%" size="10" align="left">
71
72\n The ADC functions list is here:
73
74- ADC_misura_differenziale_con_media_generico() with inpt parameters uint8_t scheda_su_scheda_giu_, uint8_t preamplifier_externalADC_1_onboardADC_0,
75uint8_t nodo_da_misurare, uint8_t differenziale1_single_0
76- ADC_misura_differenziale_single_ended() with input parameters uint8_t scheda_su_scheda_giu ,
77uint8_t nodo_da_leggere, uint8_t differenziale_1_single_0
78- ADC_pin_configurations(void)
79- ADC_selfcal_zero_scale(uint8_t up_down)
80- ADC_Sleep_fun(uint8_t up_down)
81- ADC_Wakeup(uint8_t up_down)
82- ADC_lettura_24bit(char ADC_0_o_1 , uint8_t up_down, uint8_t cosa_fare)
83- ADC_lettura_registro(char ADC_0_o_1 , uint8_t up_down, uint8_t registro_ch0)
84- ADC_lettura(uint8_t scheda_su_scheda_giu, uint8_t node_to_read, uint8_t cosa_fare)
85- instr_ADC_LETTURA_function(void)
86
87
88\n On the top of the above list there are the 2 functions that operate globally the ADC's to perform the measurement.
89\n The first one is
90ADC_misura_differenziale_con_media_generico() that allows to set all the necessary parameters to perform the measurement.
91The user could use only this function to operate the ADC.
92\n There are 2 parameters that are not passed to the function but are global and need to be set at least once, or their default
93values are considered.
94\n The variable #ADC_medie_per_misura is the first of the 2 variables that are not passed as a parameter but is a global. It can be set with the instruction via CAN,
95<a href=#instr_ADC_LETTURA_option>instr_ADC_LETTURA</a>.
96It says to the function how many measurements of the node must be taken and averaged.
97\n The other variable that is not passed, but is global is #ADC_non_leggi_lo_offset_se_true. If it is true the input offset
98of the buffer which stands in front of the ADC is not read, \ref Figure_ADC_Buffer_attenuation_input. With the new OA used
99the offset is very small and its measurement can be omitted. This shortens the reading time. This flag can be set ON or OFF from
100the instruction, <a href=#instr_ADC_LETTURA_option>instr_ADC_LETTURA</a>.
101\n The input parameters to the first function are:
102- \b scheda_su_scheda_giu_ is the board selection;
103- \b preamplifier_externalADC_1_onboardADC_0 indicates whether
104the ADC's on board are used or an external ADC is the selcted to perform the measurement, usually this parameter is set to zero
105since the external ADC is selected only for testing purpose;
106- \b nodo_da_misurare is the node whose voltage is to be measured, the node list can be found at \ref lista_nodi "lista nodi";
107- \b differenziale1_single_0 determines whether the measurement is performed differential os single ended. As an example, the ouput of the
108PGA amplifier is differential and we can read it as <b> Vout_pos - Vout_neg </b>, or to read <b>Vout_pos </b> and <b>Vout_neg </b>
109indipendently.
110
111\n The second function, ADC_misura_differenziale_single_ended(), is invoked from the previous function. Its parameters are similar
112to the previous described above:
113- \b scheda_su_scheda_giu is the board from which volateg nodes must be read;
114- \b nodo_da_leggere is the node to be read according to \ref lista_nodi "lista nodi";
115- \b differenziale_1_single_0 determines whether the measurement is performed differential os single ended.
116
117\n The function ADC_pin_configurations() is invoked just one time, at the startup. Calibration is done at startup, too, and can be invoked from time to time from the CAN, too.
118\n ADC_Wakeup() is called every time a reading must be taken, while ADC_Sleep_fun() is invoked at the end of the reading function.
119\n ADC_lettura_24bit(char ADC_0_o_1 , uint8_t up_down, uint8_t cosa_fare) allows a single reading of the previously selected node. It needs to know
120which of the 2 ADC channels to use with \b ADC_0_o_1, and which ADC to consider with \b up_down.
121The last parameter \b cosa_fare allows to operate the 2 ADC in parallel, if needed.
122It cover 3 values as it follows:
123
124- <b>cosa_fare=1:</b> The measurement is only started. The measurement function is not blocking and this allows to launch the measurement with the other ADC in parallel.
125 The returned value is 0 in this case.
126 Take care that the parallel operation is not possible with the 2 channels of the ADC because the ADC is multiplexed. If the parallel operation is anyway set for
127 the 2 channels of the same ADC one measurement will be lost.
128- <b>cosa_fare=2:</b> In this case the measuremen is launched and the result is waited and returned. This is a situation for which parallel operation is not exploited.
129This function is blocking.
130- <b>cosa_fare=3:</b> In this case the result is waited of the measuremnt launched in a previous call with <b>cosa_fare=1</b>.
131
132An example of parallel operation is here (<b>cosa_fare=1</b> combined with <b>cosa_fare=3</b>):
133
134\code{.c}
135 ADC_lettura_24bit(0, I2C_mux_Scheda_su,1);
136 ADC_lettura_24bit(1, I2C_mux_Scheda_giu,1);
137 //The 2 measurements have started in parallel and below here are read
138 int risultato[2];
139 risultato[0]= ADC_lettura_24bit(0, I2C_mux_Scheda_su,3);
140 risultato[1]= ADC_lettura_24bit(1, I2C_mux_Scheda_giu,3);
141\endcode
142
143An example of non parallel operation is here (<b>cosa_fare=2</b>):
144
145\code{.c}
146 int risultato[2];
147 risultato[0]= ADC_lettura_24bit(1, I2C_mux_Scheda_giu,2);
148 //Now the second measurement below will be done just after the measurement
149 //above is finisched since now the function is blocking
150 risultato[1]= ADC_lettura_24bit(0, I2C_mux_Scheda_su,2);
151\endcode
152
153The inputs of the ADCs are buffered. The input resistor of the buffer is a switchable, in principle. This feature cannot be used since the switches are
154MOS whos parasitic diode becomes forward bias when the input voltage goes negative. In this versione of the board the MOS are used for another fnctions and the resistirs is held
155to GND. Its value is not 10 K&Omega;, as in the picture below, but 82 K&Omega;; at the same time the resistor in series to the analog MUX's ouputs is now 8.2 K&Omega;. This
156combination attenuates a little the value of the input node to measure and avoid to be too close to the rails, where the accuracy of the buffer lowers a little.
157
158*\anchor Figure_ADC_Buffer_in
159*\image html ADC_buffer_in_resistor.png "Figure_ADC_Buffer_in 2: ADC buffer in switchable resistor" width=70%
160*\image latex ADC_buffer_in_resistor.png "Figure_ADC_Buffer_in 2: ADC buffer in switchable resistor" width=70%
161
162ADC_lettura_registro() allows to read a whatever ADC internal register of the selected ADC and ADC channel.
163Possible choices are (select the left number of the \b Addr column):
164
165*\anchor Figure_ADC_Reg_list
166*\image html ADC_register_list.png "Figure_ADC_reg 3: ADC register MAP. Select the register number from the \b Addr column. In case 2 numbers are available, choose the left one." width=40%
167*\image latex ADC_register_list.png "Figure_ADC_reg 3: ADC register MAP. Select the register number from the \b Addr column. In case 2 numbers are available, choose the left one." width=40%
168
169\n ADC_lettura(uint8_t scheda_su_scheda_giu, uint8_t node_to_read, uint8_t cosa_fare) sets the path, from the
170node to read, to the ADC input. First of all \b scheda_su_scheda_giu determines the region to operate and the ADC to select.
171It needs to know the node(\b node_to_read) to set the path.
172Then \b cosa_fare is the parameter with which we can operate in parallel with the same sintax seen above.
173
174\n Finally, instr_ADC_LETTURA_function(), is the function that is called when the CAN instruction is invoked,
175<a href=#instr_ADC_LETTURA_option>instr_ADC_LETTURA</a>.
176
177*\section OffBoard_ADC Off Board ADC
178<hr width="90%" size="10" align="left">
179\n This option is anomalous becasue is the &micro;-controller that is asking back the requirement to read the node voltage. Through the CAN Bus and the
180\ref instr_readback_node_voltages_option_ "ReadBack Node Voltage instruction" any available node volatge can be read. The function that is able to perform this
181operation is:
182*\snippetlineno .\Preamplifier_Offset_Drift_Correcttion.c fun_preamplifier_ADC_external_measured_node_function
183
184*\section ADC_conclusion Conclusions
185<hr width="90%" size="10" align="left">
186
187\n This section must be expanded
188
189
190<hr width="90%" size="10" align="left">
191 The codes for mamnaging the ADC are:
192 - \ref Adc.c
193 - \ref Adc.h
194*/
195
196
197
198// CROSS INIZIO
199int32_t volatile ADC_misura_fatta;
200volatile bool ADC_non_leggi_lo_offset_se_true=false; //!< if not necessary, the ADC input offset from buffer is not read
201
202int32_t volatile ADC_external_measurement=0;
203uint8_t volatile ADC_external_measured_node=0;
204
205volatile uint8_t ADC_sleep_off=10; //!< if 0 ADC in sleep when not working, ADC>1 ADC never sleep
206volatile uint16_t ADC_medie_per_misura=10; //!< the number of ADC readings to average, the maximum is 400
207
208
209//! Node normalizing coeficinets used in ADC_lettura_24bit()
211 /*PGA differential or positive from 0 to 5 (6 elements)*/
215 /*PGA negative from 6 to 11 (6 elements)*/
219 /* Preamplifier differntial or positive from 12 to 17 (6 elements)*/
223 /* Preamplifier negative from 18 to 23 (6 elements)*/
227 /* Power supply Vcc Vee and Vdig from 24 to 26 (3 elements)*/
231 /* Power supply Vreg_p Vreg_n e GND sense from 27 to 29 (3 elements)*/
235 /* Dummy from 30 to 31 (2 elements)*/
236 0,0, 0,0,
237 /* Detector bias from 32 to 45 (14 elements)*/
245 /* Dummy from 46 to 47 (2 elements)*/
246 0,0, 0,0,
247 /* Analog mux none e 10 Kohm from 48 to 49 (2 elements)*/
249 /* Detector bias attenuator 50 (1 elements)*/
251
252 #define indice_attenuatore_BIAS sizeof(ADC_coefficiente ) / sizeof(ADC_coefficiente[1])-1
253
254
255/*! \brief ADC is sent to sleep mode
256
257*\return No Parameters, the actual result is sent to the CAN bus output throught \ref tx_data.
258
259*\snippetlineno Adc.c fun_ADC_Sleep_fun
260*/
261//! <!-- [fun_ADC_Sleep_fun] -->
262void ADC_Sleep_fun(uint8_t up_down){
263 const porta_pin_def *ref_locale;
264 if( up_down) up_down=1;
265 if ( up_down == I2C_mux_Scheda_giu){
266 ref_locale =&ADC_Chip_Sel_down; // Viene abbassato il chip selector ADC per la lettura
267 }else{
268 ref_locale =&ADC_Chip_Sel_up;
269 }
270
271 if( up_down <2){
272 GPIO_PinWrite(ref_locale->porta_num, ref_locale->pin_num, 0);
273
274 uint8_t valore_da_trasmettere[]={ ADC_mode_reg, ADC_power_down_com};
275
276 SPIdrv->Send ( &valore_da_trasmettere ,2);
277 uint8_t troppa_attesa=0;
278 while( (SPIdrv->GetStatus().busy) && (troppa_attesa <250) ){
280 troppa_attesa++;
281 } //wait end of transmission ;
283 GPIO_PinWrite(ref_locale->porta_num, ref_locale->pin_num, 1);
284}
285}
286//! <!-- [fun_ADC_Sleep_fun] --
287
288
289/*! \brief ADC self-calibration. ADC needs to be pre-selected.
290
291*\return No return
292
293*\snippetlineno ADC.c fun_selfcal_ADC
294*/
295//! <!-- [fun_selfcal_ADC] -->
296void ADC_selfcal_zero_scale(uint8_t up_down){
297 const porta_pin_def *ref_locale,*ref_locale_ADCready;
298 uint8_t limite=0;
299 if ( up_down == I2C_mux_Scheda_giu){
300 ref_locale =&ADC_Chip_Sel_down;
301 ref_locale_ADCready=&ADC_ready_down;
303 }else{
304 ref_locale =&ADC_Chip_Sel_up;
305 ref_locale_ADCready=&ADC_ready_up;
307 }
308 GPIO_PinWrite(ref_locale->porta_num, ref_locale->pin_num, 0); // Viene abbassato il chip selector ADC per la lettura
309
310 uint8_t valore_da_trasmettere[]={ ADC_mode_reg_ch0, ADC_ZeroScaleCalibration_com}; //Calibriamo il CH0
311 SPIdrv->Send ( &valore_da_trasmettere ,2);
312// while( (SPIdrv->GetStatus().busy) ){
313// limite++;
314// Aspetta_tanti_ms(1);
315// }
316// if( (limite>=10) || Error_bad_operation) ERROR_codifica_errore(up_down, error_address_SPI, Error_bad_operation, 1);
317
318 uint8_t troppa_attesa=0;
319 while( (SPIdrv->GetStatus().busy) && (troppa_attesa <250) ){
321 troppa_attesa++;
322 } //wait end of transmission ;
324
325 limite=0;
326 while (( GPIO_PinRead(ref_locale_ADCready->porta_num,ref_locale_ADCready->pin_num) == 1 ) )
327 { // Si aspetta che il risultato sia pronto ( notRDY=0 )
329 limite++;
330 }
331 if( (limite>=10) ) ERROR_codifica_errore(up_down, error_address_reg_ADC0, ADC_RDY_pin_fault, 1);
332
333 GPIO_PinWrite(ref_locale->porta_num, ref_locale->pin_num, 1); // Viene alzato il chip selector ADC per la lettura
334 ADC_Sleep_fun(up_down + ADC_sleep_off);
335}
336//! <!-- [fun_selfcal_ADC] -->
337
338
339
340/*! \brief ADC is set to sleep or awake
341
342\param[in] up_down :ADC for board up or board down
343\param[in] ADC_ON_1_OFF_0_NOP_GT1 : 2 (ON)=ADC ON, dummy resistors OFF; 0(OFF): ADC sleep, dummy resitors ON; 1(OFF): ADC sleep, dummy resitors OFF; >2: NOP
344
345*\return No return
346
347*\snippetlineno ADC.c fun_ADC_sleep_ON_OFF
348*/
349//! <!-- [fun_ADC_sleep_ON_OFF] -->
350void ADC_sleep_ON_OFF(uint8_t up_down , uint8_t ADC_ON_1_OFF_0_NOP_GT1){
351 const porta_pin_def *ref_locale,*ref_locale_ResBuffer,*ref_locale_ResBuffer_;
352if(up_down)up_down=1;
353if ( ADC_ON_1_OFF_0_NOP_GT1 <= 2){
354 if ( up_down == I2C_mux_Scheda_giu){
355 ref_locale_ResBuffer = &ADC_ResIn_B_buffer_down;//switch for buffer resistor on/off
356 ref_locale_ResBuffer_ = &ADC_ResIn_A_buffer_down;//switch for buffer resistor on/off
357 }else if(up_down>=I2C_mux_Scheda_su){
358 ref_locale_ResBuffer = &ADC_ResIn_B_buffer_up;//switch for buffer resistor on/off
359 ref_locale_ResBuffer_ = &ADC_ResIn_A_buffer_up;//switch for buffer resistor on/off
360 }
361 if(ADC_ON_1_OFF_0_NOP_GT1==1){
362 //ADC OFF, dummy OFF
363 ADC_Sleep_fun(up_down );
364 GPIO_PinWrite(ref_locale_ResBuffer->porta_num, ref_locale_ResBuffer->pin_num, 0); // Togliamo il consumo che simula l'ADC
365 GPIO_PinWrite(ref_locale_ResBuffer_->porta_num, ref_locale_ResBuffer_->pin_num, 0); // Togliamo il consumo che simula l'ADC
366 }else if (ADC_ON_1_OFF_0_NOP_GT1==0){
367 //ADC OFF, dummy ON
368 ADC_Sleep_fun(up_down );
369 GPIO_PinWrite(ref_locale_ResBuffer->porta_num, ref_locale_ResBuffer->pin_num, 1); // Aggiungiamo il consumo che simula l'ADC
370 GPIO_PinWrite(ref_locale_ResBuffer_->porta_num, ref_locale_ResBuffer_->pin_num, 1); // Aggiungiamo il consumo che simula l'ADC
371 }else if (ADC_ON_1_OFF_0_NOP_GT1==2){
372 //ADC ON, dummy OFF
373 ADC_Wakeup(up_down);
374 GPIO_PinWrite(ref_locale_ResBuffer->porta_num, ref_locale_ResBuffer->pin_num, 0); // Togliamo il consumo che simula l'ADC
375 GPIO_PinWrite(ref_locale_ResBuffer_->porta_num, ref_locale_ResBuffer_->pin_num, 0); // Togliamo il consumo che simula l'ADC
376 }
377 }
378}
379//! <!-- [fun_ADC_sleep_ON_OFF] -->
380
381/*! \brief ADC Wakeup and 24 bits reading
382
383*\return No return
384
385*\snippetlineno ADC.c fun_ADC_Wakeup
386*/
387//! <!-- [fun_ADC_Wakeup] -->
388void ADC_Wakeup(uint8_t up_down){
389 uint8_t limite;
390 const porta_pin_def *ref_locale;
391 if ( up_down == I2C_mux_Scheda_giu){
392 ref_locale =&ADC_Chip_Sel_down;
393 }else{
394 ref_locale =&ADC_Chip_Sel_up;
395 }
396 GPIO_PinWrite(ref_locale->porta_num, ref_locale->pin_num, 0); // Viene abbassato il chip selector ADC per la lettura
397
398 uint8_t valore_da_trasmettere[]={ ADC_mode_reg_ch0, ADC_idle_com}; //Idle, attesa misura
399 SPIdrv->Send ( &valore_da_trasmettere ,2);
400 limite=0;
401 while( (SPIdrv->GetStatus().busy) && (limite<10) ) {
402 limite++;
404 }
406
407 valore_da_trasmettere[0]= ADC_mode_reg_ch1; valore_da_trasmettere[1]= ADC_idle_com; //Idle, attesa misura
408 SPIdrv->Send ( &valore_da_trasmettere ,2);
409 limite=0;
410 while( (SPIdrv->GetStatus().busy) &&(limite<10) ) {
411 limite++;
413 }
415
416// SPItx(ADC_mode_reg);
417// SPItx(ADC_idle_com); //idle mode, 24 bit
418
419 GPIO_PinWrite(ref_locale->porta_num, ref_locale->pin_num, 1); // Viene alzato il chip selector ADC per la lettura
420}
421//! <!-- [fun_ADC_Wakeup] -->
422
423/*! \brief ADC Wakeup and 24 bits reading
424*\param[in] line_to_read_to_select_ADCch0_ADCch1 : which of the 2 channels within the ADC has to be considered, if =50 ADC ch0 if =51 ADC ch 1
425*\param[in] up_down : which boards: up or down
426*\param[in] cosa_fare : cosa_fare=1 measurement is launched, but the result is not waited; cosa_fare=2 measurement is launched end the result is waited,
427 cosa_fare=3 only the result is waited
428*\return risultato : the measurement result in microV
429
430*\snippetlineno ADC.c fun_ADC_lettura_24bit
431*/
432//! <!-- [fun_ADC_lettura_24bit] -->
433long int ADC_lettura_24bit(char line_to_read_to_select_ADCch0_ADCch1 , uint8_t up_down, uint8_t cosa_fare){
434 //cosa_fare=1 measurement is launched, but the result is not waited
435 //cosa_fare=2 measurement is launched end the result is waited
436 //cosa_fare=3 only the result is waited
437 //Exploting cosa_fare the ADCs can be operated in parallel. The parallel operation is not posssible
438 //with the 2 ADC of the same chip. If the function is called with cosa_fare= 2/3 with the same value of
439 //up_down the results will be unpredictable.
440 uint8_t ADC_0_o_1;
441 uint8_t limite;
442 ARM_SPI_STATUS errorone;
443 unsigned int risultato_= 0xffffffff;
444// unsigned long int registro_di_controllo;
445 if (up_down>1) up_down=1;
446 status = SPIdrv->Control(SPI_control_for_relay_driver,spi_clock_for_relais);
448 long int risultato=0;
449 if ( ADC_node_map[line_to_read_to_select_ADCch0_ADCch1] < 16) ADC_0_o_1=0;
450 if ( (ADC_node_map[line_to_read_to_select_ADCch0_ADCch1] >=16) ) ADC_0_o_1=1;
451
452 uint8_t ii=0,scelta_ADC=ADC_mode_reg_ch0, valore_da_trasmettere[4]={0,0,0,0};
453 uint8_t indirizzo_registro_lettura=read_from_CH0 ;
454 uint8_t valore_da_ricevere[4];
455 const porta_pin_def *ref_locale, *ref_locale_ADCready, *ref_locale_ResBuffer, *ref_locale_ResBuffer_;
456
457 if ( up_down == I2C_mux_Scheda_giu){
458 ref_locale =&ADC_Chip_Sel_down;
459 ref_locale_ADCready=&ADC_ready_down; //Ready pin of ADC down
460 ref_locale_ResBuffer = &ADC_ResIn_B_buffer_down;//switch for buffer resistor on/off
461 ref_locale_ResBuffer_ = &ADC_ResIn_A_buffer_down;//switch for buffer resistor on/off
462// if( ADC_0_o_1){
463// ref_locale_ResBuffer = &ADC_ResIn_B_buffer_down;//switch for buffer resistor on/off
464// }else{
465// ref_locale_ResBuffer = &ADC_ResIn_A_buffer_down;//switch for buffer resistor on/off
466// }
467 }else{
468 ref_locale =&ADC_Chip_Sel_up;
469 ref_locale_ADCready=&ADC_ready_up; //Ready pin of ADC up
470 ref_locale_ResBuffer = &ADC_ResIn_B_buffer_up;//switch for buffer resistor on/off
471 ref_locale_ResBuffer_ = &ADC_ResIn_A_buffer_up;//switch for buffer resistor on/off
472// if( ADC_0_o_1){
473// ref_locale_ResBuffer = &ADC_ResIn_B_buffer_up;//switch for buffer resistor on/off
474// }else{
475// ref_locale_ResBuffer = &ADC_ResIn_A_buffer_up;//switch for buffer resistor on/off
476// }
477 }
478 if (ADC_0_o_1==1){
479 scelta_ADC=ADC_mode_reg_ch1; //indirizzo registro start misura
480 indirizzo_registro_lettura=read_from_CH1; //indirizzo lettura misura
481 }
482 if (cosa_fare <=2 ){// Si sceglie di fare partire a misura
483 ADC_sleep_ON_OFF(scheda_su_scheda_giu , 2 + ADC_sleep_off ); //ADC on se serve
484// ADC_Wakeup(up_down);
485 GPIO_PinWrite(ref_locale->porta_num, ref_locale->pin_num, 0); // Viene abbassato il chip selector ADC per la lettura
486// if( ADC_sleep_off==0){
487// GPIO_PinWrite(ref_locale_ResBuffer->porta_num, ref_locale_ResBuffer->pin_num, 0); // Togliamo il consumo che simula l'ADC
488// GPIO_PinWrite(ref_locale_ResBuffer_->porta_num, ref_locale_ResBuffer_->pin_num, 0); // Togliamo il consumo che simula l'ADC
489// }
491 //SI lancia la misura dell'ADC selezionato
492 valore_da_trasmettere[0]= scelta_ADC; valore_da_trasmettere[1]= ADC_mode_reg_set_single_24bit;
493 evento_SPI=0;
494 SPIdrv->Send ( &valore_da_trasmettere ,2);
495 limite=0;
496// while( (SPIdrv->GetStatus().busy) && (limite<10) ){
497 while( (evento_SPI==0) && (limite<10) ){
499 limite++;
500 }
501 if( (limite>=10) || Error_bad_operation){
502 errorone=SPIdrv->GetStatus();
503 status = SPIdrv->Control(ARM_SPI_ABORT_TRANSFER,0);
505 }
506 GPIO_PinWrite(ref_locale->porta_num, ref_locale->pin_num, 1); // Viene alzto il chip selector ADC per la lettura
507 }
508 if(cosa_fare > 1){//Polling di fine misura solo nei casi selezionati
509 uint8_t registro38= (ADC_lettura_registro(ADC_0_o_1,up_down,0x38)>>16) & 0xFF;
510 //Leggiamo il registro 0x38 per verificare che l'ADc non sia in standby
511 if ( registro38 != 0x70){
512 //Attesa misura disponibile
513 limite=0;
514 while (( GPIO_PinRead(ref_locale_ADCready->porta_num,ref_locale_ADCready->pin_num) == 1 ) && (limite<10)){
516 limite++;
517 }
518 if( (limite>=10) ) ERROR_codifica_errore(up_down, error_address_reg_ADC0, ADC_RDY_pin_fault, 1);
519
520 GPIO_PinWrite(ref_locale->porta_num, ref_locale->pin_num, 0); // Viene abbassato il chip selector ADC per la lettura
521 //Leggiamo il risultato della lettura
522 uint8_t dati_da_trasmettere[]={indirizzo_registro_lettura,0,0,0};
523 SPIdrv->Transfer (&dati_da_trasmettere, &valore_da_ricevere ,4);
524 limite=0;
525 while( (SPIdrv->GetStatus().busy) && (limite<10) ){
527 limite++;
528 }
529 if( (limite>=10) || Error_bad_operation){
530 errorone=SPIdrv->GetStatus();
531 status = SPIdrv->Control(ARM_SPI_ABORT_TRANSFER,0);
533 }
534
535 GPIO_PinWrite(ref_locale->porta_num, ref_locale->pin_num, 1); // Viene alzto il chip selector ADC per la lettura
536 //Il primo byte letto \'e il MSB
537 risultato_ =(valore_da_ricevere[1]<<16) + (valore_da_ricevere[2]<<8 )+( valore_da_ricevere[3] );
538
539 GPIO_PinWrite(ref_locale->porta_num, ref_locale->pin_num, 1); // Viene alzato il chip selector ADC
540// if( ADC_sleep_off==0){
541// GPIO_PinWrite(ref_locale_ResBuffer->porta_num, ref_locale_ResBuffer->pin_num, 1); // Riconsumiamo dummy
542// GPIO_PinWrite(ref_locale_ResBuffer_->porta_num, ref_locale_ResBuffer_->pin_num, 1); // Riconsumiamo dummy
543// }
544 /* Per convertire il risultato in MICROVOLT si dovrebbe fare: (risultato/2^24*20E6) -10E6
545 Una formula equivalente \'e: { [(risultato*2)-(2^24)]*10E6 } / 2^24
546 Notando che 10^6 = (78125 * 2^7) allora 10^6 / 2^24 = 78125 / 2^17 */
547 risultato = ( (long long int) ( (int)(risultato_ << 1) - (1 << 24) ) * 78125 ) >> 17 ;
548 }
549// ADC_Sleep_fun(up_down + +ADC_sleep_off);
550 ADC_sleep_ON_OFF(scheda_su_scheda_giu , 0 + ADC_sleep_off ); //ADC off se serve
551 }
552
553 return risultato; //Risultato in microV
554}
555//! <!-- [fun_ADC_lettura_24bit] -->
556
557
558/*! \brief This function allows to read a whatver regsiter of the ADC
559\param[in] line_to_read : the read node
560\param[in] lettura_ADC : the value read from the ADC, in microV
561\param[in] lettura_offset : the offset read from the ADC, this is proportional to the input current, in microV
562
563*\return risultato_intermedio is the voltage at the actual node in microV.
564
565*\snippetlineno Adc.c fun_ADC_compensazione_al_nodo
566*/
567//! <!-- [fun_ADC_compensazione_al_nodo] -->
568int ADC_compensazione_al_nodo(uint8_t line_to_read , int32_t lettura_ADC , int32_t lettura_offset){
569 long int risultato_intermedio= lettura_ADC;
570 //Questo varrebbe se il nodo di lettura fosse cortocircuitato a gnd
571// risultato_intermedio = risultato_intermedio - lettura_offset + ((risultato_intermedio - lettura_offset)*ADC_coefficiente[line_to_read].numeratore) / ADC_coefficiente[line_to_read].denominatore ;
572 //Questo vale se la sola re all'ingresso dell'oa fosse presente
573 risultato_intermedio = risultato_intermedio + ((risultato_intermedio - lettura_offset)*ADC_coefficiente[line_to_read].numeratore) / ADC_coefficiente[line_to_read].denominatore ;
574 if( (line_to_read >= node_voltage_Analog_Mux_0_offset ) && (line_to_read <= node_voltage_Analog_Mux_meas_input_bias_neg ) ){
575 risultato_intermedio = (risultato_intermedio * ADC_coefficiente[indice_attenuatore_BIAS].numeratore ) / ADC_coefficiente[indice_attenuatore_BIAS].denominatore ;
576 }
577 return risultato_intermedio;
578}
579//! <!-- [fun_ADC_compensazione_al_nodo] --
580
581/*! \brief This function allows to read a whatver regsiter of the ADC
582
583\param[in] ADC_0_o_1 : which of the 2 ADCs the register is considered
584\param[in] up_down : which of the 2 ADCs to consider
585\param[in] registro_ch0 : the address of the register to read. the address is for ch0. If ch1 is selected according to ADC_0_o_1
586
587*\return ADC_misura_fatta is the voltage measured in microV.
588
589*\snippetlineno Adc.c fun_ADC_lettura_registro
590*/
591//! <!-- [fun_ADC_lettura_registro] -->
592uint32_t ADC_lettura_registro(char ADC_0_o_1 /*0=ADC0, 1=ADC1*/, uint8_t up_down, uint8_t registro_ch0){
593
594// unsigned long int registro_di_controllo;
595 long int risultato=0;
596 uint8_t byte_da_trasmettere_ricevere=2;
597 if(up_down>1)up_down=1;
598 if( (registro_ch0>=5) && (registro_ch0<=0x18) ) byte_da_trasmettere_ricevere=4;
599
600 uint8_t ii=0,scelta_ADC=ADC_mode_reg_ch0, valore_da_ricevere[4]={0,0,0,0}, registro_lettura=read_from_CH0 ;
601
602 const porta_pin_def *ref_locale, *ref_locale_ADCready;
603
604 if ( up_down == I2C_mux_Scheda_giu){
605 ref_locale =&ADC_Chip_Sel_down;
606 }else{
607 ref_locale =&ADC_Chip_Sel_up;
608 }
609
610 if (registro_ch0 ==0x38){
611 registro_lettura= registro_ch0 +0x40; //il mode register, 0x38 si pu\'o leggere solo sul canale CH0
612 }else{
613 registro_lettura= registro_ch0 + ADC_0_o_1*2 +0x40;
614 }
615
616
617GPIO_PinWrite(ref_locale->porta_num, ref_locale->pin_num, 0); // Viene abbassato il chip selector ADC per la lettura
618
619// SPIdrv->Receive ( &valore_da_trasmettere ,3);
620 uint8_t istruzione[]={registro_lettura,0,0,0};
621 SPIdrv->Transfer (&istruzione, &valore_da_ricevere ,byte_da_trasmettere_ricevere);
622// while( (SPIdrv->GetStatus().busy) ){}
623
624 uint8_t troppa_attesa=0;
625 while( (SPIdrv->GetStatus().busy) && (troppa_attesa <250) ){
627 troppa_attesa++;
628 } //wait end of transmission ;
629 if((troppa_attesa>=250) || (Error_bad_operation)) ERROR_codifica_errore(scheda_su_scheda_giu, error_address_SPI, SPI_error_EVENT_DATA_LOST,1);
630
631GPIO_PinWrite(ref_locale->porta_num, ref_locale->pin_num, 1); // Viene abbassato il chip selector ADC per la lettura
632 if( byte_da_trasmettere_ricevere ==4){
633 risultato = (valore_da_ricevere[1]<<16) + (valore_da_ricevere[2]<<8) + (valore_da_ricevere[3]);
634 }else{
635 risultato = (valore_da_ricevere[1]);
636 }
637return risultato;
638}
639//! <!-- [fun_ADC_lettura_registro] -->
640
641
642/*! \brief This function allows to read a whatver regsiter of the ADC
643
644\param[in] ADC_0_o_1 : which of the 2 ADCs the register is considered
645\param[in] up_down : which of the 2 ADCs to consider
646\param[in] indirizzo_registro_ch0 : the address of the register to read. the address is for ch0. If ch1 is selected according to ADC_0_o_1
647\param[in] value_to_write : the value to write in the register
648
649*\return no return.
650
651*\snippetlineno Adc.c fun_ADC_scrittura_registro
652*/
653//! <!-- [fun_ADC_scrittura_registro] -->
654void ADC_scrittura_registro(char ADC_0_o_1 /*0=ADC0, 1=ADC1*/, uint8_t up_down, uint8_t indirizzo_registro_ch0, int32_t value_to_write){
655// unsigned long int registro_di_controllo;
656
657 uint8_t byte_da_trasmettere_ricevere=2;
658 if(up_down>1)up_down=1;
659 if( (indirizzo_registro_ch0>=5) && (indirizzo_registro_ch0<=0x18) ) byte_da_trasmettere_ricevere=4;
660
661 uint8_t ii=0,scelta_ADC=indirizzo_registro_ch0, *valore_da_trasmettere, registro_scrittura=value_to_write ;
662
663 const porta_pin_def *ref_locale, *ref_locale_ADCready;
664
665 if ( up_down == I2C_mux_Scheda_giu){
666 ref_locale =&ADC_Chip_Sel_down;
667 }else{
668 ref_locale =&ADC_Chip_Sel_up;
669 }
670
671 if (indirizzo_registro_ch0 ==0x38){
672 registro_scrittura= indirizzo_registro_ch0 ; //il mode register, 0x38 si pu\'o leggere solo sul canale CH0
673 }else{
674 registro_scrittura= indirizzo_registro_ch0 + ADC_0_o_1*2 ;
675 }
676
677 valore_da_trasmettere= (uint8_t *) &value_to_write ;
678
679 GPIO_PinWrite(ref_locale->porta_num, ref_locale->pin_num, 0); // Viene abbassato il chip selector ADC per la lettura
680
681// SPIdrv->Receive ( &valore_da_trasmettere ,3);
682 uint8_t istruzione[]={registro_scrittura,valore_da_trasmettere[0],valore_da_trasmettere[1],valore_da_trasmettere[2]};
683 SPIdrv->Send ( &istruzione ,byte_da_trasmettere_ricevere);
684// while( (SPIdrv->GetStatus().busy) ){}
685
686 uint8_t troppa_attesa=0;
687 while( (SPIdrv->GetStatus().busy) && (troppa_attesa <250) ){
689 troppa_attesa++;
690 } //wait end of transmission ;
691 if((troppa_attesa>=250) || (Error_bad_operation)) ERROR_codifica_errore(scheda_su_scheda_giu, error_address_SPI, SPI_error_EVENT_DATA_LOST,1);
692
693 GPIO_PinWrite(ref_locale->porta_num, ref_locale->pin_num, 1); // Viene abbassato il chip selector ADC per la lettura
694
695
696}
697//! <!-- [fun_ADC_scrittura_registro] -->
698
699/*! \brief This function allows to read the voltage of any of the selectable nodes
700*\param[in] scheda_su_scheda_giu_ : which boards: up or down
701*\param[in] node_to_read : which of the 49 nodes to read
702*\param[in] cosa_fare : cosa_fare=1 measurement is launched, but the result is not waited;
703 \n cosa_fare=2 measurement is launched and the result is waited;
704 \n cosa_fare=3 only the result is waited
705*\return ADC_misura_fatta : the measurement result
706
707*\snippetlineno Adc.c fun_ADC_lettura
708*/
709//! <!-- [fun_ADC_lettura] -->
710int32_t ADC_lettura(uint8_t scheda_su_scheda_giu_, uint8_t node_to_read, uint8_t cosa_fare){
711 //Da implementare: lettura di un qualsiasi nodo con ADC interno
712 status = SPIdrv->Control(SPI_control_for_relay_driver,spi_clock_for_relais);
713 if(scheda_su_scheda_giu_>1)scheda_su_scheda_giu_=1;
714 if( cosa_fare <=2){
715 //Si seleziona l'analog mux sulla mainboard, se serve
716 if ( (node_to_read >= node_voltage_Analog_Mux_0_offset ) ){//Questo \'e il mux della mainboard A
717 Analog_mux_line_to_select_deselect(scheda_su_scheda_giu_, node_to_read & 0xF, 1);
718 }
719 //si seleziona l'analog mux sulla postmainboard
720 Analog_mux_line_to_select_deselect_for_postmainboard ( scheda_su_scheda_giu_, node_to_read, 1 ) ;
721 //si toglie la res da 10k, questo viene fatto all'interno della funzione della lettura ADC
722 //si seleziona l' ADC
723 //si spara la misura in parallelo
724 ADC_misura_fatta = ADC_lettura_24bit( node_to_read, scheda_su_scheda_giu_, cosa_fare); //Lancio la misura con (2)(non in parallelo) o senza (1) polling
725 }
726
727 if ( cosa_fare ==3){
728 //si leggono solo gli ADC
729 ADC_misura_fatta = ADC_lettura_24bit( node_to_read, scheda_su_scheda_giu_, 3 );
730 }
731 if( cosa_fare>=2){
732 //Si de-seleziona l'analog mux sulla mainboard, se serve
733 if ( (node_to_read >= node_voltage_Analog_Mux_0_offset ) ){//Questo \'e il mux della mainboard A
734 Analog_mux_line_to_select_deselect(scheda_su_scheda_giu_, node_to_read & 0xF, 0);
735 }
736 //si de-seleziona l'analog mux sulla postmainboard
737 Analog_mux_line_to_select_deselect_for_postmainboard ( scheda_su_scheda_giu_, node_to_read, 0 ) ;
738 }
739// uint8_t numeratore=1, denominatore=1; //Attenuation is always 1 but with detector bias
740// if( (node_to_read >=node_voltage_Analog_Mux_0_offset) && (node_to_read <=(node_voltage_Analog_Mux_0_offset +14))){ //14=12 bias voltage + 2 external bias
741// numeratore=ADC_numeratore_Bias;
742// denominatore= ADC_denominatore_Bias;
743// }
744// ADC_misura_fatta = (ADC_misura_fatta *numeratore) / denominatore;
745// ADC_misura_fatta = (ADC_misura_fatta * ADC_coefficiente[node_to_read / ADC_molteplicita_node_to_read].numeratore )\
746// / ADC_coefficiente[node_to_read / ADC_molteplicita_node_to_read].denominatore ;
747
748 return ADC_misura_fatta;
749}
750//! <!-- [fun_ADC_lettura] -->
751
752
753/*! \brief All the posible nodes voltages can be read with this instruction. Either the internal or
754an external ADC can be used. The external ADC option will become obsolote at the time of installation.
755
756*\return No Parameters, the actual result is sent to the CAN bus output throught \ref tx_data.
757
758*\snippetlineno Adc.c fun_instr_ADC_LETTURA_function
759*/
760//! <!-- [fun_instr_ADC_LETTURA_function] -->
762 uint8_t offset,nodo_da_leggere = tx_data[6], iii;
763 uint8_t ADC_interno_esterno= tx_data[5] & 1;
764 uint8_t ADC_diff_1_single_0= tx_data[5] >>1 & 1;
765 int32_t ADC_misura_fatta_neg=0, ADC_misura_fatta_pos=0,ADC_misura;
766
767 scheda_su_scheda_giu = (nodo_da_leggere >>7) & 1;
768 nodo_da_leggere = nodo_da_leggere & 0x7F ;
769// if ( (nodo_da_leggere >= node_voltage_Analog_Mux_0_offset ) & ADC_interno_esterno){//L'ADC ha gi\'a implementato il mux.
770// Analog_mux_line_to_select_deselect(scheda_su_scheda_giu, nodo_da_leggere , 1);
771// }
772 if( vettore_istruzioni[3]==1){
774 }else{
776 }
780
781// if(ADC_interno_esterno){
782// //Lettrura con ADC esterno
783// ADC_misura_fatta_pos= preamplifier_ADC_external_measured_node_function(scheda_su_scheda_giu , nodo_da_leggere);
784// *(int32_t *)tx_data = ADC_misura_fatta;
785//// ADC_misura_fatta = (ADC_misura_fatta * ADC_coefficiente[nodo_da_leggere / ADC_molteplicita_node_to_read].numeratore )\
786//// / ADC_coefficiente[nodo_da_leggere / ADC_molteplicita_node_to_read].denominatore ;
787// }else{
788// //Lesstura con ADC interno
789// ADC_sleep_ON_OFF(scheda_su_scheda_giu , 2); //ADC ON
790// uint8_t provvisorio= ADC_sleep_off;
791// ADC_sleep_off=10; //ADC smpre accesi durante la media
792// for(iii=0; iii<ADC_medie_per_misura;iii++){
793// ADC_misura= ADC_lettura(scheda_su_scheda_giu, nodo_da_leggere, 2);
794// int risul_vof= (ADC_lettura_24bit( nodo_da_leggere,scheda_su_scheda_giu, 2) ) ;
795// ADC_misura_fatta_pos += ADC_compensazione_al_nodo(nodo_da_leggere,ADC_misura, risul_vof);
796// if( nodo_da_leggere <= node_voltage_PreOut_ch_5 ){//PGA o Pre out
797// ADC_misura = ADC_lettura(scheda_su_scheda_giu, nodo_da_leggere + 6, 2);
798// risul_vof= (ADC_lettura_24bit( nodo_da_leggere+6,scheda_su_scheda_giu, 2) ) ;
799// ADC_misura_fatta_neg += ADC_compensazione_al_nodo(nodo_da_leggere+6,ADC_misura, risul_vof);
800// }
801// }
802// ADC_sleep_off = provvisorio;
803// ADC_sleep_ON_OFF(scheda_su_scheda_giu , 0 + ADC_sleep_off ); //ADC off se serve
804// ADC_misura_fatta_pos = ADC_misura_fatta_pos / ADC_medie_per_misura;
805// ADC_misura_fatta_neg = ADC_misura_fatta_neg / ADC_medie_per_misura;
806//
807// if(ADC_diff_single ){// misure positiva e negativa in mV
808// *(int16_t *)&tx_data[0] = (ADC_misura_fatta_pos / 1000) & 0xffff;
809// *(int16_t *)&tx_data[2] = (ADC_misura_fatta_neg / 1000) & 0xffff;
810// }else{ //misura standard differenziale
811// *(int32_t *)tx_data = ADC_misura_fatta_pos - ADC_misura_fatta_neg;
812// }
813// }
814
815 ADC_misura_fatta_pos = ADC_misura_differenziale_con_media_generico(scheda_su_scheda_giu,ADC_interno_esterno,nodo_da_leggere,ADC_diff_1_single_0);
816 if (ADC_diff_1_single_0==0){
817 if( nodo_da_leggere <= node_voltage_PreOut_ch_5 ){
818 offset=6;
819 ADC_misura_fatta_neg = ADC_misura_differenziale_con_media_generico(scheda_su_scheda_giu,ADC_interno_esterno,nodo_da_leggere+offset,ADC_diff_1_single_0);
820 }else if (nodo_da_leggere >= node_voltage_Analog_Mux_meas_bias_pos_ch0 ){
821 offset=1;
822 ADC_misura_fatta_neg = ADC_misura_differenziale_con_media_generico(scheda_su_scheda_giu,ADC_interno_esterno,nodo_da_leggere+offset,ADC_diff_1_single_0);
823 }
824 }
825
826 if(ADC_interno_esterno){
827 *(int32_t *)tx_data = ADC_misura_fatta_pos;
828 }else if ( (ADC_diff_1_single_0==0) && ( ( nodo_da_leggere <= node_voltage_PreOut_ch_5 ) ||\
829 (nodo_da_leggere >= node_voltage_Analog_Mux_meas_bias_pos_ch0 )) ){// misure positiva e negativa in mV
830 *(int16_t *)&tx_data[0] = (ADC_misura_fatta_pos / 1000) & 0xffff;
831 *(int16_t *)&tx_data[2] = (ADC_misura_fatta_neg / 1000) & 0xffff;
832 }else{ //misura standard differenziale
833 *(int32_t *)tx_data = ADC_misura_fatta_pos - ADC_misura_fatta_neg;
834 }
835
836}
837//! <!-- [fun_instr_ADC_LETTURA_function] -->
838
839
840
841/*! \brief This function performs a differential or single ended measurement on nodes.
842
843\param[in] scheda_su_scheda_giu : the board to consider
844\param[in] nodo_da_leggere : the positive node to read (the negtive node is the positive plus an offset determined by the function)
845\param[in] differenziale_1_single_0 : information about the measurement to perform
846
847*\return No Parameters, the actual result is sent to the CAN bus output throught \ref tx_data.
848
849*\snippetlineno Adc.c fun_ADC_misura_differenziale_single_ended
850*/
851//! <!-- [fun_ADC_misura_differenziale_single_ended] -->
852static int32_t ADC_misura_differenziale_single_ended(uint8_t scheda_su_scheda_giu , uint8_t nodo_da_leggere, uint8_t differenziale_1_single_0 ){
853 int32_t ADC_misura_fatta_pos=0, ADC_misura_fatta_neg=0,risul_vof=0;
854 uint8_t offset;
855 {
856 ADC_misura_fatta_pos= ADC_lettura(scheda_su_scheda_giu, nodo_da_leggere, 2);
858 risul_vof=0;
859 }else{
860 risul_vof= (ADC_lettura_24bit( nodo_da_leggere,scheda_su_scheda_giu, 2) ) ;
861 }
862 ADC_misura_fatta_pos = ADC_compensazione_al_nodo(nodo_da_leggere,ADC_misura_fatta_pos, risul_vof);
863 }
864 if(differenziale_1_single_0){//PGA o Pre out neg
865 if( nodo_da_leggere <= node_voltage_PreOut_ch_5 ){
866 offset=6;
867 }else{
868 offset=1;
869 }
870 ADC_misura_fatta_neg = ADC_lettura(scheda_su_scheda_giu, nodo_da_leggere + offset, 2);
872 risul_vof=0;
873 }else{
874 risul_vof= (ADC_lettura_24bit( nodo_da_leggere+6,scheda_su_scheda_giu, 2) ) ;
875 }
876 ADC_misura_fatta_neg = ADC_compensazione_al_nodo(nodo_da_leggere+offset,ADC_misura_fatta_neg, risul_vof);
877 }else{
878 ADC_misura_fatta_neg=0;
879 }
880 return ADC_misura_fatta_pos = ADC_misura_fatta_pos - ADC_misura_fatta_neg;
881}
882//! <!-- [fun_ADC_misura_differenziale_single_ended] -->
883
884
885
886/*! \brief This function sets the original gain when a few LSb have to be determined. The umber of bits
887is bit_to_go.
888
889*\param[in] scheda_su_scheda_giu_ : the selected board
890*\param[in] preamplifier_externalADC_1_onboardADC_0 : the chosen between the external ADC (1), or the internal ADC (0)
891*\param[in] nodo_da_misurare : the channel number of PGA
892*\param[in] differenziale_1_single_0 : the measurement type
893
894*\return ADC_misura_fatta : the final measurement
895
896*\snippetlineno .\Adc.c fun_ADC_misura_differenziale_con_media_at_PGA
897*/
898//! <!-- [fun_ADC_misura_differenziale_con_media_at_PGA] -->
899int32_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){
900
901 uint16_t iii, media_prov=ADC_medie_per_misura;
902 int32_t ADC_misura_fatta_prov, ADC_misura_fatta_prov_vet[200], maggiore, minore,scarto=0,sigmetta=0;
903// int64_t sigma2=0;
904 if( ADC_medie_per_misura==0) {
906 media_prov=ADC_medie_per_misura;
907 }
908 scheda_su_scheda_giu=scheda_su_scheda_giu_;
909 //Misuro con ADC da scegliere
910 if( preamplifier_externalADC_1_onboardADC_0){
911 //Misura con adc esterno
912 ADC_misura_fatta = preamplifier_ADC_external_measured_node_function(scheda_su_scheda_giu_, nodo_da_misurare);
913 }else{
914 //Misuro con adc interno
915 ADC_sleep_ON_OFF(scheda_su_scheda_giu , 2); //ADC sempre ON durante la misura
916 uint8_t provvisorio= ADC_sleep_off;
917 ADC_sleep_off=10;
918 ADC_misura_fatta_prov=0;
920 for(iii=0; iii<ADC_medie_per_misura;iii++){
921 ADC_misura_fatta_prov_vet[iii] = ADC_misura_differenziale_single_ended(scheda_su_scheda_giu_,nodo_da_misurare,differenziale_1_single_0);
922// ADC_misura_fatta_prov_vet[iii] = ADC_misura_differenziale(scheda_su_scheda_giu_ , nodo_da_misurare );
923 ADC_misura_fatta_prov +=ADC_misura_fatta_prov_vet[iii];
924 }
925 ADC_misura_fatta_prov = ADC_misura_fatta_prov / ADC_medie_per_misura;
926 for(iii=0; iii<ADC_medie_per_misura;iii++){
927 //Misuriamo la sigma
928 if( ADC_misura_fatta_prov_vet[iii] >= ADC_misura_fatta_prov){
929 sigmetta += ADC_misura_fatta_prov_vet[iii] - ADC_misura_fatta_prov;
930 }else{
931 sigmetta += ADC_misura_fatta_prov - ADC_misura_fatta_prov_vet[iii] ;
932 }
933
934 }
935 sigmetta= sigmetta / ADC_medie_per_misura;
936 //3 sigma sono circa 4 volte il valore ottenuto con l'integrale del modulo: 3sigma=3(pi/2)^.5sigmetta=3.8sigmetta
937 maggiore= ADC_misura_fatta_prov + 4 * sigmetta;
938 minore= ADC_misura_fatta_prov - 4 * sigmetta;
939 for(iii=0; iii<ADC_medie_per_misura;iii++){
940 if( (ADC_misura_fatta_prov_vet[iii] > maggiore) || (ADC_misura_fatta_prov_vet[iii] < minore)){
941 //I punti fuori gaussiana li buttiamo
942 media_prov--;
943 scarto +=ADC_misura_fatta_prov_vet[iii];
944 }
945 }
946 if( media_prov){
947 ADC_misura_fatta = ( ADC_misura_fatta_prov * ADC_medie_per_misura - scarto) / media_prov ;
948 }else{
949 ADC_misura_fatta = ADC_misura_fatta_prov;
950 }
951 ADC_sleep_off = provvisorio; //Rimettiamo l'adc come serve
952 ADC_sleep_ON_OFF(scheda_su_scheda_giu , 0 + ADC_sleep_off ); //ADC off se serve
953 }
954 return ADC_misura_fatta;
955}
956//! <!-- [fun_ADC_misura_differenziale_con_media_at_PGA] -->
957
958
959//CROSS FINE
960
961/*****************************************************************************
962 SPItx
963******************************************************************************/
964/*! \brief This is a blocking function that transmits one byte over the SPI
965\param[in] dato the byte to be transmitted
966*\return No output
967
968*\snippetlineno Adc.c fun_SPItx
969*/
970//! <!-- [fun_SPItx] -->
971void SPItx(unsigned char dato){
972// Trasmissione di 1 byte via SPI
973 LPC_SPI->SPDR=dato; // Viene trasmesso il dato
974 while (!((LPC_SPI->SPSR & 0x80) == 0x80)){} // Si attende che il flag SPIF si alzi
975 dato=LPC_SPI->SPSR; // Dummy op per azzerare lo status reg
976 dato=LPC_SPI->SPDR; // Dummy op necessaria
977}
978//! <!-- [fun_SPItx] -->
979
980unsigned int Radc_internal=15e6; //!< The ADC has 2 interbnal resistors R=Radc_internal and 7R. The resistor is experessed in mOhm
981unsigned int Rmultiplexer=200e3; //!< This is the multiplexer resistor and the series resistor connected in series to it
982
983struct coeffcienti_misura_ADC_type coeffcienti_misura_ADC[indice_default+1];
984unsigned char coeffcienti_misura_ADC_nodi[72];
985unsigned char medie_ADC= 2 ; //!< The number of averages done is 1 << medie_ADC, or 2^medie_ADC
986
987
988
989
990
991
992void calibrazione_Resistenze_sterne_ADC(void){
993
994 long int voltage_10k,voltage_for_Rmul;
995
996// selfcal_ADC(); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
997
998 //Leggiamo dal nodo a 10k verso massa
999// voltage_10k = lettura_ADC( ADC_GND_con_10k);
1000 Radc_internal =( R_ref_10k * ( ADC_reference_voltage - voltage_10k) ) / 8 / voltage_10k;
1001
1002 //Cerchiamo di determinare anche Rmultiplexer
1003// voltage_for_Rmul = lettura_ADC( ADC_Misura_bias_20_att_ch1_p); //Usato fino a che non si \'e usato la lettura del bias esterno
1004// voltage_for_Rmul = lettura_ADC( ADC_Misura_bias_20_att_ch0_p);
1005 Rmultiplexer = (8 * Radc_internal ) ;
1006 Rmultiplexer = ( Rmultiplexer / ( ADC_reference_voltage - voltage_for_Rmul) ) * voltage_for_Rmul;
1007
1008 coeffcienti_misura_ADC[indice_Vbias].coefficiente_Vmeas = Coefficiente_Vmeas_Vbias;
1009 coeffcienti_misura_ADC[indice_Vbias].coefficiente_Vref = Coefficiente_Vref_Vbias;
1010 coeffcienti_misura_ADC[indice_Vbias].partizione_per_1000 = bias_reading_attenuation;
1011
1012 coeffcienti_misura_ADC[indice_PoerSupply].coefficiente_Vmeas = Coefficiente_Vmeas_PowerSupply;
1013 coeffcienti_misura_ADC[indice_PoerSupply].coefficiente_Vref = Coefficiente_Vref_PowerSupply;
1014 coeffcienti_misura_ADC[indice_PoerSupply].partizione_per_1000 = 1024;
1015
1016 coeffcienti_misura_ADC[indice_default].coefficiente_Vmeas = Coefficiente_Vmeas_deafult;
1017 coeffcienti_misura_ADC[indice_default].coefficiente_Vref = Coefficiente_Vref_default;
1018 coeffcienti_misura_ADC[indice_default].partizione_per_1000 = 1024;
1019
1020 coeffcienti_misura_ADC[indice_100_ohm].coefficiente_Vmeas = Coefficiente_Vmeas_100_ohm;
1021 coeffcienti_misura_ADC[indice_100_ohm].coefficiente_Vref = Coefficiente_Vref_100_ohm;
1022 coeffcienti_misura_ADC[indice_100_ohm].partizione_per_1000 = 1024;
1023
1024 coeffcienti_misura_ADC[indice_10_Kohm].coefficiente_Vmeas = Coefficiente_Vmeas_10k_ohm;
1025 coeffcienti_misura_ADC[indice_10_Kohm].coefficiente_Vref = Coefficiente_Vref_10k_ohm;
1026 coeffcienti_misura_ADC[indice_10_Kohm].partizione_per_1000 = 1024;
1027
1028 coeffcienti_misura_ADC[indice_Vbias_extern].coefficiente_Vmeas = Coefficiente_Vmeas_Vbias_extern;
1029 coeffcienti_misura_ADC[indice_Vbias_extern].coefficiente_Vref = Coefficiente_Vref_Vbias_extern;
1030 coeffcienti_misura_ADC[indice_Vbias_extern].partizione_per_1000 = bias_reading_attenuation_extern;
1031
1032
1033//mux 1
1034coeffcienti_misura_ADC_nodi[ADC_GND_con_10k]=indice_PoerSupply;
1035coeffcienti_misura_ADC_nodi[ADC_Vdig5V_micro_passed]=indice_PoerSupply;
1036coeffcienti_misura_ADC_nodi[ADC_Vcc]=indice_PoerSupply;
1037coeffcienti_misura_ADC_nodi[ADC_Vee]=indice_PoerSupply;
1038coeffcienti_misura_ADC_nodi[ADC_JFET_c_ch1_S2]=indice_default;
1039coeffcienti_misura_ADC_nodi[ADC_PRE_term_ch1]=indice_default;
1040coeffcienti_misura_ADC_nodi[ADC_ADC_PGA_pos_in_ch1]=indice_default;
1041coeffcienti_misura_ADC_nodi[ADC_ADC_PGA_neg_in_ch1]=indice_default;
1042//mux 2
1043coeffcienti_misura_ADC_nodi[ADC_Misura_bias_10_att_ch1_p]=indice_Vbias;
1044coeffcienti_misura_ADC_nodi[ADC_Misura_bias_10_att_ch1_n]=indice_Vbias;
1045coeffcienti_misura_ADC_nodi[ADC_Misura_bias_20_att_ch1_p]=indice_Vbias_extern;
1046coeffcienti_misura_ADC_nodi[ADC_Misura_bias_20_att_ch1_n]=indice_Vbias_extern;
1047coeffcienti_misura_ADC_nodi[ADC_CommonMode_ch1]=indice_default;
1048coeffcienti_misura_ADC_nodi[ADC_CommonMode_ch2]=indice_default;
1049coeffcienti_misura_ADC_nodi[ADC_ADC_PGA_pos_out_ch1]=indice_default;
1050coeffcienti_misura_ADC_nodi[ADC_ADC_PGA_neg_out_ch1]=indice_default;
1051//mux 3
1052coeffcienti_misura_ADC_nodi[ADC_Vdig5V_micro_in]=indice_PoerSupply;
1053coeffcienti_misura_ADC_nodi[ADC_Vcc_in]=indice_PoerSupply;
1054coeffcienti_misura_ADC_nodi[ADC_Vee_in]=indice_PoerSupply;
1055coeffcienti_misura_ADC_nodi[ADC_Vref_pos_in]=indice_PoerSupply;
1056coeffcienti_misura_ADC_nodi[ADC_Vref_neg_in]=indice_PoerSupply;
1057coeffcienti_misura_ADC_nodi[ADC_PRE_term_ch2]=indice_default;
1058coeffcienti_misura_ADC_nodi[ADC_ADC_PGA_pos_in_ch0]=indice_100_ohm;
1059coeffcienti_misura_ADC_nodi[ADC_ADC_PGA_neg_in_ch0]=indice_100_ohm;
1060//mux 4
1061coeffcienti_misura_ADC_nodi[ADC_Misura_bias_10_att_ch0_p]=indice_Vbias;
1062coeffcienti_misura_ADC_nodi[ADC_Misura_bias_10_att_ch0_n]=indice_Vbias;
1063coeffcienti_misura_ADC_nodi[ADC_Misura_bias_20_att_ch0_p]=indice_Vbias;
1064coeffcienti_misura_ADC_nodi[ADC_Misura_bias_20_att_ch0_n]=indice_Vbias;
1065coeffcienti_misura_ADC_nodi[ADC_JFET_c_ch0_S1]=indice_PoerSupply;
1066coeffcienti_misura_ADC_nodi[ADC_JFET_c_ch0_S2]=indice_default;
1067coeffcienti_misura_ADC_nodi[ADC_ADC_PGA_pos_out_ch0]=indice_100_ohm;
1068coeffcienti_misura_ADC_nodi[ADC_ADC_PGA_neg_out_ch0]=indice_100_ohm;
1069}
1070
1071int correzione_misura_ADC(char quali_coefficienti, int misura){
1072
1073 long long int primo_termine;
1074 long long int secondo_termine;
1075 signed char segno=1;
1076
1077 primo_termine= (long long int)misura * (coeffcienti_misura_ADC[quali_coefficienti].coefficiente_Vmeas >> 10) - (coeffcienti_misura_ADC[quali_coefficienti].coefficiente_Vref>>10) * (long long int)ADC_reference_voltage ;
1078 if (primo_termine <0){
1079 segno=-1*segno;
1080 primo_termine=primo_termine*segno;
1081 }
1082 secondo_termine = primo_termine / (long long int)(RADC_tot>>10) ;
1083// secondo_termine=divisione_di_gianlu( primo_termine , (RADC_tot>>10));
1084 secondo_termine = (secondo_termine * coeffcienti_misura_ADC[quali_coefficienti].partizione_per_1000) >> 10 ;
1085 secondo_termine=secondo_termine*segno;
1086return secondo_termine;
1087
1088}
1089
1090/*! \brief The division operator on 32 or 64 bit, positive/negative integers
1091
1092*@param[in] Numeratore the numerator;
1093*\param[in] denominatore the denominator;
1094*\return The result
1095*/
1096long long int divisione_di_gianlu( long long int Numeratore, long long int denominatore) {
1097
1098// #define meta_scala 0x8000000000000000
1099 char ii,passi_da_fare=64;
1100 char aa=0;
1101 long long int risultato=0,temporaneo=0;
1102 //meta_scala=(1 << 63);;
1103
1104 if (Numeratore < 0) { //La divisione funziona se abbiamo numeri > 0, perci\'o positivizziamo e aggiorniamo dopo
1105 aa++;
1106 Numeratore=-Numeratore;
1107 }
1108 if (denominatore<0){
1109 aa++;
1110 denominatore=-denominatore;
1111 }
1112 if(Numeratore < 0x100000000){ //Se minore di 2^32 \'e inutile considerare altri 32 bit
1113 passi_da_fare=32;
1114 }
1115
1116 for( ii=1; ii <= passi_da_fare; ii++) { // E' come nelle divisioni normali, confrontiamo le cifre + significative con il denominatore
1117 temporaneo=(temporaneo <<1); //Temporaneo contiene le cifre piu' significative che stiamo valutando
1118 risultato= (risultato << 1); //Risultato contiene il risultato della divisione mentre si forma
1119 if ( (Numeratore >> (passi_da_fare-1) ) & 1 /*(Numeratore & meta_scala) >0 */) {//Abbiam oruotato a sx tempraneo, la LSB \'e 0. Gli mettiamo un 1 se il MSB di numeratore, che verr\'a ruotato, \'e 1
1120 temporaneo=temporaneo+1;
1121 }
1122 if ( temporaneo >= denominatore) {// Ogni volta che temporaneo \'e > di denominatore glielo togliamo, ed aggiungiamo 1 a risultato
1123 temporaneo=temporaneo-denominatore;
1124 risultato++;
1125 } // Alla fine temporaneo contiene il resto della divisione, che deve essere < di denominatore
1126 Numeratore=(Numeratore << 1);
1127
1128 }
1129 if ( aa==1) risultato=-risultato; //La divisione \'e un numero negativo
1130 return risultato; // In questo programma non siamo interessati al resto della divisione
1131}
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
void ADC_sleep_ON_OFF(uint8_t up_down, uint8_t ADC_ON_1_OFF_0_NOP_GT1)
ADC is set to sleep or awake.
Definition: Adc.c:350
void SPItx(unsigned char dato)
This is a blocking function that transmits one byte over the SPI.
Definition: Adc.c:971
int ADC_compensazione_al_nodo(uint8_t line_to_read, int32_t lettura_ADC, int32_t lettura_offset)
This function allows to read a whatver regsiter of the ADC.
Definition: Adc.c:568
void ADC_Sleep_fun(uint8_t up_down)
ADC is sent to sleep mode.
Definition: Adc.c:262
long long int divisione_di_gianlu(long long int Numeratore, long long int denominatore)
The division operator on 32 or 64 bit, positive/negative integers.
Definition: Adc.c:1096
long int ADC_lettura_24bit(char line_to_read_to_select_ADCch0_ADCch1, uint8_t up_down, uint8_t cosa_fare)
ADC Wakeup and 24 bits reading.
Definition: Adc.c:433
void instr_ADC_LETTURA_function(void)
All the posible nodes voltages can be read with this instruction. Either the internal or an external ...
Definition: Adc.c:761
uint32_t ADC_lettura_registro(char ADC_0_o_1, uint8_t up_down, uint8_t registro_ch0)
This function allows to read a whatver regsiter of the ADC.
Definition: Adc.c:592
volatile uint16_t ADC_medie_per_misura
the number of ADC readings to average, the maximum is 400
Definition: Adc.c:206
static int32_t ADC_misura_differenziale_single_ended(uint8_t scheda_su_scheda_giu, uint8_t nodo_da_leggere, uint8_t differenziale_1_single_0)
This function performs a differential or single ended measurement on nodes.
Definition: Adc.c:852
int32_t ADC_lettura(uint8_t scheda_su_scheda_giu_, uint8_t node_to_read, uint8_t cosa_fare)
This function allows to read the voltage of any of the selectable nodes.
Definition: Adc.c:710
void ADC_Wakeup(uint8_t up_down)
ADC Wakeup and 24 bits reading.
Definition: Adc.c:388
unsigned char medie_ADC
The number of averages done is 1 << medie_ADC, or 2^medie_ADC.
Definition: Adc.c:985
const struct ADC_coefficiente_type ADC_coefficiente[]
Node normalizing coeficinets used in ADC_lettura_24bit()
Definition: Adc.c:210
volatile uint8_t ADC_sleep_off
if 0 ADC in sleep when not working, ADC>1 ADC never sleep
Definition: Adc.c:205
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
void ADC_selfcal_zero_scale(uint8_t up_down)
ADC self-calibration. ADC needs to be pre-selected.
Definition: Adc.c:296
void ADC_scrittura_registro(char ADC_0_o_1, uint8_t up_down, uint8_t indirizzo_registro_ch0, int32_t value_to_write)
This function allows to read a whatver regsiter of the ADC.
Definition: Adc.c:654
unsigned int Radc_internal
Definition: Adc.c:980
unsigned int Rmultiplexer
This is the multiplexer resistor and the series resistor connected in series to it.
Definition: Adc.c:981
#define ADC_denominatore_PowerSupply
Definition: Adc.h:55
#define ADC_numeratore_Res_fisse
Definition: Adc.h:62
#define ADC_numeratore_PreOut
Definition: Adc.h:52
#define ADC_numeratore_Bias
Definition: Adc.h:60
#define ADC_denominatore_Bias
Definition: Adc.h:61
#define ADC_denominatore_Bias_p
Definition: Adc.h:59
#define ADC_denominatore_Res_fisse
Definition: Adc.h:63
#define ADC_numeratore_PGA
Definition: Adc.h:50
#define ADC_numeratore_PowerSupply
Definition: Adc.h:54
#define ADC_denominatore_Vreg
Definition: Adc.h:57
#define ADC_denominatore_PGA
Definition: Adc.h:51
#define ADC_numeratore_Bias_p
Definition: Adc.h:58
#define ADC_numeratore_Vreg
Definition: Adc.h:56
#define ADC_denominatore_PreOut
Definition: Adc.h:53
uint8_t tx_data[8]
Transmission data vector.
Definition: Can.c:321
#define bias_reading_attenuation
Trimmer coarse step in microV/step at the reading attenuation node.
Definition: Detector_Bias.h:10
#define bias_reading_attenuation_extern
< Attenuation for bias reading
Definition: Detector_Bias.h:9
#define spi_clock_for_relais
[ref_spi_clock_for_relais]
volatile uint32_t Error_bad_operation
exploited to mark the errors
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.
@ ADC_RDY_pin_fault
ADC ready not received.
@ error_address_reg_ADC0
Error register for ADC0.
@ error_address_SPI
Error register for SPI.
@ SPI_error_EVENT_DATA_LOST
This is ARM_SPI_EVENT_DATA_LOST.
const porta_pin_def ADC_ready_down
Configuration ADC pin.
Definition: Gpio.c:148
const porta_pin_def ADC_Chip_Sel_up
Configuration ADC pin.
Definition: Gpio.c:146
const uint8_t ADC_node_map[]
Mapping to mux's on postmainboard. Its syntax: bits 0 to 3 are common to all the MUXs and select one ...
Definition: Gpio.c:172
const porta_pin_def ADC_ready_up
Configuration ADC pin.
Definition: Gpio.c:145
const porta_pin_def ADC_ResIn_A_buffer_down
Refernce to fgnd of theADC input buffer, if 1 there is a 10kOhm connected to GND.
Definition: Gpio.c:113
const porta_pin_def ADC_ResIn_A_buffer_up
Refernce to fgnd of theADC input buffer, if 1 there is a 10kOhm connected to GND.
Definition: Gpio.c:115
const porta_pin_def ADC_Chip_Sel_down
Configuration ADC pin.
Definition: Gpio.c:149
const porta_pin_def ADC_ResIn_B_buffer_down
Refernce to fgnd of theADC input buffer, if 1 there is a 10kOhm connected to GND.
Definition: Gpio.c:114
const porta_pin_def ADC_ResIn_B_buffer_up
Refernce to fgnd of theADC input buffer, if 1 there is a 10kOhm connected to GND.
Definition: Gpio.c:116
#define I2C_mux_Scheda_giu
Selection of the I2C1 for lower board (purtroppo \'e contorto)
Definition: I2C_mux.h:16
#define I2C_mux_Scheda_su
Selection of the I2C0 for the upper board (purtroppo \'e contorto)
Definition: I2C_mux.h:15
#define ADC_Misura_bias_10_att_ch0_p
mux 4
Definition: Istruzioni.h:193
#define ADC_GND_con_10k
instr_NO_operation has the value of zero and the follwoing instructions are increased by one at each ...
Definition: Istruzioni.h:166
@ node_voltage_PreOut_ch_5
Node voltage selection of PreOut 12+5 board down.
Definition: Istruzioni.h:90
#define ADC_Vdig5V_micro_in
mux 3
Definition: Istruzioni.h:184
#define ADC_Misura_bias_10_att_ch1_p
mux 2
Definition: Istruzioni.h:175
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...
void Analog_mux_line_to_select_deselect_for_postmainboard(uint8_t scheda_su_scheda_giu, uint8_t line_to_select, uint8_t select_1_deselect_0)
Selection of the line to measure with the analog MUX's of the postmainboard, directely driven by the ...
@ node_voltage_Analog_Mux_0_offset
Starting Offset for this set of nodes, 32.
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.
uint32_t evento_SPI
This is the variable which resembles the flags from the communication.
Definition: Spi.c:151
#define SPI_control_for_relay_driver
[ref_SPI_control_for_relay_driver]
Definition: Spi.h:10
void Aspetta_tanti_ms(int millisecondi)
The timing function.
Definition: Timer.c:52
volatile int8_t vettore_istruzioni[8]
This is a copy of the received 8 bytes from the CAN.
Definition: Gpio.h:13