STM32H7上实现AD5758驱动

目录

概述

1 下载ADI 5758 Demo

2 AD5758驱动的移植

2.1 使用STM32CubeMX创建工程 

2.2 接口函数实现

2.2.1 驱动接口列表

2.2.2 函数实现

2.2.3 修正ad5758驱动

3 AD5758应用程序

3.1 编写测试程序

3.1.1 配置参数结构

3.1.2 配置参数函数

3.1.3 读取参数函数

3.2 接口调用

4 测试代码


源代码下载地址:

stm32-h750-proj资源-CSDN文库

概述

本文主要介绍使用ADI官方提供的AD5758驱动代码,使用STM32H7驱动该芯片,实现寄存器的配置和读取功能。ADI官方提供的AD5758驱动代码采用阻塞模式配置和读取寄存器信息,在实际使用中,可以可能要对其做相应的调整,本文提供的代码可供参考。

1 下载ADI 5758 Demo

登录如下网址,下载Demo:

https://wiki.analog.com/resources/eval/user-guides/ad5758

该软件包挂载在github上,可使用git命令直接下载,下载命令为:

git clone https://github.com/analogdevicesinc/no-OS/tree/main/projects/ad5758-sdz

下载完成后,打开代码:

2 AD5758驱动的移植

2.1 使用STM32CubeMX创建工程 

使用STM32CubeMX创建工程,创建完成后,使用Keil打开工程

添加ad5758.c 和ad5758.h到项目,并创建接口函数文件:ad5758_io.c

2.2 接口函数实现

2.2.1 驱动接口列表

函数名功能描述
no_os_spi_write_and_readSPI读写数据
ad5758_cs_LOWAD5758芯片片选LOW
ad5758_cs_HIGHTAD5758芯片片选HIGH
reset_chip_LOWAD5758芯片复位LOW
reset_chip_HIGHAD5758芯片复位HIGH
ldac_chip_LOW加载数据引脚置LOW
ldac_chip_HIGH加载数据引脚置HIGH
fault_chip_statusError状态引脚
pwr_status_chipPower状态引脚

2.2.2 函数实现

step- 1: 定义IO接口列表

static const Stru_ad5758Port stru_ad5758PortList[1] =
{{0x00,&hspi2,DAC_SYNC_0_GPIO_Port,DAC_SYNC_0_Pin,DAC_RESET_0_GPIO_Port,DAC_RESET_0_Pin,DAC_LDAC_0_1_GPIO_Port,DAC_LDAC_0_1_Pin,DAC_FAULT_0_GPIO_Port,DAC_FAULT_0_Pin,DAC_PWR_STATUS_0_GPIO_Port,DAC_PWR_STATUS_0_Pin,},  //ad57578 chip-1
};

step-2: 实现接口

详细代码如下:

bool no_os_spi_write_and_read( uint8_t *buff, int len)
{	int i = 0;uint8_t rbuff[len];const Stru_ad5758Port *pAD5758_Port = &stru_ad5758PortList[chip_index];for( i = 0;  i<len; i++  ){rbuff[i] = spi_readWriteByte( pAD5758_Port->spi, buff[i]);}	for( i = 0;  i<len; i++  ){buff[i] = rbuff[i];}	return true;
}void ad5758_cs_LOW( void )
{const Stru_ad5758Port *pAD5758_Port = &stru_ad5758PortList[chip_index];HAL_GPIO_WritePin(pAD5758_Port->SpiCsGPIOx, pAD5758_Port->SpiCsPin, GPIO_PIN_RESET);
}void ad5758_cs_HIGHT( void )
{const Stru_ad5758Port *pAD5758_Port = &stru_ad5758PortList[chip_index];HAL_GPIO_WritePin(pAD5758_Port->SpiCsGPIOx, pAD5758_Port->SpiCsPin, GPIO_PIN_SET); 
}void reset_chip_LOW( void )
{const Stru_ad5758Port *pAD5758_Port = &stru_ad5758PortList[chip_index];HAL_GPIO_WritePin(pAD5758_Port->ResetGPIOx, pAD5758_Port->ResetPin, GPIO_PIN_RESET);
}void reset_chip_HIGH( void )
{const Stru_ad5758Port *pAD5758_Port = &stru_ad5758PortList[chip_index];HAL_GPIO_WritePin(pAD5758_Port->ResetGPIOx, pAD5758_Port->ResetPin, GPIO_PIN_SET); 
}void ldac_chip_LOW( void )
{const Stru_ad5758Port *pAD5758_Port = &stru_ad5758PortList[chip_index];HAL_GPIO_WritePin(pAD5758_Port->DacLoadGPIOx, pAD5758_Port->DacLoadPin, GPIO_PIN_RESET);
}void ldac_chip_HIGH( void )
{const Stru_ad5758Port *pAD5758_Port = &stru_ad5758PortList[chip_index];HAL_GPIO_WritePin(pAD5758_Port->DacLoadGPIOx, pAD5758_Port->DacLoadPin, GPIO_PIN_SET); 
}uint8_t fault_chip_status( void )
{const Stru_ad5758Port *pAD5758_Port = &stru_ad5758PortList[chip_index];return HAL_READ_DAC_PIN(pAD5758_Port->FaultGPIOx, pAD5758_Port->FaultPin); 
}uint8_t pwr_status_chip( void )
{const Stru_ad5758Port *pAD5758_Port = &stru_ad5758PortList[chip_index];return HAL_READ_DAC_PIN(pAD5758_Port->PwrOkGPIOx, pAD5758_Port->PwrOkPin); 
}

2.2.3 修正ad5758驱动

在ad5758.c文件找那个,主要重写调用no_os_spi_write_and_read()函数的接口参数。

修正前该函数调用参数原型为:

修正之后

完整代码如下:

#include "ad5758.h"
#include "ad5758_io.h"/*** Compute CRC8 checksum.* @param data - The data buffer.* @param data_size - The size of the data buffer.* @return CRC8 checksum.*/
static uint8_t ad5758_compute_crc8(uint8_t *data,uint8_t data_size)
{uint8_t i;uint8_t crc = 0;while (data_size) {for (i = 0x80; i != 0; i >>= 1) {if (((crc & 0x80) != 0) != ((*data & i) != 0)) {crc <<= 1;crc ^= AD5758_CRC8_POLY;} else {crc <<= 1;}}data++;data_size--;}return crc;
}/*** Read from device.* @param dev - The device structure.* @param reg_addr - The register address.* @param reg_data - The register data.* @return 0 in case of success, negative error code otherwise.*/
int32_t ad5758_spi_reg_read(struct ad5758_dev *dev,uint8_t reg_addr,uint16_t *reg_data)
{Stru_dataRegister st_dataRegister;uint8_t buf[4];int32_t ret;uint8_t rd_reg_addr;buf[0] = AD5758_REG_WRITE(AD5758_REG_TWO_STAGE_READBACK_SELECT);buf[1] = 0x00;buf[2] = reg_addr;if (dev->crc_en)buf[3] = ad5758_compute_crc8(buf, 3);elsebuf[3] = 0x00;ret = no_os_spi_write_and_read( buf, 4);if (ret < 0)goto spi_err;buf[0] = AD5758_REG_WRITE(AD5758_REG_NOP);buf[1] = 0x00;buf[2] = 0x00;if (dev->crc_en)buf[3] = ad5758_compute_crc8(buf, 3);elsebuf[3] = 0x00;ret = no_os_spi_write_and_read( buf, 4);if (ret < 0)goto spi_err;if ((dev->crc_en) &&(ad5758_compute_crc8(buf, 3) != buf[3]))goto error;*reg_data = (buf[1] << 8) | buf[2];// parser register addressrd_reg_addr = buf[0]&0x1f;#if DEBUG_LOG_AD5758  // update the data structurest_dataRegister.AddressStatus_bit.regiterAddress = rd_reg_addr;st_dataRegister.AddressStatus_bit.FaultStatus = (buf[0]&0x20)>>5;st_dataRegister.AddressStatus_bit.reserved = (buf[0]&0xc0)>>6;	st_dataRegister.crc_8 = buf[3];printf("[no_os_spi_write_and_read]: \r\n");for ( int i = 0; i < 4; i++ ){printf("byte-%d : 0x%02x  \r\n",i, buf[i]);}printf("\r\n\r\n");printf("[parser the data register]: \r\n");printf("reserved:    0x%02x  \r\n",st_dataRegister.AddressStatus_bit.reserved);printf("reg_addr:    0x%02x  \r\n", st_dataRegister.AddressStatus_bit.regiterAddress);printf("FaultStatus: 0x%02x  \r\n",st_dataRegister.AddressStatus_bit.FaultStatus);printf("reg_data:    0x%04x  \r\n",st_dataRegister.data);printf("crc_8:       0x%02x  \r\n",st_dataRegister.crc_8);printf("\r\n\r\n");		
#endif   return 0;spi_err:printf("%s: Failed spi comm with code: %"PRIi32".\n", __func__, ret);return -1;
error:printf("%s: Failed CRC with code: %"PRIi32".\n", __func__, ret);return -1;
}/*** Write to device.* @param dev - The device structure.* @param reg_addr - The register address.* @param reg_data - The register data.* @return 0 in case of success, negative error code otherwise.*/
int32_t ad5758_spi_reg_write(struct ad5758_dev *dev,uint8_t reg_addr,uint16_t reg_data)
{uint8_t buf[4];buf[0] = AD5758_REG_WRITE(reg_addr);buf[1] = (reg_data >> 8);buf[2] = (reg_data & 0xFF);buf[3] = ad5758_compute_crc8(buf, 3);return no_os_spi_write_and_read( buf, 4);
}/*** SPI write to device using a mask.* @param dev - The device structure.* @param reg_addr - The register address.* @param mask - The mask.* @param data - The register data.* @return 0 in case of success, negative error code otherwise.*/
static int32_t ad5758_spi_write_mask(struct ad5758_dev *dev,uint8_t reg_addr,uint32_t mask,uint16_t data)
{uint16_t reg_data;int32_t ret;ret = ad5758_spi_reg_read(dev, reg_addr, &reg_data);if (ret < 0)return -1;reg_data &= ~mask;reg_data |= data;return ad5758_spi_reg_write(dev, reg_addr, reg_data);
}/*** Enable/disable SPI CRC function.* @param dev - The device structure.* @param crc_en - CRC status* Accepted values: 0 - disabled*					1 - enabled* @return 0 in case of success, negative error code otherwise.*/
int32_t ad5758_set_crc(struct ad5758_dev *dev, uint8_t crc_en)
{int32_t ret;ret = ad5758_spi_write_mask(dev, AD5758_REG_DIGITAL_DIAG_CONFIG,AD5758_DIG_DIAG_CONFIG_SPI_CRC_EN_MSK,AD5758_DIG_DIAG_CONFIG_SPI_CRC_EN_MODE(crc_en));if (ret < 0) {printf("%s: Failed with code: %"PRIi32".\n", __func__, ret);return -1;}dev->crc_en = crc_en;return 0;
}/*** Busy wait until CAL_MEM_UNREFRESHED bit in the DIGITAL_DIAG_RESULTS clears* @param dev - The device structure.* @return 0 in case of success*/
int32_t ad5758_wait_for_refresh_cycle(struct ad5758_dev *dev)
{uint16_t reg_data;/** Wait until the CAL_MEM_UNREFRESHED bit in the DIGITAL_DIAG_RESULTS* register returns to 0.*/do {ad5758_spi_reg_read(dev, AD5758_REG_DIGITAL_DIAG_RESULTS,&reg_data);} while (reg_data & AD5758_DIG_DIAG_RESULTS_CAL_MEM_UNREFRESHED_MSK);return 0;
}/*** Initiate a software reset* @param dev - The device structure.* @return 0 in case of success, negative error code otherwise.*/
int32_t ad5758_soft_reset(struct ad5758_dev *dev)
{int32_t ret;ret = ad5758_spi_reg_write(dev, AD5758_REG_KEY,AD5758_KEY_CODE_RESET_1);if (ret < 0)goto error;ret = ad5758_spi_reg_write(dev, AD5758_REG_KEY,AD5758_KEY_CODE_RESET_2);if (ret < 0)goto error;/* Wait 100 us */no_os_udelay(100);return 0;error:printf("%s: Failed with code: %"PRIi32".\n", __func__, ret);return -1;
}/*** Initiate a calibration memory refresh to the shadow registers* @param dev - The device structure.* @return 0 in case of success, negative error code otherwise.*/
int32_t ad5758_calib_mem_refresh(struct ad5758_dev *dev)
{int32_t ret;ret = ad5758_spi_reg_write(dev, AD5758_REG_KEY,AD5758_KEY_CODE_CALIB_MEM_REFRESH);if (ret < 0) {printf("%s: Failed with code: %"PRIi32".\n", __func__, ret);return -1;}/* Wait to allow time for the internal calibrations to complete */return ad5758_wait_for_refresh_cycle(dev);
}/*** Configure the dc-to-dc controller mode* @param dev - The device structure.* @param mode - Mode[1:0] bits.* Accepted values: DC_DC_POWER_OFF*		    DPC_CURRENT_MODE*		    DPC_VOLTAGE_MODE*		    PPC_CURRENT_MODE* @return 0 in case of success, negative error code otherwise.*/
int32_t ad5758_set_dc_dc_conv_mode(struct ad5758_dev *dev,enum ad5758_dc_dc_mode mode)
{uint16_t reg_data;int32_t ret;/** The ENABLE_PPC_BUFFERS bit must be set prior to enabling PPC current* mode.*/if (mode == PPC_CURRENT_MODE) {ret  = ad5758_spi_write_mask(dev, AD5758_REG_ADC_CONFIG,AD5758_ADC_CONFIG_PPC_BUF_MSK,AD5758_ADC_CONFIG_PPC_BUF_EN(1));if (ret < 0)goto error;}ret = ad5758_spi_write_mask(dev, AD5758_REG_DCDC_CONFIG1,AD5758_DCDC_CONFIG1_DCDC_MODE_MSK,AD5758_DCDC_CONFIG1_DCDC_MODE_MODE(mode));if (ret < 0)goto error;/** Poll the BUSY_3WI bit in the DCDC_CONFIG2 register until it is 0.* This allows the 3-wire interface communication to complete.*/do {ad5758_spi_reg_read(dev, AD5758_REG_DCDC_CONFIG2, &reg_data);} while (reg_data & AD5758_DCDC_CONFIG2_BUSY_3WI_MSK);dev->dc_dc_mode = mode;return 0;error:printf("%s: Failed with code: %"PRIi32".\n", __func__, ret);return -1;
}/*** Set the dc-to-dc converter current limit.* @param dev - The device structure.* @param ilimit - current limit in mA* Accepted values: ILIMIT_150_mA*		    ILIMIT_200_mA*		    ILIMIT_250_mA*		    ILIMIT_300_mA*		    ILIMIT_350_mA*		    ILIMIT_400_mA* @return 0 in case of success, negative error code otherwise.*/
int32_t ad5758_set_dc_dc_ilimit(struct ad5758_dev *dev,enum ad5758_dc_dc_ilimt ilimit)
{uint16_t reg_data;int32_t ret;ret = ad5758_spi_write_mask(dev, AD5758_REG_DCDC_CONFIG2,AD5758_DCDC_CONFIG2_ILIMIT_MSK,AD5758_DCDC_CONFIG2_ILIMIT_MODE(ilimit));if (ret < 0) {printf("%s: Failed with code: %"PRIi32".\n", __func__, ret);return -1;}/** Poll the BUSY_3WI bit in the DCDC_CONFIG2 register until it is 0.* This allows the 3-wire interface communication to complete.*/do {ad5758_spi_reg_read(dev, AD5758_REG_DCDC_CONFIG2, &reg_data);} while (reg_data & AD5758_DCDC_CONFIG2_BUSY_3WI_MSK);dev->dc_dc_ilimit = ilimit;return 0;
}/*** Enable/disable Enable Internal Buffers.* @param dev - The device structure.* @param enable - enable or disable* Accepted values: 0: disable* 		    1: enable* @return 0 in case of success, negative error code otherwise.*/
int32_t ad5758_internal_buffers_en(struct ad5758_dev *dev, uint8_t enable)
{int32_t ret;ret = ad5758_spi_write_mask(dev, AD5758_REG_DAC_CONFIG,AD5758_DAC_CONFIG_INT_EN_MSK,AD5758_DAC_CONFIG_INT_EN_MODE(enable));if (ret < 0) {printf("%s: Failed with code: %"PRIi32".\n", __func__, ret);return -1;}/* Wait to allow time for the internal calibrations to complete */return ad5758_wait_for_refresh_cycle(dev);
}/*** Select Output Range.* @param dev - The device structure.* @param range - output range* Accepted values: RANGE_0V_5V*		    RANGE_0V_10V*		    RANGE_M5V_5V*		    RANGE_M10V_10V*		    RANGE_0mA_20mA*		    RANGE_0mA_24mA*		    RANGE_4mA_24mA*		    RANGE_M20mA_20mA*		    RANGE_M24mA_24mA*		    RANGE_M1mA_22mA* @return 0 in case of success, negative error code otherwise.*/
int32_t ad5758_set_out_range(struct ad5758_dev *dev,enum ad5758_output_range range)
{int32_t ret;ret = ad5758_spi_write_mask(dev, AD5758_REG_DAC_CONFIG,AD5758_DAC_CONFIG_RANGE_MSK,AD5758_DAC_CONFIG_RANGE_MODE(range));if (ret < 0) {printf("%s: Failed with code: %"PRIi32".\n", __func__, ret);return -1;}dev->output_range = range;/* Modifying the RANGE bits in the DAC_CONFIG register also initiates* a calibration memory refresh and, therefore, a subsequent SPI write* must not be performed until the CAL_MEM_UNREFRESHED bit in the* DIGITAL_DIAG_RESULTS register returns to 0.*/return ad5758_wait_for_refresh_cycle(dev);
}/*** Configure the slew rate by setting the clock and enable/disable the control* @param dev - The device structure.* @param clk - Slew rate clock.* Accepted values: SR_CLOCK_240_KHZ*		    SR_CLOCK_200_KHZ*		    SR_CLOCK_150_KHZ*		    SR_CLOCK_128_KHZ*		    SR_CLOCK_64_KHZ*		    SR_CLOCK_32_KHZ*		    SR_CLOCK_16_KHZ*		    SR_CLOCK_8_KHZ*		    SR_CLOCK_4_KHZ*		    SR_CLOCK_2_KHZ*		    SR_CLOCK_1_KHZ*		    SR_CLOCK_512_HZ*		    SR_CLOCK_256_HZ*		    SR_CLOCK_128_HZ*		    SR_CLOCK_64_HZ*		    SR_CLOCK_16_HZ* @param enable - enable or disable the sr coontrol* Accepted values: 0: disable* 		    1: enable* @return 0 in case of success, negative error code otherwise.*/
int32_t ad5758_slew_rate_config(struct ad5758_dev *dev,enum ad5758_slew_rate_clk clk,uint8_t enable)
{int32_t ret;ret = ad5758_spi_write_mask(dev, AD5758_REG_DAC_CONFIG,AD5758_DAC_CONFIG_SR_EN_MSK,AD5758_DAC_CONFIG_SR_EN_MODE(enable));if(ret)goto error;ret = ad5758_spi_write_mask(dev, AD5758_REG_DAC_CONFIG,AD5758_DAC_CONFIG_SR_CLOCK_MSK,AD5758_DAC_CONFIG_SR_CLOCK_MODE(clk));if (ret < 0)goto error;dev->slew_rate_clk = clk;/* Wait to allow time for the internal calibrations to complete */return ad5758_wait_for_refresh_cycle(dev);error:printf("%s: Failed with code: %"PRIi32".\n", __func__, ret);return -1;
}/*** Write DAC data to the input register* @param dev - The device structure.* @param code - DAC input data of 16 bits* Accepted values: 0x00 to 0xFFFF* @return 0 in case of success, negative error code otherwise.*/
int32_t ad5758_dac_input_write(struct ad5758_dev *dev, uint16_t code)
{int32_t ret;ret = ad5758_spi_reg_write(dev, AD5758_REG_DAC_INPUT, code);if (ret < 0) {printf("%s: Failed with code: %"PRIi32".\n", __func__, ret);return -1;}return 0;
}/*** Enable/disable VIOUT.* @param dev - The device structure.* @param enable - enable or disable VIOUT output* Accepted values: 0: disable* 		    1: enable* @return 0 in case of success, negative error code otherwise.*/
int32_t ad5758_dac_output_en(struct ad5758_dev *dev, uint8_t enable)
{int32_t ret;ret = ad5758_spi_write_mask(dev, AD5758_REG_DAC_CONFIG,AD5758_DAC_CONFIG_OUT_EN_MSK,AD5758_DAC_CONFIG_OUT_EN_MODE(enable));if (ret < 0) {printf("%s: Failed with code: %"PRIi32".\n", __func__, ret);return -1;}no_os_mdelay(1);return 0;
}/*** Clear the error flags for the on-chip digital diagnostic features* @param dev - The device structure.* @param flag - which flag to clear* Accepted values: DIAG_SPI_CRC_ERR* 		    DIAG_SLIPBIT_ERR* 		    DIAG_SCLK_COUNT_ERR* 		    DIAG_INVALID_SPI_ACCESS_ERR* 		    DIAG_CAL_MEM_CRC_ERR* 		    DIAG_INVERSE_DAC_CHECK_ERR* 		    DIAG_DAC_LATCH_MON_ERR* 		    DIAG_THREE_WI_RC_ERR* 		    DIAG_WDT_ERR* 		    DIAG_ERR_3WI* 		    DIAG_RESET_OCCURRED* @return 0 in case of success, negative error code otherwise.*/
int32_t ad5758_clear_dig_diag_flag(struct ad5758_dev *dev,enum ad5758_dig_diag_flags flag)
{int32_t ret;/** Flags require a 1 to be written to them to update them to their* current value*/ret = ad5758_spi_write_mask(dev, AD5758_REG_DIGITAL_DIAG_RESULTS,NO_OS_BIT(flag), NO_OS_BIT(flag));if (ret < 0) {printf("%s: Failed with code: %"PRIi32".\n", __func__, ret);return -1;}return 0;
}/*** Configure CLKOUT by setting the frequency and enabling/disabling the option* @param dev - The device structure.* @param config - Enable or disable* Accepted values: CLKOUT_DISABLE* 		    CLKOUT_ENABLE* @param freq - configure the frequency of CLKOUT.* Accepted values: CLKOUT_FREQ_416_KHZ* 		    CLKOUT_FREQ_435_KHZ* 		    CLKOUT_FREQ_454_KHZ* 		    CLKOUT_FREQ_476_KHZ* 		    CLKOUT_FREQ_500_KHZ* 		    CLKOUT_FREQ_526_KHZ* 		    CLKOUT_FREQ_555_KHZ* 		    CLKOUT_FREQ_588_KHZ* @return 0 in case of success, negative error code otherwise.*/
int32_t ad5758_set_clkout_config(struct ad5758_dev *dev,enum ad5758_clkout_config config,enum ad5758_clkout_freq freq)
{int32_t ret;ret = ad5758_spi_write_mask(dev, AD5758_REG_GP_CONFIG1,AD5758_GP_CONFIG1_CLKOUT_FREQ_MSK,AD5758_GP_CONFIG1_CLKOUT_FREQ_MODE(freq));if(ret < 0)goto error;ret = ad5758_spi_write_mask(dev, AD5758_REG_GP_CONFIG1,AD5758_GP_CONFIG1_CLKOUT_CONFIG_MSK,AD5758_GP_CONFIG1_CLKOUT_CONFIG_MODE(config));if(ret < 0)goto error;dev->clkout_config = config;dev->clkout_freq = freq;return 0;error:printf("%s: Failed with code: %"PRIi32".\n", __func__, ret);return -1;
}/*** Select which node to multiplex to the ADC.* @param dev - The device structure.* @param adc_ip_sel - diagnostic select* Accepted values: ADC_IP_MAIN_DIE_TEMP* 		    ADC_IP_DCDC_DIE_TEMP* 		    ADC_IP_REFIN* 		    ADC_IP_REF2* 		    ADC_IP_VSENSE* 		    ADC_IP_MVSENSE* 		    ADC_IP_INT_AVCC* 		    ADC_IP_REGOUT* 		    ADC_IP_VLOGIC* 		    ADC_IP_INT_CURR_MON_VOUT* 		    ADC_IP_REFGND* 		    ADC_IP_AGND* 		    ADC_IP_DGND* 		    ADC_IP_VDPC* 		    ADC_IP_AVDD2* 		    ADC_IP_AVSS* 		    ADC_IP_DCDC_DIE_NODE* 		    ADC_IP_REFOUT* @return 0 in case of success, negative error code otherwise.*/
int32_t ad5758_select_adc_ip(struct ad5758_dev *dev,enum ad5758_adc_ip adc_ip_sel)
{int32_t ret;ret = ad5758_spi_write_mask(dev, AD5758_REG_ADC_CONFIG,AD5758_ADC_CONFIG_ADC_IP_SELECT_MSK,AD5758_ADC_CONFIG_ADC_IP_SELECT_MODE(adc_ip_sel));if (ret < 0) {printf("%s: Failed with code: %"PRIi32".\n", __func__, ret);return -1;}return 0;
}/*** Set depth of the sequencer.* @param dev - The device structure.* @param num_of_channels - depth of the sequencer 1 to 8 channels* Accepted values: 1 channel, 2 channels ... 8 channels* @return 0 in case of success, negative error code otherwise.*/
int32_t ad5758_select_adc_depth(struct ad5758_dev *dev,uint8_t num_of_channels)
{int32_t ret = -1;if ((num_of_channels == 0) || (num_of_channels > 8)) {printf("%s: Failed with code: %"PRIi32".\n", __func__, ret);return ret;}num_of_channels -= 1;ret = ad5758_spi_reg_write(dev, AD5758_REG_ADC_CONFIG,AD5758_ADC_CONFIG_SEQUENCE_DATA_MODE(num_of_channels));if (ret < 0) {printf("%s: Failed with code: %"PRIi32".\n", __func__, ret);return ret;}return 0;
}/*** Load the desired channel into the sequencer with the adc input* @param dev - The device structure.* @param channel - Desired channel* Accepted values: 0 = channel 1, 1 = channel 2... 7 = channel 8* @param adc_ip_sel - diagnostic select* Accepted values: ADC_IP_MAIN_DIE_TEMP* 		    ADC_IP_DCDC_DIE_TEMP* 		    ADC_IP_REFIN* 		    ADC_IP_REF2* 		    ADC_IP_VSENSE* 		    ADC_IP_MVSENSE* 		    ADC_IP_INT_AVCC* 		    ADC_IP_REGOUT* 		    ADC_IP_VLOGIC* 		    ADC_IP_INT_CURR_MON_VOUT* 		    ADC_IP_REFGND* 		    ADC_IP_AGND* 		    ADC_IP_DGND* 		    ADC_IP_VDPC* 		    ADC_IP_AVDD2* 		    ADC_IP_AVSS* 		    ADC_IP_DCDC_DIE_NODE* 		    ADC_IP_REFOUT* @return 0 in case of success, negative error code otherwise.*/
int32_t ad5758_set_adc_channel_input(struct ad5758_dev *dev,uint8_t channel,enum ad5758_adc_ip adc_ip_sel)
{uint16_t cmd;int32_t ret;cmd = (AD5758_ADC_CONFIG_SEQUENCE_COMMAND_MODE(0x01) |AD5758_ADC_CONFIG_SEQUENCE_DATA_MODE(channel) |AD5758_ADC_CONFIG_ADC_IP_SELECT_MODE(adc_ip_sel));ret = ad5758_spi_reg_write(dev, AD5758_REG_ADC_CONFIG, cmd);if (ret < 0) {printf("%s: Failed with code: %"PRIi32".\n", __func__, ret);return -1;}return 0;
}/*** Configure the ADC into one of four modes of operation* @param dev - The device structure.* @param adc_mode - ADC mode of operation* Accepted values: ADC_MODE_KEY_SEQ* 		    ADC_MODE_AUTO_SEQ* 		    ADC_MODE_SINGLE_CONV* 		    ADC_MODE_SINGLE_KEY_CONV* @param enable - enable or disable the selected mode* Accepted values: 0: disable* 		    1: enable* @return 0 in case of success, negative error code otherwise.*/
int32_t ad5758_set_adc_mode(struct ad5758_dev *dev,enum ad5758_adc_mode adc_mode,uint8_t enable)
{uint16_t cmd;int32_t ret;cmd = (AD5758_ADC_CONFIG_SEQUENCE_COMMAND_MODE(adc_mode) |AD5758_ADC_CONFIG_SEQUENCE_DATA_MODE(enable));ret = ad5758_spi_reg_write(dev, AD5758_REG_ADC_CONFIG, cmd);if (ret < 0) {printf("%s: Failed with code: %"PRIi32".\n", __func__, ret);return -1;}return 0;
}/*** Configure the dc-to-dc controller mode* @param dev - The device structure.* @param mode - Mode[1:0] bits.* Accepted values: DC_DC_POWER_OFF*                  DPC_CURRENT_MODE*                  DPC_VOLTAGE_MODE*                  PPC_CURRENT_MODE* @return 0 in case of success, negative error code otherwise.*/
int32_t ad5758_set_dc_dc_conv_mode_ext(struct ad5758_dev *pdev, enum ad5758_dc_dc_mode mode)
{uint16_t reg_data;int32_t ret;#if DEBUG_LOG_AD5758printf("ad5758_set_dc_dc_conv_mode_ext: \r\n\r\n\r\n");
#endif/** The ENABLE_PPC_BUFFERS bit must be set prior to enabling PPC current* mode.*/if (mode == PPC_CURRENT_MODE) {ret  = ad5758_spi_write_mask(pdev, AD5758_REG_ADC_CONFIG,AD5758_ADC_CONFIG_PPC_BUF_MSK,AD5758_ADC_CONFIG_PPC_BUF_EN(1));if (ret < 0)goto error;}ret = ad5758_spi_write_mask(pdev, AD5758_REG_DCDC_CONFIG1,AD5758_DCDC_CONFIG1_DCDC_MODE_MSK,AD5758_DCDC_CONFIG1_DCDC_MODE_MODE(mode));if (ret < 0)goto error;/** Poll the BUSY_3WI bit in the DCDC_CONFIG2 register until it is 0.* This allows the 3-wire interface communication to complete.*/do {ad5758_spi_reg_read(pdev, AD5758_REG_DCDC_CONFIG2, &reg_data);} while (reg_data & AD5758_DCDC_CONFIG2_BUSY_3WI_MSK);return 0;error:printf("Failed with code: %d\n",ret);return -1;
}int32_t ad5758_set_clkout_config_ext( struct ad5758_dev *pdev, enum ad5758_clkout_config config,enum ad5758_clkout_freq freq)
{int32_t ret;#if DEBUG_LOG_AD5758printf("ad5758_set_clkout_config_ext: \r\n\r\n\r\n");
#endifret = ad5758_spi_write_mask( pdev, AD5758_REG_GP_CONFIG1,AD5758_GP_CONFIG1_CLKOUT_FREQ_MSK,AD5758_GP_CONFIG1_CLKOUT_FREQ_MODE(freq));if(ret < 0)goto error;ret = ad5758_spi_write_mask( pdev, AD5758_REG_GP_CONFIG1,AD5758_GP_CONFIG1_CLKOUT_CONFIG_MSK,AD5758_GP_CONFIG1_CLKOUT_CONFIG_MODE(config));if(ret < 0)goto error;return 0;error:printf("Failed with code: %d\n",ret);return -1;
}int32_t ad5758_reg_AutostatusReadbackMode(struct ad5758_dev *pdev,uint8_t reg_addr,uint16_t *reg_data)
{uint8_t buf[4];uint8_t _read_buff[4];int32_t ret;uint8_t cal_crc = 0;uint8_t r_reg_addr = 0;uint8_t reserved = 0;Stru_dataRegister st_dataRegister;do{             buf[0] = AD5758_REG_WRITE(AD5758_REG_TWO_STAGE_READBACK_SELECT);buf[1] = 0x00;buf[2] = reg_addr;buf[3] = ad5758_compute_crc8(buf, 3);ret = no_os_spi_write_and_read(buf, 4);buf[0] = AD5758_REG_WRITE(AD5758_REG_NOP);buf[1] = 0x00;buf[2] = 0x00;buf[3] = ad5758_compute_crc8(buf, 3);ret = no_os_spi_write_and_read( buf, 4);// handle the result herecal_crc = ad5758_compute_crc8(_read_buff, 3);// parser register addressr_reg_addr = _read_buff[0]&0x1f;// reserved falgreserved = (_read_buff[0]&0xc0)>>6;#if DEBUG_LOG_AD5758  printf("[read register bytes]: \r\n");for ( int i = 0; i < 4; i++ ){printf("byte-%d : 0x%02x  \r\n",i, _read_buff[i]);}
#endif   // update the data structurest_dataRegister.AddressStatus_bit.regiterAddress = r_reg_addr;st_dataRegister.AddressStatus_bit.FaultStatus = (_read_buff[0]&0x20)>>5;st_dataRegister.AddressStatus_bit.reserved = reserved;*reg_data = (_read_buff[1] << 8) | _read_buff[2];st_dataRegister.data = *reg_data;st_dataRegister.crc_8 = _read_buff[3];#if DEBUG_LOG_AD5758  printf("\r\n\r\n");printf("[parser the data register]: \r\n");printf("reserved:    0x%02x  \r\n",st_dataRegister.AddressStatus_bit.reserved);printf("reg_addr:    0x%02x  \r\n", st_dataRegister.AddressStatus_bit.regiterAddress);printf("FaultStatus: 0x%02x  \r\n",st_dataRegister.AddressStatus_bit.FaultStatus);printf("reg_data:    0x%04x  \r\n",st_dataRegister.data);printf("crc_8:       0x%02x  \r\n",st_dataRegister.crc_8);printf("\r\n\r\n");
#endif        }while(reserved != AD5758_RESERVED);return 0;spi_err:printf("- Failed spi comm with code\n");return -1;
error:printf("- Failed CRC with code: %d \n",ret);return -1;
}

3 AD5758应用程序

3.1 编写测试程序

调用ad5758.c和ad5758_io.c中的接口,实现测试程序,该程序要实现的任务如下:

1)配置参数

