Merge branch 'tiva_spi_dma'

This commit is contained in:
marcoveeneman 2015-03-17 21:58:57 +01:00
commit 799f3b5d8a
19 changed files with 2932 additions and 47 deletions

View File

@ -92,10 +92,10 @@
*/
#define GPIOA_UART0_RX 0
#define GPIOA_UART0_TX 1
#define GPIOA_PIN2 2
#define GPIOA_SSI0_CLK 2
#define GPIOA_PIN3 3
#define GPIOA_PIN4 4
#define GPIOA_PIN5 5
#define GPIOA_SSI0_RX 4
#define GPIOA_SSI0_TX 5
#define GPIOA_PIN6 6
#define GPIOA_PIN7 7
@ -191,115 +191,115 @@
*/
#define VAL_GPIOA_DATA (PIN_DATA_LOW(GPIOA_UART0_RX) | \
PIN_DATA_LOW(GPIOA_UART0_TX) | \
PIN_DATA_LOW(GPIOA_PIN2) | \
PIN_DATA_LOW(GPIOA_SSI0_CLK) | \
PIN_DATA_LOW(GPIOA_PIN3) | \
PIN_DATA_LOW(GPIOA_PIN4) | \
PIN_DATA_LOW(GPIOA_PIN5) | \
PIN_DATA_LOW(GPIOA_SSI0_RX) | \
PIN_DATA_LOW(GPIOA_SSI0_TX) | \
PIN_DATA_LOW(GPIOA_PIN6) | \
PIN_DATA_LOW(GPIOA_PIN7))
#define VAL_GPIOA_DIR (PIN_DIR_IN(GPIOA_UART0_RX) | \
PIN_DIR_IN(GPIOA_UART0_TX) | \
PIN_DIR_IN(GPIOA_PIN2) | \
PIN_DIR_IN(GPIOA_SSI0_CLK) | \
PIN_DIR_IN(GPIOA_PIN3) | \
PIN_DIR_IN(GPIOA_PIN4) | \
PIN_DIR_IN(GPIOA_PIN5) | \
PIN_DIR_IN(GPIOA_SSI0_RX) | \
PIN_DIR_IN(GPIOA_SSI0_TX) | \
PIN_DIR_IN(GPIOA_PIN6) | \
PIN_DIR_IN(GPIOA_PIN7))
#define VAL_GPIOA_AFSEL (PIN_AFSEL_GPIO(GPIOA_UART0_RX) | \
PIN_AFSEL_GPIO(GPIOA_UART0_TX) | \
PIN_AFSEL_GPIO(GPIOA_PIN2) | \
PIN_AFSEL_GPIO(GPIOA_SSI0_CLK) | \
PIN_AFSEL_GPIO(GPIOA_PIN3) | \
PIN_AFSEL_GPIO(GPIOA_PIN4) | \
PIN_AFSEL_GPIO(GPIOA_PIN5) | \
PIN_AFSEL_GPIO(GPIOA_SSI0_RX) | \
PIN_AFSEL_GPIO(GPIOA_SSI0_TX) | \
PIN_AFSEL_GPIO(GPIOA_PIN6) | \
PIN_AFSEL_GPIO(GPIOA_PIN7))
#define VAL_GPIOA_ODR (PIN_ODR_DISABLE(GPIOA_UART0_RX) | \
PIN_ODR_DISABLE(GPIOA_UART0_TX) | \
PIN_ODR_DISABLE(GPIOA_PIN2) | \
PIN_ODR_DISABLE(GPIOA_SSI0_CLK) | \
PIN_ODR_DISABLE(GPIOA_PIN3) | \
PIN_ODR_DISABLE(GPIOA_PIN4) | \
PIN_ODR_DISABLE(GPIOA_PIN5) | \
PIN_ODR_DISABLE(GPIOA_SSI0_RX) | \
PIN_ODR_DISABLE(GPIOA_SSI0_TX) | \
PIN_ODR_DISABLE(GPIOA_PIN6) | \
PIN_ODR_DISABLE(GPIOA_PIN7))
#define VAL_GPIOA_PUR (PIN_PxR_DISABLE(GPIOA_UART0_RX) | \
PIN_PxR_DISABLE(GPIOA_UART0_TX) | \
PIN_PxR_DISABLE(GPIOA_PIN2) | \
PIN_PxR_DISABLE(GPIOA_SSI0_CLK) | \
PIN_PxR_DISABLE(GPIOA_PIN3) | \
PIN_PxR_DISABLE(GPIOA_PIN4) | \
PIN_PxR_DISABLE(GPIOA_PIN5) | \
PIN_PxR_DISABLE(GPIOA_SSI0_RX) | \
PIN_PxR_DISABLE(GPIOA_SSI0_TX) | \
PIN_PxR_DISABLE(GPIOA_PIN6) | \
PIN_PxR_DISABLE(GPIOA_PIN7))
#define VAL_GPIOA_PDR (PIN_PxR_DISABLE(GPIOA_UART0_RX) | \
PIN_PxR_DISABLE(GPIOA_UART0_TX) | \
PIN_PxR_DISABLE(GPIOA_PIN2) | \
PIN_PxR_DISABLE(GPIOA_SSI0_CLK) | \
PIN_PxR_DISABLE(GPIOA_PIN3) | \
PIN_PxR_DISABLE(GPIOA_PIN4) | \
PIN_PxR_DISABLE(GPIOA_PIN5) | \
PIN_PxR_DISABLE(GPIOA_SSI0_RX) | \
PIN_PxR_DISABLE(GPIOA_SSI0_TX) | \
PIN_PxR_DISABLE(GPIOA_PIN6) | \
PIN_PxR_DISABLE(GPIOA_PIN7))
#define VAL_GPIOA_DEN (PIN_DEN_ENABLE(GPIOA_UART0_RX) | \
PIN_DEN_ENABLE(GPIOA_UART0_TX) | \
PIN_DEN_ENABLE(GPIOA_PIN2) | \
PIN_DEN_ENABLE(GPIOA_SSI0_CLK) | \
PIN_DEN_ENABLE(GPIOA_PIN3) | \
PIN_DEN_ENABLE(GPIOA_PIN4) | \
PIN_DEN_ENABLE(GPIOA_PIN5) | \
PIN_DEN_ENABLE(GPIOA_SSI0_RX) | \
PIN_DEN_ENABLE(GPIOA_SSI0_TX) | \
PIN_DEN_ENABLE(GPIOA_PIN6) | \
PIN_DEN_ENABLE(GPIOA_PIN7))
#define VAL_GPIOA_AMSEL (PIN_AMSEL_DISABLE(GPIOA_UART0_RX) | \
PIN_AMSEL_DISABLE(GPIOA_UART0_TX) | \
PIN_AMSEL_DISABLE(GPIOA_PIN2) | \
PIN_AMSEL_DISABLE(GPIOA_SSI0_CLK) | \
PIN_AMSEL_DISABLE(GPIOA_PIN3))
#define VAL_GPIOA_DR2R (PIN_DRxR_ENABLE(GPIOA_UART0_RX) | \
PIN_DRxR_ENABLE(GPIOA_UART0_TX) | \
PIN_DRxR_ENABLE(GPIOA_PIN2) | \
PIN_DRxR_ENABLE(GPIOA_SSI0_CLK) | \
PIN_DRxR_ENABLE(GPIOA_PIN3) | \
PIN_DRxR_ENABLE(GPIOA_PIN4) | \
PIN_DRxR_ENABLE(GPIOA_PIN5) | \
PIN_DRxR_ENABLE(GPIOA_SSI0_RX) | \
PIN_DRxR_ENABLE(GPIOA_SSI0_TX) | \
PIN_DRxR_ENABLE(GPIOA_PIN6) | \
PIN_DRxR_ENABLE(GPIOA_PIN7))
#define VAL_GPIOA_DR4R (PIN_DRxR_DISABLE(GPIOA_UART0_RX) | \
PIN_DRxR_DISABLE(GPIOA_UART0_TX) | \
PIN_DRxR_DISABLE(GPIOA_PIN2) | \
PIN_DRxR_DISABLE(GPIOA_SSI0_CLK) | \
PIN_DRxR_DISABLE(GPIOA_PIN3) | \
PIN_DRxR_DISABLE(GPIOA_PIN4) | \
PIN_DRxR_DISABLE(GPIOA_PIN5) | \
PIN_DRxR_DISABLE(GPIOA_SSI0_RX) | \
PIN_DRxR_DISABLE(GPIOA_SSI0_TX) | \
PIN_DRxR_DISABLE(GPIOA_PIN6) | \
PIN_DRxR_DISABLE(GPIOA_PIN7))
#define VAL_GPIOA_DR8R (PIN_DRxR_DISABLE(GPIOA_UART0_RX) | \
PIN_DRxR_DISABLE(GPIOA_UART0_TX) | \
PIN_DRxR_DISABLE(GPIOA_PIN2) | \
PIN_DRxR_DISABLE(GPIOA_SSI0_CLK) | \
PIN_DRxR_DISABLE(GPIOA_PIN3) | \
PIN_DRxR_DISABLE(GPIOA_PIN4) | \
PIN_DRxR_DISABLE(GPIOA_PIN5) | \
PIN_DRxR_DISABLE(GPIOA_SSI0_RX) | \
PIN_DRxR_DISABLE(GPIOA_SSI0_TX) | \
PIN_DRxR_DISABLE(GPIOA_PIN6) | \
PIN_DRxR_DISABLE(GPIOA_PIN7))
#define VAL_GPIOA_SLR (PIN_SLR_DISABLE(GPIOA_UART0_RX) | \
PIN_SLR_DISABLE(GPIOA_UART0_TX) | \
PIN_SLR_DISABLE(GPIOA_PIN2) | \
PIN_SLR_DISABLE(GPIOA_SSI0_CLK) | \
PIN_SLR_DISABLE(GPIOA_PIN3) | \
PIN_SLR_DISABLE(GPIOA_PIN4) | \
PIN_SLR_DISABLE(GPIOA_PIN5) | \
PIN_SLR_DISABLE(GPIOA_SSI0_RX) | \
PIN_SLR_DISABLE(GPIOA_SSI0_TX) | \
PIN_SLR_DISABLE(GPIOA_PIN6) | \
PIN_SLR_DISABLE(GPIOA_PIN7))
#define VAL_GPIOA_PCTL (PIN_PCTL_MODE(GPIOA_UART0_RX, 0) | \
PIN_PCTL_MODE(GPIOA_UART0_TX, 0) | \
PIN_PCTL_MODE(GPIOA_PIN2, 0) | \
PIN_PCTL_MODE(GPIOA_SSI0_CLK, 0) | \
PIN_PCTL_MODE(GPIOA_PIN3, 0) | \
PIN_PCTL_MODE(GPIOA_PIN4, 0) | \
PIN_PCTL_MODE(GPIOA_PIN5, 0) | \
PIN_PCTL_MODE(GPIOA_SSI0_RX, 0) | \
PIN_PCTL_MODE(GPIOA_SSI0_TX, 0) | \
PIN_PCTL_MODE(GPIOA_PIN6, 0) | \
PIN_PCTL_MODE(GPIOA_PIN7, 0))

View File

