//define SPI port
typedef struct SpiGpio_t {
GpioMap_t sck;
GpioMap_t mosi;
GpioMap_t miso;
u8 bitWidth; /8 - 16/
ErrCode_t (*Init)(struct SpiGpio_t *port);
ErrCode_t (*Access)(struct SpiGpio_t *port, u16 output, u16 *input);
}SpiGpio_t;
ErrCode_t SpiGpioInit(struct SpiGpio_t *port);
ErrCode_t SpiGpioAccess(struct SpiGpio_t *port, u16 output, u16 *input);
//SPI port operations
ErrCode_t SpiGpioAccess(struct SpiGpio_t *port, u16 output, u16 *input)
{
(*input) = 0;
for(int bit=port->bitWidth-1;bit>=0;bit--)
{
if(output & Bit(bit))
{
GpioSet( port->mosi );
}
else
{
GpioClr( port->mosi );
}
GpioSet( port->sck );
(*input) = ((*input)<<1) | ((ReadGpio(port->miso)!=FALSE)?1:0);
GpioClr( port->sck );
}
}
ErrCode_t SpiGpioInit(struct SpiGpio_t *port)
{
port->Access = SpiGpioAccess;
GpioOutputLow(port->sck);
GpioPinsConfig(port->miso, GPIO_CFG(PULL_UD,INPUT));
GpioOutputLow(port->mosi);
}
//define a chip
typedef u8 DacChnl_t;
typedef struct Ad7949_t
{
ErrCode_t (*Init)(struct Ad7949_t *self, SpiId_t spiId, GpioMap_t cs);
ErrCode_t (*Read)(struct Ad7949_t *self, DacChnl_t chnl, u16 *value);
/*private data*/
GpioMap_t cs;
SpiGpio_t *pins;
}Ad7949_t;
ErrCode_t Ad7949Init(struct Ad7949_t *self, SpiId_t spiId, GpioMap_t cs);
ErrCode_t Ad7949Read(struct Ad7949_t *self, DacChnl_t chnl, u16 *value);
//chip operations
#define CfgMask ~(0x3fff)
#define CfgOverwrite (Bit(13)) /覆盖寄存器的内容/
#define CfgHold (~CfgOverwrite) /保持当前配置/
#define DualPolarDiff (0<<10) /双极性差分对;INx参考 Vref/2/
#define DualPolar (2<<10) /双极性差分对;INx参考 COM/
#define TempSensor (3<<10) /温度传感器/
#define UniPolarDiff (4<<10) /单极性差分对;INx参考GND/
#define UniPolarRefCom (6<<10) /单极性;INx参考COM/
#define UniPolarRefGnd (7<<10) /单极性;INx参考GND/
#define Chnl(val) (val<<7) /INx/
#define BandWidthFull (Bit(6))
#define BandWidthDiv4 (~BandWidthFull)
#define RefInt2p5 (0<<3) /内部基准电压源,REF=2.5V,温度传感器使能/
#define RefInt4p0 (1<<3) /内部基准电压源,REF=4.096V,温度传感器使能/
#define RefExtTempSensor (2<<3) /外部基准电压源,温度传感器使能/
#define RefExtIntBufTempSensor (3<<3) /外部基准电压源,内部缓冲器、温度传感器使能/
#define RefExtIntBuf (6<<3) /外部基准电压源,温度传感器禁用/
#define RefExt (7<<3) /外部基准电压源,内部缓冲器、温度传感器禁用/
#define SeqDisable (0<<1) /禁用序列器/
#define SeqUpdateConfig (1<<1) /序列扫描期间更新配置/
#define SeqIn0to7AndTemp (2<<1) /扫描IN0至INx(bit[9:7]),然后扫描温度/
#define SeqIn0to7 (3<<1) /扫描IN0至INx(bit[9:7])/
#define ReadConfigEnable (0<<0) /数据结束时回读当前配置/
#define ReadConfigDisable (1<<0) /不回读配置内容/
ErrCode_t Ad7949Init(struct Ad7949_t *self, SpiId_t spiId, GpioMap_t cs)
{
self->cs = cs;
}
static void SpiInit(struct Ad7949_t *self)
{
GpioOutputLow(self->cs);
self->pins->Init(self->pins);
}
static void SpiAccess(struct Ad7949_t *self, u16 output, u16 *input)
{
self->pins->Access(self->pins, output, input);
}
#define TrigOnTime 100
ErrCode_t Ad7949Read(struct Ad7949_t *self, DacChnl_t chnl, u16 *value)
{
u16 cfg =0;
u16 adc =0;
u32 sumup = 0;
int time = 0;
SpiInit(self);
GpioClr( self->cs );
GpioSet( self->cs );
delay(TrigOnTime);
GpioClr( self->cs );
cfg = (CfgOverwrite | UniPolarRefCom | Chnl(chnl) | BandWidthFull | RefInt2p5 | SeqDisable | ReadConfigDisable);
SpiAccess(self, cfg, &adc);
GpioSet( self->cs );
delay(TrigOnTime);
GpioClr( self->cs );
cfg = (cfg & CfgHold);
SpiAccess(self, cfg, &adc);
while(time<32)
{
GpioSet( self->cs );
delay(TrigOnTime);
GpioClr( self->cs );
SpiAccess(self, cfg, &adc);
sumup += adc;
time++;
}
(*value) = sumup/time;
}
Ad7949_t Adc = {
.cs = GPIO(PortA, Pin10),
.pins = &SpiGpio,
.Init = Ad7949Init,
.Read = Ad7949Read,
};
void main()
{
Adc.Init(&Adc, SPI_GPIO, GPIO(PortA, Pin10));
Adc.Read(&Adc, (DacChnl_t)sample, &readout);
}