8000 Merge pull request #790 from dhalbert/cpu_temp · larsks/micropython@449385b · GitHub
[go: up one dir, main page]

Skip to content

Commit 449385b

Browse files
authored
Merge pull request micropython#790 from dhalbert/cpu_temp
Implement microcontroller.cpu.temperature.
2 parents 3d36f63 + 33b9c39 commit 449385b

File tree

9 files changed

+272
-236
lines changed

9 files changed

+272
-236
lines changed

ports/atmel-samd/common-hal/analogio/AnalogIn.c

Lines changed: 8 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "py/binary.h"
3535
#include "py/mphal.h"
3636

37+
#include "peripherals.h"
3738
#include "shared-bindings/analogio/AnalogIn.h"
3839

3940
#include "atmel_start_pins.h"
@@ -89,57 +90,20 @@ uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) {
8990
// Something else might have used the ADC in a different way,
9091
// so we completely re-initialize it.
9192

92-
// Turn the clocks on.
93-
#ifdef SAMD51
94-
if (self->instance == ADC0) {
95-
hri_mclk_set_APBDMASK_ADC0_bit(MCLK);
96-
hri_gclk_write_PCHCTRL_reg(GCLK, ADC0_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos));
97-
} else if (self->instance == ADC1) {
98-
hri_mclk_set_APBDMASK_ADC1_bit(MCLK);
99-
hri_gclk_write_PCHCTRL_reg(GCLK, ADC1_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos));
100-
}
101-
#endif
93+
struct adc_sync_descriptor adc;
10294

103-
#ifdef SAMD21
104-
_pm_enable_bus_clock(PM_BUS_APBC, ADC);
105-
_gclk_enable_channel(ADC_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val);
106-
#endif
95+
samd_peripherals_adc_setup(&adc, self->instance);
10796

108-
struct adc_sync_descriptor adc;
109-
adc_sync_init(&adc, self->instance, (void *)NULL);
110-
adc_sync_set_reference(&adc, ADC_REFCTRL_REFSEL_INTVCC1_Val);
111-
adc_sync_set_resolution(&adc, ADC_CTRLB_RESSEL_12BIT_Val);
97+
// Full scale is 3.3V (VDDANA) = 65535.
11298