@ -0,0 +1,685 @@
/*
Copyright (C) 2014 Marco Veeneman
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 TIVA/LLD/spi_lld.c
* @brief TM4C123x/TM4C129x SPI subsystem low level driver.
*
* @addtogroup SPI
* @{
*/
#include "ch.h"
#include "hal.h"
#if HAL_USE_SPI || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/**
* @brief SPI1 driver identifier.
*/
#if TIVA_SPI_USE_SSI0 || defined(__DOXYGEN__)
SPIDriver SPID1;
#endif
/**
* @brief SPI2 driver identifier.
*/
#if TIVA_SPI_USE_SSI1 || defined(__DOXYGEN__)
SPIDriver SPID2;
#endif
/**
* @brief SPI3 driver identifier.
*/
#if TIVA_SPI_USE_SSI2 || defined(__DOXYGEN__)
SPIDriver SPID3;
#endif
/**
* @brief SPI4 driver identifier.
*/
#if TIVA_SPI_USE_SSI3 || defined(__DOXYGEN__)
SPIDriver SPID4;
#endif
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
static uint16_t dummytx;
static uint16_t dummyrx;
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/**
* @brief Common IRQ handler.
*
* @param[in] spip pointer to the @p SPIDriver object
*/
static void spi_serve_interrupt(SPIDriver *spip)
{
SSI_TypeDef *ssi = spip->ssi;
uint32_t mis = ssi->MIS;
uint32_t dmachis = UDMA->CHIS;
/* SPI error handling.*/
if ((mis & (TIVA_MIS_RORMIS | TIVA_MIS_RTMIS)) != 0) {
TIVA_SPI_SSI_ERROR_HOOK(spip);
}
if ( (dmachis & ( (1 << spip->dmarxnr) | (1 << spip->dmatxnr) ) ) ==
( (1 << spip->dmarxnr) | (1 << spip->dmatxnr) ) ) {
/* Clear DMA Channel interrupts.*/
UDMA->CHIS = (1 << spip->dmarxnr) | (1 << spip->dmatxnr);
/* Portable SPI ISR code defined in the high level driver, note, it is a
macro.*/
_spi_isr_code(spip);
}
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if TIVA_SPI_USE_SSI0 || defined(__DOXYGEN__)
/**
* @brief SSI0 interrupt handler.
*
* @isr
*/
OSAL_IRQ_HANDLER(TIVA_SSI0_HANDLER)
{
OSAL_IRQ_PROLOGUE();
spi_serve_interrupt(&SPID1);
OSAL_IRQ_EPILOGUE();
}
#endif
#if TIVA_SPI_USE_SSI1 || defined(__DOXYGEN__)
/**
* @brief SSI1 interrupt handler.
*
* @isr
*/
OSAL_IRQ_HANDLER(TIVA_SSI1_HANDLER)
{
OSAL_IRQ_PROLOGUE();
spi_serve_interrupt(&SPID2);
OSAL_IRQ_EPILOGUE();
}
#endif
#if TIVA_SPI_USE_SSI2 || defined(__DOXYGEN__)
/**
* @brief SSI2 interrupt handler.
*
* @isr
*/
OSAL_IRQ_HANDLER(TIVA_SSI2_HANDLER)
{
OSAL_IRQ_PROLOGUE();
spi_serve_interrupt(&SPID3);
OSAL_IRQ_EPILOGUE();
}
#endif
#if TIVA_SPI_USE_SSI3 || defined(__DOXYGEN__)
/**
* @brief SSI3 interrupt handler.
*
* @isr
*/
OSAL_IRQ_HANDLER(TIVA_SSI3_HANDLER)
{
OSAL_IRQ_PROLOGUE();
spi_serve_interrupt(&SPID4);
OSAL_IRQ_EPILOGUE();
}
#endif
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level SPI driver initialization.
*
* @notapi
*/
void spi_lld_init(void)
{
dummytx = 0xFFFF;
#if TIVA_SPI_USE_SSI0
spiObjectInit(&SPID1);
SPID1.ssi = SSI0;
SPID1.dmarxnr = TIVA_SPI_SSI0_RX_UDMA_CHANNEL;
SPID1.dmatxnr = TIVA_SPI_SSI0_TX_UDMA_CHANNEL;
SPID1.rxchnmap = TIVA_SPI_SSI0_RX_UDMA_MAPPING;
SPID1.txchnmap = TIVA_SPI_SSI0_TX_UDMA_MAPPING;
#endif
#if TIVA_SPI_USE_SSI1
spiObjectInit(&SPID2);
SPID2.ssi = SSI1;
SPID2.dmarxnr = TIVA_SPI_SSI1_RX_UDMA_CHANNEL;
SPID2.dmatxnr = TIVA_SPI_SSI1_TX_UDMA_CHANNEL;
SPID2.rxchnmap = TIVA_SPI_SSI1_RX_UDMA_MAPPING;
SPID2.txchnmap = TIVA_SPI_SSI1_TX_UDMA_MAPPING;
#endif
#if TIVA_SPI_USE_SSI2
spiObjectInit(&SPID3);
SPID3.ssi = SSI2;
SPID3.dmarxnr = TIVA_SPI_SSI2_RX_UDMA_CHANNEL;
SPID3.dmatxnr = TIVA_SPI_SSI2_TX_UDMA_CHANNEL;
SPID3.rxchnmap = TIVA_SPI_SSI2_RX_UDMA_MAPPING;
SPID3.txchnmap = TIVA_SPI_SSI2_TX_UDMA_MAPPING;
#endif
#if TIVA_SPI_USE_SSI3
spiObjectInit(&SPID4);
SPID4.ssi = SSI3;
SPID4.dmarxnr = TIVA_SPI_SSI3_RX_UDMA_CHANNEL;
SPID4.dmatxnr = TIVA_SPI_SSI3_TX_UDMA_CHANNEL;
SPID4.rxchnmap = TIVA_SPI_SSI3_RX_UDMA_MAPPING;
SPID4.txchnmap = TIVA_SPI_SSI3_TX_UDMA_MAPPING;
#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 (spip->state == SPI_STOP) {
/* Clock activation.*/
#if TIVA_SPI_USE_SSI0
if (&SPID1 == spip) {
bool b;
b = udmaChannelAllocate(spip->dmarxnr);
osalDbgAssert(!b, "channel already allocated");
b = udmaChannelAllocate(spip->dmatxnr);
osalDbgAssert(!b, "channel already allocated");
/* Enable SSI0 module.*/
SYSCTL->RCGCSSI |= (1 << 0);
while (!(SYSCTL->PRSSI & (1 << 0)))
;
nvicEnableVector(TIVA_SSI0_NUMBER, TIVA_SPI_SSI0_IRQ_PRIORITY);
}
#endif
#if TIVA_SPI_USE_SSI1
if (&SPID2 == spip) {
bool b;
b = udmaChannelAllocate(spip->dmarxnr);
osalDbgAssert(!b, "channel already allocated");
b = udmaChannelAllocate(spip->dmatxnr);
osalDbgAssert(!b, "channel already allocated");
/* Enable SSI0 module.*/
SYSCTL->RCGCSSI |= (1 << 1);
while (!(SYSCTL->PRSSI & (1 << 1)))
;
nvicEnableVector(TIVA_SSI1_NUMBER, TIVA_SPI_SSI1_IRQ_PRIORITY);
}
#endif
#if TIVASPI_USE_SSI2
if (&SPID2 == spip) {
bool b;
b = udmaChannelAllocate(spip->dmarxnr);
osalDbgAssert(!b, "channel already allocated");
b = udmaChannelAllocate(spip->dmatxnr);
osalDbgAssert(!b, "channel already allocated");
/* Enable SSI0 module.*/
SYSCTL->RCGCSSI |= (1 << 2);
while (!(SYSCTL->PRSSI & (1 << 2)))
;
nvicEnableVector(TIVA_SSI2_NUMBER, TIVA_SPI_SSI2_IRQ_PRIORITY);
}
#endif
#if TIVA_SPI_USE_SSI3
if (&SPID2 == spip) {
bool b;
b = udmaChannelAllocate(spip->dmarxnr);
osalDbgAssert(!b, "channel already allocated");
b = udmaChannelAllocate(spip->dmatxnr);
osalDbgAssert(!b, "channel already allocated");
/* Enable SSI0 module.*/
SYSCTL->RCGCSSI |= (1 << 3);
while (!(SYSCTL->PRSSI & (1 << 3)))
;
nvicEnableVector(TIVA_SSI3_NUMBER, TIVA_SPI_SSI3_IRQ_PRIORITY);
}
#endif
UDMA->CHMAP[spip->dmarxnr / 8] |= (spip->rxchnmap << (spip->dmarxnr % 8));
UDMA->CHMAP[spip->dmatxnr / 8] |= (spip->txchnmap << (spip->dmatxnr % 8));
}
/* Set master operation mode.*/
spip->ssi->CR1 = 0;
/* Clock configuration - System Clock.*/
spip->ssi->CC = 0;
/* Clear pending interrupts.*/
spip->ssi->ICR = TIVA_ICR_RTIC | TIVA_ICR_RORIC;
/* Enable Receive Time-Out and Receive Overrun Interrupts.*/
spip->ssi->IM = TIVA_IM_RTIM | TIVA_IM_RORIM;
/* Configure the clock prescale divisor.*/
spip->ssi->CPSR = spip->config->cpsr;
/* Serial clock rate, phase/polarity, data size, fixed SPI frame format.*/
spip->ssi->CR0 = (spip->config->cr0 & ~TIVA_CR0_FRF_MASK) | TIVA_CR0_FRF(0);
/* Enable SSI.*/
spip->ssi->CR1 |= TIVA_CR1_SSE;
/* Enable RX and TX DMA channels.*/
spip->ssi->DMACTL = (TIVA_DMACTL_TXDMAE | TIVA_DMACTL_RXDMAE);
}
/**
* @brief Deactivates the SPI peripheral.
*
* @param[in] spip pointer to the @p SPIDriver object
*
* @notapi
*/
void spi_lld_stop(SPIDriver *spip)
{
if (spip->state != SPI_STOP) {
spip->ssi->CR1 = 0;
spip->ssi->CR0 = 0;
spip->ssi->CPSR = 0;
udmaChannelRelease(spip->dmarxnr);
udmaChannelRelease(spip->dmatxnr);
#if TIVA_SPI_USE_SSI0
if (&SPID1 == spip) {
nvicDisableVector(TIVA_SSI0_NUMBER);
}
#endif
#if TIVA_SPI_USE_SSI1
if (&SPID2 == spip) {
nvicDisableVector(TIVA_SSI1_NUMBER);
}
#endif
#if TIVA_SPI_USE_SSI2
if (&SPID3 == spip) {
nvicDisableVector(TIVA_SSI2_NUMBER);
}
#endif
#if TIVA_SPI_USE_SSI3
if (&SPID4 == spip) {
nvicDisableVector(TIVA_SSI3_NUMBER);
}
#endif
}
}
/**
* @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)
{
palClearPad(spip->config->ssport, spip->config->sspad);
}
/**
* @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)
{
palSetPad(spip->config->ssport, spip->config->sspad);
}
/**
* @brief Ignores data on the SPI bus.
* @details This function transmits a series of idle words on the SPI bus and
* ignores the received data. This function can be invoked even
* when a slave select signal has not been yet asserted.
*
* @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)
{
tiva_udma_table_entry_t *primary = udmaControlTable.primary;
if ((spip->config->cr0 & TIVA_CR0_DSS_MASK) < 8) {
/* Configure for 8-bit transfers.*/
primary[spip->dmatxnr].srcendp = (volatile void *)&dummytx;
primary[spip->dmatxnr].dstendp = &spip->ssi->DR;
primary[spip->dmatxnr].chctl = UDMA_CHCTL_DSTSIZE_8 | UDMA_CHCTL_DSTINC_0 |
UDMA_CHCTL_SRCSIZE_8 | UDMA_CHCTL_SRCINC_0 |
UDMA_CHCTL_ARBSIZE_4 |
UDMA_CHCTL_XFERSIZE(n) |
UDMA_CHCTL_XFERMODE_BASIC;
primary[spip->dmarxnr].srcendp = &spip->ssi->DR;
primary[spip->dmarxnr].dstendp = &dummyrx;
primary[spip->dmarxnr].chctl = UDMA_CHCTL_DSTSIZE_8 | UDMA_CHCTL_DSTINC_0 |
UDMA_CHCTL_SRCSIZE_8 | UDMA_CHCTL_SRCINC_0 |
UDMA_CHCTL_ARBSIZE_4 |
UDMA_CHCTL_XFERSIZE(n) |
UDMA_CHCTL_XFERMODE_BASIC;
}
else {
/* Configure for 16-bit transfers.*/
primary[spip->dmatxnr].srcendp = (volatile void *)&dummytx;
primary[spip->dmatxnr].dstendp = &spip->ssi->DR;
primary[spip->dmatxnr].chctl = UDMA_CHCTL_DSTSIZE_16 | UDMA_CHCTL_DSTINC_0 |
UDMA_CHCTL_SRCSIZE_16 | UDMA_CHCTL_SRCINC_0 |
UDMA_CHCTL_ARBSIZE_4 |
UDMA_CHCTL_XFERSIZE(n) |
UDMA_CHCTL_XFERMODE_BASIC;
primary[spip->dmarxnr].srcendp = &spip->ssi->DR;
primary[spip->dmarxnr].dstendp = &dummyrx;
primary[spip->dmarxnr].chctl = UDMA_CHCTL_DSTSIZE_16 | UDMA_CHCTL_DSTINC_0 |
UDMA_CHCTL_SRCSIZE_16 | UDMA_CHCTL_SRCINC_0 |
UDMA_CHCTL_ARBSIZE_4 |
UDMA_CHCTL_XFERSIZE(n) |
UDMA_CHCTL_XFERMODE_BASIC;
}
dmaChannelSingleBurst(spip->dmatxnr);
dmaChannelPrimary(spip->dmatxnr);
dmaChannelPriorityDefault(spip->dmatxnr);
dmaChannelEnableRequest(spip->dmatxnr);
dmaChannelSingleBurst(spip->dmarxnr);
dmaChannelPrimary(spip->dmarxnr);
dmaChannelPriorityDefault(spip->dmarxnr);
dmaChannelEnableRequest(spip->dmarxnr);
/* Enable DMA channels, when the TX channel is enabled the transfer starts.*/
dmaChannelEnable(spip->dmarxnr);
dmaChannelEnable(spip->dmatxnr);
}
/**
* @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)
{
tiva_udma_table_entry_t *primary = udmaControlTable.primary;
if ((spip->config->cr0 & TIVA_CR0_DSS_MASK) < 8) {
/* Configure for 8-bit transfers.*/
primary[spip->dmatxnr].srcendp = (volatile void *)txbuf+n-1;
primary[spip->dmatxnr].dstendp = &spip->ssi->DR;
primary[spip->dmatxnr].chctl = UDMA_CHCTL_DSTSIZE_8 | UDMA_CHCTL_DSTINC_0 |
UDMA_CHCTL_SRCSIZE_8 | UDMA_CHCTL_SRCINC_8 |
UDMA_CHCTL_ARBSIZE_4 |
UDMA_CHCTL_XFERSIZE(n) |
UDMA_CHCTL_XFERMODE_BASIC;
primary[spip->dmarxnr].srcendp = &spip->ssi->DR;
primary[spip->dmarxnr].dstendp = rxbuf+n-1;
primary[spip->dmarxnr].chctl = UDMA_CHCTL_DSTSIZE_8 | UDMA_CHCTL_DSTINC_8 |
UDMA_CHCTL_SRCSIZE_8 | UDMA_CHCTL_SRCINC_0 |
UDMA_CHCTL_ARBSIZE_4 |
UDMA_CHCTL_XFERSIZE(n) |
UDMA_CHCTL_XFERMODE_BASIC;
}
else {
/* Configure for 16-bit transfers.*/
primary[spip->dmatxnr].srcendp = (volatile void *)txbuf+(n*2)-1;
primary[spip->dmatxnr].dstendp = &spip->ssi->DR;
primary[spip->dmatxnr].chctl = UDMA_CHCTL_DSTSIZE_16 | UDMA_CHCTL_DSTINC_0 |
UDMA_CHCTL_SRCSIZE_16 | UDMA_CHCTL_SRCINC_16 |
UDMA_CHCTL_ARBSIZE_4 |
UDMA_CHCTL_XFERSIZE(n) |
UDMA_CHCTL_XFERMODE_BASIC;
primary[spip->dmarxnr].srcendp = &spip->ssi->DR;
primary[spip->dmarxnr].dstendp = rxbuf+(n*2)-1;
primary[spip->dmarxnr].chctl = UDMA_CHCTL_DSTSIZE_16 | UDMA_CHCTL_DSTINC_16 |
UDMA_CHCTL_SRCSIZE_16 | UDMA_CHCTL_SRCINC_0 |
UDMA_CHCTL_ARBSIZE_4 |
UDMA_CHCTL_XFERSIZE(n) |
UDMA_CHCTL_XFERMODE_BASIC;
}
dmaChannelSingleBurst(spip->dmatxnr);
dmaChannelPrimary(spip->dmatxnr);
dmaChannelPriorityDefault(spip->dmatxnr);
dmaChannelEnableRequest(spip->dmatxnr);
dmaChannelSingleBurst(spip->dmarxnr);
dmaChannelPrimary(spip->dmarxnr);
dmaChannelPriorityDefault(spip->dmarxnr);
dmaChannelEnableRequest(spip->dmarxnr);
/* Enable DMA channels, when the TX channel is enabled the transfer starts.*/
dmaChannelEnable(spip->dmarxnr);
dmaChannelEnable(spip->dmatxnr);
}
/**
* @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)
{
tiva_udma_table_entry_t *primary = udmaControlTable.primary;
if ((spip->config->cr0 & TIVA_CR0_DSS_MASK) < 8) {
/* Configure for 8-bit transfers.*/
primary[spip->dmatxnr].srcendp = (volatile void *)txbuf+n-1;
primary[spip->dmatxnr].dstendp = &spip->ssi->DR;
primary[spip->dmatxnr].chctl = UDMA_CHCTL_DSTSIZE_8 | UDMA_CHCTL_DSTINC_0 |
UDMA_CHCTL_SRCSIZE_8 | UDMA_CHCTL_SRCINC_8 |
UDMA_CHCTL_ARBSIZE_4 |
UDMA_CHCTL_XFERSIZE(n) |
UDMA_CHCTL_XFERMODE_BASIC;
primary[spip->dmarxnr].dstendp = &spip->ssi->DR;
primary[spip->dmarxnr].srcendp = &dummyrx;
primary[spip->dmarxnr].chctl = UDMA_CHCTL_DSTSIZE_8 | UDMA_CHCTL_DSTINC_0 |
UDMA_CHCTL_SRCSIZE_8 | UDMA_CHCTL_SRCINC_0 |
UDMA_CHCTL_ARBSIZE_4 |
UDMA_CHCTL_XFERSIZE(n) |
UDMA_CHCTL_XFERMODE_BASIC;
}
else {
/* Configure for 16-bit transfers.*/
primary[spip->dmatxnr].srcendp = (volatile void *)txbuf+(n*2)-1;
primary[spip->dmatxnr].dstendp = &spip->ssi->DR;
primary[spip->dmatxnr].chctl = UDMA_CHCTL_DSTSIZE_16 | UDMA_CHCTL_DSTINC_0 |
UDMA_CHCTL_SRCSIZE_16 | UDMA_CHCTL_SRCINC_16 |
UDMA_CHCTL_ARBSIZE_4 |
UDMA_CHCTL_XFERSIZE(n) |
UDMA_CHCTL_XFERMODE_BASIC;
primary[spip->dmarxnr].dstendp = &spip->ssi->DR;
primary[spip->dmarxnr].srcendp = &dummyrx;
primary[spip->dmarxnr].chctl = UDMA_CHCTL_DSTSIZE_16 | UDMA_CHCTL_DSTINC_0 |
UDMA_CHCTL_SRCSIZE_16 | UDMA_CHCTL_SRCINC_0 |
UDMA_CHCTL_ARBSIZE_4 |
UDMA_CHCTL_XFERSIZE(n) |
UDMA_CHCTL_XFERMODE_BASIC;
}
dmaChannelSingleBurst(spip->dmatxnr);
dmaChannelPrimary(spip->dmatxnr);
dmaChannelPriorityDefault(spip->dmatxnr);
dmaChannelEnableRequest(spip->dmatxnr);
dmaChannelSingleBurst(spip->dmarxnr);
dmaChannelPrimary(spip->dmarxnr);
dmaChannelPriorityDefault(spip->dmarxnr);
dmaChannelEnableRequest(spip->dmarxnr);
/* Enable DMA channels, when the TX channel is enabled the transfer starts.*/
dmaChannelEnable(spip->dmarxnr);
dmaChannelEnable(spip->dmatxnr);
}
/**
* @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)
{
tiva_udma_table_entry_t *primary = udmaControlTable.primary;
if ((spip->config->cr0 & TIVA_CR0_DSS_MASK) < 8) {
/* Configure for 8-bit transfers.*/
primary[spip->dmatxnr].srcendp = (volatile void *)&dummytx;
primary[spip->dmatxnr].dstendp = &spip->ssi->DR;
primary[spip->dmatxnr].chctl = UDMA_CHCTL_DSTSIZE_8 | UDMA_CHCTL_DSTINC_0 |
UDMA_CHCTL_SRCSIZE_8 | UDMA_CHCTL_SRCINC_0 |
UDMA_CHCTL_ARBSIZE_4 |
UDMA_CHCTL_XFERSIZE(n) |
UDMA_CHCTL_XFERMODE_BASIC;
primary[spip->dmarxnr].srcendp = &spip->ssi->DR;
primary[spip->dmarxnr].dstendp = rxbuf+n-1;
primary[spip->dmarxnr].chctl = UDMA_CHCTL_DSTSIZE_8 | UDMA_CHCTL_DSTINC_8 |
UDMA_CHCTL_SRCSIZE_8 | UDMA_CHCTL_SRCINC_0 |
UDMA_CHCTL_ARBSIZE_4 |
UDMA_CHCTL_XFERSIZE(n) |
UDMA_CHCTL_XFERMODE_BASIC;
}
else {
/* Configure for 16-bit transfers.*/
primary[spip->dmatxnr].srcendp = (volatile void *)&dummytx;
primary[spip->dmatxnr].dstendp = &spip->ssi->DR;
primary[spip->dmatxnr].chctl = UDMA_CHCTL_DSTSIZE_16 | UDMA_CHCTL_DSTINC_0 |
UDMA_CHCTL_SRCSIZE_16 | UDMA_CHCTL_SRCINC_0 |
UDMA_CHCTL_ARBSIZE_4 |
UDMA_CHCTL_XFERSIZE(n) |
UDMA_CHCTL_XFERMODE_BASIC;
primary[spip->dmarxnr].srcendp = &spip->ssi->DR;
primary[spip->dmarxnr].dstendp = rxbuf+(n*2)-1;
primary[spip->dmarxnr].chctl = UDMA_CHCTL_DSTSIZE_16 | UDMA_CHCTL_DSTINC_16 |
UDMA_CHCTL_SRCSIZE_16 | UDMA_CHCTL_SRCINC_0 |
UDMA_CHCTL_ARBSIZE_4 |
UDMA_CHCTL_XFERSIZE(n) |
UDMA_CHCTL_XFERMODE_BASIC;
}
dmaChannelSingleBurst(spip->dmatxnr);
dmaChannelPrimary(spip->dmatxnr);
dmaChannelPriorityDefault(spip->dmatxnr);
dmaChannelEnableRequest(spip->dmatxnr);
dmaChannelSingleBurst(spip->dmarxnr);
dmaChannelPrimary(spip->dmarxnr);
dmaChannelPriorityDefault(spip->dmarxnr);
dmaChannelEnableRequest(spip->dmarxnr);
/* Enable DMA channels, when the TX channel is enabled the transfer starts.*/
dmaChannelEnable(spip->dmarxnr);
dmaChannelEnable(spip->dmatxnr);
}
/**
* @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.
*/
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame)
{
spip->ssi->DR = (uint32_t)frame;
while ((spip->ssi->SR & TIVA_SR_RNE) == 0)
;
return (uint16_t)spip->ssi->DR;
}
#endif /* HAL_USE_SPI */
/** @} */

