sggt/App/SIG24130/SIG24130.c

689 lines
26 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*******************************************************************************
 * File Name : SIG24130_STM32_spi.c
 * Description : Implementation of SIG24130/SIG24131/SIG24132 Driver.
* Author : Bob Zhou(support@signal-micro.com)
********************************************************************************
* Copyright 2023(c) Nanjing Signal Micro.
*
* All rights reserved.
*
* Software License Agreement
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* - Neither the name of Nanjing Signal Micro nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* - The use of this software may or may not infringe the patent rights of one
* or more patent holders. This license does not release you from the requirement
* that you obtain separate licenses from these patent holders to use this software.
*
* - Use of the software either in source or binary form, must be run on or directly
* connected to an Nanjing Signal Micro component.
*
* THIS SOFTWARE IS PROVIDED BY NANJING SIGNAL MICRO "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL NANJING SIGNAL MICRO BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
********************************************************************************
* SVN Revision: 1.0
*******************************************************************************/
#include "stm32f4xx_hal.h"
#include "spi.h"
#include <SIG24130.h>
#include "math.h"
// Add printf1 for debug purpose to print out register content.
#include "usart.h"
#include <stdio.h>
#define printf1(...) HAL_UART_Transmit((UART_HandleTypeDef *)&huart1, (uint8_t *)u1_buf, \
sprintf((char *)u1_buf, __VA_ARGS__), 0xFFFF);
uint8_t u1_buf[256];
uint32_t reg_info;
uint8_t DATACHK = 0; // Store CONF0 register bit22 content to rdata command usage.
uint8_t PARITY = 0; // Store parity byte for ADC data.
uint32_t SIG24130_adc_data = 0;
uint32_t SIG16130_adc_data = 0;
unsigned char RH_DATA = 0, RM_DATA = 0, RL_DATA = 0, RS_DATA = 0;
void delay_nus(int nus)
{
volatile int i, j;
for (i = 0; i != nus; i++)
for (j = 0; j < 4; j++)
;
}
// SPI interface: SIG24130_CS_Pin, SIG24130_SCLK_Pin, SIG24130_DIN_Pin, SIG24130_DOUT_Pin
// SIG24130 works with standard SPI MODE1; if spi is not used, the initialized states are SIG24130_CSn_HIGH; SIG24130_SCLK_LOW; SIG24130_DIN_LOW if GPIO are used.
/**************************************************************************/
void SIG24130_SendByte(uint8_t tx_data)
{
uint8_t rx_data = 0;
HAL_SPI_TransmitReceive(&hspi2, &tx_data, &rx_data, 1, 1000);
}
uint8_t SIG24130_ReceiveByte(void)
{
uint8_t tx_data = 0x00;
uint8_t rx_data = 0;
HAL_SPI_TransmitReceive(&hspi2, &tx_data, &rx_data, 1, 1000);
return rx_data;
}
uint8_t SPIDEV1_transfer(uint8_t *send, uint8_t *receive, uint8_t bytes_num)
{
HAL_SPI_TransmitReceive(&hspi2, send, receive, bytes_num, 1000);
return 0;
}
/***********************************************************************
 * Function Name : WriteRegister
 * Description   : Write 24-bit register
 * Returns       : None
 * Params        : addr=>CONF0|CONF1|OFFSET|GAIN, H_DATA, M_DATA, L_DATA
 ***********************************************************************/
// Only work for 24-bit register
void SIG24130_WriteRegister(uint8_t addr, uint8_t H_DATA, uint8_t M_DATA, uint8_t L_DATA)
{
SIG24130_CSn_HIGH;
delay_nus(2);
SIG24130_CSn_LOW;
delay_nus(2); // Toggle CSn in case SPI is out of sync
SIG24130_SendByte(CMD_WRITE | addr);
SIG24130_SendByte((addr == CONF0) ? (H_DATA & 0x7F) : H_DATA); // Force bit23 to 0 for CONF0 write operation.
SIG24130_SendByte(M_DATA);
SIG24130_SendByte(L_DATA);
delay_nus(2);
SIG24130_CSn_HIGH; // Force CSn back to high to prevent unexpected command
if ((addr == 0x01) & ((RH_DATA & 0x40) == 0x40))
DATACHK = 1; // Force DATACHK = CONF0[22].
return;
}
/****************************************************************
 * Function Name : ReadRegister
 * Description   : Read 24-bit register
 * Returns       : None
 * Params        : addr=>CONF0|CONF1|OFFSET|GAIN
 ****************************************************************/
