mirror of https://github.com/rusefi/ChibiOS.git
Added unified cache handler for Cortex-M devices.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@11233 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
4148fb3cb7
commit
7761387ba0
|
@ -6,8 +6,6 @@ Driver capability:
|
|||
|
||||
The file registry must export:
|
||||
|
||||
STM32_DMAn_CHx_HANDLER - Vector name for IRQ "x" (1..7). If the macro
|
||||
STM32_BDMAn_CHx_HANDLER - Vector name for IRQ "x" (1..7). If the macro
|
||||
is not exported then the ISR is not declared.
|
||||
STM32_DMAn_CHx_NUMBER - Vector number for IRQ "x" (1..7).
|
||||
STM32_DMA_CACHE_HANDLING - TRUE if the device requires explicit cache
|
||||
handling on DMA buffers.
|
||||
STM32_BDMAn_CHx_NUMBER - Vector number for IRQ "x" (1..7).
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#ifndef STM32_DMA_H
|
||||
#define STM32_DMA_H
|
||||
|
||||
#include "cache.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
@ -258,34 +260,6 @@ typedef struct {
|
|||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Invalidates the data cache lines overlapping a DMA buffer.
|
||||
* @note It does nothing in this driver, it is supplied for compatibility.
|
||||
*
|
||||
* @param[in] saddr start address of the DMA buffer
|
||||
* @param[in] n size of the DMA buffer in bytes
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define dmaBufferInvalidate(addr, size) { \
|
||||
(void)(addr); \
|
||||
(void)(size); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Flushes the data cache lines overlapping a DMA buffer.
|
||||
* @note It does nothing in this driver, it is supplied for compatibility.
|
||||
*
|
||||
* @param[in] saddr start address of the DMA buffer
|
||||
* @param[in] n size of the DMA buffer in bytes
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define dmaBufferFlush(addr, size) { \
|
||||
(void)(addr); \
|
||||
(void)(size); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
|
|
|
@ -16,5 +16,3 @@ STM32_ADVANCED_DMA - TRUE not used by the DMA drivers but other
|
|||
STM32_HAS_DMAx - Support for DMA unit "x" (1..2).
|
||||
STM32_DMAx_CHn_HANDLER - Vector name for channel "n" (0..7).
|
||||
STM32_DMAn_CHx_NUMBER - Vector number for channel "n" (0..7).
|
||||
STM32_DMA_CACHE_HANDLING - TRUE if the device requires explicit cache
|
||||
handling on DMA buffers.
|
|
@ -25,6 +25,8 @@
|
|||
#ifndef STM32_DMA_H
|
||||
#define STM32_DMA_H
|
||||
|
||||
#include "cache.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
@ -216,10 +218,6 @@
|
|||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !defined(STM32_DMA_CACHE_HANDLING)
|
||||
#error "STM32_DMA_CACHE_HANDLING missing in registry"
|
||||
#endif
|
||||
|
||||
#if !defined(STM32_HAS_DMA1)
|
||||
#error "STM32_HAS_DMA1 missing in registry"
|
||||
#endif
|
||||
|
@ -385,71 +383,6 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
|||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if STM32_DMA_CACHE_HANDLING || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Invalidates the data cache lines overlapping a DMA buffer.
|
||||
* @details This function is meant to make sure that data written in
|
||||
* data cache is invalidated. It is used for DMA buffers that
|
||||
* must have been written by a DMA stream.
|
||||
* @note On devices without data cache this function does nothing.
|
||||
* @note The function does not consider the lower 5 bits of addresses,
|
||||
* the buffers are meant to be aligned to a 32 bytes boundary or
|
||||
* adjacent data can be invalidated as side effect.
|
||||
*
|
||||
* @param[in] saddr start address of the DMA buffer
|
||||
* @param[in] n size of the DMA buffer in bytes
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define dmaBufferInvalidate(saddr, n) { \
|
||||
uint8_t *start = (uint8_t *)(saddr); \
|
||||
uint8_t *end = start + (size_t)(n); \
|
||||
__DSB(); \
|
||||
while (start < end) { \
|
||||
SCB->DCIMVAC = (uint32_t)start; \
|
||||
start += 32U; \
|
||||
} \
|
||||
__DSB(); \
|
||||
__ISB(); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Flushes the data cache lines overlapping a DMA buffer.
|
||||
* @details This function is meant to make sure that data written in
|
||||
* data cache is flushed to RAM. It is used for DMA buffers that
|
||||
* must be read by a DMA stream.
|
||||
* @note On devices without data cache this function does nothing.
|
||||
* @note The function does not consider the lower 5 bits of addresses,
|
||||
* the buffers are meant to be aligned to a 32 bytes boundary or
|
||||
* adjacent data can be flushed as side effect.
|
||||
*
|
||||
* @param[in] saddr start address of the DMA buffer
|
||||
* @param[in] n size of the DMA buffer in bytes
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define dmaBufferFlush(saddr, n) { \
|
||||
uint8_t *start = (uint8_t *)(saddr); \
|
||||
uint8_t *end = start + (size_t)(n); \
|
||||
__DSB(); \
|
||||
while (start < end) { \
|
||||
SCB->DCCIMVAC = (uint32_t)start; \
|
||||
start += 32U; \
|
||||
} \
|
||||
__DSB(); \
|
||||
__ISB(); \
|
||||
}
|
||||
#else
|
||||
#define dmaBufferInvalidate(addr, size) { \
|
||||
(void)(addr); \
|
||||
(void)(size); \
|
||||
}
|
||||
#define dmaBufferFlush(addr, size) { \
|
||||
(void)(addr); \
|
||||
(void)(size); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
|
|
|
@ -10,5 +10,3 @@ The file registry must export:
|
|||
STM32_HAS_DMAx - Support for DMA unit "x" (1..2).
|
||||
STM32_DMAx_CHn_HANDLER - Vector name for channel "n" (0..7).
|
||||
STM32_DMAx_CHn_NUMBER - Vector number for channel "n" (0..7).
|
||||
STM32_DMA_CACHE_HANDLING - TRUE if the device requires explicit cache
|
||||
handling on DMA buffers.
|
|
@ -25,6 +25,7 @@
|
|||
#ifndef STM32_DMA_H
|
||||
#define STM32_DMA_H
|
||||
|
||||
#include "cache.h"
|
||||
#include "stm32_dmamux.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -171,10 +172,6 @@
|
|||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !defined(STM32_DMA_CACHE_HANDLING)
|
||||
#error "STM32_DMA_CACHE_HANDLING missing in registry"
|
||||
#endif
|
||||
|
||||
#if !defined(STM32_HAS_DMA1)
|
||||
#error "STM32_HAS_DMA1 missing in registry"
|
||||
#endif
|
||||
|
@ -341,71 +338,6 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
|||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if STM32_DMA_CACHE_HANDLING || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Invalidates the data cache lines overlapping a DMA buffer.
|
||||
* @details This function is meant to make sure that data written in
|
||||
* data cache is invalidated. It is used for DMA buffers that
|
||||
* must have been written by a DMA stream.
|
||||
* @note On devices without data cache this function does nothing.
|
||||
* @note The function does not consider the lower 5 bits of addresses,
|
||||
* the buffers are meant to be aligned to a 32 bytes boundary or
|
||||
* adjacent data can be invalidated as side effect.
|
||||
*
|
||||
* @param[in] saddr start address of the DMA buffer
|
||||
* @param[in] n size of the DMA buffer in bytes
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define dmaBufferInvalidate(saddr, n) { \
|
||||
uint8_t *start = (uint8_t *)(saddr); \
|
||||
uint8_t *end = start + (size_t)(n); \
|
||||
__DSB(); \
|
||||
while (start < end) { \
|
||||
SCB->DCIMVAC = (uint32_t)start; \
|
||||
start += 32U; \
|
||||
} \
|
||||
__DSB(); \
|
||||
__ISB(); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Flushes the data cache lines overlapping a DMA buffer.
|
||||
* @details This function is meant to make sure that data written in
|
||||
* data cache is flushed to RAM. It is used for DMA buffers that
|
||||
* must be read by a DMA stream.
|
||||
* @note On devices without data cache this function does nothing.
|
||||
* @note The function does not consider the lower 5 bits of addresses,
|
||||
* the buffers are meant to be aligned to a 32 bytes boundary or
|
||||
* adjacent data can be flushed as side effect.
|
||||
*
|
||||
* @param[in] saddr start address of the DMA buffer
|
||||
* @param[in] n size of the DMA buffer in bytes
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define dmaBufferFlush(saddr, n) { \
|
||||
uint8_t *start = (uint8_t *)(saddr); \
|
||||
uint8_t *end = start + (size_t)(n); \
|
||||
__DSB(); \
|
||||
while (start < end) { \
|
||||
SCB->DCCIMVAC = (uint32_t)start; \
|
||||
start += 32U; \
|
||||
} \
|
||||
__DSB(); \
|
||||
__ISB(); \
|
||||
}
|
||||
#else
|
||||
#define dmaBufferInvalidate(addr, size) { \
|
||||
(void)(addr); \
|
||||
(void)(size); \
|
||||
}
|
||||
#define dmaBufferFlush(addr, size) { \
|
||||
(void)(addr); \
|
||||
(void)(size); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
|
|
|
@ -130,9 +130,6 @@
|
|||
#define STM32_HAS_DAC2_CH2 FALSE
|
||||
|
||||
/* DMA attributes.*/
|
||||
#define STM32_ADVANCED_DMA TRUE
|
||||
#define STM32_DMA_CACHE_HANDLING FALSE
|
||||
|
||||
#define STM32_HAS_DMA1 TRUE
|
||||
#define STM32_DMA1_CH0_HANDLER Vector6C
|
||||
#define STM32_DMA1_CH1_HANDLER Vector70
|
||||
|
@ -501,9 +498,6 @@
|
|||
#define STM32_HAS_DAC2_CH2 FALSE
|
||||
|
||||
/* DMA attributes.*/
|
||||
#define STM32_ADVANCED_DMA TRUE
|
||||
#define STM32_DMA_CACHE_HANDLING FALSE
|
||||
|
||||
#define STM32_HAS_DMA1 TRUE
|
||||
#define STM32_DMA1_CH0_HANDLER Vector6C
|
||||
#define STM32_DMA1_CH1_HANDLER Vector70
|
||||
|
@ -847,9 +841,6 @@
|
|||
#define STM32_HAS_DAC2_CH2 FALSE
|
||||
|
||||
/* DMA attributes.*/
|
||||
#define STM32_ADVANCED_DMA TRUE
|
||||
#define STM32_DMA_CACHE_HANDLING FALSE
|
||||
|
||||
#define STM32_HAS_DMA1 TRUE
|
||||
#define STM32_DMA1_CH0_HANDLER Vector6C
|
||||
#define STM32_DMA1_CH1_HANDLER Vector70
|
||||
|
@ -1200,9 +1191,6 @@
|
|||
#define STM32_HAS_DAC2_CH2 FALSE
|
||||
|
||||
/* DMA attributes.*/
|
||||
#define STM32_ADVANCED_DMA TRUE
|
||||
#define STM32_DMA_CACHE_HANDLING FALSE
|
||||
|
||||
#define STM32_HAS_DMA1 TRUE
|
||||
#define STM32_DMA1_CH0_HANDLER Vector6C
|
||||
#define STM32_DMA1_CH1_HANDLER Vector70
|
||||
|
@ -1523,9 +1511,6 @@
|
|||
#define STM32_HAS_DAC2_CH2 FALSE
|
||||
|
||||
/* DMA attributes.*/
|
||||
#define STM32_ADVANCED_DMA TRUE
|
||||
#define STM32_DMA_CACHE_HANDLING FALSE
|
||||
|
||||
#define STM32_HAS_DMA1 TRUE
|
||||
#define STM32_DMA1_CH0_HANDLER Vector6C
|
||||
#define STM32_DMA1_CH1_HANDLER Vector70
|
||||
|
@ -1824,9 +1809,6 @@
|
|||
#define STM32_HAS_DAC2_CH2 FALSE
|
||||
|
||||
/* DMA attributes.*/
|
||||
#define STM32_ADVANCED_DMA TRUE
|
||||
#define STM32_DMA_CACHE_HANDLING FALSE
|
||||
|
||||
#define STM32_HAS_DMA1 TRUE
|
||||
#define STM32_DMA1_CH0_HANDLER Vector6C
|
||||
#define STM32_DMA1_CH1_HANDLER Vector70
|
||||
|
@ -2104,9 +2086,6 @@
|
|||
#define STM32_HAS_DAC2_CH2 FALSE
|
||||
|
||||
/* DMA attributes.*/
|
||||
#define STM32_ADVANCED_DMA TRUE
|
||||
#define STM32_DMA_CACHE_HANDLING FALSE
|
||||
|
||||
#define STM32_HAS_DMA1 TRUE
|
||||
#define STM32_DMA1_CH0_HANDLER Vector6C
|
||||
#define STM32_DMA1_CH1_HANDLER Vector70
|
||||
|
@ -2441,9 +2420,6 @@
|
|||
#define STM32_HAS_DAC2_CH2 FALSE
|
||||
|
||||
/* DMA attributes.*/
|
||||
#define STM32_ADVANCED_DMA TRUE
|
||||
#define STM32_DMA_CACHE_HANDLING FALSE
|
||||
|
||||
#define STM32_HAS_DMA1 TRUE
|
||||
#define STM32_DMA1_CH0_HANDLER Vector6C
|
||||
#define STM32_DMA1_CH1_HANDLER Vector70
|
||||
|
|
|
@ -111,9 +111,6 @@
|
|||
#define STM32_HAS_DAC2_CH2 FALSE
|
||||
|
||||
/* DMA attributes.*/
|
||||
#define STM32_ADVANCED_DMA TRUE
|
||||
#define STM32_DMA_CACHE_HANDLING TRUE
|
||||
|
||||
#define STM32_HAS_DMA1 TRUE
|
||||
#define STM32_DMA1_CH0_HANDLER Vector6C
|
||||
#define STM32_DMA1_CH1_HANDLER Vector70
|
||||
|
|
|
@ -87,8 +87,6 @@
|
|||
#define STM32_BDMA1_CH7_NUMBER 136
|
||||
|
||||
/* DMA attributes.*/
|
||||
#define STM32_DMA_CACHE_HANDLING TRUE
|
||||
|
||||
#define STM32_HAS_DMA1 TRUE
|
||||
#define STM32_DMA1_CH0_HANDLER Vector6C
|
||||
#define STM32_DMA1_CH1_HANDLER Vector70
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2016 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 common/ARMCMx/cache.h
|
||||
* @brief Cortex-Mx cache support macros and structures.
|
||||
*
|
||||
* @addtogroup COMMON_ARMCMx_CACHE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef CACHE_H
|
||||
#define CACHE_H
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if defined(__DCACHE_PRESENT) || defined(__DOXYGEN__)
|
||||
#if (__DCACHE_PRESENT != 0) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Invalidates the data cache lines overlapping a memory buffer.
|
||||
* @details This function is meant to make sure that data written in
|
||||
* data cache is invalidated.
|
||||
* @note On devices without data cache this function does nothing.
|
||||
* @note The function does not consider the lower 5 bits of addresses,
|
||||
* the buffers are meant to be aligned to a 32 bytes boundary or
|
||||
* adjacent data can be invalidated as side effect.
|
||||
*
|
||||
* @param[in] saddr start address of the DMA buffer
|
||||
* @param[in] n size of the DMA buffer in bytes
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define cacheBufferInvalidate(saddr, n) { \
|
||||
uint8_t *start = (uint8_t *)(saddr); \
|
||||
uint8_t *end = start + (size_t)(n); \
|
||||
__DSB(); \
|
||||
while (start < end) { \
|
||||
SCB->DCIMVAC = (uint32_t)start; \
|
||||
start += 32U; \
|
||||
} \
|
||||
__DSB(); \
|
||||
__ISB(); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Flushes the data cache lines overlapping a DMA buffer.
|
||||
* @details This function is meant to make sure that data written in
|
||||
* data cache is flushed to RAM.
|
||||
* @note On devices without data cache this function does nothing.
|
||||
* @note The function does not consider the lower 5 bits of addresses,
|
||||
* the buffers are meant to be aligned to a 32 bytes boundary or
|
||||
* adjacent data can be flushed as side effect.
|
||||
*
|
||||
* @param[in] saddr start address of the DMA buffer
|
||||
* @param[in] n size of the DMA buffer in bytes
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define cacheBufferFlush(saddr, n) { \
|
||||
uint8_t *start = (uint8_t *)(saddr); \
|
||||
uint8_t *end = start + (size_t)(n); \
|
||||
__DSB(); \
|
||||
while (start < end) { \
|
||||
SCB->DCCIMVAC = (uint32_t)start; \
|
||||
start += 32U; \
|
||||
} \
|
||||
__DSB(); \
|
||||
__ISB(); \
|
||||
}
|
||||
|
||||
#else /* __DCACHE_PRESENT == 0 */
|
||||
#define dmaBufferInvalidate(addr, size) { \
|
||||
(void)(addr); \
|
||||
(void)(size); \
|
||||
}
|
||||
#define dmaBufferFlush(addr, size) { \
|
||||
(void)(addr); \
|
||||
(void)(size); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* !defined(__DCACHE_PRESENT) */
|
||||
#define dmaBufferInvalidate(addr, size) { \
|
||||
(void)(addr); \
|
||||
(void)(size); \
|
||||
}
|
||||
#define dmaBufferFlush(addr, size) { \
|
||||
(void)(addr); \
|
||||
(void)(size); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CACHE_H */
|
||||
|
||||
/** @} */
|
|
@ -42,8 +42,8 @@ static THD_FUNCTION(spi_thread_1, p) {
|
|||
spiExchange(&PORTAB_SPI1, 512,
|
||||
txbuf, rxbuf); /* Atomic transfer operations. */
|
||||
spiUnselect(&PORTAB_SPI1); /* Slave Select de-assertion. */
|
||||
dmaBufferInvalidate(&txbuf[0], /* Cache invalidation over the */
|
||||
sizeof txbuf); /* buffer. */
|
||||
cacheBufferInvalidate(&txbuf[0], /* Cache invalidation over the */
|
||||
sizeof txbuf);/* buffer. */
|
||||
spiReleaseBus(&PORTAB_SPI1); /* Ownership release. */
|
||||
}
|
||||
}
|
||||
|
@ -64,8 +64,8 @@ static THD_FUNCTION(spi_thread_2, p) {
|
|||
spiExchange(&PORTAB_SPI1, 512,
|
||||
txbuf, rxbuf); /* Atomic transfer operations. */
|
||||
spiUnselect(&PORTAB_SPI1); /* Slave Select de-assertion. */
|
||||
dmaBufferInvalidate(&txbuf[0], /* Cache invalidation over the */
|
||||
sizeof txbuf); /* buffer. */
|
||||
cacheBufferInvalidate(&txbuf[0], /* Cache invalidation over the */
|
||||
sizeof txbuf);/* buffer. */
|
||||
spiReleaseBus(&PORTAB_SPI1); /* Ownership release. */
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ int main(void) {
|
|||
*/
|
||||
for (i = 0; i < sizeof(txbuf); i++)
|
||||
txbuf[i] = (uint8_t)i;
|
||||
dmaBufferFlush(&txbuf[0], sizeof txbuf);
|
||||
cacheBufferFlush(&txbuf[0], sizeof txbuf);
|
||||
|
||||
/*
|
||||
* Starting the transmitter and receiver threads.
|
||||
|
|
Loading…
Reference in New Issue