gblink.h 6.7 KB

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