// Only work for 24-bit register
uint32_t SIG24130_ReadRegister(uint8_t addr)
{
uint32_t reg_info;
SIG24130_CSn_HIGH;
delay_nus(2);
SIG24130_CSn_LOW;
delay_nus(2); // Toggle CSn in case SPI is out of sync
SIG24130_SendByte(CMD_READ | addr);
RH_DATA = SIG24130_ReceiveByte();
RM_DATA = SIG24130_ReceiveByte();
RL_DATA = SIG24130_ReceiveByte();
delay_nus(2);
SIG24130_CSn_HIGH; // Force CSn back to high to prevent unexpected command
reg_info = (RH_DATA << 16) | (RM_DATA << 8) | RL_DATA;
return (reg_info);
}
/****************************************************************
 * Function Name : SetInputMux
 * Description   : Set Input Mux
 * Returns       : None
 * Params        : muxp=>0(AIN0), 1(AIN1), 2(AIN2), 3(AIN3), 4(AIN4), 5(AIN5), 6(AIN6), 7(AIN7), 8(AINCOM), 9(TPS+), 10(REFP), 11(AVSS), 12(DVSS), 13((AVDD-AVSS)/4+), 14((DVDD-DVSS)/4+)
* muxp=>0(AIN0), 1(AIN1), 2(AIN2), 3(AIN3), 4(AIN4), 5(AIN5), 6(AIN6), 7(AIN7), 8(AINCOM), 9(TPS-), 10(REFN), 11(AVSS), 12(DVSS), 13((AVDD-AVSS)/4-), 14((DVDD-DVSS)/4-)
* 4(AIN4), 5(AIN5), 6(AIN6), 7(AIN7) is only available for SIG24131/SIG24132
 ****************************************************************/
void SIG24130_SetInputMux(uint8_t muxp, uint8_t muxn)
{
SIG24130_ReadRegister(CONF1);
SIG24130_WriteRegister(CONF1, RH_DATA, RM_DATA, (muxp << 4) | muxn);
// SIG24130_ReadRegister(CONF1); // Read CONF1 register if wanted for verification
return;
}
/****************************************************************
 * Function Name : SetSpeed
 * Description   : Set ADC speed
 * Returns       : None
 * Params        : speed=>SPEED_2p5|SPEED_5|...|SPEED_8000|SPEED_9600
 ****************************************************************/
void SIG24130_SetSpeed(uint8_t speed)
{
SIG24130_ReadRegister(CONF1);
SIG24130_WriteRegister(CONF1, RH_DATA, (RM_DATA & 0xC0) | speed, RL_DATA); // Update CONF1 register with speed
// SIG24130_ReadRegister(CONF1); // Read CONF1 register if wanted for verification
return;
}
/****************************************************************
 * Function Name : SetFilter
 * Description   : Set Filter
 * Returns       : None
 * Params        : sinc4=>0(sinc1), 1(sinc4)
* rej60=>0(no), 1(yes)
* data rate need to be 50sps for rej60 to be effective
 ****************************************************************/
void SIG24130_SetFilter(uint8_t sinc4, uint8_t rej60)
{
SIG24130_ReadRegister(CONF1);
SIG24130_WriteRegister(CONF1, RH_DATA, (RM_DATA & 0x3F) | (sinc4 << 7) | (rej60 << 6), RL_DATA);
// SIG24130_ReadRegister(CONF1); // Read CONF1 register if wanted for verification
return;
}
/****************************************************************
 * Function Name : SetGain
 * Description   : Set ADC Gain
 * Returns       : None
 * Params        : gain=0(1), 1(2), 2(4), 3(8), 4(16), 5(32), 6(64), 7(128), 8(256)
 ****************************************************************/
void SIG24130_SetGain(uint8_t gain)
{
SIG24130_ReadRegister(CONF1);
SIG24130_WriteRegister(CONF1, (RH_DATA & 0xF0) | gain, RM_DATA, RL_DATA); // Update CONF1 register with gain
// SIG24130_ReadRegister(CONF1); // Read CONF1 register if wanted for verification
return;
}
/****************************************************************
 * Function Name : SetBuffer
 * Description   : Set buffer
 * Returns       : None
 * Params        : buffer=>0(off), 1(on)
* buffer can only be off if gain is not 1
 ****************************************************************/
