gblink.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. // SPDX-License-Identifier: BSD-2-Clause
  2. // Copyright (c) 2023 KBEmbedded
  3. #ifndef __GBLINK_H__
  4. #define __GBLINK_H__
  5. #pragma once
  6. #include <furi.h>
  7. #include <furi_hal.h>
  8. #include <stdint.h>
  9. #ifdef __cplusplus
  10. extern "C" {
  11. #endif
  12. /** \enum gblink_clk_source
  13. * \brief Clock sources available
  14. */
  15. typedef enum {
  16. //! Flipper generates the clock internally
  17. GBLINK_CLK_INT,
  18. //! Flipper expects a clock input
  19. GBLINK_CLK_EXT,
  20. } gblink_clk_source;
  21. /**
  22. * Currently unused
  23. */
  24. typedef enum {
  25. GBLINK_MODE_GBC,
  26. GBLINK_MODE_GBA,
  27. } gblink_mode;
  28. /**
  29. * When using GBLINK_CLK_INT, the rate at which the Flipper drives the clock
  30. *
  31. * Specified speed does not matter if GBLINK_CLK_EXT.
  32. *
  33. * Anything above GBLINK_SPD_8192HZ only applies to GBC. The original DMG
  34. * and pocket variants of the Game Boy _can_ receive at higher rates, but
  35. * it may have issues.
  36. */
  37. typedef enum {
  38. GBLINK_SPD_8192HZ = 4096,
  39. GBLINK_SPD_16384HZ = 8192,
  40. GBLINK_SPD_262144HZ = 16384,
  41. GBLINK_SPD_524288HZ = 262144,
  42. } gblink_speed;
  43. typedef enum {
  44. PINOUT_ORIGINAL,
  45. PINOUT_MALVEKE_EXT1,
  46. PINOUT_COUNT,
  47. } gblink_pinouts;
  48. typedef enum {
  49. PIN_SERIN,
  50. PIN_SEROUT,
  51. PIN_CLK,
  52. PIN_SD,
  53. PIN_COUNT,
  54. } gblink_bus_pins;
  55. /**
  56. * Set the clock source for transfer, internal or external.
  57. *
  58. * @param handle Pointer to gblink handle
  59. * @param clk_source Specify Flipper expects an internal or external clock
  60. *
  61. * @note This can be called at any time, it will reset the current byte transfer
  62. * if called mid-transfer.
  63. */
  64. void gblink_clk_source_set(void *handle, gblink_clk_source clk_source);
  65. /**
  66. * Set the clock rate for GBLINK_CLK_INT transfer
  67. *
  68. * @param handle Pointer to gblink handle
  69. * @param speed Clock rate to be used
  70. *
  71. * @note This can be called at any time, changes will take effect on the next
  72. * byte transfer start.
  73. *
  74. * @note This can be arbitrary if really needed, the value passed needs to be
  75. * the desired frequency in Hz/2. e.g. passing 512 will result in a 1 kHz clock.
  76. */
  77. void gblink_speed_set(void *handle, gblink_speed speed);
  78. /**
  79. * Set up an inter-bit timeout
  80. *
  81. * Specify a timeout in microseconds that, when exceeded, will reset the transfer
  82. * state machine. If a transfer is interrupted or errant clocks are received when
  83. * connecting/disconnecting the Link Cable, this will ensure the state machine
  84. * gets reset with the start of the next clock.
  85. *
  86. * @note This can apply to GBLINK_CLK_INT, but only if there are significant
  87. * issues, e.g. the CPU is starved too long and the timer doesn't get called
  88. * in a reasonable amount of time.
  89. *
  90. * @note This defaults to 500 us if unset.
  91. *
  92. * @param handle Pointer to gblink handle
  93. * @param us Inter-bit timeout to set in microseconds.
  94. */
  95. void gblink_timeout_set(void *handle, uint32_t us);
  96. /**
  97. * Set up a data transfer
  98. *
  99. * When in GBLINK_CLK_INT, this initiates a transfer immediately.
  100. * When in GBLINK_CLK_EXT, this pre-loads data to transmit to the link partner.
  101. *
  102. * In both cases, the call is non-blocking and the transfer will happen
  103. * asynchronously. If a blocking call is needed, then gblink_transfer_tx_wait_complete()
  104. * should be called immediately after.
  105. *
  106. * @param handle Pointer to gblink handle
  107. * @param val 8-bit value to transmit
  108. *
  109. * @returns true if TX data was properly set up to transmit, false if there
  110. * was an error or a transfer is in progress already.
  111. */
  112. bool gblink_transfer(void *handle, uint8_t val);
  113. /**
  114. * Set a callback to call in to after each byte received
  115. *
  116. * @param handle Pointer to gblink handle
  117. * @param callback Pointer to callback function
  118. * @param cb_context Pointer to a context to pass to the callback
  119. *
  120. * @note The gblink instance must not be gblink_start()'ed!
  121. *
  122. * @note If no callback is set, then gblink_transfer_tx_wait_complete() must be
  123. * used after each call to gblink_transfer() to acquire the received data!
  124. *
  125. * @returns 0 on success, 1 if gblink instance is not gblink_stop()'ed.
  126. */
  127. int gblink_callback_set(void *handle, void (*callback)(void* cb_context, uint8_t in), void *cb_context);
  128. /**
  129. * Set the link interface mode
  130. *
  131. * @param handle Pointer to gblink handle
  132. * @param mode Mode of operation
  133. *
  134. * @note The gblink instance must not be gblink_start()'ed!
  135. *
  136. * @returns 0 on success, 1 if gblink instance is not gblink_stop()'ed.
  137. *
  138. * @deprecated Only GBLINK_MODE_GBC is used at this time.
  139. */
  140. int gblink_mode_set(void *handle, gblink_mode mode);
  141. /**
  142. * Wait for a transfer to complete
  143. *
  144. * This can be used for INT or EXT clock modes. After a call to gblink_transfer(),
  145. * this can be called at any time and will return only after a full byte is
  146. * transferred.
  147. *
  148. * @param handle Pointer to gblink handle
  149. *
  150. * @returns The last byte received from the link partner
  151. */
  152. uint8_t gblink_transfer_tx_wait_complete(void *handle);
  153. /**
  154. * Set a dummy byte to load in to TX buffer in case real data not available in time
  155. *
  156. * This is very specific to individual uses of the Link interface, but, some games
  157. * and tools have a byte that the EXT clock side can set in the TX immediately
  158. * after a byte transfer is complete. If the INT clock side sees this byte, then
  159. * it knows that the EXT clock side was not ready and can retry or do something
  160. * else.
  161. *
  162. * For example, Pokemon Gen I/II trade link interface uses 0xFE to tell the INT
  163. * clock side that data was not ready yet. The INT clock will continue to repeat
  164. * sending the same byte until the EXT clock side finally sends valid data.
  165. *
  166. * @note This is specific to what the link partner expects!
  167. */
  168. void gblink_nobyte_set(void *handle, uint8_t val);
  169. /**
  170. * Enable interrupts on gblink clock pin
  171. *
  172. * @param handle Pointer to gblink handle
  173. *
  174. * @deprecated This may go away. Use of gblink_start() and gblink_stop() are
  175. * preferred.
  176. */
  177. void gblink_int_enable(void *handle);
  178. /**
  179. * Disable interrupts on gblink clock pin
  180. *
  181. * @param handle Pointer to gblink handle
  182. *
  183. * @deprecated This may go away. Use of gblink_start() and gblink_stop() are
  184. * preferred.
  185. */
  186. void gblink_int_disable(void *handle);
  187. /**
  188. * Allocate a handle of a gblink instance
  189. *
  190. * @returns pointer to handle
  191. */
  192. void *gblink_alloc(void);
  193. /**
  194. * Free a gblink instance
  195. *
  196. * @param handle Pointer to gblink handle
  197. */
  198. void gblink_free(void *handle);
  199. /**
  200. * Start a gblink instance
  201. *
  202. * This will enable interrupts if EXT clock, as well as prevents some changes
  203. * being made. e.g. pin assignments, mode, etc.
  204. *
  205. * @param handle Pointer to gblink handle
  206. */
  207. void gblink_start(void *handle);
  208. /**
  209. * Stop a gblink instance
  210. *
  211. * Disables interrupts, stops any pending timers, and enters back to an idle
  212. * state. Once called, re-allows changes to be made.
  213. *
  214. * @param handle Pointer to gblink handle
  215. */
  216. void gblink_stop(void *handle);
  217. // void gblink_blink_led_on_byte(handle, color?)
  218. // get blink?
  219. #ifdef __cplusplus
  220. }
  221. #endif
  222. #endif // __GBLINK_H__