firmware for the SOLID Slow Control Module for SM1
Dependencies: S_SCTRL_SMlib adc_ad9249 mbed sscm_comm AD5384 SWSPI T_adt7320
main.cpp
- Committer:
- wbeaumont
- Date:
- 2015-10-23
- Revision:
- 13:ac7235a87242
- Parent:
- 12:54b96bf7b291
File content as of revision 13:ac7235a87242:
#include "mbed.h" /* SOLID SM1 Slow Control firmware * * V 1.0? initial version release * v 1.11 version , added status field * v 1.13 corrected error in ADC register write * v 1.14 added heartbeat off / in * v 1.20 added DAC * v 1.30 added Temperature probe support * v 1.31 bug correction ,for selecting the probe the devnr has to be used * v 1.35 added version read for software modules (comm, T , ADC , DAC SWSPI) * v 1.36 added ini1 ini2 srst commands for DAC * v 1.37 new get Version class * v 1.40 added init ( dac) for all connectors (2) * v 1.50 added broadcast for DAC channels ( 1.. 32 ) * v 1.51 added set bias (digital) commands * v 1.54 added hardware DAC reset in init , added hw reset call for DAC * v 1.55 removed decode message , messages on the ADC commands * v 1.60 added set cal values fire call , error codes corrected * v 1.61 corrected BIAS channel, introduced DEIMOS32.h * v 1.65 added heartbeat on / off, added set cal level * v 1.66 implemented real temperature readout * v 1.70 implemented set_volt and get_volt commands * v 1.72 implemented setbias , get bias volt dummy * v 1.73 implemented setbias , get bias volt via Deimos32 class * v 1.74 added check for empty deimos pointer * v 1.75 added check for devnr < 1 * v 1.76 added check for devnr per device type , added connector range ( only 1 or 2 are accepted) * v 1.78 canged the place of cmd read to the end of the mail loop was at the start * v 1.79 added hv stet /get string to replace bi(ias) old commands are still working * wait only if cmd is not ready * v 1.86 corrected dac assignment in DEIMOS32 class , correced gain factor in dac AD5384 class * V 1.90 sthv returns * (C) Wim Beaumont Univeristeit Antwerpen 2014 , 2015 * */ #define VERSION "1.90" #include "SWSPI_BI.h" #include "solid_sctrl_def.h" #include "S_SCTRL_SM1_PinDef.h" #include "S_SCTRL_SM1_hwfunct.h" #include "DEIMOS32.h" #include "AD9249.h" #include "AD5384.h" #include "adt7320.h" #include "getVersion.h" #define DEBUGPF(x) printf((x)); #define MAXCMDLLENGTH 256 #include "sscm_comm.h" using namespace sscm_comm ; Serial pc(USBTX,USBRX); char cmdin[MAXCMDLLENGTH]; u8 cmdready; bool cmdstart=false; void pc_callback() { // Note: you need to actually read from the serial to clear the RX interrupt static unsigned char cnt; char c; c=pc.getc(); if( c== CMDSTART && !cmdready ) { cnt=0; cmdstart=true; cmdready=false; } if ( cmdstart) { cmdin[cnt]=c; cnt++; if (c== CMDSTOP ) { cmdready=true;} } //printf("%c:",c ); } int main() { pc.attach(pc_callback); ssc_cmd cmd; bool heartbeat=false; int i = 0; HWlines hwl ; assignports( &hwl ); setdefault(hwl ); // reuse getVesion getVersion gv( VERSION, VERSION , __TIME__, __DATE__ ); getVersion gvc; getsscmVersion gvsscm; SWSPI spi(hwl.mosi[0],hwl.miso[0],hwl.sclk[0]); // mosi, miso, sclk SWSPI spi2(hwl.mosi[1],hwl.miso[1],hwl.sclk[1]); // mosi, miso, sclk SWSPI_BI spi_adc(hwl.msio[0],hwl.direction[0],hwl.stio_mo[0] ,hwl.sclk[0]); // msio, dir , sclk SWSPI_BI spi_adc2(hwl.msio[1],hwl.direction[1],hwl.stio_mo[1],hwl.sclk[1]); // msio, dir , sclk // initalize ADC classes AD9249 adc[2][2]={AD9249( &spi_adc,hwl.csb1[0]), AD9249( &spi_adc,hwl.csb2[0]), AD9249( &spi_adc2,hwl.csb1[1]), AD9249 ( &spi_adc2,hwl.csb2[1])}; AD5384 dac[2][1]={AD5384(&spi,hwl.dac_cs[0],hwl.dac_rst[0]), AD5384(&spi2,hwl.dac_cs[1],hwl.dac_rst[1]) }; adt7320 temp[2][3]= { adt7320(&spi, hwl.t_cs[0]),adt7320(&spi, hwl.tc_cs1[0]),adt7320(&spi, hwl.tc_cs2[0]), adt7320(&spi2, hwl.t_cs[1]),adt7320(&spi2, hwl.tc_cs1[1]),adt7320(&spi2, hwl.tc_cs2[1]) }; Deimos32* deimos[2] = { 0,0}; pc.printf("\nSOLID SLOW CONTROL for SM1 version %s %s %s \n\r",VERSION,__DATE__,__TIME__ ); for (u8 cc= 1; cc < 3 ; cc++) { dac[cc-1][0].init1(); } cmdready=false; while (1) { char cmdoutstr[100]; if (cmdready) { //cmdready=false; int decresult=decode_cmd(cmdin,&cmd); //printf("decode result = %d \n\r" ,decresult); decresult=abs(decresult); if( cmd.con <1 || cmd.con > 2 ) { decresult= 0x04 +decresult; } if( decresult){ u8 errcode=(u8)decresult ; errcode = 0xE0 + errcode; cmd.status=errcode; encode_cmd ( cmdoutstr, &cmd); pc.printf( "%s", cmdoutstr); cmdready=false; continue; } u8 do8; // dataout u16 do16; int chc=0, stch=0 ,endch=0; cmd.status=1; // use it for the moment as error handling , switch ( cmd.dev) { case ADC : { cmd.status=2; //pc.printf("ADC cmd = %s \n\r",cmd.cmd); //pc.printf("check now ranges %d %d \n\r",cmd.con, cmd.devnr); if( cmd.devnr < 1 || cmd.devnr > 2 ) { cmd.status =3; } else { if (!strcmp( cmd.cmd, "spa1")) { adc[cmd.con-1][cmd.devnr-1].setPattern1(cmd.datain);cmd.dataout=cmd.datain;cmd.status=0;} if (!strcmp( cmd.cmd, "spa2")) { adc[cmd.con-1][cmd.devnr-1].setPattern2(cmd.datain);cmd.dataout=cmd.datain;cmd.status=0;} if (!strcmp( cmd.cmd, "rpa1")) { adc[cmd.con-1][cmd.devnr-1].readPattern1(do16 ); cmd.dataout=do16; cmd.status=0; } if (!strcmp( cmd.cmd, "rpa2")) { adc[cmd.con-1][cmd.devnr-1].readPattern2(do16 ); cmd.dataout=do16; cmd.status=0; } if (!strcmp( cmd.cmd, "rr08")) {adc[cmd.con-1][cmd.devnr-1].readReg8(cmd.ch,do8 ); cmd.dataout=(u16)do8; cmd.status=0; } if (!strcmp( cmd.cmd, "rr16")) {adc[cmd.con-1][cmd.devnr-1].readReg16(cmd.ch,do16 ); cmd.dataout=(u32)do16;cmd.status=0; } if (!strcmp( cmd.cmd, "sr08")) { adc[cmd.con-1][cmd.devnr-1].setReg8(cmd.ch, (u8)cmd.datain ); cmd.dataout=cmd.datain; cmd.status=0; } if (!strcmp( cmd.cmd, "sr16")) { adc[cmd.con-1][cmd.devnr-1].setReg16(cmd.ch, (u16)cmd.datain ); cmd.dataout=cmd.datain; cmd.status=0; } if (!strcmp( cmd.cmd, "ghrv")) {do16=adc[cmd.con-1][cmd.devnr-1].getHdrVersion();cmd.dataout=do16; cmd.status=0;} if (!strcmp( cmd.cmd, "gscv")) {do16=adc[cmd.con-1][cmd.devnr-1].getSrcVersion();cmd.dataout=do16; cmd.status=0;} if (!strcmp( cmd.cmd, "ini1")) { adc[cmd.con-1][cmd.devnr-1].init1();cmd.dataout=cmd.datain;cmd.status=0;} if (!strcmp( cmd.cmd, "ini2")) { adc[cmd.con-1][cmd.devnr-1].init2();cmd.dataout=cmd.datain;cmd.status=0;} } // end check dev nr. }break; case DAC :{ cmd.status=2; if( cmd.devnr != 1 ) { cmd.status =3;goto DACENDCMD; } if (!strcmp( cmd.cmd, "ini1")) { dac[cmd.con-1][cmd.devnr-1].init1();cmd.dataout=cmd.datain;cmd.status=0; goto DACENDCMD;} if (!strcmp( cmd.cmd, "ini2")) { dac[cmd.con-1][cmd.devnr-1].init2();cmd.dataout=cmd.datain;cmd.status=0; goto DACENDCMD;} if (!strcmp( cmd.cmd, "srst")) { dac[cmd.con-1][cmd.devnr-1].soft_rst();cmd.dataout=cmd.datain;cmd.status=0;goto DACENDCMD;} if (!strcmp( cmd.cmd, "hrst")) { dac[cmd.con-1][cmd.devnr-1].hw_rst();cmd.dataout=cmd.datain;cmd.status=0;goto DACENDCMD;} if (!strcmp( cmd.cmd, "gctr")) { do16=dac[cmd.con-1][cmd.devnr-1].get_ctrl();cmd.dataout=do16;cmd.status=0;goto DACENDCMD;} if (!strcmp( cmd.cmd, "ghrv")) { do16=dac[cmd.con-1][cmd.devnr-1].getHdrVersion();cmd.dataout=do16; cmd.status=0;goto DACENDCMD;} if (!strcmp( cmd.cmd, "gscv")) { do16=dac[cmd.con-1][cmd.devnr-1].getSrcVersion();cmd.dataout=do16; cmd.status=0;goto DACENDCMD;} // set output register bias channel if ((!strcmp( cmd.cmd, "sbid")) || (!strcmp( cmd.cmd, "shvd")) ) { cmd.ch=DACBIASCH;dac[cmd.con-1][cmd.devnr-1].set_dac(cmd.ch-1,cmd.datain);cmd.dataout=cmd.datain;cmd.status=0;goto DACENDCMD;} if ((!strcmp( cmd.cmd, "gbid")) || (!strcmp( cmd.cmd, "ghvd")) ) {cmd.ch=DACBIASCH;do16=dac[cmd.con-1][cmd.devnr-1].get_dac(cmd.ch-1);cmd.dataout=do16;cmd.status=0;goto DACENDCMD;} if (!strcmp( cmd.cmd, "inhv")) { if(cmd.con== 0) {cmd.status=100;goto DACENDCMD;} // can not be broadcast ;} if(cmd.con > 2) {cmd.status=101;goto DACENDCMD;} if( deimos[cmd.con-1] ) {cmd.status=102;goto DACENDCMD;} // if already init don't init again. float hvnom=u162float( cmd.dataout , cmd.datain); deimos[cmd.con-1]= new Deimos32(hvnom ,cmd.con,&dac[cmd.con-1][cmd.devnr-1]); cmd.status=0;goto DACENDCMD; } if ((!strcmp( cmd.cmd, "sbia")) || (!strcmp( cmd.cmd, "sthv")) ) { float biasvolt= u162float( cmd.dataout , cmd.datain); u8 strtcnt=0; u8 stpcnt=2; if (cmd.con ==1) stpcnt=1; if (cmd.con ==2) strtcnt=1; // else it is assumed to be 9 float retvalue=0; for ( u8 bcnt=strtcnt ; bcnt < stpcnt; bcnt++) { u16 dacvalue=0; if ( ! deimos[bcnt]) retvalue=200; else { retvalue+=-deimos[bcnt]->setHV(biasvolt,dacvalue); cmd.datain=0; cmd.dataout=dacvalue; } } cmd.status=u8(retvalue);goto DACENDCMD; } if ((!strcmp( cmd.cmd, "gbia")) || (!strcmp( cmd.cmd, "gthv")) || (!strcmp( cmd.cmd, "gthn")) ) { if ( cmd.con ==0 ) cmd.con=1; if (deimos[cmd.con-1]) { float volt; if (!strcmp( cmd.cmd, "gthn")) volt=deimos[cmd.con-1]->getHvNom(); else volt=deimos[cmd.con-1]->getHv(); float2_2u16( volt , cmd.dataout , cmd.datain); cmd.status=0; } else cmd.status=200; goto DACENDCMD; } // set CAL level values if (!strcmp( cmd.cmd, "scll")) { if( cmd.ch !=0) { stch=cmd.ch+DACCAL1CH-1; endch=cmd.ch+DACCAL1CH; } else { stch=DACCAL1CH; endch=DACCAL1CH+4;}; for (chc= stch ; chc < endch; chc++){ cmd.ch=chc; dac[cmd.con-1][cmd.devnr-1].set_dac(cmd.ch-1,cmd.datain);cmd.dataout=cmd.datain;cmd.status=0; } goto DACENDCMD; } if (!strcmp( cmd.cmd, "gcll")){ if( cmd.ch !=0) { stch=cmd.ch+DACCAL1CH-1; endch=cmd.ch+DACCAL1CH; } else { stch=DACCAL1CH; endch=DACCAL1CH+4;}; for (chc= stch ; chc < endch; chc++){ cmd.ch=chc; do16=dac[cmd.con-1][cmd.devnr-1].get_dac(cmd.ch-1);cmd.dataout=do16;cmd.status=0; } goto DACENDCMD; } // channel related commands if( cmd.ch !=0) { stch=cmd.ch-1; endch=cmd.ch; } else { stch=0; endch=31;}; if (!strcmp( cmd.cmd, "sdac")) { for (chc= stch ; chc < endch; chc++){ dac[cmd.con-1][cmd.devnr-1].set_dac(chc,cmd.datain);cmd.dataout=cmd.datain;cmd.status=0; } goto DACENDCMD; } if (!strcmp( cmd.cmd, "svlt")) { for (chc= stch ; chc < endch; chc++){ float volt= u162float( cmd.dataout , cmd.datain); dac[cmd.con-1][cmd.devnr-1].set_volt(chc,volt);cmd.status=0; } goto DACENDCMD; } // next is not very usefull for multiple channels if (!strcmp( cmd.cmd, "rdac")) { for (chc= stch ; chc < endch; chc++){ do16=dac[cmd.con-1][cmd.devnr-1].get_dac(chc);cmd.dataout=do16;cmd.status=0; } goto DACENDCMD; } if (!strcmp( cmd.cmd, "gvlt")) { for (chc= stch ; chc < endch; chc++){ float volt=dac[cmd.con-1][cmd.devnr-1].get_volt(chc); float2_2u16( volt , cmd.dataout , cmd.datain); cmd.status=0; } goto DACENDCMD; } DACENDCMD : ; }break; case TEMP : {cmd.status=2; if( cmd.devnr < 1 || cmd.devnr > 3 ) { cmd.status =3; goto TEMPENDCMD; } if (!strcmp( cmd.cmd, "rtmp")){ float temperature=temp[cmd.con-1][cmd.devnr-1].getTemperature(); float2_2u16(temperature,cmd.dataout,cmd.datain);cmd.status=0; } if (!strcmp( cmd.cmd, "rtpd")){ do16=temp[cmd.con-1][cmd.devnr-1].get_T();cmd.dataout=do16;cmd.status=0;} if (!strcmp( cmd.cmd, "gtid")){ do8=temp[cmd.con-1][cmd.devnr-1].getId();cmd.dataout=do8;cmd.status=0;} if (!strcmp( cmd.cmd, "rtcr")){ do16=temp[cmd.con-1][cmd.devnr-1].get_TcritSP();cmd.dataout=do16;cmd.status=0;} if (!strcmp( cmd.cmd, "stcr")){ temp[cmd.con-1][cmd.devnr-1].set_TcritSP(cmd.datain);cmd.dataout=cmd.datain;cmd.status=0;} if (!strcmp( cmd.cmd, "ghrv")) {do16=temp[cmd.con-1][cmd.devnr-1].getHdrVersion();cmd.dataout=do16; cmd.status=0;} if (!strcmp( cmd.cmd, "gscv")) {do16=temp[cmd.con-1][cmd.devnr-1].getSrcVersion();cmd.dataout=do16; cmd.status=0;} if (!strcmp( cmd.cmd, "gtmp")) {do16=temp[cmd.con-1][cmd.devnr-1].getSrcVersion();cmd.dataout=do16; cmd.status=0;} if (!strcmp( cmd.cmd, "ini1")) { temp[cmd.con-1][cmd.devnr-1].init1();cmd.dataout=cmd.datain;cmd.status=0;} if (!strcmp( cmd.cmd, "ini2")) { temp[cmd.con-1][cmd.devnr-1].init2();cmd.dataout=cmd.datain;cmd.status=0;} TEMPENDCMD : ; }break; case SSCM: cmd.status=2; // generate internal CAL if (!strcmp( cmd.cmd, "acal")){toggle_cal(hwl,cmd.ch );cmd.status=0;} // set calline lvl if (!strcmp( cmd.cmd, "scll")){set_cal_line(hwl,cmd.ch, cmd.datain );cmd.status=0;} // heartbeat if (!strcmp( cmd.cmd, "t_hb")) { if ( cmd.datain ==0 ) heartbeat=false; if ( cmd.datain ==1 ) heartbeat=true; if ( cmd.datain ==2) heartbeat=!heartbeat;cmd.status=0; } //get main version if (!strcmp( cmd.cmd, "gmpv")) {do16=gv.getHdrVersion();cmd.dataout=do16; cmd.status=0;} // get module serial nr if (!strcmp( cmd.cmd, "msnr")) {do8=get_serialnr(&hwl);cmd.dataout=(u16)do8; cmd.status=0;} // get version module version if (!strcmp( cmd.cmd, "gvhv")) {do16=gvc.getHdrVersion();cmd.dataout=do16; cmd.status=0;} if (!strcmp( cmd.cmd, "gvsv")) {do16=gvc.getSrcVersion();cmd.dataout=do16; cmd.status=0;} // get communication module version if (!strcmp( cmd.cmd, "gchv")) {do16=gvsscm.getHdrVersion();cmd.dataout=do16; cmd.status=0;} if (!strcmp( cmd.cmd, "gcsv")) {do16=gvsscm.getSrcVersion();cmd.dataout=do16; cmd.status=0;} // get spi module version if (!strcmp( cmd.cmd, "gshv")) {do16=spi.getHdrVersion();cmd.dataout=do16; cmd.status=0;} if (!strcmp( cmd.cmd, "gssv")) {do16=spi.getSrcVersion();cmd.dataout=do16; cmd.status=0;} // get bispi module version if (!strcmp( cmd.cmd, "gbhv")) {do16=spi_adc.getHdrVersion();cmd.dataout=do16; cmd.status=0;} if (!strcmp( cmd.cmd, "gbsv")) {do16=spi_adc.getSrcVersion();cmd.dataout=do16; cmd.status=0;} break; default : cmd.status=1; break; } // end switch encode_cmd ( cmdoutstr, &cmd); pc.printf( "%s", cmdoutstr); cmdready=false; }//end if cmdready else { if ( heartbeat) printf( "%03d>%s\n\r",(i++ % 1000),cmdin); wait(0.2); } }// end while }