/***********************************************************************
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
}
}
}