AD74413R example of "spi_write_and_read" function body in AD74413.c file

Hi guys:

Can you help to provide the example of the "spi_write_and_read" function body in AD74413.c file, I can't find it in our website.

Parents Reply
  • Hello, thanks for this snippet, I'm trying to connect the AD-SWIO 2 Click to my STM32F4 board, I tried to use HAL_SPI_Receive and transmit, following all the steps starting with clearing the alert register and so on...  but I could not read the ADC_RESULTA register (it shows 0x0000), maybe if I work with the driver given by AD it would give a result, can you help me with the spi_write_and_read function?  I couldn't find ADI_SPI_RESULT and ADI_SPI_TRANSCEIVER in the driver. Thank you 

Children
  • +1
    •  Analog Employees 
    on Sep 15, 2021 10:54 AM in reply to KhalilTR

    Hi,

    Have you been in touch with the MikroE support team for help with the click? They may be able to help with the issues you are having. I am not familiar with the software environment or hardware for the MikroE product so it might be helpful to get in touch with them. 

    Meanwhile, here are the definitions that were used for ADI_SPI_RESULT & ADI_SPI_TRANSCEIVER.

    Thanks,

    Bríde

  • void SPI_WRITE(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t crc) {
    	spi_tx_buffer[0] = b0;
    	spi_tx_buffer[1] = b1; //1; //0x02
    	spi_tx_buffer[2] = b2;
    	spi_tx_buffer[3] = crc;
    	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //SYNC To Low
    	HAL_SPI_Transmit(&hspi3, (uint8_t*) spi_tx_buffer, 4, 10);
    	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); //SYNC To Low
    
    }
    
    void SPI_WRITE_READ() {
    	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
    	//HAL_SPI_TransmitReceive(&hspi3, spi_tx_nop, spi_rx_buffer, 10, 10);
    	HAL_SPI_Receive(&hspi3, (uint8_t*) spi_rx_buffer, 10, 2);
    	//HAL_SPI_Transmit(&hspi3, (uint8_t*)spi_tx_nop, 3, 1);
    	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); //SYNC To High
    
    }
    
    void read_siliconrev() {
    	//CONFIG READ_SELEC REGISTER
    	//spi_tx_buffer[0] = REG_AD74413_READ_SELECT;
    	//spi_tx_buffer[1] = 1; //1; //0x02
    	//spi_tx_buffer[2] = REG_AD74413_SILICON_REV;
    	SPI_WRITE(REG_AD74413_READ_SELECT, 0x2, REG_AD74413_SILICON_REV, 0x00);
    	// Enable write enable latch (allow write operations)
    	//HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //SYNC To Low
    	//HAL_SPI_Transmit(&hspi3, (uint8_t*) spi_tx_buffer, 3, 50);
    	//HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); //SYNC To Low
    	SPI_WRITE_READ();
    	// Read status register
    	//HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
    	//HAL_SPI_TransmitReceive(&hspi3, spi_tx_buffer, spi_rx_buffer, 10, 50);
    	//HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); //SYNC To High
    
    }
    
    /*
     * READBACK SELECT REGISTER
     * Address: 0x41, Reset: 0x0000, Name: READ_SELECT
     * [15:10] -- RESERVED -- Reserved
     * 9		- AUTO_RD_EN - Automatic read enabled
     * 							Automatic read enabled. When this bit is set to 0, a read is performed by first writing the
     * 							readback address to the READ_SELECT register, followed by a frame where the read data is
     * 							returned on the SDO only for the next SPI transaction, which is called a two-stage read.
     * 							When this bit is set to 1, read data is returned on the SDO for every SPI access.
     * 							The location read is determined by the current value of the READBACK_ADDR bits, Bits[7:0].
     * 							Repeated reads of a register location can execute without needing a write to the
     * 							READ_SELECT register between each read. For streaming mode, the address starts at the value
     * 							of the READBACK_ADDR bits, Bits[7:0] and increments until the read stops. At the start of
     * 							the next burst read, the address reverts to the value of the READBACK_ADDR bits, Bits[7:0].
     * 							Repeated burst reads can execute without needing a write to the READ_SELECT register between each burst read.
     *
     * 8 		- SPI_RD_RET_INFO
     * 							Determines the content of the MSBs in the SPI read frame.
     * 							When this bit is set to 0, the READBACK_ADDR is returned in bits,
     * 							Bits[30:24] (the MSB is not shown) of any subsequent SPI read.
     * 							When this bit is set to 1, the ADC_RDY bit, alert flags, and the four
     * 							digital input outputs are returned in Bits[30:24] of any subsequent SPI read.
     *
     * [7:0]	- READBACK_ADDR
     * 							Bits[D7:D0] contains the register address to be read.
     *
     */
    
    void CLC_ALERT_STATUS() {
    
    	/*
    	 * ALERT_STATUS_REGISTER
    	 * Address: 0x2E, Reset: 0x8000, Name: ALERT_STATUS
    	 * 15 RESET_OCCURRED -- Reset occurred. this bit is aserted after a reset event
    	 * 14 CAL_MEM_ERR -- Calibration Memory Error
    	 * 13 SPI_CRC_ERR -- SPI CRC eror detected
    	 * 12 SPI_SCLK_CNT_ERR -- SPI SCLK count error detected
    	 * 11 ADC_SAT_ERR -- ADC Saturation Error
    	 * 10 ADC_CONV_ERR -- ADC Conversion Error.
    	 * 09 ALDO1V8_ERR
    	 * 08 DVCC_ERR
    	 * 07 AVDD_ERR
    	 * 06 ALDO5V_ERR
    	 * 05 CHARGE_PUMP_ERR -- Charged pump error detected.
    	 * 04 HI_TEMP_ERR -- High temperature detected
    	 * 03 VI_ERR_D
    	 * 02 VI_ERR_C
    	 * 01 VI_ERR_B
    	 * 00 VI_ERR_A -- Voltage or current error detector on Channel A
    	 *
    	 */
    	//read alert status
    	SPI_WRITE(REG_AD74413_READ_SELECT, 1, REG_AD74413_ALERT_STATUS, 0x00);
    	SPI_WRITE_READ();
    
    	//send reset cmd
    	SPI_WRITE(REG_AD74413_ALERT_STATUS, 0x80, 0x00, 0x00);
    	SPI_WRITE(REG_AD74413_READ_SELECT, 1, REG_AD74413_ALERT_STATUS, 0x00);
    	SPI_WRITE_READ();
    
    }
    
    void CONFIG_CH_FUNC() {
    	/*
    	 * CONFIG Bits CONFIG_CH_FUNC
    	 * [15:4] -- RESERVED -- Reserved
    	 * [ 3:0] -- CH_FUNC -- Sets the channel function.
    	 * 				0000: high impedance. ADC is functional in this mode.
    	 * 				0001: voltage output. Force voltage measure current (FVMI).
    	 * 				0010: current output, FVMI.
    	 * 				0011: voltage input, which measures the voltage across the I/OP_x to I/ON_x screw terminals.
    	 * 				0100: current input externally powered.
    	 * 				0101: current input loop powered.
    	 * 				0110: resistance measurement.
    	 * 				0111: digital input (logic).
    	 * 				1000: digital input (loop powered).
    	 * 				1001: current input externally powered with HART termination impedance.
    	 */
    
    	//config tx_buffer message
    	//SPI_WRITE(REG_AD74413_CH_FUNC_SETUP0, 0x00, 0x00, 0x6B);// ---> high impedance.
    	//SPI_WRITE(REG_AD74413_CH_FUNC_SETUP0, 0x00, 0x03, 0x62);// ---> Voltage input
    	//SPI_WRITE(REG_AD74413_CH_FUNC_SETUP0, 0x00, 0x06, 0x79); // ---> Resistance measurement
    	SPI_WRITE(REG_AD74413_CH_FUNC_SETUP0, 0x00, 0x04, 0x77); // ---> Current Input Externally powered
    
    }
    
    void CONFIG_ADC_CONFIG() {
    	/*
    	 CONFIG Bits ADC_CONFIG
    	 //[15:8] -- RESERVED -- Reserved
    	 //[ 7:5] -- RANGE
    	 //							000: 0 V to 10 V range
    	 //							001: 2.5 V range, RTD and input current (IIN) externally powered
    	 //							010: 2.5 V range, IIN loop powered.
    	 //							011: −2.5 V to +2.5 V range.
    	 //							100: −104.16 mV to +104.16 mV range -- Thermocouple
    	 //[ 4:3] -- EN_50_60_HZ
    	 //							00: enables the 50 Hz and 60 Hz rejection, resulting in a sampling rate of 20 SPS.
    	 //							01: disables the 50 Hz and 60 Hz rejection, resulting in a sampling rate of 4.8 kSPS.
    	 //							10: enables the 50 Hz and 60 Hz rejection and HART noise rejection, resulting in a	sampling rate of 10 SPS.
    	 //							11: disables the 50 Hz and 60 Hz rejection, resulting in a sampling rate of 1.2 kSPS.
    	 //2 -- CH_200K_TO_GND
    	 //[ 1:0] -- ADC_MUX
    	 //							00: voltage between the I/OP_x screw terminals and the AGND_SENSE pin.
    	 //							01: voltage across the 100 Ω resistor. Typically used to measure the current.
    	 */
    
    		//option1
    	//  [7:5]	[4:3]  2  [ 1:0]
    	//  000     00     0     00
    
    	//option2 Enable 200k Ro  to GND
    	//  [7:5]	[4:3]  2  [ 1:0]
    	//  000     00     1     00
    	//config tx_buffer message
    	//SPI_WRITE(REG_AD74413_ADC_CONFIG0, 0x00, 0x00, 0xC0); //0 to 10V Range //200k Disable
    	//SPI_WRITE(REG_AD74413_ADC_CONFIG0, 0x00, 0x1C, 0x94); //0 to 10V Range //200k Enable //Disable 50Hz y 60Hz
    
    	//RTD config
    		//  [7:5]	[4:3]  2  [ 1:0]
    		//  001     00     0     00
    
    	//SPI_WRITE(REG_AD74413_ADC_CONFIG0, 0x00, 0x20, 0x20); //RDT Config
    
    
    	//Current Input Externally Powered
    		//  [7:5]	[4:3]  2  [ 1:0]
    		//  001     10     1     01
    
    	SPI_WRITE(REG_AD74413_ADC_CONFIG0, 0x00, 0x35, 0x4B); //Input Current Externally Powered
    
    }
    
    void CONFIG_ADC_CONV_CRTL() {
    
    	/*
    	 * ADC
    	 *
    	 *
    	 * [15:11]	-- RESERVED	 *
    	 *
    	 * 10 		-- EN_50_60_HZ_REJ_DIAG
    	 * 						Enable 50 Hz or 60 Hz rejection for diagnostics. Set this bit to 0 to disable 50 Hz or 60 Hz rejection,
    	 * 						which results in a sampling rate of 4.8 kSPS for diagnostics. Set this bit to 1 to enable 50 Hz or 60 Hz rejection,
    	 * 						which results in a sampling rate of 20 samples per second for diagnostics.
    	 *
    	 * [9:8]	-- CONV_SEQ
    	 *
    	 * 						00: stops continuous conversions and leaves the ADC powered up or powers up the ADC.
    	 * 						01: starts single sequence conversion and performs a single conversion on each
    	 * 						enabled channel and diagnostic.
    	 * 						10: starts continuous conversions. Sequences continuously through the enabled
    	 * 						channels and diagnostics.
    	 * 						11: stops continuous conversions and powers down the ADC.
    	 *
    	 * 7		-- DIAG_3_EN
    	 * 6		-- DIAG_2_EN
    	 * 5		-- DIAG_1_EN
    	 * 4		-- DIAG_0_EN
    	 * 3		-- Enables conversions on Channel D.
    	 * 2		-- Enables conversions on Channel C.
    	 * 1		-- Enables conversions on Channel B.
    	 * 0		-- Enables conversions on Channel A.
    	 *
    	 *
    	 */
    
    	SPI_WRITE(REG_AD74413_ADC_CONV_CTRL, 0x05, 0xFF, 0x4C);
    
    }
    
    void READ_ADC_CH0() {
    
    	//SPI_WRITE(REG_AD74413_READ_SELECT, 0, REG_AD74413_ADC_RESULT0, 0x1F);
    	SPI_WRITE(REG_AD74413_READ_SELECT, 1, REG_AD74413_ADC_RESULT0, 0x0A);
    	SPI_WRITE_READ(); // Read ADC Channel 0
    
    }
    
    
    int main(void)
    {
      /* USER CODE BEGIN 1 */
    
      /* USER CODE END 1 */
    
      /* MCU Configuration--------------------------------------------------------*/
    
      /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
      HAL_Init();
    
      /* USER CODE BEGIN Init */
    
      /* USER CODE END Init */
    
      /* Configure the system clock */
      SystemClock_Config();
    
      /* USER CODE BEGIN SysInit */
    
      /* USER CODE END SysInit */
    
      /* Initialize all configured peripherals */
      MX_GPIO_Init();
      MX_UART4_Init();
      MX_CRC_Init();
      MX_SPI3_Init();
      MX_LPUART1_UART_Init();
      /* USER CODE BEGIN 2 */
    
    	//SYNC Pin To HIGH
    	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
    	HAL_Delay(500);
    
    	//RESET AD74413R
    	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET);
    	HAL_Delay(50);
    	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);
    	//Upon initial power-up or after device reset, the output channels are disabled and default to a high impedance state.
    	HAL_Delay(100);
    
    	myprintf("\r\nInit ADC: ");
    	//Step 1 - Check AlertStatus
    	//Write 1 to clear each bit in the ALERT_STATUS register. -- pag 43 Datasheet AD74413R
    	//Upon initial power-up or after device reset, the output channels are disabled and default to a high impedance state.
    	SPI_WRITE(REG_AD74413_ALERT_STATUS, 0x80, 0, 0xD9); //Clear Alert Status
    	HAL_Delay(1);
    	SPI_WRITE(REG_AD74413_ALERT_STATUS, 0xFF, 0xFF, 0x4B); //Clear Alert Status
    	HAL_Delay(1);
    	SPI_WRITE(REG_AD74413_READ_SELECT, 0, REG_AD74413_ALERT_STATUS, 0x27);
    	SPI_WRITE_READ(); // Read Alert Status Register
    	HAL_Delay(1);
    
    	//Config CH_FUNC_ SETUPx registers.
    	CONFIG_CH_FUNC();
    	//Config ADC_CONFIGx registers.
    	CONFIG_ADC_CONFIG();
    
    	//read_siliconrev();
    
    	//CONFIG_ADC_CONV_CRTL();
    	//READ_ADC_CH0();
    
      /* USER CODE END 2 */
    
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
    	while (1) {
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
    		HAL_Delay(1000);
    		CONFIG_ADC_CONV_CRTL();
    		//HAL_Delay(1);
    		READ_ADC_CH0();
    		adc_data = ((uint16_t)spi_rx_buffer[1] << 8) | spi_rx_buffer[2];
    		//((float)ADCData / (float)MAX_ADC_CODE) * VoltageRange;
    		//volt_adc = ((float)adc_data/(float)65535)*20.0;
    		volt_adc = ((float)adc_data/(float)65535)*2.5;
    		volt_adc = 2*(volt_adc/100);
    		sprintf(buff, "\n\rmA %F ",volt_adc);
    		myprintf(buff);
    
    
    	}
      /* USER CODE END 3 */
    }

    Hi. im working too with AD-SWIO 2 Click.  try that code.. it works for testing.. now im trying to improving beacuse as you can see its not the best way. but it works

  • Hi, many thanks for the example code.

    I have been working too with both Analog EV-board and AD-SWIO 2 Click and after struggling with the SPI communication I compared the frames sent by Analog GUI program and mines and found out that what its critical to make SPI communication work properly with AD74413R is the timing between SYNC and SDO: if there is too much delay between SYNC low edge and the first transition on the SDO the communication won't work.

    I suggest to check the timing diagram on the manual and to make sure that SYNC low edge is just before the SPI transmission in the C code without any instruction or delay in between that could stretch the timing between SYNC and SDO. 

    This worked for me I hope it helps.

  • 0
    •  Analog Employees 
    on Oct 5, 2021 10:43 AM in reply to jacopo.soffritti

    Hi,

    Thank you for the update. Good to know that you are up & running. 

    We will look into the issue that you have pointed out.

    Bríde