Просмотр исходного кода

gblink_pinconf: create new unit for handling pinconf

Split off from gblink functions. Will need to create a handful of
different and more advanced pinconf handling functions so it is
going to be ideal in the long run to split this out.

Moves the struct gblink definition to gblink_i.h so the pinconf
unit can directly access parts of the struct.

Signed-off-by: Kris Bahnsen <Kris@KBEmbedded.com>
Kris Bahnsen 1 год назад
Родитель
Сommit
a008ea298d
5 измененных файлов с 276 добавлено и 235 удалено
  1. 3 191
      gblink/gblink.c
  2. 80 0
      gblink/gblink_i.h
  3. 129 0
      gblink/gblink_pinconf.c
  4. 0 44
      gblink/include/gblink.h
  5. 64 0
      gblink/include/gblink_pinconf.h

+ 3 - 191
gblink/gblink.c

@@ -9,105 +9,12 @@
 #include <stdint.h>
 
 #include <gblink/include/gblink.h>
+#include <gblink/include/gblink_pinconf.h>
+
+#include "gblink_i.h"
 #include "exti_workaround_i.h"
 #include "clock_timer_i.h"
 
-struct gblink_pins {
-        const GpioPin *serin;
-        const GpioPin *serout;
-        const GpioPin *clk;
-        const GpioPin *sd;
-};
-
-const struct gblink_pins common_pinouts[PINOUT_COUNT] = {
-	/* Original */
-	{
-		&gpio_ext_pc3,
-		&gpio_ext_pb3,
-		&gpio_ext_pb2,
-		&gpio_ext_pa4,
-	},
-	/* MALVEKE EXT1 */
-	{
-		&gpio_ext_pa6,
-		&gpio_ext_pa7,
-		&gpio_ext_pb3,
-		&gpio_ext_pa4,
-	},
-};
-
-struct gblink {
-	const GpioPin *serin;
-	const GpioPin *serout;
-	const GpioPin *clk;
-	const GpioPin *sd;
-	gblink_mode mode;
-	void (*callback)(void* cb_context, uint8_t in);
-	void *cb_context;
-
-	/* These two semaphores serve similar but distinct purposes. */
-	/* The transfer semaphore is taken as soon as a transfer() request
-	 * has been started. This is used in the function to wait until the
-	 * transfer has been completed.
-	 */
-	FuriSemaphore *transfer_sem;
-	/* The out byte semaphore is used to indicate that a byte transfer
-	 * is in progress. This is used in the transfer function to not allow
-	 * a transfer request if we're in the middle of sending a byte.
-	 * The transfer semaphore is not used for that purpose since if the
-	 * Flipper is in EXT clk mode, once a transfer() is started, there
-	 * would be no way to both prevent transfer() from being called again
-	 * as well as cancelling/changing what we're wanting to send. Using
-	 * out byte semaphore means a transfer() can be called at any time,
-	 * waited on synchronously for a timeout, and then re-called at a
-	 * later time; while blocking that update if a byte is actually
-	 * in the middle of being transmitted.
-	 */
-	FuriSemaphore *out_byte_sem;
-
-	/* Used to lock out changing things after a certain point. Pinout,
-	 * mode, etc.
-	 * XXX: Might make more sense to use the mutex to protect a flag?
-	 * Maybe a semaphore? Though I think that is the wrong use.
-	 */
-	FuriMutex *start_mutex;
-
-	/* 
-	 * The following should probably have the world stopped around them
-	 * if not modified in an interrupt context.
-	 */
-	uint8_t in;
-	uint8_t out;
-	uint8_t shift;
-	uint8_t nobyte;
-
-	/* Should only be changed when not in middle of tx, will affect a lot */
-	gblink_clk_source source;
-
-	/* Can be changed at any time, will only take effect on the next
-	 * transfer.
-	 */
-	gblink_speed speed;
-
-
-	/* 
-	 * The following is based on observing Pokemon trade data
-	 *
-	 * Clocks idle between bytes is nominally 430 us long for burst data,
-	 * 15 ms for idle polling (e.g. waiting for menu selection), some oddball
-	 * 2 ms gaps that appears between one 0xFE byte from the Game Boy every trade;
-	 * clock period is nominally 122 us.
-	 *
-	 * Therefore, if we haven't seen a clock in 500 us, reset our bit counter.
-	 * Note that, this should never actually be a concern, but it is an additional
-	 * safeguard against desyncing.
-	 */
-	uint32_t time;
-	uint32_t bitclk_timeout_us;
-
-	void *exti_workaround_handle;
-};
-
 static inline bool gblink_transfer_in_progress(struct gblink *gblink)
 {
 	return !(furi_semaphore_get_count(gblink->out_byte_sem));
@@ -272,101 +179,6 @@ void gblink_timeout_set(void *handle, uint32_t us)
 	gblink->bitclk_timeout_us = us;
 }
 
