Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stm32] Fix address of F0 temperature calibration values #526

Merged
merged 5 commits into from
Jan 14, 2021

Conversation

chris-durand
Copy link
Member

@chris-durand chris-durand commented Dec 19, 2020

The addresses for the temperature sensor calibration values are wrong in modm. ST manual:
image

When first trying to use the ADC temperature sensor on a custom board with an F042K6 I ended up in the hardfault handler. I am wondering how the nucleo f042k6 adc example could have ever worked. This change is tested on real hardware.

I'll also fix the example which has these addresses hardcoded for demonstration purposes.

  • change constants in F0 ADC driver
  • fix values in example
  • make temperature sensor code compatible with F030/F070

@chris-durand
Copy link
Member Author

I just figured out the modm adc temperature sensor code does not work on F0 "Value Line Devices" (030, 070) which don't have a valid value for TS_CAL2 ...
I'll also have to fix that.

@rleh rleh added the fix 💎 label Dec 19, 2020
@salkinium
Copy link
Member

salkinium commented Dec 19, 2020

I remember that the addresses of these values were only written in the datasheet, and are different between devices. Perhaps there is a list of them in CubeMX or the CubeHAL, lemme check.

@chris-durand
Copy link
Member Author

I remember that the addresses of these values were only written in the datasheet, and are different between devices. Perhaps there is a list of them in CubeMX or the CubeHAL, lemme check.

The values are hardcoded in the CubeHAL and identical for all chips of the same family.

@chris-durand chris-durand force-pushed the fix/f0_adc_temperature branch from ac1d2b0 to c45623f Compare January 13, 2021 19:52
@chris-durand
Copy link
Member Author

chris-durand commented Jan 13, 2021

@salkinium @rleh Does anyone of you have an F030 or F070 board lying around to test the change? It compiles for F030C6 but I have nothing to test it on.

The F030 code I added comes more or less directly from the reference manual Appendix A.7.16:
image

@chris-durand chris-durand marked this pull request as ready for review January 13, 2021 19:59
@rleh
Copy link
Member

rleh commented Jan 13, 2021

Does anyone of you have an F030 or F070 board lying around to test the change?

grafik

What exactly should I check with the test?

Ignore the Nucleo-L031K6 board. I mistook it for a F031 board....

@chris-durand
Copy link
Member Author

STM32F072 are different. ST calibrates all STM32 ADC temperature sensors at two temperature points except "STM32F0 Value line devices", also known as F030 and F070. They use a different code path to calculate the temperature. If one had a suitable board, I would have added a BSP and an example.

In modm we only have one board with a matching controller, the stm32f030f4p6 demo board. This one basically has nothing on it except for a power supply and an orange led. I could add a quite meaningless example to get at least some CI coverage for compilation.

@salkinium
Copy link
Member

I have the stm32f030f4p6 board here, I could at least do a sanity check of the internal temperature sensor and compare it to the F072 Disco output.

@salkinium
Copy link
Member

Something isn't working right.

#include <modm/board.hpp>
using namespace Board;
int main()
{
	Board::initialize();
	Adc::initialize<Board::SystemClock, Adc::ClockMode::Synchronous, 12_MHz>();
	const uint16_t Vref = Adc::readInternalVoltageReference();
	while (true)
	{
		int16_t Temp = Adc::readTemperature(Vref);
		LedOrange::set(Temp > 685);
		modm::delay(1s);
	}

	return 0;
}

Stepping though this example I get 686°C.

// *TS_CAL1 = 1746
// VDDA_CAL = 3300
// TS_AVG_SLOPE = 5336
// TS_CAL1_TEMP = 30

// Vref = 3287
// TS_DATA = 1762

// const int32_t value = (int32_t(*TS_CAL1) + (TS_DATA * Vref / VDDA_CAL)) * 1000;
// value = 3501000 (real value == ~3501059)

// return value / TS_AVG_SLOPE + TS_CAL1_TEMP;
// return = 686

@salkinium salkinium force-pushed the fix/f0_adc_temperature branch from c45623f to 3ecad35 Compare January 14, 2021 22:00
Copy link
Member

@salkinium salkinium left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested in hardware, works.

src/modm/platform/adc/stm32f0/adc_impl.hpp.in Show resolved Hide resolved
@chris-durand
Copy link
Member Author

Thanks for testing!

@salkinium salkinium merged commit 3ecad35 into modm-io:develop Jan 14, 2021
@chris-durand chris-durand deleted the fix/f0_adc_temperature branch January 14, 2021 22:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

3 participants