gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
gbdk-lib/include/duck/laptop_io.h
1 #include <gbdk/platform.h>
2 #include <stdint.h>
3 #include <stdbool.h>
4
5 /** @file duck/laptop_io.h
6
7 @anchor megaduck_laptop_io_docs
8 # MegaDuck Laptop Peripheral IO support
9
10 The MegaDuck Laptop models (Spanish and German) have
11 several built-in hardware peripherals which are attached
12 via a controller that is communicated with using the
13 serial link port.
14
15 @note Using the duck_io_* functions referenced from this
16 header file will cause the duck_io_ serial interrupt
17 handler to be automatically installed.
18
19 To use any functions here, @ref duck_io_laptop_init()
20 must be called first (just once).
21
22 For the present time all of the serial operations are
23 blocking, they do not return until completed.
24 */
25
26 #ifndef _MEGADUCK_LAPTOP_IO_H
27 #define _MEGADUCK_LAPTOP_IO_H
28
29
30 // Commands sent via serial IO to the Duck laptop peripheral hardware
31 #define DUCK_IO_CMD_INIT_START 0x00u /**< Command to request starting the hardware init counter sequence process */
32 #define DUCK_IO_CMD_GET_KEYS 0x00u /**< Command to get hardware keyboard data by receiving a multi-byte packet*/
33 #define DUCK_IO_CMD_DONE_OR_OK 0x01u
34 // #define DUCK_IO_CMD_DONE_OR_OK_AND_SOMETHING 0x81u
35 #define DUCK_IO_CMD_ABORT_OR_FAIL 0x04u
36 #define DUCK_IO_CMD_PLAY_SPEECH 0x05u
37 #define DUCK_IO_CMD_RUN_CART_IN_SLOT 0x08u
38 #define DUCK_IO_CMD_PRINT_INIT_EXT_IO 0x09u /**< Command to init the printer and return status + model type */
39 #define DUCK_IO_CMD_SET_RTC 0x0Bu /**< Command to set hardware RTC by sending a multi-byte packet */
40 #define DUCK_IO_CMD_GET_RTC 0x0Cu /**< Command to get hardware RTC by receiving a a multi-byte packet */
41 #define DUCK_IO_CMD_PRINT_SEND_BYTES 0x11u /**< Send printer data */
42
43
44 // #define FF60_REG_BEFORE_XFER 0x00u
45 #define DUCK_IO_REPLY_BOOT_UNSET 0x00u
46 #define DUCK_IO_REPLY_BOOT_FAIL 0x01u
47 #define DUCK_IO_REPLY_BUFFER_XFER_OK 0x01u
48 #define DUCK_IO_REPLY_SEND_BUFFER_OK 0x03u
49 // #define DUCK_IO_REPLY_READ_FAIL_MAYBE 0x00u
50 #define DUCK_IO_REPLY_BOOT_OK 0x01u
51
52 #define DUCK_IO_LEN_KBD_GET 2u /**< Get Keyboard key payload size: 2 bytes Payload (excludes 1 length header byte, 1 byte Checksum) */
53 #define DUCK_IO_LEN_RTC_GET 8u /**< Get RTC payload size: 8 bytes Payload (excludes 1 length header byte, 1 byte Checksum) */
54 #define DUCK_IO_LEN_RTC_SET 8u /**< Set RTC payload size: 8 bytes Payload (excludes 1 length header byte, 1 byte Checksum) */
55 #define DUCK_IO_LEN_PLAY_SPEECH 1u /**< Play Speech payload size: 1 byte Payload (excludes 1 length header byte, 1 byte Checksum) */
56
57 #define DUCK_IO_REPLY_NO_CART_IN_SLOT 06u
58
59 // #define MEGADUCK_KBD_BYTE_1_EXPECT 0x0Eu
60 // #define MEGADUCK_SIO_BOOT_OK 0x01u
61
62 #define DUCK_IO_LEN_RX_MAX 14u // 13 data bytes + 1 checksum byte max reply length?
63 #define DUCK_IO_LEN_TX_MAX 14u // 13 data bytes + 1 checksum byte max reply length?
64
65 #define DUCK_IO_TIMEOUT_2_MSEC 2u // Used for hardware init counter sequence
66 #define DUCK_IO_TIMEOUT_100_MSEC 100u
67 #define DUCK_IO_TIMEOUT_200_MSEC 200u
68
69
70 // Pre-recorded Speech Samples for playback
71 #define DUCK_IO_SPEECH_CMD_MIN 1
72 #define DUCK_IO_SPEECH_CMD_MAX 6
73
74
75 // RTC packet byte ordering (all in BCD format)
76 #define DUCK_IO_RTC_YEAR 0u
77 #define DUCK_IO_RTC_MON 1u
78 #define DUCK_IO_RTC_DAY 2u
79 #define DUCK_IO_RTC_WEEKDAY 3u
80 #define DUCK_IO_RTC_AMPM 4u
81 #define DUCK_IO_RTC_HOUR 5u
82 #define DUCK_IO_RTC_MIN 6u
83 #define DUCK_IO_RTC_SEC 7u
84
85
86 // Keyboard packet byte ordering (all in BCD format)
87 #define DUCK_IO_KBD_FLAGS 0u
88 #define DUCK_IO_KBD_KEYCODE 1u
89
90
91 // Printer init reply related
92 // Init Reply Bits:1..0
93 #define DUCK_IO_PRINTER_FAIL 0x00u
94 #define DUCK_IO_PRINTER_TYPE_2_PASS 0x01u // Bit.1 = 0 // 13 x 12 byte packets + 1 x 5 or 6 byte packet (with CR and/or LF)
95 #define DUCK_IO_PRINTER_TYPE_1_PASS 0x02u // Bit.1 = 1 // 3 x 12 byte packets + 118 non-packet bytes
96 #define DUCK_IO_PRINTER_MAYBE_BUSY 0x03u // Maybe indicating that Printer Type 1 is busy?
97
98
99 extern volatile bool duck_io_rx_byte_done;
100 extern volatile uint8_t duck_io_rx_byte;
101
102
103 // TODO: change these to user supplied buffers?
104 extern uint8_t duck_io_rx_buf[DUCK_IO_LEN_RX_MAX];
105 extern uint8_t duck_io_rx_buf_len;
106
107 extern uint8_t duck_io_tx_buf[DUCK_IO_LEN_TX_MAX];
108 extern uint8_t duck_io_tx_buf_len;
109
110
111 // ===== Low level helper IO functions =====
112
113
114 // TODO: No longer in use(?)
115 //
116 // Waits for a serial transfer to complete with a timeout
117 //
118 // @param timeout_len_ms Unit size is in msec (100 is about ~ 103 msec or 6.14 frames)
119 //
120 // Serial ISR populates status var if anything was received
121 //
122 // void duck_io_wait_done_with_timeout(uint8_t timeout_len_ms);
123
124
125 /** Sends a byte over serial to the MegaDuck laptop peripheral
126
127 @param tx_byte Byte to send
128
129 */
130 void duck_io_send_byte(uint8_t tx_byte);
131
132
133 /** Reads a byte over serial from the MegaDuck laptop peripheral with NO timeout
134
135 Returns: the received byte
136
137 If there is no reply then it will hang forever
138 */
139 uint8_t duck_io_read_byte_no_timeout(void);
140
141
142 /** Prepares to receive serial data from the MegaDuck laptop peripheral
143
144 \li Sets serial IO to external clock and enables ready state.
145 \li Turns on Serial interrupt, clears any pending interrupts and
146 then turns interrupts on (state of @ref IE_REG should be
147 preserved before calling this and then restored at the end of
148 the serial communication being performed).
149 */
150 void duck_io_enable_read_byte(void);
151
152
153 /** Performs init sequence over serial with the MegaDuck laptop peripheral
154
155 Returns `true` if successful, otherwise `false`
156
157 Needs to be done *just once* any time system is powered
158 on or a cartridge is booted.
159
160 Sends count up sequence + some commands, then waits for
161 a matching count down sequence in reverse.
162 */
163 bool duck_io_laptop_init(void);
164
165
166 /** Returns status of MegaDuck Printer as last detected by duck_io_laptop_init() or duck_io_printer_query()
167
168 Should be called immediately before trying to print
169
170 Returned unsigned 8 bit value will have Printer Type
171 and Status in bits 1..0
172
173 The resulting value will be cached and used for
174 any subsequent duck_io_printer_last_status() calls.
175
176 @ref duck_io_laptop_init() must be called first
177 @see DUCK_IO_PRINTER_FAIL, DUCK_IO_PRINTER_TYPE_2_PASS, DUCK_IO_PRINTER_TYPE_1_PASS, DUCK_IO_PRINTER_MAYBE_BUSY
178 */
179 uint8_t duck_io_printer_last_status(void);
180
181
182 /** Performs a 3 x printer query serial command and returns raw system printer reply
183
184 Should be called immediately before trying to print
185
186 Returned unsigned 8 bit value will have Printer Type
187 and Status in bits 1..0
188
189 The resulting value will be cached and used for
190 any subsequent duck_io_printer_last_status() calls.
191
192 @ref duck_io_laptop_init() must be called first
193 @see duck_io_printer_last_status(), DUCK_IO_PRINTER_FAIL, DUCK_IO_PRINTER_TYPE_2_PASS, DUCK_IO_PRINTER_TYPE_1_PASS, DUCK_IO_PRINTER_MAYBE_BUSY
194 */
195 uint8_t duck_io_printer_query(void);
196
197
198 // ===== Higher level IO functions =====
199
200
201 /** Waits to receive a byte over serial from the MegaDuck laptop peripheral with a timeout
202
203 @param timeout_len_ms Unit size is in msec (100 is about ~ 103 msec or 6.14 frames)
204
205 Returns:
206 \li `true`: Success, received byte will be in `duck_io_rx_byte` global
207 \li `false`: Read timed out with no reply
208 */
209 bool duck_io_read_byte_with_msecs_timeout(uint8_t timeout_len_ms);
210
211
212 /** Sends a byte over over serial to the MegaDuck laptop peripheral and waits for a reply with a timeout
213
214 @param tx_byte Byte to send
215 @param timeout_len_ms Unit size is in msec (100 is about ~ 103 msec or 6.14 frames)
216 @param expected_reply The expected value of the reply byte
217
218 Returns:
219 \li `true`: Success
220 \li `false`: if timed out or reply byte didn't match expected value
221 */
222 bool duck_io_send_byte_and_check_ack_msecs_timeout(uint8_t tx_byte, uint8_t timeout_len_ms, uint8_t expected_reply);
223
224
225 /** Sends a command and a multi-byte buffer over serial to the MegaDuck laptop peripheral
226
227 @param io_cmd Command byte to send
228
229 The data should be pre-loaded into these globals:
230 \li @ref duck_io_tx_buf : Buffer with data to send
231 \li @ref duck_io_tx_buf_len : Number of bytes to send
232
233 Returns: `true` if succeeded
234
235 @see DUCK_IO_CMD_GET_KEYS, DUCK_IO_CMD_SET_RTC
236 */
237 bool duck_io_send_cmd_and_buffer(uint8_t io_cmd);
238
239
240 /** Sends a command and then receives a multi-byte buffer over serial from the MegaDuck laptop peripheral
241
242 @param io_cmd Command byte to send
243
244 If successful, the received data and length will be in these globals:
245 \li @ref duck_io_rx_buf : Buffer with received data
246 \li @ref duck_io_rx_buf_len : Number of bytes received
247
248 Returns: `true` if succeeded, `false` if failed (could be no reply, failed checksum, etc)
249
250 @see DUCK_IO_CMD_GET_RTC
251 */
252 bool duck_io_send_cmd_and_receive_buffer(uint8_t io_cmd);
253
254 #endif // _MEGADUCK_LAPTOP_IO_H
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.