2)使能输出属性(电流/电压)

3)读出配置参数

3.1.1 配置参数结构

代码第7行: 配置电压模式输出

代码第11行:电压输出范围为:0 ~ 10V

3.1.2 配置参数函数

该函数主要实现初始化参数功能,配置方法严格遵守AD5758 data sheet 上给出的流程

int32_t ad5758_init( struct ad5758_init_param *init_param )
{uint16_t reg_data_list[] = {0, 0x7FFF,0x6FFF, 0x5FFF,0x4FFF,0x3FFF,0x2FFF, 0x1FFF};struct ad5758_dev *dev = &stru_dev;int32_t ret;// select the chip select_ad5758_chip(0);printf("debug_ad5758_init:  \r\n\r\n");/* Get the DAC out of reset */reset_chip_HIGH();/* Tie the LDAC pin low */ldac_chip_LOW();dev->crc_en = true;/* Perform a software reset */ret = ad5758_soft_reset(dev);if(ret)goto err;/* Perform a calibration memory refresh */ret = ad5758_calib_mem_refresh(dev);if(ret)goto err;/* Clear the RESET_OCCURRED flag */ret = ad5758_clear_dig_diag_flag(dev, DIAG_RESET_OCCURRED);if(ret)goto err;/* Configure CLKOUT before enabling the dc-to-dc converter */ret = ad5758_set_clkout_config(dev, init_param->clkout_config,init_param->clkout_freq);if(ret)goto err;/* Set the dc-to-dc current limit */ret = ad5758_set_dc_dc_ilimit(dev, init_param->dc_dc_ilimit);if(ret)goto err;/* Set up the dc-to-dc converter mode */ret = ad5758_set_dc_dc_conv_mode(dev, init_param->dc_dc_mode);if(ret)goto err;/* Power up the DAC and internal (INT) amplifiers */ret = ad5758_internal_buffers_en(dev, 1);if(ret)goto err;/* Configure the output range */ret = ad5758_set_out_range(dev, init_param->output_range);if(ret)goto err;/* Enable Slew Rate Control and set the slew rate clock */ret = ad5758_slew_rate_config(dev, init_param->slew_rate_clk, 1);if(ret)goto err;ad5758_dac_input_write( dev ,reg_data_list[0]); /* Enable VIOUT */ret = ad5758_dac_output_en(dev, 1);if(ret)goto err;printf("ad5758 successfully initialized\n");no_os_mdelay(1000);return 0;err:printf("initialized ad5758 error \n");return -1;
}

