CROSS Technical Documentation User Manual and Technical Doc.
INFN Milano Bicocca
Loading...
Searching...
No Matches
Memoria_pre_M24CXX.c
Go to the documentation of this file.
1
2// DOCUMENTAZIONE DOXYGEN
3/// \file
4
5/*! \page Flash_M24CXX I2C EPROM memory
6*\brief <b> This chip is exploited to store the preamplifier parameters and settings </b>
7*\tableofcontents
8
9 \b SUMMARY:
10*\arg \ref preamplifier_flash_memory
11*\arg \ref state_store_recovering
12*\arg \ref sw_detail
13*\arg \ref location_list
14*\arg \ref location_list_mainboard
15*\arg \ref location_list_postmainboard
16
17\section preamplifier_flash_memory Use of the Preamplifier EPROM memory
18<hr width="100%" size="20" align="left">
19
20\n Each unit of the system has its own EPROM memory where to store at least its sn and, when present, the fw version.
21The first samples of the preamplifier has the <a href="./File_pdf/MC24C08.pdf" target=_blank><b>MC24C08</b></a>,
22that is a 8 Kb I2C flash memory. The frontend board has a <a href="./File_pdf/MC24C16.pdf" target=_blank><b>MC24C16</b></a>.
23Finally the postfrontend board has the <a href="./File_pdf/MC24C64.pdf" target=_blank><b>MC24C64</b></a>. The different memory sizes
24have different cell address organization. From 1Kb up to 16Kb they are shown in figure \ref Figure_M24C00_16K. Namely, depending on the size, the 8-LSb bits
25are in the first word sent, while the MSb in excess of 8 are in the first bits of the I2C addres, so that the larger is the size, the lesser is the available
26choice left for the I2C addres (4 of the 7 I2C address bits are fixed). Different is the approach for the M24C32 and M24C64 that
27uses 2 bytes of data for addressing and have the 3 available bits free for I2C address, the case 1 KB in \ref Figure_M24C00_16K.
28\n In our frontend we are going to use the \b M24C32 for both the preamplifier and the frontend board and the \b M24C64 in the post frontend board.
29The different choices are only due to the availability at the moment of the population of the boards. Both memories requires a 2-bytes address.
30\n An example of use of 4-bytes writing of the 32k/64K EPROM at addres \b 0x20 of the channel6 EPROM is here:
31
32<span style="color:orange;"> <I>
33\code {.c}
34dati_da_scrivere[0]= 50; // The value is arbitrary
35dati_da_scrivere[1]= 60;
36dati_da_scrivere[2]= 70;
37dati_da_scrivere[3]= 80;
38EPROM_scrittura_M24C32_64(scheda_su_scheda_giu_provvisorio, I2C_mainboard,, canale6 , 0x20 , dati_da_scrivere);
39\endcode
40</I> </span>
41
42*\anchor Figure_M24C00_16K
43*\image html M24C00_16K.jpg "Figure_M24C00_16K 1: M24C00_16K I2C address organization" width=30%
44*\image latex M24C00_16K.jpg "Figure_M24C00_16K 1: M24C00_16K I2C address organization" width=30%
45
46\n There are a number of variables and definitions to manage the memories, but the the functions to use are
47only 2 and very simple. To read from the memory we use EPROM_lettura_M24C32_64(uint8_t scheda_su_scheda_giu,uint8_t I2C_mainboard,uint8_t canale, short indirizzo_memoria , uint8_t *dati_letti),
48while to write EPROM_scrittura_M24C32_64(uint8_t scheda_su_scheda_giu, uint8_t mainboard_postmainboard , uint8_t canale, short indirizzo_memoria , uint8_t *dati_da_scrivere).
49\n \b scheda_su_scheda_giu is one of the 2 boards to select, \b canali is the preamplifier memory or the frontend
50board memory, according to the following enum #canali_eprom:
51\snippet Memoria_pre_M24CXX.h fun_canali_eprom
52\n \b indirizzo_memoria is the address of the memory to write to or to read from and \b *dati_da_scrivere the pointer to the data to read/write. Take care:
53only 4 bytes can be read or written for each call.
54
55\remark The EPROM is organized per pages whose length is 16 Bytes from sizes from 0 Kb up to 16 Kb, while it is 32 Bytes for
56the 32 Kb and 64 Kb. Writing can be done only per single page, namely, a writing cannot cover 2 pages contemporary.
57To avoid loss of data during writing in the stream of data the address bits from A4 to the MSb must not change,
58for EPROM size smaller or equal to 16 Kb. The same applies to the 32 Kb and 64 Kb except that in this case bits
59from A5 to the MSb are those that should not change during a data storage.
60
61\note Variables stored into the memories are located at fixed defined positions. To have a copy of them
62the .h files for the preamplifirs EPROM is the "enum preamplifier_EPROM" on the following
63link: <a href="_memoria__pre___m24_c_x_x_8h.html" download>Memoria_pre_M24CXX.h</a>. Note that each element of the link
64must be multiplied by 4 for getting the actual address since the memory is orhanized as a uint32.
65
66\section state_store_recovering Channel state store and recovery
67<hr width="100%" size="20" align="left">
68\n The state condition of the channel cane be recordered and aplied in a differenta ways. The variables that reflect
69the state are stored in 2 memory loactions.
70\n The first state is that recalled at startup. This state requires that the PGA gain is 1 and that the preamplifier
71is connected to GND. The memory location for this state is #Memory_preamplifier_startup_offset_trimmer. Note that at sturtup
72this state is applied only if the memory location #Memory_preamplifier_startup_offset_trimmer_ON_0_OFF_ff is set to 0 value.
73This is done by the sw at the time the storing takes place.
74The state can be called also by setting the corresponding bit, but take care that for this case gain and detector state
75are not resumed and the user must do it.
76The startup state is created at the end of the offset adjustment, if the corresponding flag is set.
77\n Another possible state is the user state. In this case it is stored at #Memory_preamplifier_user_offset_trimmer and
78#Memory_preamplifier_user_detector_and_gain which reflect the full condition for the channel, both offset, gain and
79detector condition. This state can be stored in 2 ways. After offset adjustment by setting the corresponding bit, or by
80a picture of the state, with no other actions than the storing of the variables, by setting the corresponding bit.
81\n The state can be recovered by the corresponding bit and this work only if the
82#Memory_preamplifier_user_offset_trimmer_ON_0_OFF_ff was set to 0. This is done by the sw at the time the storing takes place.
83\n The bits to set are in the
84<a href="_instruction_set.html#instr_output_offset_to_be_set_option" download>instr_output_offset_to_be_set</a>,
85at the Byte<sub>3</sub> option.
86
87\remark If the startup stored is invoked remember that it refers to a PGA gain of 1 V/V and the detector disconnected.
88If the user state stored is invoked all the channel settings are recovered from memory: offset, PGA gain end detector settings.
89Regarding the detector setting the amount of the external bias, if it that consodered is not set.
90
91\n The function invoked is the following:
92*\snippet{lineno} Memoria_pre_M24CXX.c fun_EPROM_store_recover_state_M24C32_64
93\n
94
95\section sw_detail Functions and vars details
96<hr width="100%" size="20" align="left">
97\n Concerning the functions which are able to work with the EPROM having size smaller or equalt o 16Kb we have that
98the reading function is here:
99*\snippet{lineno} Memoria_pre_M24CXX.c fun_EPROM_lettura_M24C32_64
100\n While the writng function is here:
101\snippet{lineno} Memoria_pre_M24CXX.c fun_EPROM_scrittura_M24C32_64
102\n There are 4 different I2C channels (selected at I2C_mux_select_ch()) and 2 I2C addresses are exploitable
103for the preamplifier EPROMs:
104#EPROM_I2C_addres_memory_ch_pari and #EPROM_I2C_addres_memory_ch_dispari, while the onboard EPROM is at
105#EPROM_mainboard_I2C_addres. The I2C paremeters for each EPROM are in the structure #address_detector_bias_trimmer_type:
106*\snippet Memoria_pre_M24CXX.h fun_EPROM_I2C
107\n So that the 7 positions strucure is #EPROM_address.
108
109\n The codes for I2C_0 is at:
110- \ref Memoria_pre_M24CXX.c
111- \ref Memoria_pre_M24CXX.h
112
113\anchor preamplifier_memory_location_list
114\section location_list The list of locations of the preamplifier EPROM
115<hr width="100%" size="20" align="left">
116\n Here the list of the locations of preamplifier EPROM, remember to multiply by 4, or <<2, the bullet number
117to set the actual address, an unsigned int:
118
119<ol start="0">
120 <li> #Memory_preamplifier_address_SN;
121<!-- Preamplifier offset trimmer -->
122 <li> #Memory_preamplifier_slope_calibration_ON_0_OFF_ff;
123 <li> #Memory_preamplifier_address_fine_trimmer_slope_offset;
124 <li> #Memory_preamplifier_address_coarse_trimmer_slope_offset;
125<!-- Offset trimmer for sturtup -->
126 <li> #Memory_preamplifier_startup_offset_trimmer_ON_0_OFF_ff;
127 <li> #Memory_preamplifier_startup_offset_trimmer;
128<!-- User Offset trimmer -->
129 <li> #Memory_preamplifier_user_offset_trimmer_ON_0_OFF_ff;
130 <li> #Memory_preamplifier_user_offset_trimmer;
131 <li> #Memory_preamplifier_user_detector_and_gain;
132 <li> #Memory_preamplifier_user_detector_trimmer;
133<!-- Detector trimmer coarse calibration voltage -->
134 <li> #Memory_detector_coarse_slope_calibration_ON_0_OFF_ff;
135 <li> #Memory_detector_positive_address_coarse_trimmer_slope_bias;
136 <li> #Memory_detector_negative_address_coarse_trimmer_slope_bias;
137<!-- Detector trimmer fine calibration voltage -->
138 <li> #Memory_detector_fine_slope_calibration_ON_0_OFF_ff;
139 <li> #Memory_detector_positive_address_fine_trimmer_slope_bias;
140 <li> #Memory_detector_negative_address_fine_trimmer_slope_bias.
141<!-- Preamplifier Drift parameteers -->
142 <li> #Memory_preamplifier_drift_ON_0_OFF_ff,
143 <li> #Memory_preamplifier_trimmers_for_drift,
144 <li> #Memory_preamplifier_offset_slope_trimmer_with_temp
145 <li> #Memory_preamplifier_compensation_slope_trimmer_with_temp
146 <li> #Memory_preamplifier_compensation_slope
147 <li> #Memory_preamplifier_last_memory_used_first_free
148 </li>
149</ol>
150
151The last memory cell used is #Memory_preamplifier_last_memory_used. If it not coincide with the length of the list above it means that the list is not upgraded.
152
153
154\anchor mainboard_memory_location_list
155\section location_list_mainboard The list of locations of the mainboard EPROM adrress
156<hr width="100%" size="20" align="left">
157
158\n Here the list of the locations of mainboard EPROM, remember to multiply by 4, or <<2, the bullet number
159to set the actual address, an unsigned int:
160
161<ol start="0">
162 <li> #Memory_mainboard_address_SN;
163<!-- CAN addresses -->
164 <li> #Memory_mainboard_address_fw;
165 <li> #Memory_mainboard_address_CAN_own_filter;
166 <li> #Memory_mainboard_address_CAN_common_filter;
167<!-- Preamplifier information -->
168 <li> #Memory_mainboard_preamplifier_address_SN_0;
169 <li> #Memory_mainboard_preamplifier_address_SN_1;
170 <li> #Memory_mainboard_preamplifier_address_SN_2;
171 <li> #Memory_mainboard_preamplifier_address_SN_3;
172 <li> #Memory_mainboard_preamplifier_address_SN_4;
173 <li> #Memory_mainboard_preamplifier_address_SN_5;
174<!-- Copy of the detector trimmer slopes for ch0 -->
175 <li> #Memory_mainboard_det_coa_slope_cali_ON_0_OFF_ff_ch0;
176 <li> #Memory_mainboard_det_positive_ad_coarse_trim_slope_bias_ch0;
177 <li> #Memory_mainboard_det_negative_ad_coarse_trim_slope_bias_ch0;
178 <li> #Memory_mainboard_det_fin_slope_cali_ON_0_OFF_ff_ch0;
179 <li> #Memory_mainboard_det_positive_ad_fine_trim_slope_bias_ch0;
180 <li> #Memory_mainboard_det_negative_ad_fine_trim_slope_bias_ch0;
181<!-- Copy of the detector trimmer slopes for ch1 -->
182 <li> #Memory_mainboard_det_coa_slope_cali_ON_0_OFF_ff_ch1;
183 <li> #Memory_mainboard_det_positive_ad_coarse_trim_slope_bias_ch1;
184 <li> #Memory_mainboard_det_negative_ad_coarse_trim_slope_bias_ch1;
185 <li> #Memory_mainboard_det_fin_slope_cali_ON_0_OFF_ff_ch1;
186 <li> #Memory_mainboard_det_positive_ad_fine_trim_slope_bias_ch1;
187 <li> #Memory_mainboard_det_negative_ad_fine_trim_slope_bias_ch1;
188<!-- Copy of the detector trimmer slopes for ch2 -->
189 <li> #Memory_mainboard_det_coa_slope_cali_ON_0_OFF_ff_ch2;
190 <li> #Memory_mainboard_det_positive_ad_coarse_trim_slope_bias_ch2;
191 <li> #Memory_mainboard_det_negative_ad_coarse_trim_slope_bias_ch2;
192 <li> #Memory_mainboard_det_fin_slope_cali_ON_0_OFF_ff_ch2;
193 <li> #Memory_mainboard_det_positive_ad_fine_trim_slope_bias_ch2;
194 <li> #Memory_mainboard_det_negative_ad_fine_trim_slope_bias_ch2;
195<!-- Copy of the detector trimmer slopes for ch3 -->
196 <li> #Memory_mainboard_det_coa_slope_cali_ON_0_OFF_ff_ch3;
197 <li> #Memory_mainboard_det_positive_ad_coarse_trim_slope_bias_ch3;
198 <li> #Memory_mainboard_det_negative_ad_coarse_trim_slope_bias_ch3;
199 <li> #Memory_mainboard_det_fin_slope_cali_ON_0_OFF_ff_ch3;
200 <li> #Memory_mainboard_det_positive_ad_fine_trim_slope_bias_ch3;
201 <li> #Memory_mainboard_det_negative_ad_fine_trim_slope_bias_ch3;
202<!-- Copy of the detector trimmer slopes for ch4 -->
203 <li> #Memory_mainboard_det_coa_slope_cali_ON_0_OFF_ff_ch4;
204 <li> #Memory_mainboard_det_positive_ad_coarse_trim_slope_bias_ch4;
205 <li> #Memory_mainboard_det_negative_ad_coarse_trim_slope_bias_ch4;
206 <li> #Memory_mainboard_det_fin_slope_cali_ON_0_OFF_ff_ch4;
207 <li> #Memory_mainboard_det_positive_ad_fine_trim_slope_bias_ch4;
208 <li> #Memory_mainboard_det_negative_ad_fine_trim_slope_bias_ch4;
209<!-- Copy of the detector trimmer slopes for ch5 -->
210 <li> #Memory_mainboard_det_coa_slope_cali_ON_0_OFF_ff_ch5;
211 <li> #Memory_mainboard_det_positive_ad_coarse_trim_slope_bias_ch5;
212 <li> #Memory_mainboard_det_negative_ad_coarse_trim_slope_bias_ch5;
213 <li> #Memory_mainboard_det_fin_slope_cali_ON_0_OFF_ff_ch5;
214 <li> #Memory_mainboard_det_positive_ad_fine_trim_slope_bias_ch5;
215 <li> #Memory_mainboard_det_negative_ad_fine_trim_slope_bias_ch5;
216<!-- Last used memory -->
217 <li> #Memory_mainboard_last_memory_used_first_free.
218
219\anchor postmainboard_memory_location_list
220\section location_list_postmainboard The list of locations of the post-mainboard EPROM adrress
221<hr width="100%" size="20" align="left">
222
223\n Here the list of the locations of post-mainboard EPROM, remember to multiply by 4, or <<2, the bullet number
224to set the actual address, an unsigned int:
225
226<ol start="0">
227 <li> #Memory_postmainboard_address_SN;
228<!-- CAN addresses -->
229 <li> #Memory_postmainboard_address_fw;
230 <li> #Memory_postmainboard_address_CAN_own_filter;
231 <li> #Memory_postmainboard_address_CAN_common_filter;
232 <li> #Memory_postmainboard_CAN_from_hw_switch_1_from_EPROM_0;
233<!-- Preamplifier information -->
234 <li> #Memory_postmainboard_preamplifier_address_SN_0;
235 <li> #Memory_postmainboard_preamplifier_address_SN_1;
236 <li> #Memory_postmainboard_preamplifier_address_SN_2;
237 <li> #Memory_postmainboard_preamplifier_address_SN_3;
238 <li> #Memory_postmainboard_preamplifier_address_SN_4;
239 <li> #Memory_postmainboard_preamplifier_address_SN_5;
240<!-- Power ON/OFF of micro-controller and ADCs -->
241 <li> #Memory_postmainboard_micro_powdown_active_1_alwaysON_0;
242 <li> #Memory_postmainboard_ADCs_always_ON_0_powerdown_1;
243 <li> #Memory_postmainboard_micro_PD_wait_time_in_sec;
244<!-- Last used memory -->
245 <li> #Memory_postmainboard_last_memory_used_first_free.
246
247
248<!-- pappa -->
249*/
250
251#include "tutti_gli_header.h"
252
253//Inizio CROSS
254
255//enum canali_eprom{
256// canale1,
257// canale2,
258// canale3,
259// canale4,
260// canale6,
261// Canale_Eprom_mainboard};
262
263/*! \brief This is the structure from which the I2C addressess and the I2C of the
264preamplifier and frontend board are located
265*/
267// uint8_t quale_I2C;
268// uint8_t indirizzo_I2C
274 I2C_mux_abilita_2,EPROM_I2C_addres_memory_ch_dispari,//< Address of the memroies on the preamplifiers, 32k bits
275 I2C_mux_abilita_3, EPROM_mainboard_I2C_addres, //< Address of the memoies onboard, this is a 32k bits
276 I2C_mux_abilita_3, EPROM_postmainboard_I2C_addres, //< Address of the memoies onboard, this is a 32k bits
277 I2C_mux_abilita_3, EPROM_postmainboard_I2C_addres}; //< Address of the memoies onboard, this is a 32k bits
278
279
280/*! \brief CAN insrtuction to Read from preamplifier, on-board and post frontend board EPROM
281
282*\return No Parameters
283\showrefby
284\showrefs
285*\snippet{lineno} Memoria_pre_M24CCXX.c fun_instr_EPROM_read_write_function
286 */
287//! <!-- [fun_instr_EPROM_read_write_function] -->
289 uint16_t indirizzo_memoria= *(uint16_t *)tx_data;
290 uint8_t quale_memoria = (tx_data[6]>>3) & 3;
291 uint8_t Write_read = (tx_data[6] >>5) &1;
292 uint8_t canale,quale_canale = (tx_data[6] & 7) ;
293 uint8_t scheda_su_scheda_giu = ((tx_data[6]>>7) & 1)*6;
294 uint8_t dati_letti[4],canale_da_usare;
295 #define preamplifier_memory 0
296 #define mainboard_memory 1
297 #define postfronend_memory 2
298 ERROR_codifica_errore(0,0,0,0); //Reset_ch0 errori
299 switch (quale_memoria){
300 case preamplifier_memory: //Preamplifier
301// for(canale=0;canale<6;canale++){
302// if( (quale_canale >> canale ) & 1 ) break;
303// }
304// canale = (1 << quale_canale) & 0x3F;
305 canale = quale_canale;
306 if( Write_read==0){
307 //Lettura
308 EPROM_lettura_M24C32_64( scheda_su_scheda_giu, I2C_mainboard, canale, indirizzo_memoria , &tx_data[2]);
309// *(uint32_t *)&tx_data[2] = *(uint32_t *)dati_letti ;
310 }else{
311 //scrittura
312 EPROM_scrittura_M24C32_64( scheda_su_scheda_giu, I2C_mainboard, canale, indirizzo_memoria , (uint8_t *) &rx_data[2]);
313 }
314 break;
315 case mainboard_memory: //Mainboard A memory
316 if( Write_read==0){
317 //Lettura
318 EPROM_lettura_M24C32_64( scheda_su_scheda_giu, I2C_mainboard, Canale_Eprom_mainboard, indirizzo_memoria , &tx_data[2]);
319// *(uint32_t *)&tx_data[2] = *(uint32_t *)dati_letti ;
320 }else{
321 //scrittura
322 EPROM_scrittura_M24C32_64( scheda_su_scheda_giu, I2C_mainboard, Canale_Eprom_mainboard, indirizzo_memoria , (uint8_t *) &rx_data[2]);
323 }
324 break;
325 case postfronend_memory://mainboard B memory
326 if (scheda_su_scheda_giu == I2C_mux_Scheda_giu){
327 canale_da_usare= Canale_EPROM_postmainboard_down;
328 }else if (scheda_su_scheda_giu >= I2C_mux_Scheda_su){
329 canale_da_usare=Canale_EPROM_postmainboard_up;
330 }
331 if( Write_read==0){
332 //Lettura
333 EPROM_lettura_M24C32_64( scheda_su_scheda_giu, I2C_postmainboard, canale_da_usare, indirizzo_memoria , &tx_data[2]);
334// *(uint32_t *)&tx_data[2] = *(uint32_t *)dati_letti ;
335 }else{
336 //scrittura
337 EPROM_scrittura_M24C32_64( scheda_su_scheda_giu, I2C_postmainboard, canale_da_usare, indirizzo_memoria , (uint8_t *) &rx_data[2]);
338 }
339 break;
340 }
342 if(flag_error_verified){
343 if( tx_data[0]==255){
344 tx_data[0]=250;
345 }else{
346 tx_data[0]= 255;
347 }
348 }
349}
350//! <!-- [fun_instr_EPROM_read_write_function] -->
351
352
353/*! \brief Read from preamplifier and on-board flashes
354
355\param[in] scheda_su_scheda_giu
356\param[in] canale
357\param[in] indirizzo_memoria
358\param[out] *dati_letti (4 bytes)
359*\return No Parameters
360\showrefby
361\showrefs
362*\snippet{lineno} Memoria_pre_M24CCXX.c fun_EPROM_lettura_M24C08_16
363 */
364//! <!-- [fun_EPROM_lettura_M24C08_16] -->
365void EPROM_lettura_M24C08_16(uint8_t scheda_su_scheda_giu,enum canali_eprom canale, short indirizzo_memoria , uint8_t *dati_letti){
366 uint8_t indirizzi_I2C=EPROM_address[canale].indirizzo_I2C;
367 indirizzo_memoria = indirizzo_memoria & 0xFFFC; //4 bytes at a time and composed of 2 bytes
368 dati_letti[0]= (indirizzo_memoria & 0xFF); //first 2 bytes are the 8 LSB bits sent as data
369 indirizzi_I2C |= (indirizzo_memoria & 0x300)>>8 ; //I primi 2 bit nel secondo byte sono indirizzo
370 //Memory read
371 I2C_mux_select_ch( scheda_su_scheda_giu_provvisorio, I2C_mainboard, EPROM_address[canale].quale_I2C);
372 I2CBdrv->MasterTransmit (indirizzi_I2C, dati_letti , 1, false); //Scriviamo l'indirizzo iniziale
373 while (I2CBdrv->GetStatus().busy);
374
375 I2CBdrv-> MasterReceive (indirizzi_I2C, dati_letti, 4, false); //Ora leggiamo
376 while (I2CBdrv->GetStatus().busy);
377 I2C_mux_select_ch( scheda_su_scheda_giu_provvisorio, I2C_mainboard, I2C_mux_disabilita_tutto);
378
379}
380//! <!-- [fun_EPROM_lettura_M24C08_16] -->
381
382
383/*! \brief Wriring the EEPROM
384
385\param[in] scheda_su_scheda_giu
386\param[in] canale
387\param[in] indirizzo_memoria
388\param[in] *dati_da_scrivere
389*\return No Parameters
390 \showrefby
391 \showrefs
392*\snippet{lineno} Memoria_pre_M24CCXX.c fun_EPROM_scrittura_M24C08_16
393 */
394//! <!-- [fun_EPROM_scrittura_M24C08_16] -->
395void EPROM_scrittura_M24C08_16(uint8_t scheda_su_scheda_giu, enum canali_eprom canale, short indirizzo_memoria , uint8_t *dati_da_scrivere){
396
397 uint8_t Indirizzo_I2C_effettivo = (indirizzo_memoria & 0x3FF) >>8 ; //< The 2 MSB of the address memory are the
398 //first 2 bits of the I2C address
399 uint8_t indirizzo_memoria_8LSB= indirizzo_memoria & 0xFF;
400 uint8_t dati_da_spedire[5];
401
402 dati_da_spedire[0]=indirizzo_memoria_8LSB; //< this is the 8 LSB of the memory address
403 dati_da_spedire[1]=dati_da_scrivere[0]; //<First data to store
404 dati_da_spedire[2]=dati_da_scrivere[1]; //<Second data to store
405 dati_da_spedire[3]=dati_da_scrivere[2]; //<Third data to store
406 dati_da_spedire[4]=dati_da_scrivere[3]; //<Fourth data to store
407
408 Indirizzo_I2C_effettivo += EPROM_address[canale].indirizzo_I2C;
409
410 I2C_mux_select_ch( scheda_su_scheda_giu_provvisorio, I2C_mainboard, EPROM_address[canale].quale_I2C);
411 I2CBdrv->MasterTransmit (Indirizzo_I2C_effettivo, dati_da_spedire , 5, false); //Scriviamo l'indirizzo iniziale
412 while (I2CBdrv->GetStatus().busy);
413 Aspetta_tanti_ms(10); //Attenzione, se non si temporeggia qui si blocca tutto.
414 I2C_mux_select_ch( scheda_su_scheda_giu_provvisorio, I2C_mainboard, I2C_mux_disabilita_tutto);
415
416}
417//! <!-- [fun_EPROM_scrittura_M24C08_16] -->
418
419
420/*! \brief Wriring the EEPROM
421
422\param[in] scheda_su_scheda_giu
423\param[in] mainboard_postmainboard for selecting the I2C mux on mainboard, if I2C_mainboard,
424 or postmainboard, if I2C_postmainboard
425\param[in] canale
426\param[in] indirizzo_memoria
427\param[in] *dati_da_scrivere
428
429\return No Parameters
430 \showrefby
431 \showrefs
432*\snippet{lineno} Memoria_pre_M24CCXX.c fun_EPROM_scrittura_M24C32_64
433 */
434//! <!-- [fun_EPROM_scrittura_M24C32_64] -->
435void EPROM_scrittura_M24C32_64(uint8_t scheda_su_scheda_giu, uint8_t mainboard_postmainboard, uint8_t canale, short indirizzo_memoria , uint8_t *dati_da_scrivere){
436
437// uint8_t Indirizzo_I2C_effettivo = (indirizzo_memoria & 0x3FF) >>8 ; //< The 2 MSB of the address memory are the
438 //first 2 bits of the I2C address
439// uint8_t indirizzo_memoria_8LSB= indirizzo_memoria & 0xFF;
440 uint8_t dati_da_spedire[6], tampone_qui=100, error_I2C;
441
442 dati_da_spedire[1]=indirizzo_memoria & 0xFF; //< this is the 8 LSb of the memory address
443 dati_da_spedire[0]=( indirizzo_memoria >> 8) & 0xFF; //< this is the 8 MSb of the memory address
444 dati_da_spedire[2]=dati_da_scrivere[0]; //<First data to store
445 dati_da_spedire[3]=dati_da_scrivere[1]; //<Second data to store
446 dati_da_spedire[4]=dati_da_scrivere[2]; //<Third data to store
447 dati_da_spedire[5]=dati_da_scrivere[3]; //<Fourth data to store
448
449// Indirizzo_I2C_effettivo += EPROM_address[canale].indirizzo_I2C;
450 if(mainboard_postmainboard == I2C_mainboard){ //memoria su postmainboard o mainboard
451 tampone_qui=I2C_mainboard;
452 error_I2C= error_address_I2C1;
453 }else if (mainboard_postmainboard == I2C_postmainboard){
454 tampone_qui=I2C_postmainboard;
455 error_I2C= error_address_I2C0;
456 }
457 if (tampone_qui<100){
458 I2C_mux_select_ch( scheda_su_scheda_giu, tampone_qui, EPROM_address[canale].quale_I2C);
459 I2C_mux->MasterTransmit (EPROM_address[canale].indirizzo_I2C, dati_da_spedire , 6, false); //Scriviamo l'indirizzo iniziale
460 while (I2C_mux->GetStatus().busy);
461 if(Error_bad_operation) ERROR_codifica_errore( scheda_su_scheda_giu, error_I2C , I2C_error_EPROM_0 + canale , 1 );
462 Aspetta_tanti_ms(10); //Attenzione, se non si temporeggia qui si blocca tutto.
463 I2C_mux_select_ch( scheda_su_scheda_giu, tampone_qui, I2C_mux_disabilita_tutto);
464 }
465}
466//! <!-- [fun_EPROM_scrittura_M24C32_64] -->
467
468
469/*! \brief Read from preamplifier and on-board flashes
470
471\param[in] scheda_su_scheda_giu_ : the selected board
472\param[in] mainboard_postmainboard : memory read from mainboard, if I2C_mainboard, or postamainboard, if I2C_mainboard
473\param[in] canale : the selected channel
474\param[in] indirizzo_memoria : memory address
475\param[out] *dati_letti : the 4 read bytes
476
477*\return No Parameters
478\showrefby
479\showrefs
480*\snippet{lineno} Memoria_pre_M24CCXX.c fun_EPROM_lettura_M24C32_64
481 */
482//! <!-- [fun_EPROM_lettura_M24C32_64] -->
483void EPROM_lettura_M24C32_64(uint8_t scheda_su_scheda_giu_, uint8_t mainboard_postmainboard, uint8_t canale, \
484 short indirizzo_memoria , uint8_t *dati_letti){
485 uint8_t tampone_qui=100,error_I2C;
486// uint8_t indirizzi_I2C=EPROM_address[canale].indirizzo_I2C;
487// indirizzo_memoria = indirizzo_memoria & 0xFFFC; //4 bytes at a time and composed of 2 bytes
488 dati_letti[1]= (indirizzo_memoria & 0xFF); //first 2 bytes are the 8 LSB bits sent as data
489 dati_letti[0]=( (indirizzo_memoria >> 8) & 0xFF); //first 2 bytes are the 8 LSB bits sent as data
490
491// indirizzi_I2C |= (indirizzo_memoria & 0x300)>>8 ; //I primi 2 bit nel secondo byte sono indirizzo
492
493 if(mainboard_postmainboard == I2C_mainboard){ //memoria su postmainboard o mainboard
494 tampone_qui=I2C_mainboard;
495 error_I2C =error_address_I2C1 ;
496 }else if (mainboard_postmainboard == I2C_postmainboard){
497 tampone_qui=I2C_postmainboard;
498 error_I2C = error_address_I2C0 ;
499 }
500 if (tampone_qui<100){ //Memory read
501 I2C_mux_select_ch( scheda_su_scheda_giu_, tampone_qui, EPROM_address[canale].quale_I2C);
502 I2C_mux->MasterTransmit (EPROM_address[canale].indirizzo_I2C, dati_letti , 2, false); //Scriviamo l'indirizzo iniziale
503 while (I2C_mux->GetStatus().busy);
504 if(Error_bad_operation) ERROR_codifica_errore( scheda_su_scheda_giu, error_I2C , I2C_error_EPROM_0 + canale , 1 );
505 I2C_mux-> MasterReceive (EPROM_address[canale].indirizzo_I2C, dati_letti, 4, false); //Ora leggiamo
506 while (I2C_mux->GetStatus().busy);
507 I2C_mux_select_ch( scheda_su_scheda_giu_, tampone_qui, I2C_mux_disabilita_tutto);
508 if(Error_bad_operation) ERROR_codifica_errore( scheda_su_scheda_giu, error_I2C , I2C_error_EPROM_0 + canale , 1 );
509 }
510
511}
512//! <!-- [fun_EPROM_lettura_M24C32_64] -->
513
514
515/*! \brief Store the system state or recover and apply the system state
516
517\param[in] scheda_su_scheda_giu
518\param[in] canali_da_regolare the channels to be worked out, 1= yes, 0=no. Ex: 101001= ch 0, ch 3 and ch 5 are worked.
519\param[in] set_1_store_0 store the system state in memory, if 1, recover and apply the stored setup, if 0
520\param[out] startup_1_user_0 store/recover from the startup, if 1, or from the user location, if 0
521*\return No Parameters
522\showrefby
523\showrefs
524*\snippet{lineno} Memoria_pre_M24CXX.c fun_EPROM_store_recover_state_M24C32_64
525 */
526//! [fun_EPROM_store_recover_state_M24C32_64]
527void EPROM_store_recover_state_M24C32_64(uint8_t scheda_su_scheda_giu,uint8_t canali_da_regolare, \
528uint8_t set_1_store_0 , uint8_t startup_1_user_0){
529
530 uint8_t dati_da_leggere[4],ii_,canale,dati_da_scrivere[]={0,0,0,0},esegui=0;
531 uint16_t memoria_per_trimmer, memoria_per_abilitazione, memoria_per_relay_PGA,memoria_per_detector_trimmer;
532 if(scheda_su_scheda_giu) scheda_su_scheda_giu=6;
533
534 if( startup_1_user_0){
535 memoria_per_abilitazione=Memory_preamplifier_startup_offset_trimmer_ON_0_OFF_ff <<2 ;
536 memoria_per_trimmer=Memory_preamplifier_startup_offset_trimmer <<2;
537 memoria_per_relay_PGA=0;
538 esegui=1;
539 }else if(startup_1_user_0 ==0){
540 memoria_per_abilitazione=Memory_preamplifier_user_offset_trimmer_ON_0_OFF_ff <<2;
541 memoria_per_trimmer=Memory_preamplifier_user_offset_trimmer <<2;
542 memoria_per_detector_trimmer=Memory_preamplifier_user_detector_trimmer;
543 memoria_per_relay_PGA = Memory_preamplifier_user_detector_and_gain <<2;
544 esegui=1;
545 }
546
547 if ((set_1_store_0 ==0) && esegui){ //Quindi scriviamo
548 for(canale=0;canale<6;canale++){
549 if((canali_da_regolare >> canale) &1 ){
550 EPROM_scrittura_M24C32_64(scheda_su_scheda_giu, I2C_mainboard,canale,\
551 memoria_per_abilitazione , dati_da_scrivere);
552 EPROM_scrittura_M24C32_64(scheda_su_scheda_giu, I2C_mainboard, canale,\
553 memoria_per_trimmer , (uint8_t *)&contenuto_trimmer_preamplifier[canale+scheda_su_scheda_giu]);
554 if (memoria_per_relay_PGA){
555 dati_da_scrivere[0]= detector_Relay_state[scheda_su_scheda_giu + canale];
556 dati_da_scrivere[1]= PGA_settled_gain[scheda_su_scheda_giu+canale];
557 dati_da_scrivere[2]= 0;
558 dati_da_scrivere[3]= 0;
559 EPROM_scrittura_M24C32_64(scheda_su_scheda_giu, I2C_mainboard,canale, \
560 memoria_per_relay_PGA , dati_da_scrivere);
561 dati_da_scrivere[0]= 0;
562 dati_da_scrivere[1]= 0;
563 EPROM_scrittura_M24C32_64(scheda_su_scheda_giu, I2C_mainboard,canale,\
564 memoria_per_detector_trimmer , (uint8_t *)&contenuto_trimmer_detector[canale+scheda_su_scheda_giu]);
565 }
566 }
567 }
568 }
569
570 if (set_1_store_0 && esegui){ //Quindi recuperiamo ed applichiamo o stato
571 for(canale=0;canale<6;canale++){
572 if((canali_da_regolare >> canale) &1 ){
573 EPROM_lettura_M24C32_64(scheda_su_scheda_giu, I2C_mainboard, canale, \
574 memoria_per_abilitazione , dati_da_leggere);
575 if(*(uint32_t *)dati_da_leggere ==0){
576 EPROM_lettura_M24C32_64(scheda_su_scheda_giu, I2C_mainboard, canale, \
577 memoria_per_trimmer , dati_da_leggere);
578 for(ii_=0;ii_<4;ii_++){
579 preamplifier_scrittura_lettura_trimmer( scheda_su_scheda_giu, canale, ii_, \
580 dati_da_leggere[ii_], preamplifier_scrivi_il_trimmer );
581 }
582 if(memoria_per_relay_PGA){
583 EPROM_lettura_M24C32_64(scheda_su_scheda_giu, I2C_mainboard, canale, \
584 memoria_per_relay_PGA , dati_da_leggere);
585 PGA_GAIN_CROSS( scheda_su_scheda_giu, canale, dati_da_leggere[1] );
586 for(ii_=0;ii_<7;ii_++){
587 if( (dati_da_leggere[0] >> ii_) & 1){
588 Relays_driver_set_reset_channel(scheda_su_scheda_giu,canale, (1<<ii_));
589 }
590 }
591 EPROM_lettura_M24C32_64(scheda_su_scheda_giu, I2C_mainboard, canale, \
592 memoria_per_detector_trimmer , dati_da_leggere);
593 for(ii_=0;ii_<4;ii_++){
594 detector_scrittura_lettura_trimmer_bias( scheda_su_scheda_giu, canale, ii_, \
595 dati_da_leggere[ii_], preamplifier_scrivi_il_trimmer );
596 }
597 }
598 }
599 }
600 }
601
602 }
603}
604//! [fun_EPROM_store_recover_state_M24C32_64]
605
606
607//************************** questa è in costruzione ************************************
608
609/*! \brief Store or load the detector bias trimmer content
610
611\param[in] scheda_su_scheda_giu
612\param[in] canali_da_regolare the channels to be worked out, 1= yes, 0=no. Ex: 101001= ch 0, ch 3 and ch 5 are worked.
613\param[in] set_1_store_0 store the system state in memory, if 1, recover and apply the stored setup, if 0
614\param[out] startup_1_user_0 store/recover from the startup, if 1, or from the user location, if 0
615*\return No Parameters
616\showrefby
617\showrefs
618*\snippet{lineno} Memoria_pre_M24CXX.c fun_EPROM_store_recover_detector_voltage_M24C32_64
619 */
620//! [fun_EPROM_store_recover_detector_voltage_M24C32_64]
621void EPROM_store_recover_detector_voltage_M24C32_64(uint8_t scheda_su_scheda_giu,uint8_t canali_da_regolare, \
622uint32_t voltage_integer ,uint8_t set_1_store_0 ){
623
624 uint8_t dati_da_leggere[4],ii_,canale,dati_da_scrivere[]={0,0,0,0};
625 uint16_t memoria_per_trimmer, memoria_per_abilitazione, memoria_per_relay_PGA,memoria_per_detector_trimmer;
626 uint8_t valori_per_canale=51; //Valori da memorizzare, da 0 V a 50 V
627
628 voltage_integer = voltage_integer /1000; //Bias trasformato in intero
629
630 if(scheda_su_scheda_giu) scheda_su_scheda_giu=6;
631
632 memoria_per_abilitazione=Memory_mainboard_det_chan_0_0V + voltage_integer ; //A questo va aggiunto valori_per_canale x canale
633
634
635 if ((set_1_store_0 ==0) ){ //Quindi scriviamo in memoria
636 for(canale=0;canale<6;canale++){
637 if((canali_da_regolare >> canale) &1 ){
638 memoria_per_abilitazione += canale * valori_per_canale;
639 EPROM_scrittura_M24C32_64(scheda_su_scheda_giu, I2C_mainboard, canale,\
640 memoria_per_abilitazione << 2 , (uint8_t *)&contenuto_trimmer_detector[canale+scheda_su_scheda_giu]);
641 }
642 }
643 }
644
645 if (set_1_store_0 ){ //Quindi recuperiamo ed applichiamo o stato
646 for(canale=0;canale<6;canale++){
647 if((canali_da_regolare >> canale) &1 ){
648 memoria_per_abilitazione += canale * valori_per_canale;
649 EPROM_lettura_M24C32_64(scheda_su_scheda_giu, I2C_mainboard, canale, \
650 memoria_per_abilitazione , dati_da_leggere);
651
652 for(ii_=0;ii_<4;ii_++){
653 detector_scrittura_lettura_trimmer_bias( scheda_su_scheda_giu, canale, ii_, \
654 dati_da_leggere[ii_], preamplifier_scrivi_il_trimmer );
655 }
656 }
657 }
658
659 }
660}
661//! [fun_EPROM_store_recover_detector_voltage_M24C32_64]
662
663
664/*! \brief Preamplifier memory contents regarding detector trimmer slopes are restored from mainboard memory.
665This is a patch: the storing of these data in the preamplifier memoery is unnecessary, but it was done and used from there.
666So now the content of the preamplifier memory is done also in the mainboard memory at the time of the slopes measurements.
667These data are restored in the preamplifier memory at startup so that if the preamplifier is changed or swapped the slopes are not lost.
668
669\param[in] scheda_su_scheda_giu : which mmainboard
670\param[in] canale : the channel to where data are copied
671
672*\return No Parameters
673\showrefby
674\showrefs
675*\snippet{lineno} Memoria_pre_M24CXX.c fun_EPROM_copy_restore_detector_slopes
676 */
677//! [fun_EPROM_copy_restore_detector_slopes]
678void EPROM_restore_detector_slopes_in_pream( uint8_t scheda_su_scheda_giu , uint8_t canale){
679 uint8_t dati_da_scrivere[4], iii;
680
681 //Data cells to restore are 6.
682
683 for(iii=0;iii<6;iii++){
684
685 EPROM_lettura_M24C32_64(scheda_su_scheda_giu, I2C_mainboard, Canale_Eprom_mainboard, \
686 ((Memory_mainboard_det_coa_slope_cali_ON_0_OFF_ff_ch0 +6*canale + iii)<<2) , dati_da_scrivere);
687
688 EPROM_scrittura_M24C32_64( scheda_su_scheda_giu, I2C_mainboard, canale, \
689 (Memory_detector_coarse_slope_calibration_ON_0_OFF_ff + iii)<<2 , dati_da_scrivere);
690
691 }
692
693
694}
695//! [fun_EPROM_copy_restore_detector_slopes]
696
697//fine cross
uint8_t tx_data[8]
Transmission data vector.
Definition: Can.c:321
volatile uint8_t rx_data[8]
Received data vector.
Definition: Can.c:318
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 PGA_settled_gain[12]
PGA set gain.
Definition: DAC_PGA.c:95
uint8_t detector_Relay_state[12]
The state of the Detector realis is considerede. Note that this is the wanted working condition....
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,...
void Error_imposta_la_istruzione(void)
Function to be located at the end of every instruction to mark the error, if any.
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.
@ I2C_error_EPROM_0
EPROM ch0.
@ error_address_I2C0
Error register A for I2C0.
@ error_address_I2C1
Error register A for I2C1
void I2C_mux_select_ch(uint8_t scheda_su_scheda_giu, uint8_t mainboard_postmainboard, uint8_t canale_da_abilitare)
The I2C mux.
Definition: I2C_mux.c:100
#define I2C_mux_disabilita_tutto
i2C transmission/reception was bad
Definition: I2C_mux.h:24
#define I2C_mux_abilita_2
Enable channel 2.
Definition: I2C_mux.h:27
#define I2C_mux_abilita_1
Enable channel 1.
Definition: I2C_mux.h:26
#define I2C_mux_abilita_3
Enable channel 3.
Definition: I2C_mux.h:28
#define I2C_mux_Scheda_giu
Selection of the I2C1 for lower board (purtroppo \'e contorto)
Definition: I2C_mux.h:16
#define I2C_mux_abilita_0
Enable channel 0.
Definition: I2C_mux.h:25
#define I2C_mux_Scheda_su
Selection of the I2C0 for the upper board (purtroppo \'e contorto)
Definition: I2C_mux.h:15
void EPROM_scrittura_M24C08_16(uint8_t scheda_su_scheda_giu, enum canali_eprom canale, short indirizzo_memoria, uint8_t *dati_da_scrivere)
Wriring the EEPROM.
void EPROM_store_recover_detector_voltage_M24C32_64(uint8_t scheda_su_scheda_giu, uint8_t canali_da_regolare, uint32_t voltage_integer, uint8_t set_1_store_0)
[fun_EPROM_store_recover_state_M24C32_64]
void EPROM_lettura_M24C32_64(uint8_t scheda_su_scheda_giu_, uint8_t mainboard_postmainboard, uint8_t canale, short indirizzo_memoria, uint8_t *dati_letti)
Read from preamplifier and on-board flashes.
void EPROM_scrittura_M24C32_64(uint8_t scheda_su_scheda_giu, uint8_t mainboard_postmainboard, uint8_t canale, short indirizzo_memoria, uint8_t *dati_da_scrivere)
Wriring the EEPROM.
void instr_EPROM_read_write_function(void)
CAN insrtuction to Read from preamplifier, on-board and post frontend board EPROM.
void EPROM_store_recover_state_M24C32_64(uint8_t scheda_su_scheda_giu, uint8_t canali_da_regolare, uint8_t set_1_store_0, uint8_t startup_1_user_0)
Store the system state or recover and apply the system state.
void EPROM_lettura_M24C08_16(uint8_t scheda_su_scheda_giu, enum canali_eprom canale, short indirizzo_memoria, uint8_t *dati_letti)
Read from preamplifier and on-board flashes.
void EPROM_restore_detector_slopes_in_pream(uint8_t scheda_su_scheda_giu, uint8_t canale)
[fun_EPROM_store_recover_detector_voltage_M24C32_64]
const struct address_detector_bias_trimmer_type EPROM_address[9]
This is the structure from which the I2C addressess and the I2C of the preamplifier and frontend boar...
@ Memory_mainboard_det_coa_slope_cali_ON_0_OFF_ff_ch0
slope detector positive trimmer active if zero
@ Memory_mainboard_det_chan_0_0V
fine slope for detector negative trimmer bias
#define EPROM_I2C_addres_memory_ch_pari
I2C address of channle 0, 2 and 4.
canali_eprom
Refer to these definitions for using the channels during eprom R/W.
@ Memory_preamplifier_user_detector_trimmer
detector trimmer content is stored here
@ Memory_preamplifier_startup_offset_trimmer
startup offset trimmer active if zero
@ Memory_preamplifier_user_offset_trimmer_ON_0_OFF_ff
user offset trimmer active if zero
@ Memory_preamplifier_startup_offset_trimmer_ON_0_OFF_ff
startup offset trimmer active if zero
@ Memory_preamplifier_user_offset_trimmer
startup offset trimmer active if zero
@ Memory_detector_coarse_slope_calibration_ON_0_OFF_ff
slope detector positive trimmer active if zero
@ Memory_preamplifier_user_detector_and_gain
detectro setup anf PGA gain at user location
#define EPROM_I2C_addres_memory_ch_dispari
I2C address of channle 1, 3 and 5.
#define EPROM_mainboard_I2C_addres
#define preamplifier_scrivi_il_trimmer
void Aspetta_tanti_ms(int millisecondi)
The timing function.
Definition: Timer.c:52
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
uint8_t volatile contenuto_trimmer_preamplifier[12][4]
Definition: Trimmer.c:179
void preamplifier_scrittura_lettura_trimmer(uint8_t scheda_su_scheda_giu, uint8_t canale, uint8_t trimmer, uint8_t valore, uint8_t scrivi_1_leggi_0)
Setting the value of any trimmer for preamplifier trimmer, the contents of the trimmers are stored in...
Definition: Trimmer.c:283
Coordinates for the preamplifier and onboard EPROMs.
Definition: Trimmer.h:97