/* * ProgramName: karacri_PI.c * I/O Device: KBRS31A * Compile: cc karacri_PI.c -o a.out * Execute: ./a.out # v1.01 2016/10/20: Add Voltage Display # v1.00 2015/6/25: Release */ #include #include #include #include #include #define RASPORT_DIR_IN (0) #define RASPORT_DIR_OUT (1) #define RASPORT_Di_1 (9) #define RASPORT_Di_2 (25) #define RASPORT_Di_3 (10) #define RASPORT_Di_4 (24) #define RASPORT_Do_1 (23) #define RASPORT_Do_2 (27) #define RASPORT_Do_3 (17) #define RASPORT_Do_4 (18) #define RASPORT_Do_5 (7) #define RASPORT_Do_6 (22) #define RASPORT_AD_din (3) //out #define RASPORT_AD_cs (2) //out #define RASPORT_AD_sclk (14) //out #define RASPORT_AD_dout (15) //in #define RASPORT_AD_sstrb (4) //in #define RASPORT_AiCMP (11) //in #define RASPORT_WdtPulse (8) //out void raspi_gpio_init( int ch, int direction ) { int i,fd,N; char stext [128]; char stext2[128]; //1)ToEnableSet sprintf( stext, "%d", ch ); if((fd=open("/sys/class/gpio/unexport",O_WRONLY)) >= 0 ){ write(fd,stext,2); //port unenable close(fd); } for(i=0,N=100;i= 0) break; usleep((useconds_t)1000); system( "sudo chmod a+w /sys/class/gpio/export" ); } if( i == N ){ return; } write(fd,stext,2); //port enable close(fd); //2)DirectionSet sprintf( stext, "/sys/class/gpio/gpio%d/direction", ch ); for(i=0,N=100;i= 0) break; usleep((useconds_t)1000); sprintf( stext2, "sudo chmod a+w %s", stext ); system ( stext2 ); } if( i == N ){ return; } switch(direction){ case RASPORT_DIR_IN: write(fd,"in",3); break; case RASPORT_DIR_OUT: write(fd,"out",4); break; } close(fd); } int raspi_gpio_read( int ch ) { int i,fd,N; char stext [128]; char stext2[128]; char cdata [4]; sprintf( stext, "/sys/class/gpio/gpio%d/value", ch ); for(i=0,N=100;i= 0) break; usleep((useconds_t)1000); sprintf( stext2, "sudo chmod a+r %s", stext ); system ( stext2 ); } if( i == N ){ sleep(1); return 0; } read(fd,cdata,2); close(fd); if( cdata[0] == (char)'1' ) return 1; else return 0; } void raspi_gpio_write( int ch, int data ) { int i,fd,N; char stext [128]; char stext2[128]; sprintf( stext, "/sys/class/gpio/gpio%d/value", ch ); for(i=0,N=100;i= 0) break; usleep((useconds_t)1000); sprintf( stext2, "sudo chmod a+w %s", stext ); system ( stext2 ); } if( i == N ){ sleep(1); return; } switch(data){ case 0: write(fd,"0",2); break; case 1: default: write(fd,"1",2); break; } close(fd); } int kcxio_raspi_din( int ch ) { int k = 0; switch(ch){ case 1: k = raspi_gpio_read( RASPORT_Di_1 ); break; case 2: k = raspi_gpio_read( RASPORT_Di_2 ); break; case 3: k = raspi_gpio_read( RASPORT_Di_3 ); break; case 4: k = raspi_gpio_read( RASPORT_Di_4 ); break; default: break; } if( k == 0 ) return 1; //ON else return 0; //OFF } void kcxio_raspi_dout( int ch, int idata ) { void raspi_gpio_write(int ch,int data); if( idata != 0 ) idata = 1; switch(ch){ case 1: raspi_gpio_write( RASPORT_Do_1, idata ); break; case 2: raspi_gpio_write( RASPORT_Do_2, idata ); break; case 3: raspi_gpio_write( RASPORT_Do_3, idata ); break; case 4: raspi_gpio_write( RASPORT_Do_4, idata ); break; case 5: raspi_gpio_write( RASPORT_Do_5, idata ); break; case 6: raspi_gpio_write( RASPORT_Do_6, idata ); break; default: break; } } void kcxadc_raspi_reset() { int i,cmd; raspi_gpio_write(RASPORT_AD_cs, 1); raspi_gpio_write(RASPORT_AD_sclk,0); /*1)ChipReset*/ usleep(5000); cmd = 0x00C8; /*ManualTable8*/ raspi_gpio_write(RASPORT_AD_cs, 0); for(i=0;i<(8);i++){ raspi_gpio_write(RASPORT_AD_din, (cmd & (0x80>>i))); raspi_gpio_write(RASPORT_AD_sclk, 1); raspi_gpio_write(RASPORT_AD_sclk, 0); } raspi_gpio_write(RASPORT_AD_cs, 1); raspi_gpio_write(RASPORT_AD_sclk,0); /*2)InternalClock(Mode2)*/ usleep(5000); cmd = 0x00A8; /*ManualTable8*/ raspi_gpio_write(RASPORT_AD_cs, 0); for(i=0;i<(8);i++){ raspi_gpio_write(RASPORT_AD_din, (cmd & (0x80>>i))); raspi_gpio_write(RASPORT_AD_sclk, 1); raspi_gpio_write(RASPORT_AD_sclk, 0); } raspi_gpio_write(RASPORT_AD_cs, 1); raspi_gpio_write(RASPORT_AD_sclk,0); } static int range_mode_1ch = 0; static int range_mode_2ch = 0; static int range_mode_3ch = 0; static int range_mode_4ch = 0; void kcxadc_raspi_rangeset( int ch, int range ) { int i,_maximch,cmd,range_R210; switch( range ){ case 4: range_R210 = 0x07; break; /* +-12v */ case 3: range_R210 = 0x04; break; /* +- 6v */ case 2: range_R210 = 0x01; break; /* +- 3v */ case 1: range_R210 = 0x06; break; /* + 12v */ case 0: default: range_R210 = 0x03; break; /* + 6v */ } switch( ch ){ case 1: _maximch = 0; range_mode_1ch = range; break; case 2: _maximch = 1; range_mode_2ch = range; break; case 3: _maximch = 2; range_mode_3ch = range; break; case 4: _maximch = 3; range_mode_4ch = range; break; default: _maximch = 3; range_mode_4ch = range; break; } cmd = ( _maximch << 4 ) | range_R210 | 0x80; raspi_gpio_write(RASPORT_AD_cs, 0); for(i=0;i<(8);i++){ raspi_gpio_write(RASPORT_AD_din, (cmd & (0x80>>i))); raspi_gpio_write(RASPORT_AD_sclk, 1); raspi_gpio_write(RASPORT_AD_sclk, 0); } raspi_gpio_write(RASPORT_AD_cs, 1); raspi_gpio_write(RASPORT_AD_sclk,0); } #define RasPiAdcSSTRBCNTs (20) //Fix #define RasPiAdvalAVRs (1) //Number of average of the AD value int kcxio_raspi_adval( int ch ) { int i,j,_maximch,cmd; int ad_val,getval,bit_data; int adc_error; long ldata; static int ad_val_statck[4][RasPiAdvalAVRs]; static int crntP = 0; static int init = 0; void kcxadc_raspi_init(int r1,int r2,int r3,int r4); if( init == 0 ){ for(i=0;i<(4);i++){ for(j=0;j= 5 ) return 0; adc_error = 0; raspi_gpio_write(RASPORT_AD_cs, 1); raspi_gpio_write(RASPORT_AD_sclk,0); raspi_gpio_write(RASPORT_AD_din, 0); raspi_gpio_write(RASPORT_AD_cs, 0); /* Active CS */ switch( ch ){ case 1: _maximch = 0; break; case 2: _maximch = 1; break; case 3: _maximch = 2; break; case 4: _maximch = 3; break; default: _maximch = 0; break; } cmd = ( _maximch << 4 ) | 0x80; for(i=0;i<(8);i++){ raspi_gpio_write(RASPORT_AD_din, (cmd & (0x80>>i))); raspi_gpio_write(RASPORT_AD_sclk,1); raspi_gpio_write(RASPORT_AD_sclk,0); } raspi_gpio_write(RASPORT_AD_cs,1); for(i=0;i 0 ) break; usleep((useconds_t)1000); } if( i == RasPiAdcSSTRBCNTs ){ adc_error = 1; } raspi_gpio_write(RASPORT_AD_cs,0); getval = 0; for(i=0;i<(16);i++){ raspi_gpio_write(RASPORT_AD_sclk, 1); if( raspi_gpio_read( RASPORT_AD_dout ) > 0 ) bit_data = 1; else bit_data = 0; getval = (getval<<1) | bit_data; raspi_gpio_write(RASPORT_AD_sclk,0); } raspi_gpio_write(RASPORT_AD_cs, 1); raspi_gpio_write(RASPORT_AD_din,0); if( RasPiAdvalAVRs >= 2 ){ //Average of the AD value ad_val_statck[ch][crntP] = getval; ldata = 0; for(i=0;i= RasPiAdvalAVRs ) crntP = 0; }else{ //Non average ad_val = getval; } if( adc_error == 1 ){ kcxadc_raspi_init(0,0,0,0); } return ad_val; } float kcxio_raspi_advolt( int ch ) { int adcval,range_mode; float volt; range_mode = 0; switch(ch){ case 1: range_mode = range_mode_1ch; break; case 2: range_mode = range_mode_2ch; break; case 3: range_mode = range_mode_3ch; break; case 4: range_mode = range_mode_4ch; break; } adcval = kcxio_raspi_adval(ch); switch(range_mode){ case 4: // +- 12.288v (over) volt = 0.0; break; case 3: // +- 6.144v volt = ( 2.0 * 6.144 ) * ( (float)adcval / 65535.0 ) - 6.144; break; case 2: // +- 3.072v volt = ( 2.0 * 3.072 ) * ( (float)adcval / 65535.0 ) - 3.072; break; case 1: // 0 - 12.288v (over) volt = 0.0; break; case 0: // 0 - 6.144v defalt: volt = 6.144 * ( (float)adcval / 65535.0 ); break; } return volt; } float kcxio_raspi_ain(int ch) { return kcxio_raspi_advolt(ch); } void kcxio_raspi_in( int mode, int idata[], float fdata[] ) { switch( mode ){ case 1: idata[0] = kcxio_raspi_din( 1 ); idata[1] = kcxio_raspi_din( 2 ); idata[2] = kcxio_raspi_din( 3 ); idata[3] = kcxio_raspi_din( 4 ); break; case 2: idata[4] = kcxio_raspi_adval( 1 ); idata[5] = kcxio_raspi_adval( 2 ); idata[6] = kcxio_raspi_adval( 3 ); idata[7] = kcxio_raspi_adval( 4 ); fdata[0] = kcxio_raspi_advolt( 1 ); fdata[1] = kcxio_raspi_advolt( 2 ); fdata[2] = kcxio_raspi_advolt( 3 ); fdata[3] = kcxio_raspi_advolt( 4 ); break; case 3: idata[0] = kcxio_raspi_din( 1 ); idata[1] = kcxio_raspi_din( 2 ); idata[2] = kcxio_raspi_din( 3 ); idata[3] = kcxio_raspi_din( 4 ); idata[4] = kcxio_raspi_adval( 1 ); idata[5] = kcxio_raspi_adval( 2 ); idata[6] = kcxio_raspi_adval( 3 ); idata[7] = kcxio_raspi_adval( 4 ); fdata[0] = kcxio_raspi_advolt( 1 ); fdata[1] = kcxio_raspi_advolt( 2 ); fdata[2] = kcxio_raspi_advolt( 3 ); fdata[3] = kcxio_raspi_advolt( 4 ); break; default: break; } } void kcxadc_raspi_init(int range1,int range2,int range3,int range4) { kcxadc_raspi_reset(); kcxadc_raspi_rangeset(1,range1); kcxadc_raspi_rangeset(2,range2); kcxadc_raspi_rangeset(3,range3); kcxadc_raspi_rangeset(4,range4); } void kcxinit_raspi_all() { int i; raspi_gpio_init( RASPORT_Di_1, RASPORT_DIR_IN ); raspi_gpio_init( RASPORT_Di_2, RASPORT_DIR_IN ); raspi_gpio_init( RASPORT_Di_3, RASPORT_DIR_IN ); raspi_gpio_init( RASPORT_Di_4, RASPORT_DIR_IN ); raspi_gpio_init( RASPORT_Do_1, RASPORT_DIR_OUT ); raspi_gpio_init( RASPORT_Do_2, RASPORT_DIR_OUT ); raspi_gpio_init( RASPORT_Do_3, RASPORT_DIR_OUT ); raspi_gpio_init( RASPORT_Do_4, RASPORT_DIR_OUT ); raspi_gpio_init( RASPORT_Do_5, RASPORT_DIR_OUT ); raspi_gpio_init( RASPORT_Do_6, RASPORT_DIR_OUT ); raspi_gpio_init( RASPORT_AD_din, RASPORT_DIR_OUT ); raspi_gpio_init( RASPORT_AD_cs, RASPORT_DIR_OUT ); raspi_gpio_init( RASPORT_AD_sclk, RASPORT_DIR_OUT ); raspi_gpio_init( RASPORT_AD_dout, RASPORT_DIR_IN ); raspi_gpio_init( RASPORT_AD_sstrb, RASPORT_DIR_IN ); raspi_gpio_init( RASPORT_AiCMP, RASPORT_DIR_IN ); raspi_gpio_init( RASPORT_WdtPulse, RASPORT_DIR_OUT ); for(i=0;i<(6);i++){ kcxio_raspi_dout( 1 + i, 0 ); // all OFF } kcxadc_raspi_init(0,0,0,0); } main() { int ch; int di1,di2,di3,di4; float ai_advolt; int ai_adval; int idata[8]; float fdata[4]; /* Initialization */ kcxinit_raspi_all(); /* I/O Control Sample */ di1 = kcxio_raspi_din( 1 ); // Di-1ch status get di2 = kcxio_raspi_din( 2 ); // Di-2ch status get di3 = kcxio_raspi_din( 3 ); // Di-3ch status get di4 = kcxio_raspi_din( 4 ); // Di-4ch status get printf("Di: 1ch=%d 2ch=%d 3ch=%d 4ch=%d\n", di1,di2,di3,di4); usleep((useconds_t)500000); // 0.5 sec kcxio_raspi_dout( 1,1 ); // Do-1ch Tr1 On kcxio_raspi_dout( 2,1 ); // Do-2ch Tr2 On kcxio_raspi_dout( 3,1 ); // Do-3ch Tr3 On kcxio_raspi_dout( 4,1 ); // Do-4ch Tr4 On kcxio_raspi_dout( 5,1 ); // Do-5ch Relay On kcxio_raspi_dout( 6,1 ); // Do-6ch Buzzer On sleep(1); // 1 sec for(ch=1;ch<=6;ch++){ kcxio_raspi_dout( ch,0 ); // Do all OFF } for(ch=1;ch<=4;ch++){ ai_advolt = kcxio_raspi_ain ( ch ); // Ai-ch volt data ai_adval = kcxio_raspi_adval ( ch ); // Ai-ch ad-val data (0-65535) [range 0-6.144v]; printf( "Ai: %dch = %f v [adcval=%d]\n", ch,ai_advolt,ai_adval); } /* SetDataGet */ kcxio_raspi_in( 3, idata, fdata ); // Di-1,2,3,4ch Ai-1,2,3,4 data get } /* FILE_END */