Added SPI IRQ based implementation (Still not totally tested)
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@13134 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
b928dda064
commit
05e2b8becc
|
@ -0,0 +1,411 @@
|
||||||
|
/*
|
||||||
|
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file ADUCM36x/hal_spi_lld.c
|
||||||
|
* @brief ADUCM SPI subsystem low level driver source.
|
||||||
|
*
|
||||||
|
* @addtogroup SPI
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hal.h"
|
||||||
|
|
||||||
|
#if HAL_USE_SPI || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local definitions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#define ADUCM_SPI_DIV_MASK 0x003FU
|
||||||
|
|
||||||
|
#define ADUCM_SPI_STA_IRQ 0x0001U
|
||||||
|
#define ADUCM_SPI_STA_TX 0x0020U
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/** @brief SPI0 driver identifier.*/
|
||||||
|
#if ADUCM_SPI_USE_SPI0 || defined(__DOXYGEN__)
|
||||||
|
SPIDriver SPID0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** @brief SPI1 driver identifier.*/
|
||||||
|
#if ADUCM_SPI_USE_SPI1 || defined(__DOXYGEN__)
|
||||||
|
SPIDriver SPID1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local variables and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Shared interrupt service routine.
|
||||||
|
*
|
||||||
|
* @param[in] spip pointer to the @p SPIDriver object
|
||||||
|
*/
|
||||||
|
static void spi_lld_serve_interrupt(SPIDriver *spip) {
|
||||||
|
|
||||||
|
uint32_t sta = spip->spi->SPISTA;
|
||||||
|
uint8_t dummy_rx;
|
||||||
|
uint8_t dummy_tx = 0xFFU;
|
||||||
|
|
||||||
|
if((sta & ADUCM_SPI_STA_TX) && (spip->size > 0)) {
|
||||||
|
/* Decreasing the size. */
|
||||||
|
(spip->size)--;
|
||||||
|
|
||||||
|
/* Retrieving the RX. */
|
||||||
|
if(spip->rxbuf != NULL) {
|
||||||
|
*(spip->rxbuf) = spip->spi->SPIRX;
|
||||||
|
(spip->rxbuf)++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dummy_rx = spip->spi->SPIRX;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pushing the new TX: this will start a new transfert. */
|
||||||
|
if(spip->txbuf != NULL) {
|
||||||
|
spip->spi->SPITX = *(spip->txbuf);
|
||||||
|
(spip->txbuf)++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
spip->spi->SPITX = dummy_tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)dummy_rx;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(spip->size == 0) {
|
||||||
|
/* Portable SPI ISR code defined in the high level driver, note, it is
|
||||||
|
a macro.*/
|
||||||
|
_spi_isr_code(spip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver interrupt handlers. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if ADUCM_SPI_USE_SPI0 || defined(__DOXYGEN__)
|
||||||
|
#if !defined(ADUCM_SPI0_HANDLER)
|
||||||
|
#error "ADUCM_SPI0_HANDLER not defined"
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* @brief SPI0 interrupt handler.
|
||||||
|
*
|
||||||
|
* @isr
|
||||||
|
*/
|
||||||
|
OSAL_IRQ_HANDLER(ADUCM_SPI0_HANDLER) {
|
||||||
|
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
spi_lld_serve_interrupt(&SPID0);
|
||||||
|
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ADUCM_SPI_USE_SPI1 || defined(__DOXYGEN__)
|
||||||
|
#if !defined(ADUCM_SPI1_HANDLER)
|
||||||
|
#error "ADUCM_SPI1_HANDLER not defined"
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* @brief SPI1 interrupt handler.
|
||||||
|
*
|
||||||
|
* @isr
|
||||||
|
*/
|
||||||
|
OSAL_IRQ_HANDLER(ADUCM_SPI1_HANDLER) {
|
||||||
|
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
spi_lld_serve_interrupt(&SPID1);
|
||||||
|
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Low level SPI driver initialization.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void spi_lld_init(void) {
|
||||||
|
|
||||||
|
#if ADUCM_SPI_USE_SPI0
|
||||||
|
spiObjectInit(&SPID0);
|
||||||
|
SPID0.spi = pADI_SPI0;
|
||||||
|
SPID0.rxbuf = NULL;
|
||||||
|
SPID0.txbuf = NULL;
|
||||||
|
SPID0.size = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ADUCM_SPI_USE_SPI1
|
||||||
|
spiObjectInit(&SPID1);
|
||||||
|
SPID1.spi = pADI_SPI1;
|
||||||
|
SPID1.rxbuf = NULL;
|
||||||
|
SPID1.txbuf = NULL;
|
||||||
|
SPID1.size = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configures and activates the SPI peripheral.
|
||||||
|
*
|
||||||
|
* @param[in] spip pointer to the @p SPIDriver object
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void spi_lld_start(SPIDriver *spip) {
|
||||||
|
|
||||||
|
/* If in stopped state then enables the SPI and DMA clocks.*/
|
||||||
|
if (spip->state == SPI_STOP) {
|
||||||
|
#if ADUCM_SPI_USE_SPI0
|
||||||
|
if (&SPID0 == spip) {
|
||||||
|
/* Enabling peripheral clock branch. */
|
||||||
|
ccEnableSPI0();
|
||||||
|
|
||||||
|
/* Enabling peripheral interrupt. */
|
||||||
|
nvicEnableVector(ADUCM_SPI0_NUMBER, ADUCM_SPI_SPI0_IRQ_PRIORITY);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if ADUCM_SPI_USE_SPI1
|
||||||
|
if (&SPID1 == spip) {
|
||||||
|
/* Enabling peripheral clock branch. */
|
||||||
|
ccEnableSPI1();
|
||||||
|
|
||||||
|
/* Enabling peripheral interrupt. */
|
||||||
|
nvicEnableVector(ADUCM_SPI1_NUMBER, ADUCM_SPI_SPI1_IRQ_PRIORITY);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SPI clock divider configuration.*/
|
||||||
|
spip->spi->SPIDIV = (spip->config->div & ADUCM_SPI_DIV_MASK);
|
||||||
|
|
||||||
|
/* SPI enabling and configuration. Note that some configuration are
|
||||||
|
enforced to ensure the IRQ proper behavior. */
|
||||||
|
spip->spi->SPICON = spip->config->con | ADUCM_SPI_CON_TIM |
|
||||||
|
ADUCM_SPI_CON_MASEN;
|
||||||
|
spip->spi->SPICON &= ~ADUCM_SPI_CON_MOD_MASK;
|
||||||
|
spip->spi->SPICON |= ADUCM_SPI_CON_ENABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Deactivates the SPI peripheral.
|
||||||
|
*
|
||||||
|
* @param[in] spip pointer to the @p SPIDriver object
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void spi_lld_stop(SPIDriver *spip) {
|
||||||
|
|
||||||
|
/* If in ready state then disables the SPI clock.*/
|
||||||
|
if (spip->state == SPI_READY) {
|
||||||
|
|
||||||
|
/* SPI disable.*/
|
||||||
|
spip->spi->SPICON &= ~ADUCM_SPI_CON_ENABLE;
|
||||||
|
spip->spi->SPICON = 0;
|
||||||
|
spip->spi->SPIDIV = 0;
|
||||||
|
spip->rxbuf = NULL;
|
||||||
|
spip->txbuf = NULL;
|
||||||
|
spip->size = 0;
|
||||||
|
|
||||||
|
#if ADUCM_SPI_USE_SPI0
|
||||||
|
if (&SPID0 == spip)
|
||||||
|
ccDisableSPI0();
|
||||||
|
#endif
|
||||||
|
#if ADUCM_SPI_USE_SPI1
|
||||||
|
if (&SPID1 == spip)
|
||||||
|
ccDisableSPI1();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief Asserts the slave select signal and prepares for transfers.
|
||||||
|
*
|
||||||
|
* @param[in] spip pointer to the @p SPIDriver object
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void spi_lld_select(SPIDriver *spip) {
|
||||||
|
|
||||||
|
/* No implementation on ADUCM.*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Deasserts the slave select signal.
|
||||||
|
* @details The previously selected peripheral is unselected.
|
||||||
|
*
|
||||||
|
* @param[in] spip pointer to the @p SPIDriver object
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void spi_lld_unselect(SPIDriver *spip) {
|
||||||
|
|
||||||
|
/* No implementation on ADUCM.*/
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Ignores data on the SPI bus.
|
||||||
|
* @details This asynchronous function starts the transmission of a series of
|
||||||
|
* idle words on the SPI bus and ignores the received data.
|
||||||
|
* @post At the end of the operation the configured callback is invoked.
|
||||||
|
*
|
||||||
|
* @param[in] spip pointer to the @p SPIDriver object
|
||||||
|
* @param[in] n number of words to be ignored
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void spi_lld_ignore(SPIDriver *spip, size_t n) {
|
||||||
|
uint8_t dummy_tx = 0xFFU;
|
||||||
|
|
||||||
|
spip->txbuf = NULL;
|
||||||
|
spip->rxbuf = NULL;
|
||||||
|
spip->size = n;
|
||||||
|
spip->spi->SPITX = dummy_tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Exchanges data on the SPI bus.
|
||||||
|
* @details This asynchronous function starts a simultaneous transmit/receive
|
||||||
|
* operation.
|
||||||
|
* @post At the end of the operation the configured callback is invoked.
|
||||||
|
* @note The buffers are organized as uint8_t arrays for data sizes below or
|
||||||
|
* equal to 8 bits else it is organized as uint16_t arrays.
|
||||||
|
*
|
||||||
|
* @param[in] spip pointer to the @p SPIDriver object
|
||||||
|
* @param[in] n number of words to be exchanged
|
||||||
|
* @param[in] txbuf the pointer to the transmit buffer
|
||||||
|
* @param[out] rxbuf the pointer to the receive buffer
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void spi_lld_exchange(SPIDriver *spip, size_t n,
|
||||||
|
const void *txbuf, void *rxbuf) {
|
||||||
|
spip->txbuf = (uint8_t*)txbuf;
|
||||||
|
spip->rxbuf = (uint8_t*)rxbuf;
|
||||||
|
spip->size = n;
|
||||||
|
spip->spi->SPITX = *(spip->txbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sends data over the SPI bus.
|
||||||
|
* @details This asynchronous function starts a transmit operation.
|
||||||
|
* @post At the end of the operation the configured callback is invoked.
|
||||||
|
* @note The buffers are organized as uint8_t arrays for data sizes below or
|
||||||
|
* equal to 8 bits else it is organized as uint16_t arrays.
|
||||||
|
*
|
||||||
|
* @param[in] spip pointer to the @p SPIDriver object
|
||||||
|
* @param[in] n number of words to send
|
||||||
|
* @param[in] txbuf the pointer to the transmit buffer
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
|
||||||
|
spip->txbuf = (uint8_t*)txbuf;
|
||||||
|
spip->rxbuf = NULL;
|
||||||
|
spip->size = n;
|
||||||
|
spip->spi->SPITX = *(spip->txbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Receives data from the SPI bus.
|
||||||
|
* @details This asynchronous function starts a receive operation.
|
||||||
|
* @post At the end of the operation the configured callback is invoked.
|
||||||
|
* @note The buffers are organized as uint8_t arrays for data sizes below or
|
||||||
|
* equal to 8 bits else it is organized as uint16_t arrays.
|
||||||
|
*
|
||||||
|
* @param[in] spip pointer to the @p SPIDriver object
|
||||||
|
* @param[in] n number of words to receive
|
||||||
|
* @param[out] rxbuf the pointer to the receive buffer
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
|
||||||
|
uint8_t dummy_tx = 0xFFU;
|
||||||
|
|
||||||
|
spip->txbuf = NULL;
|
||||||
|
spip->rxbuf = (uint8_t*) rxbuf;
|
||||||
|
spip->size = n;
|
||||||
|
spip->spi->SPITX = dummy_tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Exchanges one frame using a polled wait.
|
||||||
|
* @details This synchronous function exchanges one frame using a polled
|
||||||
|
* synchronization method. This function is useful when exchanging
|
||||||
|
* small amount of data on high speed channels, usually in this
|
||||||
|
* situation is much more efficient just wait for completion using
|
||||||
|
* polling than suspending the thread waiting for an interrupt.
|
||||||
|
*
|
||||||
|
* @param[in] spip pointer to the @p SPIDriver object
|
||||||
|
* @param[in] frame the data frame to send over the SPI bus
|
||||||
|
* @return The received data frame from the SPI bus.
|
||||||
|
*/
|
||||||
|
uint8_t spi_lld_polled_exchange(SPIDriver *spip, uint8_t frame) {
|
||||||
|
uint32_t sta = spip->spi->SPISTA;
|
||||||
|
|
||||||
|
#if ADUCM_SPI_USE_SPI0
|
||||||
|
if (&SPID0 == spip) {
|
||||||
|
/* Disabling ISR. */
|
||||||
|
nvicDisableVector(ADUCM_SPI0_NUMBER);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ADUCM_SPI_USE_SPI1
|
||||||
|
if (&SPID1 == spip) {
|
||||||
|
/* Disabling ISR. */
|
||||||
|
nvicDisableVector(ADUCM_SPI1_NUMBER);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
spip->spi->SPITX = frame;
|
||||||
|
while((sta & (ADUCM_SPI_STA_TX | ADUCM_SPI_STA_IRQ))) {
|
||||||
|
sta = spip->spi->SPISTA;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ADUCM_SPI_USE_SPI0
|
||||||
|
if (&SPID0 == spip) {
|
||||||
|
/* Re-enabling peripheral interrupt. */
|
||||||
|
nvicEnableVector(ADUCM_SPI0_NUMBER, ADUCM_SPI_SPI0_IRQ_PRIORITY);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ADUCM_SPI_USE_SPI1
|
||||||
|
if (&SPID1 == spip) {
|
||||||
|
/* Re-enabling peripheral interrupt. */
|
||||||
|
nvicEnableVector(ADUCM_SPI1_NUMBER, ADUCM_SPI_SPI1_IRQ_PRIORITY);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return spip->spi->SPIRX;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAL_USE_SPI */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,231 @@
|
||||||
|
/*
|
||||||
|
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file ADUCM36x/hal_spi_lld.h
|
||||||
|
* @brief ADUCM SPI subsystem low level driver header.
|
||||||
|
*
|
||||||
|
* @addtogroup SPI
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAL_SPI_LLD_H
|
||||||
|
#define HAL_SPI_LLD_H
|
||||||
|
|
||||||
|
#if HAL_USE_SPI || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver constants. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Circular mode support flag.
|
||||||
|
*/
|
||||||
|
#define SPI_SUPPORTS_CIRCULAR FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Register helpers not found in ADI headers
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define ADUCM_SPI_CON_ENABLE 0x0001U
|
||||||
|
#define ADUCM_SPI_CON_MASEN 0x0002U
|
||||||
|
#define ADUCM_SPI_CON_CPHA 0x0004U
|
||||||
|
#define ADUCM_SPI_CON_CPOL 0x0008U
|
||||||
|
#define ADUCM_SPI_CON_WOM 0x0010U
|
||||||
|
#define ADUCM_SPI_CON_LSB 0x0020U
|
||||||
|
#define ADUCM_SPI_CON_TIM 0x0040U
|
||||||
|
#define ADUCM_SPI_CON_ZEN 0x0080U
|
||||||
|
#define ADUCM_SPI_CON_RXOF 0x0100U
|
||||||
|
#define ADUCM_SPI_CON_OEN 0x0200U
|
||||||
|
#define ADUCM_SPI_CON_LOOPBACK 0x0400U
|
||||||
|
#define ADUCM_SPI_CON_CON 0x0800U
|
||||||
|
#define ADUCM_SPI_CON_RFLUSH 0x1000U
|
||||||
|
#define ADUCM_SPI_CON_TFLUSH 0x2000U
|
||||||
|
#define ADUCM_SPI_CON_MOD_MASK 0xC000U
|
||||||
|
#define ADUCM_SPI_CON_MOD_TX1RX1 0x0000U
|
||||||
|
#define ADUCM_SPI_CON_MOD_TX2RX2 0x4000U
|
||||||
|
#define ADUCM_SPI_CON_MOD_TX3RX3 0x8000U
|
||||||
|
#define ADUCM_SPI_CON_MOD_TX4RX4 0xC000U
|
||||||
|
|
||||||
|
#define ADUCM_SPI_DIV_0 0x0001U
|
||||||
|
#define ADUCM_SPI_DIV_1 0x0002U
|
||||||
|
#define ADUCM_SPI_DIV_2 0x0004U
|
||||||
|
#define ADUCM_SPI_DIV_3 0x0008U
|
||||||
|
#define ADUCM_SPI_DIV_4 0x00F0U
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver pre-compile time settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Configuration options
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief SPI0 driver enable switch.
|
||||||
|
* @details If set to @p TRUE the support for SPI0 is included.
|
||||||
|
* @note The default is @p FALSE.
|
||||||
|
*/
|
||||||
|
#if !defined(ADUCM_SPI_USE_SPI0) || defined(__DOXYGEN__)
|
||||||
|
#define ADUCM_SPI_USE_SPI0 FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SPI1 driver enable switch.
|
||||||
|
* @details If set to @p TRUE the support for SPI1 is included.
|
||||||
|
* @note The default is @p FALSE.
|
||||||
|
*/
|
||||||
|
#if !defined(ADUCM_SPI_USE_SPI1) || defined(__DOXYGEN__)
|
||||||
|
#define ADUCM_SPI_USE_SPI1 FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SPI0 interrupt priority level setting.
|
||||||
|
*/
|
||||||
|
#if !defined(ADUCM_SPI_SPI0_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||||
|
#define ADUCM_SPI_SPI0_IRQ_PRIORITY 5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SPI1 interrupt priority level setting.
|
||||||
|
*/
|
||||||
|
#if !defined(ADUCM_SPI_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||||
|
#define ADUCM_SPI_SPI1_IRQ_PRIORITY 5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable SPI DMA support
|
||||||
|
*/
|
||||||
|
#if !defined(ADUCM_SPI_USE_DMA) || defined(__DOXYGEN__)
|
||||||
|
#define ADUCM_SPI_USE_DMA FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Derived constants and error checks. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if !ADUCM_SPI_USE_SPI0 && !ADUCM_SPI_USE_SPI1
|
||||||
|
#error "SPI driver activated but no SPI peripheral assigned"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ADUCM_SPI_USE_SPI0 && \
|
||||||
|
!OSAL_IRQ_IS_VALID_PRIORITY(ADUCM_SPI_SPI0_IRQ_PRIORITY)
|
||||||
|
#error "Invalid IRQ priority assigned to SPI0"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ADUCM_SPI_USE_SPI1 && \
|
||||||
|
!OSAL_IRQ_IS_VALID_PRIORITY(ADUCM_SPI_SPI1_IRQ_PRIORITY)
|
||||||
|
#error "Invalid IRQ priority assigned to SPI1"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ADUCM_SPI_USE_DMA
|
||||||
|
#error "ADuCM SPI driver implementation does not supports DMA yet."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ADUCM_SPI_USE_DMA && ADUCM_SPI_USE_SPI0
|
||||||
|
#error "ADuCM SPI0 does not supports DMA."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (ADUCM_SPI_USE_DMA == TRUE) && !defined(ADUCM_DMA_REQUIRED)
|
||||||
|
#define ADUCM_DMA_REQUIRED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (SPI_USE_CIRCULAR == TRUE) && (SPI_SUPPORTS_CIRCULAR == FALSE)
|
||||||
|
#error "ADuCM SPI does not support circular mode."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SPI_SELECT_MODE == SPI_SELECT_MODE_LLD
|
||||||
|
#error "SPI_SELECT_MODE_LLD not supported by this driver"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver data structures and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver macros. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Low level fields of the SPI driver structure.
|
||||||
|
*/
|
||||||
|
#if ADUCM_SPI_USE_DMA
|
||||||
|
#define spi_lld_driver_fields \
|
||||||
|
/* Empty placeholder for DMA based implementation. */
|
||||||
|
#else
|
||||||
|
#define spi_lld_driver_fields \
|
||||||
|
/* Pointer to the SPIx registers block.*/ \
|
||||||
|
ADI_SPI_TypeDef *spi; \
|
||||||
|
/* Receive buffer pointer.*/ \
|
||||||
|
uint8_t *rxbuf; \
|
||||||
|
/* Transmission buffer pointer.*/ \
|
||||||
|
uint8_t *txbuf; \
|
||||||
|
/* Transfert size.*/ \
|
||||||
|
uint32_t size;
|
||||||
|
#endif /* ADUCM_SPI_USE_DMA */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Low level fields of the SPI configuration structure.
|
||||||
|
*/
|
||||||
|
#define spi_lld_config_fields \
|
||||||
|
/* SPIxCON register initialization data.*/ \
|
||||||
|
uint16_t con; \
|
||||||
|
/* SPIxDIV register initialization data.*/ \
|
||||||
|
uint16_t div
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if ADUCM_SPI_USE_SPI0 && !defined(__DOXYGEN__)
|
||||||
|
extern SPIDriver SPID0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ADUCM_SPI_USE_SPI1 && !defined(__DOXYGEN__)
|
||||||
|
extern SPIDriver SPID1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void spi_lld_init(void);
|
||||||
|
void spi_lld_start(SPIDriver *spip);
|
||||||
|
void spi_lld_stop(SPIDriver *spip);
|
||||||
|
#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
|
||||||
|
void spi_lld_select(SPIDriver *spip);
|
||||||
|
void spi_lld_unselect(SPIDriver *spip);
|
||||||
|
#endif
|
||||||
|
void spi_lld_ignore(SPIDriver *spip, size_t n);
|
||||||
|
void spi_lld_exchange(SPIDriver *spip, size_t n,
|
||||||
|
const void *txbuf, void *rxbuf);
|
||||||
|
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf);
|
||||||
|
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf);
|
||||||
|
#if (SPI_SUPPORTS_CIRCULAR == TRUE) || defined(__DOXYGEN__)
|
||||||
|
void spi_lld_abort(SPIDriver *spip);
|
||||||
|
#endif
|
||||||
|
uint8_t spi_lld_polled_exchange(SPIDriver *spip, uint8_t frame);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HAL_USE_SPI */
|
||||||
|
|
||||||
|
#endif /* HAL_SPI_LLD_H */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -4,6 +4,7 @@ PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
|
||||||
$(CHIBIOS)/os/hal/ports/ADUCM/ADUCM36x/hal_lld.c \
|
$(CHIBIOS)/os/hal/ports/ADUCM/ADUCM36x/hal_lld.c \
|
||||||
$(CHIBIOS)/os/hal/ports/ADUCM/ADUCM36x/hal_pal_lld.c \
|
$(CHIBIOS)/os/hal/ports/ADUCM/ADUCM36x/hal_pal_lld.c \
|
||||||
$(CHIBIOS)/os/hal/ports/ADUCM/ADUCM36x/hal_serial_lld.c \
|
$(CHIBIOS)/os/hal/ports/ADUCM/ADUCM36x/hal_serial_lld.c \
|
||||||
|
$(CHIBIOS)/os/hal/ports/ADUCM/ADUCM36x/hal_spi_lld.c \
|
||||||
$(CHIBIOS)/os/hal/ports/ADUCM/ADUCM36x/hal_st_lld.c
|
$(CHIBIOS)/os/hal/ports/ADUCM/ADUCM36x/hal_st_lld.c
|
||||||
|
|
||||||
# Required include directories.
|
# Required include directories.
|
||||||
|
|
Loading…
Reference in New Issue