99+
// On SAMD21, INTVCC1 is 0.5*VDDANA. On SAMD51, INTVCC1 is 1*VDDANA.
100+
// So on SAMD21 only, divide the input by 2, so full scale will match 0.5*VDDANA.
101+
adc_sync_set_reference(&adc, ADC_REFCTRL_REFSEL_INTVCC1_Val);
113102
#ifdef SAMD21
114103
adc_sync_set_channel_gain(&adc, self->channel, ADC_INPUTCTRL_GAIN_DIV2_Val);
115-
116-
// Load the factory calibration
117-
hri_adc_write_CALIB_BIAS_CAL_bf(ADC, (*((uint32_t*) ADC_FUSES_BIASCAL_ADDR) & ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos);
118-
// Bits 7:5
119-
uint16_t linearity = ((*((uint32_t*) ADC_FUSES_LINEARITY_1_ADDR) & ADC_FUSES_LINEARITY_1_Msk) >> ADC_FUSES_LINEARITY_1_Pos) << 5;
120-
// Bits 4:0
121-
linearity |= (*((uint32_t*) ADC_FUSES_LINEARITY_0_ADDR) & ADC_FUSES_LINEARITY_0_Msk) >> ADC_FUSES_LINEARITY_0_Pos;
122-
hri_adc_write_CALIB_LINEARITY_CAL_bf(ADC, linearity);
123104
#endif
124105

125-
// SAMD51 has a CALIB register but doesn't have documented fuses for them.
126-
#ifdef SAMD51
127-
uint8_t biasrefbuf;
128-
uint8_t biasr2r;
129-
uint8_t biascomp;
130-
if (self->instance == ADC0) {
131-
biasrefbuf = ((*(uint32_t*) ADC0_FUSES_BIASREFBUF_ADDR) & ADC0_FUSES_BIASREFBUF_Msk) >> ADC0_FUSES_BIASREFBUF_Pos;
132-
biasr2r = ((*(uint32_t*) ADC0_FUSES_BIASR2R_ADDR) & ADC0_FUSES_BIASR2R_Msk) >> ADC0_FUSES_BIASR2R_Pos;
133-
biascomp = ((*(uint32_t*) ADC0_FUSES_BIASCOMP_ADDR) & ADC0_FUSES_BIASCOMP_Msk) >> ADC0_FUSES_BIASCOMP_Pos;
134-
} else {
135-
biasrefbuf = ((*(uint32_t*) ADC1_FUSES_BIASREFBUF_ADDR) & ADC1_FUSES_BIASREFBUF_Msk) >> ADC1_FUSES_BIASREFBUF_Pos;
136-
biasr2r = ((*(uint32_t*) ADC1_FUSES_BIASR2R_ADDR) & ADC1_FUSES_BIASR2R_Msk) >> ADC1_FUSES_BIASR2R_Pos;
137-
biascomp = ((*(uint32_t*) ADC1_FUSES_BIASCOMP_ADDR) & ADC1_FUSES_BIASCOMP_Msk) >> ADC1_FUSES_BIASCOMP_Pos;
138-
}
139-
hri_adc_write_CALIB_BIASREFBUF_bf(self->instance, biasrefbuf);
140-
hri_adc_write_CALIB_BIASR2R_bf(self->instance, biasr2r);
141-
hri_adc_write_CALIB_BIASCOMP_bf(self->instance, biascomp);
142-
#endif
106+
adc_sync_set_resolution(&adc, ADC_CTRLB_RESSEL_12BIT_Val);
143107

144108
adc_sync_enable_channel(&adc, self->channel);
145109

ports/atmel-samd/common-hal/microcontroller/Processor.c

Lines changed: 206 additions & 153 deletions
Large diffs are not rendered by default.

ports/atmel-samd/peripherals.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,3 @@ uint8_t samd_peripherals_spi_baudrate_to_baud_reg_value(const uint32_t baudrate)
4242
uint32_t samd_peripherals_spi_baud_reg_value_to_baudrate(const uint8_t baud_reg_value) {
4343
return PROTOTYPE_SERCOM_SPI_M_SYNC_CLOCK_FREQUENCY / (2 * (baud_reg_value + 1));
4444
}
45-

ports/atmel-samd/peripherals.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,4 @@ Sercom* sercom_insts[SERCOM_INST_NUM];
4444
#include "samd51_peripherals.h"
4545
#endif
4646

47-
#endif // MICROPY_INCLUDED_ATMEL_SAMD_PINS_H
47+
#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_H

ports/atmel-samd/samd21_peripherals.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@
2424
* THE SOFTWARE.
2525
*/
2626

27+
#include "hal/include/hal_adc_sync.h"
2728
#include "hpl/gclk/hpl_gclk_base.h"
2829
#include "hpl/pm/hpl_pm_base.h"
2930

31+
3032
// The clock initializer values are rather random, so we need to put them in
3133
// tables for lookup. We can't compute them.
3234

@@ -91,3 +93,21 @@ uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad) {
9193
bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad) {
9294
return clock_pad == 1 || clock_pad == 3;
9395
}
96+
97+
// Do initialization and calibration setup needed for any use of the ADC.
98+
// The reference and resolution should be set by the caller.
99+
void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance) {
100+
// Turn the clocks on.
101+
_pm_enable_bus_clock(PM_BUS_APBC, ADC);
102+
_gclk_enable_channel(ADC_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val);
103+
104+
adc_sync_init(adc, instance, (void *)NULL);
105+
106+
// Load the factory calibration
107+
hri_adc_write_CALIB_BIAS_CAL_bf(ADC, (*((uint32_t*) ADC_FUSES_BIASCAL_ADDR) & ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos);
108+
// Bits 7:5
109+
uint16_t linearity = ((*((uint32_t*) ADC_FUSES_LINEARITY_1_ADDR) & ADC_FUSES_LINEARITY_1_Msk) >> ADC_FUSES_LINEARITY_1_Pos) << 5;
110+
// Bits 4:0
111+
linearity |= (*((uint32_t*) ADC_FUSES_LINEARITY_0_ADDR) & ADC_FUSES_LINEARITY_0_Msk) >> ADC_FUSES_LINEARITY_0_Pos;
112+
hri_adc_write_CALIB_LINEARITY_CAL_bf(ADC, linearity);
113+
}

ports/atmel-samd/samd21_peripherals.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@
2828
#define MICROPY_INCLUDED_ATMEL_SAMD_SAMD21_PERIPHERALS_H
2929

3030
#include "include/sam.h"
31+
#include "hal/include/hal_adc_sync.h"
3132

3233
void samd_peripherals_sercom_clock_init(Sercom* sercom, uint8_t sercom_index);
3334
uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad);
3435
bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad);
36+
void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance);
3537

