mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-11-16 12:34:45 +00:00
bsps/stm32h7/spi: Add IRQ support
This commit is contained in:
committed by
Chris Johns
parent
b1a350a18a
commit
b3be636863
@@ -3138,6 +3138,7 @@ void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __rtems__
|
||||
/**
|
||||
* @brief Tx Transfer completed callback.
|
||||
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
|
||||
@@ -3185,6 +3186,7 @@ __weak void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISR
|
||||
the HAL_SPI_TxRxCpltCallback should be implemented in the user file
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Tx Half Transfer completed callback.
|
||||
@@ -3234,6 +3236,7 @@ __weak void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation
|
||||
*/
|
||||
}
|
||||
|
||||
#ifndef __rtems__
|
||||
/**
|
||||
* @brief SPI error callback.
|
||||
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
|
||||
@@ -3252,6 +3255,7 @@ __weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2
|
||||
and user can use HAL_SPI_GetError() API to check the latest error occurred
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI Abort Complete callback.
|
||||
|
||||
@@ -193,6 +193,11 @@ typedef struct {
|
||||
bool transmitting;
|
||||
const stm32h7_spi_config *config;
|
||||
rtems_vector_number irq;
|
||||
#ifdef STM32H7_SPI_USE_INTERRUPTS
|
||||
rtems_interrupt_entry spi_irq_entry;
|
||||
rtems_binary_semaphore sem;
|
||||
int error;
|
||||
#endif
|
||||
} stm32h7_spi_context;
|
||||
|
||||
extern stm32h7_spi_context stm32h7_spi1_instance;
|
||||
|
||||
@@ -43,10 +43,16 @@
|
||||
#include <rtems/bspIo.h>
|
||||
#include <rtems/sysinit.h>
|
||||
#include <stdio.h>
|
||||
#include <stm32h7xx_hal_dma.h>
|
||||
#include <stm32h7xx_hal_spi.h>
|
||||
|
||||
#include <stm32h7/hal.h>
|
||||
#include <rtems/score/prioritybitmapimpl.h>
|
||||
|
||||
#define STM32H7_SPI_COMPLETE 0
|
||||
#define STM32H7_SPI_ERROR 1
|
||||
#define SPI_TIMEOUT_MS 100
|
||||
|
||||
/* NULLs are included for disabled devices to preserve index */
|
||||
static stm32h7_spi_context * const stm32h7_spi_instances[] = {
|
||||
#ifdef STM32H7_SPI1_ENABLE
|
||||
@@ -187,11 +193,11 @@ static int stm32h7_spi_setup(spi_bus *base)
|
||||
stm32h7_spi_context *ctx = RTEMS_CONTAINER_OF(base, stm32h7_spi_context, bus);
|
||||
|
||||
if (stm32h7_spi_set_prescaler(ctx, ctx->bus.speed_hz)) {
|
||||
return 1;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (stm32h7_spi_set_bpw(ctx, ctx->bus.bits_per_word)) {
|
||||
return 1;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
stm32h7_spi_set_mode(ctx, ctx->bus.mode);
|
||||
@@ -203,6 +209,9 @@ static void stm32h7_spi_destroy(spi_bus *base)
|
||||
{
|
||||
stm32h7_spi_context *ctx = RTEMS_CONTAINER_OF(base, stm32h7_spi_context, bus);
|
||||
|
||||
#ifdef STM32H7_SPI_USE_INTERRUPTS
|
||||
rtems_binary_semaphore_destroy(&ctx->sem);
|
||||
#endif
|
||||
HAL_SPI_DeInit(&ctx->spi);
|
||||
|
||||
spi_bus_destroy(base);
|
||||
@@ -282,6 +291,108 @@ static void stm32h7_spi_apply_postmessage_settings(
|
||||
}
|
||||
}
|
||||
|
||||
static int stm32h7_spi_transfer_wait(stm32h7_spi_context *ctx, uint32_t timeout_ms)
|
||||
{
|
||||
#ifdef STM32H7_SPI_USE_INTERRUPTS
|
||||
int status;
|
||||
uint32_t timeout_ticks = timeout_ms;
|
||||
|
||||
timeout_ticks /= rtems_configuration_get_milliseconds_per_tick();
|
||||
|
||||
status = rtems_binary_semaphore_wait_timed_ticks(&ctx->sem, timeout_ticks);
|
||||
if (status != 0) {
|
||||
return -ETIME;
|
||||
}
|
||||
if (ctx->error == STM32H7_SPI_ERROR) {
|
||||
return -EIO;
|
||||
}
|
||||
#else
|
||||
(void) timeout_ms;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hal_status_to_errno(HAL_StatusTypeDef status)
|
||||
{
|
||||
_Assert(status != HAL_OK);
|
||||
|
||||
switch (status) {
|
||||
case HAL_BUSY:
|
||||
return -EBUSY;
|
||||
case HAL_ERROR:
|
||||
return -EINVAL;
|
||||
case HAL_TIMEOUT:
|
||||
return -ETIME;
|
||||
case HAL_OK:
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static int stm32h7_spi_txrx(
|
||||
stm32h7_spi_context *ctx,
|
||||
const uint8_t *pTxData,
|
||||
uint8_t *pRxData,
|
||||
uint16_t Size
|
||||
)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
#ifdef STM32H7_SPI_USE_INTERRUPTS
|
||||
status = HAL_SPI_TransmitReceive_IT(&ctx->spi, pTxData, pRxData, Size);
|
||||
#else
|
||||
status = HAL_SPI_TransmitReceive(
|
||||
&ctx->spi, pTxData, pRxData, Size, SPI_TIMEOUT_MS
|
||||
);
|
||||
#endif
|
||||
if (status != HAL_OK) {
|
||||
return hal_status_to_errno(status);
|
||||
}
|
||||
|
||||
return stm32h7_spi_transfer_wait(ctx, SPI_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
static int stm32h7_spi_tx(
|
||||
stm32h7_spi_context *ctx,
|
||||
const uint8_t *pData,
|
||||
uint16_t Size
|
||||
)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
#ifdef STM32H7_SPI_USE_INTERRUPTS
|
||||
status = HAL_SPI_Transmit_IT(&ctx->spi, pData, Size);
|
||||
#else
|
||||
status = HAL_SPI_Transmit(&ctx->spi, pData, Size, SPI_TIMEOUT_MS);
|
||||
#endif
|
||||
if (status != HAL_OK) {
|
||||
return hal_status_to_errno(status);
|
||||
}
|
||||
|
||||
return stm32h7_spi_transfer_wait(ctx, SPI_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
static int stm32h7_spi_rx(
|
||||
stm32h7_spi_context *ctx,
|
||||
uint8_t *pData,
|
||||
uint16_t Size
|
||||
)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
#ifdef STM32H7_SPI_USE_INTERRUPTS
|
||||
status = HAL_SPI_Receive_IT(&ctx->spi, pData, Size);
|
||||
#else
|
||||
status = HAL_SPI_Receive(&ctx->spi, pData, Size, SPI_TIMEOUT_MS);
|
||||
#endif
|
||||
if (status != HAL_OK) {
|
||||
return hal_status_to_errno(status);
|
||||
}
|
||||
|
||||
return stm32h7_spi_transfer_wait(ctx, SPI_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
static int stm32h7_spi_transfer(
|
||||
spi_bus *base,
|
||||
const spi_ioc_transfer *msgs,
|
||||
@@ -292,28 +403,25 @@ static int stm32h7_spi_transfer(
|
||||
|
||||
for (int i = 0; i < msg_count; i++) {
|
||||
const spi_ioc_transfer *msg = &msgs[i];
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
if (stm32h7_spi_apply_premessage_settings(ctx, msg)) {
|
||||
return 1;
|
||||
return -EINVAL;
|
||||
}
|
||||
/* perform transfer */
|
||||
if (msg->tx_buf != NULL && msg->rx_buf != NULL) {
|
||||
status = HAL_SPI_TransmitReceive(
|
||||
&ctx->spi, msg->tx_buf, msg->rx_buf, msg->len, 100
|
||||
);
|
||||
if (status != HAL_OK) {
|
||||
return 1;
|
||||
int ret = stm32h7_spi_txrx(ctx, msg->tx_buf, msg->rx_buf, msg->len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
} else if (msg->tx_buf != NULL) {
|
||||
status = HAL_SPI_Transmit(&ctx->spi, msg->tx_buf, msg->len, 100);
|
||||
if (status != HAL_OK) {
|
||||
return 1;
|
||||
int ret = stm32h7_spi_tx(ctx, msg->tx_buf, msg->len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
} else if (msg->rx_buf != NULL) {
|
||||
status = HAL_SPI_Receive(&ctx->spi, msg->rx_buf, msg->len, 100);
|
||||
if (status != HAL_OK) {
|
||||
return 1;
|
||||
int ret = stm32h7_spi_rx(ctx, msg->rx_buf, msg->len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
/* set final to true on last iteration */
|
||||
@@ -323,6 +431,55 @@ static int stm32h7_spi_transfer(
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *spi)
|
||||
{
|
||||
#ifdef STM32H7_SPI_USE_INTERRUPTS
|
||||
stm32h7_spi_context *ctx = RTEMS_CONTAINER_OF(spi, stm32h7_spi_context, spi);
|
||||
|
||||
ctx->error = STM32H7_SPI_ERROR;
|
||||
rtems_binary_semaphore_post(&ctx->sem);
|
||||
#endif
|
||||
}
|
||||
|
||||
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *spi)
|
||||
{
|
||||
#ifdef STM32H7_SPI_USE_INTERRUPTS
|
||||
stm32h7_spi_context *ctx = RTEMS_CONTAINER_OF(spi, stm32h7_spi_context, spi);
|
||||
|
||||
ctx->error = STM32H7_SPI_COMPLETE;
|
||||
rtems_binary_semaphore_post(&ctx->sem);
|
||||
#endif
|
||||
}
|
||||
|
||||
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *spi)
|
||||
{
|
||||
#ifdef STM32H7_SPI_USE_INTERRUPTS
|
||||
stm32h7_spi_context *ctx = RTEMS_CONTAINER_OF(spi, stm32h7_spi_context, spi);
|
||||
|
||||
ctx->error = STM32H7_SPI_COMPLETE;
|
||||
rtems_binary_semaphore_post(&ctx->sem);
|
||||
#endif
|
||||
}
|
||||
|
||||
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *spi)
|
||||
{
|
||||
#ifdef STM32H7_SPI_USE_INTERRUPTS
|
||||
stm32h7_spi_context *ctx = RTEMS_CONTAINER_OF(spi, stm32h7_spi_context, spi);
|
||||
|
||||
ctx->error = STM32H7_SPI_COMPLETE;
|
||||
rtems_binary_semaphore_post(&ctx->sem);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef STM32H7_SPI_USE_INTERRUPTS
|
||||
static void stm32h7_spi_irq_handler(void *arg)
|
||||
{
|
||||
stm32h7_spi_context *ctx = arg;
|
||||
|
||||
HAL_SPI_IRQHandler(&ctx->spi);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int stm32h7_register_spi_device(
|
||||
stm32h7_spi_context *ctx,
|
||||
uint8_t device_index
|
||||
@@ -330,6 +487,9 @@ static int stm32h7_register_spi_device(
|
||||
{
|
||||
char path[sizeof("/dev/spiXXX")];
|
||||
int rv;
|
||||
#ifdef STM32H7_SPI_USE_INTERRUPTS
|
||||
rtems_status_code sc;
|
||||
#endif
|
||||
spi_bus *bus = &ctx->bus;
|
||||
|
||||
rv = spi_bus_init(bus);
|
||||
@@ -374,6 +534,25 @@ static int stm32h7_register_spi_device(
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef STM32H7_SPI_USE_INTERRUPTS
|
||||
/* Configure interrupt */
|
||||
rtems_interrupt_entry_initialize(
|
||||
&ctx->spi_irq_entry,
|
||||
stm32h7_spi_irq_handler,
|
||||
ctx,
|
||||
"SPI"
|
||||
);
|
||||
sc = rtems_interrupt_entry_install(
|
||||
ctx->irq,
|
||||
RTEMS_INTERRUPT_SHARED,
|
||||
&ctx->spi_irq_entry
|
||||
);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
return false;
|
||||
}
|
||||
rtems_binary_semaphore_init(&ctx->sem, "STM32H7 SPI");
|
||||
#endif
|
||||
|
||||
snprintf(path, sizeof(path), "/dev/spi%" PRIu8, device_index);
|
||||
rv = spi_bus_register(bus, path);
|
||||
if (rv) {
|
||||
|
||||
@@ -102,6 +102,8 @@ links:
|
||||
uid: optprintkinstance
|
||||
- role: build-dependency
|
||||
uid: optpwrsupply
|
||||
- role: build-dependency
|
||||
uid: optspiirq
|
||||
- role: build-dependency
|
||||
uid: optbootcore
|
||||
- role: build-dependency
|
||||
|
||||
17
spec/build/bsps/arm/stm32h7/optspiirq.yml
Normal file
17
spec/build/bsps/arm/stm32h7/optspiirq.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
|
||||
actions:
|
||||
- get-boolean: null
|
||||
- define-condition: null
|
||||
build-type: option
|
||||
copyrights:
|
||||
- Copyright (C) 2024 On-Line Applications Research (OAR)
|
||||
default:
|
||||
- enabled-by: true
|
||||
value: true
|
||||
description: |
|
||||
Use SPI devices in interrupt mode
|
||||
enabled-by: true
|
||||
format: '{}'
|
||||
links: []
|
||||
name: STM32H7_SPI_USE_INTERRUPTS
|
||||
type: build
|
||||
Reference in New Issue
Block a user