git.y1.nz

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.