SPI芯片驱动(C)

//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);
}

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值