View File

@ -0,0 +1,388 @@
/*
Copyright (C) 2014 Marco Veeneman
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 TIVA/LLD/spi_lld.h
* @brief TM4C123x/TM4C129x SPI subsystem low level driver.
*
* @addtogroup SPI
* @{
*/
#ifndef _SPI_LLD_H_
#define _SPI_LLD_H_
#if HAL_USE_SPI || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @name Control 0
* @{
*/
#define TIVA_CR0_DSS_MASK 0x0F
#define TIVA_CR0_DSS(n) ((n-1) << 0)
#define TIVA_CR0_FRF_MASK (3 << 4)
#define TIVA_CR0_FRF(n) ((n) << 4)
#define TIVA_CR0_SPO (1 << 6)
#define TIVA_CR0_SPH (1 << 7)
#define TIVA_CR0_SRC_MASK (0xFF << 8)
#define TIVA_CR0_SRC(n) ((n) << 8)
/** @} */
/**
* @name Control 1
* @{
*/
#define TIVA_CR1_LBM (1 << 0)
#define TIVA_CR1_SSE (1 << 1)
#define TIVA_CR1_MS (1 << 2)
#define TIVA_CR1_SOD (1 << 3)
#define TIVA_CR1_EOT (1 << 4)
/** @} */
/**
* @name Status
* @{
*/
#define TIVA_SR_TFE (1 << 0)
#define TIVA_SR_TNF (1 << 1)
#define TIVA_SR_RNE (1 << 2)
#define TIVA_SR_RFF (1 << 3)
#define TIVA_SR_BSY (1 << 4)
/** @} */
/**
* @name Interrupt Mask
* @{
*/
#define TIVA_IM_RORIM (1 << 0)
#define TIVA_IM_RTIM (1 << 1)
#define TIVA_IM_RXIM (1 << 2)
#define TIVA_IM_TXIM (1 << 3)
/** @} */
/**
* @name Interrupt Status
* @{
*/
#define TIVA_IS_RORIS (1 << 0)
#define TIVA_IS_RTIS (1 << 1)
#define TIVA_IS_RXIS (1 << 2)
#define TIVA_IS_TXIS (1 << 3)
/** @} */
/**
* @name Masked Interrupt Status
* @{
*/
#define TIVA_MIS_RORMIS (1 << 0)
#define TIVA_MIS_RTMIS (1 << 1)
#define TIVA_MIS_RXMIS (1 << 2)
#define TIVA_MIS_TXMIS (1 << 3)
/** @} */
/**
* @name Interrupt Clear
* @{
*/
#define TIVA_ICR_RORIC (1 << 0)
#define TIVA_ICR_RTIC (1 << 1)
/** @} */
/**
* @name DMA Control
* @{
*/
#define TIVA_DMACTL_RXDMAE (1 << 0)
#define TIVA_DMACTL_TXDMAE (1 << 1)
/** @}
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name Configuration options
* @{
*/
/**
* @brief SSI0 driver enable switch.
* @details If set to @p TRUE the support for SSI0 is included.
* @note The default is @p FALSE.
*/
#if !defined(TIVA_SPI_USE_SSI0) || defined(__DOXYGEN__)
#define TIVA_SPI_USE_SSI0 FALSE
#endif
/**
* @brief SSI1 driver enable switch.
* @details If set to @p TRUE the support for SSI1 is included.
* @note The default is @p FALSE.
*/
#if !defined(TIVA_SPI_USE_SSI1) || defined(__DOXYGEN__)
#define TIVA_SPI_USE_SSI1 FALSE
#endif
/**
* @brief SSI2 driver enable switch.
* @details If set to @p TRUE the support for SSI2 is included.
* @note The default is @p FALSE.
*/
#if !defined(TIVA_SPI_USE_SSI2) || defined(__DOXYGEN__)
#define TIVA_SPI_USE_SSI2 FALSE
#endif
/**
* @brief SSI3 driver enable switch.
* @details If set to @p TRUE the support for SSI3 is included.
* @note The default is @p FALSE.
*/
#if !defined(TIVA_SPI_USE_SSI3) || defined(__DOXYGEN__)
#define TIVA_SPI_USE_SSI3 FALSE
#endif
/**
* @brief SPID1 interrupt priority level setting.
*/
#if !defined(TIVA_SPI_SSI0_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define TIVA_SPI_SSI0_IRQ_PRIORITY 5
#endif
/**
* @brief SPID2 interrupt priority level setting.
*/
#if !defined(TIVA_SPI_SSI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define TIVA_SPI_SSI1_IRQ_PRIORITY 5
#endif
/**
* @brief SPID3 interrupt priority level setting.
*/
#if !defined(TIVA_SPI_SSI2_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define TIVA_SPI_SSI2_IRQ_PRIORITY 5
#endif
/**
* @brief SPID4 interrupt priority level setting.
*/
#if !defined(TIVA_SPI_SSI3_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define TIVA_SPI_SSI3_IRQ_PRIORITY 5
#endif
/**
* @brief SPI error hook.
*/
#if !defined(TIVA_SPI_SSI_ERROR_HOOK) || defined(__DOXYGEN__)
#define TIVA_SPI_SSI_ERROR_HOOK(spip) osalSysHalt("SSI failure")
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if TIVA_SPI_USE_SSI0 && !TIVA_HAS_SSI0
#error "SSI0 not present in the selected device"
#endif
#if TIVA_SPI_USE_SSI1 && !TIVA_HAS_SSI1
#error "SSI1 not present in the selected device"
#endif
#if TIVA_SPI_USE_SSI2 && !TIVA_HAS_SSI2
#error "SSI2 not present in the selected device"
#endif
#if TIVA_SPI_USE_SSI3 && !TIVA_HAS_SSI03
#error "SSI3 not present in the selected device"
#endif
#if !TIVA_SPI_USE_SSI0 && !TIVA_SPI_USE_SSI1 && !TIVA_SPI_USE_SSI2 && \
!TIVA_SPI_USE_SSI3
#error "SPI driver activated but no SSI peripheral assigned"
#endif
#if TIVA_SPI_USE_SSI0 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(TIVA_SPI_SSI0_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to SSI0"
#endif
#if TIVA_SPI_USE_SSI1 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(TIVA_SPI_SSI1_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to SSI1"
#endif
#if TIVA_SPI_USE_SSI2 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(TIVA_SPI_SSI2_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to SSI2"
#endif
#if TM4C123x_SPI_USE_SSI3 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(TIVA_SPI_SSI3_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to SSI3"
#endif
#if !defined(TIVA_UDMA_REQUIRED)
#define TIVA_UDMA_REQUIRED
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Type of a structure representing an SPI driver.
*/
typedef struct SPIDriver SPIDriver;
/**
* @brief SPI notification callback type.
*
* @param[in] spip pointer to the @p SPIDriver object triggering the
* callback
*/
typedef void (*spicallback_t)(SPIDriver *spip);
/**
* @brief Driver configuration structure.
*/
typedef struct {
/**
* @brief Operation complete callback or @p NULL.
*/
spicallback_t end_cb;
/* End of the mandatory fields.*/
/**
* @brief The chip select line port.
*/
ioportid_t ssport;
/**
* @brief The chip select line pad number.
*/
uint16_t sspad;
/**
* @brief SSI CR0 initialization data.
*/
uint16_t cr0;
/**
* @brief SSI CPSR initialization data.
*/
uint32_t cpsr;
} SPIConfig;
/**
* @brief Structure representing a SPI driver.
*/
struct SPIDriver {
/**
* @brief Driver state.
*/
spistate_t state;
/**
* @brief Current configuration data.
*/
const SPIConfig *config;
#if SPI_USE_WAIT || defined(__DOXYGEN__)
/**
* @brief Waiting thread.
*/
thread_reference_t thread;
#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the bus.
*/
mutex_t mutex;
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#if defined(SPI_DRIVER_EXT_FIELDS)
SPI_DRIVER_EXT_FIELDS
#endif
/* End of the mandatory fields.*/
/**
* @brief Pointer to the SSI registers block.
*/
SSI_TypeDef *ssi;
/**
* @brief Receive DMA channel number.
*/
uint8_t dmarxnr;
/**
* @brief Transmit DMA channel number.
*/
uint8_t dmatxnr;
/**
* @brief Receive DMA channel map.
*/
uint8_t rxchnmap;
/**
* @brief Transmit DMA channel map.
*/
uint8_t txchnmap;
};
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if TIVA_SPI_USE_SSI0 && !defined(__DOXYGEN__)
extern SPIDriver SPID1;
#endif
#if TIVA_SPI_USE_SSI1 && !defined(__DOXYGEN__)
extern SPIDriver SPID2;
#endif
#if TIVA_SPI_USE_SSI2 && !defined(__DOXYGEN__)
extern SPIDriver SPID3;
#endif
#if TIVA_SPI_USE_SSI3 && !defined(__DOXYGEN__)
extern SPIDriver SPID4;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void spi_lld_init(void);
void spi_lld_start(SPIDriver *spip);
void spi_lld_stop(SPIDriver *spip);
void spi_lld_select(SPIDriver *spip);
void spi_lld_unselect(SPIDriver *spip);
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);
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_SPI */
#endif /* _SPI_LLD_H_ */
/** @} */