void SIG24130_SetBuffer(uint8_t buffer)
{
SIG24130_ReadRegister(CONF0);
SIG24130_WriteRegister(CONF0, RH_DATA & 0x7F, (RM_DATA & 0x7F) | (buffer << 7), RL_DATA); // Force bit23 to 0 for CONF0 write operation.
// SIG24130_ReadRegister(CONF0); // Read CONF0 register if wanted for verification
return;
}
/****************************************************************
 * Function Name : SetRefMux
 * Description   : Set ADC reference connection
 * Returns       : None
 * Params        : refmux=>0(REFP/REFN), 1(REFP1/REFN1), 2(2.5V Int. Ref), 3(1.17V Int. Ref)
* 1(REFP1/REFN1) is only available for SIG24132
 ****************************************************************/
void SIG24130_SetRefMux(uint8_t refmux)
{
SIG24130_ReadRegister(CONF1);
SIG24130_WriteRegister(CONF1, (RH_DATA & 0xCF) | (refmux << 4), RM_DATA, RL_DATA);
// SIG24130_ReadRegister(CONF1); // Read CONF1 register if wanted for verification
return;
}
/****************************************************************
 * Function Name : SetSingleShot
 * Description   : Set ADC to run at continuous mode or single shot mode
 * Returns       : None
 * Params        : single=>0(continuous), 1(single shot mode)
 ****************************************************************/
void SIG24130_SetSingleShot(uint8_t single)
{
SIG24130_ReadRegister(CONF1);
SIG24130_WriteRegister(CONF1, (RH_DATA & 0xBF) | (single << 6), RM_DATA, RL_DATA);
// SIG24130_ReadRegister(CONF1); // Read CONF1 register if wanted for verification
return;
}
/****************************************************************
 * Function Name : SetZeroLatency
 * Description   : Set ADC to run at zero latency mode or not
 * Returns       : None
 * Params        : latency=>0(no), 1(yes)
 ****************************************************************/
void SIG24130_SetZeroLatency(uint8_t latency)
{
SIG24130_ReadRegister(CONF1);
SIG24130_WriteRegister(CONF1, (RH_DATA & 0x7F) | (latency << 7), RM_DATA, RL_DATA);
// SIG24130_ReadRegister(CONF1); // Read CONF1 register if wanted for verification
return;
}
/****************************************************************
 * Function Name : SetIDAC
 * Description   : Set IDAC
 * Returns       : None
 * Params        : idac_size=>0(off), 1(10uA), 2(50uA), 3(100uA), 4(200uA), 5(250uA), 6(500uA), 7(1000uA)
* idac2_mux=>0(AIN0), 1(AIN1), 2(AIN2), 3(AIN3), 4(AIN4), 5(AIN5), 6(AIN6), 7(AIN7)
* idac1_mux=>0(AIN0), 1(AIN1), 2(AIN2), 3(AIN3), 4(AIN4), 5(AIN5), 6(AIN6), 7(AIN7)
* idac_pair=>0(no), 1(yes)
* 4(AIN4), 5(AIN5), 6(AIN6), 7(AIN7) is only available for SIG24131/SIG24132
 ****************************************************************/
void SIG24130_SetIDAC(uint8_t idac_size, uint8_t idac2_mux, uint8_t idac1_mux, uint8_t idac_pair)
{
SIG24130_ReadRegister(CONF0);
SIG24130_WriteRegister(CONF0, RH_DATA & 0x7F, (RM_DATA & 0xF8) | idac_size, (RL_DATA & 0xBF) | (idac_pair << 7) | (idac2_mux << 3) | idac1_mux); // Force bit23 to 0 for CONF0 write operation.
// SIG24130_ReadRegister(CONF0); // Read CONF0 register if wanted for verification
return;
}
/****************************************************************
 * Function Name : SetBCS
 * Description   : Set burnout current source(BCS) at input pins.
 * Returns       : None
 * Params        : burnout=>0(no), 1(1uA)
 ****************************************************************/