3.1.3 读取参数函数

该函数主要实现读取配置参数,并通过串口终端打印出来

int32_t debug_ad5758_readconfig( void )
{int32_t ret;uint16_t reg_data;struct ad5758_dev *dev = &stru_dev;printf("debug_ad5758_config:  \r\n\r\n");  // select the chip select_ad5758_chip(0);printf("debug_ad5758_config: AD5758_REG_DCDC_CONFIG1 \r\n\r\n");  ret = ad5758_reg_AutostatusReadbackMode( dev, AD5758_REG_DCDC_CONFIG1, &reg_data);if (ret < 0)goto err;/* read  AD5758_REG_DIGITAL_DIAG_RESULTS */printf("debug_ad5758_config: AD5758_REG_DIGITAL_DIAG_RESULTS \r\n\r\n");  ret = ad5758_reg_AutostatusReadbackMode( dev, AD5758_REG_DIGITAL_DIAG_RESULTS, &reg_data);if (ret < 0)goto err;/* read  AD5758_REG_DIGITAL_DIAG_RESULTS */printf("debug_ad5758_config: AD5758_REG_ANALOG_DIAG_RESULTS \r\n\r\n");  ret = ad5758_reg_AutostatusReadbackMode( dev, AD5758_REG_ANALOG_DIAG_RESULTS, &reg_data);if (ret < 0)goto err;/* read  AD5758_REG_FREQ_MONITOR */printf("debug_ad5758_config: AD5758_REG_FREQ_MONITOR \r\n\r\n");  ret = ad5758_reg_AutostatusReadbackMode( dev, AD5758_REG_FREQ_MONITOR, &reg_data);if (ret < 0)goto err;/* read  AD5758_REG_DAC_OUTPUT */printf("debug_ad5758_config: AD5758_REG_DAC_OUTPUT \r\n\r\n");  ret = ad5758_reg_AutostatusReadbackMode( dev, AD5758_REG_DAC_OUTPUT, &reg_data);if (ret < 0)goto err;/* read  AD5758_REG_DAC_CONFIG */printf("debug_ad5758_config: AD5758_REG_DAC_CONFIG \r\n\r\n");  ret = ad5758_reg_AutostatusReadbackMode( dev, AD5758_REG_DAC_CONFIG, &reg_data);if (ret < 0)goto err;printf("read config parameter: pass \r\n\r\n");return ret;err:printf(" debug_ad5758_config: fail \r\n\r\n");return 0;
}void appA5758_Init( void )
{ad5758_init( &init_param );debug_ad5758_readconfig();
}

