Files
VesiScan-Basic-firmware-test/project/ble_peripheral/ble_app_bladder_patch/ad5272_i2c.c
Charles Kwon 72f5eb3cd9 Initial commit: MT firmware project
- BLE peripheral applications
- dr_piezo and bladder_patch projects

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 17:26:39 +09:00

300 lines
7.6 KiB
C

/*******************************************************************************
* @file ad5272_i2c.c
* @author CandyPops Co.
* @version V1.0.0
* @date 2022-09-05
* @brief
******************************************************************************/
/* board driver */
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdbool.h>
#include "nrf.h"
#include "app_error.h"
#include "boards.h"
#include "nrfx_gpiote.h"
#include "nrfx_twi.h"
#include "nrf_delay.h"
#include "ad5272_i2c.h"
#include "debug_print.h"
/* I2C number and slave address for AD5272 */
#define AD5272_I2C_ADDR 0x2F /* Default I2C address if ADDR = GND */
#define AD5272_MAX_SERIAL_WRITE 16
int16_t read_from_ad5272 = 0;
uint16_t data_16_to_write = 0;
/* TWI instance. */
const nrfx_twi_t m_twi_ad5272 = NRFX_TWI_INSTANCE(AD5272_I2C_INSTANCE);
void ad5272_i2c_uninit(void){
nrfx_twi_disable(&m_twi_ad5272);
nrfx_twi_uninit(&m_twi_ad5272);
}
void ad5272_i2c_init(void){
ret_code_t err_code;
const nrfx_twi_config_t twi_ad5272_config = {
.scl = AD5272_I2C_SCL_PIN,
.sda = AD5272_I2C_SDA_PIN,
.frequency = NRF_TWI_FREQ_400K,
.interrupt_priority = APP_IRQ_PRIORITY_HIGH,
};
err_code = nrfx_twi_init(&m_twi_ad5272, &twi_ad5272_config, NULL, NULL);
APP_ERROR_CHECK(err_code);
nrfx_twi_enable(&m_twi_ad5272);
}
ret_code_t ad5272_twi_tx( uint8_t device_id,
uint8_t const * p_data,
uint8_t length,
bool no_stop)
{
ret_code_t ret;
ret = nrfx_twi_tx(&m_twi_ad5272, device_id, p_data, length, no_stop);
return ret;
}
ret_code_t ad5272_twi_rx( uint8_t device_id,
uint8_t * p_data,
uint8_t length)
{
ret_code_t ret;
ret = nrfx_twi_rx(&m_twi_ad5272, device_id, p_data, length);
return ret;
}
int16_t ad5272_command_read(uint8_t command, uint8_t write_data)
{
uint8_t error_count = 0;
uint8_t data_buff[1+AD5272_MAX_SERIAL_WRITE];
uint16_t data_to_write = 0;
int16_t read_data = 0;
ret_code_t ret;
if (AD5272_50TP_WIPER_READ == command)
{
// shift the command over into bits 13:10
data_to_write = command<<10;
// also need to send 6-bit 50-TP location
data_to_write |= write_data;
}
else if ( (AD5272_RDAC_READ == command) || (AD5272_50TP_LAST_USED == command) || (AD5272_CONTROL_READ == command) )
{
// command is in range and something possible to read
// shift the command over into bits 13:10
data_to_write = command<<10;
}
else
{
// It's either a bad command (out of range, > AD5272_SHUTDOWN), or its not a readable command
// Bad command, we can't reasonably proceed
error_count = 100;
}
/**
* At this point, if error_count == 0 we have a valid read command
*/
if (0 == error_count)
{
memset(data_buff, 0, 1+AD5272_MAX_SERIAL_WRITE);
data_buff[0] = (data_to_write >> 8); // ms byte to write
data_buff[1] = data_to_write & 0x0FF; // ls byte to write
#if FEATURE_PRINTF
DBG_PRINTF("ad5272_rx_1_buff[0]=0x%x, [1]=0x%x\r\n", data_buff[0], data_buff[1]);
#endif
ret = ad5272_twi_tx(AD5272_I2C_ADDR, data_buff, 2, true);
if(ret != NRF_SUCCESS) {
ret = ad5272_twi_tx(AD5272_I2C_ADDR, data_buff, 2, true);
if(ret != NRF_SUCCESS) {
#if FEATURE_PRINTF
DBG_PRINTF("ad5272_ERR! i2c read-1\r\n");
#endif
//APP_ERROR_CHECK(ret);
}
}
memset(data_buff, 0, 1+AD5272_MAX_SERIAL_WRITE);
ret = ad5272_twi_rx(AD5272_I2C_ADDR, data_buff, 2);
if(ret != NRF_SUCCESS) {
ret = ad5272_twi_rx(AD5272_I2C_ADDR, data_buff, 2);
if(ret != NRF_SUCCESS) {
#if FEATURE_PRINTF
DBG_PRINTF("ad5272_ERR! i2c read-2\r\n");
#endif
//APP_ERROR_CHECK(ret);
}
}
read_data = data_buff[0] << 8; // ms byte
read_data |= data_buff[1]; // ls byte
#if FEATURE_PRINTF
DBG_PRINTF("ad5272_read_data = 0x%x\r\n",read_data);
#endif
}else{
#if FEATURE_PRINTF
DBG_PRINTF("ad5272_read_data USELESS!!!\r\n");
#endif
}
return read_data;
}
int8_t ad5272_command_write(uint8_t command, uint16_t write_data)
{
uint8_t error_count = 0;
uint8_t data_buff[1+AD5272_MAX_SERIAL_WRITE];
ret_code_t ret;
int8_t return_val = 0;
uint16_t data_to_write = 0;
if (write_data > 0x3FF)
{
// data in bits 13:10 will clobber the command when we OR in write_datum16
write_data &= 0x3FF; // clip off any bad high bits even though we are going to error out and not use them
#if FEATURE_PRINTF
DBG_PRINTF("ad5272_ERR! Input Value wrong!\r\n");
#endif
}
if ( (AD5272_RDAC_WRITE == command) || (AD5272_CONTROL_WRITE == command) || (AD5272_SHUTDOWN == command) )
{
// these commands need to use data we send over
// shift the command over into bits 13:10
data_to_write = command<<10;
// also need to send 10-bit or 8-bit wiper value, or 3 control bits, or shutdown bit
data_to_write |= write_data;
}
else if ( (AD5272_50TP_WRITE == command) || (AD5272_RDAC_REFRESH == command) )
{
// shift the command over into bits 13:10
data_to_write = command<<10;
// no data needed
}
else
{
// It's either a bad command (out of range, > AD5272_SHUTDOWN), or its not a writeable command
// Bad command, we can't reasonably proceed
error_count = 100;
}
// if no errors so far, command is valid and datum is too
if (0 == error_count)
{
data_buff[0] = (data_to_write >> 8); // ms byte to write
data_buff[1] = data_to_write & 0x0FF; // ls byte to write
ret = ad5272_twi_tx(AD5272_I2C_ADDR, data_buff, 2, false);
if(ret != NRF_SUCCESS) {
ret = ad5272_twi_tx(AD5272_I2C_ADDR, data_buff, 2, false);
if(ret != NRF_SUCCESS) {
#if FEATURE_PRINTF
DBG_PRINTF("ad5272_ERR! i2c write\r\n");
#endif
//APP_ERROR_CHECK(ret);
return_val = NRF_ERROR_INTERNAL;
}
}
}
return return_val;
}
void ad5272_i2c_is_busy(void)
{
uint8_t buffer[3]; /* Addr + data */
buffer[0] = AD5272_COMMAND_NOP;
buffer[1] = 0x00;
while(NRF_SUCCESS != ad5272_twi_tx(AD5272_I2C_ADDR, buffer, 1, false))
{
#if FEATURE_PRINTF
DBG_PRINTF("ad5272_BUSY : is Busy\r\n");
#endif
}
}
/**
*
*/
int8_t ad5272_write_and_read_rdac (uint16_t data_16_to_write)
{
ret_code_t ret;
ret = ad5272_command_write(AD5272_CONTROL_WRITE, AD5272_RDAC_WIPER_WRITE_ENABLE); /* Write Enable */
ret |= ad5272_command_write(AD5272_RDAC_WRITE, data_16_to_write); /* Write Data */
ret |= ad5272_command_write(AD5272_CONTROL_WRITE, 0x00); /* Write Disable & Use 50tp value */
read_from_ad5272 = ad5272_command_read(AD5272_RDAC_READ, 0x00);
return ret;
}
int16_t ad5272_read_rdac (void)
{
read_from_ad5272 = ad5272_command_read(AD5272_RDAC_READ, 0x00);
return read_from_ad5272;
}
int8_t ad5272_write_rdac (uint16_t data_16_to_write)
{
ret_code_t ret;
ret = ad5272_command_write(AD5272_CONTROL_WRITE, AD5272_RDAC_WIPER_WRITE_ENABLE); /* Write Enable */
ret |= ad5272_command_write(AD5272_RDAC_WRITE, data_16_to_write); /* Write Data */
ret |= ad5272_command_write(AD5272_CONTROL_WRITE, 0x00); /* Write Disable & Use 50tp value */
return ret;
}
void ad5272_RDAC_refresh(void)
{
ad5272_command_write(AD5272_RDAC_REFRESH, 0x00);
ad5272_i2c_is_busy();
}
void ad5272_shutdown_mode(void)
{
ad5272_command_write(AD5272_SHUTDOWN, 0x01);
ad5272_i2c_is_busy();
}
void ad5272_normal_mode(void)
{
ad5272_command_write(AD5272_SHUTDOWN, 0x00);
ad5272_i2c_is_busy();
}