|
73 | 73 | #include "peripheral_clk_config.h"
|
74 | 74 |
|
75 | 75 | #define ADC_TEMP_SAMPLE_LENGTH 4
|
76 |
| -#define INT1V_VALUE_FLOAT 1.0 |
77 |
| -#define INT1V_DIVIDER_1000 1000.0 |
78 |
| -#define ADC_12BIT_FULL_SCALE_VALUE_FLOAT 4095.0 |
| 76 | +#define INT1V_VALUE_FLOAT MICROPY_FLOAT_CONST(1.0) |
| 77 | +#define INT1V_DIVIDER_1000 MICROPY_FLOAT_CONST(1000.0) |
| 78 | +#define ADC_12BIT_FULL_SCALE_VALUE_FLOAT MICROPY_FLOAT_CONST(4095.0) |
79 | 79 |
|
80 | 80 | // channel argument (ignored in calls below)
|
81 | 81 | #define IGNORED_CHANNEL 0
|
82 | 82 |
|
83 |
| -// Decimal to fraction conversion. (adapted from ASF sample). |
84 |
| -STATIC float convert_dec_to_frac(uint8_t val) { |
85 |
| - float float_val = (float)val; |
86 |
| - if (val < 10) { |
87 |
| - return float_val / 10.0; |
88 |
| - } else if (val < 100) { |
89 |
| - return float_val / 100.0; |
90 |
| - } else { |
91 |
| - return float_val / 1000.0; |
92 |
| - } |
93 |
| -} |
94 | 83 |
|
95 | 84 | // Extract the production calibration data information from NVM (adapted from ASF sample),
|
96 | 85 | // then calculate the temperature
|
97 | 86 | #ifdef SAMD21
|
98 | 87 | STATIC float calculate_temperature(uint16_t raw_value) {
|
99 |
| - volatile uint32_t val1; /* Temperature Log Row Content first 32 bits */ |
100 |
| - volatile uint32_t val2; /* Temperature Log Row Content another 32 bits */ |
101 |
| - uint8_t room_temp_val_int; /* Integer part of room temperature in °C */ |
102 |
| - uint8_t room_temp_val_dec; /* Decimal part of room temperature in °C */ |
103 |
| - uint8_t hot_temp_val_int; /* Integer part of hot temperature in °C */ |
104 |
| - uint8_t hot_temp_val_dec; /* Decimal part of hot temperature in °C */ |
105 |
| - int8_t room_int1v_val; /* internal 1V reference drift at room temperature */ |
106 |
| - int8_t hot_int1v_val; /* internal 1V reference drift at hot temperature*/ |
107 |
| - |
108 |
| - float tempR; // Production Room temperature |
109 |
| - float tempH; // Production Hot temperature |
110 |
| - float INT1VR; // Room temp 2's complement of the internal 1V reference value |
111 |
| - float INT1VH; // Hot temp 2's complement of the internal 1V reference value |
112 |
| - uint16_t ADCR; // Production Room temperature ADC value |
113 |
| - uint16_t ADCH; // Production Hot temperature ADC value |
114 |
| - float VADCR; // Room temperature ADC voltage |
115 |
| - float VADCH; // Hot temperature ADC voltage |
| 88 | + uint32_t val1; /* Temperature Log Row Content first 32 bits */ |
| 89 | + uint32_t val2; /* Temperature Log Row Content another 32 bits */ |
| 90 | + int room_temp_val_int; /* Integer part of room temperature in °C */ |
| 91 | + int room_temp_val_dec; /* Decimal part of room temperature in °C */ |
| 92 | + int hot_temp_val_int; /* Integer part of hot temperature in °C */ |
| 93 | + int hot_temp_val_dec; /* Decimal part of hot temperature in °C */ |
| 94 | + int room_int1v_val; /* internal 1V reference drift at room temperature */ |
| 95 | + int hot_int1v_val; /* internal 1V reference drift at hot temperature*/ |
116 | 96 |
|
117 | 97 | uint32_t *temp_log_row_ptr = (uint32_t *)NVMCTRL_TEMP_LOG;
|
118 | 98 |
|
119 | 99 | val1 = *temp_log_row_ptr;
|
120 | 100 | temp_log_row_ptr++;
|
121 | 101 | val2 = *temp_log_row_ptr;
|
122 | 102 |
|
123 |
| - room_temp_val_int = (uint8_t)((val1 & FUSES_ROOM_TEMP_VAL_INT_Msk) >> FUSES_ROOM_TEMP_VAL_INT_Pos); |
124 |
| - room_temp_val_dec = (uint8_t)((val1 & FUSES_ROOM_TEMP_VAL_DEC_Msk) >> FUSES_ROOM_TEMP_VAL_DEC_Pos); |
| 103 | + room_temp_val_int = ((val1 & FUSES_ROOM_TEMP_VAL_INT_Msk) >> FUSES_ROOM_TEMP_VAL_INT_Pos); |
| 104 | + room_temp_val_dec = ((val1 & FUSES_ROOM_TEMP_VAL_DEC_Msk) >> FUSES_ROOM_TEMP_VAL_DEC_Pos); |
125 | 105 |
|
126 |
| - hot_temp_val_int = (uint8_t)((val1 & FUSES_HOT_TEMP_VAL_INT_Msk) >> FUSES_HOT_TEMP_VAL_INT_Pos); |
127 |
| - hot_temp_val_dec = (uint8_t)((val1 & FUSES_HOT_TEMP_VAL_DEC_Msk) >> FUSES_HOT_TEMP_VAL_DEC_Pos); |
| 106 | + hot_temp_val_int = ((val1 & FUSES_HOT_TEMP_VAL_INT_Msk) >> FUSES_HOT_TEMP_VAL_INT_Pos); |
| 107 | + hot_temp_val_dec = ((val1 & FUSES_HOT_TEMP_VAL_DEC_Msk) >> FUSES_HOT_TEMP_VAL_DEC_Pos); |
128 | 108 |
|
| 109 | + // necessary casts: must interpret 8 bits as signed |
129 | 110 | room_int1v_val = (int8_t)((val1 & FUSES_ROOM_INT1V_VAL_Msk) >> FUSES_ROOM_INT1V_VAL_Pos);
|
130 | 111 | hot_int1v_val = (int8_t)((val2 & FUSES_HOT_INT1V_VAL_Msk) >> FUSES_HOT_INT1V_VAL_Pos);
|
131 | 112 |
|
132 |
| - ADCR = (uint16_t)((val2 & FUSES_ROOM_ADC_VAL_Msk) >> FUSES_ROOM_ADC_VAL_Pos); |
133 |
| - ADCH = (uint16_t)((val2 & FUSES_HOT_ADC_VAL_Msk) >> FUSES_HOT_ADC_VAL_Pos); |
| 113 | + int ADCR = ((val2 & FUSES_ROOM_ADC_VAL_Msk) >> FUSES_ROOM_ADC_VAL_Pos); |
| 114 | + int ADCH = ((val2 & FUSES_HOT_ADC_VAL_Msk) >> FUSES_HOT_ADC_VAL_Pos); |
134 | 115 |
|
135 |
| - tempR = room_temp_val_int + convert_dec_to_frac(room_temp_val_dec); |
136 |
| - tempH = hot_temp_val_int + convert_dec_to_frac(hot_temp_val_dec); |
| 116 | + int tempR = 10 * room_temp_val_int + room_temp_val_dec; |
| 117 | + int tempH = 10 * hot_temp_val_int + hot_temp_val_dec; |
137 | 118 |
|
138 |
| - INT1VR = 1 - ((float)room_int1v_val / INT1V_DIVIDER_1000); |
139 |
| - INT1VH = 1 - ((float)hot_int1v_val / INT1V_DIVIDER_1000); |
| 119 | + int INT1VR = 1000 - room_int1v_val; |
| 120 | + int INT1VH = 1000 - hot_int1v_val; |
140 | 121 |
|
141 |
| - VADCR = ((float)ADCR * INT1VR) / ADC_12BIT_FULL_SCALE_VALUE_FLOAT; |
142 |
| - VADCH = ((float)ADCH * INT1VH) / ADC_12BIT_FULL_SCALE_VALUE_FLOAT; |
| 122 | + int VADCR = ADCR * INT1VR; |
| 123 | + int VADCH = ADCH * INT1VH; |
143 | 124 |
|
144 |
| - float VADC; /* Voltage calculation using ADC result for Coarse Temp calculation */ |
145 |
| - float VADCM; /* Voltage calculation using ADC result for Fine Temp calculation. */ |
146 |
| - float INT1VM; /* Voltage calculation for reality INT1V value during the ADC conversion */ |
| 125 | + int INT1VM; /* Voltage calculation for reality INT1V value during the ADC conversion */ |
147 | 126 |
|
148 |
| - VADC = ((float)raw_value * INT1V_VALUE_FLOAT) / ADC_12BIT_FULL_SCALE_VALUE_FLOAT; |
| 127 | + int VADC = raw_value * 1000; |
149 | 128 |
|
150 | 129 | // Hopefully compiler will remove common subepxressions here.
|
151 | 130 |
|
152 | 131 | // calculate fine temperature using Equation1 and Equation
|
153 | 132 | // 1b as mentioned in data sheet section "Temperature Sensor Characteristics"
|
154 | 133 | // of Electrical Characteristics. (adapted from ASF sample code).
|
155 | 134 | // Coarse Temp Calculation by assume INT1V=1V for this ADC conversion
|
156 |
| - float coarse_temp = tempR + (((tempH - tempR) / (VADCH - VADCR)) * (VADC - VADCR)); |
| 135 | + int coarse_temp = tempR + (tempH - tempR) * (VADC - VADCR) / (VADCH - VADCR); |
157 | 136 |
|
158 | 137 | // Calculation to find the real INT1V value during the ADC conversion
|
159 | 138 | INT1VM = INT1VR + (((INT1VH - INT1VR) * (coarse_temp - tempR)) / (tempH - tempR));
|
160 | 139 |
|
161 |
| - VADCM = ((float)raw_value * INT1VM) / ADC_12BIT_FULL_SCALE_VALUE_FLOAT; |
| 140 | + int VADCM = raw_value * INT1VM; |
162 | 141 |
|
163 | 142 | // Fine Temp Calculation by replace INT1V=1V by INT1V = INT1Vm for ADC conversion
|
164 |
| - float fine_temp = tempR + (((tempH - tempR) / (VADCH - VADCR)) * (VADCM - VADCR)); |
| 143 | + float fine_temp = tempR + (((tempH - tempR) * (VADCM - VADCR)) / (VADCH - VADCR)); |
165 | 144 |
|
166 |
| - return fine_temp; |
| 145 | + return fine_temp / 10; |
167 | 146 | }
|
168 | 147 | #endif // SAMD21
|
169 | 148 |
|
170 | 149 | #ifdef SAM_D5X_E5X
|
| 150 | +// Decimal to fraction conversion. (adapted from ASF sample). |
| 151 | +STATIC float convert_dec_to_frac(uint8_t val) { |
| 152 | + return val / MICROPY_FLOAT_CONST(10.); |
| 153 | +} |
171 | 154 | STATIC float calculate_temperature(uint16_t TP, uint16_t TC) {
|
172 | 155 | uint32_t TLI = (*(uint32_t *)FUSES_ROOM_TEMP_VAL_INT_ADDR & FUSES_ROOM_TEMP_VAL_INT_Msk) >> FUSES_ROOM_TEMP_VAL_INT_Pos;
|
173 | 156 | uint32_t TLD = (*(uint32_t *)FUSES_ROOM_TEMP_VAL_DEC_ADDR & FUSES_ROOM_TEMP_VAL_DEC_Msk) >> FUSES_ROOM_TEMP_VAL_DEC_Pos;
|
|
0 commit comments