3.2 接口调用

编写函数appA5758_Init()调用以上接口,详细代码如下:

void appA5758_Init( void )
{ad5758_init( &init_param );debug_ad5758_readconfig();
}

在主函数Task中调用该函数:

4 测试代码

在ad5758_init()函数和debug_ad5758_readconfig()中分别添加两个断点

1)运行ad5758_init() 函数中的断点

 2)运行debug_ad5758_readconfig()中的断点

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/819031.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

时隔一年,再次讨论下AutoGPT-安装篇

AutoGPT是23年3月份推出的&#xff0c;距今已经1年多的时间了。刚推出时&#xff0c;我们还只能通过命令行使用AutoGPT的能力&#xff0c;但现在&#xff0c;我们不仅可以基于AutoGPT创建自己的Agent&#xff0c;我们还可以通过Web页面与我们创建的Agent进行聊天。这次的AutoGP…

设计模式——观察者模式17

观察者模式指多个对象间存在一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式。 中介者模式是N对N的双向关系。观察者模式是1对N的单向关系。 设计模式&#xff0c;一定要敲代码…

腾讯EdgeOne产品测评体验—金字塔般的网络安全守护神

作为一名对网络安全和性能优化充满热情的用户&#xff0c;我决定体验腾讯云下一代 CDN 服务 - EdgeOne。这款引以为傲的全方位服务如数来到&#xff0c;从域名解析、动静态智能加速到四层加速及DDoS/CC/Web/Bot 防护&#xff0c;一应俱全。随着时代风云变幻&#xff0c;日均数千…

