Obsługa protokołu SIO przez urządzenie peryferyjne
From Atariki
(Różnice między wersjami)
Wersja z dnia 16:01, 25 maj 2024 Mono (Dyskusja | wkład) (→Kod dla mikrokontolera AVR (Arduino) - kosmetyka) ← Previous diff |
Wersja z dnia 16:04, 25 maj 2024 Mono (Dyskusja | wkład) (→Kod dla mikrokontolera AVR (Arduino) - usunięte komentarze zw. z prototypem) Next diff → |
||
Linia 35: | Linia 35: | ||
SIO CMD structure: | SIO CMD structure: | ||
Byte: | Byte: | ||
- | RxBuffer[0] - SIO device identifier and unit number | + | RxBuffer[0] - SIO device identifier and unit number |
- | RxBuffer[1] - COMMAND, for future use, | + | RxBuffer[1] - COMMAND |
- | RxBuffer[2] - DAUX1, for future use, | + | RxBuffer[2] - DAUX1 |
- | RxBuffer[3] - DAUX2, for future use, | + | RxBuffer[3] - DAUX2 |
- | RxBuffer[4] - checksum. | + | RxBuffer[4] - checksum |
SIO DATA structure: | SIO DATA structure: | ||
- | RxBuffer[0] - data, | + | RxBuffer[0] - data |
- | RxBuffer[1] - data, | + | RxBuffer[1] - data |
... | ... | ||
... | ... | ||
- | RxBuffer[RxDataSize-1] - data, | + | RxBuffer[RxDataSize-1] - data |
- | RxBuffer[RxDataSize] - checksum. | + | RxBuffer[RxDataSize] - checksum |
*/ | */ | ||
Wersja z dnia 16:04, 25 maj 2024
Dane jest urządzenie peryferyjne o identyfikatorze $40 obsługujące rozkaz 'W' ($57), dla którego odbiera 8 bajtów danych i realizuje jakąś operację.
Kod dla Atari
lda #$40 sta DDEVIC ;$300 lda #$01 sta DUNIT ;$301 lda #'W' sta DCMND ;$302 lda #$80 sta DSTATS ;$303 lda #<buffer sta DBUFA ;$304 lda #>buffer sta DBUFA+1 lda #$07 sta DTIMLO ;$306 lda #<8 sta DBUFL ;$308 lda #>8 sta DBUFL+1 lda #$00 sta DAUX1 ;$30A lda #$00 sta DAUX2 ;$30B jsr SIOV ;$E459 bmi ?error
Kod dla mikrokontolera AVR (Arduino)
/* SIO CMD structure: Byte: RxBuffer[0] - SIO device identifier and unit number RxBuffer[1] - COMMAND RxBuffer[2] - DAUX1 RxBuffer[3] - DAUX2 RxBuffer[4] - checksum SIO DATA structure: RxBuffer[0] - data RxBuffer[1] - data ... ... RxBuffer[RxDataSize-1] - data RxBuffer[RxDataSize] - checksum */ /* Arduino hardware settings */ #define PIN_SIOCOMMAND 2 // ATARI SIO-COMMAND Pin #define SIO Serial1 // ATARI SIO-Serial interface // ---------------------------------------- /* Global define */ #define RxCmdSize 4 // size of command frame (w/o checksum byte) #define RxDataSize 8 // size of data frame (w/o checksum byte) #define DEVICE_ID 0x40 // SIO device identifier and unit number #define COMMAND_ID 'W' // SIO operation command /* Global Variable */ uint8_t RxBuffer[8+1]; uint8_t RxSum; void setup() { pinMode(PIN_SIOCOMMAND, INPUT_PULLUP); SIO.begin(19200); } void loop() { while (1) { //wait for COMMAND line is LOW while (digitalRead(PIN_SIOCOMMAND) != 0) ; //receive command frame and calculate checksum RxSum = ReceiveData(RxBuffer, RxCmdSize+1); //wait for COMMAND line is HIGH while (digitalRead(PIN_SIOCOMMAND) == 0) ; //verify device identifier if (RxBuffer[0] == DEVICE_ID) { //check command checksum if (RxSum == RxBuffer[RxCmdSize]) { //check command identifier if (RxBuffer[1] == COMMAND_ID) { //-- check or process auxiliary bytes RxBuffer[2] and RxBuffer[3] when needed //... //... //-- end of aux data processing ---------------------------------------- //send ACK and continue receive data delayMicroseconds(1000); SIO.write('A'); SIO.flush(); //receive data frame RxSum = ReceiveData(RxBuffer, RxDataSize+1); if (RxSum == RxBuffer[RxDataSize]) { //send ACK delayMicroseconds(1000); SIO.write('A'); SIO.flush(); //-- start operation according to received command and data //... //... //-- end of operation ---------------------------------------- //then send operation COMPLETE delayMicroseconds(250); SIO.write('C'); SIO.flush(); } else { //send NAK because of wrong data frame checksum delayMicroseconds(1000); SIO.write('N'); SIO.flush(); //then send operation ERROR delayMicroseconds(250); SIO.write('E'); SIO.flush(); } } else { //send NAK because of not supported command delayMicroseconds(1000); SIO.write('N'); SIO.flush(); } } else { //send NAK because of wrong command frame checksum delayMicroseconds(1000); SIO.write('N'); SIO.flush(); } } } } //functions uint8_t ReceiveData(uint8_t *buffer, uint8_t length) { u8 cnt = 0; int sum = 0; cnt = SIO.readBytes(buffer,length); if (cnt == length) { for (cnt = 0; cnt < length-1; cnt++) { sum += buffer[cnt]; if (sum >= 256) { sum = (sum - 256) + 1; // add carry into sum } } } return sum; }