mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
1293 lines
36 KiB
C
1293 lines
36 KiB
C
/* Copyright (C) 2022 Alif Semiconductor - All Rights Reserved.
|
|
* Use, distribution and modification of this code is permitted under the
|
|
* terms stated in the Alif Semiconductor Software License Agreement
|
|
*
|
|
* You should have received a copy of the Alif Semiconductor Software
|
|
* License Agreement with this file. If not, please write to:
|
|
* contact@alifsemi.com, or visit: https://alifsemi.com/license
|
|
*
|
|
*/
|
|
|
|
/**************************************************************************//**
|
|
* @file Driver_OSPI.c
|
|
* @author Khushboo Singh
|
|
* @email khushboo.singh@alifsemi.com
|
|
* @version V1.0.0
|
|
* @date 21-Oct-2022
|
|
* @brief CMSIS-Driver for OSPI derived from CMSIS SPI driver.
|
|
* @bug None.
|
|
* @Note None
|
|
******************************************************************************/
|
|
|
|
#include "Driver_OSPI_Private.h"
|
|
|
|
#if !( (RTE_OSPI0) || (RTE_OSPI1) )
|
|
#error "OSPI is not enabled in the RTE_Device.h"
|
|
#endif
|
|
|
|
#if !defined(RTE_Drivers_OSPI)
|
|
#error "OSPI is not enabled in the RTE_Components.h"
|
|
#endif
|
|
|
|
#define ARM_OSPI_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0) /* driver version */
|
|
|
|
/* Driver Version */
|
|
static const ARM_DRIVER_VERSION DriverVersion = {
|
|
ARM_OSPI_API_VERSION,
|
|
ARM_OSPI_DRV_VERSION
|
|
};
|
|
|
|
/* Driver Capabilities */
|
|
static const ARM_OSPI_CAPABILITIES DriverCapabilities = {
|
|
0, /* Simplex Mode (Master and Slave) Deprecated: Reserved (must be zero)*/
|
|
0, /* TI Synchronous Serial Interface */
|
|
0, /* Microwire Interface */
|
|
0, /* Signal Mode Fault event: \ref ARM_OSPI_EVENT_MODE_FAULT */
|
|
0 /* Reserved, must be zero */
|
|
};
|
|
|
|
/**
|
|
* @fn ARM_DRIVER_VERSION ARM_OSPI_GetVersion(void)
|
|
* @brief get ospi version
|
|
* @note none
|
|
* @param none
|
|
* @retval driver version
|
|
*/
|
|
static ARM_DRIVER_VERSION ARM_OSPI_GetVersion(void)
|
|
{
|
|
return DriverVersion;
|
|
}
|
|
|
|
/**
|
|
* @fn ARM_OSPI_CAPABILITIES ARM_OSPI_GetCapabilities(void)
|
|
* @brief get ospi capabilities
|
|
* @note none
|
|
* @param none
|
|
* @retval driver capabilities
|
|
*/
|
|
static ARM_OSPI_CAPABILITIES ARM_OSPI_GetCapabilities(void)
|
|
{
|
|
return DriverCapabilities;
|
|
}
|
|
|
|
/**
|
|
* @fn void OSPI_IRQHandler(OSPI_RESOURCES *OSPI)
|
|
* @brief OSPI interrupt handler
|
|
* @note none
|
|
* @param OSPI : Pointer to ospi resources structure
|
|
* @retval none
|
|
*/
|
|
static void OSPI_IRQHandler(OSPI_RESOURCES *OSPI)
|
|
{
|
|
ospi_transfer_t *transfer = &(OSPI->transfer);
|
|
|
|
ospi_irq_handler(OSPI->regs, transfer);
|
|
|
|
if (transfer->status == SPI_TRANSFER_STATUS_COMPLETE)
|
|
{
|
|
transfer->status = SPI_TRANSFER_STATUS_NONE;
|
|
OSPI->status.busy = 0;
|
|
OSPI->cb_event(ARM_OSPI_EVENT_TRANSFER_COMPLETE);
|
|
}
|
|
|
|
if (transfer->status == SPI_TRANSFER_STATUS_OVERFLOW)
|
|
{
|
|
transfer->status = SPI_TRANSFER_STATUS_NONE;
|
|
OSPI->status.busy = 0;
|
|
OSPI->status.data_lost = 1;
|
|
OSPI->cb_event(ARM_OSPI_EVENT_DATA_LOST);
|
|
}
|
|
}
|
|
|
|
#if OSPI_DMA_ENABLE
|
|
/**
|
|
\fn static void OSPI_DMACallback(uint32_t event, int8_t peri_num,
|
|
OSPI_RESOURCES *OSPI)
|
|
\brief Callback function from DMA for OSPI
|
|
\param[in] event Event from DMA
|
|
\param[in] peri_num Peripheral number
|
|
\param[in] OSPI Pointer to OSPI resources
|
|
*/
|
|
static void OSPI_DMACallback(uint32_t event, int8_t peri_num,
|
|
OSPI_RESOURCES *OSPI)
|
|
{
|
|
if (!OSPI->cb_event)
|
|
return;
|
|
|
|
if (event & ARM_DMA_EVENT_COMPLETE)
|
|
{
|
|
switch (peri_num)
|
|
{
|
|
case OSPI0_DMA_RX_PERIPH_REQ:
|
|
case OSPI1_DMA_RX_PERIPH_REQ:
|
|
OSPI->status.busy = 0;
|
|
OSPI->cb_event(ARM_OSPI_EVENT_TRANSFER_COMPLETE);
|
|
break;
|
|
case OSPI0_DMA_TX_PERIPH_REQ:
|
|
case OSPI1_DMA_TX_PERIPH_REQ:
|
|
if (OSPI->transfer.mode == SPI_TMOD_TX)
|
|
{
|
|
OSPI->status.busy = 0;
|
|
OSPI->cb_event(ARM_OSPI_EVENT_TRANSFER_COMPLETE);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (event & ARM_DMA_EVENT_ABORT)
|
|
{
|
|
OSPI->status.busy = 0;
|
|
OSPI->cb_event(ARM_OSPI_EVENT_DATA_LOST);
|
|
}
|
|
}
|
|
|
|
/**
|
|
\fn int32_t OSPI_DMA_Initialize(DMA_PERIPHERAL_CONFIG *dma_periph)
|
|
\brief Initialize DMA for OSPI
|
|
\param[in] dma_periph Pointer to DMA resources
|
|
\return \ref execution_status
|
|
*/
|
|
__STATIC_INLINE int32_t OSPI_DMA_Initialize(DMA_PERIPHERAL_CONFIG *dma_periph)
|
|
{
|
|
int32_t status;
|
|
ARM_DRIVER_DMA *dma_drv = dma_periph->dma_drv;
|
|
|
|
status = dma_drv->Initialize();
|
|
|
|
if (status)
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
\fn int32_t OSPI_DMA_PowerControl(ARM_POWER_STATE state, DMA_PERIPHERAL_CONFIG *dma_periph)
|
|
\brief PowerControl DMA for OSPI
|
|
\param[in] state Power state
|
|
\param[in] dma_periph Pointer to DMA resources
|
|
\return \ref execution_status
|
|
*/
|
|
__STATIC_INLINE int32_t OSPI_DMA_PowerControl(ARM_POWER_STATE state, DMA_PERIPHERAL_CONFIG *dma_periph)
|
|
{
|
|
int32_t status;
|
|
ARM_DRIVER_DMA *dma_drv = dma_periph->dma_drv;
|
|
|
|
status = dma_drv->PowerControl(state);
|
|
|
|
if (status)
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
\fn int32_t OSPI_DMA_Allocate(DMA_PERIPHERAL_CONFIG *dma_periph)
|
|
\brief Allocate a channel for OSPI
|
|
\param[in] dma_periph Pointer to DMA resources
|
|
\return \ref execution_status
|
|
*/
|
|
__STATIC_INLINE int32_t OSPI_DMA_Allocate(DMA_PERIPHERAL_CONFIG *dma_periph)
|
|
{
|
|
int32_t status;
|
|
ARM_DRIVER_DMA *dma_drv = dma_periph->dma_drv;
|
|
|
|
/* Allocate handle for peripheral */
|
|
status = dma_drv->Allocate(&dma_periph->dma_handle);
|
|
|
|
if (status)
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
/* Enable the channel in the Event Router */
|
|
if (dma_periph->evtrtr_cfg.instance == 0)
|
|
{
|
|
evtrtr0_enable_dma_channel(dma_periph->evtrtr_cfg.channel,
|
|
dma_periph->evtrtr_cfg.group,
|
|
DMA_ACK_COMPLETION_PERIPHERAL);
|
|
evtrtr0_enable_dma_handshake(dma_periph->evtrtr_cfg.channel,
|
|
dma_periph->evtrtr_cfg.group);
|
|
}
|
|
else
|
|
{
|
|
evtrtrlocal_enable_dma_channel(dma_periph->evtrtr_cfg.channel,
|
|
DMA_ACK_COMPLETION_PERIPHERAL);
|
|
}
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
\fn int32_t OSPI_DMA_DeAllocate(DMA_PERIPHERAL_CONFIG *dma_periph)
|
|
\brief De-allocate channel of OSPI
|
|
\param[in] dma_periph Pointer to DMA resources
|
|
\return \ref execution_status
|
|
*/
|
|
__STATIC_INLINE int32_t OSPI_DMA_DeAllocate(DMA_PERIPHERAL_CONFIG *dma_periph)
|
|
{
|
|
int32_t status;
|
|
ARM_DRIVER_DMA *dma_drv = dma_periph->dma_drv;
|
|
|
|
/* De-Allocate handle */
|
|
status = dma_drv->DeAllocate(&dma_periph->dma_handle);
|
|
|
|
if (status)
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
/* Disable the channel in the Event Router */
|
|
if (dma_periph->evtrtr_cfg.instance == 0)
|
|
{
|
|
evtrtr0_disable_dma_channel(dma_periph->evtrtr_cfg.channel);
|
|
evtrtr0_disable_dma_handshake(dma_periph->evtrtr_cfg.channel,
|
|
dma_periph->evtrtr_cfg.group);
|
|
}
|
|
else
|
|
{
|
|
evtrtrlocal_disable_dma_channel(dma_periph->evtrtr_cfg.channel);
|
|
}
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
\fn int32_t OSPI_DMA_Start(DMA_PERIPHERAL_CONFIG *dma_periph,
|
|
ARM_DMA_PARAMS *dma_params)
|
|
\brief Start OSPI DMA transfer
|
|
\param[in] dma_periph Pointer to DMA resources
|
|
\param[in] dma_params Pointer to DMA parameters
|
|
\return \ref execution_status
|
|
*/
|
|
__STATIC_INLINE int32_t OSPI_DMA_Start(DMA_PERIPHERAL_CONFIG *dma_periph,
|
|
ARM_DMA_PARAMS *dma_params)
|
|
{
|
|
int32_t status;
|
|
ARM_DRIVER_DMA *dma_drv = dma_periph->dma_drv;
|
|
|
|
/* Start transfer */
|
|
status = dma_drv->Start(&dma_periph->dma_handle, dma_params);
|
|
if (status)
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
\fn int32_t OSPI_DMA_Stop(DMA_PERIPHERAL_CONFIG *dma_periph)
|
|
\brief Stop OSPI DMA transfer
|
|
\param[in] dma_periph Pointer to DMA resources
|
|
\return \ref execution_status
|
|
*/
|
|
__STATIC_INLINE int32_t OSPI_DMA_Stop(DMA_PERIPHERAL_CONFIG *dma_periph)
|
|
{
|
|
int32_t status;
|
|
ARM_DRIVER_DMA *dma_drv = dma_periph->dma_drv;
|
|
|
|
/* Stop transfer */
|
|
status = dma_drv->Stop(&dma_periph->dma_handle);
|
|
if (status)
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* @fn int32_t ARM_OSPI_Initialize(OSPI_RESOURCES *OSPI, ARM_OSPI_SignalEvent_t cb_event).
|
|
* @brief Initialize the Spi for communication.
|
|
* @note none.
|
|
* @param OSPI : Pointer to spi resources structure.
|
|
* @param cb_event : Pointer to user callback function.
|
|
* @retval \ref execution_status
|
|
*/
|
|
static int32_t ARM_OSPI_Initialize(OSPI_RESOURCES *OSPI, ARM_OSPI_SignalEvent_t cb_event)
|
|
{
|
|
if (OSPI->state.initialized == 1)
|
|
{
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
if (cb_event == NULL)
|
|
{
|
|
return ARM_DRIVER_ERROR_PARAMETER;
|
|
}
|
|
|
|
if ((OSPI->tx_fifo_threshold > OSPI_TX_FIFO_DEPTH) || (OSPI->tx_fifo_start_level > OSPI_TX_FIFO_DEPTH))
|
|
{
|
|
return ARM_DRIVER_ERROR_PARAMETER;
|
|
}
|
|
|
|
if (OSPI->rx_fifo_threshold > OSPI_RX_FIFO_DEPTH)
|
|
{
|
|
return ARM_DRIVER_ERROR_PARAMETER;
|
|
}
|
|
|
|
OSPI->transfer.addr_len = 0;
|
|
OSPI->transfer.dummy_cycle = 0;
|
|
OSPI->transfer.tx_buff = NULL;
|
|
OSPI->transfer.rx_buff = NULL;
|
|
OSPI->transfer.tx_default_val = 0;
|
|
OSPI->transfer.tx_default_enable = 0;
|
|
OSPI->transfer.tx_total_cnt = 0;
|
|
OSPI->transfer.rx_total_cnt = 0;
|
|
OSPI->transfer.tx_current_cnt = 0;
|
|
OSPI->transfer.rx_current_cnt = 0;
|
|
|
|
OSPI->cb_event = cb_event;
|
|
|
|
#if OSPI_DMA_ENABLE
|
|
if (OSPI->dma_enable)
|
|
{
|
|
OSPI->dma_config->dma_rx.dma_handle = -1;
|
|
OSPI->dma_config->dma_tx.dma_handle = -1;
|
|
|
|
/* Initialize DMA for OSPI-Tx */
|
|
if (OSPI_DMA_Initialize(&OSPI->dma_config->dma_tx) != ARM_DRIVER_OK)
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
/* Initialize DMA for OSPI-Rx */
|
|
if (OSPI_DMA_Initialize(&OSPI->dma_config->dma_rx) != ARM_DRIVER_OK)
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
}
|
|
#endif
|
|
OSPI->state.initialized = 1;
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
* @fn int32_t ARM_OSPI_Uninitialize(OSPI_RESOURCES *OSPI).
|
|
* @brief Un-Initialize the Spi.
|
|
* @note none.
|
|
* @param OSPI : Pointer to spi resources structure.
|
|
* @retval \ref execution_status
|
|
*/
|
|
static int32_t ARM_OSPI_Uninitialize(OSPI_RESOURCES *OSPI)
|
|
{
|
|
if (OSPI->state.initialized == 0)
|
|
{
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
if (OSPI->state.powered == 1)
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
OSPI->transfer.tx_buff = NULL;
|
|
OSPI->transfer.rx_buff = NULL;
|
|
OSPI->transfer.tx_default_val = 0;
|
|
OSPI->transfer.tx_default_enable = 0;
|
|
OSPI->transfer.tx_total_cnt = 0;
|
|
OSPI->transfer.rx_total_cnt = 0;
|
|
OSPI->transfer.tx_current_cnt = 0;
|
|
OSPI->transfer.rx_current_cnt = 0;
|
|
|
|
OSPI->cb_event = NULL;
|
|
OSPI->state.initialized = 0;
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
* @fn int32_t ARM_OSPI_PowerControl(OSPI_RESOURCES *OSPI, ARM_POWER_STATE state).
|
|
* @brief Handles the spi power.
|
|
* @note none.
|
|
* @param OSPI : Pointer to spi resources structure.
|
|
* @param state : power state.
|
|
* @retval \ref execution_status
|
|
*/
|
|
static int32_t ARM_OSPI_PowerControl(OSPI_RESOURCES *OSPI, ARM_POWER_STATE state)
|
|
{
|
|
if (OSPI->state.initialized == 0)
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
switch (state)
|
|
{
|
|
case ARM_POWER_OFF:
|
|
{
|
|
if (OSPI->state.powered == 0)
|
|
{
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
if (ospi_busy(OSPI->regs))
|
|
{
|
|
return ARM_DRIVER_ERROR_BUSY;
|
|
}
|
|
|
|
ospi_mask_interrupts(OSPI->regs);
|
|
NVIC_ClearPendingIRQ(OSPI->irq);
|
|
NVIC_DisableIRQ(OSPI->irq);
|
|
ospi_disable(OSPI->regs);
|
|
#if OSPI_DMA_ENABLE
|
|
if (OSPI->dma_enable)
|
|
{
|
|
ospi_disable_tx_dma(OSPI->regs);
|
|
ospi_disable_rx_dma(OSPI->regs);
|
|
if (OSPI_DMA_DeAllocate(&OSPI->dma_config->dma_tx) == ARM_DRIVER_ERROR)
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
if (OSPI_DMA_DeAllocate(&OSPI->dma_config->dma_rx) == ARM_DRIVER_ERROR)
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
}
|
|
#endif
|
|
OSPI->state.powered = 0;
|
|
break;
|
|
}
|
|
|
|
case ARM_POWER_FULL:
|
|
{
|
|
if (OSPI->state.powered == 1)
|
|
{
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
ospi_set_tx_threshold(OSPI->regs, OSPI->tx_fifo_threshold);
|
|
ospi_set_rx_threshold(OSPI->regs, OSPI->rx_fifo_threshold);
|
|
ospi_set_rx_sample_delay(OSPI->regs, OSPI->rx_sample_delay);
|
|
ospi_set_ddr_drive_edge(OSPI->regs, OSPI->ddr_drive_edge);
|
|
aes_set_rxds_delay(OSPI->aes_regs, OSPI->rxds_delay);
|
|
ospi_mask_interrupts(OSPI->regs);
|
|
#if OSPI_DMA_ENABLE
|
|
if (OSPI->dma_enable)
|
|
{
|
|
ospi_set_rx_dma_data_level(OSPI->regs, OSPI->rx_dma_data_level);
|
|
ospi_set_tx_dma_data_level(OSPI->regs, OSPI->tx_dma_data_level);
|
|
}
|
|
#endif
|
|
NVIC_ClearPendingIRQ(OSPI->irq);
|
|
NVIC_SetPriority(OSPI->irq, OSPI->irq_priority);
|
|
NVIC_EnableIRQ(OSPI->irq);
|
|
|
|
OSPI->state.powered = 1;
|
|
break;
|
|
}
|
|
|
|
case ARM_POWER_LOW:
|
|
default :
|
|
{
|
|
return ARM_DRIVER_ERROR_UNSUPPORTED;
|
|
}
|
|
}
|
|
|
|
|
|
#if OSPI_DMA_ENABLE
|
|
if (OSPI->dma_enable)
|
|
{
|
|
/* Power Control DMA for OSPI-Tx */
|
|
if (OSPI_DMA_PowerControl (state, &OSPI->dma_config->dma_tx) != ARM_DRIVER_OK)
|
|
{
|
|
OSPI->state.powered = 0;
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
/* Power Control DMA for OSPI-Rx */
|
|
if (OSPI_DMA_PowerControl (state, &OSPI->dma_config->dma_rx) != ARM_DRIVER_OK)
|
|
{
|
|
OSPI->state.powered = 0;
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
if (state == ARM_POWER_FULL)
|
|
{
|
|
/* Try to allocate a DMA channel for Tx */
|
|
if (OSPI_DMA_Allocate(&OSPI->dma_config->dma_tx) == ARM_DRIVER_ERROR)
|
|
{
|
|
OSPI->state.powered = 0;
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
/* Try to allocate a DMA channel for Rx */
|
|
if (OSPI_DMA_Allocate(&OSPI->dma_config->dma_rx) == ARM_DRIVER_ERROR)
|
|
{
|
|
OSPI->state.powered = 0;
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
* @fn int32_t ARM_OSPI_Send(OSPI_RESOURCES *OSPI, const void *data, uint32_t num).
|
|
* @brief Used to send through spi.
|
|
* @note none.
|
|
* @param OSPI : Pointer to spi resources structure.
|
|
* @param data : Pointer to the data to send.
|
|
* @param num : Number of data byte to send.
|
|
* @retval \ref execution_status
|
|
*/
|
|
static int32_t ARM_OSPI_Send(OSPI_RESOURCES *OSPI, const void *data, uint32_t num)
|
|
{
|
|
#if OSPI_DMA_ENABLE
|
|
int32_t status;
|
|
#endif
|
|
|
|
if (OSPI->state.powered == 0)
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
if (ospi_busy(OSPI->regs))
|
|
{
|
|
return ARM_DRIVER_ERROR_BUSY;
|
|
}
|
|
|
|
if ((data == NULL) && (OSPI->transfer.tx_default_enable == false))
|
|
{
|
|
return ARM_DRIVER_ERROR_PARAMETER;
|
|
}
|
|
|
|
if (num == 0)
|
|
{
|
|
return ARM_DRIVER_ERROR_PARAMETER;
|
|
}
|
|
|
|
if (OSPI->status.busy)
|
|
{
|
|
return ARM_DRIVER_ERROR_BUSY;
|
|
}
|
|
|
|
OSPI->status.busy = 1;
|
|
OSPI->transfer.tx_total_cnt = num;
|
|
OSPI->transfer.mode = SPI_TMOD_TX;
|
|
|
|
#if OSPI_DMA_ENABLE
|
|
ARM_DMA_PARAMS dma_params;
|
|
|
|
if (OSPI->dma_enable && (ospi_get_dfs(OSPI->regs) > 8))
|
|
{
|
|
dma_params.peri_reqno = OSPI->dma_config->dma_tx.dma_periph_req;
|
|
dma_params.dir = ARM_DMA_MEM_TO_DEV;
|
|
dma_params.cb_event = OSPI->dma_cb;
|
|
dma_params.src_addr = (void *) data;
|
|
dma_params.dst_addr = (void *) ospi_get_dma_addr(OSPI->regs);
|
|
dma_params.num_bytes = num * 4;
|
|
dma_params.irq_priority = OSPI->dma_irq_priority;
|
|
dma_params.burst_size = BS_BYTE_4;
|
|
dma_params.burst_len = 16;
|
|
|
|
ospi_dma_send(OSPI->regs, &(OSPI->transfer));
|
|
|
|
/* Start DMA transfer */
|
|
status = OSPI_DMA_Start(&OSPI->dma_config->dma_tx, &dma_params);
|
|
|
|
if (status)
|
|
{
|
|
OSPI->status.busy = 0;
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
OSPI->transfer.tx_buff = data;
|
|
OSPI->transfer.tx_current_cnt = 0;
|
|
OSPI->transfer.status = SPI_TRANSFER_STATUS_NONE;
|
|
ospi_send(OSPI->regs, &(OSPI->transfer));
|
|
}
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
* @fn int32_t ARM_OSPI_Receive(OSPI_RESOURCES *OSPI, void *data, uint32_t num).
|
|
* @brief Used to receive data through spi.
|
|
* @note none.
|
|
* @param OSPI : Pointer to spi resources structure.
|
|
* @param data : Pointer to the data received.
|
|
* @param num : Number of data byte to receive.
|
|
* @retval \ref execution_status
|
|
*/
|
|
static int32_t ARM_OSPI_Receive(OSPI_RESOURCES *OSPI, void *data, uint32_t num)
|
|
{
|
|
if (OSPI->state.powered == 0)
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
if (ospi_busy(OSPI->regs))
|
|
{
|
|
return ARM_DRIVER_ERROR_BUSY;
|
|
}
|
|
|
|
if ((data == NULL) || (num == 0))
|
|
{
|
|
return ARM_DRIVER_ERROR_PARAMETER;
|
|
}
|
|
|
|
if (OSPI->status.busy)
|
|
{
|
|
return ARM_DRIVER_ERROR_BUSY;
|
|
}
|
|
|
|
OSPI->status.busy = 1;
|
|
|
|
OSPI->transfer.rx_buff = (uint8_t *) data;
|
|
OSPI->transfer.rx_current_cnt = 0;
|
|
OSPI->transfer.rx_total_cnt = num;
|
|
OSPI->transfer.mode = SPI_TMOD_RX;
|
|
OSPI->transfer.status = SPI_TRANSFER_STATUS_NONE;
|
|
|
|
ospi_receive(OSPI->regs, &(OSPI->transfer));
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
* @fn int32_t ARM_OSPI_Transfer(OSPI_RESOURCES *OSPI, const void *data_out, void *data_in, uint32_t num).
|
|
* @brief Used to Transfer and Receive data through spi.
|
|
* @note none.
|
|
* @param OSPI : Pointer to spi resources structure.
|
|
* @param data_out : Pointer to the data send.
|
|
* @param data_in : Pointer to the data received.
|
|
* @param num : Number of data byte to receive.
|
|
* @retval \ref execution_status
|
|
*/
|
|
static int32_t ARM_OSPI_Transfer(OSPI_RESOURCES *OSPI, const void *data_out, void *data_in, uint32_t num)
|
|
{
|
|
#if OSPI_DMA_ENABLE
|
|
int32_t status;
|
|
#endif
|
|
|
|
if (OSPI->state.powered == 0)
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
if (ospi_busy(OSPI->regs))
|
|
{
|
|
return ARM_DRIVER_ERROR_BUSY;
|
|
}
|
|
|
|
if ((OSPI->transfer.tx_default_enable == 0) && (data_out == NULL))
|
|
{
|
|
return ARM_DRIVER_ERROR_PARAMETER;
|
|
}
|
|
|
|
if ((data_out == NULL) || (data_in == NULL) || (num == 0))
|
|
{
|
|
return ARM_DRIVER_ERROR_PARAMETER;
|
|
}
|
|
|
|
if (OSPI->status.busy)
|
|
{
|
|
return ARM_DRIVER_ERROR_BUSY;
|
|
}
|
|
|
|
OSPI->status.busy = 1;
|
|
|
|
OSPI->transfer.rx_total_cnt = num;
|
|
OSPI->transfer.mode = SPI_TMOD_TX_AND_RX;
|
|
|
|
/* Tx total count based on address length */
|
|
if (OSPI->transfer.addr_len == ARM_OSPI_ADDR_LENGTH_0_BITS)
|
|
OSPI->transfer.tx_total_cnt = 1;
|
|
else if (OSPI->transfer.addr_len == ARM_OSPI_ADDR_LENGTH_24_BITS)
|
|
OSPI->transfer.tx_total_cnt = 4;
|
|
else if (OSPI->transfer.addr_len == ARM_OSPI_ADDR_LENGTH_32_BITS)
|
|
OSPI->transfer.tx_total_cnt = 2;
|
|
|
|
#if OSPI_DMA_ENABLE
|
|
ARM_DMA_PARAMS tx_dma_params, rx_dma_params;
|
|
/*
|
|
* DMA transfers with 8 bit DFS are not supported because of the
|
|
* h/w limitation on 8bit reception
|
|
*/
|
|
uint8_t dfs = ospi_get_dfs(OSPI->regs);
|
|
|
|
if (OSPI->dma_enable && dfs > 8)
|
|
{
|
|
tx_dma_params.peri_reqno = OSPI->dma_config->dma_tx.dma_periph_req;
|
|
tx_dma_params.dir = ARM_DMA_MEM_TO_DEV;
|
|
tx_dma_params.cb_event = OSPI->dma_cb;
|
|
tx_dma_params.src_addr = (void *) data_out;
|
|
tx_dma_params.dst_addr = (void *) ospi_get_dma_addr(OSPI->regs);
|
|
tx_dma_params.num_bytes = OSPI->transfer.tx_total_cnt * 4;
|
|
tx_dma_params.irq_priority = OSPI->dma_irq_priority;
|
|
tx_dma_params.burst_size = BS_BYTE_4;
|
|
tx_dma_params.burst_len = 16;
|
|
|
|
rx_dma_params.peri_reqno = OSPI->dma_config->dma_rx.dma_periph_req;
|
|
rx_dma_params.dir = ARM_DMA_DEV_TO_MEM;
|
|
rx_dma_params.cb_event = OSPI->dma_cb;
|
|
rx_dma_params.src_addr = (void *) ospi_get_dma_addr(OSPI->regs);
|
|
rx_dma_params.dst_addr = data_in;
|
|
rx_dma_params.irq_priority = OSPI->dma_irq_priority;
|
|
rx_dma_params.burst_len = 16;
|
|
|
|
if (dfs == 16)
|
|
{
|
|
rx_dma_params.num_bytes = num * 2;
|
|
rx_dma_params.burst_size = BS_BYTE_2;
|
|
}
|
|
else if (dfs == 32)
|
|
{
|
|
rx_dma_params.num_bytes = num * 4;
|
|
rx_dma_params.burst_size = BS_BYTE_4;
|
|
}
|
|
|
|
ospi_dma_transfer(OSPI->regs, &(OSPI->transfer));
|
|
|
|
/* Start DMA transfers */
|
|
status = OSPI_DMA_Start(&OSPI->dma_config->dma_rx, &rx_dma_params);
|
|
|
|
if (status)
|
|
{
|
|
OSPI->status.busy = 0;
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
status = OSPI_DMA_Start(&OSPI->dma_config->dma_tx, &tx_dma_params);
|
|
|
|
if (status)
|
|
{
|
|
OSPI->status.busy = 0;
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
OSPI->transfer.tx_buff = data_out;
|
|
OSPI->transfer.rx_buff = data_in;
|
|
OSPI->transfer.tx_current_cnt = 0;
|
|
OSPI->transfer.rx_current_cnt = 0;
|
|
OSPI->transfer.status = SPI_TRANSFER_STATUS_NONE;
|
|
|
|
ospi_transfer(OSPI->regs, &(OSPI->transfer));
|
|
}
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
* @fn int32_t ARM_OSPI_GetDataCount(OSPI_RESOURCES *OSPI).
|
|
* @brief Used to get the data count on spi transfer.
|
|
* @note none.
|
|
* @param OSPI : Pointer to spi resources structure.
|
|
* @retval \ref data count
|
|
*/
|
|
static uint32_t ARM_OSPI_GetDataCount(OSPI_RESOURCES *OSPI)
|
|
{
|
|
if (OSPI->transfer.mode == SPI_TMOD_TX)
|
|
return OSPI->transfer.tx_current_cnt;
|
|
else
|
|
return OSPI->transfer.rx_current_cnt;
|
|
}
|
|
|
|
/**
|
|
* @fn int32_t ARM_OSPI_Control(OSPI_RESOURCES *OSPI, uint32_t control, uint32_t arg).
|
|
* @brief Used to configure spi.
|
|
* @note none.
|
|
* @param OSPI : Pointer to spi resources structure.
|
|
* @param control : control code.
|
|
* @param arg : argument.
|
|
* @retval \ref execution_status
|
|
*/
|
|
static int32_t ARM_OSPI_Control(OSPI_RESOURCES *OSPI, uint32_t control, uint32_t arg)
|
|
{
|
|
int32_t ret = ARM_DRIVER_OK;
|
|
uint32_t clk;
|
|
|
|
if (ospi_busy(OSPI->regs))
|
|
{
|
|
return ARM_DRIVER_ERROR_BUSY;
|
|
}
|
|
|
|
switch (control & ARM_OSPI_CONTROL_MSK)
|
|
{
|
|
case ARM_OSPI_MODE_INACTIVE:
|
|
{
|
|
if (control == 0)
|
|
{
|
|
ospi_disable(OSPI->regs);
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case ARM_OSPI_MODE_MASTER:
|
|
{
|
|
ospi_mode_master(OSPI->regs);
|
|
clk = getOSPICoreClock();
|
|
ospi_set_bus_speed(OSPI->regs, arg, clk);
|
|
break;
|
|
}
|
|
|
|
case ARM_OSPI_SET_BUS_SPEED:
|
|
{
|
|
clk = getOSPICoreClock();
|
|
ospi_set_bus_speed(OSPI->regs, arg, clk);
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
case ARM_OSPI_GET_BUS_SPEED:
|
|
{
|
|
clk = getOSPICoreClock();
|
|
return (int32_t) ospi_get_bus_speed(OSPI->regs, clk);
|
|
}
|
|
|
|
case ARM_OSPI_SET_DEFAULT_TX_VALUE:
|
|
{
|
|
OSPI->transfer.tx_default_val = arg;
|
|
OSPI->transfer.tx_default_enable = true;
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
case ARM_OSPI_CONTROL_SS:
|
|
{
|
|
if (arg == 1)
|
|
{
|
|
ospi_control_ss(OSPI->regs, OSPI->chip_selection_pin, SPI_SS_STATE_ENABLE);
|
|
}
|
|
else if (arg == 0)
|
|
{
|
|
ospi_control_ss(OSPI->regs, OSPI->chip_selection_pin, SPI_SS_STATE_DISABLE);
|
|
}
|
|
else
|
|
{
|
|
return ARM_DRIVER_ERROR_PARAMETER;
|
|
}
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
case ARM_OSPI_ABORT_TRANSFER:
|
|
{
|
|
#if OSPI_DMA_ENABLE
|
|
if (OSPI->dma_enable)
|
|
{
|
|
if (OSPI->transfer.mode == SPI_TMOD_TX)
|
|
{
|
|
if (OSPI_DMA_Stop(&OSPI->dma_config->dma_tx) != ARM_DRIVER_OK)
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
}
|
|
else if (OSPI->transfer.mode == SPI_TMOD_TX_AND_RX)
|
|
{
|
|
if (OSPI_DMA_Stop(&OSPI->dma_config->dma_tx) != ARM_DRIVER_OK)
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
if (OSPI_DMA_Stop(&OSPI->dma_config->dma_rx) != ARM_DRIVER_OK)
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
ospi_mask_interrupts(OSPI->regs);
|
|
ospi_disable(OSPI->regs);
|
|
ospi_enable(OSPI->regs);
|
|
|
|
OSPI->transfer.tx_buff = NULL;
|
|
OSPI->transfer.rx_buff = NULL;
|
|
OSPI->transfer.tx_default_val = 0;
|
|
OSPI->transfer.tx_default_enable = 0;
|
|
OSPI->transfer.tx_total_cnt = 0;
|
|
OSPI->transfer.rx_total_cnt = 0;
|
|
OSPI->transfer.tx_current_cnt = 0;
|
|
OSPI->transfer.rx_current_cnt = 0;
|
|
OSPI->status.busy = 0;
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
case ARM_OSPI_SET_ADDR_LENGTH_WAIT_CYCLE:
|
|
{
|
|
OSPI->transfer.addr_len = 0xF & arg;
|
|
OSPI->transfer.dummy_cycle = 0xFF & (arg >> ARM_OSPI_WAIT_CYCLE_POS);
|
|
break;
|
|
}
|
|
|
|
case ARM_OSPI_SET_FRAME_FORMAT:
|
|
{
|
|
OSPI->transfer.spi_frf = arg;
|
|
break;
|
|
}
|
|
|
|
case ARM_OSPI_SET_DDR_MODE:
|
|
{
|
|
OSPI->transfer.ddr = arg;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
return ARM_DRIVER_ERROR_UNSUPPORTED;
|
|
}
|
|
|
|
switch (control & ARM_OSPI_FRAME_FORMAT_MSK)
|
|
{
|
|
case ARM_OSPI_CPOL0_CPHA0:
|
|
{
|
|
ospi_set_mode(OSPI->regs, SPI_MODE_0);
|
|
break;
|
|
}
|
|
case ARM_OSPI_CPOL0_CPHA1:
|
|
{
|
|
ospi_set_mode(OSPI->regs, SPI_MODE_1);
|
|
break;
|
|
}
|
|
case ARM_OSPI_CPOL1_CPHA0:
|
|
{
|
|
ospi_set_mode(OSPI->regs, SPI_MODE_2);
|
|
break;
|
|
}
|
|
case ARM_OSPI_CPOL1_CPHA1:
|
|
{
|
|
ospi_set_mode(OSPI->regs, SPI_MODE_3);
|
|
break;
|
|
}
|
|
default:
|
|
return ARM_DRIVER_ERROR_UNSUPPORTED;
|
|
}
|
|
|
|
if (control & ARM_OSPI_DATA_BITS_MSK)
|
|
{
|
|
ospi_set_dfs(OSPI->regs, ((control & ARM_OSPI_DATA_BITS_MSK) >> ARM_OSPI_DATA_BITS_POS));
|
|
}
|
|
|
|
switch (control & ARM_OSPI_BIT_ORDER_MSK)
|
|
{
|
|
case ARM_OSPI_MSB_LSB:
|
|
{
|
|
break;
|
|
}
|
|
case ARM_OSPI_LSB_MSB:
|
|
{
|
|
return ARM_DRIVER_ERROR_UNSUPPORTED;
|
|
}
|
|
}
|
|
|
|
switch (control & ARM_OSPI_SS_MASTER_MODE_MSK)
|
|
{
|
|
case ARM_OSPI_SS_MASTER_UNUSED:
|
|
{
|
|
ospi_control_ss(OSPI->regs, 0xF, SPI_SS_STATE_DISABLE);
|
|
break;
|
|
}
|
|
|
|
case ARM_OSPI_SS_MASTER_SW:
|
|
{
|
|
if ((control & ARM_OSPI_CONTROL_MSK) == ARM_OSPI_MODE_MASTER)
|
|
{
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
case ARM_OSPI_SS_MASTER_HW_OUTPUT:
|
|
{
|
|
/* This is the default state in the IP, No need to configure */
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
case ARM_OSPI_SS_MASTER_HW_INPUT:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @fn uint32_t ARM_OSPI_GetStatus(OSPI_RESOURCES *OSPI)
|
|
* @brief Used to get spi status.
|
|
* @note none.
|
|
* @param OSPI : Pointer to spi resources structure.
|
|
* @retval \ref spi driver status.
|
|
*/
|
|
static ARM_OSPI_STATUS ARM_OSPI_GetStatus(OSPI_RESOURCES *OSPI)
|
|
{
|
|
return OSPI->status;
|
|
}
|
|
|
|
/* OSPI0 driver instance */
|
|
#if RTE_OSPI0
|
|
|
|
#if RTE_OSPI0_DMA_ENABLE
|
|
static void OSPI0_DMACallback (uint32_t event, int8_t peri_num);
|
|
|
|
static OSPI_DMA_HW_CONFIG OSPI0_DMA_HW_CONFIG = {
|
|
.dma_rx =
|
|
{
|
|
.dma_drv = &ARM_Driver_DMA_(OSPI0_DMA),
|
|
.dma_periph_req = OSPI0_DMA_RX_PERIPH_REQ,
|
|
.evtrtr_cfg =
|
|
{
|
|
.instance = OSPI0_DMA,
|
|
.group = OSPI0_DMA_GROUP,
|
|
.channel = OSPI0_DMA_RX_PERIPH_REQ,
|
|
.enable_handshake = OSPI0_DMA_HANDSHAKE_ENABLE,
|
|
},
|
|
},
|
|
.dma_tx =
|
|
{
|
|
.dma_drv = &ARM_Driver_DMA_(OSPI0_DMA),
|
|
.dma_periph_req = OSPI0_DMA_TX_PERIPH_REQ,
|
|
.evtrtr_cfg =
|
|
{
|
|
.instance = OSPI0_DMA,
|
|
.group = OSPI0_DMA_GROUP,
|
|
.channel = OSPI0_DMA_TX_PERIPH_REQ,
|
|
.enable_handshake = OSPI0_DMA_HANDSHAKE_ENABLE,
|
|
},
|
|
},
|
|
};
|
|
#endif
|
|
OSPI_RESOURCES OSPI0_RES = {
|
|
.regs = (OSPI_Type *) OSPI0_BASE,
|
|
.aes_regs = (AES_Type *) AES0_BASE,
|
|
.irq = OSPI0_IRQ_IRQn,
|
|
.cb_event = NULL,
|
|
.irq_priority = RTE_OSPI0_IRQ_PRIORITY,
|
|
.drv_instance = OSPI_INSTANCE_0,
|
|
.chip_selection_pin = RTE_OSPI0_CHIP_SELECTION_PIN,
|
|
.transfer.spi_frf = RTE_OSPI0_SPI_FRAME_FORMAT,
|
|
.tx_fifo_threshold = RTE_OSPI0_TX_FIFO_THRESHOLD,
|
|
.tx_fifo_start_level = RTE_OSPI0_TX_FIFO_LEVEL_TO_START_TRANSFER,
|
|
.rx_fifo_threshold = RTE_OSPI0_RX_FIFO_THRESHOLD,
|
|
#if RTE_OSPI0_DMA_ENABLE
|
|
.dma_cb = OSPI0_DMACallback,
|
|
.dma_config = &OSPI0_DMA_HW_CONFIG,
|
|
.dma_enable = RTE_OSPI0_DMA_ENABLE,
|
|
.dma_irq_priority = RTE_OSPI0_DMA_IRQ_PRIORITY,
|
|
.rx_dma_data_level = RTE_OSPI0_RX_DMA_DATA_LEVEL,
|
|
.tx_dma_data_level = RTE_OSPI0_TX_DMA_DATA_LEVEL,
|
|
#endif
|
|
.ddr_drive_edge = RTE_OSPI0_DDR_DRIVE_EDGE,
|
|
.rx_sample_delay = RTE_OSPI0_RX_SAMPLE_DELAY,
|
|
.rxds_delay = RTE_OSPI0_RXDS_DELAY
|
|
};
|
|
|
|
void OSPI0_IRQHandler(void)
|
|
{
|
|
OSPI_IRQHandler(&OSPI0_RES);
|
|
}
|
|
|
|
#if RTE_OSPI0_DMA_ENABLE
|
|
static void OSPI0_DMACallback(uint32_t event, int8_t peri_num)
|
|
{
|
|
OSPI_DMACallback(event, peri_num, &OSPI0_RES);
|
|
}
|
|
#endif
|
|
|
|
static int32_t ARM_OSPI0_Initialize(ARM_OSPI_SignalEvent_t cb_event)
|
|
{
|
|
return ARM_OSPI_Initialize(&OSPI0_RES, cb_event);
|
|
}
|
|
|
|
static int32_t ARM_OSPI0_Uninitialize(void)
|
|
{
|
|
return ARM_OSPI_Uninitialize(&OSPI0_RES);
|
|
}
|
|
|
|
static int32_t ARM_OSPI0_PowerControl(ARM_POWER_STATE state)
|
|
{
|
|
return ARM_OSPI_PowerControl(&OSPI0_RES, state);
|
|
}
|
|
|
|
static int32_t ARM_OSPI0_Send(const void *data, uint32_t num)
|
|
{
|
|
return ARM_OSPI_Send(&OSPI0_RES, data, num);
|
|
}
|
|
|
|
static int32_t ARM_OSPI0_Receive(void *data, uint32_t num)
|
|
{
|
|
return ARM_OSPI_Receive(&OSPI0_RES, data, num);
|
|
}
|
|
|
|
static int32_t ARM_OSPI0_Transfer(const void *data_out, void *data_in, uint32_t num)
|
|
{
|
|
return ARM_OSPI_Transfer(&OSPI0_RES, data_out, data_in, num);
|
|
}
|
|
|
|
static uint32_t ARM_OSPI0_GetDataCount(void)
|
|
{
|
|
return ARM_OSPI_GetDataCount(&OSPI0_RES);
|
|
}
|
|
|
|
static int32_t ARM_OSPI0_Control(uint32_t control, uint32_t arg)
|
|
{
|
|
return ARM_OSPI_Control(&OSPI0_RES, control, arg);
|
|
}
|
|
|
|
static ARM_OSPI_STATUS ARM_OSPI0_GetStatus(void)
|
|
{
|
|
return ARM_OSPI_GetStatus(&OSPI0_RES);
|
|
}
|
|
|
|
extern ARM_DRIVER_OSPI Driver_OSPI0;
|
|
ARM_DRIVER_OSPI Driver_OSPI0 = {
|
|
ARM_OSPI_GetVersion,
|
|
ARM_OSPI_GetCapabilities,
|
|
ARM_OSPI0_Initialize,
|
|
ARM_OSPI0_Uninitialize,
|
|
ARM_OSPI0_PowerControl,
|
|
ARM_OSPI0_Send,
|
|
ARM_OSPI0_Receive,
|
|
ARM_OSPI0_Transfer,
|
|
ARM_OSPI0_GetDataCount,
|
|
ARM_OSPI0_Control,
|
|
ARM_OSPI0_GetStatus
|
|
};
|
|
#endif /* RTE_OSPI0 */
|
|
|
|
/* OSPI1 driver instance */
|
|
#if RTE_OSPI1
|
|
|
|
#if RTE_OSPI1_DMA_ENABLE
|
|
static void OSPI1_DMACallback(uint32_t event, int8_t peri_num);
|
|
|
|
static OSPI_DMA_HW_CONFIG OSPI1_DMA_HW_CONFIG = {
|
|
.dma_rx =
|
|
{
|
|
.dma_drv = &ARM_Driver_DMA_(OSPI1_DMA),
|
|
.dma_periph_req = OSPI1_DMA_RX_PERIPH_REQ,
|
|
.evtrtr_cfg =
|
|
{
|
|
.instance = OSPI1_DMA,
|
|
.group = OSPI1_DMA_GROUP,
|
|
.channel = OSPI1_DMA_RX_PERIPH_REQ,
|
|
.enable_handshake = OSPI1_DMA_HANDSHAKE_ENABLE,
|
|
},
|
|
},
|
|
.dma_tx =
|
|
{
|
|
.dma_drv = &ARM_Driver_DMA_(OSPI1_DMA),
|
|
.dma_periph_req = OSPI1_DMA_TX_PERIPH_REQ,
|
|
.evtrtr_cfg =
|
|
{
|
|
.instance = OSPI1_DMA,
|
|
.group = OSPI1_DMA_GROUP,
|
|
.channel = OSPI1_DMA_TX_PERIPH_REQ,
|
|
.enable_handshake = OSPI1_DMA_HANDSHAKE_ENABLE,
|
|
},
|
|
},
|
|
};
|
|
#endif
|
|
OSPI_RESOURCES OSPI1_RES = {
|
|
.regs = (OSPI_Type *) OSPI1_BASE,
|
|
.aes_regs = (AES_Type *) AES1_BASE,
|
|
.irq = OSPI1_IRQ_IRQn,
|
|
.cb_event = NULL,
|
|
.irq_priority = RTE_OSPI1_IRQ_PRIORITY,
|
|
.drv_instance = OSPI_INSTANCE_1,
|
|
.chip_selection_pin = RTE_OSPI1_CHIP_SELECTION_PIN,
|
|
.transfer.spi_frf = RTE_OSPI1_SPI_FRAME_FORMAT,
|
|
.tx_fifo_threshold = RTE_OSPI1_TX_FIFO_THRESHOLD,
|
|
.tx_fifo_start_level = RTE_OSPI1_TX_FIFO_LEVEL_TO_START_TRANSFER,
|
|
.rx_fifo_threshold = RTE_OSPI1_RX_FIFO_THRESHOLD,
|
|
#if RTE_OSPI1_DMA_ENABLE
|
|
.dma_cb = OSPI1_DMACallback,
|
|
.dma_config = &OSPI1_DMA_HW_CONFIG,
|
|
.dma_irq_priority = RTE_OSPI1_DMA_IRQ_PRIORITY,
|
|
.dma_enable = RTE_OSPI1_DMA_ENABLE,
|
|
.rx_dma_data_level = RTE_OSPI1_RX_DMA_DATA_LEVEL,
|
|
.tx_dma_data_level = RTE_OSPI1_TX_DMA_DATA_LEVEL,
|
|
#endif
|
|
.ddr_drive_edge = RTE_OSPI1_DDR_DRIVE_EDGE,
|
|
.rx_sample_delay = RTE_OSPI1_RX_SAMPLE_DELAY,
|
|
.rxds_delay = RTE_OSPI1_RXDS_DELAY
|
|
};
|
|
|
|
void OSPI1_IRQHandler(void)
|
|
{
|
|
OSPI_IRQHandler(&OSPI1_RES);
|
|
}
|
|
|
|
#if RTE_OSPI1_DMA_ENABLE
|
|
static void OSPI1_DMACallback(uint32_t event, int8_t peri_num)
|
|
{
|
|
OSPI_DMACallback(event, peri_num, &OSPI1_RES);
|
|
}
|
|
#endif
|
|
static int32_t ARM_OSPI1_Initialize(ARM_OSPI_SignalEvent_t cb_event)
|
|
{
|
|
return ARM_OSPI_Initialize(&OSPI1_RES, cb_event);
|
|
}
|
|
|
|
static int32_t ARM_OSPI1_Uninitialize(void)
|
|
{
|
|
return ARM_OSPI_Uninitialize(&OSPI1_RES);
|
|
}
|
|
|
|
static int32_t ARM_OSPI1_PowerControl(ARM_POWER_STATE state)
|
|
{
|
|
return ARM_OSPI_PowerControl(&OSPI1_RES, state);
|
|
}
|
|
|
|
static int32_t ARM_OSPI1_Send(const void *data, uint32_t num)
|
|
{
|
|
return ARM_OSPI_Send(&OSPI1_RES, data, num);
|
|
}
|
|
|
|
static int32_t ARM_OSPI1_Receive(void *data, uint32_t num)
|
|
{
|
|
return ARM_OSPI_Receive(&OSPI1_RES, data, num);
|
|
}
|
|
|
|
static int32_t ARM_OSPI1_Transfer(const void *data_out, void *data_in, uint32_t num)
|
|
{
|
|
return ARM_OSPI_Transfer(&OSPI1_RES, data_out, data_in, num);
|
|
}
|
|
|
|
static uint32_t ARM_OSPI1_GetDataCount(void)
|
|
{
|
|
return ARM_OSPI_GetDataCount(&OSPI1_RES);
|
|
}
|
|
|
|
static int32_t ARM_OSPI1_Control(uint32_t control, uint32_t arg)
|
|
{
|
|
return ARM_OSPI_Control(&OSPI1_RES, control, arg);
|
|
}
|
|
|
|
static ARM_OSPI_STATUS ARM_OSPI1_GetStatus(void)
|
|
{
|
|
return ARM_OSPI_GetStatus(&OSPI1_RES);
|
|
}
|
|
|
|
extern ARM_DRIVER_OSPI Driver_OSPI1;
|
|
ARM_DRIVER_OSPI Driver_OSPI1 = {
|
|
ARM_OSPI_GetVersion,
|
|
ARM_OSPI_GetCapabilities,
|
|
ARM_OSPI1_Initialize,
|
|
ARM_OSPI1_Uninitialize,
|
|
ARM_OSPI1_PowerControl,
|
|
ARM_OSPI1_Send,
|
|
ARM_OSPI1_Receive,
|
|
ARM_OSPI1_Transfer,
|
|
ARM_OSPI1_GetDataCount,
|
|
ARM_OSPI1_Control,
|
|
ARM_OSPI1_GetStatus
|
|
};
|
|
#endif /* RTE_OSPI1 */
|