[ADD] ADS8688 Driver

This commit is contained in:
guzz 2024-11-29 17:31:12 +08:00
parent 3bc41217d8
commit 7ac4bcd37b
2 changed files with 221 additions and 0 deletions

View File

@ -0,0 +1,126 @@
#include "ads8688.h"
#include "drv_spi.h"
#include "gpio_manager.h"
void ads8688_write_command_reg(uint16_t command)
{
uint8_t command_data[2] = {0, 0};
command_data[0] = (uint8_t) (command >> 8);
command_data[1] = (uint8_t) (command & 0x00FF);
drv_spi_sync_send_receive(kSpiDev_2, command_data);
}
void ads8688_write_program_reg(uint8_t addr, uint8_t data)
{
uint8_t w_data[2] = {0, 0};
w_data[0] = (addr < 1) | 0x01;
w_data[1] = data;
drv_spi_sync_send_receive(kSpiDev_2, w_data);
}
void ads8688_read_program_reg(uint8_t addr)
{
uint8_t r_data[2] = {0, 0};
uint8_t RxBuff;
r_data[0] = (addr < 1);
drv_spi_series_sync_send_receive(kSpiDev_2, r_data, 2, &RxBuff, 1);
}
void ads8688_enter_auto_rst_mode()
{
ads8688_write_command_reg(AUTO_RST);
}
void ads8688_set_autoscan_sequence(uint8_t data)
{
ads8688_write_program_reg(AUTO_SEQ_EN, data);
}
void ads8688_set_ch_range_select(uint8_t ch, uint8_t range)
{
ads8688_write_program_reg(ch, range);
}
void ads8688_set_channel_power_down(uint8_t pwd)
{
ads8688_write_program_reg(Channel_Power_Down, pwd);
}
short ads8688_adc_data_convert(uint16_t x, uint8_t AI_RANGE)
{
short y;
switch(AI_RANGE) {
case 0:
y = x * 15625 / 100000; //channel range 0~10.24V
break;
case 1:
y = x * 78125 / 1000000; //channel range 0~5.12V
break;
case 2:
y = (x - 0x8000) * 3125 / 10000; //channel range 10.24V
break;
case 3:
y = (uint16_t)(((double)(x - 32768) * 10.24 / (double)65535) * 1000); //channel range 5.12V
break;
case 4:
y = (uint16_t)(((double)(x - 32768) * 5.12 / (double)65535) * 1000); //channel range 2.56V
break;
}
return y;
}
uint16_t adc_data[8];
uint16_t adc_real[8];
void ads8688_get_real_adc_data(uint16_t *adc_real, uint8_t AI_RANGE)
{
adc_real[0] = (uint16_t)ads8688_adc_data_convert(adc_data[0], AI_RANGE);
adc_real[1] = (uint16_t)ads8688_adc_data_convert(adc_data[1], AI_RANGE);
adc_real[2] = (uint16_t)ads8688_adc_data_convert(adc_data[2], AI_RANGE);
adc_real[3] = (uint16_t)ads8688_adc_data_convert(adc_data[3], AI_RANGE);
adc_real[4] = (uint16_t)ads8688_adc_data_convert(adc_data[4], AI_RANGE);
adc_real[5] = (uint16_t)ads8688_adc_data_convert(adc_data[5], AI_RANGE);
adc_real[6] = (uint16_t)ads8688_adc_data_convert(adc_data[6], AI_RANGE);
adc_real[7] = (uint16_t)ads8688_adc_data_convert(adc_data[7], AI_RANGE);
}
void Get_AUTO_RST_Mode_Data(uint8_t chn)
{
uint16_t i = 0;
for(i = 0; i < chn; i++)
{
uint8_t data;
drv_spi_sync_send_rev(kSpiDev_2, data);
adc_data[i] = data << 8;
drv_spi_sync_send_rev(kSpiDev_2, data);
adc_data[i] = data;
}
}
void get_ADS_all(uint8_t chn, uint16_t *adc_real, uint8_t AI_RANGE)
{
Get_AUTO_RST_Mode_Data(chn);
ads8688_get_real_adc_data(adc_real, AI_RANGE);
}
void ads8688_init()
{
drv_spi_init(kSpiDev_2, kSpiFreq_Div16, kSpiMode_C1E0, SpiFrame_MSBFirst, kGpioType_ADC_Clk, kGpioType_ADC_Miso, kGpioType_ADC_Mosi);
//drv_spi_set_dma(kSpiDev_2, true, false);
ads8688_set_autoscan_sequence(0xFF);
ads8688_set_channel_power_down(0x00);
ads8688_set_ch_range_select(Channel_0_Input_Range, VREF_U_0_25);
ads8688_set_ch_range_select(Channel_1_Input_Range, VREF_U_0_25);
ads8688_set_ch_range_select(Channel_2_Input_Range, VREF_U_0_25);
ads8688_set_ch_range_select(Channel_3_Input_Range, VREF_U_0_25);
ads8688_set_ch_range_select(Channel_4_Input_Range, VREF_U_0_25);
ads8688_set_ch_range_select(Channel_5_Input_Range, VREF_U_0_25);
ads8688_set_ch_range_select(Channel_6_Input_Range, VREF_U_0_25);
ads8688_set_ch_range_select(Channel_7_Input_Range, VREF_U_0_25);
ads8688_enter_auto_rst_mode();
}

