gblink.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  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 one of the pre-configured pinouts
  115. *
  116. * @param handle Pointer to gblink handle
  117. * @param pinout Which pinout to use
  118. *
  119. * @note The gblink instance must not be gblink_start()'ed!
  120. *
  121. * @returns 0 on success, 1 if gblink instance is not gblink_stop()'ed.
  122. */
  123. int gblink_pin_set_default(void *handle, gblink_pinouts pinout);
  124. /**
  125. * Set a gpio pin to a specific pin mode
  126. *
  127. * @param handle Pointer to gblink handle
  128. * @param pin Pin mode to assign to the gpio pin
  129. * @param gpio Which gpio pin to assign the pin mode
  130. *
  131. * @note The gblink instance must not be gblink_start()'ed!
  132. *
  133. * @returns 0 on success, 1 if gblink instance is not gblink_stop()'ed.
  134. */
  135. int gblink_pin_set(void *handle, gblink_bus_pins pin, const GpioPin *gpio);
  136. /**
  137. * Get the gpio pin associated with the requested pin mode
  138. *
  139. * @param handle Pointer to gblink handle
  140. * @param pin Pin mode to inquire about
  141. *
  142. * @returns GpioPin pointer
  143. */
  144. const GpioPin *gblink_pin_get(void *handle, gblink_bus_pins pin);
  145. /**
  146. * Set a callback to call in to after each byte received
  147. *
  148. * @param handle Pointer to gblink handle
  149. * @param callback Pointer to callback function
  150. * @param cb_context Pointer to a context to pass to the callback
  151. *
  152. * @note The gblink instance must not be gblink_start()'ed!
  153. *
  154. * @note If no callback is set, then gblink_transfer_tx_wait_complete() must be
  155. * used after each call to gblink_transfer() to acquire the received data!
  156. *
  157. * @returns 0 on success, 1 if gblink instance is not gblink_stop()'ed.
  158. */
  159. int gblink_callback_set(void *handle, void (*callback)(void* cb_context, uint8_t in), void *cb_context);
  160. /**
  161. * Set the link interface mode
  162. *
  163. * @param handle Pointer to gblink handle
  164. * @param mode Mode of operation
  165. *
  166. * @note The gblink instance must not be gblink_start()'ed!
  167. *
  168. * @returns 0 on success, 1 if gblink instance is not gblink_stop()'ed.
  169. *
  170. * @deprecated Only GBLINK_MODE_GBC is used at this time.
  171. */
  172. int gblink_mode_set(void *handle, gblink_mode mode);
  173. /**
  174. * Wait for a transfer to complete
  175. *
  176. * This can be used for INT or EXT clock modes. After a call to gblink_transfer(),
  177. * this can be called at any time and will return only after a full byte is
  178. * transferred.
  179. *
  180. * @param handle Pointer to gblink handle
  181. *
  182. * @returns The last byte received from the link partner
  183. */
  184. uint8_t gblink_transfer_tx_wait_complete(void *handle);
  185. /**
  186. * Set a dummy byte to load in to TX buffer in case real data not available in time
  187. *
  188. * This is very specific to individual uses of the Link interface, but, some games
  189. * and tools have a byte that the EXT clock side can set in the TX immediately
  190. * after a byte transfer is complete. If the INT clock side sees this byte, then
  191. * it knows that the EXT clock side was not ready and can retry or do something
  192. * else.
  193. *
  194. * For example, Pokemon Gen I/II trade link interface uses 0xFE to tell the INT
  195. * clock side that data was not ready yet. The INT clock will continue to repeat
  196. * sending the same byte until the EXT clock side finally sends valid data.
  197. *
  198. * @note This is specific to what the link partner expects!
  199. */
  200. void gblink_nobyte_set(void *handle, uint8_t val);
  201. /**
  202. * Enable interrupts on gblink clock pin
  203. *
  204. * @param handle Pointer to gblink handle
  205. *
  206. * @deprecated This may go away. Use of gblink_start() and gblink_stop() are
  207. * preferred.
  208. */
  209. void gblink_int_enable(void *handle);
  210. /**
  211. * Disable interrupts on gblink clock pin
  212. *
  213. * @param handle Pointer to gblink handle
  214. *
  215. * @deprecated This may go away. Use of gblink_start() and gblink_stop() are
  216. * preferred.
  217. */
  218. void gblink_int_disable(void *handle);
  219. /**
  220. * Allocate a handle of a gblink instance
  221. *
  222. * @returns pointer to handle
  223. */
  224. void *gblink_alloc(void);
  225. /**
  226. * Free a gblink instance
  227. *
  228. * @param handle Pointer to gblink handle
  229. */
  230. void gblink_free(void *handle);
  231. /**
  232. * Start a gblink instance
  233. *
  234. * This will enable interrupts if EXT clock, as well as prevents some changes
  235. * being made. e.g. pin assignments, mode, etc.
  236. *
  237. * @param handle Pointer to gblink handle
  238. */
  239. void gblink_start(void *handle);
  240. /**
  241. * Stop a gblink instance
  242. *
  243. * Disables interrupts, stops any pending timers, and enters back to an idle
  244. * state. Once called, re-allows changes to be made.
  245. *
  246. * @param handle Pointer to gblink handle
  247. */
  248. void gblink_stop(void *handle);
  249. // void gblink_blink_led_on_byte(handle, color?)
  250. // get blink?
  251. #ifdef __cplusplus
  252. }
  253. #endif
  254. #endif // __GBLINK_H__