void SIG24130_SetBCS(uint8_t burnout)
{
SIG24130_ReadRegister(CONF0);
SIG24130_WriteRegister(CONF0, RH_DATA & 0x7F, (RM_DATA & 0xF7) | (burnout << 3), RL_DATA); // Force bit23 to 0 for CONF0 write operation.
// SIG24130_ReadRegister(CONF0); // Read CONF0 register if wanted for verification
return;
}
/****************************************************************
 * Function Name : SetVbias
 * Description   : Set Vbias at AINCOM pin.
 * Returns       : None
 * Params        : vbias=>0(no), 1(AINCOM=(AVDD-AVSS)/2)
 ****************************************************************/
void SIG24130_SetVbias(uint8_t vbias)
{
SIG24130_ReadRegister(CONF0);
SIG24130_WriteRegister(CONF0, (RH_DATA & 0x77) | (vbias << 3), RM_DATA, RL_DATA); // Force bit23 to 0 for CONF0 write operation.
// SIG24130_ReadRegister(CONF0); // Read CONF0 register if wanted for verification
return;
}
/****************************************************************
 * Function Name : SetDelay
 * Description   : Add extra delay before filter starts to work, allocate extra time needed for analog input to fully settle.
 * Returns       : None
 * Params        : delay=0(0us), 1(104.2us), 2(416.7us), 3(1.667ms), 4(6.667ms), 5(26.67ms), 6(106.7ms), 7(426.7ms)
 ****************************************************************/
void SIG24130_SetDelay(uint8_t delay)
{
SIG24130_ReadRegister(CONF0);
SIG24130_WriteRegister(CONF0, RH_DATA & 0x7F, (RM_DATA & 0x8F) | (delay << 4), RL_DATA); // Force bit23 to 0 for CONF0 write operation.
// SIG24130_ReadRegister(CONF0); // Read CONF0 register if wanted for verification
return;
}
/****************************************************************
 * Function Name : SetDataChk
 * Description   : Set ADC checksum function during rdata command.
 * Returns       : None
 * Params        : datachk=>0(no), 1(checksum enabled)
 ****************************************************************/
void SIG24130_SetDataChk(uint8_t datachk)
{
SIG24130_ReadRegister(CONF0);
SIG24130_WriteRegister(CONF0, (RH_DATA & 0x3F) | (datachk << 6), RM_DATA, RL_DATA); // Force bit23 to 0 for CONF0 write operation.
// SIG24130_ReadRegister(CONF0); // Read CONF0 register if wanted for verification
return;
}
/****************************************************************
 * Function Name : SetRefOut
 * Description   : Set ADC Int. Ref to output pin.
 * Returns       : None
 * Params        : refout=>0(no), 1(yes)
* if REFOUT=1, Int. Ref connected to REFP pin for SIG24130/SIG24131 and REFP1 pin for SIG24132.
 ****************************************************************/
void SIG24130_SetRefOut(uint8_t refout)
{
SIG24130_ReadRegister(CONF0);
SIG24130_WriteRegister(CONF0, (RH_DATA & 0x7E) | refout, RM_DATA, RL_DATA); // Force bit23 to 0 for CONF0 write operation.
// SIG24130_ReadRegister(CONF0); // Read CONF0 register if wanted for verification
return;
}
/****************************************************************
 * Function Name : Reset
 * Description   : Resets the SIG24130
 * Returns       : None
 * Params        : None
 ****************************************************************/
void SIG24130_Reset()
{
SIG24130_CSn_HIGH;
delay_nus(2);
SIG24130_CSn_LOW;
delay_nus(2); // Toggle CSn in case SPI is out of sync
SIG24130_SendByte(0x02); // Send 0x02 reset command
delay_nus(10);
SIG24130_CSn_HIGH; // Force CSn back to high to prevent unexpected command
}
/****************************************************************
 * Function Name : Sync
 * Description   : Sync the SIG24130 conversion
 * Returns       : None
 * Params        : None
 ****************************************************************/
void SIG24130_Sync()
{
SIG24130_CSn_HIGH;
delay_nus(2);
SIG24130_CSn_LOW;
delay_nus(2); // Toggle CSn in case SPI is out of sync
SIG24130_SendByte(0x04); // Send 0x04 sync command
delay_nus(2);
SIG24130_CSn_HIGH; // Force CSn back to high to prevent unexpected command
}
/****************************************************************
 * Function Name : Sleep
 * Description   : Put the SIG24130 into sleep mode
 * Returns       : None
 * Params        : None
 ****************************************************************/