View File

@ -0,0 +1,95 @@
#ifndef __ADS8688_H__
#define __ADS8688_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stdint.h"
//command register map
//only care about high 8 bits
#define NO_OP 0x0000
#define STDBY 0x8200
#define PWR_DN 0x8300
#define RST 0x8500
#define AUTO_RST 0xA000
#define MAN_Ch_0 0xC000
#define MAN_CH_1 0xC400
#define MAN_Ch_2 0xC800
#define MAN_Ch_3 0xCC00
#define MAN_Ch_4 0xD000
#define MAN_Ch_5 0xD400
#define MAN_Ch_6 0xD800
#define MAN_Ch_7 0xDC00
#define MAN_AUX 0xE000
//program register map
//format : 15~9 8 7~0
// addr W/R DATA
//register bit15 ~ 9
#define AUTO_SEQ_EN 0x01
#define Channel_Power_Down 0x02
#define Feature_Select 0x03
#define Channel_0_Input_Range 0x05
#define Channel_1_Input_Range 0x06
#define Channel_2_Input_Range 0x07
#define Channel_3_Input_Range 0x08
#define Channel_4_Input_Range 0x09
#define Channel_5_Input_Range 0x0A
#define Channel_6_Input_Range 0x0B
#define Channel_7_Input_Range 0x0C
#define Ch_0_Hysteresis 0x15
#define Ch_0_High_Threshold_MSB 0x16
#define Ch_0_High_Threshold_LSB 0x17
#define Ch_0_Low_Threshold_MSB 0x18
#define Ch_0_Low_Threshold_LSB 0x19
#define Ch_7_Hysteresis 0x38
#define Ch_7_High_Threshold_MSB 0x39
#define Ch_7_High_Threshold_LSB 0x3A
#define Ch_7_Low_Threshold_MSB 0x3B
#define Ch_7_Low_Threshold_LSB 0x3C
#define Command_Read_Back 0x3F
//register bit8
#define WRITE 1
#define READ 0
//register AUTO_SEQ_EN bit7 ~ 0
//default value is FFh(bit7~0 all selected)
#define CH7_EN 0x80
#define CH6_EN 0x40
#define CH5_EN 0x20
#define CH4_EN 0x10
#define CH3_EN 0x08
#define CH2_EN 0x04
#define CH1_EN 0x02
#define CH0_EN 0x01
//register Channel_Power_Down bit7 ~ 0
//default value is 00h(bit7~0 all powered up)
#define CH7_PD 0x80
#define CH6_PD 0x40
#define CH5_PD 0x20
#define CH4_PD 0x10
#define CH3_PD 0x08
#define CH2_PD 0x04
#define CH1_PD 0x02
#define CH0_PD 0x01
//register Channel_x_Input_Range bit7 ~ 3 is 00000
//register Channel_x_Input_Range bit2 ~ 0
#define VREF_B_25 0x00 //channel range:±2.5×VREF = ±10.24V
#define VREF_B_125 0x01 //channel range:±1.25×VREF = ±5.12V
#define VREF_B_0625 0x02 //channel range:±0.625×VREF = ±2.56V
#define VREF_U_0_25 0x05 //channel range:0~2.5×VREF = 0~10.24V
#define VREF_U_0_125 0x06 //channel range:0~1.25×VREF = 0~5.12V
#endif /* __ADS8688_H__ */