-int gblink_pin_set(void *handle, gblink_bus_pins pin, const GpioPin *gpio)
-{
-	furi_assert(handle);
-	struct gblink *gblink = handle;
-
-	if (furi_mutex_acquire(gblink->start_mutex, 0) != FuriStatusOk)
-		return 1;
-
-	switch (pin) {
-	case PIN_SERIN:
-		gblink->serin = gpio;
-		break;
-	case PIN_SEROUT:
-		gblink->serout = gpio;
-		break;
-	case PIN_CLK:
-		gblink->clk = gpio;
-		break;
-	case PIN_SD:
-		gblink->sd = gpio;
-		break;
-	default:
-		furi_crash();
-		break;
-	}
-
-	furi_mutex_release(gblink->start_mutex);
-
-	return 0;
-}
-
-int gblink_pin_set_default(void *handle, gblink_pinouts pinout)
-{
-	furi_assert(handle);
-	struct gblink *gblink = handle;
-
-	if (furi_mutex_acquire(gblink->start_mutex, 0) != FuriStatusOk)
-		return 1;
-
-	gblink->serin = common_pinouts[pinout].serin;
-	gblink->serout = common_pinouts[pinout].serout;
-	gblink->clk = common_pinouts[pinout].clk;
-	gblink->sd = common_pinouts[pinout].sd;
-
-	furi_mutex_release(gblink->start_mutex);
-
-	return 0;
-}
-
-int gblink_pin_get_default(void *handle)
-{
-	furi_assert(handle);
-	struct gblink *gblink = handle;
-	int i;
-
-	for (i = 0; i < PINOUT_COUNT; i++) {
-		if (gblink->serin != common_pinouts[i].serin)
-			continue;
-		if (gblink->serout != common_pinouts[i].serout)
-			continue;
-		if (gblink->clk != common_pinouts[i].clk)
-			continue;
-		/* XXX: Currently not checked or used! */
-		//if (gblink->sd != common_pinouts[pinout].sd;
-		break;
-	}
-
-	if (i == PINOUT_COUNT)
-		i = -1;
-
-	return i;
-}
-
-const GpioPin *gblink_pin_get(void *handle, gblink_bus_pins pin)
-{
-	furi_assert(handle);
-	struct gblink *gblink = handle;
-
-	switch (pin) {
-	case PIN_SERIN:
-		return gblink->serin;
-	case PIN_SEROUT:
-		return gblink->serout;
-	case PIN_CLK:
-		return gblink->clk;
-	case PIN_SD:
-		return gblink->sd;
-	default:
-		furi_crash();
-		break;
-	}
-
-	return NULL;
-}
-
 int gblink_callback_set(void *handle, void (*callback)(void* cb_context, uint8_t in), void *cb_context)
 {
 	furi_assert(handle);

+ 80 - 0
gblink/gblink_i.h

@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: BSD-2-Clause
+// Copyright (c) 2024 KBEmbedded
+
+#include <furi.h>
+#include <furi_hal.h>
+#include <stdint.h>
+
+#include <gblink/include/gblink.h>
+
+struct gblink {
+	const GpioPin *serin;
+	const GpioPin *serout;
+	const GpioPin *clk;
+	const GpioPin *sd;
+	gblink_mode mode;
+	void (*callback)(void* cb_context, uint8_t in);
+	void *cb_context;
+
+	/* These two semaphores serve similar but distinct purposes. */
+	/* The transfer semaphore is taken as soon as a transfer() request
+	 * has been started. This is used in the function to wait until the
+	 * transfer has been completed.
+	 */
+	FuriSemaphore *transfer_sem;
+	/* The out byte semaphore is used to indicate that a byte transfer
+	 * is in progress. This is used in the transfer function to not allow
+	 * a transfer request if we're in the middle of sending a byte.
+	 * The transfer semaphore is not used for that purpose since if the
+	 * Flipper is in EXT clk mode, once a transfer() is started, there
+	 * would be no way to both prevent transfer() from being called again
+	 * as well as cancelling/changing what we're wanting to send. Using
+	 * out byte semaphore means a transfer() can be called at any time,
+	 * waited on synchronously for a timeout, and then re-called at a
+	 * later time; while blocking that update if a byte is actually
+	 * in the middle of being transmitted.
+	 */
+	FuriSemaphore *out_byte_sem;
+
+	/* Used to lock out changing things after a certain point. Pinout,
+	 * mode, etc.
+	 * XXX: Might make more sense to use the mutex to protect a flag?
+	 * Maybe a semaphore? Though I think that is the wrong use.
+	 */
+	FuriMutex *start_mutex;
+
+	/*
+	 * The following should probably have the world stopped around them
+	 * if not modified in an interrupt context.
+	 */
+	uint8_t in;
+	uint8_t out;
+	uint8_t shift;
+	uint8_t nobyte;
+
+	/* Should only be changed when not in middle of tx, will affect a lot */
+	gblink_clk_source source;
+
+	/* Can be changed at any time, will only take effect on the next
+	 * transfer.
+	 */
+	gblink_speed speed;
+
+
+	/*
+	 * The following is based on observing Pokemon trade data
+	 *
+	 * Clocks idle between bytes is nominally 430 us long for burst data,
+	 * 15 ms for idle polling (e.g. waiting for menu selection), some oddball
+	 * 2 ms gaps that appears between one 0xFE byte from the Game Boy every trade;
+	 * clock period is nominally 122 us.
+	 *
+	 * Therefore, if we haven't seen a clock in 500 us, reset our bit counter.
+	 * Note that, this should never actually be a concern, but it is an additional
+	 * safeguard against desyncing.
+	 */
+	uint32_t time;
+	uint32_t bitclk_timeout_us;
+
+	void *exti_workaround_handle;
+};

+ 129 - 0
gblink/gblink_pinconf.c

@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: BSD-2-Clause
+// Copyright (c) 2023 KBEmbedded
+
+#include <furi.h>
+#include <furi_hal.h>
+
+#include <stdint.h>
+
+#include <gblink/include/gblink.h>
+#include "gblink_i.h"
+
+struct gblink_pins {
+        const GpioPin *serin;
+        const GpioPin *serout;
+        const GpioPin *clk;
+        const GpioPin *sd;
+};
+
+const struct gblink_pins common_pinouts[PINOUT_COUNT] = {
+	/* Original */
+	{
+		&gpio_ext_pc3,
+		&gpio_ext_pb3,
+		&gpio_ext_pb2,
+		&gpio_ext_pa4,
+	},
+	/* MALVEKE EXT1 */
+	{
+		&gpio_ext_pa6,
+		&gpio_ext_pa7,
+		&gpio_ext_pb3,
+		&gpio_ext_pa4,
+	},
+};
+
+int gblink_pin_set(void *handle, gblink_bus_pins pin, const GpioPin *gpio)
+{
+	furi_assert(handle);
+	struct gblink *gblink = handle;
+
+	if (furi_mutex_acquire(gblink->start_mutex, 0) != FuriStatusOk)
+		return 1;
+
+	switch (pin) {
+	case PIN_SERIN:
+		gblink->serin = gpio;
+		break;
+	case PIN_SEROUT:
+		gblink->serout = gpio;
+		break;
+	case PIN_CLK:
+		gblink->clk = gpio;
+		break;
+	case PIN_SD:
+		gblink->sd = gpio;
+		break;
+	default:
+		furi_crash();
+		break;
+	}
+
+	furi_mutex_release(gblink->start_mutex);
+
+	return 0;
+}
+
+const GpioPin *gblink_pin_get(void *handle, gblink_bus_pins pin)
+{
+	furi_assert(handle);
+	struct gblink *gblink = handle;
+
+	switch (pin) {
+	case PIN_SERIN:
+		return gblink->serin;
+	case PIN_SEROUT:
+		return gblink->serout;
+	case PIN_CLK:
+		return gblink->clk;
+	case PIN_SD:
+		return gblink->sd;
+	default:
+		furi_crash();
+		break;
+	}
+
+	return NULL;
+}
+
+int gblink_pin_set_default(void *handle, gblink_pinouts pinout)
+{
+	furi_assert(handle);
+	struct gblink *gblink = handle;
+
+	if (furi_mutex_acquire(gblink->start_mutex, 0) != FuriStatusOk)
+		return 1;
+
+	gblink->serin = common_pinouts[pinout].serin;
+	gblink->serout = common_pinouts[pinout].serout;
+	gblink->clk = common_pinouts[pinout].clk;
+	gblink->sd = common_pinouts[pinout].sd;
+
+	furi_mutex_release(gblink->start_mutex);
+
+	return 0;
+}
+
+int gblink_pin_get_default(void *handle)
+{
+	furi_assert(handle);
+	struct gblink *gblink = handle;
+	int i;
+
+	for (i = 0; i < PINOUT_COUNT; i++) {
+		if (gblink->serin != common_pinouts[i].serin)
+			continue;
+		if (gblink->serout != common_pinouts[i].serout)
+			continue;
+		if (gblink->clk != common_pinouts[i].clk)
+			continue;
+		/* XXX: Currently not checked or used! */
+		//if (gblink->sd != common_pinouts[pinout].sd;
+		break;
+	}
+
+	if (i == PINOUT_COUNT)
+		i = -1;
+
+	return i;
+}

+ 0 - 44
gblink/include/gblink.h

@@ -124,50 +124,6 @@ void gblink_timeout_set(void *handle, uint32_t us);
  */
 bool gblink_transfer(void *handle, uint8_t val);
 
-/**
- * Set one of the pre-configured pinouts
- *
- * @param handle Pointer to gblink handle
- * @param pinout Which pinout to use
- *
- * @note The gblink instance must not be gblink_start()'ed!
- *
- * @returns 0 on success, 1 if gblink instance is not gblink_stop()'ed.
- */
-int gblink_pin_set_default(void *handle, gblink_pinouts pinout);
-
-/**
- * Check if the pinout set matches a pre-configured one
- *
- * @param handle Pointer to gblink handle
- *
- * @returns The index of the pre-configured pinout or -1 on error
- */
-int gblink_pin_get_default(void *handle);
-
-/**
- * Set a gpio pin to a specific pin mode
- *
- * @param handle Pointer to gblink handle
- * @param pin Pin mode to assign to the gpio pin
- * @param gpio Which gpio pin to assign the pin mode
- *
- * @note The gblink instance must not be gblink_start()'ed!
- *
- * @returns 0 on success, 1 if gblink instance is not gblink_stop()'ed.
- */
-int gblink_pin_set(void *handle, gblink_bus_pins pin, const GpioPin *gpio);
-
-/**
- * Get the gpio pin associated with the requested pin mode
- *
- * @param handle Pointer to gblink handle
- * @param pin Pin mode to inquire about
- *
- * @returns GpioPin pointer
- */
-const GpioPin *gblink_pin_get(void *handle, gblink_bus_pins pin);
-
 /**
  * Set a callback to call in to after each byte received
  *

+ 64 - 0
gblink/include/gblink_pinconf.h

@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: BSD-2-Clause
+// Copyright (c) 2023 KBEmbedded
+
+#ifndef __GBLINK_PINCONF_H__
+#define __GBLINK_PINCONF_H__
+
+#pragma once
+
+#include <furi.h>
+#include <furi_hal.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Set one of the pre-configured pinouts
+ *
+ * @param handle Pointer to gblink handle
+ * @param pinout Which pinout to use
+ *
+ * @note The gblink instance must not be gblink_start()'ed!
+ *
+ * @returns 0 on success, 1 if gblink instance is not gblink_stop()'ed.
+ */
+int gblink_pin_set_default(void *handle, gblink_pinouts pinout);
+
+/**
+ * Check if the pinout set matches a pre-configured one
+ *
+ * @param handle Pointer to gblink handle
+ *
+ * @returns The index of the pre-configured pinout or -1 on error
+ */
+int gblink_pin_get_default(void *handle);
+
+/**
+ * Set a gpio pin to a specific pin mode
+ *
+ * @param handle Pointer to gblink handle
+ * @param pin Pin mode to assign to the gpio pin
+ * @param gpio Which gpio pin to assign the pin mode
+ *
+ * @note The gblink instance must not be gblink_start()'ed!
+ *
+ * @returns 0 on success, 1 if gblink instance is not gblink_stop()'ed.
+ */
+int gblink_pin_set(void *handle, gblink_bus_pins pin, const GpioPin *gpio);
+
+/**
+ * Get the gpio pin associated with the requested pin mode
+ *
+ * @param handle Pointer to gblink handle
+ * @param pin Pin mode to inquire about
+ *
+ * @returns GpioPin pointer
+ */
+const GpioPin *gblink_pin_get(void *handle, gblink_bus_pins pin);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __GBLINK_PINCONF_H__