View File

@ -0,0 +1,141 @@
/*
Copyright (C) 2014 Marco Veeneman
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.
*/
#include "hal.h"
/* The following macro is only defined if some driver requiring DMA services
has been enabled.*/
#if defined(TIVA_UDMA_REQUIRED) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
udmaControlTable_t udmaControlTable;
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
static uint32_t udma_channel_mask;
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if !defined(TIVA_UDMA_SW_HANDLER)
#error "TIVA_UDMA_SW_HANDLER not defined"
#endif
/**
* @brief UDMA software interrupt handler.
*
* @isr
*/
OSAL_IRQ_HANDLER(TIVA_UDMA_SW_HANDLER)
{
OSAL_IRQ_PROLOGUE();
/* TODO Process software transfer interrupts.*/
OSAL_IRQ_EPILOGUE();
}
#if !defined(TIVA_UDMA_ERR_HANDLER)
#error "TIVA_UDMA_ERR_HANDLER not defined"
#endif
/**
* @brief UDMA error interrupt handler.
*
* @isr
*/
OSAL_IRQ_HANDLER(TIVA_UDMA_ERR_HANDLER)
{
OSAL_IRQ_PROLOGUE();
/* TODO Do we need to halt the system on a DMA error?*/
if (UDMA->ERRCLR) {
UDMA->ERRCLR = 1;
}
OSAL_IRQ_EPILOGUE();
}
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Initialize UDMA.
*
* @init
*/
void udmaInit(void)
{
udma_channel_mask = 0;
/* Enable UDMA module.*/
SYSCTL->RCGCDMA = 1;
while (!(SYSCTL->PRDMA & (1 << 0)))
;
nvicEnableVector(TIVA_UDMA_ERR_NUMBER, TIVA_UDMA_ERR_IRQ_PRIORITY);
nvicEnableVector(TIVA_UDMA_SW_NUMBER, TIVA_UDMA_SW_IRQ_PRIORITY);
/* Enable UDMA controller.*/
UDMA->CFG = 1;
/* Set address of control table.*/
UDMA->CTLBASE = (uint32_t)udmaControlTable.primary;
}
/**
* @brief Allocates a DMA channel.
*
* @special
*/
bool udmaChannelAllocate(uint8_t dmach)
{
/* Checks if the channel is already taken.*/
if ((udma_channel_mask & (1 << dmach)) != 0)
return TRUE;
/* Mark channel as used */
udma_channel_mask |= (1 << dmach);
return FALSE;
}
/**
* @brief Releases a DMA channel.
*
* @special
*/
void udmaChannelRelease(uint8_t dmach)
{
/* Marks the channel as not used.*/
udma_channel_mask &= ~(1 << dmach);
}
#endif

