Initial commit: MT firmware project
- BLE peripheral applications - dr_piezo and bladder_patch projects Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
299
project/ble_peripheral/ble_app_bladder_patch/ad5272_i2c.c
Normal file
299
project/ble_peripheral/ble_app_bladder_patch/ad5272_i2c.c
Normal file
@@ -0,0 +1,299 @@
|
||||
/*******************************************************************************
|
||||
* @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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user