高级数据结构与算法习题(7)

一、单选题 1、When solving a problem with input size N by divide and conquer, if at each stage the problem is divided into 8 sub-problems of equal size N/3, and the conquer step takes O(N2logN) to form the solution from the sub-solutions, then the overall…

Linux调试器之gdb

前言 我们前面介绍了几个基本的环境开发工具。例如通过yum我们可以安装和卸载软件、通过vim我们可以写代码、通过gcc和g我们可以编译代码成可执行程序。但是如何在Linux下调试代码呢&#xff1f;我们并未介绍&#xff0c;本期我们将来介绍最后一个工具 --- 调试器gdb。 本期内…

DAY13|239. 滑动窗口最大值、347.前K个高频元素

239. 滑动窗口最大值、347.前 K 个高频元素 239. 滑动窗口最大值347.前 K 个高频元素 239. 滑动窗口最大值 难度有些大啊… 其实队列没有必要维护窗口里的所有元素&#xff0c;只需要维护有可能成为窗口里最大值的元素就可以了&#xff0c;同时保证队列里的元素数值是由大到小…

基于U-Net的图像分割算法介绍

U-Net是一种用于图像分割的深度学习架构,其设计初衷是用于生物医学图像分割,尤其是医学影像中的细胞分割任务。U-Net结构独特,具有编码器-解码器结构,能够有效地捕捉图像中的局部和全局信息,并在像素级别上进行精确的分割。 相关论文: U-Net: Convolutional Networks for…