View File

@ -0,0 +1,195 @@
/*
Copyright (C) 2014 Marco Veeneman
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.
*/
#ifndef TIVA_UDMA_H_
#define TIVA_UDMA_H_
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @name CHCTL register defines.
* @{
*/
#define UDMA_CHCTL_DSTINC_MASK 0xC0000000
#define UDMA_CHCTL_DSTINC_0 0xC0000000
#define UDMA_CHCTL_DSTINC_8 0x00000000
#define UDMA_CHCTL_DSTINC_16 0x40000000
#define UDMA_CHCTL_DSTINC_32 0x80000000
#define UDMA_CHCTL_DSTSIZE_MASK 0x30000000
#define UDMA_CHCTL_DSTSIZE_8 0x00000000
#define UDMA_CHCTL_DSTSIZE_16 0x10000000
#define UDMA_CHCTL_DSTSIZE_32 0x20000000
#define UDMA_CHCTL_SRCINC_MASK 0x0C000000
#define UDMA_CHCTL_SRCINC_0 0x0C000000
#define UDMA_CHCTL_SRCINC_8 0x00000000
#define UDMA_CHCTL_SRCINC_16 0x04000000
#define UDMA_CHCTL_SRCINC_32 0x08000000
#define UDMA_CHCTL_SRCSIZE_MASK 0x03000000
#define UDMA_CHCTL_SRCSIZE_8 0x00000000
#define UDMA_CHCTL_SRCSIZE_16 0x01000000
#define UDMA_CHCTL_SRCSIZE_32 0x02000000
#define UDMA_CHCTL_ARBSIZE_MASK 0x0003C000
#define UDMA_CHCTL_ARBSIZE_1 0x00000000
#define UDMA_CHCTL_ARBSIZE_2 0x00004000
#define UDMA_CHCTL_ARBSIZE_4 0x00008000
#define UDMA_CHCTL_ARBSIZE_8 0x0000C000
#define UDMA_CHCTL_ARBSIZE_16 0x00010000
#define UDMA_CHCTL_ARBSIZE_32 0x00014000
#define UDMA_CHCTL_ARBSIZE_64 0x00018000
#define UDMA_CHCTL_ARBSIZE_128 0x0001C000
#define UDMA_CHCTL_ARBSIZE_256 0x00020000
#define UDMA_CHCTL_ARBSIZE_512 0x00024000
#define UDMA_CHCTL_ARBSIZE_1024 0x00028000
#define UDMA_CHCTL_XFERSIZE_MASK 0x00003FF0
#define UDMA_CHCTL_XFERSIZE(n) ((n-1) << 4)
#define UDMA_CHCTL_NXTUSEBURST 0x00000008
#define UDMA_CHCTL_XFERMODE_MASK 0x00000007
#define UDMA_CHCTL_XFERMODE_STOP 0x00000000
#define UDMA_CHCTL_XFERMODE_BASIC 0x00000001
#define UDMA_CHCTL_XFERMODE_AUTO 0x00000002
#define UDMA_CHCTL_XFERMODE_PINGPONG 0x00000003
#define UDMA_CHCTL_XFERMODE_MSG 0x00000004
#define UDMA_CHCTL_XFERMODE_AMSG 0x00000005
#define UDMA_CHCTL_XFERMODE_PSG 0x00000006
#define UDMA_CHCTL_XFERMODE_APSG 0x00000007
/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief UDMA software interrupt priority level setting.
*/
#if !defined(TIVA_UDMA_SW_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define TIVA_UDMA_SW_IRQ_PRIORITY 5
#endif
/**
* @brief UDMA error interrupt priority level setting.
*/
#if !defined(TIVA_UDMA_ERR_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define TIVA_UDMA_ERR_IRQ_PRIORITY 5
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief A structure that defines an entry in the channel control table.
* @note These fields are used by the uDMA controller and normally it is not
* necessary for software to directly read or write fields in the
* table.
*/
typedef struct __attribute__((packed))
{
/**
* @brief The ending source address of the data transfer.
*/
volatile void *srcendp;
/**
* @brief The ending destination address of the data transfer.
*/
volatile void *dstendp;
/**
* @brief The channel control mode.
*/
volatile uint32_t chctl;
/**
* @brief An unused location.
*/
volatile uint32_t unused;
} tiva_udma_table_entry_t;
typedef struct __attribute__((packed, aligned(1024)))
{
union {
struct {
tiva_udma_table_entry_t primary[32];
tiva_udma_table_entry_t alternate[32];
};
uint8_t raw[1024];
};
} udmaControlTable_t ;
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
#define dmaChannelEnable(dmach) {\
UDMA->ENASET = (1 << dmach);\
}
#define dmaChannelDisable(dmach) { \
UDMA->ENACLR = (1 << dmach); \
}
#define dmaChannelPrimary(dmach) {\
UDMA->ALTCLR = (1 << dmach); \
}
#define dmaChannelAlternate(dmach) { \
UDMA->ALTSET = (1 << dmach); \
}
#define dmaChannelSingleBurst(dmach) { \
UDMA->USEBURSTCLR = (1 << dmach); \
}
#define dmaChannelBurstOnly(dmach) { \
UDMA->USEBURSTSET = (1 << dmach); \
}
#define dmaChannelPriorityHigh(dmach) { \
UDMA->PRIOSET = (1 << dmach); \
}
#define dmaChannelPriorityDefault(dmach) { \
UDMA->PRIOCLR = (1 << dmach); \
}
#define dmaChannelEnableRequest(dmach) {\
UDMA->REQMASKCLR = (1 << dmach); \
}
#define dmaChannelDisableRequest(dmach) {\
UDMA->REQMASKSET = (1 << dmach); \
}
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
extern udmaControlTable_t udmaControlTable;
#ifdef __cplusplus
extern "C" {
#endif
void udmaInit(void);
bool udmaChannelAllocate(uint8_t dmach);
void udmaChannelRelease(uint8_t dmach);
#ifdef __cplusplus
}
#endif
#endif /* TIVA_UDMA_H_ */

View File

