1313#include " led.h"
1414#include < cstring>
1515
16- #define IDLE_TIME 1000 // Idle tolerance in microseconds
16+ #define IDLE_TIME 500 // Idle tolerance in microseconds (roughly three characters at 62500 baud)
17+
18+ // systemBus SYSTEM_BUS.;
1719
1820static QueueHandle_t reset_evt_queue = NULL ;
1921
@@ -78,18 +80,58 @@ uint8_t comlynx_checksum(uint8_t *buf, unsigned short len)
7880
7981void virtualDevice::comlynx_send (uint8_t b)
8082{
83+ Debug_printf (" comlynx_send_buffer: %X\n " , b);
84+
85+ // Wait for idle only when in UDPStream mode
86+ if (SYSTEM_BUS._udpDev ->udpstreamActive )
87+ SYSTEM_BUS.wait_for_idle ();
88+
8189 // Write the byte
82- ComLynx.wait_for_idle ();
8390 fnUartBUS.write (b);
8491 fnUartBUS.flush ();
8592 fnUartBUS.read ();
8693}
8794
8895void virtualDevice::comlynx_send_buffer (uint8_t *buf, unsigned short len)
8996{
90- ComLynx.wait_for_idle ();
91- fnUartBUS.write (buf,len);
92- fnUartBUS.readBytes (buf,len);
97+
98+ // buf[len] = '\0';
99+ // Debug_printf("comlynx_send_buffer: %d %s\n", len, buf); // causes out of bounds write in disk routines
100+
101+ // Debug_printf("comlynx_send_buffer: len:%d %0X %0X %0X %0X %0X %0X\n", len, buf[0], buf[1], buf[2], buf[3], buf[4], buf[len-1]);
102+ Debug_printf (" comlynx_send_buffer: len:%d\n " , len);
103+
104+ // Wait for idle only when in UDPStream mode
105+ if (SYSTEM_BUS._udpDev ->udpstreamActive )
106+ SYSTEM_BUS.wait_for_idle ();
107+
108+ fnUartBUS.write (buf, len);
109+ fnUartBUS.readBytes (buf, len);
110+ }
111+
112+ bool virtualDevice::comlynx_recv_ck ()
113+ {
114+ uint8_t recv_ck, ck;
115+
116+
117+ while (fnUartBUS.available () <= 0 )
118+ fnSystem.yield ();
119+
120+ // get checksum
121+ recv_ck = fnUartBUS.read ();
122+
123+ ck = comlynx_checksum (recvbuffer, recvbuffer_len);
124+
125+ // debugging checksum values
126+ // Debug_printf("comlynx_recv_ck, recv:%02X calc:%02X\n", recv_ck, ck);
127+
128+ // reset receive buffer
129+ recvbuffer_len = 0 ;
130+
131+ if (recv_ck == ck)
132+ return true ;
133+ else
134+ return false ;
93135}
94136
95137uint8_t virtualDevice::comlynx_recv ()
@@ -101,6 +143,11 @@ uint8_t virtualDevice::comlynx_recv()
101143
102144 b = fnUartBUS.read ();
103145
146+ // Add to receive buffer
147+ recvbuffer[recvbuffer_len] = b;
148+ recvbuffer_len++;
149+
150+ // Debug_printf("comlynx_recv: %x\n", b);
104151 return b;
105152}
106153
@@ -136,19 +183,32 @@ uint16_t virtualDevice::comlynx_recv_length()
136183 s = comlynx_recv () << 8 ;
137184 s |= comlynx_recv ();
138185
186+ if (s > 1024 )
187+ s = 1024 ;
188+
189+ // Reset recv buffer, but maybe we want checksum over the length too? -SJ
190+ recvbuffer_len = 0 ;
191+
139192 return s;
140193}
141194
142195void virtualDevice::comlynx_send_length (uint16_t l)
143196{
144- ComLynx.wait_for_idle ();
145197 comlynx_send (l >> 8 );
146198 comlynx_send (l & 0xFF );
147199}
148200
149201unsigned short virtualDevice::comlynx_recv_buffer (uint8_t *buf, unsigned short len)
150202{
151- return fnUartBUS.readBytes (buf, len);
203+ unsigned short b;
204+
205+ b = fnUartBUS.readBytes (buf, len);
206+
207+ // Add to receive buffer
208+ memcpy (&recvbuffer[recvbuffer_len], buf, len);
209+ recvbuffer_len += len;
210+
211+ return (b);
152212}
153213
154214uint32_t virtualDevice::comlynx_recv_blockno ()
@@ -180,35 +240,32 @@ void virtualDevice::comlynx_control_ready()
180240 comlynx_response_ack ();
181241}
182242
183- void systemBus::wait_for_idle ()
243+ bool systemBus::wait_for_idle ()
184244{
185- bool isIdle = false ;
186245 int64_t start, current, dur;
187- int trashCount = 0 ;
188246
189- do
190- {
191- // Wait for serial line to quiet down.
192- while (fnUartBUS.available () > 0 )
193- {
194- fnUartBUS.read ();
195- trashCount++;
196- }
247+ // SJ notes: we really don't need to do this unless we are in UDPStream mode
248+ // Likely we want to just wait until the bus is "idle" for about 3 character times
249+ // which is about 0.5 ms at 62500 baud 8N1
250+ //
251+ // Check that the bus is truly idle for the whole duration, and then we can start sending?
197252
198- if (trashCount > 0 )
199- Debug_printf (" wait_for_idle() dropped %d bytes\n " , trashCount);
253+ start = esp_timer_get_time ();
200254
201- start = current = esp_timer_get_time ();
255+ do {
256+ current = esp_timer_get_time ();
257+ dur = current - start;
202258
203- while ((fnUartBUS.available () <= 0 ) && (isIdle == false ))
204- {
205- current = esp_timer_get_time ();
206- dur = current - start;
207- if (dur > IDLE_TIME)
208- isIdle = true ;
209- }
210- } while (isIdle == false );
211- fnSystem.yield ();
259+ // Did we get any data in the FIFO while waiting?
260+ if (fnUartBUS.available () > 0 )
261+ return false ;
262+
263+ } while (dur < IDLE_TIME);
264+
265+ // Must have been idle at least IDLE_TIME to get here
266+ return true ;
267+
268+ // fnSystem.yield(); // not sure if we need to do this, from old function - SJ
212269}
213270
214271void virtualDevice::comlynx_process (uint8_t b)
@@ -218,7 +275,7 @@ void virtualDevice::comlynx_process(uint8_t b)
218275
219276void virtualDevice::comlynx_control_status ()
220277{
221- ComLynx .start_time = esp_timer_get_time ();
278+ // SYSTEM_BUS .start_time = esp_timer_get_time();
222279 comlynx_response_status ();
223280}
224281
@@ -262,10 +319,19 @@ void systemBus::_comlynx_process_cmd()
262319 uint8_t b;
263320
264321 b = fnUartBUS.read ();
265- start_time = esp_timer_get_time ();
322+ // start_time = esp_timer_get_time();
266323
267324 uint8_t d = b & 0x0F ;
268325
326+ #ifdef DEBUG
327+ if ((b & 0xF0 ) == (MN_ACK<<4 ))
328+ Debug_println (" Lynx sent ACK" );
329+ else {
330+ Debug_println (" ---" );
331+ Debug_printf (" comlynx_process_cmd: dev:%X cmd:%X\n " , d, (b & 0xF0 )>>4 );
332+ }
333+ #endif
334+
269335 // Find device ID and pass control to it
270336 if (_daisyChain.count (d) < 1 )
271337 {
@@ -453,9 +519,54 @@ void systemBus::setUDPHost(const char *hostname, int port)
453519 }
454520
455521 // Restart UDP Stream mode if needed
456- if (_udpDev->udpstreamActive )
522+ if (_udpDev->udpstreamActive ) {
457523 _udpDev->comlynx_disable_udpstream ();
458- if (_udpDev->udpstream_host_ip != IPADDR_NONE)
524+ _udpDev->comlynx_disable_redeye ();
525+ }
526+ if (_udpDev->udpstream_host_ip != IPADDR_NONE) {
459527 _udpDev->comlynx_enable_udpstream ();
528+ if (_udpDev->redeye_mode )
529+ _udpDev->comlynx_enable_redeye ();
530+ }
531+ }
532+
533+
534+ void systemBus::setRedeyeMode (bool enable)
535+ {
536+ Debug_printf (" setRedeyeMode, %d\n " , enable);
537+ _udpDev->redeye_mode = enable;
538+ _udpDev->redeye_logon = true ;
460539}
540+
541+
542+ void systemBus::setRedeyeGameRemap (uint32_t remap)
543+ {
544+ Debug_printf (" setRedeyeGameRemap, %d\n " , remap);
545+
546+ // handle pure updstream games
547+ if ((remap >> 8 ) == 0xE1 ) {
548+ _udpDev->redeye_mode = false ; // turn off redeye
549+ _udpDev->redeye_logon = true ; // reset logon phase toggle
550+ _udpDev->redeye_game = remap; // set game, since we can't detect it
551+ }
552+
553+ // handle redeye game that need remapping
554+ if (remap != 0xFFFF ) {
555+ _udpDev->remap_game_id = true ;
556+ _udpDev->new_game_id = remap;
557+ }
558+ else {
559+ _udpDev->remap_game_id = false ;
560+ _udpDev->new_game_id = 0xFFFF ;
561+ }
562+ }
563+
564+
565+ /* void systemBus::setComlynxIdleTime(uint64_t idle_time)
566+ {
567+ Debug_printf("setComlynxIdleTime, %d\n", idle_time);
568+
569+ SYSTEM_BUS.comlynx_idle_time = idle_time;
570+ }*/
571+
461572#endif /* BUILD_LYNX */
0 commit comments