void SIG24130_Sleep()
{
SIG24130_CSn_HIGH;
delay_nus(2);
SIG24130_CSn_LOW;
delay_nus(2); // Toggle CSn in case SPI is out of sync
SIG24130_SendByte(0x0A); // Send 0x0A sleep command
delay_nus(2);
SIG24130_CSn_HIGH; // Force CSn back to high to prevent unexpected command
}
/****************************************************************
 * Function Name : Wakeup
 * Description   : Put the SIG24130 into sleep mode
 * Returns       : None
 * Params        : None
 ****************************************************************/
void SIG24130_Wakeup()
{
SIG24130_CSn_HIGH;
delay_nus(2);
SIG24130_CSn_LOW;
delay_nus(2); // Toggle CSn in case SPI is out of sync
SIG24130_SendByte(0x0C); // Send 0x0C wakeup command
delay_nus(2);
SIG24130_CSn_HIGH; // Force CSn back to high to prevent unexpected command
}
/****************************************************************
 * Function Name : SYSOCAL
 * Description   : System offset cal
 * Returns       : None
 * Params        : None
 ****************************************************************/
void SIG24130_SYSOCAL()
{
SIG24130_CSn_HIGH;
delay_nus(2);
SIG24130_CSn_LOW;
delay_nus(2); // Toggle CSn in case SPI is out of sync
SIG24130_SendByte(0x10); // Send 0x10 SYSOCAL command
delay_nus(2);
SIG24130_CSn_HIGH; // Force CSn back to high to prevent unexpected command
}
/****************************************************************
 * Function Name : SYSGCAL
 * Description   : System gain cal
 * Returns       : None
 * Params        : None
 ****************************************************************/
void SIG24130_SYSGCAL()
{
SIG24130_CSn_HIGH;
delay_nus(2);
SIG24130_CSn_LOW;
delay_nus(2); // Toggle CSn in case SPI is out of sync
SIG24130_SendByte(0x11); // Send 0x11 SYSGCAL command
delay_nus(2);
SIG24130_CSn_HIGH; // Force CSn back to high to prevent unexpected command
}
/****************************************************************
 * Function Name : SELFOCAL
 * Description   : Self offset cal
 * Returns       : None
 * Params        : None
 ****************************************************************/