@ -131,6 +131,10 @@ void tiva_clock_init(void)
#if HAL_USE_PWM
SYSCTL->RCC |= TIVA_PWM_FIELDS;
#endif
#if defined(TIVA_UDMA_REQUIRED)
udmaInit();
#endif
}
/**

View File

@ -349,6 +349,7 @@
/* Various helpers.*/
#include "nvic.h"
#include "tiva_isr.h"
#include "tiva_udma.h"
#ifdef __cplusplus
extern "C" {

View File

@ -6,7 +6,9 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/ports/common/ARMCMx/nvic.c \
${CHIBIOS}/community/os/hal/ports/TIVA/LLD/serial_lld.c \
${CHIBIOS}/community/os/hal/ports/TIVA/LLD/i2c_lld.c \
${CHIBIOS}/community/os/hal/ports/TIVA/LLD/gpt_lld.c \
${CHIBIOS}/community/os/hal/ports/TIVA/LLD/pwm_lld.c
${CHIBIOS}/community/os/hal/ports/TIVA/LLD/pwm_lld.c \
${CHIBIOS}/community/os/hal/ports/TIVA/LLD/spi_lld.c \
${CHISIOS}/community/os/hal/ports/TIVA/LLD/tiva_udma.c
# Required include directories
PLATFORMINC = ${CHIBIOS}/os/hal/ports/common/ARMCMx \

View File

@ -34,6 +34,13 @@
* @{
*/
/* UDMA units.*/
#define TIVA_UDMA_SW_HANDLER VectorF8
#define TIVA_UDMA_ERR_HANDLER VectorFC
#define TIVA_UDMA_SW_NUMBER 46
#define TIVA_UDMA_ERR_NUMBER 47
/* GPIO units.*/
#if defined(TM4C1230C3PM) || defined(TM4C1230D5PM) || defined(TM4C1230E6PM) \
|| defined(TM4C1230H6PM) || defined(TM4C1232C3PM) || defined(TM4C1232D5PM) \

View File

@ -505,7 +505,8 @@ typedef struct
*/
typedef struct
{
__IO uint32_t CR[2]; /**< Control 0, 1 */
__IO uint32_t CR0; /**< Control 0 */
__IO uint32_t CR1; /**< Control 1 */
__IO uint32_t DR; /**< Data */
__I uint32_t SR; /**< Status */
__IO uint32_t CPSR; /**< Clock Prescale */
@ -742,11 +743,16 @@ typedef struct
__IO uint32_t ALTBASE; /**< Alternate Channel Control Base Pointer */
__IO uint32_t WAITSTAT; /**< Channel Wait-on-Request Status */
__O uint32_t SWREQ; /**< Channel Software Request */
UDMA_SC_t USEBURST; /**< Channel Useburst registers */
UDMA_SC_t REQMASK; /**< Channel Request Mask registers */
UDMA_SC_t ENA; /**< Channel Enable registers */
UDMA_SC_t ALT; /**< Channel Primary Alternate registers */
UDMA_SC_t PRIO; /**< Channel Priority registers */
__IO uint32_t USEBURSTSET; /**< Channel Useburst Set */
__O uint32_t USEBURSTCLR; /**< Channel Useburst Clear */
__IO uint32_t REQMASKSET; /**< Channel Request Mask Set */
__O uint32_t REQMASKCLR; /**< Channel Request Mask Clear */
__IO uint32_t ENASET; /**< Channel Enable Set */
__O uint32_t ENACLR; /**< Channel Enable Clear */
__IO uint32_t ALTSET; /**< Channel Primary Alternate Set */
__O uint32_t ALTCLR; /**< Channel Primary Alternate Clear */
__IO uint32_t PRIOSET; /**< Channel Priority Set */
__O uint32_t PRIOCLR; /**< Channel Priority Clear */
__I uint32_t _RESERVED0[3]; /**< Reserved */
__IO uint32_t ERRCLR; /**< Bus Error Clear */
__I uint32_t _RESERVED1[300];/**< Reserved */

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?>
<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="0.114656749">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.114656749" moduleId="org.eclipse.cdt.core.settings" name="Default">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildProperties="" description="" id="0.114656749" name="Default" parent="org.eclipse.cdt.build.core.prefbase.cfg">
<folderInfo id="0.114656749." name="/" resourcePath="">
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.1182750861" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
<targetPlatform id="org.eclipse.cdt.build.core.prefbase.toolchain.1182750861.169007201" name=""/>
<builder autoBuildTarget="all" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="org.eclipse.cdt.build.core.settings.default.builder.579570726" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.2143276802" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
<tool id="org.eclipse.cdt.build.core.settings.holder.1873650595" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1337802279" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
<tool id="org.eclipse.cdt.build.core.settings.holder.1707090075" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.338985256" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
<tool id="org.eclipse.cdt.build.core.settings.holder.1165165914" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.714476670" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="TM4C123x-SPI.null.1703860681" name="TM4C123x-SPI"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="0.114656749">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope"/>
</cproject>

View File

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>TM4C123x-SPI</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
<dictionary>
<key>?name?</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.append_environment</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
<value>all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildArguments</key>
<value>-j1</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildCommand</key>
<value>make</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
<value>clean</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.contents</key>
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
<value>false</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
<value>all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.stopOnError</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
<value>true</value>
</dictionary>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
<linkedResources>
<link>
<name>board</name>
<type>2</type>
<locationURI>CHIBIOS3/community/os/hal/boards/TI_TM4C123G_LAUNCHPAD</locationURI>
</link>
<link>
<name>community_os</name>
<type>2</type>
<locationURI>CHIBIOS3/community/os</locationURI>
</link>
<link>
<name>os</name>
<type>2</type>
<locationURI>CHIBIOS3/os</locationURI>
</link>
<link>
<name>test</name>
<type>2</type>
<locationURI>CHIBIOS3/test</locationURI>
</link>
</linkedResources>
<variableList>
<variable>
<name>CHIBIOS3</name>
<value>file:/C:/ChibiStudio/chibios3</value>
</variable>
</variableList>
</projectDescription>

View File

@ -0,0 +1,197 @@
##############################################################################
# Build global options
# NOTE: Can be overridden externally.
#
# Compiler options here.
ifeq ($(USE_OPT),)
USE_OPT = -O0 -ggdb -fomit-frame-pointer -falign-functions=16
endif
# C specific options here (added to USE_OPT).
ifeq ($(USE_COPT),)
USE_COPT =
endif
# C++ specific options here (added to USE_OPT).
ifeq ($(USE_CPPOPT),)
USE_CPPOPT = -fno-rtti
endif
# Enable this if you want the linker to remove unused code and data
ifeq ($(USE_LINK_GC),)
USE_LINK_GC = yes
endif
# Enable this if you want link time optimizations (LTO)
ifeq ($(USE_LTO),)
USE_LTO = yes
endif
# If enabled, this option allows to compile the application in THUMB mode.
ifeq ($(USE_THUMB),)
USE_THUMB = yes
endif
# Enable this if you want to see the full log while compiling.
ifeq ($(USE_VERBOSE_COMPILE),)
USE_VERBOSE_COMPILE = no
endif
#
# Build global options
##############################################################################
##############################################################################
# Architecture or project specific options
#
# Stack size to be allocated to the Cortex-M process stack. This stack is
# the stack used by the main() thread.
ifeq ($(USE_PROCESS_STACKSIZE),)
USE_PROCESS_STACKSIZE = 0x400
endif
# Stack size to the allocated to the Cortex-M main/exceptions stack. This
# stack is used for processing interrupts and exceptions.
ifeq ($(USE_EXCEPTIONS_STACKSIZE),)
USE_EXCEPTIONS_STACKSIZE = 0x400
endif
# Enables the use of FPU on Cortex-M4.
ifeq ($(USE_FPU),)
USE_FPU = no
endif
#
# Architecture or project specific options
##############################################################################
##############################################################################
# Project, sources and paths
#
# Define project name here
PROJECT = ch
# Imported source files and paths
CHIBIOS = ../../../../..
include $(CHIBIOS)/os/hal/hal.mk
include $(CHIBIOS)/community/os/hal/boards/TI_TM4C123G_LAUNCHPAD/board.mk
include $(CHIBIOS)/community/os/hal/ports/TIVA/TM4C123x/platform.mk
include $(CHIBIOS)/os/hal/osal/rt/osal.mk
include $(CHIBIOS)/os/rt/rt.mk
include $(CHIBIOS)/community/os/rt/ports/ARMCMx/compilers/GCC/mk/port_tm4c123x.mk
# Define linker script file here
LDSCRIPT= $(PORTLD)/TM4C123xH6.ld
# C sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
CSRC = $(PORTSRC) \
$(KERNSRC) \
$(TESTSRC) \
$(HALSRC) \
$(OSALSRC) \
$(PLATFORMSRC) \
$(BOARDSRC) \
main.c
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
CPPSRC =
# C sources to be compiled in ARM mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
ACSRC =
# C++ sources to be compiled in ARM mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
ACPPSRC =
# C sources to be compiled in THUMB mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
TCSRC =
# C sources to be compiled in THUMB mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
TCPPSRC =
# List ASM source files here
ASMSRC = $(PORTASM)
INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \
$(HALINC) $(OSALINC) $(PLATFORMINC) $(BOARDINC) \
$(CHIBIOS)/os/various
#
# Project, sources and paths
##############################################################################
##############################################################################
# Compiler settings
#
MCU = cortex-m4
#TRGT = arm-elf-
TRGT = arm-none-eabi-
CC = $(TRGT)gcc
CPPC = $(TRGT)g++
# Enable loading with g++ only if you need C++ runtime support.
# NOTE: You can use C++ even without C++ support if you are careful. C++
# runtime support makes code size explode.
LD = $(TRGT)gcc
#LD = $(TRGT)g++
CP = $(TRGT)objcopy
AS = $(TRGT)gcc -x assembler-with-cpp
OD = $(TRGT)objdump
SZ = $(TRGT)size
HEX = $(CP) -O ihex
BIN = $(CP) -O binary
# ARM-specific options here
AOPT =
# THUMB-specific options here
TOPT = -mthumb -DTHUMB
# Define C warning options here
CWARN = -Wall -Wextra -Wstrict-prototypes
# Define C++ warning options here
CPPWARN = -Wall -Wextra
#
# Compiler settings
##############################################################################
##############################################################################
# Start of user section
#
# List all user C define here, like -D_DEBUG=1
UDEFS =
# Define ASM defines here
UADEFS =
# List all user directories here
UINCDIR =
# List the user directory to look for the libraries here
ULIBDIR =
# List all user libraries here
ULIBS =
#
# End of user defines
##############################################################################
RULESPATH = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC
include $(RULESPATH)/rules.mk

View File

@ -0,0 +1,468 @@
#ifndef _CHCONF_H_
#define _CHCONF_H_
/*===========================================================================*/
/**
* @name System timers settings
* @{
*/
/*===========================================================================*/
/**
* @brief System time counter resolution.
* @note Allowed values are 16 or 32 bits.
*/
#define CH_CFG_ST_RESOLUTION 32
/**
* @brief System tick frequency.
* @details Frequency of the system timer that drives the system ticks. This
* setting also defines the system tick time unit.
*/
#define CH_CFG_ST_FREQUENCY 10000
/**
* @brief Time delta constant for the tick-less mode.
* @note If this value is zero then the system uses the classic
* periodic tick. This value represents the minimum number
* of ticks that is safe to specify in a timeout directive.
* The value one is not valid, timeouts are rounded up to
* this value.
*/
#define CH_CFG_ST_TIMEDELTA 0
/**
* @brief Realtime Counter frequency.
* @details Frequency of the system counter used for realtime delays and
* measurements.
*/
#define CH_CFG_RTC_FREQUENCY 80000000
/** @} */
/*===========================================================================*/
/**
* @name Kernel parameters and options
* @{
*/
/*===========================================================================*/
/**
* @brief Round robin interval.
* @details This constant is the number of system ticks allowed for the
* threads before preemption occurs. Setting this value to zero
* disables the preemption for threads with equal priority and the
* round robin becomes cooperative. Note that higher priority
* threads can still preempt, the kernel is always preemptive.
* @note Disabling the round robin preemption makes the kernel more compact
* and generally faster.
* @note The round robin preemption is not supported in tickless mode and
* must be set to zero in that case.
*/
#define CH_CFG_TIME_QUANTUM 0
/**
* @brief Managed RAM size.
* @details Size of the RAM area to be managed by the OS. If set to zero
* then the whole available RAM is used. The core memory is made
* available to the heap allocator and/or can be used directly through
* the simplified core memory allocator.
*
* @note In order to let the OS manage the whole RAM the linker script must
* provide the @p __heap_base__ and @p __heap_end__ symbols.
* @note Requires @p CH_CFG_USE_MEMCORE.
*/
#define CH_CFG_MEMCORE_SIZE 0
/**
* @brief Idle thread automatic spawn suppression.
* @details When this option is activated the function @p chSysInit()
* does not spawn the idle thread. The application @p main()
* function becomes the idle thread and must implement an
* infinite loop. */
#define CH_CFG_NO_IDLE_THREAD FALSE
/** @} */
/*===========================================================================*/
/**
* @name Performance options
* @{
*/
/*===========================================================================*/
/**
* @brief OS optimization.
* @details If enabled then time efficient rather than space efficient code
* is used when two possible implementations exist.
*
* @note This is not related to the compiler optimization options.
* @note The default is @p TRUE.
*/
#define CH_CFG_OPTIMIZE_SPEED TRUE
/** @} */
/*===========================================================================*/
/**
* @name Subsystem options
* @{
*/
/*===========================================================================*/
/**
* @brief Time Measurement APIs.
* @details If enabled then the time measurement APIs are included in
* the kernel.
*
* @note The default is @p TRUE.
*/
#define CH_CFG_USE_TM TRUE
/**
* @brief Threads registry APIs.
* @details If enabled then the registry APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#define CH_CFG_USE_REGISTRY TRUE
/**
* @brief Threads synchronization APIs.
* @details If enabled then the @p chThdWait() function is included in
* the kernel.
*
* @note The default is @p TRUE.
*/
#define CH_CFG_USE_WAITEXIT TRUE
/**
* @brief Semaphores APIs.
* @details If enabled then the Semaphores APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#define CH_CFG_USE_SEMAPHORES TRUE
/**
* @brief Semaphores queuing mode.
* @details If enabled then the threads are enqueued on semaphores by
* priority rather than in FIFO order.
*
* @note The default is @p FALSE. Enable this if you have special
* requirements.
* @note Requires @p CH_CFG_USE_SEMAPHORES.
*/
#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE
/**
* @brief Mutexes APIs.
* @details If enabled then the mutexes APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#define CH_CFG_USE_MUTEXES TRUE
/**
* @brief Conditional Variables APIs.
* @details If enabled then the conditional variables APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_CFG_USE_MUTEXES.
*/
#define CH_CFG_USE_CONDVARS TRUE
/**
* @brief Conditional Variables APIs with timeout.
* @details If enabled then the conditional variables APIs with timeout
* specification are included in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_CFG_USE_CONDVARS.
*/
#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE
/**
* @brief Events Flags APIs.
* @details If enabled then the event flags APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#define CH_CFG_USE_EVENTS TRUE
/**
* @brief Events Flags APIs with timeout.
* @details If enabled then the events APIs with timeout specification
* are included in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_CFG_USE_EVENTS.
*/
#define CH_CFG_USE_EVENTS_TIMEOUT TRUE
/**
* @brief Synchronous Messages APIs.
* @details If enabled then the synchronous messages APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
*/
#define CH_CFG_USE_MESSAGES TRUE
/**
* @brief Synchronous Messages queuing mode.
* @details If enabled then messages are served by priority rather than in
* FIFO order.
*
* @note The default is @p FALSE. Enable this if you have special
* requirements.
* @note Requires @p CH_CFG_USE_MESSAGES.
*/
#define CH_CFG_USE_MESSAGES_PRIORITY FALSE
/**
* @brief Mailboxes APIs.
* @details If enabled then the asynchronous messages (mailboxes) APIs are
* included in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_CFG_USE_SEMAPHORES.
*/
#define CH_CFG_USE_MAILBOXES TRUE
/**
* @brief I/O Queues APIs.
* @details If enabled then the I/O queues APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#define CH_CFG_USE_QUEUES TRUE
/**
* @brief Core Memory Manager APIs.
* @details If enabled then the core memory manager APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
*/
#define CH_CFG_USE_MEMCORE TRUE
/**
* @brief Heap Allocator APIs.
* @details If enabled then the memory heap allocator APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or
* @p CH_CFG_USE_SEMAPHORES.
* @note Mutexes are recommended.
*/
#define CH_CFG_USE_HEAP TRUE
/**
* @brief Memory Pools Allocator APIs.
* @details If enabled then the memory pools allocator APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
*/
#define CH_CFG_USE_MEMPOOLS TRUE
/**
* @brief Dynamic Threads APIs.
* @details If enabled then the dynamic threads creation APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_CFG_USE_WAITEXIT.
* @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS.
*/
#define CH_CFG_USE_DYNAMIC TRUE
/** @} */
/*===========================================================================*/
/**
* @name Debug options
* @{
*/
/*===========================================================================*/
/**
* @brief Debug option, kernel statistics.
*
* @note The default is @p FALSE.
*/
#define CH_DBG_STATISTICS FALSE
/**
* @brief Debug option, system state check.
* @details If enabled the correct call protocol for system APIs is checked
* at runtime.
*
* @note The default is @p FALSE.
*/
#define CH_DBG_SYSTEM_STATE_CHECK FALSE
/**
* @brief Debug option, parameters checks.
* @details If enabled then the checks on the API functions input
* parameters are activated.
*
* @note The default is @p FALSE.
*/
#define CH_DBG_ENABLE_CHECKS FALSE
/**
* @brief Debug option, consistency checks.
* @details If enabled then all the assertions in the kernel code are
* activated. This includes consistency checks inside the kernel,
* runtime anomalies and port-defined checks.
*
* @note The default is @p FALSE.
*/
#define CH_DBG_ENABLE_ASSERTS FALSE
/**
* @brief Debug option, trace buffer.
* @details If enabled then the context switch circular trace buffer is
* activated.
*
* @note The default is @p FALSE.
*/
#define CH_DBG_ENABLE_TRACE FALSE
/**
* @brief Debug option, stack checks.
* @details If enabled then a runtime stack check is performed.
*
* @note The default is @p FALSE.
* @note The stack check is performed in a architecture/port dependent way.
* It may not be implemented or some ports.
* @note The default failure mode is to halt the system with the global
* @p panic_msg variable set to @p NULL.
*/
#define CH_DBG_ENABLE_STACK_CHECK FALSE
/**
* @brief Debug option, stacks initialization.
* @details If enabled then the threads working area is filled with a byte
* value when a thread is created. This can be useful for the
* runtime measurement of the used stack.
*
* @note The default is @p FALSE.
*/
#define CH_DBG_FILL_THREADS FALSE
/**
* @brief Debug option, threads profiling.
* @details If enabled then a field is added to the @p thread_t structure that
* counts the system ticks occurred while executing the thread.
*
* @note The default is @p FALSE.
* @note This debug option is not currently compatible with the
* tickless mode.
*/
#define CH_DBG_THREADS_PROFILING FALSE
/** @} */
/*===========================================================================*/
/**
* @name Kernel hooks
* @{
*/
/*===========================================================================*/
/**
* @brief Threads descriptor structure extension.
* @details User fields added to the end of the @p thread_t structure.
*/
#define CH_CFG_THREAD_EXTRA_FIELDS \
/* Add threads custom fields here.*/
/**
* @brief Threads initialization hook.
* @details User initialization code added to the @p chThdInit() API.
*
* @note It is invoked from within @p chThdInit() and implicitly from all
* the threads creation APIs.
*/
#define CH_CFG_THREAD_INIT_HOOK(tp) { \
/* Add threads initialization code here.*/ \
}
/**
* @brief Threads finalization hook.
* @details User finalization code added to the @p chThdExit() API.
*
* @note It is inserted into lock zone.
* @note It is also invoked when the threads simply return in order to
* terminate.
*/
#define CH_CFG_THREAD_EXIT_HOOK(tp) { \
/* Add threads finalization code here.*/ \
}
/**
* @brief Context switch hook.
* @details This hook is invoked just before switching between threads.
*/
#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \
/* System halt code here.*/ \
}
/**
* @brief Idle thread enter hook.
* @note This hook is invoked within a critical zone, no OS functions
* should be invoked from here.
* @note This macro can be used to activate a power saving mode.
*/
#define CH_CFG_IDLE_ENTER_HOOK() { \
}
/**
* @brief Idle thread leave hook.
* @note This hook is invoked within a critical zone, no OS functions
* should be invoked from here.
* @note This macro can be used to deactivate a power saving mode.
*/
#define CH_CFG_IDLE_LEAVE_HOOK() { \
}
/**
* @brief Idle Loop hook.
* @details This hook is continuously invoked by the idle thread loop.
*/
#define CH_CFG_IDLE_LOOP_HOOK() { \
/* Idle loop code here.*/ \
}
/**
* @brief System tick event hook.
* @details This hook is invoked in the system tick handler immediately
* after processing the virtual timers queue.
*/
#define CH_CFG_SYSTEM_TICK_HOOK() { \
/* System tick event code here.*/ \
}
/**
* @brief System halt hook.
* @details This hook is invoked in case to a system halting error before
* the system is halted.
*/
#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \
/* System halt code here.*/ \
}
/** @} */
/*===========================================================================*/
/* Port-specific settings (override port settings defaulted in chcore.h). */
/*===========================================================================*/
#endif /* _CHCONF_H_ */
/** @} */

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramLaunchConfigurationType">
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.ui.externaltools.launchGroup"/>
</listAttribute>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LAUNCH_CONFIGURATION_BUILD_SCOPE" value="${none}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${eclipse_home}\..\tools\openocd\bin\openocd.exe"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-c &quot;telnet_port 4444&quot; -f &quot;interface/ti-icdi.cfg&quot; -f &quot;${file_prompt}&quot;"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${eclipse_home}\..\tools\openocd\bin\"/>
</launchConfiguration>

