In the previous chapter, we wrote about the driver of adx112, but we haven't written about the driver of adx122 yet. adx122 is an upgraded version of adx112, upgraded to 20bit, and has its own constant current source, which will be of great help for ptc/ntc temperature measurement, eliminating the bias of the peripheral circuit. The first page of adx122 is as follows
It can be seen that it is compatible with adx112 and uses the spi interface. In this chapter, we mainly talk about how to write drivers, so we will skip some important information first.
Since we use the SPI interface, let's see what kind of SPI it is, three-wire or four-wire, whether it writes data on the rising edge or the falling edge. From the manual's firgure2, we can see that it writes data on the falling edge and reads data on the falling edge, as shown in the figure below
I found in the description of the data sheet that it is the falling edge to read data and the falling edge to write data.
Look at the register configuration order, as follows
First, let's roughly define the entire pin, and start writing the SPI timing. The test prints normally.
Spi reading and writing are roughly completed, the code is as follows
#include <stdio.h>
/* define pin*/
#define mosi_h printf(" mosi h ")
#define mosi_l printf(" mosi l ")
#define cs_h printf("cs h\r\n")
#define cs_l printf("cs l\r\n")
#define sclk_h printf(" sclk h ")
#define sclk_l printf("sclk l\r\n")
#define hal_delay(x) printf("delay_%dms \r\ n",x)
//declare function
int32_t SPI_Write_Read(int32_t Data);
int main() {
int32_t rdata;
rdata=SPI_Write_Read(0x55aaffff);
printf("%x",rdata);
return 0;
}
int32_t SPI_Write_Read(int32_t Data)
{
int8_t i;
int32_t rdata=0;
//supporting role
int32_t misodata=0x0000aaaa;
int8_t miso=0;
//initial pin state
sclk_h;
mosi_l;
cs_h;
hal_delay(1);
//start transferring data
cs_l;
for ( i = 0; i < 32; i++)
{
sclk_h;
if(Data&0x80000000)
{
mosi_h;
}
else
mosi_l;
// supporting role
miso=misodata&0x00000001;
misodata>>=1;
// Equivalent to rdata=rdata|miso
rdata|= miso;
rdata<<=1;
sclk_l;
Data<<=1;
}
return rdata;
}
|
The effect is as follows
/Users/xutong/CLionProjects/untitled/cmake-build-debug/untitled
sclk h mosi l cs h
delay_1ms
cs l
sclk h mosi l sclk l
sclk h mosi h sclk l
sclk h mosi l sclk l
sclk h mosi h sclk l
sclk h mosi l sclk l
sclk h mosi h sclk l
sclk h mosi l sclk l
sclk h mosi h sclk l
sclk h mosi h sclk l
sclk h mosi l sclk l
sclk h mosi h sclk l
sclk h mosi l sclk l
sclk h mosi h sclk l
sclk h mosi l sclk l
sclk h mosi h sclk l
sclk h mosi l sclk l
sclk h mosi h sclk l
sclk h mosi h sclk l
sclk h mosi h sclk l
sclk h mosi h sclk l
sclk h mosi h sclk l
sclk h mosi h sclk l
sclk h mosi h sclk l
sclk h mosi h sclk l
sclk h mosi h sclk l
sclk h mosi h sclk l
sclk h mosi h sclk l
sclk h mosi h sclk l
sclk h mosi h sclk l
sclk h mosi h sclk l
sclk h mosi h sclk l
sclk h mosi h sclk l
aaaa0000
Process finished with exit code 0
|
It is in line with our expectations, but adx122 requires 80 clocks, which is not enough here. There are only 32 clocks here. The printed data is brought into Excel. It is obvious that the conclusion here is that 55aaffff is the value we wrote, and the read-back aaaa0000 is also the value we wrote, so there is no problem at this step, continue down
There are a lot of things to complete in 80 clocks, and if we want to read it back, we can't just use int32-t.
So we need to use a pointer to define an array, pass the read data into the array, and then return the entire array, using a pointer to receive it.
#include <stdio.h>
/* define pin*/
#define mosi_h printf(" mosi h ")
#define mosi_l printf(" mosi l ")
#define cs_h printf("cs h\r\n")
#define cs_l printf("cs l\r\n")
#define sclk_h printf(" sclk h ")
#define sclk_l printf("sclk l\r\n")
#define hal_delay(x) printf("delay_%dms \r\ n",x)
//declare function
int32_t* SPI_Write_Read(int32_t Data);
int main() {
int32_t *rdatas;
rdatas=SPI_Write_Read(0x55aaffff);
printf("%x\r\n",*rdatas);
printf("%x\r\n",*(rdatas+1));
printf("%x\r\n",*(rdatas+2));
return 0;
}
int32_t* SPI_Write_Read(int32_t Data)
{
int8_t i;
static int32_t rdata[11];
//supporting role
int32_t misodata=0x0000aaaa;
int8_t miso=0;
//initial pin state
sclk_h;
mosi_l;
cs_h;
hal_delay(1);
//start transferring data
cs_l;
for (i = 0; i < 32; i++)
{
sclk_h;
if(Data&0x80000000)
{
mosi_h;
}
else
mosi_l;
// supporting role
miso=misodata&0x00000001;
misodata>>=1;
// Equivalent to rdata=rdata|miso
rdata[0]|=miso;
rdata[0]<<=1;
sclk_l;
Data<<=1;
}
rdata[1]=0x1fffffff;
rdata[2]=0x2fffffff;
rdata[3 ]=0x3ffffffff;
rdata[4]=0x4ffffffff;
rdata[5]=0x5fffffff;
rdata[6]=0x6fffffff;
rdata[7]=0x7ffffffff;
return rdata;
}
|
Here you can see that it is the same as our setting
Because we simulate miso here, it looks a bit strange in reverse, but there is no such problem when using the actual chip.
See the simulation effect.
The general driver code for SPI is now complete, and you just need to adjust the registers yourself.
#include <stdio.h>
/* define pin*/
#define mosi_h printf(" mosi h ")
#define mosi_l printf(" mosi l ")
#define cs_h printf("cs h\r\n")
#define cs_l printf("cs l\r\n")
#define sclk_h printf(" sclk h ")
#define sclk_l printf("sclk l\r\n")
#define hal_delay(x) printf("delay_%dms \r\ n",x)
//declare function
u_int32_t* SPI_Write_Read(u_int32_t Data);
int main() {
u_int32_t *rdatas;
rdatas=SPI_Write_Read(0x55aaffff);
printf("%x\r\n",*rdatas);
printf("%x\r\n",*(rdatas+1));
printf("%x\r\n",*(rdatas+2));
return 0;
}
u_int32_t* SPI_Write_Read(u_int32_t Data)
{
int i;
static u_int32_t rdata[4]={0x00000000,0x00000000,
0x00000000,0x00000000};
//supporting role
u_int32_t temp;
u_int32_t misodata=0x10000001;
u_int32_t miso;
//initial pin state
sclk_h;
_l;
cs_h;
hal_delay(1) ;
//start transferring data
cs_l;
temp=0;
for (i = 0; i < 32; i++)
{
sclk_h;
if(Data&0x80000000)
{
mosi_h;
}
else
{
mosi_l;
}
// supporting role
miso=misodata&0x00000001;
misodata>>=1;
// Equivalent to rdata=rdata|miso
rdata[0]<<=1;
rdata[0 ]|=miso;
sclk_l;
Data<<=1;
}
//rdata[1]
misodata=0x80000008;
//
for (i = 0; i < 32;i++)
{
sclk_h;
// supporting role
miso=misodata&0x00000001;
misodata >>=1;
// Equivalent to rdata=rdata|miso
rdata[1]<<=1;
rdata[1]|=miso;
sclk_l;
}
misodata=0x20000002;
//rdata[2]
for (i = 0; i < 16; i++)
{
sclk_h;
// supporting role
miso=misodata&0x00000001;
misodata>>=1;
// Equivalent to rdata=rdata|miso
rdata[2]<< =1;
rdata[2]|=miso;
sclk_l;
}
cs_h;
return rdata;
}
|
Exactly 80
That’s all for today.