Xilinx is now part ofAMDUpdated Privacy Policy

MicroZed Chronicles: Avnet ZUBoard – Temperature Sensor

September 16, 2022


Editor’s Note: This content is republished from the MicroZed Chronicles, with permission from the author.

 

Ever since the previous overview, I’ve had the Avnet ZUBoard 1CG sitting on my desk. I also just purchased a FLIR C5 thermal imaging camera and was curious how accurate the temperature sensor is when compared to the measurement taken by the thermal camera.  

To get started with this project, we first need to create a new project targeting the ZUBoard.

MZ_461_ZUBoard

Once the project is created, we need to create a block diagram and add in a Zynq MPSoC system. Run the block automation to configure the processing system for the ZUBoard.

MZ_461_New_Product_with_ZUBoard

From the boards tab in Vivado, add in the RGB 1 and 3 LED and the PL temperature I2C.

MZ_461_Add_LEDs

Running the connection automation will create the necessary AXI interconnect and reset structure. Make sure to connect the AXI master clock on the MPSoC processing system.

MZ_461_Create_AXI_Connect

The next step is to create the HDL wrapper and implement the design. Once the bit stream is available, we can export the project and import it in to a new Vitis project.

MZ_461_New_Vitis_Project

I created a simple hello world template where we need to add the code to drive the I2C temperature sensor.

The sensor on the board is a STTS22HTR device with a simple seven register interface which can be accessed over the I2C network.

Writes to the device are simple accesses which consist of the register address and the data followed by an I2C stop. Reads require an initial write to select the register we wish to read, followed by an I2C restart before performing the read operation.

MZ_461_Register_Map
MZ_461_temperature_sensor

To access the AXI IIC driver, we use the XIIC.h API provided by the BSP within the platform. As this is a simple application, we can use the XIIC_SEND and XIIC_RECV functions to send and receive several bytes.

The software application is designed to initially check the WHO AM I register on the temperature sensor to ensure that the correct response is received. This ensures the I2C address and configuration is correct if we read the expected value back correctly.

Once the WHO AM I register is received, the next step is to enable the temperature sensor on free running and enable address incrementing via the control register.

We can read two bytes from address six to read the temperature sensor. This will be the upper and lower bytes of the 16-bit temperature value.

The temperature value represents a twos compliment number, where 100 LSB equal the 1 C. As a result, we can divide the concatenated 16-bit result by 100 to get the temperature for positive temperatures.

The code for the software can be seen here.

#include <stdio.h>

#include "platform.h"

#include "xil_printf.h"

#include "xiic.h"

 

#define IIC_dev XPAR_IIC_0_DEVICE_ID

#define IIC_SLAVE_ADDR 0x3F

#define BUFFER_SIZE     6

#define WHOAMI 0xA0

 

XIic  iic;

u8 SendBuffer [2];

u8 RecvBuffer [2];

u16 result;

float temp;

 

int main()

{

    XIic_Config *iic_conf;

    init_platform();

 

    print("Hello World\n\r");

    print("Successfully ran Hello World application");

 

    iic_conf = XIic_LookupConfig(IIC_dev);

    XIic_CfgInitialize(&iic, iic_conf, iic_conf->BaseAddress);

 

    SendBuffer[0] = 0x01;

    XIic_Send(iic.BaseAddress,IIC_SLAVE_ADDR,(u8 *)&SendBuffer, 1,XIIC_REPEATED_START);

    XIic_Recv(iic.BaseAddress,IIC_SLAVE_ADDR,(u8 *)&RecvBuffer, 1,XIIC_STOP);

 

    if(RecvBuffer[0]==WHOAMI){

        printf("Temp Sensor Detected\n\r");

    }

    else{

        printf("Temp Sensor NOT Detected\n\r");

        return 0;

    }

 

    SendBuffer[0] = 0x04;

    SendBuffer[1] = 0x0C;

    XIic_Send(iic.BaseAddress,IIC_SLAVE_ADDR,(u8 *)&SendBuffer, 2,XIIC_STOP);

 

    SendBuffer[0] = 0x04;

    XIic_Send(iic.BaseAddress,IIC_SLAVE_ADDR,(u8 *)&SendBuffer, 1,XIIC_REPEATED_START);

    XIic_Recv(iic.BaseAddress,IIC_SLAVE_ADDR,(u8 *)&RecvBuffer, 1,XIIC_STOP);

 

    while (1){

        SendBuffer[0] = 0x06;

        XIic_Send(iic.BaseAddress,IIC_SLAVE_ADDR,(u8 *)&SendBuffer, 1,XIIC_REPEATED_START);

        XIic_Recv(iic.BaseAddress,IIC_SLAVE_ADDR,(u8 *)&RecvBuffer, sizeof(RecvBuffer),XIIC_STOP);

        result = RecvBuffer[1] << 8 | RecvBuffer[0];

        temp = (float) result / 100;

        printf("Temperature is %f \n\r",temp);

        usleep(1000000);

    }

    cleanup_platform();

    return 0;

}

Running this code on the board shows the temperature being reported as in the range of 33C to 35C.

MZ_461_read_temperature

Looking at the temperature sensor chip U1 on the board with a thermal camera shows the temperature of the sensor to be 34C, which aligns with that reported by software.

MZ_461_thermal_camera

The next step in my journey of exploration with the ZUBoard 1CG board is looking at creating a SZYGZY-based application.