void ResultRx(void) { GIE = 0; RCIF = 0; BYTE Rw = ResultQC & 0xFC; ResultQue[ResultQC] = RCREG; ResultQC = (ResultQC+1) & (MAX_RESULT_COUNT*4-1); if(RCSTAbits.OERR) { // error occured Status.ErrorCount++; RCSTAbits.CREN = 0; // clear error RCSTAbits.CREN = 1; // renable } if((ResultQC & 3) == 0) { BYTE buf[7]; buf[0] = '='; buf[1] = SlaveAddress; buf[2] = WorkQue[WorkNow].WorkID; buf[3] = ResultQue[Rw++]; buf[4] = ResultQue[Rw++]; buf[5] = ResultQue[Rw++]; buf[6] = ResultQue[Rw]; SendCmdReply(buf, buf+2, sizeof(DWORD)); } GIE = 1; }
void ResultRx(void) { while(RCIF) { ResultQue[ResultQC] = ~RCREG; if(RCSTAbits.OERR) { // error occured Status.ErrorCount++; RCSTAbits.SPEN = 0; // clear error, don't re-enable yet return; } if((ResultQC & 3) == 3) { BYTE Rw = ResultQC & 0xFC; BYTE buf[7]; buf[0] = '='; buf[1] = SlaveAddress; buf[2] = Status.WorkID; buf[3] = ResultQue[Rw++]; buf[4] = ResultQue[Rw++]; buf[5] = ResultQue[Rw++]; buf[6] = ResultQue[Rw]; if(Status.State == 'W') SendCmdReply(buf, buf+2, sizeof(DWORD)+1); } ResultQC = (ResultQC+1) & (MAX_RESULT_COUNT*4-1); } }
void ResultRx(void) { BYTE TimeOut = 0; ResultQC = 0; while(ResultQC < 4) { if(RCIF) { ResultQue[2+ResultQC++] = RCREG; TimeOut = 0; } if(TimeOut++ > 32 ) { Status.Noise++; goto outrx; } if(RCSTAbits.OERR) { // error occured, either overun or no more bits if(Status.State == 'W') Status.ErrorCount++; RCSTAbits.SPEN = 0; // clear error, don't re-enable until next tick TMR0, 21.3uS goto outrx; } } if(Status.State == 'W') { ResultQue[0] = '='; ResultQue[1] = Status.WorkID; SendCmdReply(&ResultQue, &ResultQue+1, sizeof(ResultQue)-1); } outrx: RCSTAbits.SPEN = 0; RCSTAbits.SPEN = 1; IOCBF = 0; }
void ProcessCmd(char *cmd) { // cmd is one char, dest address 1 byte, data follows // we already know address is ours here switch(cmd[0]) { case 'W': // queue new work if( Status.WorkQC < MAX_WORK_COUNT-1 ) { WorkQue[ (WorkNow + Status.WorkQC) & WORKMASK ] = *(WORKTASK *)(cmd+2); if(Status.WorkQC++ == 0) { AsicPreCalc(&WorkQue[WorkNow]); AsicPushWork(); } } SendCmdReply(cmd, (char *)&Status, sizeof(Status)); break; case 'A': // abort work, reply with hash completion count Status.WorkQC = WorkNow = 0; WorkQue[ (WorkNow + Status.WorkQC++) & WORKMASK ] = *(WORKTASK *)(cmd+2); AsicPreCalc(&WorkQue[WorkNow]); AsicPushWork(); SendCmdReply(cmd, (char *)&Status, sizeof(Status)); break; case 'I': // return identity SendCmdReply(cmd, (char *)&ID, sizeof(ID)); break; case 'S': // return status SendCmdReply(cmd, (char *)&Status, sizeof(Status)); break; case 'C': // set config values if( cmd[2] != 0 ) { Cfg = *(WORKCFG *)(cmd+2); if(Cfg.HashClock < MIN_HASH_CLOCK) Cfg.HashClock = MIN_HASH_CLOCK; if(Cfg.HashClock > MAX_HASH_CLOCK) Cfg.HashClock = MAX_HASH_CLOCK; ClockCfg[0] = ((DWORD)Cfg.HashClock << 18) | 0x00000003; HashTime = 256-(TICK_FACTOR/Cfg.HashClock); PWM1DCH = Cfg.FanTarget; } SendCmdReply(cmd, (char *)&Cfg, sizeof(Cfg)); break; case 'E': // enable/disable work HASH_CLK_EN = (cmd[2] == '1'); Status.State = (cmd[2] == '1') ? 'R' : 'D'; SendCmdReply(cmd, (char *)&Status, sizeof(Status)); break; case 'Z': //I2CDetect(); SendCmdReply(cmd, (char *)&I2CState, sizeof(I2CState)); // case 'D': // detect asics // DetectAsics(); // SendCmdReply(cmd, (char *)&Status, sizeof(Status)); break; default: break; } LED_On(); }
void ProcessCmd(char *cmd) { // cmd is one char, dest address 1 byte, data follows // we already know address is ours here switch(cmd[0]) { case 'W': // queue new work if( Status.WorkQC < MAX_WORK_COUNT-1 ) { WorkQue[ (WorkNow + Status.WorkQC++) & WORKMASK ] = *(WORKTASK *)(cmd+2); if(Status.State == 'R') { AsicPreCalc(&WorkQue[WorkNow]); AsicPushWork(); } } SendCmdReply(cmd, (char *)&Status, sizeof(Status)); break; case 'A': // abort work, reply status has hash completed count Status.WorkQC = WorkNow = 0; Status.State = 'R'; SendCmdReply(cmd, (char *)&Status, sizeof(Status)); break; case 'I': // return identity SendCmdReply(cmd, (char *)&ID, sizeof(ID)); break; case 'S': // return status SendCmdReply(cmd, (char *)&Status, sizeof(Status)); break; case 'C': // set config values if( *(WORD *)&cmd[2] != 0 ) { Cfg = *(WORKCFG *)(cmd+2); if(Cfg.HashClock < MIN_HASH_CLOCK) Cfg.HashClock = MIN_HASH_CLOCK; if(Cfg.HashClock <= HALF_HASH_CLOCK && Cfg.HashClock >= MAX_HASH_CLOCK/2) Cfg.HashClock = MAX_HASH_CLOCK/2-1; if(Cfg.HashClock >= MAX_HASH_CLOCK) Cfg.HashClock = MAX_HASH_CLOCK-1; if(Cfg.HashClock <= HALF_HASH_CLOCK) ClockCfg[0] = (((DWORD)Cfg.HashClock*2) << 18) | CLOCK_HALF_CHG; else ClockCfg[0] = ((DWORD)Cfg.HashClock << 18) | CLOCK_LOW_CHG; HashTime = 256-((DWORD)TICK_FACTOR/Cfg.HashClock); PWM1DCH = Cfg.FanTarget; } SendCmdReply(cmd, (char *)&Cfg, sizeof(Cfg)); break; case 'E': // enable/disable work HASH_CLK_EN = (cmd[2] == '1'); Status.State = (cmd[2] == '1') ? 'R' : 'D'; SendCmdReply(cmd, (char *)&Status, sizeof(Status)); break; case 'D': SendCmdReply(cmd, (char *)&HashTime, sizeof(HashTime)); default: break; } LED_On(); }