diff options
Diffstat (limited to 'bsps/arm/atsam/spi')
-rw-r--r-- | bsps/arm/atsam/spi/atsam_spi_bus.c | 190 | ||||
-rw-r--r-- | bsps/arm/atsam/spi/atsam_spi_init.c | 31 | ||||
-rw-r--r-- | bsps/arm/atsam/spi/sc16is752.c | 31 |
3 files changed, 176 insertions, 76 deletions
diff --git a/bsps/arm/atsam/spi/atsam_spi_bus.c b/bsps/arm/atsam/spi/atsam_spi_bus.c index 53c1fe4827..322c6a9728 100644 --- a/bsps/arm/atsam/spi/atsam_spi_bus.c +++ b/bsps/arm/atsam/spi/atsam_spi_bus.c @@ -3,7 +3,7 @@ /* SAM Software Package License */ /* ---------------------------------------------------------------------------- */ /* Copyright (c) 2015, Atmel Corporation */ -/* Copyright (c) 2016, embedded brains GmbH */ +/* Copyright (c) 2016, embedded brains GmbH & Co. KG */ /* */ /* All rights reserved. */ /* */ @@ -41,8 +41,8 @@ #define MAX_SPI_FREQUENCY 50000000 typedef struct { - volatile LinkedListDescriporView0 tx_desc; - volatile LinkedListDescriporView0 rx_desc[3]; + volatile LinkedListDescriporView2 tx_desc; + volatile LinkedListDescriporView2 rx_desc[3]; uint8_t rx_bounce_head_buf[CPU_CACHE_LINE_BYTES]; uint8_t rx_bounce_tail_buf[CPU_CACHE_LINE_BYTES]; } atsam_spi_dma; @@ -67,6 +67,8 @@ typedef struct { uint32_t spi_csr[4]; } atsam_spi_bus; +static const uint32_t atsam_spi_dummy_write_data = 0xffffffff; + static void atsam_spi_wakeup_task(atsam_spi_bus *bus) { rtems_binary_semaphore_post(&bus->sem); @@ -181,14 +183,14 @@ static void atsam_spi_copy_rx_bounce_bufs( } } -static void atsam_spi_setup_rx_dma_desc( +static void atsam_spi_setup_real_rx_dma_desc( atsam_spi_bus *bus, atsam_spi_dma *dma, const uint8_t *buf, size_t n ) { - volatile LinkedListDescriporView0 *desc; + volatile LinkedListDescriporView2 *desc; uintptr_t m; uintptr_t b; uintptr_t a; @@ -202,53 +204,56 @@ static void atsam_spi_setup_rx_dma_desc( a = (b + m) & ~m; ae = e & ~m; + /* An earlier dummy read maybe has set the DAM to FIXED_AM. Reset it. */ + desc[0].mbr_cfg = + (desc[0].mbr_cfg & ~XDMAC_CC_DAM_Msk) | XDMAC_CC_DAM_INCREMENTED_AM; if (n <= m) { bus->rx_bounce_head_len = n; bus->rx_bounce_tail_len = 0; - desc[0].mbr_ta = (uint32_t) dma->rx_bounce_head_buf; - desc[0].mbr_ubc = n; + desc[0].mbr_da = (uint32_t) dma->rx_bounce_head_buf; + desc[0].mbr_ubc = n | XDMA_UBC_NVIEW_NDV2; } else { bus->rx_bounce_head_len = a - b; bus->rx_bounce_tail_len = e & m; if ((b & m) == 0) { if ((n & m) == 0) { - desc[0].mbr_ta = a; - desc[0].mbr_ubc = n; + desc[0].mbr_da = a; + desc[0].mbr_ubc = n | XDMA_UBC_NVIEW_NDV2; } else { - desc[0].mbr_ta = a; + desc[0].mbr_da = a; desc[0].mbr_ubc = (ae - a) | XDMA_UBC_NDEN_UPDATED - | XDMA_UBC_NVIEW_NDV0 + | XDMA_UBC_NVIEW_NDV2 | XDMA_UBC_NDE_FETCH_EN; - desc[1].mbr_ta = (uint32_t) dma->rx_bounce_tail_buf; - desc[1].mbr_ubc = n & m; + desc[1].mbr_da = (uint32_t) dma->rx_bounce_tail_buf; + desc[1].mbr_ubc = n & m | XDMA_UBC_NVIEW_NDV2; } } else { if ((e & m) == 0) { - desc[0].mbr_ta = (uint32_t) dma->rx_bounce_head_buf; + desc[0].mbr_da = (uint32_t) dma->rx_bounce_head_buf; desc[0].mbr_ubc = (a - b) | XDMA_UBC_NDEN_UPDATED - | XDMA_UBC_NVIEW_NDV0 + | XDMA_UBC_NVIEW_NDV2 | XDMA_UBC_NDE_FETCH_EN; - desc[1].mbr_ta = a; - desc[1].mbr_ubc = ae - a; + desc[1].mbr_da = a; + desc[1].mbr_ubc = ae - a | XDMA_UBC_NVIEW_NDV2; } else if ((ae - a) == 0) { bus->rx_bounce_head_len = n; bus->rx_bounce_tail_len = 0; - desc[0].mbr_ta = (uint32_t) dma->rx_bounce_head_buf; - desc[0].mbr_ubc = n; + desc[0].mbr_da = (uint32_t) dma->rx_bounce_head_buf; + desc[0].mbr_ubc = n | XDMA_UBC_NVIEW_NDV2; } else { - desc[0].mbr_ta = (uint32_t) dma->rx_bounce_head_buf; + desc[0].mbr_da = (uint32_t) dma->rx_bounce_head_buf; desc[0].mbr_ubc = (a - b) | XDMA_UBC_NDEN_UPDATED - | XDMA_UBC_NVIEW_NDV0 + | XDMA_UBC_NVIEW_NDV2 | XDMA_UBC_NDE_FETCH_EN; - desc[1].mbr_ta = a; + desc[1].mbr_da = a; desc[1].mbr_ubc = (ae - a) | XDMA_UBC_NDEN_UPDATED - | XDMA_UBC_NVIEW_NDV0 + | XDMA_UBC_NVIEW_NDV2 | XDMA_UBC_NDE_FETCH_EN; - desc[2].mbr_ta = (uint32_t) dma->rx_bounce_tail_buf; - desc[2].mbr_ubc = e - ae; + desc[2].mbr_da = (uint32_t) dma->rx_bounce_tail_buf; + desc[2].mbr_ubc = e - ae | XDMA_UBC_NVIEW_NDV2; } } @@ -256,19 +261,61 @@ static void atsam_spi_setup_rx_dma_desc( } } +static void atsam_spi_setup_dummy_rx_dma_desc( + atsam_spi_bus *bus, + atsam_spi_dma *dma, + size_t n +) +{ + volatile LinkedListDescriporView2 *desc; + + desc = &dma->rx_desc[0]; + + /* Avoid copying bounce buffers after receive. */ + bus->rx_bounce_head_len = 0; + bus->rx_bounce_tail_len = 0; + + /* But use one of the bounce buffers to write dummy data to. */ + desc[0].mbr_da = (uint32_t) dma->rx_bounce_head_buf; + desc[0].mbr_ubc = n | XDMA_UBC_NVIEW_NDV2; + desc[0].mbr_cfg = + (desc[0].mbr_cfg & ~XDMAC_CC_DAM_Msk) | XDMAC_CC_DAM_FIXED_AM; +} + +static void atsam_spi_setup_rx_dma_desc( + atsam_spi_bus *bus, + atsam_spi_dma *dma, + const uint8_t *buf, + size_t n +) +{ + if (buf != NULL) { + atsam_spi_setup_real_rx_dma_desc(bus, dma, buf, n); + } else { + atsam_spi_setup_dummy_rx_dma_desc(bus, dma, n); + } +} + static void atsam_spi_setup_tx_dma_desc( atsam_spi_dma *dma, const uint8_t *buf, size_t n ) { - volatile LinkedListDescriporView0 *desc; + volatile LinkedListDescriporView2 *desc; desc = &dma->tx_desc; - desc->mbr_ta = (uint32_t) buf; - desc->mbr_ubc = n; - - rtems_cache_flush_multiple_data_lines(buf, n); + desc->mbr_ubc = n | XDMA_UBC_NVIEW_NDV2; + if (buf != NULL) { + desc->mbr_sa = (uint32_t) buf; + desc->mbr_cfg = + (desc->mbr_cfg & ~XDMAC_CC_SAM_Msk) | XDMAC_CC_SAM_INCREMENTED_AM; + rtems_cache_flush_multiple_data_lines(buf, n); + } else { + desc->mbr_sa = (uint32_t)&atsam_spi_dummy_write_data; + desc->mbr_cfg = + (desc->mbr_cfg & ~XDMAC_CC_SAM_Msk) | XDMAC_CC_SAM_FIXED_AM; + } } static void atsam_spi_start_dma_transfer( @@ -296,8 +343,9 @@ static void atsam_spi_start_dma_transfer( XDMAC_SetDescriptorControl( pXdmac, bus->dma_rx_channel, - XDMAC_CNDC_NDVIEW_NDV0 | + XDMAC_CNDC_NDVIEW_NDV2 | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED | + XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED | XDMAC_CNDC_NDE_DSCR_FETCH_EN ); XDMAC_SetDescriptorAddr( @@ -309,7 +357,8 @@ static void atsam_spi_start_dma_transfer( XDMAC_SetDescriptorControl( pXdmac, bus->dma_tx_channel, - XDMAC_CNDC_NDVIEW_NDV0 | + XDMAC_CNDC_NDVIEW_NDV2 | + XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED | XDMAC_CNDC_NDE_DSCR_FETCH_EN ); @@ -485,15 +534,60 @@ static void atsam_spi_init_xdma(atsam_spi_bus *bus) uint8_t channel; eXdmadRC rc; uint32_t xdma_cndc; + uint32_t tx_da; + uint32_t rx_sa; + uint32_t tx_cfg; + uint32_t rx_cfg; + + tx_da = (uint32_t)&bus->spi_regs->SPI_TDR; + rx_sa = (uint32_t)&bus->spi_regs->SPI_RDR; + + channel = XDMAIF_Get_ChannelNumber(bus->spi_id, XDMAD_TRANSFER_TX); + tx_cfg = + XDMAC_CC_TYPE_PER_TRAN | + XDMAC_CC_MBSIZE_SINGLE | + XDMAC_CC_DSYNC_MEM2PER | + XDMAC_CC_CSIZE_CHK_1 | + XDMAC_CC_DWIDTH_BYTE | + XDMAC_CC_SIF_AHB_IF1 | + XDMAC_CC_DIF_AHB_IF1 | + XDMAC_CC_SAM_INCREMENTED_AM | + XDMAC_CC_DAM_FIXED_AM | + XDMAC_CC_PERID(channel); + + channel = XDMAIF_Get_ChannelNumber(bus->spi_id, XDMAD_TRANSFER_RX); + rx_cfg = + XDMAC_CC_TYPE_PER_TRAN | + XDMAC_CC_MBSIZE_SINGLE | + XDMAC_CC_DSYNC_PER2MEM | + XDMAC_CC_CSIZE_CHK_1 | + XDMAC_CC_DWIDTH_BYTE | + XDMAC_CC_SIF_AHB_IF1 | + XDMAC_CC_DIF_AHB_IF1 | + XDMAC_CC_SAM_FIXED_AM | + XDMAC_CC_DAM_INCREMENTED_AM | + XDMAC_CC_PERID(channel); dma = rtems_cache_coherent_allocate(sizeof(*dma), 0, 0); assert(dma != NULL); bus->dma = dma; dma->tx_desc.mbr_nda = 0; + dma->tx_desc.mbr_sa = 0; + dma->tx_desc.mbr_da = tx_da; + dma->tx_desc.mbr_cfg = tx_cfg; dma->rx_desc[0].mbr_nda = (uint32_t) &dma->rx_desc[1]; + dma->rx_desc[0].mbr_sa = rx_sa; + dma->rx_desc[0].mbr_da = 0; + dma->rx_desc[0].mbr_cfg = rx_cfg; dma->rx_desc[1].mbr_nda = (uint32_t) &dma->rx_desc[2]; + dma->rx_desc[1].mbr_sa = rx_sa; + dma->rx_desc[1].mbr_da = 0; + dma->rx_desc[1].mbr_cfg = rx_cfg; dma->rx_desc[2].mbr_nda = 0; + dma->rx_desc[2].mbr_sa = rx_sa; + dma->rx_desc[2].mbr_da = 0; + dma->rx_desc[2].mbr_cfg = rx_cfg; bus->dma_tx_channel = XDMAD_AllocateChannel( &XDMAD_Instance, @@ -538,19 +632,9 @@ static void atsam_spi_init_xdma(atsam_spi_bus *bus) /* Setup RX */ memset(&cfg, 0, sizeof(cfg)); channel = XDMAIF_Get_ChannelNumber(bus->spi_id, XDMAD_TRANSFER_RX); - cfg.mbr_sa = (uint32_t)&bus->spi_regs->SPI_RDR; - cfg.mbr_cfg = - XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SINGLE | - XDMAC_CC_DSYNC_PER2MEM | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(channel); - xdma_cndc = XDMAC_CNDC_NDVIEW_NDV0 | + cfg.mbr_sa = rx_sa; + cfg.mbr_cfg = rx_cfg; + xdma_cndc = XDMAC_CNDC_NDVIEW_NDV2 | XDMAC_CNDC_NDE_DSCR_FETCH_EN | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED | XDMAC_CNDC_NDSUP_SRC_PARAMS_UNCHANGED; @@ -567,19 +651,9 @@ static void atsam_spi_init_xdma(atsam_spi_bus *bus) /* Setup TX */ memset(&cfg, 0, sizeof(cfg)); channel = XDMAIF_Get_ChannelNumber(bus->spi_id, XDMAD_TRANSFER_TX); - cfg.mbr_da = (uint32_t)&bus->spi_regs->SPI_TDR; - cfg.mbr_cfg = - XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SINGLE | - XDMAC_CC_DSYNC_MEM2PER | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(channel); - xdma_cndc = XDMAC_CNDC_NDVIEW_NDV0 | + cfg.mbr_da = tx_da; + cfg.mbr_cfg = tx_cfg; + xdma_cndc = XDMAC_CNDC_NDVIEW_NDV2 | XDMAC_CNDC_NDE_DSCR_FETCH_EN | XDMAC_CNDC_NDDUP_DST_PARAMS_UNCHANGED | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED; diff --git a/bsps/arm/atsam/spi/atsam_spi_init.c b/bsps/arm/atsam/spi/atsam_spi_init.c index ca18f8ec35..4784ca57c6 100644 --- a/bsps/arm/atsam/spi/atsam_spi_init.c +++ b/bsps/arm/atsam/spi/atsam_spi_init.c @@ -1,15 +1,28 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* - * Copyright (c) 2016 embedded brains GmbH. All rights reserved. + * Copyright (c) 2016 embedded brains GmbH & Co. KG * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * <info@embedded-brains.de> + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include <bsp/atsam-spi.h> diff --git a/bsps/arm/atsam/spi/sc16is752.c b/bsps/arm/atsam/spi/sc16is752.c index 59380d5057..7038694fda 100644 --- a/bsps/arm/atsam/spi/sc16is752.c +++ b/bsps/arm/atsam/spi/sc16is752.c @@ -1,16 +1,29 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* - * Copyright (c) 2016 embedded brains GmbH. All rights reserved. + * Copyright (c) 2016 embedded brains GmbH & Co. KG * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * <rtems@embedded-brains.de> + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include <bsp/sc16is752.h> |