View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.cdt.debug.gdbjtag.launchConfigurationType">
<stringAttribute key="bad_container_name" value="\TM4C123x-SPI\debug"/>
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.delay" value="1"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doHalt" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doReset" value="true"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.initCommands" value="monitor reset halt&#13;&#10;monitor reset init"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="Generic TCP/IP"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="3333"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.runCommands" value=""/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/>
<stringAttribute key="org.eclipse.cdt.debug.mi.core.DEBUG_NAME" value="arm-none-eabi-gdb"/>
<stringAttribute key="org.eclipse.cdt.debug.mi.core.commandFactory" value="Standard"/>
<stringAttribute key="org.eclipse.cdt.debug.mi.core.protocol" value="mi"/>
<booleanAttribute key="org.eclipse.cdt.debug.mi.core.verboseMode" value="false"/>
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="arm-none-eabi-gdb"/>
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
<stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&lt;contentList&gt;&lt;content id=&quot;dmachis-spi_serve_interrupt-(format)&quot; val=&quot;0&quot;/&gt;&lt;/contentList&gt;"/>
<stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;globalVariableList/&gt;&#13;&#10;"/>
<stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;memoryBlockExpressionList/&gt;&#13;&#10;"/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="./build/ch.elf"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="TM4C123x-SPI"/>
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="0.114656749"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/TM4C123x-SPI"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
</listAttribute>
</launchConfiguration>

View File

@ -0,0 +1,278 @@
#ifndef _HALCONF_H_
#define _HALCONF_H_
#include "mcuconf.h"
/**
* @brief Enables the PAL subsystem.
*/
#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
#define HAL_USE_PAL TRUE
#endif
/**
* @brief Enables the ADC subsystem.
*/
#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
#define HAL_USE_ADC FALSE
#endif
/**
* @brief Enables the CAN subsystem.
*/
#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
#define HAL_USE_CAN FALSE
#endif
/**
* @brief Enables the EXT subsystem.
*/
#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__)
#define HAL_USE_EXT FALSE
#endif
/**
* @brief Enables the GPT subsystem.
*/
#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
#define HAL_USE_GPT FALSE
#endif
/**
* @brief Enables the I2C subsystem.
*/
#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
#define HAL_USE_I2C FALSE
#endif
/**
* @brief Enables the ICU subsystem.
*/
#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
#define HAL_USE_ICU FALSE
#endif
/**
* @brief Enables the MAC subsystem.
*/
#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
#define HAL_USE_MAC FALSE
#endif
/**
* @brief Enables the MMC_SPI subsystem.
*/
#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
#define HAL_USE_MMC_SPI FALSE
#endif
/**
* @brief Enables the PWM subsystem.
*/
#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
#define HAL_USE_PWM FALSE
#endif
/**
* @brief Enables the RTC subsystem.
*/
#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
#define HAL_USE_RTC FALSE
#endif
/**
* @brief Enables the SDC subsystem.
*/
#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
#define HAL_USE_SDC FALSE
#endif
/**
* @brief Enables the SERIAL subsystem.
*/
#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
#define HAL_USE_SERIAL FALSE
#endif
/**
* @brief Enables the SERIAL over USB subsystem.
*/
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
#define HAL_USE_SERIAL_USB FALSE
#endif
/**
* @brief Enables the SPI subsystem.
*/
#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
#define HAL_USE_SPI TRUE
#endif
/**
* @brief Enables the UART subsystem.
*/
#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
#define HAL_USE_UART FALSE
#endif
/**
* @brief Enables the USB subsystem.
*/
#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
#define HAL_USE_USB FALSE
#endif
/*===========================================================================*/
/* ADC driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
#define ADC_USE_WAIT TRUE
#endif
/**
* @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define ADC_USE_MUTUAL_EXCLUSION TRUE
#endif
/*===========================================================================*/
/* CAN driver related settings. */
/*===========================================================================*/
/**
* @brief Sleep mode related APIs inclusion switch.
*/
#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
#define CAN_USE_SLEEP_MODE TRUE
#endif
/*===========================================================================*/
/* I2C driver related settings. */
/*===========================================================================*/
/**
* @brief Enables the mutual exclusion APIs on the I2C bus.
*/
#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define I2C_USE_MUTUAL_EXCLUSION TRUE
#endif
/*===========================================================================*/
/* MAC driver related settings. */
/*===========================================================================*/
/**
* @brief Enables an event sources for incoming packets.
*/
#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
#define MAC_USE_ZERO_COPY FALSE
#endif
/**
* @brief Enables an event sources for incoming packets.
*/
#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
#define MAC_USE_EVENTS TRUE
#endif
/*===========================================================================*/
/* MMC_SPI driver related settings. */
/*===========================================================================*/
/**
* @brief Delays insertions.
* @details If enabled this options inserts delays into the MMC waiting
* routines releasing some extra CPU time for the threads with
* lower priority, this may slow down the driver a bit however.
* This option is recommended also if the SPI driver does not
* use a DMA channel and heavily loads the CPU.
*/
#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
#define MMC_NICE_WAITING TRUE
#endif
/*===========================================================================*/
/* SDC driver related settings. */
/*===========================================================================*/
/**
* @brief Number of initialization attempts before rejecting the card.
* @note Attempts are performed at 10mS intervals.
*/
#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
#define SDC_INIT_RETRY 100
#endif
/**
* @brief Include support for MMC cards.
* @note MMC support is not yet implemented so this option must be kept
* at @p FALSE.
*/
#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
#define SDC_MMC_SUPPORT FALSE
#endif
/**
* @brief Delays insertions.
* @details If enabled this options inserts delays into the MMC waiting
* routines releasing some extra CPU time for the threads with
* lower priority, this may slow down the driver a bit however.
*/
#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
#define SDC_NICE_WAITING TRUE
#endif
/*===========================================================================*/
/* SERIAL driver related settings. */
/*===========================================================================*/
/**
* @brief Default bit rate.
* @details Configuration parameter, this is the baud rate selected for the
* default configuration.
*/
#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
#define SERIAL_DEFAULT_BITRATE 38400
#endif
/**
* @brief Serial buffers size.
* @details Configuration parameter, you can change the depth of the queue
* buffers depending on the requirements of your application.
* @note The default is 64 bytes for both the transmission and receive
* buffers.
*/
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define SERIAL_BUFFERS_SIZE 16
#endif
/*===========================================================================*/
/* SPI driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
#define SPI_USE_WAIT TRUE
#endif
/**
* @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define SPI_USE_MUTUAL_EXCLUSION TRUE
#endif
#endif /* _HALCONF_H_ */
/** @} */

View File

