如果你认为本系列文章对你有所帮助,请大家有钱的捧个钱场,点击此处赞助,赞助额1元起步,多少随意
锋影
e-mail 174176320@qq.com
Create spi app to read data from SPI device use QNX 6.6
spi_app is used to read temperature and pressure from spi chip (LPS25H). This chip is connected to Raspberry Pi2 via spi port.
Follow section 5 to create an app name “spi_app”.
Figure 9.1 spi_app project is created
spi_app use some APIs from libspi-master.a, so please edit common.mk add the lib as below:
Figure 9.2 Add libspi-master library to spi_app project
Notes:
In the case libspi-master.a isn’t available in the qnx6.6 installed folder, please download libspi-master.a at the link:
http://community.qnx.com/sf/wiki/do/viewHtml/projects.bsp/wiki/ExperimentalDriversAndUtilities
Copy libspi-master.a to qnx6.6 installed folder at C:\qnx660\target\qnx6\armle-v7\usr\lib
Copy following code to “spi_app.c” file
#include <stdlib.h>
#include <stdio.h>
#include <hw/spi-master.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
const char *devname[1] = {“/dev/spi0”};
/* Define registers of LPS25HP */
#define LPS25HP_CONF 0x10
#define LPS25HP_WHO_AM_I 0x0F
#define LPS25HP_CTRL1 0x20
#define LPS25HP_CTRL2 0x21
#define LPS25HP_CTRL3 0x22
#define LPS25HP_CTRL4 0x23
#define LPS25HP_INT_CFG 0x24
#define LPS25HP_INT_SOURCE 0x25
#define LPS25HP_POUT_XL 0x28
#define LPS25HP_POUT_L 0x29
#define LPS25HP_POUT_H 0x2A
#define LPS25HP_TEMP_OUT_L 0x2B
#define LPS25HP_TEMP_OUT_H 0x2C
#define LPS25HP_FIFO_CTRL 0x2E
#define ST_SENSORS_SPI_READ 0x80
#define ST_SENSORS_SPI_MULTIREAD 0xC0
#define LPS25HP_DEVIVE_ID 0xBD
unsigned spi_speed[2] = {100000, 10000000};
static float result_press, result_temp;
int tspi_getdrvinfo()
{
spi_drvinfo_t info;
int i, fd;
if ((fd = spi_open(devname[0])) < 0){
fprintf(stdout,”SPI open failed, fd = %d errno = %d\n”, fd, errno);
return (-1);
}
i = spi_getdrvinfo( fd, &info );
if (i == EOK){
fprintf( stdout, “version = %x\n”, info.version );
fprintf( stdout, “driver name = %s\n”, info.name );
fprintf( stdout, “feature = %x\n”, info.feature );
}
else
fprintf( stdout, “get driver info failed\n” );
spi_close( fd );
return 0;
}
uint8_t LPS25H_spi_read (int fd, int device, uint8_t addr)
{
int ret = 0;
uint8_t tx_buf[2], rx_buf[2];
memset(tx_buf,0,2);
memset(rx_buf,0,2);
tx_buf[0] = addr | ST_SENSORS_SPI_READ;
tx_buf[1] = 0;
ret = spi_xchange(fd, device, (void*)tx_buf, (void*)rx_buf, 2);
if(-1 == ret){
fprintf(stdout,”%s: reg=0x%2x failed\n”,__func__,addr);
return 0xFF;
}
return rx_buf[1];
}
int LPS25H_spi_write (int fd, int device, uint8_t addr, uint8_t data)
{
int ret = 0;
uint8_t tx_buf[2], rx_buf[2];
memset(tx_buf,0,2);
memset(rx_buf,0,2);
tx_buf[0] = addr;
tx_buf[1] = data;
ret = spi_xchange(fd, device, (void*)tx_buf, (void*)rx_buf, 2);
if(-1 == ret){
fprintf(stdout,”%s: with reg=0x%2x failed\n”,__func__,addr);
return -1;
}
return EOK;
}
int get_pressure_temperature(int fd, int device)
{
int val_press, val_temp;
int ret, data, timeout;
val_press = 0;
val_temp = 0;
ret = LPS25H_spi_read(fd,device,LPS25HP_CTRL2);
if(0xFF == ret){
fprintf(stdout,”%s: failed\n”,__func__);
return -1;
}
ret += 0x01;
//Trigger a single measurement of pressure and temperature.
LPS25H_spi_write(fd,device,LPS25HP_CTRL2, (uint8_t)ret);
// Wait until new data are available in the output registers
ret = 1;
timeout = 0;
while ((ret & 0x01) !=0 ){
ret = LPS25H_spi_read(fd,device,LPS25HP_CTRL2);
if(0xFF == ret){
fprintf(stdout,”%s: failed\n”,__func__);
return -1;
}
usleep(10);
if(timeout++ > 10000)
break;
}
// Read PRESS_POUT_XL
val_press = LPS25H_spi_read(fd,device,LPS25HP_POUT_XL);
if(-1 == val_press){
fprintf(stdout,”%s: failed\n”,__func__);
return -1;
}
// Read PRESS_OUT_L
ret = LPS25H_spi_read(fd,device,LPS25HP_POUT_L);
if(0xFF == ret){
fprintf(stdout,”%s: failed\n”,__func__);
return -1;
}
data = ret << 8;
val_press |= data;
// Read PRESS_OUT_H
ret = LPS25H_spi_read(fd,device,LPS25HP_POUT_H);
if(0xFF == ret){
fprintf(stdout,”%s: failed\n”,__func__);
return -1;
}
data = ret << 16;
val_press = val_press | data;
result_press = (float)((float)val_press / 4096);
// Read TEMP_OUT_L
val_temp = LPS25H_spi_read(fd,device,LPS25HP_TEMP_OUT_L);
if(0xFF == val_temp){
fprintf(stdout,”%s: failed\n”,__func__);
return -1;
}
// Read TEMP_OUT_H
ret = LPS25H_spi_read(fd,device,LPS25HP_TEMP_OUT_H);
if(0xFF == ret){
fprintf(stdout,”%s: failed\n”,__func__);
return -1;
}
data = (ret << 8);
val_temp |= data;
if (data == 0){
//In this case, temperature = 42.5
result_temp = 42.5;
}
if ((data & 0x8000) != 0){
//In this case, need to caluculate 2’s complement because temperature < 42.5
val_temp = 0x10000 – val_temp;
result_temp = (float)((float)val_temp/480);
result_temp = 42.5 – result_temp;
}else{
//In this case, No need to caluculate 2’s complement because temperature > 42.5
result_temp = (float)((float)val_temp/480);
result_temp += 42.5;
}
return EOK;
}
int LPS25H_init(int fd,int device)
{
int ret = 0;
uint8_t whoami = 0;
fprintf(stdout,”Device ID:”);
whoami = LPS25H_spi_read(fd,device,LPS25HP_WHO_AM_I);
fprintf(stdout,” 0x%X \n”, whoami);
if (LPS25HP_DEVIVE_ID != (uint8_t)whoami){
fprintf(stdout,”%s: Device ID mismatch.\n”,__func__);
return -1;
}
ret = LPS25H_spi_write(fd,device,LPS25HP_CONF,0x05);
if(-1 == ret)
return -1;
ret = LPS25H_spi_write(fd,device,LPS25HP_CTRL1,0x84);
if(-1 == ret)
return -1;
ret = LPS25H_spi_write(fd,device,LPS25HP_FIFO_CTRL,0xDF);
if(-1 == ret)
return -1;
ret = LPS25H_spi_write(fd,device,LPS25HP_CTRL2,0x40);
if(-1 == ret)
return -1;
return EOK;
}
int LPS25H_test(int fd,int device)
{
int i =0, ret = 0;
for (i = 0; i < 1440; i++){
ret = get_pressure_temperature(fd,device);
if(-1 == ret){
return -1;
}
fprintf(stdout,”No.%d, Pressure: %.2f hPa, Temperture: %.2f C \n\r”,i,result_press,result_temp);
sleep(5);
}
return EOK;
}
int main(int argc, char *argv[])
{
int fd, ret;
int device;
spi_cfg_t spicfg;
device = 0 ;
fprintf(stdout,”Opening SPI driver\n” );
fd = spi_open(devname[0]);
if (fd < 0){
fprintf( stdout, “spi_open() failed\n” );
return 0;
}
spicfg.mode = ((8 & SPI_MODE_CHAR_LEN_MASK) | SPI_MODE_BODER_MSB );
spicfg.clock_rate = 2780000;
ret = spi_setcfg( fd, 0 , &spicfg );
if (ret != EOK){
fprintf( stdout, “spi0_setcfg() call failed! (err=0x%x)\n”, ret );
goto cleanup;
}
ret = LPS25H_init(fd,device);
if(-1 == ret){
goto cleanup;
}
ret = LPS25H_test(fd,device);
if(-1 == ret){
goto cleanup;
}
cleanup: spi_close( fd );
return 0;
}
Build project to create binary file: spi_app. Copy the file to Raspberry Pi2 board under /tmp folder
9.2 Verify spi app
After make hardware connection, please run spi_app from command line:
# /tmp/spi_app
Please make sure pressure and temperature is printed out as below: