689 lines
26 KiB
C
689 lines
26 KiB
C
/*******************************************************************************
|
||
* 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输入检测
|
||
{
|
||
// 在0~650℃范围内:
|
||
// Rt =R0 (1+At+Bt2)
|
||
// 在-190~0℃范围内:
|
||
// 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;
|
||
}
|
||
}
|
||
}
|