1
0
Fork 0

Compare commits

...

4 commits

Author SHA1 Message Date
610ccc630a Unity: Use UInt16.MaxValue rather than hardcoding 65536
Unity provides constants that reflect the maximum value of integer types,
use it for checking the checksum overflow rather than using 65536 directly.
This makes the intent more clear.
2023-12-16 14:10:28 +00:00
91dae1be7e Unity: Fix hardcoded page size in ReceiveSerialData()
Remove the hardocded '128' that checked for a full page being received
and replace it with the appropriate constant.
2023-12-16 14:10:28 +00:00
a18c37daa1 Unity: Add delay after serial connection
The Arduino will block if sent data too quickly after connection.
Add a new coroutine to force waiting for 1s+ and update the UI
accordingly.

Update some comments throughout.
2023-12-16 14:10:28 +00:00
4e11af1da0 Arduino: Use 400kHz clock for I²C
The EEPROM in the cartridges support 'Fast I²C' at 400kHz.
Testing it out, it seems to work fine despite the high pull-ups,
so update the Arduino code to enjoy the 4x speed-up !
2023-12-16 14:10:25 +00:00
3 changed files with 38 additions and 10 deletions

View file

@ -45,6 +45,7 @@ void setup() {
Serial.begin(115200); Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT); pinMode(LED_BUILTIN, OUTPUT);
Wire.begin(); Wire.begin();
Wire.setClock(400000);
} }
void loop() { void loop() {

View file

@ -33,6 +33,7 @@ void setup() {
Serial.begin(115200); Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT); pinMode(LED_BUILTIN, OUTPUT);
Wire.begin(); Wire.begin();
Wire.setClock(400000);
} }
/* /*

View file

@ -14,6 +14,7 @@ public class Arduino_Com : MonoBehaviour
{ {
Déconnecté, Déconnecté,
Connecté, Connecté,
Connexion,
Lecture, Lecture,
Écriture, Écriture,
Invalide Invalide
@ -68,16 +69,26 @@ public class Arduino_Com : MonoBehaviour
return sum; return sum;
} }
// Core communication function.
// Receives all the data from the cartridge and writes it out to the png file.
// As the computer will probably read the serial data faster than the Arduino
// /and/ the transfer is quite slow (lots of bits, low baudrate), make this a
// coroutine.
// This prevents the whole application freezing up why waiting for data and
// allow presenting visual feedback.
private IEnumerator<WaitUntil> ReceiveSerialData() private IEnumerator<WaitUntil> ReceiveSerialData()
{ {
do do
{ {
// We could use an event instead but as Unity is lagging behind .NET versions,
// it wouldn't be cross-platform.
yield return new WaitUntil(() => _serial.BytesToRead >= 1); yield return new WaitUntil(() => _serial.BytesToRead >= 1);
// Read all available data, up to the PageSize. // Read all available data, up to the PageSize.
_readBytes += _serial.Read(_pageBuffer, _readBytes, PageSize - _readBytes); _readBytes += _serial.Read(_pageBuffer, _readBytes, PageSize - _readBytes);
// Full page received, check checksum and ACK/NAK, write received page. // Full page received, check checksum and ACK/NAK, write received page.
if (_readBytes >= 128) if (_readBytes >= PageSize)
{ {
Byte[] checksum = new byte[2]; Byte[] checksum = new byte[2];
// There might be less than the two characters of the checksum available, loop until complete. // There might be less than the two characters of the checksum available, loop until complete.
@ -88,7 +99,8 @@ public class Arduino_Com : MonoBehaviour
} while (checksumRead < 2); } while (checksumRead < 2);
// Implicit type of the sum is 4 bytes, so the overflow doesn't occur. Compute manually. // Implicit type of the sum is 4 bytes, so the overflow doesn't occur. Compute manually.
if (65536 - (BitConverter.ToUInt16(checksum) + ComputeChecksum(_pageBuffer)) == 0) if ((UInt16.MaxValue + 1) -
(BitConverter.ToUInt16(checksum) + ComputeChecksum(_pageBuffer)) == 0)
{ {
// Checksum valid, write it out to the cart. // Checksum valid, write it out to the cart.
_cart.Write(_pageBuffer); _cart.Write(_pageBuffer);
@ -104,6 +116,7 @@ public class Arduino_Com : MonoBehaviour
_readBytes = 0; _readBytes = 0;
} }
} while (_currentPage < PageCount); } while (_currentPage < PageCount);
// We are done receiving the cart, we don't expect more data to be received so the coroutine can return. // We are done receiving the cart, we don't expect more data to be received so the coroutine can return.
_currentPage = 0; _currentPage = 0;
_state = ArduinoState.Connecté; _state = ArduinoState.Connecté;
@ -222,14 +235,7 @@ public class Arduino_Com : MonoBehaviour
return; return;
} }
// TODO: Wait ~2s for Arduino startup StartCoroutine(DoSerialConnection());
_arduinoControlButton.text = "Déconnecter";
_cartLoadButton.SetEnabled(true);
// _cartWriteButton.SetEnabled(true); TODO: Not implemented
_arduinoSerialPort.SetEnabled(false);
_state = ArduinoState.Connecté;
} }
} }
@ -244,4 +250,24 @@ public class Arduino_Com : MonoBehaviour
_state = SerialPort.GetPortNames().Contains(newPort.newValue) ? ArduinoState.Déconnecté : ArduinoState.Invalide; _state = SerialPort.GetPortNames().Contains(newPort.newValue) ? ArduinoState.Déconnecté : ArduinoState.Invalide;
_arduinoControlButton.SetEnabled(_state != ArduinoState.Invalide); _arduinoControlButton.SetEnabled(_state != ArduinoState.Invalide);
} }
// Update UI during connection and when ready, prevent interacting too quickly.
IEnumerator<WaitForSeconds> DoSerialConnection()
{
_arduinoControlButton.text = "Connexion...";
_arduinoControlButton.SetEnabled(false);
_arduinoSerialPort.SetEnabled(false);
_state = ArduinoState.Connexion;
// Delay enabling transfers because the Arduino is slow to set-up the serial.
yield return new WaitForSeconds(1.5f);
_arduinoControlButton.text = "Déconnecter";
_arduinoControlButton.SetEnabled(true);
_cartLoadButton.SetEnabled(true);
// _cartWriteButton.SetEnabled(true); TODO: Not implemented
_state = ArduinoState.Connecté;
}
} }