密码学基础 -- 走进RSA(2)(放弃数学原理版)

目录 1.概述 2. RSA测试 2.1 加解密实验 2.2 签名验签测试 3. RSA原理简介 4.小结 1.概述 从上面密码学基础 -- 走进RSA(1)(放弃数学原理版)-CSDN博客我们知道了非对称算法的密钥对使用时机&#xff0c;那么接下里我们继续讲解RSA&#xff0c;我们分别从RSA加解密、签名验…

科大讯飞星火开源大模型iFlytekSpark-13B GPU版部署方法

星火大模型的主页&#xff1a;iFlytekSpark-13B: 讯飞星火开源-13B&#xff08;iFlytekSpark-13B&#xff09;拥有130亿参数&#xff0c;新一代认知大模型&#xff0c;一经发布&#xff0c;众多科研院所和高校便期待科大讯飞能够开源。 为了让大家使用的更加方便&#xff0c;科…

leetcode-链表中间节点

876. 链表的中间结点 题目 给你单链表的头结点 head &#xff0c;请你找出并返回链表的中间结点。 如果有两个中间结点&#xff0c;则返回第二个中间结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[3,4,5] 解释&#xff1a;链表只有一个中间…

12.MySQL应用架构演变

MySQL应用架构演变 1.总览 单机单库主从架构分库分表云数据库 2.单机单库 介绍 一个简单的小型网站或者应用背后的架构可以非常简单&#xff0c;数据存储只需要一个MySQL Instance就能满足数据读取和写入需求&#xff08;这里忽略掉了数据备份的实例&#xff09;&#xff…

