@@ -26,13 +26,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
2626
2727#if (DISPLAY_TYPE & DISPLAY_TYPE_BAFANG)
2828
29-
30-
3129// Definitions
32- #define RXSTATE_STARTCODE 0
33- #define RXSTATE_MSGBODY 1
34- #define RXSTATE_DONE 2
35-
30+ #define RXSTATE_WAITGAP 0 // waiting for gap between messages to reset rx buffer
31+ #define RXSTATE_STARTCODE 1 // waiting for startcode
32+ #define RXSTATE_REQUEST 2 // request startcode received, waiting for request code
33+ #define RXSTATE_INFO 3 // info startcode received, waiting for info code
34+ #define RXSTATE_INFOMESSAGE 4 // info code received, waiting for info message
35+ #define RXSTATE_DONE 5 // command received
3636
3737// Local function prototypes
3838static void BAFANG_Service (BAFANG_t* BF_ctx);
@@ -57,7 +57,7 @@ void Bafang_Init (BAFANG_t* BF_ctx, HardwareSerial* DisplaySerial)
5757 uint8_t i;
5858 BF_ctx->SerialPort = DisplaySerial; // Store serial port to use
5959
60- BF_ctx->RxState = RXSTATE_STARTCODE ;
60+ BF_ctx->RxState = RXSTATE_WAITGAP ;
6161 BF_ctx->LastRx = millis ();
6262
6363 for (i=0 ; i<BF_MAX_RXBUFF; i++)
@@ -77,89 +77,136 @@ void Bafang_Init (BAFANG_t* BF_ctx, HardwareSerial* DisplaySerial)
7777void Bafang_Service (BAFANG_t* BF_ctx)
7878{
7979 uint8_t i;
80+ // wait for gap
81+ if (BF_ctx->RxState == RXSTATE_WAITGAP) // waiting for start code
82+ {
83+ while (BF_ctx->SerialPort ->available ())
84+ {
85+ BF_ctx->SerialPort ->read ();
86+ BF_ctx->LastRx = millis ();
87+ }
88+
89+ if (millis ()-BF_ctx->LastRx >BF_DISPLAYTIMEOUT) // gap detected
90+ {
91+ BF_ctx->RxState ++; // /go to next state
92+ BF_ctx->RxCnt =0 ;
93+ }
94+ }
95+
8096 // Search for Start Code
8197 if (BF_ctx->RxState == RXSTATE_STARTCODE) // waiting for start code
8298 {
83- if (millis ()-BF_ctx->LastRx >BF_DISPLAYTIMEOUT) // new transmission frame will come
84- if (BF_ctx->SerialPort ->available ())
85- {
86- BF_ctx->LastRx = millis ();
87- BF_ctx->RxBuff [0 ]=BF_ctx->SerialPort ->read ();
88- if (BF_ctx->RxBuff [0 ]==BF_CMD_STARTREQUEST||BF_ctx->RxBuff [0 ]==BF_CMD_STARTINFO) // valid startcode detected
89- {
90- BF_ctx->RxCnt = 1 ;
91- BF_ctx->RxState = RXSTATE_MSGBODY;
92- }
93- else
94- {
95- return ; // No need to continue
96- }
97- }
99+ if (BF_ctx->SerialPort ->available ())
100+ {
101+ BF_ctx->LastRx = millis ();
102+ BF_ctx->RxBuff [0 ]=BF_ctx->SerialPort ->read ();
103+ if (BF_ctx->RxBuff [0 ]==BF_CMD_STARTREQUEST) // valid request startcode detected
104+ {
105+ BF_ctx->RxCnt = 1 ;
106+ BF_ctx->RxState = RXSTATE_REQUEST;
107+ }
108+ else if (BF_ctx->RxBuff [0 ]==BF_CMD_STARTINFO) // valid info startcode detected
109+ {
110+ BF_ctx->RxCnt = 1 ;
111+ BF_ctx->RxState = RXSTATE_INFO;
112+ }
113+ else
114+ {
115+ BF_ctx->RxState == RXSTATE_WAITGAP;
116+ }
117+ }
98118 }
99119
100- // Receive Message body
101- if (BF_ctx->RxState == RXSTATE_MSGBODY)
120+ if (BF_ctx->RxState == RXSTATE_REQUEST) // we are waiting for request code
102121 {
103- while (BF_ctx->SerialPort ->available ())
122+ if (BF_ctx->SerialPort ->available ()) // request code received
104123 {
105124 BF_ctx->RxBuff [BF_ctx->RxCnt ] = BF_ctx->SerialPort ->read ();
106125 BF_ctx->RxCnt ++;
107- if (BF_ctx->RxCnt > 5 ) // something is wrong, reset
126+ BF_ctx->LastRx = millis ();
127+ switch (BF_ctx->RxBuff [1 ]) // analyze and send correct answer
108128 {
109- BF_ctx->RxState = RXSTATE_STARTCODE;
110- BF_ctx->LastRx = millis ();
111- break ;
129+ case BF_CMD_GETSPEED:
130+ #if (DISPLAY_TYPE==DISPLAY_TYPE_BAFANG_C961)
131+ spd_tmp=BF_ctx->Rx .Wheeldiameter *0.02 *spd;
132+ #elif (DISPLAY_TYPE==DISPLAY_TYPE_BAFANG_C965)
133+ spd_tmp=BF_ctx->Rx .Wheeldiameter *0.03887 *spd;
134+ #endif
135+ TxBuff[0 ]=(spd_tmp>>8 );
136+ TxBuff[1 ]=(spd_tmp&0xff );
137+ TxBuff[2 ]=TxBuff[0 ]+TxBuff[1 ]+32 ;
138+ BF_sendmessage (BF_ctx,3 );
139+ break ;
140+
141+ case BF_CMD_GETERROR:
142+ TxBuff[0 ]=1 ;
143+ BF_sendmessage (BF_ctx,1 );
144+ break ;
145+
146+ case BF_CMD_GETBAT:
147+ TxBuff[0 ]=battery_percent_fromcapacity;
148+ TxBuff[1 ]=battery_percent_fromcapacity;
149+ BF_sendmessage (BF_ctx,2 );
150+ break ;
151+
152+ case BF_CMD_GETPOWER:
153+ TxBuff[0 ]=power/10 ;
154+ TxBuff[1 ]=power/10 ;
155+ BF_sendmessage (BF_ctx,2 );
156+ break ;
157+
158+ case BF_CMD_GET2:
159+ TxBuff[0 ]=48 ;
160+ TxBuff[1 ]=48 ;
161+ BF_sendmessage (BF_ctx,2 );
162+ break ;
112163 }
113- BF_ctx->LastRx = millis ();
114- }
164+ BF_ctx->RxState = RXSTATE_WAITGAP; // reset state machine
165+ }
166+
115167 }
116168
117- if (( millis ()- BF_ctx->LastRx )>BF_DISPLAYTIMEOUT&&(BF_ctx-> RxState == RXSTATE_MSGBODY)) // new message has been received -> analyze
169+ if ( BF_ctx->RxState == RXSTATE_INFO) // we are waiting for info code
118170 {
119- BF_ctx->RxState = RXSTATE_DONE;
120- }
121-
122- // Message received completely, analyze
123- if (BF_ctx->RxState == RXSTATE_DONE)
124- {
125- BF_ctx->RxState = RXSTATE_STARTCODE;
126- if (BF_ctx->RxBuff [0 ]==BF_CMD_STARTREQUEST) // display wants an answer, send it!
171+ if (BF_ctx->SerialPort ->available ()) // info code received
127172 {
128- switch (BF_ctx->RxBuff [1 ])
173+ BF_ctx->RxBuff [BF_ctx->RxCnt ] = BF_ctx->SerialPort ->read ();
174+ BF_ctx->RxCnt ++;
175+ BF_ctx->LastRx = millis ();
176+ switch (BF_ctx->RxBuff [1 ]) // analyze info code and set correct bytes to receive
129177 {
130- case BF_CMD_GETSPEED:
131- spd_tmp=BF_ctx->Rx .Wheeldiameter *0.03887 *spd;
132- TxBuff[0 ]=(spd_tmp>>8 );
133- TxBuff[1 ]=(spd_tmp&0xff );
134- TxBuff[2 ]=TxBuff[0 ]+TxBuff[1 ]+32 ;
135- BF_sendmessage (BF_ctx,3 );
178+ case BF_CMD_LEVEL:
179+ BF_ctx->InfoLength =4 ; // level message has length of 4 bytes
180+ BF_ctx->RxState ++;
136181 break ;
137182
138- case BF_CMD_GETERROR :
139- TxBuff[ 0 ]= 1 ;
140- BF_sendmessage ( BF_ctx, 1 ) ;
183+ case BF_CMD_LIGHT :
184+ BF_ctx-> InfoLength = 3 ; // light message has length of 3 bytes
185+ BF_ctx-> RxState ++ ;
141186 break ;
142187
143- case BF_CMD_GETBAT:
144- TxBuff[0 ]=battery_percent_fromcapacity;
145- TxBuff[1 ]=battery_percent_fromcapacity;
146- BF_sendmessage (BF_ctx,2 );
147-
148- case BF_CMD_GETPOWER:
149- TxBuff[0 ]=power/10 ;
150- TxBuff[1 ]=power/10 ;
151- BF_sendmessage (BF_ctx,2 );
188+ case BF_CMD_WHEELDIAM: // wheeldiameter message has length of 5 bytes
189+ BF_ctx->InfoLength =5 ;
190+ BF_ctx->RxState ++;
152191 break ;
153192
154- case BF_CMD_GET2:
155- TxBuff[0 ]=48 ;
156- TxBuff[1 ]=48 ;
157- BF_sendmessage (BF_ctx,2 );
193+ default :
194+ BF_ctx->RxState =RXSTATE_WAITGAP; // not a valid message -> reset state machine
158195 break ;
159196 }
160-
197+ }
198+ }
199+
200+ if (BF_ctx->RxState == RXSTATE_INFOMESSAGE) // we are waiting for info message
201+ {
202+ while (BF_ctx->SerialPort ->available ()&&BF_ctx->RxCnt <BF_ctx->InfoLength ) // read info message
203+ {
204+ BF_ctx->RxBuff [BF_ctx->RxCnt ] = BF_ctx->SerialPort ->read ();
205+ BF_ctx->RxCnt ++;
206+ BF_ctx->LastRx = millis ();
161207 }
162- else if (BF_ctx->RxBuff [0 ]==BF_CMD_STARTINFO)
208+
209+ if (BF_ctx->RxCnt ==BF_ctx->InfoLength ) // info message complete --> analyze
163210 {
164211 switch (BF_ctx->RxBuff [1 ])
165212 {
@@ -213,8 +260,9 @@ void Bafang_Service(BAFANG_t* BF_ctx)
213260 case BF_CMD_WHEELDIAM:
214261 BF_ctx->Rx .Wheeldiameter =BF_ctx->RxBuff [2 ]*256 +BF_ctx->RxBuff [3 ];
215262 break ;
216- }
217- }
263+ }
264+ BF_ctx->RxState = RXSTATE_STARTCODE;
265+ }
218266 }
219267}
220268
0 commit comments