00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdio.h>
00019 #include <math.h>
00020 #include "mscbemb.h"
00021 #include "cmb.h"
00022
00023 #include "Devices/adc_internal.h"
00024
00025 #include "Protocols/CMB_SPI_handler.h"
00026
00027 #ifdef _ADT7486A_
00028 #include "Devices/ADT7486A_tsensor.h"
00029 #endif
00030
00031 #ifdef _ExtEEPROM_
00032 #include "Devices/ExtEEPROM.h"
00033 #endif
00034
00035
00036
00037 char code node_name[] = "cmb";
00038 char idata svn_rev_code[] = "$Rev: 942 $";
00039
00040
00041 sbit CFG_RECOVER = P2 ^ 0;
00042 sbit CMB_CSn = P2 ^ 1;
00043 sbit CLK_SEL = P0 ^ 7;
00044 sbit V4_ENn = P2 ^ 3;
00045 sbit V4_OCn = P2 ^ 4;
00046
00047
00048
00049 unsigned char idata _n_sub_addr = 1;
00050
00051
00052 unsigned char xdata channel;
00053 unsigned long xdata tempTime=0, sstTime=0;
00054 unsigned char xdata status, channel, NodeOK=0;
00055 unsigned int xdata crate_add=0, pca_add=0;
00056
00057
00058
00059 unsigned char bdata bChange;
00060
00061 sbit bCPupdoitNOW = bChange ^ 0;
00062 sbit EEP_CTR_Flag = bChange ^ 1;
00063 sbit bMeasuredOnce = bChange ^ 2;
00064
00065
00066
00067 MSCB_INFO_VAR code vars[] = {
00068 4, UNIT_BYTE, 0, 0, 0, "SerialN", &user_data.SerialN,
00069 2, UNIT_BYTE, 0, 0, 0, "Error", &user_data.error,
00070 1, UNIT_BYTE, 0, 0, 0, "Control", &user_data.control,
00071 1, UNIT_BYTE, 0, 0, 0, "Status", &user_data.status,
00072 1, UNIT_BYTE, 0, 0, 0, "EEPage", &user_data.eepage,
00073 1, UNIT_BYTE, 0, 0, 0, "Spare", &user_data.spare,
00074
00075 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "pDI4Mon", &user_data.pDI4Mon,
00076 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT, "pDV4Mon", &user_data.pDV4Mon,
00077 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT, "pAV33Mon", &user_data.pAV33Mon,
00078 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT, "pAV25Mon", &user_data.pAV25Mon,
00079 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT, "pDV15Mon", &user_data.pDV15Mon,
00080 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT, "pDV18Mon", &user_data.pDV18Mon,
00081 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT, "pDV25Mon", &user_data.pDV25Mon,
00082 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT, "pDV33Mon", &user_data.pDV33Mon,
00083
00084 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT, "uCTemp", &user_data.uCTemp,
00085 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT, "FpgaTemp", &user_data.FPGATemp,
00086 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT, "Vrg1Temp", &user_data.Vrg1Temp,
00087 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT, "Vrg2Temp", &user_data.Vrg2Temp,
00088
00089 2, UNIT_BYTE, 0, 0, 0, "rDI4Mon", &user_data.rpDI4Mon,
00090 2, UNIT_BYTE, 0, 0, 0, "rDV4Mon", &user_data.rpDV4Mon,
00091 2, UNIT_BYTE, 0, 0, 0, "rAV33Mon", &user_data.rpAV33Mon,
00092 2, UNIT_BYTE, 0, 0, 0, "rA25VMon", &user_data.rA25VMon,
00093 2, UNIT_BYTE, 0, 0, 0, "rDV15Mon", &user_data.rpDV15Mon,
00094 2, UNIT_BYTE, 0, 0, 0, "rDV18Mon", &user_data.rpDV18Mon,
00095 2, UNIT_BYTE, 0, 0, 0, "rDV25Mon", &user_data.rpDV25Mon,
00096 2, UNIT_BYTE, 0, 0, 0, "rDV33Mon", &user_data.rpDV33Mon,
00097
00098 4, UNIT_BYTE, 0, 0,MSCBF_FLOAT|MSCBF_HIDDEN, "eepValue", &user_data.eepValue,
00099 4, UNIT_BYTE, 0, 0,MSCBF_HIDDEN, "eeCtrSet", &user_data.eeCtrSet,
00100 0
00101 };
00102
00103 MSCB_INFO_VAR *variables = vars;
00104
00105 extern SYS_INFO sys_info;
00106
00107
00108
00109
00110 void publishCtlCsr(void) {
00111 DISABLE_INTERRUPTS;
00112 user_data.control = rCTL;
00113 user_data.status = rCSR;
00114 ENABLE_INTERRUPTS;
00115 }
00116
00117
00118
00119 void publishErr(bit errbit) {
00120 DISABLE_INTERRUPTS;
00121 errbit = SET;
00122 user_data.error = rESR;
00123 ENABLE_INTERRUPTS;
00124 }
00125
00126
00127
00128 void publishAll() {
00129 user_data.control = rCTL;
00130 user_data.status = rCSR;
00131 user_data.error = rESR;
00132 ENABLE_INTERRUPTS;
00133 }
00134
00135
00136
00137 void CMB_SPI_WriteByte(unsigned char cmbinst, unsigned char cmbdata) {
00138 CMB_CSn = 0;
00139 CMBSPI_WriteByte(cmbinst);
00140 CMBSPI_WriteByte(cmbdata);
00141 CMB_CSn = 1;
00142 }
00143
00144
00145
00146 unsigned char CMB_SPI_ReadByte(unsigned char cmbinst) {
00147 unsigned char cdata;
00148 CMB_CSn = 0;
00149 CMBSPI_WriteByte(cmbinst);
00150 cdata = CMBSPI_ReadByteRising();
00151 CMB_CSn = 1;
00152 return cdata;
00153 }
00154
00155
00156
00157 void PublishVariable(float xdata * pvarDest, float varSrce, bit errbit) {
00158 DISABLE_INTERRUPTS;
00159 *pvarDest = varSrce;
00160 if (errbit) user_data.error = rESR;
00161 ENABLE_INTERRUPTS;
00162 }
00163
00164
00165
00166 unsigned int NodeAdd_get(void)
00167 {
00168
00169
00170
00171
00172
00173
00174 SFRPAGE = CONFIG_PAGE;
00175
00176 P3MDOUT = 0x00;
00177 P3=0xFF;
00178
00179 pca_add= P3;
00180 crate_add= ((~pca_add)<<3) & 0x01F8;
00181 return ( (crate_add & 0x01FC) | 0x0004);
00182 }
00183
00184
00185
00186 void switchonoff(unsigned char command)
00187 {
00188 if(command==ON)
00189 {
00190
00191 SFRPAGE = CONFIG_PAGE;
00192 P2MDOUT &= ~0x08;
00193 V4_ENn = 0;
00194
00195 rESR = 0x0000;
00196 rCSR = user_data.status;
00197 SPup = ON;
00198 SsS = OFF;
00199 SmSd = OFF;
00200
00201
00202 DISABLE_INTERRUPTS;
00203 user_data.status = rCSR;
00204 user_data.error = rESR;
00205 ENABLE_INTERRUPTS;
00206
00207
00208 P2MDOUT |= 0x20;
00209 P2MDOUT |= 0x40;
00210 P2MDOUT &= ~0x80;
00211 P2MDOUT |= 0x02;
00212 P2MDOUT |= 0x01;
00213 CMB_CSn = 1;
00214
00215 CMBSPI_Init();
00216
00217 delay_ms(1000);
00218 CMB_SPI_WriteByte(CMBSPI_WADDRESS, ~pca_add);
00219 delay_us(100);
00220 user_data.eepage = CMB_SPI_ReadByte(CMBSPI_RADDRESS);
00221 delay_us(100);
00222 CMB_SPI_WriteByte(CMBSPI_WADDRESS, ~pca_add);
00223 delay_us(100);
00224 user_data.spare = CMB_SPI_ReadByte(CMBSPI_RADDRESS);
00225
00226 } else if(command==OFF) {
00227
00228 SFRPAGE = CONFIG_PAGE;
00229 P2MDOUT = 0;
00230 V4_ENn = 1;
00231 }
00232 }
00233
00234
00235
00236 float read_voltage(unsigned char channel,unsigned int *rvalue, unsigned char gain)
00237 {
00238 unsigned int xdata i;
00239 float xdata voltage;
00240 unsigned int xdata rawbin;
00241 unsigned long xdata rawsum = 0;
00242
00243
00244 for (i=0 ; i<10 ; i++) {
00245 rawbin = adc_read(channel, gain);
00246 rawsum += rawbin;
00247 yield();
00248 }
00249
00250
00251 *rvalue = rawsum / 10;
00252 voltage = (float) *rvalue;
00253 voltage = (float) voltage / 1024.0 * VREF;
00254 if ( channel != TCHANNEL)
00255 voltage = voltage * coeff[channel] + offset[channel];
00256
00257 return voltage;
00258 }
00259
00260
00261
00262
00263
00264 void user_init(unsigned char init)
00265 {
00266 char xdata i;
00267
00268
00269 for (i=0;i<4;i++) {
00270 if (svn_rev_code[6+i] < 48) {
00271 svn_rev_code[6+i] = '0';
00272 }
00273 }
00274 sys_info.svn_revision = (svn_rev_code[6]-'0')*1000+
00275 (svn_rev_code[7]-'0')*100+
00276 (svn_rev_code[8]-'0')*10+
00277 (svn_rev_code[9]-'0');
00278
00279 i = cur_sub_addr();
00280
00281 if (init){
00282 user_data.FPGATemp = 0;
00283 user_data.Vrg1Temp = 0;
00284 user_data.Vrg2Temp = 0;
00285 user_data.error = 0;
00286 user_data.SerialN = 0x0;
00287 sys_info.node_addr = cur_sub_addr();
00288 }
00289
00290 user_data.control = 0;
00291 user_data.status = 0;
00292 user_data.error = 0;
00293 user_data.spare = 0;
00294 user_data.eepage = 0;
00295
00296
00297 rCTL = user_data.control;
00298 rCSR = user_data.status;
00299
00300
00301
00302 sys_info.group_addr = 400;
00303
00304 bMeasuredOnce = 0;
00305
00306
00307
00308 SFRPAGE = CONFIG_PAGE;
00309 P0MDOUT |= 0x20;
00310
00311
00312
00313 SFRPAGE = CONFIG_PAGE;
00314
00315 adc_internal_init();
00316
00317 #ifdef _ADT7486A_
00318
00319
00320 SFRPAGE = CONFIG_PAGE;
00321 P1MDOUT |= 0x01;
00322 SFRPAGE = CPT1_PAGE;
00323 CPT1CN |= 0x80;
00324 CPT1MD = 0x03;
00325
00326
00327 ADT7486A_Init(SST_LINE1);
00328 #endif
00329
00330 #ifdef _ExtEEPROM_
00331
00332
00333
00334 SFRPAGE = CONFIG_PAGE;
00335 P1MDOUT |= 0x80;
00336 P1MDOUT |= 0x06;
00337 P1MDOUT &= ~0x20;
00338 ExtEEPROM_Init();
00339
00340
00341 ExtEEPROM_Read(SERIALN_ADD,(unsigned char xdata *)&eepage.SerialN, SERIALN_LENGTH);
00342 user_data.SerialN = eepage.SerialN;
00343
00344
00345 ExtEEPROM_Read(PageAddr[0], (unsigned char xdata *)&eepage, PAGE_SIZE);
00346 #endif
00347
00348
00349 sys_info.node_addr = NodeAdd_get();
00350
00351
00352
00353 SFRPAGE = CONFIG_PAGE;
00354 P0MDOUT &= ~0x80;
00355 CLK_SEL = SXclk = ON;
00356
00357
00358
00359 SFRPAGE = CONFIG_PAGE;
00360 P2MDOUT &= ~0x10;
00361
00362
00363
00364 P2MDOUT |= 0x01;
00365
00366
00367
00368 switchonoff(OFF);
00369
00370 SmSd = OFF;
00371 SPup = OFF;
00372
00373 CmSd = CLEAR;
00374 Cdeb1 = CLEAR;
00375
00376
00377 DISABLE_INTERRUPTS;
00378 user_data.control = rCTL;
00379 user_data.status = rCSR;
00380 ENABLE_INTERRUPTS;
00381 }
00382
00383
00384 #pragma NOAREGS
00385
00386 void user_write(unsigned char index) reentrant
00387 {
00388 rCSR = user_data.status;
00389 if (index == IDXCTL) {
00390 rCTL = user_data.control;
00391 }
00392
00393
00394
00395 if (index == IDXEEP_CTL) EEP_CTR_Flag = 1;
00396 }
00397
00398
00399 unsigned char user_read(unsigned char index)
00400 {
00401 if (index);
00402 return 0;
00403 }
00404
00405
00406 unsigned char user_func(unsigned char *data_in, unsigned char *data_out)
00407 {
00408
00409 data_out[0] = data_in[0];
00410 data_out[1] = data_in[1];
00411 return 2;
00412 }
00413
00414
00415 void user_loop(void) {
00416
00417 float xdata volt, temperature, *pfData;
00418 float* xdata eep_address;
00419 unsigned int xdata eeptemp_addr;
00420 unsigned char xdata *eeptemp_source;
00421 unsigned char xdata eep_request, fpgaStatus, AsumLock;
00422 static unsigned char xdata eeprom_flag = CLEAR;
00423 unsigned int *xdata rpfData;
00424 unsigned int xdata i, rvolt;
00425
00426
00427
00428 if (!NodeOK && uptime()) {
00429 sys_info.node_addr = NodeAdd_get();
00430 NodeOK = 1;
00431 }
00432
00433
00434
00435 if (CPup) {
00436 switchonoff(ON);
00437 delay_ms(100);
00438
00439 bCPupdoitNOW = ON;
00440
00441 CPup = CLEAR;
00442
00443 rESR = 0x0000;
00444
00445 }
00446
00447
00448
00449 if (CmSd) {
00450 rCSR = user_data.status;
00451 SmSd = ON;
00452 switchonoff(OFF);
00453 SPup = OFF;
00454
00455 CmSd = CLEAR;
00456
00457 publishCtlCsr();
00458 }
00459
00460
00461
00462 if (CXclk) {
00463 rCSR = user_data.status;
00464 if (SXclk) CLK_SEL = SXclk = 0;
00465 else CLK_SEL = SXclk = 1;
00466 CXclk = 0;
00467 publishCtlCsr();
00468 }
00469
00470
00471
00472 if (Ccfg) {
00473 for (i=0;i<4;i++) {
00474 CFG_RECOVER = 1;
00475 delay_us(1);
00476 CFG_RECOVER = 0;
00477 delay_us(1);
00478 }
00479 delay_us(10);
00480 Ccfg = 0;
00481 }
00482
00483
00484
00485 if (Cdeb1) {
00486
00487
00488 CMB_SPI_WriteByte(CMBSPI_WADDRESS, ~pca_add);
00489
00490 delay_us(105);
00491
00492
00493 user_data.spare = CMB_SPI_ReadByte(CMBSPI_RADDRESS);
00494 Cdeb1 = 0;
00495 }
00496
00497 #ifdef _ExtEEPROM_
00498
00499
00500 if (EEP_CTR_Flag) {
00501
00502 if (user_data.eeCtrSet & EEP_CTRL_KEY) {
00503
00504 if( (int)(user_data.eeCtrSet & 0x000000ff) >= EEP_RW_IDX) {
00505
00506 eep_address = (float*)&eepage + (user_data.eeCtrSet & 0x000000ff);
00507
00508 if (user_data.eeCtrSet & EEP_CTRL_WRITE){
00509 *eep_address = user_data.eepValue;
00510
00511 } else if (user_data.eeCtrSet & EEP_CTRL_READ) {
00512 DISABLE_INTERRUPTS;
00513 user_data.eepValue = *eep_address;
00514 ENABLE_INTERRUPTS;
00515 } else {
00516
00517 DISABLE_INTERRUPTS;
00518 user_data.eeCtrSet = EEP_CTRL_INVAL_REQ;
00519 ENABLE_INTERRUPTS;
00520 }
00521 } else {
00522 DISABLE_INTERRUPTS;
00523 user_data.eeCtrSet = EEP_CTRL_OFF_RANGE;
00524 ENABLE_INTERRUPTS;
00525 }
00526 } else {
00527
00528 DISABLE_INTERRUPTS;
00529 user_data.eeCtrSet = EEP_CTRL_INVAL_KEY;
00530 ENABLE_INTERRUPTS;
00531 }
00532 EEP_CTR_Flag = CLEAR;
00533 }
00534
00535
00536
00537 if (CeeS) {
00538
00539 if (!eeprom_flag) {
00540 rCSR = user_data.status;
00541
00542
00543 eeptemp_addr = PageAddr[(unsigned char)(user_data.eepage & 0x07)];
00544
00545 eeptemp_source = (unsigned char xdata *)&eepage;
00546 }
00547
00548
00549 if (CeeClr) eep_request = CLEAR_EEPROM;
00550 else eep_request = WRITE_EEPROM;
00551
00552 status = ExtEEPROM_Write_Clear (eeptemp_addr
00553 , &eeptemp_source
00554 , PAGE_SIZE
00555 , eep_request
00556 , &eeprom_flag);
00557
00558 if (status == DONE) {
00559 SeeS = DONE;
00560 eeprom_flag = CLEAR;
00561
00562 user_data.eepage |= ((user_data.eepage & 0x07) << 5);
00563 } else {
00564 SeeS = FAILED;
00565 }
00566
00567 CeeS = CLEAR;
00568
00569 publishCtlCsr();
00570 }
00571
00572
00573
00574 if (CeeR) {
00575 rCSR = user_data.status;
00576
00577
00578 status = ExtEEPROM_Read (PageAddr[(unsigned char)(user_data.eepage & 0x07)]
00579 , (unsigned char xdata *)&eepage, PAGE_SIZE);
00580
00581 if (status == DONE) SeeR = DONE;
00582 else SeeR = FAILED;
00583
00584 CeeR = CLEAR;
00585 publishCtlCsr();
00586 }
00587 #endif
00588
00589
00590
00591 if (bCPupdoitNOW || ((uptime() - tempTime) > TEMP_TIME)) {
00592 pfData = &(user_data.pDI4Mon);
00593 rpfData = &(user_data.rpDI4Mon);
00594 for (channel=0; channel<INTERNAL_N_CHN ; channel++) {
00595 volt = read_voltage(channel,&rvolt, IGAIN1);
00596 DISABLE_INTERRUPTS;
00597 pfData[channel] = volt;
00598 rpfData[channel]= rvolt;
00599 ENABLE_INTERRUPTS;
00600 }
00601
00602
00603
00604 volt = read_voltage(TCHANNEL,&rvolt, IGAIN1);
00605
00606 temperature = 1000 * (volt - 0.776) / 2.86;
00607
00608 temperature = ((int) (temperature * 10 + 0.5)) / 10.0;
00609 if ((temperature < eepage.luCTlimit) || (temperature > eepage.uuCTlimit)) uCT = ON;
00610 PublishVariable(&(user_data.uCTemp), temperature, uCT);
00611
00612
00613 tempTime = uptime();
00614 bMeasuredOnce = 1;
00615 }
00616
00617 yield();
00618
00619
00620
00621 #ifdef _ADT7486A_
00622 if (bCPupdoitNOW || ((uptime() - sstTime) > SST_TIME)) {
00623
00624 if(!ADT7486A_Cmd(ADT7486A_address, GetIntTemp, SST_LINE1, &temperature)) {
00625 if ((temperature < eepage.lSSTlimit) || (temperature > eepage.uSSTlimit)) Vreg1ssTT = ON;
00626 PublishVariable(&user_data.Vrg1Temp, temperature, Vreg1ssTT);
00627 } else publishErr(RdssT);
00628
00629
00630
00631 if(!ADT7486A_Cmd(ADT7486A_address, GetExt1Temp, SST_LINE1, &temperature)) {
00632 if ((temperature < eepage.lSSTlimit) || (temperature > eepage.uSSTlimit)) Vreg2ssTT = ON;
00633 PublishVariable(&user_data.Vrg2Temp, temperature, Vreg2ssTT);
00634 } else publishErr(RdssT);
00635
00636
00637
00638 if(!ADT7486A_Cmd(ADT7486A_address, GetExt2Temp, SST_LINE1, &temperature)) {
00639 if ((temperature < eepage.luCTlimit) || (temperature > eepage.uuCTlimit)) FPGAssTT = ON;
00640 PublishVariable(&user_data.FPGATemp, temperature, FPGAssTT);
00641 } else publishErr(RdssT);
00642
00643
00644 sstTime = uptime();
00645 }
00646 #endif
00647
00648
00649
00650 if (bMeasuredOnce) {
00651 pfData = &(user_data.pDI4Mon);
00652 for (channel=0; channel<INTERNAL_N_CHN ; channel++) {
00653 if ((pfData[channel] < eepage.lVIlimit[channel])
00654 || (pfData[channel] > eepage.uVIlimit[channel])) {
00655 rESR |= (1<<channel);
00656 }
00657 }
00658 }
00659
00660
00661 fpgaStatus = CMB_SPI_ReadByte(CMBSPI_RSTATUS);
00662
00663 SLinkOn = (fpgaStatus & 0x01) ? 0 : 1;
00664
00665 AsumLock = ((fpgaStatus>>4) == 0) ? 1 : 0;
00666
00667
00668 V4_OC = (V4_OCn == 0) ? 1 : 0;
00669
00670
00671
00672 DISABLE_INTERRUPTS;
00673 user_data.error = rESR;
00674 ENABLE_INTERRUPTS;
00675
00676
00677
00678 if (SPup && (rESR & ( UFTEMPERATURE_MASK | BTEMPERATURE_MASK))) {
00679 switchonoff(OFF);
00680 SPup = OFF;
00681 SsS = ON;
00682 } else if (bCPupdoitNOW) {
00683 bCPupdoitNOW = OFF;
00684 SsS = SmSd = OFF;
00685 SPup = ON;
00686 }
00687
00688
00689 publishAll();
00690 }