/*********************************************************************** 2011 (C) Alex Dobrianski Stepper Motor controller module This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see ************************************************************************/ /*********************************************************************** see www.adobri.com for communication protocol spec ************************************************************************/ #include "int16CXX.H" #pragma config PWRTE=off, WDTE=off, FOSC=4, BODEN=off #pragma config |= 0x2f80 #pragma config reg2 = 0 #define Clock_8MHz #define bitset(i,j) i |= 1U << j #define bitclr(i,j) i &= ~(1U << j) #define bittest(i,j) (i & (1U< matched unit, // and 1 bit impulse send in responce that unit ready to recieve data if (GetMsgSend2Bits) { //Next3: if (Ch0) { if (!bittest(TransferBits,7)) goto SkipChanges; } else if (Ch1) { if (!bittest(TransferBits,6)) goto SkipChanges; } else { if (!bittest(TransferBits,4)) goto SkipChanges; } } RecieveByte: if (!GetingByte) { if (bittest(TransferBits,7)) Ch0 = 1; else if (bittest(TransferBits,6)) Ch1 = 1; else Ch2 = 1; RecieveByte_F: TMR1L = 0x80; TMR1H = 0xf0; #pragma updateBank 1 TMR1IE = 1; TimeLast = 0xf0; //#pragma updateBank 0 Rsi = 0; GetingByte = 1; RByte = 0x01; SkipStopBit = 0; CommLinesOld = CommLines; goto ExitIntr; } else { DeltaTime = TMR1H - TimeLast; TimeLast += W; if (Ch0) { if (!bittest(TransferBits,7)) goto SkipChanges; } else if (Ch1) { if (!bittest(TransferBits,6)) goto SkipChanges; } else { if (!bittest(TransferBits,4)) goto SkipChanges; } RecieveByte_N: if (SkipStopBit) { if (Rsi) { Rsi = 0; CommLinesOld = CommLines; goto ExitIntr; } else Rsi = 1; SkipStopBit = 0; Byte_ready: GetingByte = 0; GotByte = 1; InputByte = RByte; CommLinesOld = CommLines; goto ExitIntr; } while(1) { RByte <<=1; if (bittest(STATUS,0)) { if (Rsi) { if (--DeltaTime == 0) ; else bitset(RByte,0); Rsi = 0; } else { Rsi = 1; if (--DeltaTime == 0) bitset(RByte,0); else goto Byte_ready; } SkipStopBit = 1; break; } if (--DeltaTime == 0) { if (Rsi) Rsi = 0; else { bitset(RByte,0); Rsi = 1; } break; } else { if (Rsi) bitset(RByte,0); } } CommLinesOld = CommLines; goto ExitIntr; } SkipChanges: CommLinesOld = CommLines; } #pragma updateBank 1 ExitIntr: FSR = sv_FSR; // restore FSR if saved int_restore_registers // W, STATUS (and PCLATH) } #define ONEBIT_TMR0_LEN 0x10 void TransByte(unsigned char mByte) { bit si = 0; unsigned char i = 8; unsigned char MinusTmr0Delay; MinusTmr0Delay = 0 - Tmr0Delay; FSR = &CT[0]; INDF = MinusTmr0Delay; do { mByte<<=1; if (bittest(STATUS,0)) // ==1 { if (si) INDF-= Tmr0Delay; else { FSR++; INDF = MinusTmr0Delay; si = 1; } } else // == 0 { if (si) { FSR++; INDF = MinusTmr0Delay; si = 0; } else INDF-= Tmr0Delay; } } while(--i>0); if (si) { FSR+=1; INDF = MinusTmr0Delay; } else INDF -= Tmr0Delay; iCT = 1; FSR+=1; INDF = 0; } ///////////////////////////////////////////////COPY END////////// void enable_uart()//bit want_ints) { TX9 = 0; RX9 = 0; BRGH = 1; //Normal speed UART port 0x98 // 00000x00 BRGH: High Baud Rate Select bit //Asynchronous mode: // 1 = High speed 0 = Low speed SPBRG = 51;// 9600 //SPBRG = 25;// 19200 //SPBRG = 12;// 38400 //SPBRG = 8; // 57600 SYNC = 0; // port 0x98 = 000x0000 x=0 asynch mode 1-synchr SPEN = 1; // port 0x18 x0000000 SPEN: Serial Port Enable bit // 1 = Serial port enabled (configures RB2/SDO/RX/DT // and RB5/SS/TX/CK pins as serial port pins) //if(want_ints) //Check if we want to turn on interrupts //{ // TXIE = 1; // PEIE = 1; // GIE = 1; //} TXEN = 1; //Enable transmission port 0x8c // AUSART Transmit Interrupt Enable bit // 1 = Enabled 0 = Disabled ADDEN = 0; CREN = 1; // port 0x18 000x0000 CREN: Continuous Receive Enable bit // Asynchronous mode: 1 = Enables continuous receive //WREN = 1; } void putch(unsigned char nate) { TXREG = nate; // port 0x19 while(TXIF == 0); // port 0x0c 000x0000 TXIF: // AUSART Transmit Interrupt Flag bit // 1 = The AUSART transmit buffer is empty // (cleared by writing to TXREG) } void puts(const char * s) { while(*s) { putch(*s); s++; } } unsigned char eeprom_read(unsigned char addr) { EEADR = addr; EECON1 &= 0x3F; RD = 1; return EEDATA; } void eeprom_write(unsigned char addr, unsigned char value) { EEADR = addr; EEDATA = value; EECON1 &= 0x3F; Carry = 0; if(GIE) Carry = 1; GIE = 0; WREN = 1; EECON2 = 0x55; EECON2 = 0xAA; WR = 1; WREN = 0; if(Carry) GIE = 1; while(WR) { } } void Reset_device(void) { OSCCON = 0b01110000; //OSCILLATOR CONTROL REGISTER (ADDRESS 8Fh) // bit 6-4 IRCF<2:0>: Internal RC Oscillator Frequency Select bits // 000 = 31.25 kHz // 001 = 125 kHz // 010 = 250 kHz // 011 = 500 kHz // 100 = 1 MHz // 101 = 2 MHz // 110 = 4 MHz // 111 = 8 MHz // bit 3 OSTS: Oscillator Start-up Time-out Status bit(1) // 1 = Device is running from the primary system clock // 0 = Device is running from T1OSC or INTRC as a secondary system clock // Note 1: Bit resets to ‘0’ with Two-Speed Start-up mode and LP, XT or HS selected as the // oscillator mode. // bit 2 IOFS: INTOSC Frequency Stable bit // 1 = Frequency is stable // 0 = Frequency is not stable // bit 1-0 SCS<1:0>: Oscillator Mode Select bits // 00 = Oscillator mode defined by FOSC<2:0> // 01 = T1OSC is used for system clock // 10 = Internal RC is used for system clock // 11 = Reserved #ifdef _NOT_SIMULATOR while((OSCCON&0b00000100) == 0); //Wait for frequency to stabilize #endif ANSEL = 0b00000000; //Turn pins to Digital instead of Analog CMCON = 0b00000111; //Turn off comparator on RA port PORTA = 0b00000000; // for each unit it is individual TRISA = 0b11100001; //0 = Output, 1 = Input // RB5 - Serial Out Pin 11 // RB2 - Serial In Pin 8 // RB4-RB7 - Serial PORTB = 0b00000000; TRISB = 0b11010100; //0 = Output, 1 = Input //bitclr(OPTION,RBPU_); //Each of the PORTB pins has a weak internal pull-up. A //single control bit can turn on all the pull-ups. This is //performed by clearing bit RBPU (OPTION_REG<7>). //The weak pull-up is automatically turned off when the //port pin is configured as an output. The pull-ups are //disabled on a Power-on Reset. RBIF = 0; RBIE = 1; enable_uart(); //Setup the hardware UART for 20MHz at 9600bps ///////////////////////////////////2COPY BEGIN////////////// /////////////////////////////////////////////////////////// // Timer 0 /////////////////////////////////////////////////////////// TMR0 = 0; // Timer 0 set to 0 OPTION = 0x83; // OPTION_REG: OPTION CONTROL REGISTER (ADDRESS 81h, 181h) // bit 7 Not RBPU: PORTB Pull-up Enable bit // bit 6 INTEDG: Interrupt Edge Select bit // bit 5 T0CS: TMR0 Clock Source Select bit // 1 = Transition on T0CKI pin // 0 = Internal instruction cycle clock (CLKO) // bit 4 T0SE: TMR0 Source Edge Select bit // 1 = Increment on high-to-low transition on T0CKI pin // 0 = Increment on low-to-high transition on T0CKI pin // bit 3 PSA: Prescaler Assignment bit // 1 = Prescaler is assigned to the WDT // 0 = Prescaler is assigned to the Timer0 module // bit 2-0 PS<2:0>: Prescaler Rate Select bits // 001 - 1:4 // 010 - 1:8 // 011 - 1:16 TMR0IE = 0; // INTCON 0Bh,8Bh,10Bh,18Bh // Bit 5 Timer 0 Enable Interrupt TMR0IF = 0; // INTCON 0Bh,8Bh,10Bh,18Bh // Bit 5 Timer 0 Interrupt happened /////////////////////////////////////////////////////////// // Timer 1 /////////////////////////////////////////////////////////// TMR1ON = 0; // TMR1ON: Timer1 On bit // 1 = Enables Timer1 // 0 = Stops Timer1 TMR1IE = 0; TMR1CS = 0; // T1CON: TIMER1 CONTROL REGISTER (ADDRESS 10h) // TMR1CS: Timer1 Clock Source Select bit // 1 = External clock from pin RB6/AN5(1)/PGC/T1OSO/T1CKI (on the rising edge) // 0 = Internal clock (FOSC/4) bitclr(T1CON, 5); bitclr(T1CON, 4); // T1CKPS<1:0>: Timer1 Input Clock Prescale Select bits // 11 =1:8 Prescale value // 10 =1:4 Prescale value // 01 =1:2 Prescale value // 00 =1:1 Prescale value TMR1L =0; TMR1H = 0; TMR1IF = 0; TMR1ON = 1; // TMR1ON: Timer1 On bit // 1 = Enables Timer1 // 0 = Stops Timer1 PEIE = 1; // bit 6 PEIE: Peripheral Interrupt Enable bit // 1 = Enables all unmasked peripheral interrupts // 0 = Disables all peripheral interrupts GIE = 1; // bit 7 GIE: Global Interrupt Enable bit // 1 = Enables all unmasked interrupts // 0 = Disables all interrupts /////////////////////////////////////2COPY END///////////////////// } //////////////////////////////////////3COPY BEGIN/////////////////// void SetReply(void) { if (Ch0Send) { bitclr(TRISB,7); bitclr(PORTB,7); } else if (Ch1Send) { bitclr(TRISB,6); bitclr(PORTB,6); } else { bitclr(TRISB,4); bitclr(PORTB,4); } } void SetReceive(void) { if (Ch0) { bitset(TRISB,7); bitset(CommLinesOld,7); } else if (Ch1) { bitset(TRISB,6); bitset(CommLinesOld,6); } else { bitset(TRISB,4); bitset(CommLinesOld,4); } } void SetReceiveOnSend(void) { if (Ch0Send) { bitset(TRISB,7); bitset(CommLinesOld,7); } else if (Ch1Send) { bitset(TRISB,6); bitset(CommLinesOld,6); } else { bitset(TRISB,4); bitset(CommLinesOld,4); } } void SendByteOnCh(unsigned char Byte) { TransByte(Byte); GIE = 0; SetReply(); TMR0 = CT[0]; TMR0IF = 0; TMR0IE = 1; GIE = 1; } void Send2BitsOnCh(unsigned char Byte) { TransByte(Byte); GIE = 0; iCT = 3; SetReply(); TMR0 = CT[0]; TMR0IF = 0; TMR0IE = 1; GIE = 1; } ////////////////////////////////////////////////////////// // CMD implementation for Stepper motor controller // 0x80 - NOP with storing neighbor adr - message a0 02 XX 80 - XX neighbor addr // 0xc0 - storing neighbor adr - message a0 02 XX c0 - XX neighbor addr // and send responce on the same channel: XX 02 YY 80 - where YY my unit adr void GetMessageByte(unsigned char InByte) { if (GetMsgFrom) { if (!CmdFetch) { if (InByte == 0x80) // execute immeduatly store neighbour addr { CMD_80: if (Ch0) ChNeighbour[0] = From; else if (Ch1) ChNeighbour[1] = From; else ChNeighbour[2] = From; } else if (InByte == 0xC0) { MsgOut[0] = From; MsgOut[1] = 2; MsgOut[2] = Unit; MsgOut[3] = 0x80; pMsgOut = 3; ReqSendMsg = 1; goto CMD_80; } else //if (bittest(InByte,5)) { //if (bittest(InByte,4)) //{ //OUTPUT – output 4 bits for stepper motor //0011 XXXX – set bits for Stepper motor // RA1,RA2,RA3,RA4 the bits for stepper motor CMD[0]= InByte; ExecCMD = 1; //InByte &= 0x0f; //InByte <<=1; //PORTA = InByte; //} } // control point for test1 (must be 2 occurance) // control point for test4 // control point for test5 CmdFetch =1; } else { } } else { CmdFetch = 0; } } unsigned char GetNextByteToSend(void) { FSR = pMsgOut; pMsgOut--; FSR += &MsgOut[0]; return INDF; } void FindNextChanel(void) { if (!SendChooseNext) // second choose second channel { SendChooseLast = 0; // BD - do not forget to clean this bit before send message SendChooseNext = 1; RoundCh: if (Ch0Send) { Ch0Send = 0; Ch1Send = 1; } else if (Ch1Send) { Ch1Send = 0; Ch2Send = 1; } else { Ch2Send = 0; Ch0Send = 1; } } else { if (!SendChooseLast) // third choose last channel { SendChooseLast = 1; goto RoundCh; } else { // test7 check point StatusWait = 1; StatusSend = 0; } } } void FindMatchChanel(unsigned char ToWhom) { unsigned char iFound; int i; iFound = 0xff; FSR = &ChNeighbour[0]; for (i = 0; i < 3; i++) { if (INDF == ToWhom)//MsgOut[0]) { iFound = i; break; } FSR++; } Ch0Send =0; Ch1Send =0; Ch2Send =0; switch(iFound) { case 0: // channel 0 Ch0Send =1; break; case 1: // channel 1 Ch1Send =1; break; case 2: // channel 2 Ch2Send =1; break; default: // channel 0 Ch0Send =1; break; } } // ch0 -> ch1 / ch2 // ch1 -> ch0 / ch2 // ch2 -> ch0 / ch1 // must be inversed to oposit direction // TRISB 0 = Output, 1 = Input /* void SwitchRedirection(void) { if (RedirectCh0) { RedirectCh0 = 0; bitclr(TRISB,7); if (!RedirectPlus) { RedirectCh1 = 1; bitset(TRISB,6); bitset(CommLinesOld,6); } else { RedirectCh2 = 1; RedirectPlus = 0; bitset(TRISB,4); bitset(CommLinesOld,4); } } else if (RedirectCh1) { RedirectCh1 = 0; bitclr(TRISB,6); if (!RedirectPlus) { RedirectCh0 = 1; bitset(TRISB,7); bitset(CommLinesOld,7); } else { RedirectCh2 = 1; bitset(TRISB,4); bitset(CommLinesOld,4); } } else// if (RedirectCh2) { RedirectCh2 = 0; bitclr(TRISB,6); if (!RedirectPlus) { RedirectCh0 = 1; RedirectPlus = 1; bitset(TRISB,7); } else { RedirectCh1 = 1; bitset(TRISB,6); } } RedirectSet = 1; }*/ // ch0 -> ch1 / ch2 // ch1 -> ch0 / ch2 // ch2 -> ch0 / ch1 // TRISB 0 = Output, 1 = Input void SetPinRedirection(void) { if (RedirectCh0) { bitset(TRISB,7); bitset(CommLinesOld,7); if (!RedirectPlus) bitclr(TRISB,6); else bitclr(TRISB,4); } else if (RedirectCh1) { bitset(TRISB,6); bitset(CommLinesOld,6); if (!RedirectPlus) bitclr(TRISB,7); else bitclr(TRISB,4); } else { bitset(TRISB,4); bitset(CommLinesOld,4); if (!RedirectPlus) bitclr(TRISB,7); else bitclr(TRISB,6); } RedirectSet = 1; } void ExecCMDBuf(void); ///////////////////////////////////////3COPY END////////////////////////// void main() { // needs to check what is it: unsigned char i; if (TO) // Power up or MCLR { Unit = 0x81; //////////////////////////////////////4COPY BEGIN/////////////////// Tmr0Delay = 0x0F; // set zerro all bits (total two bytes) FSR = &Ch0; INDF = 0; FSR = &RedirectCh0; INDF = 0; Reset_device(); CommLinesOld = PORTB; StatusSend = 0; StatusWait = 1; StatusGetMsg = 0; StatusRedirect = 0; ReqSendMsg = 0; SendWaitFor2Bits = 0; SendToUnit = 0; RedirectWaitNBits = 0; RedirectWaitForTO = 0; RedirectSet = 0; GetMsgSend2Bits = 0; ExecCMD = 0; //////////////////////////////////////4COPY END///////////////////////// } //////////////////////////////////////5COPY BEGIN/////////////////////// while(1) { ///////////////////////// send /////////////////////////////// if (StatusSend) // needs to send something to { DoChooseChanel: // first: choosing channnel(pin) if (!StatusSendChooseChanel) // need to choose chanel { MessageSend = 0; SendWaitFor2Bits = 0; // first needs to find match looking over // neghborhood list if (!SendChoosematch) // first attempt is by matching neightbour address { FindMatchChanel(MsgOut[0]); SendChoosematch = 1; } else { // if not try another channel FindNextChanel(); } SendToUnit = 0; StatusSendChooseChanel = 1; } else { if (!SendToUnit) // address send == NOT then send byte { SendSwitchDir1 = 0; SendToUnit = 1; SendByteOnCh(MsgOut[0]); SendWait2bit = 0; TimeOutTmr1 = 0; TMR1L = 0; TMR1H = 0xe0; TMR1IF = 0; TMR1IE = 1; } else { if (!SendWait2bit) // send - wait for 1001 == OK { // or wait for 101 == chanel not accesable if (TMR0IE) goto ContinueWaiting; if (TimeOutTmr1) { StatusSendChooseChanel = 0; } else { if (!SendSwitchDir1) { SendSwitchDir1 = 1; SendOkResponce: SetReceiveOnSend(); TwoBitInterval = 0; SendWaitFor2Bits = 1; } else { if (SendWaitFor2Bits == 0) { if (TwoBitInterval == 1) { SendWait2bit = 1; SendLen = 0; } else { StatusSendChooseChanel = 0; } } } } } else { // send byte if (!SendLen) { SendLen = 1; SendFrom = 0; SendByteOnCh(MsgOut[1]); } else { if (!SendFrom) { if (TMR0IE) goto ContinueWaiting; // sned byte SendFrom = 1; SendByteOnCh(Unit); //MsgOut[1]--; } else { if (TMR0IE) goto ContinueWaiting; // check message done? if (--MsgOut[1] == 0) { // message done StatusSend = 0; MessageSend = 1; goto DoWaitState; } else { // send next byte from message i = GetNextByteToSend(); SendByteOnCh(i); } } } } } } } else // NOT a send state { // if it is not "SEND" state (wait/redirect) // then it is possible to send prepeared message if (ReqSendMsg) { if (StatusWait) { StatusSend = 1; StatusSendChooseChanel = 0; SendChoosematch = 0; ReqSendMsg = 0; SendChooseNext = 0; } } } ////////////monitor incoming bytes////////////////////////// if (StatusWait) { // if some byte received from some line this byte is address if (GotByte) { ///////////////////////////////////////////// // possible addresses 22: // a0 1010 0000 42 0100 0010 // 90 1001 0000 44 0100 0100 // 88 1000 1000 48 0100 1000 // 84 1000 0100 50 0101 0000 // 82 1000 0010 22 0010 0010 // 81 1000 0001 24 0010 0100 // 41 0100 0001 28 0010 1000 // 21 0010 0001 12 0001 0010 // 11 0001 0001 14 0001 0100 // 09 0000 1001 0a 0000 1010 // 05 0000 0101 if (InputByte == 0xa0) // generic addr goto accept_msg; if (Unit == InputByte) { accept_msg: StatusWait = 0; StatusGetMsg = 1; GetSending2bits = 0; } else // byte not matched - will be redirection { StatusRedirect = 1; RedirectRetrAdr = 0; RedirectAllChTried = 0; RedeirectEndingNotFound = 0; RedirectWaitForTO = 0; // attempt to find matching pin in neghborhood list FindMatchChanel(InputByte); // if this is the same pin as recived byte? if (Ch0) if (Ch0Send) goto ChooseNextToRedirect; if (Ch1) if (Ch1Send) goto ChooseNextToRedirect; if (Ch2) if (Ch2Send) goto ChooseNextToRedirect; goto GoodRedirectionFound; ChooseNextToRedirect: SendChooseNext = 0; // second call will switch to next one FindNextChanel(); GoodRedirectionFound: RedirectCh0 = 0; RedirectCh1 = 0; RedirectCh2 = 0; // now setting redirection chanels if (Ch0) { RedirectCh0 = 1; if (Ch1Send) RedirectPlus = 0; else RedirectPlus = 1; } else if (Ch1) { RedirectCh1 = 1; if (Ch0Send) RedirectPlus = 0; else RedirectPlus = 1; } else { RedirectCh2 = 1; if (Ch0Send) RedirectPlus = 0; else RedirectPlus = 1; } // retransmitt byte to redirectional chanel retransmit_to: SendByteOnCh(InputByte); Ch0 = 0; Ch1 = 0; Ch2 = 0; GotByte = 0; } } } ////////////////////getting message////////////////////// if (StatusGetMsg) { // need to send responce 1001 that address matched if (!GetSending2bits) { // set chanel to send impuls 1001 = adr matched Ch0Send=0; Ch1Send=0; Ch2Send=0; if (Ch0) Ch0Send =1; else if (Ch1) Ch1Send =1; else Ch2Send =1; SendBackOkMsg: Send2BitsOnCh(0xff); // send 0x7e 1|00111 11100|1 to [3] == No // or 0xFF 1|00111 11110|1 to [3] == Ok // "no" never send if unit matched GetSending2bits = 1; GetMsgSend2Bits = 0; } else { // this will wait till moment "OK" is sending if (!GetMsgSend2Bits) { // interrupt switch off TMR0 on impulse send if (TMR0IE) goto ContinueWaiting; // now reverse direction - pin to be receiver SetReceive(); GetMsgSend2Bits =1; GetMsgLen = 0; GotByte = 0; // setup timeout for incoming message TimeOutTmr1 = 0; TMR1L = 0; TMR1H = 0xe0; } else { // waiting to get byte if (!GetMsgLen) { if (GotByte) { iMsglen = InputByte; iGMsglen = InputByte; GetMsgLen = 1; GotByte = 0; GetMsgFrom = 0; } if (TimeOutTmr1) { //test6 control point goto DoWaitState; } } else { if (GotByte) { // process bytes from a message GetMessageByte(InputByte); // if it is last byte then pin is free // to get data if (--iMsglen == 0) // mesage done { StatusGotMsg = 1; DoWaitState: // control point for test2 must be second occurence StatusWait = 1; StatusGetMsg = 0; GetMsgSend2Bits = 0; Ch0 = 0; Ch1 = 0; Ch2 = 0; } else { // for byte processing if (!GetMsgFrom) { From = InputByte; GetMsgFrom = 1; } } GotByte = 0; } } } } } ///////////////redirect messadge/////////////// if (StatusRedirect) { if (!RedirectRetrAdr) { if (TMR0IE) goto ContinueWaiting; RedirectRetrAdr = 1; RedirectWaitOK = 0; // now needs to get impluls from ch1 / ch2 // ch1 -> ch0 / ch2 // ch2 -> ch0 / ch1 Ch0Send=0; Ch1Send=0; Ch2Send=0; if (RedirectCh0) { if (!RedirectPlus) Ch1Send = 1; else Ch2Send = 1; } else if (RedirectCh0) { if (!RedirectPlus) Ch0Send = 1; else Ch2Send = 1; } else { if (!RedirectPlus) Ch0Send = 1; else Ch1Send = 1; } RedirectRetrAdr = 0; RedirectAllChTried = 1; goto retransmit_to; } else { // none of channeks found retransmit unit // need to transmit "not found" Ch0Send=0; Ch1Send=0; Ch2Send=0; if (RedirectCh0) Ch0Send =1; else if (RedirectCh1) Ch1Send =1; else Ch2Send =1; Send2BitsOnCh(0x7e); // send 0x7e 1|00111 11100|1 to [3] == No // or 0xFF 1|00111 11110|1 to [3] == Ok // "no" never send if unit matched GetSending2bits = 1; GetMsgSend2Bits = 0; RedeirectEndingNotFound = 1; RedirectWaitOK = 1; } } } } else { if (!RedirectWaitForTO) { // interrupt switch off TMR0 on impulse send if (TMR0IE) goto ContinueWaiting; if (RedeirectEndingNotFound) { EndingRedirection: // test3 control point StatusRedirect = 0; RedirectSet = 0; goto ContinueWaiting; } // now reverse direction - pin to be receiver SetPinRedirection(); RedirectWaitForTO = 1; TimeOutTmr1 = 0; } else { // if timeout on redirection then done with redirection if (TimeOutTmr1) goto EndingRedirection; } } } } ContinueWaiting:; if (ExecCMD) { ExecCMDBuf(); } } /////////////////////////////////////////5COPY END/////////////////// } // at the end will be Sleep which then continue to main void ExecCMDBuf(void) { unsigned char i; if (bittest(CMD[0],5)) { if (bittest(CMD[0],4)) { // 0x3X //OUTPUT – output 4 bits for stepper motor //0011 XXXX – set bits for Stepper motor // RA1,RA2,RA3,RA4 the bits for stepper motor i = CMD[0]; i &= 0x0f; i <<= 1; PORTA = i; // control point for testc1 ExecCMD = 0; } else { // BWD – backward movements // 0010 0001 – 1 step back // 0010 xxxx – '0001' – '1110' 1-14 steps backward // 0010 1111 – continuous backward } } else { if (bittest(CMD[0],4)) { // FWD – forward movements movements // 0001 0001 - 1 step FWRD // 0001 xxxx - '0001' – '1110' 1-14 steps forward // 0001 1111 - continuous forward } } }