@ -0,0 +1,142 @@
/*
Copyright (C) 2014 Marco Veeneman
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.
*/
#include "ch.h"
#include "hal.h"
/*
* SPI TX and RX buffers.
*/
static uint8_t txbuf[512];
static uint8_t rxbuf[512];
/*
* High speed SPI configuration (5MHZ, CPHA=0, CPOL=0).
*/
static const SPIConfig hs_spicfg =
{
NULL,
GPIOA,
3,
TIVA_CR0_DSS(8) | /*TIVA_CR0_SPH | TIVA_CR_SPO |*/ TIVA_CR0_SRC(0),
16
};
/*
* Low speed SPI configuration (1MHz, CPHA=0, CPOL=0).
*/
static const SPIConfig ls_spicfg =
{
NULL,
GPIOA,
3,
TIVA_CR0_DSS(8) | /*TIVA_CR0_SPH | TIVA_CR_SPO |*/ TIVA_CR0_SRC(0),
80
};
/*
* SPI bus contender 1.
*/
static THD_WORKING_AREA(spi_thread_1_wa, 256);
static msg_t spi_thread_1(void *p)
{
(void)p;
chRegSetThreadName("SPI thread 1");
while (TRUE) {
spiAcquireBus(&SPID1); /* Acquire ownership of the bus. */
palSetPad(GPIOF, GPIOF_LED_GREEN); /* LED ON. */
spiStart(&SPID1, &hs_spicfg); /* Setup transfer parameters. */
spiSelect(&SPID1); /* Slave Select assertion. */
spiExchange(&SPID1, 512,
txbuf, rxbuf); /* Atomic transfer operations. */
spiUnselect(&SPID1); /* Slave Select de-assertion. */
spiReleaseBus(&SPID1); /* Ownership release. */
}
return 0;
}
/*
* SPI bus contender 2.
*/
static THD_WORKING_AREA(spi_thread_2_wa, 256);
static msg_t spi_thread_2(void *p)
{
(void)p;
chRegSetThreadName("SPI thread 2");
while (TRUE) {
spiAcquireBus(&SPID1); /* Acquire ownership of the bus. */
palClearPad(GPIOF, GPIOF_LED_GREEN);/* LED OFF. */
spiStart(&SPID1, &ls_spicfg); /* Setup transfer parameters. */
spiSelect(&SPID1); /* Slave Select assertion. */
spiExchange(&SPID1, 512,
txbuf, rxbuf); /* Atomic transfer operations. */
spiUnselect(&SPID1); /* Slave Select de-assertion. */
spiReleaseBus(&SPID1); /* Ownership release. */
}
return 0;
}
/*
* Application entry point.
*/
int main(void)
{
size_t i;
/*
* System initializations.
* - HAL initialization, this also initializes the configured device drivers
* and performs the board-specific initializations.
* - Kernel initialization, the main() function becomes a thread and the
* RTOS is active.
*/
halInit();
chSysInit();
palSetPadMode(GPIOA, GPIOA_SSI0_CLK, PAL_MODE_OUTPUT_PUSHPULL |
PAL_MODE_ALTERNATE(2));
palSetPadMode(GPIOA, GPIOA_SSI0_RX, PAL_MODE_OUTPUT_PUSHPULL |
PAL_MODE_ALTERNATE(2));
palSetPadMode(GPIOA, GPIOA_SSI0_TX, PAL_MODE_OUTPUT_PUSHPULL |
PAL_MODE_ALTERNATE(2));
palSetPadMode(GPIOA, GPIOA_PIN3, PAL_MODE_OUTPUT_PUSHPULL);
palSetPadMode(GPIOF, GPIOF_LED_GREEN, PAL_MODE_OUTPUT_PUSHPULL);
/*
* Prepare transmit pattern.
*/
for (i = 0; i < sizeof(txbuf); i++) {
txbuf[i] = (uint8_t)i;
}
/*
* Starting the transmitter and receiver threads.
*/
chThdCreateStatic(spi_thread_1_wa, sizeof(spi_thread_1_wa),
NORMALPRIO + 1, spi_thread_1, NULL);
chThdCreateStatic(spi_thread_2_wa, sizeof(spi_thread_2_wa),
NORMALPRIO + 1, spi_thread_2, NULL);
/*
* Normal main() thread activity
*/
while (TRUE) {
chThdSleepMilliseconds(500);
}
return 0;
}

View File

@ -0,0 +1,152 @@
/*
* TM4C123x drivers configuration.
* The following settings override the default settings present in
* the various device driver implementation headers.
* Note that the settings for each driver only have effect if the whole
* driver is enabled in halconf.h.
*
* IRQ priorities:
* 7...0 Lowest...Highest.
*/
#define TM4C123x_MCUCONF
/*
* HAL driver system settings.
*/
#define TIVA_OSCSRC TIVA_RCC2_OSCSRC2_MOSC
#define TIVA_MOSC_ENABLE TRUE
#define TIVA_DIV400_VALUE 1
#define TIVA_SYSDIV_VALUE 2
#define TIVA_USESYSDIV_ENABLE FALSE
#define TIVA_SYSDIV2LSB_ENABLE FALSE
#define TIVA_BYPASS_VALUE 0
#define TIVA_PWM_FIELDS (TIVA_RCC_USEPWMDIV | \
TIVA_RCC_PWMDIV_8)
/*
* GPIO driver system settings.
*/
#define TIVA_GPIO_GPIOA_USE_AHB TRUE
#define TIVA_GPIO_GPIOB_USE_AHB TRUE
#define TIVA_GPIO_GPIOC_USE_AHB TRUE
#define TIVA_GPIO_GPIOD_USE_AHB TRUE
#define TIVA_GPIO_GPIOE_USE_AHB TRUE
#define TIVA_GPIO_GPIOF_USE_AHB TRUE
/*
* GPT driver system settings.
*/
#define TIVA_GPT_USE_GPT0 FALSE
#define TIVA_GPT_USE_GPT1 FALSE
#define TIVA_GPT_USE_GPT2 FALSE
#define TIVA_GPT_USE_GPT3 FALSE
#define TIVA_GPT_USE_GPT4 FALSE
#define TIVA_GPT_USE_GPT5 FALSE
#define TIVA_GPT_USE_WGPT0 FALSE
#define TIVA_GPT_USE_WGPT1 FALSE
#define TIVA_GPT_USE_WGPT2 FALSE
#define TIVA_GPT_USE_WGPT3 FALSE
#define TIVA_GPT_USE_WGPT4 FALSE
#define TIVA_GPT_USE_WGPT5 FALSE
#define TIVA_GPT_GPT0A_IRQ_PRIORITY 7
#define TIVA_GPT_GPT1A_IRQ_PRIORITY 7
#define TIVA_GPT_GPT2A_IRQ_PRIORITY 7
#define TIVA_GPT_GPT3A_IRQ_PRIORITY 7
#define TIVA_GPT_GPT4A_IRQ_PRIORITY 7
#define TIVA_GPT_GPT5A_IRQ_PRIORITY 7
#define TIVA_GPT_WGPT0A_IRQ_PRIORITY 7
#define TIVA_GPT_WGPT1A_IRQ_PRIORITY 7
#define TIVA_GPT_WGPT2A_IRQ_PRIORITY 7
#define TIVA_GPT_WGPT3A_IRQ_PRIORITY 7
#define TIVA_GPT_WGPT4A_IRQ_PRIORITY 7
#define TIVA_GPT_WGPT5A_IRQ_PRIORITY 7
/*
* I2C driver system settings.
*/
#define TIVA_I2C_USE_I2C0 FALSE
#define TIVA_I2C_USE_I2C1 FALSE
#define TIVA_I2C_USE_I2C2 FALSE
#define TIVA_I2C_USE_I2C3 FALSE
#define TIVA_I2C_USE_I2C4 FALSE
#define TIVA_I2C_USE_I2C5 FALSE
#define TIVA_I2C_USE_I2C6 FALSE
#define TIVA_I2C_USE_I2C7 FALSE
#define TIVA_I2C_I2C0_IRQ_PRIORITY 4
#define TIVA_I2C_I2C1_IRQ_PRIORITY 4
#define TIVA_I2C_I2C2_IRQ_PRIORITY 4
#define TIVA_I2C_I2C3_IRQ_PRIORITY 4
#define TIVA_I2C_I2C4_IRQ_PRIORITY 4
#define TIVA_I2C_I2C5_IRQ_PRIORITY 4
#define TIVA_I2C_I2C6_IRQ_PRIORITY 4
#define TIVA_I2C_I2C7_IRQ_PRIORITY 4
/*
* PWM driver system settings.
*/
#define TIVA_PWM_USE_PWM0 FALSE
#define TIVA_PWM_USE_PWM1 FALSE
#define TIVA_PWM_PWM0_FAULT_IRQ_PRIORITY 4
#define TIVA_PWM_PWM0_0_IRQ_PRIORITY 4
#define TIVA_PWM_PWM0_1_IRQ_PRIORITY 4
#define TIVA_PWM_PWM0_2_IRQ_PRIORITY 4
#define TIVA_PWM_PWM0_3_IRQ_PRIORITY 4
#define TIVA_PWM_PWM1_FAULT_IRQ_PRIORITY 4
#define TIVA_PWM_PWM1_0_IRQ_PRIORITY 4
#define TIVA_PWM_PWM1_1_IRQ_PRIORITY 4
#define TIVA_PWM_PWM1_2_IRQ_PRIORITY 4
#define TIVA_PWM_PWM1_3_IRQ_PRIORITY 4
/*
* SERIAL driver system settings.
*/
#define TIVA_SERIAL_USE_UART0 FALSE
#define TIVA_SERIAL_USE_UART1 FALSE
#define TIVA_SERIAL_USE_UART2 FALSE
#define TIVA_SERIAL_USE_UART3 FALSE
#define TIVA_SERIAL_USE_UART4 FALSE
#define TIVA_SERIAL_USE_UART5 FALSE
#define TIVA_SERIAL_USE_UART6 FALSE
#define TIVA_SERIAL_USE_UART7 FALSE
#define TIVA_SERIAL_UART0_PRIORITY 5
#define TIVA_SERIAL_UART1_PRIORITY 5
#define TIVA_SERIAL_UART2_PRIORITY 5
#define TIVA_SERIAL_UART3_PRIORITY 5
#define TIVA_SERIAL_UART4_PRIORITY 5
#define TIVA_SERIAL_UART5_PRIORITY 5
#define TIVA_SERIAL_UART6_PRIORITY 5
#define TIVA_SERIAL_UART7_PRIORITY 5
/*
* SPI driver system settings.
*/
#define TIVA_SPI_USE_SSI0 TRUE
#define TIVA_SPI_USE_SSI1 FALSE
#define TIVA_SPI_USE_SSI2 FALSE
#define TIVA_SPI_USE_SSI3 FALSE
#define TIVA_SPI_SSI0_RX_UDMA_CHANNEL 10
#define TIVA_SPI_SSI1_RX_UDMA_CHANNEL 24
#define TIVA_SPI_SSI2_RX_UDMA_CHANNEL 12
#define TIVA_SPI_SSI3_RX_UDMA_CHANNEL 14
#define TIVA_SPI_SSI0_TX_UDMA_CHANNEL 11
#define TIVA_SPI_SSI1_TX_UDMA_CHANNEL 25
#define TIVA_SPI_SSI2_TX_UDMA_CHANNEL 13
#define TIVA_SPI_SSI3_TX_UDMA_CHANNEL 15
#define TIVA_SPI_SSI0_RX_UDMA_MAPPING 0
#define TIVA_SPI_SSI1_RX_UDMA_MAPPING 0
#define TIVA_SPI_SSI2_RX_UDMA_MAPPING 2
#define TIVA_SPI_SSI3_RX_UDMA_MAPPING 2
#define TIVA_SPI_SSI0_TX_UDMA_MAPPING 0
#define TIVA_SPI_SSI1_TX_UDMA_MAPPING 0
#define TIVA_SPI_SSI2_TX_UDMA_MAPPING 2
#define TIVA_SPI_SSI3_TX_UDMA_MAPPING 2
/*
* ST driver system settings.
*/
#define TIVA_ST_IRQ_PRIORITY 2
#define TIVA_ST_USE_WIDE_TIMER TRUE
#define TIVA_ST_TIMER_NUMBER 5
#define TIVA_ST_TIMER_LETTER A