void SIG24130_SELFOCAL()
{
SIG24130_CSn_HIGH;
delay_nus(2);
SIG24130_CSn_LOW;
delay_nus(2); // Toggle CSn in case SPI is out of sync
SIG24130_SendByte(0x12); // Send 0x12 SELFOCAL command
delay_nus(2);
SIG24130_CSn_HIGH; // Force CSn back to high to prevent unexpected command
}
void SIG24130_Init(void)
{
HAL_Delay(100); // Wait time after power-up before SPI communication. Power-On Reset(POR) time is 43ms.
SIG24130_Reset();
delay_nus(100); // RESET SIG24130
SIG24130_WriteRegister(CONF1, 0x20, 0x89, 0xDD); // Update CONF1 register with 0x2089DD for int 2.5V ref, SINC4, 50sps(0x2089) or 1200sps(0x2096), 0xDD=>(AVDD-AVSS)/4 or 0xBB=>(AVSS-AVSS),
reg_info = SIG24130_ReadRegister(CONF1); // Read CONF1 register if wanted
// printf1("Register CONF1= %x \r\n", (unsigned int)reg_info); // Used only for manual debug with breakpoint.
SIG24130_CSn_LOW;
delay_nus(2); // DOUT/DRDYn signal can only be available at the pin while CSn pin is low, otherwise it is tri-state.
}
/*************************************************
 * Function Name : RetrievalData for SIG24130/24131/24132
 * Description   : Retrieval ADC Data
 * Returns       : ADC data
 * Params        : rdata=>0(no), 1(yes)
*
* 1. Extra byte is clocked with chksum=1 or DATACHK=1 to force DOUT to high at the end of data retrieval.
* 2. Rdata command is provided to guarantee that the retrieved data is always correct with rdata command sent at any time.
* 3. Data retrieval without rdata command should start right after DOUT falling edge and finish
* before the next new data is updating, otherwise the data could be corrupted.
*************************************************/
unsigned long SIG24130_RetrievalData(uint8_t rdata, uint8_t chksum)
{
unsigned char Rx_bytes[4] = {0, 0, 0, 0};
uint8_t parity_cal = 0;
SIG24130_adc_data = 0;
SIG24130_CSn_HIGH;
delay_nus(2);
SIG24130_CSn_LOW;
delay_nus(2); // Toggle CSn in case SPI is out of sync
if (rdata)
SIG24130_SendByte(0x60); // rdata command is used to make sure that the retrieved data is also correct.
// Method #1
HAL_SPI_Receive(&hspi2, Rx_bytes, (rdata & DATACHK) | chksum ? 4 : 3, 1000); // Rx_bytes[3] is the parity byte.
// Method #2
// unsigned char Tx_bytes[4] = {0x00,0x00,0x00,0x00};
// HAL_SPI_TransmitReceive(&hspi2, Tx_bytes, Rx_bytes, (rdata & DATACHK)|chksum ? 4 : 3, 1000);
// Method #3
// Rx_bytes[0]=SIG24130_ReceiveByte();
// Rx_bytes[1]=SIG24130_ReceiveByte();
// Rx_bytes[2]=SIG24130_ReceiveByte();
// if((rdata & DATACHK)|chksum) Rx_bytes[3]=SIG24130_ReceiveByte();
SIG24130_adc_data = (SIG24130_adc_data | Rx_bytes[0]) << 8;
SIG24130_adc_data = (SIG24130_adc_data | Rx_bytes[1]) << 8;
SIG24130_adc_data = (SIG24130_adc_data | Rx_bytes[2]);
if ((rdata & DATACHK) | chksum)
{
PARITY = Rx_bytes[3]; // Store parity byte if retrieved.
parity_cal = Rx_bytes[0] + Rx_bytes[1] + Rx_bytes[2] + 0x5B;
parity_cal = parity_cal | 0x81; // Force bit7 and bit0 to 1.
if (PARITY != parity_cal)
return (0xFFFFFFFF); // Return 0xFFFFFFFF if checksum calculation is not correct.
}
SIG24130_CSn_HIGH;
delay_nus(2);
SIG24130_CSn_LOW;
delay_nus(2); // Toggle CSn in case SPI is out of sync
return (SIG24130_adc_data);
}
/*************************************************
 * Function Name : RetrievalData for SIG16130/16131/16132
 * Description   : Retrieval ADC Data
 * Returns       : ADC data
 * Params        : rdata=>0(no), 1(yes)
*
* 1. Extra byte is clocked with chksum=1 or DATACHK=1 to force DOUT to high at the end of data retrieval.
* 2. Rdata command is provided to guarantee that the retrieved data is always correct with rdata command sent at any time.
* 3. Data retrieval without rdata command should start right after DOUT falling edge and finish
* before the next new data is updating, otherwise the data could be corrupted.
*************************************************/
unsigned long SIG16130_RetrievalData(uint8_t rdata, uint8_t chksum)
{
unsigned char Rx_bytes[3] = {0, 0, 0};
uint8_t parity_cal = 0;
SIG16130_adc_data = 0;
SIG24130_CSn_HIGH;
delay_nus(2);
SIG24130_CSn_LOW;
delay_nus(2); // Toggle CSn in case SPI is out of sync
if (rdata)
SIG24130_SendByte(0x60); // rdata command is used to make sure that the retrieved data is also correct.
// Method #1
HAL_SPI_Receive(&hspi2, Rx_bytes, (rdata & DATACHK) | chksum ? 3 : 2, 1000); // Rx_bytes[2] is the parity byte.
// Method #2
// unsigned char Tx_bytes[3] = {0x00,0x00,0x00};
// HAL_SPI_TransmitReceive(&hspi2, Tx_bytes, Rx_bytes, (rdata & DATACHK)|chksum ? 3 : 2, 1000);
// Method #3
// Rx_bytes[0]=SIG24130_ReceiveByte();
// Rx_bytes[1]=SIG24130_ReceiveByte();
// if((rdata & DATACHK)|chksum) Rx_bytes[2]=SIG24130_ReceiveByte();
SIG16130_adc_data = (SIG16130_adc_data | Rx_bytes[0]) << 8;
SIG16130_adc_data = (SIG16130_adc_data | Rx_bytes[1]);
if ((rdata & DATACHK) | chksum)
{
PARITY = Rx_bytes[2]; // Store parity byte if retrieved.
parity_cal = Rx_bytes[0] + Rx_bytes[1] + 0x5B;
parity_cal = parity_cal | 0x81; // Force bit7 and bit0 to 1.
if (PARITY != parity_cal)
return (0xFFFFFFFF); // Return 0xFFFFFFFF if checksum calculation is not correct.
}
SIG24130_CSn_HIGH;
delay_nus(2);
SIG24130_CSn_LOW;
delay_nus(2); // Toggle CSn in case SPI is out of sync
return (SIG16130_adc_data);
}
void fun_get_sig16132_ch(uint8_t channel, float32 *data)
{
if (!data)
return;
BOOL config_flag = FALSE;
static uint8_t last_ch = 0;
if (channel != last_ch)
{
last_ch = channel;
config_flag = TRUE;
}
if (config_flag == TRUE)
{
config_flag = FALSE;
if ((channel == 2) || (channel == 3) || (channel == 4) || (channel == 5) || (channel == 7))
{
HAL_Delay(100); // Wait time after power-up before SPI communication. Power-On Reset(POR) time is 43ms.
SIG24130_Reset();
delay_nus(100); // RESET SIG24130
SIG24130_SetRefMux(2); // 内部2.5V参考
SIG24130_SetInputMux(channel, 11); // 单端输出对地11(AVSS)
SIG24130_CSn_LOW;
delay_nus(2); // DOUT/DRDYn signal can only be available at the pin while CSn pin is low, otherwise it is tri-state.
//*data = SIG16130_RetrievalData(1, 0);
}
else if (channel == 10)
{
HAL_Delay(100); // Wait time after power-up before SPI communication. Power-On Reset(POR) time is 43ms.
SIG24130_Reset();
delay_nus(100); // RESET SIG24130
SIG24130_SetRefMux(2); // 内部2.5V参考
SIG24130_SetInputMux(0, 1); // 差分输入in0+ in1-
SIG24130_SetIDAC(6, 6, 6, 0); // 1mA IDAC0 IDAC1 pair 0
SIG24130_CSn_LOW;
delay_nus(2); // DOUT/DRDYn signal can only be available at the pin while CSn pin is low, otherwise it is tri-state.
//*data = SIG16130_RetrievalData(1, 0);
}
else
*data = 0;
}
else
{
float32 ad_16 = SIG16130_RetrievalData(1, 0);
float32 voltage = (float32)(2.5f * ad_16 / 32767.0f);
float32 Rt = 0;
if (channel == 2) // 0~30V电压输入检测
{
*data = voltage * 16.0f;
}
else if (channel == 3) // mV电压输入检测
{
*data = voltage * 1000.0f - 0.2f;
}
else if (channel == 4) //-2.5~2.5V输出反馈
{
*data = 2.0f * voltage - 2.5f;
}
else if (channel == 5) // 4`20mA输入检测
{
*data = voltage / 100.0f * 1000.0f;
}
else if (channel == 7) // 4`20mA输出反馈
{
*data = voltage * 1000.0f * 0.02f * 0.5f;
}
else if (channel == 10) // RTD输入检测
{
// 在0650℃范围内
// Rt =R0 (1+At+Bt2)
// 在-1900℃范围内
// Rt =R0 (1+At+Bt2+C(t-100)t3)
// 式中A、B、C 为常数,
// A=3.96847×10-3
// B=-5.847×10-7
// C=-4.22×10-12
#define R0 100.0f
#define A 3.96847e-3
#define B -5.847e-7
#define C -4.22e-12
Rt = voltage * 1000.0f / 1.0f;
float32 temp1 = (-A + sqrt(A * A - 4 * B * (1 - Rt / R0))) / (2 * B);
float32 temp2 = (-A - sqrt(A * A - 4 * B * (1 - Rt / R0))) / (2 * B);
*data = temp1;
//*data = voltage * 1000.0f;
}
}
}