From a13422fe2b044b26b667f4e045ce8cfedd6ec647 Mon Sep 17 00:00:00 2001 From: kruger <kruger@astron.nl> Date: Thu, 18 Mar 2021 12:12:05 +0100 Subject: [PATCH] spi bitbang add --- src/apsctl/RCU.yaml | 26 +++++++++--------- src/drivers/RCU_switch.cpp | 6 ++--- src/drivers/drvbase.cpp | 4 +++ src/drivers/drvbase.h | 3 +++ src/drivers/i2c.cpp | 17 +++++++++--- src/drivers/i2c.h | 4 ++- src/drivers/i2c_array.cpp | 29 ++++++++++++-------- src/drivers/i2c_array.h | 5 ++-- src/drivers/i2cbitbang1.cpp | 1 - src/drivers/i2cbitbang1.h | 3 +++ src/drivers/spibitbang1.cpp | 53 ++++++++++++++++++++++++++++++++++++- src/drivers/spibitbang1.h | 7 +++++ src/main.cpp | 1 + 13 files changed, 123 insertions(+), 36 deletions(-) diff --git a/src/apsctl/RCU.yaml b/src/apsctl/RCU.yaml index b0a5443..fda46ea 100644 --- a/src/apsctl/RCU.yaml +++ b/src/apsctl/RCU.yaml @@ -55,7 +55,7 @@ device_registers: description: [IO-Expander for filter selection,IO-Expander for ON/OFF, Band, BUFx2,IO-Expander for ADC control] address: [0x75,0x76,0x20] device: [TCA9539,TCA9539,TCA6416] - driver: I2C_RCU + driver: I2C1 registers: - name: CONF1 description: Direction of port1 @@ -86,7 +86,7 @@ device_registers: - name: ROM description: IO-Expander for filter selection address: 0x50 - driver: I2C_RCU + driver: I2C1 registers: - name: ID description: Random @@ -99,23 +99,23 @@ device_registers: description: Monitor ADC on RCU address: 0x14 device: LTC2495 - driver: I2C_RCU + driver: I2C1 registers: - - name: Ch0 + - name: V_1v8 address: 0xB080 - - name: Ch1 + - name: V_2v5 address: 0xB880 - - name: Ch2 + - name: V_3v3 address: 0xB180 - - name: Ch3 + - name: I_Ant0 address: 0xB980 - - name: Ch4 + - name: I_Ant1 address: 0xB280 - - name: Ch5 + - name: I_Ant2 address: 0xBA80 - - name: Ch6 + - name: V_Ant0 address: 0xB380 - - name: Ch7 + - name: V_Ant1 address: 0xBB80 - name: Temp address: 0xA0C0 @@ -125,7 +125,7 @@ device_registers: - name: HB_UC description: RCU microcontroller address: 0x40 - driver: I2C_RCU + driver: I2C1 registers: - name: ID description: Device ID @@ -135,7 +135,7 @@ device_registers: dim: 3 address: [0x41,0x42,0x43] description: Virtual HBAT0 interface - driver: I2C_HBAT + driver: I2C1 registers: - name: XY address: 0x10 diff --git a/src/drivers/RCU_switch.cpp b/src/drivers/RCU_switch.cpp index a91e43d..c5f8aac 100644 --- a/src/drivers/RCU_switch.cpp +++ b/src/drivers/RCU_switch.cpp @@ -11,7 +11,7 @@ bool c_RCU_switch::I2Csend_swreg(unsigned int swstate,int addr,int reg,int len,t if (swstate!=state) { state=t_buffer(swstate); t_buffer SW1=state & 0xff; - if (!(c_i2c::I2Csend(config.devreg->address,1,&SW1))) return false; + if (!(c_i2c::I2Csend_noreg(config.devreg->address,1,&SW1))) return false; } return c_i2c::I2Csend_reg(addr,reg,len,data); } @@ -19,11 +19,11 @@ bool c_RCU_switch::I2Csend_swreg(unsigned int swstate,int addr,int reg,int len,t bool c_RCU_switch::I2Cset_switch(unsigned int swstate) { if (swstate!=state) { - std::cout << "state=" << swstate << "->" << int(state) <<"\n"; +// std::cout << "state=" << swstate << "->" << int(state) <<"\n"; state=(swstate); t_buffer SW1=state & 0xff; t_buffer SW2=(state>>8) & 0xff; //TODO: implemented for DTS - if (!(c_i2c::I2Csend(config.devreg->address,1,&SW1))) return false; + if (!(c_i2c::I2Csend_noreg(config.devreg->address,1,&SW1))) return false; } return true; } diff --git a/src/drivers/drvbase.cpp b/src/drivers/drvbase.cpp index aa739bb..365a1ed 100644 --- a/src/drivers/drvbase.cpp +++ b/src/drivers/drvbase.cpp @@ -2,6 +2,10 @@ #include <iostream> drvbase::drvbase(const t_driver config1) : config (config1){}; +bool drvbase::I2Csend(int addr,int reg,int len,t_buffer* data,int direction){ + std::cout << "I2Csend "<<config.name <<" not implemented!\n"; + return false; +}; int ApplyMask(int value,int width,int bitoffset,int old){ diff --git a/src/drivers/drvbase.h b/src/drivers/drvbase.h index 13b489c..90b50e7 100644 --- a/src/drivers/drvbase.h +++ b/src/drivers/drvbase.h @@ -12,7 +12,10 @@ class drvbase{ virtual bool setvar(int x,int len,t_buffer* buffer,int lenmask,bool* mask){}; virtual int getvar(int x,t_buffer* buffer,int lenmask,bool* mask){return 0;}; virtual bool setdevreg(t_devreg devreg,int len,t_buffer* buffer,int lenmask,bool* mask){}; + virtual bool I2Csend(int addr,int reg,int len,t_buffer* data,int direction); + // protected: const t_driver config; + drvbase** drivers; }; #endif \ No newline at end of file diff --git a/src/drivers/i2c.cpp b/src/drivers/i2c.cpp index 76b2a30..cd79120 100644 --- a/src/drivers/i2c.cpp +++ b/src/drivers/i2c.cpp @@ -23,8 +23,17 @@ c_i2c::c_i2c(const t_driver config1) : drvbase (config1){ } }; +bool c_i2c::I2Csend(int addr,int reg,int len,t_buffer* data,int direction){ + if (direction==0) { //send + if (reg>=0) I2Csend_reg(addr,reg,len,data); + else I2Csend_noreg(addr,len,data); + } else { + I2Cget_reg(addr,reg,len,data); + } +} + bool c_i2c::I2Csend_reg(int addr,int reg,int len,t_buffer* data){ - std::cout << config.name <<": i2c send to addr="<<addr<<" reg="<<reg<<" len="<<len<<" value="<<int(data[0]) <<"\n"; +// std::cout << config.name <<": i2c send to addr="<<addr<<" reg="<<reg<<" len="<<len<<" value="<<int(data[0]) <<"\n"; if (ioctl(file, I2C_SLAVE, addr)<0) return false; // return true; // return (i2c_smbus_write_block_data(file,reg,len,data)>=0); @@ -35,15 +44,15 @@ bool c_i2c::I2Cget_reg(int addr,int reg,int len,t_buffer* data){ if (ioctl(file, I2C_SLAVE, addr)<0) return false; // return true; int result=i2c_smbus_read_i2c_block_data(file,reg,len,data); - std::cout << config.name <<": i2c get from addr="<<addr<<" reg="<<reg<<" len="<<len<<" value="<<int(data[0]) <<" result" << result<<"\n"; +// std::cout << config.name <<": i2c get from addr="<<addr<<" reg="<<reg<<" len="<<len<<" value="<<int(data[0]) <<" result" << result<<"\n"; return (result==len); } -bool c_i2c::I2Csend(int addr,int len,t_buffer* data){ +bool c_i2c::I2Csend_noreg(int addr,int len,t_buffer* data){ // std::cout << config.name <<": i2c send to addr="<<addr<<" len="<<len<<" value="<<int(data[0])<<"\n"; if (ioctl(file, I2C_SLAVE, addr)<0) return false; int result=write(file,data,len); - std::cout << config.name <<": i2c send to addr="<<addr<<" len="<<len<<" value="<<int(data[0])<<" result" << result<<"\n"; +// std::cout << config.name <<": i2c send to addr="<<addr<<" len="<<len<<" value="<<int(data[0])<<" result" << result<<"\n"; return (result>=0); } diff --git a/src/drivers/i2c.h b/src/drivers/i2c.h index df46dd1..711d771 100644 --- a/src/drivers/i2c.h +++ b/src/drivers/i2c.h @@ -6,9 +6,11 @@ class c_i2c : public drvbase { public: c_i2c(const t_driver config1); + bool I2Csend(int addr,int reg,int len,t_buffer* data,int direction); + bool I2Csend_reg(int addr,int reg,int len,t_buffer* data); bool I2Cget_reg(int addr,int reg,int len,t_buffer* data); - bool I2Csend(int addr,int len,t_buffer* data); + bool I2Csend_noreg(int addr,int len,t_buffer* data); private: int file; }; diff --git a/src/drivers/i2c_array.cpp b/src/drivers/i2c_array.cpp index 9883c30..afa4b25 100644 --- a/src/drivers/i2c_array.cpp +++ b/src/drivers/i2c_array.cpp @@ -29,7 +29,8 @@ bool c_i2c_array::setvar2(t_variable variable,int Ndev,int stepbuf,t_buffer* buf for (int rcui=0;rcui<N;rcui++){ if ((stepmask>0) && (!mask[rcui*stepmask])) continue; parent->I2Cset_switch(1<<rcui);//todo add offset - seti2c(rcui,variable.devreg[Ndev],variable.width,variable.bitoffset[Ndev],&(buffer[rcui*stepbuf])); + selectedRCU=rcui; + seti2c(variable.devreg[Ndev],variable.width,variable.bitoffset[Ndev],&(buffer[rcui*stepbuf])); } } @@ -47,7 +48,8 @@ int c_i2c_array::getvar2(t_variable variable,int Ndev,int stepbuf,t_buffer* buff for (int rcui=0;rcui<N;rcui++){ if ((stepmask>0) && (!mask[rcui*stepmask])) continue; parent->I2Cset_switch(1<<rcui);//todo add offset - geti2c(rcui,variable.devreg[Ndev],variable.width,variable.bitoffset[Ndev],&(buffer[rcui*stepbuf])); + selectedRCU=rcui; + geti2c(variable.devreg[Ndev],variable.width,variable.bitoffset[Ndev],&(buffer[rcui*stepbuf])); } return N; }; @@ -62,30 +64,35 @@ bool c_i2c_array::setdevreg(t_devreg devreg,int len,t_buffer* buffer,int lenmask if (width==0) width=8;//todo: make this a broadcast for (int rcui=0;rcui<N;rcui++){ if ((lenmask>0) && (!mask[rcui])) continue; - parent->I2Cset_switch(1<<rcui);//todo add offset - seti2c(rcui,devreg,width,0,&(buffer[rcui*stride])); + parent->I2Cset_switch(1<<rcui);//todo add offset + selectedRCU=rcui; + seti2c(devreg,width,0,&(buffer[rcui*stride])); } } -void c_i2c_array::seti2c(int rcui,const t_devreg devreg,int width,int bitoffset,t_buffer* buffer){ +void c_i2c_array::seti2c(const t_devreg devreg,int width,int bitoffset,t_buffer* buffer){ t_buffer oldvalue=0; if (devreg.store>0) { - oldvalue=storedRegs[devreg.store-1][rcui]; + oldvalue=storedRegs[devreg.store-1][selectedRCU]; buffer[0]=ApplyMask(buffer[0],width,bitoffset,oldvalue); - storedRegs[devreg.store-1][rcui]=buffer[0]; + storedRegs[devreg.store-1][selectedRCU]=buffer[0]; } int len2=((width+bitoffset-1)>>3)+1; //1..8 bits = 1 byte, 9..16 bits=2bytes etc. - parent->I2Csend_reg(devreg.address,devreg.register_W,len2,buffer); +// std::cout << "seti2c" << drivers[devreg.driver]->config.name << "\n"; + drivers[devreg.driver]->I2Csend(devreg.address,devreg.register_W,len2,buffer,0); +// parent->I2Csend_reg(devreg.address,devreg.register_W,len2,buffer); } -void c_i2c_array::geti2c(int rcui,const t_devreg devreg,int width,int bitoffset,t_buffer* buffer){ +void c_i2c_array::geti2c(const t_devreg devreg,int width,int bitoffset,t_buffer* buffer){ int len2=((width+bitoffset-1)>>3)+1; //1..8 bits = 1 byte, 9..16 bits=2bytes etc. - parent->I2Cget_reg(devreg.address,devreg.register_R,len2,buffer); +// parent->I2Cget_reg(devreg.address,devreg.register_R,len2,buffer); +// std::cout << "geti2c" << devreg.driver << " " << drivers[devreg.driver]->config.name << "\n"; + drivers[devreg.driver]->I2Csend(devreg.address,devreg.register_R,len2,buffer,1); if (devreg.store>0) { // std::cout << "DEBUG: USED stored value="<< int(buffer[0]) <<"\n"; // buffer[0]=storedRegs[devreg.store-1][rcui]; - storedRegs[devreg.store-1][rcui]=buffer[0]; + storedRegs[devreg.store-1][selectedRCU]=buffer[0]; buffer[0]=UnMask(buffer[0],width,bitoffset); } diff --git a/src/drivers/i2c_array.h b/src/drivers/i2c_array.h index a2c094e..beff261 100644 --- a/src/drivers/i2c_array.h +++ b/src/drivers/i2c_array.h @@ -14,8 +14,8 @@ class c_i2c_array : public drvbase { bool setvar2(t_variable variable,int Ndev,int stepbuf,t_buffer* buffer,int stepmask,bool* mask); int getvar2(t_variable variable,int Ndev,int stepbuf,t_buffer* buffer,int stepmask,bool* mask); - void seti2c(int rcui,const t_devreg devreg,int width,int bitoffset,t_buffer* buffer); - void geti2c(int rcui,const t_devreg devreg,int width,int bitoffset,t_buffer* buffer); + void seti2c(const t_devreg devreg,int width,int bitoffset,t_buffer* buffer); + void geti2c(const t_devreg devreg,int width,int bitoffset,t_buffer* buffer); bool setdevreg(t_devreg devreg,int len,t_buffer* buffer,int lenmask,bool* mask); c_RCU_switch* parent; @@ -23,6 +23,7 @@ class c_i2c_array : public drvbase { int N; //number of devices private: int switch_dev; + int selectedRCU; t_buffer storedRegs[NumberStoreReg][32]; //Todo: use N instead of 32 }; #endif \ No newline at end of file diff --git a/src/drivers/i2cbitbang1.cpp b/src/drivers/i2cbitbang1.cpp index 91fcd5f..c25bc6d 100644 --- a/src/drivers/i2cbitbang1.cpp +++ b/src/drivers/i2cbitbang1.cpp @@ -6,4 +6,3 @@ c_i2cbitbang1::c_i2cbitbang1(const t_driver config1) : drvbase (config1){}; - diff --git a/src/drivers/i2cbitbang1.h b/src/drivers/i2cbitbang1.h index 92a3bb6..ffafa41 100644 --- a/src/drivers/i2cbitbang1.h +++ b/src/drivers/i2cbitbang1.h @@ -9,6 +9,9 @@ class c_i2cbitbang1 : public drvbase { c_i2cbitbang1(const t_driver config1); c_i2c_array* parent; + + private: + }; #endif \ No newline at end of file diff --git a/src/drivers/spibitbang1.cpp b/src/drivers/spibitbang1.cpp index f144883..2edb3c2 100644 --- a/src/drivers/spibitbang1.cpp +++ b/src/drivers/spibitbang1.cpp @@ -3,7 +3,58 @@ #include <iostream> -c_spibitbang1::c_spibitbang1(const t_driver config1) : drvbase (config1){}; +c_spibitbang1::c_spibitbang1(const t_driver config1) : drvbase (config1){ + CLK=config1.devreg[0]; + SDIO=config1.devreg[1]; + SDIOdir=config1.devreg[2]; + CS=config1.devreg[3]; + CLKpin=config1.parameters[0]; + SDIOpin=config1.parameters[1]; + CSpin=config1.parameters[2]; +}; +bool c_spibitbang1::I2Csend(int addr,int reg,int len,t_buffer* data,int direction){ + t_buffer bit[1]={0}; + if (direction==0) { //Send + int data2 = ( 0x00 << 23 ) + ( 0x00 << 21 ) + ( reg << 8 ) + data[0]; + std::cout << "SPI send" << data2 << "\n"; + bit[0]={0};parent->seti2c(CS,1,CSpin,bit); + for (int x=0;x<32;x++) + { + bit[0]=(data2>>(31-x)) & 1; //Not that efficient, but works + parent->seti2c(SDIO,1,SDIOpin,bit); + bit[0]={1};parent->seti2c(CLK,1,CLKpin,bit); + bit[0]={0};parent->seti2c(CLK,1,CLKpin,bit); + } + bit[0]={1};parent->seti2c(CS,1,CSpin,bit); + bit[0]={1};parent->seti2c(SDIO,1,SDIOpin,bit); + } else { + int data2 = ( 0x01 << 15) + ( 0x00 << 13 ) + reg; + bit[0]={0};parent->seti2c(CLK,1,CLKpin,bit); + bit[0]={0};parent->seti2c(CS,1,CSpin,bit);//enable + for (int x=0;x<16;x++){ + bit[0]={0};parent->seti2c(CLK,1,CLKpin,bit); + bit[0]=(data2>>(15-x)) & 1; //Not that efficient, but works + parent->seti2c(SDIO,1,SDIOpin,bit); + bit[0]={1};parent->seti2c(CLK,1,CLKpin,bit); + } + bit[0]=1;parent->seti2c(SDIOdir,1,SDIOpin,bit); + bit[0]=0;parent->seti2c(CLK,1,CLKpin,bit); + data2=0; + for (int x=0;x<8;x++){ + parent->geti2c(SDIO,1,SDIOpin,bit); + data2<<=2; + data2+=bit[0]; + bit[0]=1;parent->seti2c(CLK,1,CLKpin,bit); + bit[0]=0;parent->seti2c(CLK,1,CLKpin,bit); + } + + bit[0]=1;parent->seti2c(CS,1,CSpin,bit);//disable + bit[0]=1;parent->seti2c(SDIO,1,SDIOpin,bit); + bit[0]=0;parent->seti2c(SDIOdir,1,SDIOpin,bit); + + } + return true; +} diff --git a/src/drivers/spibitbang1.h b/src/drivers/spibitbang1.h index baa0748..6f8bf2f 100644 --- a/src/drivers/spibitbang1.h +++ b/src/drivers/spibitbang1.h @@ -8,7 +8,14 @@ class c_spibitbang1 : public drvbase { public: c_spibitbang1(const t_driver config1); c_i2c_array* parent; + //bool setvar(int x,int len,t_buffer* buffer,int lenmask,bool* mask); + // int getvar(int x,t_buffer* buffer,int lenmask,bool* mask); + bool I2Csend(int addr,int reg,int len,t_buffer* data,int direction); private: + t_devreg CLK,SDIO,SDIOdir,CS; + int CLKpin,SDIOpin,CSpin; + int setpin(int mask,t_devreg reg,int pin,int value); + }; #endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index c5af4e7..7717d13 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -107,6 +107,7 @@ int main(int argc, char *argv[]) // drivers1.d[1]->setvar(4,32,buffer); // for (int x=0;x<number_vars;x++) // std::cout << variables[x].name << "\n"; + for (int x=0;x<number_drivers;x++) drivers1.d[x]->drivers=drivers1.d; std::cout << "Open read pipe\n"; int fd_in=open("serv_to_RCU",O_RDONLY); if (fd_in<0) return false; -- GitLab