Skip to content

Commit

Permalink
Merge branch 'feature/parlio_rx_driver' into 'master'
Browse files Browse the repository at this point in the history
driver: add parallel IO RX driver

Closes IDF-7002 and IDF-6984

See merge request espressif/esp-idf!23488
  • Loading branch information
L-KAYA committed Dec 29, 2023
2 parents 1dfa401 + db7e90f commit 83d5797
Show file tree
Hide file tree
Showing 56 changed files with 3,613 additions and 185 deletions.
4 changes: 3 additions & 1 deletion components/driver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ endif()

# Parallel IO related source files
if(CONFIG_SOC_PARLIO_SUPPORTED)
list(APPEND srcs "parlio/parlio_common.c" "parlio/parlio_tx.c")
list(APPEND srcs "parlio/parlio_common.c"
"parlio/parlio_tx.c"
"parlio/parlio_rx.c")
endif()

# GPTimer legacy driver
Expand Down
334 changes: 334 additions & 0 deletions components/driver/parlio/include/driver/parlio_rx.h

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions components/driver/parlio/include/driver/parlio_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ extern "C" {
*/
typedef struct parlio_tx_unit_t *parlio_tx_unit_handle_t;

/**
* @brief Type of Parallel IO RX unit handle
*/
typedef struct parlio_rx_unit_t *parlio_rx_unit_handle_t;

/**
* @brief Type of Parallel IO RX frame delimiter handle
*/
typedef struct parlio_rx_delimiter_t *parlio_rx_delimiter_handle_t;

#ifdef __cplusplus
}
#endif
59 changes: 59 additions & 0 deletions components/driver/parlio/parlio_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,62 @@ void parlio_release_group_handle(parlio_group_t *group)
ESP_LOGD(TAG, "del group(%d)", group_id);
}
}

esp_err_t parlio_register_unit_to_group(parlio_unit_base_handle_t unit)
{
parlio_group_t *group = NULL;
int unit_id = -1;
for (int i = 0; i < SOC_PARLIO_GROUPS; i++) {
group = parlio_acquire_group_handle(i);
parlio_unit_base_handle_t *group_unit = NULL;
ESP_RETURN_ON_FALSE(group, ESP_ERR_NO_MEM, TAG, "no memory for group (%d)", i);
portENTER_CRITICAL(&group->spinlock);
if (unit->dir == PARLIO_DIR_TX) {
for (int j = 0; j < SOC_PARLIO_TX_UNITS_PER_GROUP; j++) {
group_unit = &group->tx_units[j];
if (*group_unit == NULL) {
*group_unit = unit;
unit_id = j;
break;
}
}
} else {
for (int j = 0; j < SOC_PARLIO_RX_UNITS_PER_GROUP; j++) {
group_unit = &group->rx_units[j];
if (*group_unit == NULL) {
*group_unit = unit;
unit_id = j;
break;
}
}
}
portEXIT_CRITICAL(&group->spinlock);
if (unit_id < 0) {
/* didn't find a free unit slot in the group */
parlio_release_group_handle(group);
group = NULL;
} else {
unit->unit_id = unit_id;
unit->group = group;
break;
}
}
ESP_RETURN_ON_FALSE(unit_id >= 0, ESP_ERR_NOT_FOUND, TAG,
"no free %s unit", unit->dir == PARLIO_DIR_TX ? "tx" : "rx");
return ESP_OK;
}

void parlio_unregister_unit_from_group(parlio_unit_base_handle_t unit)
{
assert(unit);
parlio_group_t *group = unit->group;
portENTER_CRITICAL(&group->spinlock);
if (unit->dir == PARLIO_DIR_TX) {
group->tx_units[unit->unit_id] = NULL;
} else {
group->rx_units[unit->unit_id] = NULL;
}
portEXIT_CRITICAL(&group->spinlock);
/* the parlio unit has a reference of the group, release it now */
parlio_release_group_handle(group);
}
44 changes: 38 additions & 6 deletions components/driver/parlio/parlio_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ enum {
PARLIO_TX_QUEUE_MAX,
};

typedef enum {
PARLIO_DIR_TX,
PARLIO_DIR_RX,
} parlio_dir_t;

typedef enum {
PARLIO_TX_FSM_INIT_WAIT,
PARLIO_TX_FSM_INIT,
Expand All @@ -93,16 +98,43 @@ typedef enum {
PARLIO_TX_FSM_RUN,
} parlio_tx_fsm_t;

typedef struct parlio_unit_t *parlio_unit_base_handle_t;

typedef struct parlio_group_t {
int group_id; // group ID, index from 0
portMUX_TYPE spinlock; // to protect per-group register level concurrent access
parlio_hal_context_t hal; // hal layer for each group
parlio_tx_unit_handle_t tx_units[SOC_PARLIO_TX_UNITS_PER_GROUP]; // tx unit handles
int group_id; // group ID, index from 0
portMUX_TYPE spinlock; // to protect per-group register level concurrent access
parlio_hal_context_t hal; // hal layer for each group
parlio_unit_base_handle_t tx_units[SOC_PARLIO_TX_UNITS_PER_GROUP]; // tx unit handles
parlio_unit_base_handle_t rx_units[SOC_PARLIO_RX_UNITS_PER_GROUP]; // rx unit handles
} parlio_group_t;

parlio_group_t *parlio_acquire_group_handle(int group_id);
/**
* @brief The common field of rx and tx unit structure
*
*/
struct parlio_unit_t {
int unit_id; // unit id
parlio_dir_t dir;
parlio_group_t *group; // group handle
};

void parlio_release_group_handle(parlio_group_t *group);
/**
* @brief Register the rx or tx unit to the parlio group
*
* @param[in] unit The TX/RX unit base handle
* @return
* - ESP_ERR_NO_MEM No memory for the unit
* - ESP_ERR_NOT_FOUND No available unit found on this group
* - ESP_OK Success to register the unit on the group
*/
esp_err_t parlio_register_unit_to_group(parlio_unit_base_handle_t unit);

/**
* @brief Unregister the rx or tx unit from the parlio group
*
* @param[in] unit The TX/RX unit base handle
*/
void parlio_unregister_unit_from_group(parlio_unit_base_handle_t unit);

#ifdef __cplusplus
}
Expand Down
Loading

0 comments on commit 83d5797

Please sign in to comment.