3638
#endif // MICROPY_INCLUDED_ATMEL_SAMD_SAMD21_PERIPHERALS_H

ports/atmel-samd/samd51_peripherals.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
* THE SOFTWARE.
2525
*/
2626

27+
#include "hal/include/hal_adc_sync.h"
2728
#include "hpl/gclk/hpl_gclk_base.h"
2829
#include "hri/hri_mclk_d51.h"
2930

@@ -130,3 +131,35 @@ uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad) {
130131
bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad) {
131132
return clock_pad == 1;
132133
}
134+
135+
// Do initialization and calibration setup needed for any use of the ADC.
136+
// The reference and resolution should be set by the caller.
137+
void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance) {
138+
// Turn the clocks on.
139+
if (instance == ADC0) {
140+
hri_mclk_set_APBDMASK_ADC0_bit(MCLK);
141+
hri_gclk_write_PCHCTRL_reg(GCLK, ADC0_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos));
142+
} else if (instance == ADC1) {
143+
hri_mclk_set_APBDMASK_ADC1_bit(MCLK);
144+
hri_gclk_write_PCHCTRL_reg(GCLK, ADC1_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos));
145+
}
146+
147+
adc_sync_init(adc, instance, (void *)NULL);
148+
149+
// SAMD51 has a CALIB register but doesn't have documented fuses for them.
150+
uint8_t biasrefbuf;
151+
uint8_t biasr2r;
152+
uint8_t biascomp;
153+
if (instance == ADC0) {
154+
biasrefbuf = ((*(uint32_t*) ADC0_FUSES_BIASREFBUF_ADDR) & ADC0_FUSES_BIASREFBUF_Msk) >> ADC0_FUSES_BIASREFBUF_Pos;
155+
biasr2r = ((*(uint32_t*) ADC0_FUSES_BIASR2R_ADDR) & ADC0_FUSES_BIASR2R_Msk) >> ADC0_FUSES_BIASR2R_Pos;
156+
biascomp = ((*(uint32_t*) ADC0_FUSES_BIASCOMP_ADDR) & ADC0_FUSES_BIASCOMP_Msk) >> ADC0_FUSES_BIASCOMP_Pos;
157+
} else {
158+
biasrefbuf = ((*(uint32_t*) ADC1_FUSES_BIASREFBUF_ADDR) & ADC1_FUSES_BIASREFBUF_Msk) >> ADC1_FUSES_BIASREFBUF_Pos;
159+
biasr2r = ((*(uint32_t*) ADC1_FUSES_BIASR2R_ADDR) & ADC1_FUSES_BIASR2R_Msk) >> ADC1_FUSES_BIASR2R_Pos;
160+
biascomp = ((*(uint32_t*) ADC1_FUSES_BIASCOMP_ADDR) & ADC1_FUSES_BIASCOMP_Msk) >> ADC1_FUSES_BIASCOMP_Pos;
161+
}
162+
hri_adc_write_CALIB_BIASREFBUF_bf(instance, biasrefbuf);
163+
hri_adc_write_CALIB_BIASR2R_bf(instance, biasr2r);
164+
hri_adc_write_CALIB_BIASCOMP_bf(instance, biascomp);
165+
}

ports/atmel-samd/samd51_peripherals.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@
2828
#define MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PERIPHERALS_H
2929

3030
#include "sam.h"
31+
#include "hal/include/hal_adc_sync.h"
3132

3233
void samd_peripherals_sercom_clock_init(Sercom* sercom, uint8_t sercom_index);
3334
uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad);
3435
bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad);
36+
void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance);
3537

3638
#endif // MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PERIPHERALS_H
37-

ports/atmel-samd/samd_peripherals.h

Lines changed: 0 additions & 36 deletions
This file was deleted.

0 commit comments

Comments
 (0)
0