gblink.h 7.9 KB

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