25 #define BPS_TIMEOUT_MS 2000
33 #define BPS_MAX_RET_LEN 80
34 #define BPS_MAX_CMD_LEN 80
36 static unsigned char _BpsCmdBuf[BPS_MAX_CMD_LEN];
37 static unsigned char _retBpsCmdBuf[BPS_MAX_RET_LEN];
44 #define _BPS_USHORT_SIZE 4
45 #define _BPS_UCHAR_SIZE 2
49 #define _BPSCMD_ReadSensors_Request 0x03
50 #define _BPSCMD_ReadSensors_Answer 0x04
51 #define _BPSCMD_ReleToggle_BackBone_Request 0x05
52 #define _BPSCMD_ReleToggle_BackBone_Answer 0x06
53 #define _BPSCMD_ReleToggle_12Vdc_Request 0x0B
54 #define _BPSCMD_ReleToggle_12Vdc_Answer 0x0C
55 #define _BPSCMD_PingDevice_Request 0x2F
56 #define _BPSCMD_PingDevice_Answer 0x30
57 #define _BPSCMD_Alarm_Enable_Save_Request 0x25
58 #define _BPSCMD_Alarm_Enable_Save_Answer 0x26
59 #define _BPSCMD_Alarm_Enable_Load_Request 0x27
60 #define _BPSCMD_Alarm_Enable_Load_Answer 0x28
61 #define _BPSCMD_Alarm_ClearStatus_Request 0x29
62 #define _BPSCMD_Alarm_ClearStatus_Answer 0x2A
63 #define _BPSCMD_Alarm_Threshold_Save_Request 0x2B
64 #define _BPSCMD_Alarm_Threshold_Save_Answer 0x2C
65 #define _BPSCMD_Alarm_Threshold_Load_Request 0x2D
66 #define _BPSCMD_Alarm_Threshold_Load_Answer 0x2E
69 #define _BPSCMD_Error_Chk 0x02
70 #define _BPSCMD_Error_Start 0x04
71 #define _BPSCMD_Error_Timeout 0x08
98 #define SIZE_THRESHOLD (NTHRESHOLD * _BPS_USHORT_SIZE)
106 static const BpsCmd BSP_CMD_INIT = {BPS_ADDR,0x0,0x0,0x0};
108 static const CnvParams _hex = CNV_DEFAULT_HEX;
170 bool _bpsIn(
char *c );
171 void _bpsOut(
char c);
172 unsigned char bpschecksum(
unsigned char* buff,
int num);
173 unsigned char s_bpschecksum(
BpsAnsw* answ);
174 void _bpsCmdTx (
int nBytes);
175 bool _bpsRxCommand(
BpsAnsw* answ);
176 int _bpsBufferCmd(
BpsCmd* _cmd);
177 bool _bpsCmdRxCheck(uint8_t answ,
BpsAnsw* s_answ);
178 bool _bpsTxAndRx(
BpsCmd *pcmd,
BpsAnsw* pansw, uint8_t cansw);
185 bool _bpsIn(
char *c )
188 if(
bfEmpty(BPS_UART->rxfifo))
return false;
191 bfRead(BPS_UART->rxfifo,(uint8_t*) c);
194 printf(
"rx -> 0x%x (%d)\n",*c,*c);
208 printf(
"tx -> 0x%x (%d)\n",c,c);
215 unsigned char bpschecksum(
unsigned char* buff,
int num)
227 unsigned char chk = 256;
238 unsigned char s_bpschecksum(
BpsAnsw* answ)
244 chk = bpschecksum(answ->pData, answ->nData);
246 chk -= answ->hf.addr ;
247 chk -= answ->hf.cmd ;
254 void _bpsCmdTx (
int nBytes)
257 assert(nBytes < BPS_MAX_CMD_LEN);
267 _bpsOut(_BpsCmdBuf[i]);
271 _bpsOut(bpschecksum(_BpsCmdBuf,nBytes));
283 bool _bpsRxCommand(
BpsAnsw* answ)
287 assert(answ->nData +
sizeof(
BpsAnswFix) < BPS_MAX_RET_LEN);
292 bool isFrame =
false;
295 while(i< (answ->nData +
sizeof(
BpsAnswFix) )){
302 if(c == _BPS_SOF || isFrame){
303 _retBpsCmdBuf[i] = (
unsigned char) c;
314 _retBpsCmdBuf[0] = _BPS_SOF;
315 _retBpsCmdBuf[1] = _BpsCmdBuf[0];
318 if(_BpsCmdBuf[1] == _BPSCMD_ReadSensors_Request){
319 _retBpsCmdBuf[2] = _BPSCMD_ReadSensors_Answer;
320 _retBpsCmdBuf[3] =
'1';
321 _retBpsCmdBuf[4] =
'2';
322 _retBpsCmdBuf[5] =
'3';
323 _retBpsCmdBuf[6] =
'4';
324 _retBpsCmdBuf[7] =
'5';
325 _retBpsCmdBuf[8] =
'6';
326 _retBpsCmdBuf[9] =
'7';
327 _retBpsCmdBuf[10] =
'8';
328 _retBpsCmdBuf[11] =
'9';
329 _retBpsCmdBuf[12] =
'a';
330 _retBpsCmdBuf[13] =
'b';
331 _retBpsCmdBuf[14] =
'c';
332 _retBpsCmdBuf[15] =
'd';
333 _retBpsCmdBuf[16] =
'e';
334 _retBpsCmdBuf[17] =
'f';
335 _retBpsCmdBuf[18] =
'0';
336 _retBpsCmdBuf[19] =
'1';
337 _retBpsCmdBuf[20] =
'2';
338 _retBpsCmdBuf[21] =
'3';
339 _retBpsCmdBuf[22] =
'4';
340 _retBpsCmdBuf[23] =
'5';
341 _retBpsCmdBuf[24] =
'6';
342 _retBpsCmdBuf[25] =
'7';
343 _retBpsCmdBuf[26] =
'8';
344 _retBpsCmdBuf[27] =
'9';
345 _retBpsCmdBuf[28] =
'a';
346 _retBpsCmdBuf[29] =
'b';
347 _retBpsCmdBuf[30] =
'c';
348 _retBpsCmdBuf[31] =
'd';
349 _retBpsCmdBuf[32] =
'e';
350 _retBpsCmdBuf[33] =
'f';
351 _retBpsCmdBuf[34] =
'0';
352 _retBpsCmdBuf[35] = bpschecksum(_retBpsCmdBuf+1,34);
353 _retBpsCmdBuf[36] = _BPS_EOF;
356 else if(_BpsCmdBuf[1] == _BPSCMD_Alarm_Enable_Load_Request){
357 _retBpsCmdBuf[2] = _BPSCMD_Alarm_Enable_Load_Answer;
358 _retBpsCmdBuf[3] =
'1';
359 _retBpsCmdBuf[4] =
'2';
360 _retBpsCmdBuf[5] =
'3';
361 _retBpsCmdBuf[6] =
'4';
362 _retBpsCmdBuf[7] = bpschecksum(_retBpsCmdBuf+1,6);
363 _retBpsCmdBuf[8] = _BPS_EOF;
365 else if(_BpsCmdBuf[1] == _BPSCMD_Alarm_Enable_Save_Request){
366 _retBpsCmdBuf[2] = _BPSCMD_Alarm_Enable_Save_Answer;
367 _retBpsCmdBuf[3] = _BpsCmdBuf[2];
368 _retBpsCmdBuf[4] = _BpsCmdBuf[3];
369 _retBpsCmdBuf[5] = _BpsCmdBuf[4];
370 _retBpsCmdBuf[6] = _BpsCmdBuf[5];
371 _retBpsCmdBuf[7] = bpschecksum(_retBpsCmdBuf+1,6);
372 _retBpsCmdBuf[8] = _BPS_EOF;
374 else if(_BpsCmdBuf[1] == _BPSCMD_Alarm_ClearStatus_Request){
375 _retBpsCmdBuf[2] = _BPSCMD_Alarm_ClearStatus_Answer;
376 _retBpsCmdBuf[3] =
'1';
377 _retBpsCmdBuf[4] =
'2';
378 _retBpsCmdBuf[5] =
'3';
379 _retBpsCmdBuf[6] =
'4';
380 _retBpsCmdBuf[7] = bpschecksum(_retBpsCmdBuf+1,6);
381 _retBpsCmdBuf[8] = _BPS_EOF;
383 else if(_BpsCmdBuf[1] == _BPSCMD_Alarm_Threshold_Load_Request){
384 _retBpsCmdBuf[2] = _BPSCMD_Alarm_Threshold_Load_Answer;
385 _retBpsCmdBuf[3] =
'1';
386 _retBpsCmdBuf[4] =
'2';
387 _retBpsCmdBuf[5] =
'3';
388 _retBpsCmdBuf[6] =
'4';
389 _retBpsCmdBuf[7] =
'1';
390 _retBpsCmdBuf[8] =
'2';
391 _retBpsCmdBuf[9] =
'3';
392 _retBpsCmdBuf[10] =
'4';
393 _retBpsCmdBuf[11] = bpschecksum(_retBpsCmdBuf+1,10);
394 _retBpsCmdBuf[12] = _BPS_EOF;
396 else if(_BpsCmdBuf[1] == _BPSCMD_Alarm_Threshold_Save_Request){
397 _retBpsCmdBuf[2] = _BPSCMD_Alarm_Threshold_Save_Answer;
398 _retBpsCmdBuf[3] = _BpsCmdBuf[2];
399 _retBpsCmdBuf[4] = _BpsCmdBuf[3];
400 _retBpsCmdBuf[5] = _BpsCmdBuf[4];
401 _retBpsCmdBuf[6] = _BpsCmdBuf[5];
402 _retBpsCmdBuf[7] = _BpsCmdBuf[6];
403 _retBpsCmdBuf[8] = _BpsCmdBuf[7];
404 _retBpsCmdBuf[9] = _BpsCmdBuf[8];
405 _retBpsCmdBuf[10] = _BpsCmdBuf[9];
406 _retBpsCmdBuf[11] = bpschecksum(_retBpsCmdBuf+1,10);
407 _retBpsCmdBuf[12] = _BPS_EOF;
409 else if(_BpsCmdBuf[1] == _BPSCMD_ReleToggle_Ixx_Request){
410 _retBpsCmdBuf[2] = _BPSCMD_ReleToggle_Ixx_Answer;
411 _retBpsCmdBuf[3] = 0x31;
412 _retBpsCmdBuf[4] = 0x30;
413 _retBpsCmdBuf[5] = 0x30;
414 _retBpsCmdBuf[6] = 0x30;
415 _retBpsCmdBuf[7] = bpschecksum(_retBpsCmdBuf+1,6);
416 _retBpsCmdBuf[8] = _BPS_EOF;
418 else if(_BpsCmdBuf[1] == _BPSCMD_PingDevice_Request){
419 _retBpsCmdBuf[2] = _BPSCMD_PingDevice_Answer;
420 _retBpsCmdBuf[3] =
'1';
421 _retBpsCmdBuf[4] =
'2';
422 _retBpsCmdBuf[5] =
'3';
423 _retBpsCmdBuf[6] =
'4';
424 _retBpsCmdBuf[7] = bpschecksum(_retBpsCmdBuf+1,6);
425 _retBpsCmdBuf[8] = _BPS_EOF;
434 answ->hf.sof = _retBpsCmdBuf[0];
435 answ->hf.addr = _retBpsCmdBuf[1];
436 answ->hf.cmd = _retBpsCmdBuf[2];
437 answ->pData = &_retBpsCmdBuf[3];
438 answ->hf.chk = _retBpsCmdBuf[3+answ->nData];
439 answ->hf.eof = _retBpsCmdBuf[4+answ->nData];
447 int _bpsBufferCmd(
BpsCmd* _cmd)
449 assert(_cmd->nData + 2 < BPS_MAX_CMD_LEN);
450 _BpsCmdBuf[0] = _cmd->addr;
451 _BpsCmdBuf[1] = _cmd->cmd;
452 if(_cmd->nData && _cmd->pData)memcpy ( _BpsCmdBuf+2, _cmd->pData, _cmd->nData );
453 return (_cmd->nData + 2);
458 bool _bpsCmdRxCheck(uint8_t answ,
BpsAnsw* s_answ)
462 if(s_answ->hf.sof != _BPS_SOF){
467 if(s_bpschecksum(s_answ) != s_answ->hf.chk ){
472 if(s_answ->hf.eof != _BPS_EOF){
478 if(BPS_ADDR != s_answ->hf.addr){
482 if(s_answ->hf.cmd == answ)
return true;
484 switch(s_answ->hf.cmd){
485 case _BPSCMD_Error_Chk:
488 case _BPSCMD_Error_Start:
491 case _BPSCMD_Error_Timeout:
504 _bpsCmdTx (_bpsBufferCmd(pcmd));
505 if(_bpsRxCommand(pansw))
return _bpsCmdRxCheck(cansw,pansw);
510 uint16_t _bpsHexAscii2Short(uint8_t* input)
513 char crev[_BPS_USHORT_SIZE];
516 for(j=0;j<_BPS_USHORT_SIZE;j++){
517 crev[j]=input[_BPS_USHORT_SIZE-1-j];
523 if (
cnvParseU(crev, &lb, _hex) == 0)
return 0x0;
525 return (uint16_t) (lb & 0xFFFF);
528 uint8_t _bpsHexAscii2Char(uint8_t* input)
531 char crev[_BPS_UCHAR_SIZE];
534 for(j=0;j<_BPS_UCHAR_SIZE;j++){
535 crev[j]=input[_BPS_UCHAR_SIZE-1-j];
541 if (
cnvParseU(crev, &lb, _hex) == 0)
return 0x0;
543 return (uint8_t) (lb & 0xFFFF);
546 void _bpsShort2HexAscii(uint16_t sdata, uint8_t* input)
549 char outstring[2*_BPS_USHORT_SIZE];
554 if(
cnvFormatU( (int32_t) sdata, outstring,_hex) == 0)
return;
557 while(outstring[j] !=
'\0' && j<2*_BPS_USHORT_SIZE)
564 for(k=0;k<_BPS_USHORT_SIZE;k++){
565 if(j-1-k >= 0)input[k]=outstring[j-1-k];
579 #define STATUS_NDATA (sizeof(BpsRdSensAnsw) / sizeof(uint16_t))
580 #define STATUS_SIZE (_BPS_USHORT_SIZE * STATUS_NDATA)
583 BpsCmd cmd = BSP_CMD_INIT;
584 cmd.cmd = _BPSCMD_ReadSensors_Request;
586 uint16_t pRet[STATUS_NDATA];
591 ans.nData = STATUS_SIZE;
593 if(!_bpsTxAndRx(&cmd,&ans, _BPSCMD_ReadSensors_Answer))
return false;
595 for(i=0;i<STATUS_NDATA;i++){
597 pRet[i] = _bpsHexAscii2Short(ans.pData+i*_BPS_USHORT_SIZE);
600 stat->mon_i = pRet[0];
601 stat->mon1_i12 = pRet[1];
602 stat->mon2_v375 = pRet[2];
603 stat->spare = pRet[3];
604 stat->mon3_i375 = pRet[4];
605 stat->mon4_v375 = pRet[5];
606 stat->breaker = pRet[6];
607 stat->alarm = pRet[7];
618 BpsCmd cmd = BSP_CMD_INIT;
619 cmd.cmd = _BPSCMD_Alarm_Enable_Load_Request;
621 ans.nData = _BPS_USHORT_SIZE;
623 if(!_bpsTxAndRx(&cmd,&ans, _BPSCMD_Alarm_Enable_Load_Answer))
return false;
625 *alarms = _bpsHexAscii2Short(ans.pData);
633 uint8_t sData[_BPS_USHORT_SIZE];
635 BpsCmd cmd = BSP_CMD_INIT;
636 cmd.cmd = _BPSCMD_Alarm_Enable_Save_Request;
637 cmd.nData = _BPS_USHORT_SIZE;
640 ans.nData = _BPS_USHORT_SIZE;
642 _bpsShort2HexAscii(newal,sData);
644 if(!_bpsTxAndRx(&cmd,&ans, _BPSCMD_Alarm_Enable_Save_Answer))
return false;
648 *alarms = _bpsHexAscii2Short(ans.pData);
657 BpsCmd cmd = BSP_CMD_INIT;
658 cmd.cmd = _BPSCMD_Alarm_ClearStatus_Request;
660 ans.nData = _BPS_USHORT_SIZE;
662 if(!_bpsTxAndRx(&cmd,&ans, _BPSCMD_Alarm_ClearStatus_Answer))
return false;
664 *alarms = _bpsHexAscii2Short(ans.pData);
676 BpsCmd cmd = BSP_CMD_INIT;
677 cmd.cmd = _BPSCMD_Alarm_Threshold_Load_Request;
680 uint16_t rawth[NTHRESHOLD];
683 ans.nData = SIZE_THRESHOLD;
685 if(!_bpsTxAndRx(&cmd,&ans, _BPSCMD_Alarm_Threshold_Load_Answer))
return false;
687 for(i=0;i<NTHRESHOLD;i++){
689 rawth[i] = _bpsHexAscii2Short(ans.pData+i*_BPS_USHORT_SIZE);
692 th->thr_mon_375i0 = rawth[0] ;
693 th->thr_mon_12v = rawth[1];
703 uint8_t sData[SIZE_THRESHOLD];
705 uint16_t rawth[NTHRESHOLD];
707 BpsCmd cmd = BSP_CMD_INIT;
708 cmd.cmd = _BPSCMD_Alarm_Threshold_Save_Request;
709 cmd.nData = SIZE_THRESHOLD;
712 ans.nData = SIZE_THRESHOLD;
714 rawth[0] = newth->thr_mon_375i0;
715 rawth[1] = newth->thr_mon_12v;
718 for(i=0;i<NTHRESHOLD;i++){
719 _bpsShort2HexAscii(rawth[i],sData+i*_BPS_USHORT_SIZE);
722 if(!_bpsTxAndRx(&cmd,&ans, _BPSCMD_Alarm_Threshold_Save_Answer))
return false;
726 for(i=0;i<NTHRESHOLD;i++){
728 rawth[i] = _bpsHexAscii2Short(ans.pData+i*_BPS_USHORT_SIZE);
731 th->thr_mon_375i0 = rawth[0] ;
732 th->thr_mon_12v = rawth[1];
741 BpsCmd cmd = BSP_CMD_INIT;
742 cmd.cmd = _BPSCMD_ReleToggle_BackBone_Request;
744 ans.nData = _BPS_USHORT_SIZE;
746 if(!_bpsTxAndRx(&cmd,&ans, _BPSCMD_ReleToggle_BackBone_Answer))
return false;
749 *breakers = _bpsHexAscii2Short(ans.pData);
753 bool bpsRelayToggle12V(uint16_t *breakers){
757 BpsCmd cmd = BSP_CMD_INIT;
758 cmd.cmd = _BPSCMD_ReleToggle_12Vdc_Request;
760 ans.nData = _BPS_USHORT_SIZE;
762 if(!_bpsTxAndRx(&cmd,&ans, _BPSCMD_ReleToggle_12Vdc_Answer))
return false;
765 *breakers = _bpsHexAscii2Short(ans.pData);
774 BpsCmd cmd = BSP_CMD_INIT;
775 cmd.cmd = _BPSCMD_PingDevice_Request;
777 ans.nData =
sizeof(uint8_t);
779 if(!_bpsTxAndRx(&cmd,&ans, _BPSCMD_PingDevice_Answer))
return false;
782 *fw = (uint16_t) (ans.pData[0] & 0xFF);
789 uint8_t rplCode, uint8_t ** rplPData, uint8_t rplNData)
791 BpsCmd cmd = BSP_CMD_INIT ;
794 cmd.pData = cmdPData;
795 cmd.nData = cmdNData;
796 ans.nData = rplNData;
798 if (!_bpsTxAndRx(&cmd, &ans, rplCode))
return false;
800 *rplPData = ans.pData;
int cnvFormatU(int32_t input, char *output, CnvParams params)
Formats an unsigned integer into a character buffer.
static bool bfEmpty(ByteFifo *const bf)
Returns whether or not the byte-fifo is empty.
bool bpsDbgCmdReply(uint8_t cmdCode, uint8_t *cmdPData, uint8_t cmdNData, uint8_t rplCode, uint8_t **rplPData, uint8_t rplNData)
Exposes the low-level interface to the BPS.
bool bpsRelayToggleBackBone(uint16_t *breakers)
Toggle relay status.
static void __irqEnable()
Enabled IRQ's on a global level.
int cnvParseU(const char *input, uint32_t *output, CnvParams params)
Parse an unsigned integer.
bool bpsAlarmClearStat(uint16_t *alarms)
Clear Status Alarm.
bool bpsAlarmThLoad(BspTh *th)
load already saved alarm threshold (in mA)
static void __irqDisable()
Disables IRQ's on a global level.
bool bpsPingDevice(uint16_t *fw)
Ping Device.
bool bpsAlarmThSave(BspTh *newth, BspTh *th)
save alarm threshold (in mA)
#define E_BPS_TIMEOUT
Receive timeout.
static uint32_t timeOutInit(uint32_t msec)
Initializes a timeout with the specified no of msecs.
static bool timeOut(uint32_t to)
Checks whether or not the timeout has expired.
Manages the global system error.
This structure provides information about formatting and parsing.
bool bpsReadSensor(BpsRdSensAnsw *stat)
return sensor values
#define E_BPS_NOSOF
no EOF received when expected
#define E_BPS_CHKERR
bad checksum received
bool bfRead(ByteFifo *const bf, uint8_t *const b)
Reads a byte from the byte-fifo.
#define E_BPS_NOEOF
no EOF received when expected
bool errSet(uint32_t code, const char *error, const char *name)
Sets an error.
#define ERROR(CODE,...)
Expands an error code to an error code with a description (if ERROR_W_DESCR is declared).
bool suartTx(SUART_Descriptor *desc, char c)
Transmits a character.
bool bpsAlarmEnSave(uint16_t newal, uint16_t *alarms)
save alarm enable
This module implements parsing and formating of strings and integers.
bool bpsAlarmEnLoad(uint16_t *alarms)
Load already saved alarm enable.