三款好用的 Docker 可视化管理工具

文章目录 1、Docker Desktop1.1、介绍1.2、下载地址1.3、在Windows上安装Docker桌面1.4、启动Docker Desktop1.5、Docker相关学习网址 2、Portainer2.1、介绍2.2、安装使用 3、Docker UI3.1、介绍3.2、安装使用3.2.1、常规方式安装3.2.2、通过容器安装 Docker提供了命令行工具&…

【vue】购物车案例

change"fun"&#xff1a;元素值发生改变时&#xff0c;会触发事件fun <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale…

Qt创建基于应用程序的插件

应用程序插件 什么是插件插件的好处插件的种类应用程序插件创建应用程序的插件步骤:创建测试插件的应用程序步骤:应用程序插件示例开发环境创建示例生成插件运行结果总结什么是插件 插件是一种用于应用程序功能扩展和增强,且按照特定规范编写的应用程序接口的程序。 插件的…

linux 自定义快捷指令(docker

vi /root/.bashrc alias disdocker images alias dpsdocker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}" 保存退出后使用sourece /root/.bashrc 让其立即生效 sourece /root/.bashrc

Python学习笔记(37)——用xlwings库生成excel

老规矩先pip入xlwings库 STEP1:下载xlwings库 windowsr>>cmd>>pip install xlwings (如果需要不同版本可以到pypi上搜&#xff09; STEP2:完成EXCEL初级创建 请打开您的编写软件~~~~~&#xff08;小编的显示结果为PYCHARM编写的&#xff0c;因为颜色标注好看(…

【论文笔记】PointMamba: A Simple State Space Model for Point Cloud Analysis

原文链接&#xff1a;https://arxiv.org/abs/2402.10739 1. 引言 基于Transformer的点云分析方法有二次时空复杂度&#xff0c;一些方法通过限制感受野降低计算。这引出了一个问题&#xff1a;如何设计方法实现线性复杂度并有全局感受野。 状态空间模型&#xff08;SSM&…

蓝桥杯 — — 纯质数

纯质数 题目&#xff1a; 思路&#xff1a; 一个最简单的思路就是枚举出所有的质数&#xff0c;然后再判断这个质数是否是一个纯质数。 枚举出所有的质数&#xff1a; 可以使用常规的暴力求解法&#xff0c;其时间复杂度为&#xff08; O ( N N ) O(N\sqrt{N}) O(NN ​)&…

SQL12 获取每个部门中当前员工薪水最高的相关信息

题目&#xff1a;获取每个部门中当前员工薪水最高的相关信息 注意了&#xff0c;这道题目&#xff0c;分组函数只能查出来&#xff1a;每个部门的最高薪水&#xff0c;group by dept_no &#xff0c;根据部门分组&#xff0c;绝对不能group by dept_no,emp_no&#xff0c;不能…

学习一门语言的方法和套路(B站转述)

视频链接 up虽然长相英(ping)俊(ping)&#xff0c;但是讲的干活&#xff0c;没恰饭。 学习流程&#xff1a; 1.快速阅读&#xff0c;掌握概况 2.深入细节内容 例如&#xff1a;java (JDBC)、html 、netty 不管三七二十一&#xff0c;先了解套路&#xff0c;再深入研究。 高…