unleashed-firmware/applications/debug/unit_tests/furi_hal/furi_hal_tests.c
Leptopt1los 3fd5f15e7f
Furi_hal_rtc: new function (#3294)
* furi_hal_rtc_timestamp_to_datetime added
* hw targets api version sync
* hw targets api version sync, bump
* FuriHal: update rtc docs
* unit tests added

Co-authored-by: hedger <hedger@users.noreply.github.com>
Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
2024-01-14 17:07:42 +09:00

273 lines
8.0 KiB
C

#include "furi_hal_rtc.h"
#include <stdint.h>
#include <stdio.h>
#include <furi.h>
#include <furi_hal.h>
#include <lp5562_reg.h>
#include "../minunit.h"
#include <stdlib.h>
#define DATA_SIZE 4
#define EEPROM_ADDRESS 0b10101000
#define EEPROM_ADDRESS_HIGH (EEPROM_ADDRESS | 0b10)
#define EEPROM_SIZE 512
#define EEPROM_PAGE_SIZE 16
#define EEPROM_WRITE_DELAY_MS 6
static void furi_hal_i2c_int_setup() {
furi_hal_i2c_acquire(&furi_hal_i2c_handle_power);
}
static void furi_hal_i2c_int_teardown() {
furi_hal_i2c_release(&furi_hal_i2c_handle_power);
}
static void furi_hal_i2c_ext_setup() {
furi_hal_i2c_acquire(&furi_hal_i2c_handle_external);
}
static void furi_hal_i2c_ext_teardown() {
furi_hal_i2c_release(&furi_hal_i2c_handle_external);
}
MU_TEST(furi_hal_i2c_int_1b) {
bool ret = false;
uint8_t data_one = 0;
// 1 byte: read, write, read
ret = furi_hal_i2c_read_reg_8(
&furi_hal_i2c_handle_power,
LP5562_ADDRESS,
LP5562_CHANNEL_BLUE_CURRENT_REGISTER,
&data_one,
LP5562_I2C_TIMEOUT);
mu_assert(ret, "0 read_reg_8 failed");
mu_assert(data_one != 0, "0 invalid data");
ret = furi_hal_i2c_write_reg_8(
&furi_hal_i2c_handle_power,
LP5562_ADDRESS,
LP5562_CHANNEL_BLUE_CURRENT_REGISTER,
data_one,
LP5562_I2C_TIMEOUT);
mu_assert(ret, "1 write_reg_8 failed");
ret = furi_hal_i2c_read_reg_8(
&furi_hal_i2c_handle_power,
LP5562_ADDRESS,
LP5562_CHANNEL_BLUE_CURRENT_REGISTER,
&data_one,
LP5562_I2C_TIMEOUT);
mu_assert(ret, "2 read_reg_8 failed");
mu_assert(data_one != 0, "2 invalid data");
}
MU_TEST(furi_hal_i2c_int_3b) {
bool ret = false;
uint8_t data_many[DATA_SIZE] = {0};
// 3 byte: read, write, read
data_many[0] = LP5562_CHANNEL_BLUE_CURRENT_REGISTER;
ret = furi_hal_i2c_tx(
&furi_hal_i2c_handle_power, LP5562_ADDRESS, data_many, 1, LP5562_I2C_TIMEOUT);
mu_assert(ret, "3 tx failed");
ret = furi_hal_i2c_rx(
&furi_hal_i2c_handle_power,
LP5562_ADDRESS,
data_many + 1,
DATA_SIZE - 1,
LP5562_I2C_TIMEOUT);
mu_assert(ret, "4 rx failed");
for(size_t i = 0; i < DATA_SIZE; i++) mu_assert(data_many[i] != 0, "4 invalid data_many");
ret = furi_hal_i2c_tx(
&furi_hal_i2c_handle_power, LP5562_ADDRESS, data_many, DATA_SIZE, LP5562_I2C_TIMEOUT);
mu_assert(ret, "5 tx failed");
ret = furi_hal_i2c_tx(
&furi_hal_i2c_handle_power, LP5562_ADDRESS, data_many, 1, LP5562_I2C_TIMEOUT);
mu_assert(ret, "6 tx failed");
ret = furi_hal_i2c_rx(
&furi_hal_i2c_handle_power,
LP5562_ADDRESS,
data_many + 1,
DATA_SIZE - 1,
LP5562_I2C_TIMEOUT);
mu_assert(ret, "7 rx failed");
for(size_t i = 0; i < DATA_SIZE; i++) mu_assert(data_many[i] != 0, "7 invalid data_many");
}
MU_TEST(furi_hal_i2c_int_1b_fail) {
bool ret = false;
uint8_t data_one = 0;
// 1 byte: fail, read, fail, write, fail, read
data_one = 0;
ret = furi_hal_i2c_read_reg_8(
&furi_hal_i2c_handle_power,
LP5562_ADDRESS + 0x10,
LP5562_CHANNEL_BLUE_CURRENT_REGISTER,
&data_one,
LP5562_I2C_TIMEOUT);
mu_assert(!ret, "8 read_reg_8 failed");
mu_assert(data_one == 0, "8 invalid data");
ret = furi_hal_i2c_read_reg_8(
&furi_hal_i2c_handle_power,
LP5562_ADDRESS,
LP5562_CHANNEL_BLUE_CURRENT_REGISTER,
&data_one,
LP5562_I2C_TIMEOUT);
mu_assert(ret, "9 read_reg_8 failed");
mu_assert(data_one != 0, "9 invalid data");
}
MU_TEST(furi_hal_i2c_int_ext_3b) {
bool ret = false;
uint8_t data_many[DATA_SIZE] = {0};
// 3 byte: read
data_many[0] = LP5562_CHANNEL_BLUE_CURRENT_REGISTER;
ret = furi_hal_i2c_tx_ext(
&furi_hal_i2c_handle_power,
LP5562_ADDRESS,
false,
data_many,
1,
FuriHalI2cBeginStart,
FuriHalI2cEndAwaitRestart,
LP5562_I2C_TIMEOUT);
mu_assert(ret, "3 tx failed");
// Send a RESTART condition, then read the 3 bytes one after the other
ret = furi_hal_i2c_rx_ext(
&furi_hal_i2c_handle_power,
LP5562_ADDRESS,
false,
data_many + 1,
1,
FuriHalI2cBeginRestart,
FuriHalI2cEndPause,
LP5562_I2C_TIMEOUT);
mu_assert(ret, "4 rx failed");
mu_assert(data_many[1] != 0, "4 invalid data");
ret = furi_hal_i2c_rx_ext(
&furi_hal_i2c_handle_power,
LP5562_ADDRESS,
false,
data_many + 2,
1,
FuriHalI2cBeginResume,
FuriHalI2cEndPause,
LP5562_I2C_TIMEOUT);
mu_assert(ret, "5 rx failed");
mu_assert(data_many[2] != 0, "5 invalid data");
ret = furi_hal_i2c_rx_ext(
&furi_hal_i2c_handle_power,
LP5562_ADDRESS,
false,
data_many + 3,
1,
FuriHalI2cBeginResume,
FuriHalI2cEndStop,
LP5562_I2C_TIMEOUT);
mu_assert(ret, "6 rx failed");
mu_assert(data_many[3] != 0, "6 invalid data");
}
MU_TEST(furi_hal_i2c_ext_eeprom) {
if(!furi_hal_i2c_is_device_ready(&furi_hal_i2c_handle_external, EEPROM_ADDRESS, 100)) {
printf("no device connected, skipping\r\n");
return;
}
bool ret = false;
uint8_t buffer[EEPROM_SIZE] = {0};
for(size_t page = 0; page < (EEPROM_SIZE / EEPROM_PAGE_SIZE); ++page) {
// Fill page buffer
for(size_t page_byte = 0; page_byte < EEPROM_PAGE_SIZE; ++page_byte) {
// Each byte is its position in the EEPROM modulo 256
uint8_t byte = ((page * EEPROM_PAGE_SIZE) + page_byte) % 256;
buffer[page_byte] = byte;
}
uint8_t address = (page < 16) ? EEPROM_ADDRESS : EEPROM_ADDRESS_HIGH;
ret = furi_hal_i2c_write_mem(
&furi_hal_i2c_handle_external,
address,
page * EEPROM_PAGE_SIZE,
buffer,
EEPROM_PAGE_SIZE,
20);
mu_assert(ret, "EEPROM write failed");
furi_delay_ms(EEPROM_WRITE_DELAY_MS);
}
ret = furi_hal_i2c_read_mem(
&furi_hal_i2c_handle_external, EEPROM_ADDRESS, 0, buffer, EEPROM_SIZE, 100);
mu_assert(ret, "EEPROM read failed");
for(size_t pos = 0; pos < EEPROM_SIZE; ++pos) {
mu_assert_int_eq(pos % 256, buffer[pos]);
}
}
MU_TEST(furi_hal_rtc_timestamp2datetime_min) {
uint32_t test_value = 0;
FuriHalRtcDateTime min_datetime_expected = {0, 0, 0, 1, 1, 1970, 0};
FuriHalRtcDateTime result = {0};
furi_hal_rtc_timestamp_to_datetime(test_value, &result);
mu_assert_mem_eq(&min_datetime_expected, &result, sizeof(result));
}
MU_TEST(furi_hal_rtc_timestamp2datetime_max) {
uint32_t test_value = UINT32_MAX;
FuriHalRtcDateTime max_datetime_expected = {6, 28, 15, 7, 2, 2106, 0};
FuriHalRtcDateTime result = {0};
furi_hal_rtc_timestamp_to_datetime(test_value, &result);
mu_assert_mem_eq(&max_datetime_expected, &result, sizeof(result));
}
MU_TEST(furi_hal_rtc_timestamp2datetime2timestamp) {
uint32_t test_value = random();
FuriHalRtcDateTime datetime = {0};
furi_hal_rtc_timestamp_to_datetime(test_value, &datetime);
uint32_t result = furi_hal_rtc_datetime_to_timestamp(&datetime);
mu_assert_int_eq(test_value, result);
}
MU_TEST_SUITE(furi_hal_i2c_int_suite) {
MU_SUITE_CONFIGURE(&furi_hal_i2c_int_setup, &furi_hal_i2c_int_teardown);
MU_RUN_TEST(furi_hal_i2c_int_1b);
MU_RUN_TEST(furi_hal_i2c_int_3b);
MU_RUN_TEST(furi_hal_i2c_int_ext_3b);
MU_RUN_TEST(furi_hal_i2c_int_1b_fail);
}
MU_TEST_SUITE(furi_hal_i2c_ext_suite) {
MU_SUITE_CONFIGURE(&furi_hal_i2c_ext_setup, &furi_hal_i2c_ext_teardown);
MU_RUN_TEST(furi_hal_i2c_ext_eeprom);
}
MU_TEST_SUITE(furi_hal_rtc_datetime_suite) {
MU_RUN_TEST(furi_hal_rtc_timestamp2datetime_min);
MU_RUN_TEST(furi_hal_rtc_timestamp2datetime_max);
MU_RUN_TEST(furi_hal_rtc_timestamp2datetime2timestamp);
}
int run_minunit_test_furi_hal() {
MU_RUN_SUITE(furi_hal_i2c_int_suite);
MU_RUN_SUITE(furi_hal_i2c_ext_suite);
MU_RUN_SUITE(furi_hal_rtc_datetime_suite);
return MU_EXIT_CODE;
}