esp-idf/examples/system/ulp_riscv/i2c/main/ulp/main.c
Sudeep Mohanty 4fde033a5f ulp: Added support for RTC I2C driver for ULP RISC-V on esp32s2 and esp32s3
This commit adds support for using the RTC I2C peripheral on the ULP
RISC-V core for esp32s2 and esp32s3. It also adds an example to demonstrate the
usage of the RTC I2C peripheral.

This commit also modifies the rtc_i2c register structure files to enable
the use of bitfields in the ULP RISC-V RTC I2C driver.
2022-09-05 10:21:43 +02:00

127 lines
4.0 KiB
C

/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/* ULP RISC-V RTC I2C example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
This code runs on ULP RISC-V coprocessor
*/
#include <stdint.h>
#include "ulp_riscv.h"
#include "ulp_riscv_utils.h"
#include "ulp_riscv_i2c_ulp_core.h"
#include "../bmp180_defs.h"
/************************************************
* Shared data between main CPU and ULP
************************************************/
int16_t ut_data = 0;
int32_t up_data = 0;
int32_t ut_threshold = EXAMPLE_UT_THRESHOLD;
int32_t up_threshold = EXAMPLE_UP_THRESHOLD;
oss_mode_t oss_mode = EXAMPLE_OSS_MODE;
int main (void)
{
/* Read uncompensated temperature */
bmp180_read_ut_data(&ut_data);
/* Read uncompensated pressure */
bmp180_read_up_data(&up_data, oss_mode);
/* Wakeup the main CPU if either the uncompensated temperature or uncompensated pressure values
* are more than their respective threshold values.
*/
if ((ut_data > ut_threshold) || (up_data > up_threshold)) {
ulp_riscv_wakeup_main_processor();
}
return 0;
}
static void bmp180_read16(uint16_t *data_out, uint32_t reg_msb, uint32_t reg_lsb)
{
uint8_t data_rd = 0;
*data_out = 0;
ulp_riscv_i2c_master_set_slave_reg_addr(reg_msb);
ulp_riscv_i2c_master_read_from_device(&data_rd, 1);
*data_out |= (uint16_t)(data_rd << 8);
ulp_riscv_i2c_master_set_slave_reg_addr(reg_lsb);
data_rd = 0;
ulp_riscv_i2c_master_read_from_device(&data_rd, 1);
*data_out |= (uint16_t)(data_rd);
}
static void bmp180_read_ut_data(int16_t *ut_data)
{
/* Set slave register address to the control register */
ulp_riscv_i2c_master_set_slave_reg_addr(BMP180_SENSOR_REG_ADDR_CTRL_REG);
/* Setup control register to read temperature */
uint8_t cmd = BMP180_SENSOR_CMD_READ_TEMPERATURE;
ulp_riscv_i2c_master_write_to_device(&cmd, 1);
/* Wait at least 4.5 milliseconds for the sensor to complete the reading */
ulp_riscv_delay_cycles(5 * ULP_RISCV_CYCLES_PER_US * 1000);
/* Read uncompensated temperature data */
bmp180_read16((uint16_t *)ut_data, BMP180_SENSOR_REG_ADDR_SENSOR_DATA_MSB, BMP180_SENSOR_REG_ADDR_SENSOR_DATA_LSB);
}
static void bmp180_read_up_data(int32_t *up_data, oss_mode_t oss_mode)
{
uint16_t press_high;
uint8_t press_low;
/* Set slave register address to the control register */
ulp_riscv_i2c_master_set_slave_reg_addr(BMP180_SENSOR_REG_ADDR_CTRL_REG);
/* Setup control register to read pressure */
uint8_t cmd = 0;
uint8_t wait = 0;
switch(oss_mode)
{
case OSS_0:
cmd = BMP180_SENSOR_CMD_READ_PRESSURE_OSS_0;
wait = 5; // Wait atleast 4.5 msec
break;
case OSS_1:
cmd = BMP180_SENSOR_CMD_READ_PRESSURE_OSS_1;
wait = 8; // Wait atleast 7.5 msec
break;
case OSS_2:
cmd = BMP180_SENSOR_CMD_READ_PRESSURE_OSS_2;
wait = 14; // Wait atleast 13.5 msec
break;
case OSS_3:
cmd = BMP180_SENSOR_CMD_READ_PRESSURE_OSS_3;
wait = 26; // Wait atleast 25.5 msec
break;
}
ulp_riscv_i2c_master_write_to_device(&cmd, 1);
/* Wait for the required amount of time for the sensor to complete the reading */
ulp_riscv_delay_cycles(wait * ULP_RISCV_CYCLES_PER_US * 1000);
/* Read uncompensated temperature data */
/* Read MSB + LSB */
bmp180_read16(&press_high, BMP180_SENSOR_REG_ADDR_SENSOR_DATA_MSB, BMP180_SENSOR_REG_ADDR_SENSOR_DATA_LSB);
/* Read XLSB */
ulp_riscv_i2c_master_set_slave_reg_addr(BMP180_SENSOR_REG_ADDR_SENSOR_DATA_XLSB);
ulp_riscv_i2c_master_read_from_device(&press_low, 1);
*up_data = (((uint32_t)press_high << 8) + (uint32_t)press_low) >> (8 - oss_mode);
}