Basic I2C functionality

This commit is contained in:
2024-12-29 16:24:54 +01:00
parent 17099b0047
commit 1e648be211
9 changed files with 416 additions and 208 deletions

View File

@@ -1,12 +1,22 @@
#include "main.h"
#include <cstdlib>
#include <cstdint>
#include <memory>
#include <string>
#include "gpio.h"
#include "i2c.hpp"
#include "stm32_hal_legacy.h"
#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_def.h"
#include "stm32f4xx_hal_i2c.h"
#include "usart.hpp"
// needs to be global to be accessible in error handler
std::unique_ptr<driver::usart::Usart> usart2{nullptr};
void SystemClock_Config(void);
void checkHalStatus(HAL_StatusTypeDef);
int main(void) {
@@ -19,20 +29,85 @@ int main(void) {
/* Initialize all configured peripherals */
MX_GPIO_Init();
driver::usart::Usart usart2(USART2, 115200, UART_WORDLENGTH_8B, UART_STOPBITS_1,
UART_PARITY_NONE, UART_MODE_TX_RX, UART_HWCONTROL_NONE,
UART_OVERSAMPLING_16);
usart2 = std::make_unique<driver::usart::Usart>(
driver::usart::Usart(USART2, 115200, UART_WORDLENGTH_8B, UART_STOPBITS_1, UART_PARITY_NONE,
UART_MODE_TX_RX, UART_HWCONTROL_NONE, UART_OVERSAMPLING_16));
usart2.init();
usart2.println("");
usart2.println("\r\nWeight cell init.");
usart2->init();
usart2->println("");
usart2->println("\r\nWeight cell init.");
int i{0};
auto i2c1 = std::make_unique<driver::i2c::I2c>(
I2C1, 100000, I2C_DUTYCYCLE_2, 0x00, I2C_ADDRESSINGMODE_7BIT, I2C_DUALADDRESS_DISABLED,
0x00, I2C_GENERALCALL_DISABLED, I2C_NOSTRETCH_DISABLED);
if (!i2c1->init()) {
usart2->println("Error intializing I2C1!");
usart2->println("Last Error: " + std::to_string(i2c1->getLastError()));
Error_Handler();
} else {
usart2->println("I2C1 intialized successful");
}
// init NAU7802
{
std::vector<uint8_t> data = {0x01};
// reset NAU7802
checkHalStatus(i2c1->write(0x2A, 0x00, data));
usart2->println("Reset nau");
HAL_Delay(100);
// power up digital logic
data[0] = 0x02;
i2c1->write(0x2A, 0x00, data);
HAL_Delay(100);
usart2->println("PUP digi");
// power up analog logic
data[0] = 0x06;
i2c1->write(0x2A, 0x00, data);
HAL_Delay(100);
usart2->println("PUP analog");
// use internal LDO as reference
data[0] = 0x86;
checkHalStatus(i2c1->write(0x2A, 0x00, data));
HAL_Delay(100);
// print status back to usart
auto ret = i2c1->read(0x2A, 0x00);
checkHalStatus(ret.first);
usart2->println("NAU7802 reports state " + std::to_string(ret.second) + " at 0x00");
// REG_CHPS CLK_CHP off
data[0] = 0x30;
checkHalStatus(i2c1->write(0x2A, 0x15, data));
HAL_Delay(100);
}
uint32_t measurement = 0;
auto val = i2c1->read(0x2A, 0x12);
measurement |= (val.second << 16);
val = i2c1->read(0x2A, 0x13);
measurement |= (val.second << 8);
val = i2c1->read(0x2A, 0x14);
measurement |= val.second << 16;
while (1) {
std::string buf{"Iteration #"};
measurement = 0;
val = i2c1->read(0x2A, 0x12);
measurement |= (val.second << 16);
val = i2c1->read(0x2A, 0x13);
measurement |= (val.second << 8);
val = i2c1->read(0x2A, 0x14);
measurement |= val.second << 16;
usart2->println("Measurement " + std::to_string(measurement) + " counts");
usart2.println(buf + std::to_string(i++));
HAL_Delay(1000);
}
}
@@ -75,6 +150,17 @@ void SystemClock_Config(void) {
}
}
void checkHalStatus(HAL_StatusTypeDef status) {
if (status == HAL_OK) {
return;
}
if (usart2 == nullptr) {
Error_Handler();
return; // never reached
}
usart2->println("HAL Status not okay! Calling Error Handler");
}
/**
* @brief This function is executed in case of error occurrence.
* @retval None
@@ -82,6 +168,10 @@ void SystemClock_Config(void) {
void Error_Handler(void) {
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
if (usart2 != nullptr) {
usart2->println("=== ERROR HANDLER ===");
usart2->println("entering infinite loop...");
}
__disable_irq();
while (1) {}
/* USER CODE END Error_Handler_Debug */