# HG changeset patch # User vae # Date 1329945025 0 # Node ID a18d3fded36e73b8411643aadc422e58f9075b7d # Parent df73565489514b801f0a554c5530cac552aff343 * cdl/spi_freescale_dspi.cdl: * include/spi_freescale_dspi.h * include/spi_freescale_dspi_io.h: * include/spi_freescale_dspi_buses.inl * src/spi_freescale_dspi.c: New package -- Freescale DSPI SPI driver. [Bugzilla 1001450] diff --git a/packages/devs/spi/freescale/dspi/current/ChangeLog b/packages/devs/spi/freescale/dspi/current/ChangeLog new file mode 100644 --- /dev/null +++ b/packages/devs/spi/freescale/dspi/current/ChangeLog @@ -0,0 +1,32 @@ +2012-01-06 Ilija Kocho + + * cdl/spi_freescale_dspi.cdl: + * include/spi_freescale_dspi.h + * include/spi_freescale_dspi_io.h: + * include/spi_freescale_dspi_buses.inl + * src/spi_freescale_dspi.c: + New package -- Freescale DSPI SPI driver. [Bugzilla 1001450] + +//=========================================================================== +// ####GPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2012 Free Software Foundation, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 or (at your option) any +// later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., 51 Franklin Street, +// Fifth Floor, Boston, MA 02110-1301, USA. +// ------------------------------------------- +// ####GPLCOPYRIGHTEND#### +//=========================================================================== diff --git a/packages/devs/spi/freescale/dspi/current/cdl/spi_freescale_dspi.cdl b/packages/devs/spi/freescale/dspi/current/cdl/spi_freescale_dspi.cdl new file mode 100644 --- /dev/null +++ b/packages/devs/spi/freescale/dspi/current/cdl/spi_freescale_dspi.cdl @@ -0,0 +1,486 @@ +##============================================================================= +## +## spi_freescale_dspi.cdl +## +## Freescale DSPI driver configuration options. +## +##============================================================================= +## ####ECOSGPLCOPYRIGHTBEGIN#### +## ------------------------------------------- +## This file is part of eCos, the Embedded Configurable Operating System. +## Copyright (C) 2011 Free Software Foundation, Inc. +## +## eCos is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free +## Software Foundation; either version 2 or (at your option) any later +## version. +## +## eCos is distributed in the hope that it will be useful, but WITHOUT +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +## for more details. +## +## You should have received a copy of the GNU General Public License +## along with eCos; if not, write to the Free Software Foundation, Inc., +## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +## +## As a special exception, if other files instantiate templates or use +## macros or inline functions from this file, or you compile this file +## and link it with other works to produce a work based on this file, +## this file does not by itself cause the resulting work to be covered by +## the GNU General Public License. However the source code for this file +## must still be made available in accordance with section (3) of the GNU +## General Public License v2. +## +## This exception does not invalidate any other reasons why a work based +## on this file might be covered by the GNU General Public License. +## ------------------------------------------- +## ####ECOSGPLCOPYRIGHTEND#### +##============================================================================= +#######DESCRIPTIONBEGIN#### +## +## Author(s): Ilija Kocho +## Date: 2011-11-03 +## Purpose: Configure Freescale DSPI driver. +## +######DESCRIPTIONEND#### +## +##============================================================================= + +cdl_package CYGPKG_DEVS_SPI_FREESCALE_DSPI { + display "Freescale DSPI driver" + description " + This package provides SPI driver support for the Freescale + microcontrollers that employ DSPI interface." + + parent CYGPKG_IO_SPI + active_if CYGPKG_IO_SPI + requires CYGPKG_HAL_CORTEXM_KINETIS + + hardware + include_dir cyg/io + compile spi_freescale_dspi.c + + cdl_option CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE { + display "DSPI FIFO size" + flavor data + calculated 4 + } + + cdl_component CYGHWR_DEVS_SPI_FREESCALE_DSPI_CTAR_NUM { + display "CTAR registers" + flavor data + calculated 2 + + description "DSPI can have from 2 to 8 CTAR registers that keep + transfer communication settings. In eCos CTAR0 is used for + all normal transfers while CTAR1 is used as auxiliary for + 'transaction end' (non)transfer." + + cdl_component CYGHWR_DEVS_SPI_FREESCALEDSPI_DSPI_CTAR1_AUX { + display "CTAR1 Aux settings" + flavor none + no_define + + cdl_component CYGHWR_DEVS_FREESCALEDSPI_DSPI_CTAR1_AUX_SPEED { + display "Nominal clock speed Hz" + flavor data + default_value 25000000 + + cdl_option CYGHWR_DEVS_FREESCALEDSPI_DSPI_CTAR1_AUX_USE_DBR { + display "Use double baud rate" + flavor bool + default_value 1 + description "Double baud rate is a feature of Freescale DSPI + that may provide higher baud rates but duty the cycle may be + different than 50/50 depdent on scaler/prescaler setting + for achieved baud rate." + } + } + + cdl_option CYGHWR_DEVS_FREESCALEDSPI_DSPI_CTAR1_AUX_CS_DELAY { + display "Nominal chip select delay (units)" + flavor data + legal_values { 1 to 1000 } + default_value 1 + } + + cdl_option CYGHWR_DEVS_FREESCALE_DSPI_DSPI_CTAR1_AUX_DELAY_UNIT { + display "Chip select delay unit (ns)" + flavor data + calculated 100 + } + } + } + + + for { set ::spibus 0 } { $::spibus < 3 } { incr ::spibus } { + + cdl_interface CYGINT_DEVS_SPI_FREESCALE_DSPI[set ::spibus] { + } + + cdl_component CYGHWR_DEVS_SPI_FREESCALE_DSPI[set ::spibus] { + display "Freescale DSPI bus [set ::spibus]" + description "Enable DSPI bus [set :: spibus]." + flavor bool + default_value CYGINT_DEVS_SPI_FREESCALE_DSPI[set ::spibus] + active_if CYGINT_DEVS_SPI_FREESCALE_DSPI[set ::spibus] + + implements CYGINT_HAL_DMA + requires CYGPKG_HAL_FREESCALE_EDMA + + cdl_component CYGHWR_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_CS { + display "Chip-selects" + flavor none + no_define + cdl_option CYHGWR_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_PCSS { + display "Chip-select Strobe enable" + flavor bool + default_value 0 + + requires CYHGWR_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_PCSS == 1 \ + implies CYGHWR_FREESCALE_DSPI[set ::spibus]_CS5 == 0 + } + + cdl_interface CYGINT_FREESCALE_DSPI[set ::spibus]_CS0 { + description " + Number of devices selected by CS0. + May be be 0 or 1" + } + + cdl_component CYGHWR_FREESCALE_DSPI[set ::spibus]_CS0 { + display "CS0" + flavor bool + calculated CYGINT_FREESCALE_DSPI[set ::spibus]_CS0 + active_if CYGINT_FREESCALE_DSPI[set ::spibus]_CS0 + + requires CYGINT_FREESCALE_DSPI[set ::spibus]_CS0 == 1 + + cdl_option CYGHWR_FREESCALE_DSPI[set ::spibus]_CS0_IS { + display "CS0 Inactive state Hi(1) Lo(0)" + flavor data + no_define + default_value { 1 } + legal_values { 0 1 } + } + } + + cdl_interface CYGINT_FREESCALE_DSPI[set ::spibus]_CS1 { + description " + Number of devices selected by CS1. + May be be 0 or 1" + } + + cdl_component CYGHWR_FREESCALE_DSPI[set ::spibus]_CS1 { + display "CS1" + flavor bool + calculated CYGINT_FREESCALE_DSPI[set ::spibus]_CS1 + active_if CYGINT_FREESCALE_DSPI[set ::spibus]_CS1 + + requires CYGINT_FREESCALE_DSPI[set ::spibus]_CS1 == 1 + + cdl_option CYGHWR_FREESCALE_DSPI[set ::spibus]_CS1_IS { + display "CS1 Inactive state Hi(1) Lo(0)" + flavor data + no_define + default_value { 1 } + legal_values { 0 1 } + } + } + + cdl_interface CYGINT_FREESCALE_DSPI[set ::spibus]_CS2 { + description " + Number of devices selected by CS2. + May be be 0 or 1" + } + + cdl_component CYGHWR_FREESCALE_DSPI[set ::spibus]_CS2 { + display "CS2" + flavor bool + calculated CYGINT_FREESCALE_DSPI[set ::spibus]_CS2 + active_if CYGINT_FREESCALE_DSPI[set ::spibus]_CS2 + + requires CYGINT_FREESCALE_DSPI[set ::spibus]_CS2 == 1 + + cdl_option CYGHWR_FREESCALE_DSPI[set ::spibus]_CS2_IS { + display "CS2 Inactive state Hi(1) Lo(0)" + flavor data + no_define + default_value { 1 } + legal_values { 0 1 } + } + } + + cdl_interface CYGINT_FREESCALE_DSPI[set ::spibus]_CS3 { + description " + Number of devices selected by CS3. + May be be 0 or 1" + } + + cdl_component CYGHWR_FREESCALE_DSPI[set ::spibus]_CS3 { + display "CS3" + flavor bool + calculated CYGINT_FREESCALE_DSPI[set ::spibus]_CS3 + active_if CYGINT_FREESCALE_DSPI[set ::spibus]_CS3 + + requires CYGINT_FREESCALE_DSPI[set ::spibus]_CS3 == 1 + + cdl_option CYGHWR_FREESCALE_DSPI[set ::spibus]_CS3_IS { + display "CS3 Inactive state Hi(1) Lo(0)" + flavor data + no_define + default_value { 1 } + legal_values { 0 1 } + } + } + + cdl_interface CYGINT_FREESCALE_DSPI[set ::spibus]_CS4 { + description " + Number of devices selected by CS4. + May be be 0 or 1" + } + + cdl_component CYGHWR_FREESCALE_DSPI[set ::spibus]_CS4 { + display "CS4" + flavor bool + calculated CYGINT_FREESCALE_DSPI[set ::spibus]_CS4 + active_if CYGINT_FREESCALE_DSPI[set ::spibus]_CS4 + + requires CYGINT_FREESCALE_DSPI[set ::spibus]_CS4 == 1 + + cdl_option CYGHWR_FREESCALE_DSPI[set ::spibus]_CS4_IS { + display "CS4 Inactive state Hi(1) Lo(0)" + flavor data + no_define + default_value { 1 } + legal_values { 0 1 } + } + } + + cdl_interface CYGINT_FREESCALE_DSPI[set ::spibus]_CS5 { + description " + Number of devices selected by CS5. + May be be 0 or 1" + } + + cdl_component CYGHWR_FREESCALE_DSPI[set ::spibus]_CS5 { + display "CS5" + flavor bool + calculated CYGINT_FREESCALE_DSPI[set ::spibus]_CS5 + active_if CYGINT_FREESCALE_DSPI[set ::spibus]_CS5 + + requires CYGINT_FREESCALE_DSPI[set ::spibus]_CS5 == 1 + + cdl_option CYGHWR_FREESCALE_DSPI[set ::spibus]_CS5_IS { + display "CS5 Inactive state Hi(1) Lo(0)" + flavor data + no_define + default_value { 1 } + legal_values { 0 1 } + } + } + + cdl_component CYGHWR_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_PCSIS { + display "Peripheral CS inactive states" + flavor data + calculated (0x0 + \ + (get_data(CYGHWR_FREESCALE_DSPI[set ::spibus]_CS0_IS) == 1 ? 1 : 0) + \ + (get_data(CYGHWR_FREESCALE_DSPI[set ::spibus]_CS1_IS) == 1 ? 2 : 0) + \ + (get_data(CYGHWR_FREESCALE_DSPI[set ::spibus]_CS2_IS) == 1 ? 4 : 0) + \ + (get_data(CYGHWR_FREESCALE_DSPI[set ::spibus]_CS3_IS) == 1 ? 8 : 0) + \ + (get_data(CYGHWR_FREESCALE_DSPI[set ::spibus]_CS4_IS) == 1 ? 16 : 0) + \ + (get_data(CYGHWR_FREESCALE_DSPI[set ::spibus]_CS5_IS) == 1 ? 32 : 0)) + } + } + + cdl_interface CYGINT_FREESCALE_DSPI[set ::spibus]_HAS_MASS { + description "SPI bus serves mas data device(s)." + } + + cdl_option CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_PUSHQUE_SIZE { + display "Queue buffer size" + description " + DSPI requires a command for every transfer so output + data must be re-packed in additional buffer prior to + being submitted to DMA. + If Queue capacity is same as DSPI FIFO size, the minimal + legal value, the DMA is not needed so no buffer memory + is allocated. Note: For every entry, byte (8 bit transfer) + or half word (16 bit transfer) a whole 32 bit word + is being allocated." + + legal_values { CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE to 2048 } + flavor data + default_value CYGINT_FREESCALE_DSPI[set ::spibus]_HAS_MASS ? 128 : \ + CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE + } + + cdl_interface CYGINT_DEVS_SPI_DSPI[set ::spibus]_USES_DMA { + flavor bool + } + + cdl_component CYGHWR_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_TX_DMA_CHAN { + display "TX DMA channel" + flavor data + implements CYGINT_DEVS_SPI_DSPI[set ::spibus]_USES_DMA + + active_if CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_PUSHQUE_SIZE > \ + CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE + default_value 6 + legal_values { 0 to (CYGNUM_HAL_FREESCALE_EDMA_CHAN_NUM-1) } + description "DMA channel assigned to the trasmitter of SPI bus" + + cdl_component CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_TX_DMA_PRI { + display "Transmit DMA channel priority" + flavor data + legal_values { 0 to (CYGNUM_HAL_FREESCALE_EDMA_CHAN_NUM-1) 255 } + default_value 255 + description " + DMA can work in either round robin or preeptve arbitration + mode. In preemptive mode, DMA each channel has unique priority, + lower number meaning lower priority. + 255 is a phony meaning \"default channel priority\"." + + cdl_option CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_TX_DMA_ECP { + display "Enable channel preemption" + flavor data + legal_values { 0 1 } + default_value 0 + } + + cdl_option CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_TX_DMA_DPA { + display "Disable preempt ability" + flavor data + legal_values { 0 1 } + default_value 0 + } + + } + + cdl_option CYGOPT_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_TCD_SECTION { + display "DMA TCD section" + flavor data + default_value { "\".sram\"" } + legal_values { "\".sram\"" "\".ram\"" } + + description " + Section in which will be DMA Transfer Control + Descriptors shall reside" + } + } + + cdl_component CYGHWR_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_RX_DMA_CHAN { + display "RX DMA channel" + flavor data + implements CYGINT_DEVS_SPI_DSPI[set ::spibus]_USES_DMA + + active_if CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_PUSHQUE_SIZE > \ + CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE + default_value 7 + legal_values { 0 to (CYGNUM_HAL_FREESCALE_EDMA_CHAN_NUM-1) } + description "DMA channel assigned to the receiver of SPI bus" + + cdl_component CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_RX_DMA_PRI { + display "Receive DMA channel priority" + flavor data + legal_values { 0 to (CYGNUM_HAL_FREESCALE_EDMA_CHAN_NUM-1) 255 } + default_value 255 + description " + DMA can work in either round robin or preeptve arbitration + mode. In preemptive mode, DMA each channel has unique priority, + lower number meaning lower priority. + 255 is a phony meaning \"default channel priority\"." + + cdl_option CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_RX_DMA_ECP { + display "Enable channel preemption" + flavor data + legal_values { 0 1 } + default_value 0 + } + + cdl_option CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_RX_DMA_DPA { + display "Disable preempt ability" + flavor data + legal_values { 0 1 } + default_value 0 + } + } + } + + cdl_option CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_ISR_PRI { + display "Interrupt priority" + flavor data + requires CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_ISR_PRI_SP + calculated CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_ISR_PRI_SP + description "Interrupt priority set-point is provtded bu HAL" + } + } + } + +cdl_option CYGPKG_DEVS_SPI_FREESCALE_DSPI_DEBUG_LEVEL { + display "Driver debug output level" + flavor data + legal_values { 0 1 2 3 } + default_value 0 + description " + This option specifies the level of debug data output by + the Freescale DSPI device driver. A value of 0 signifies + no debug data output; 1 signifies normal debug data + output; and 2 signifies maximum debug data output." + } + + + cdl_component CYGPKG_DEVS_SPI_FREESCALE_DSPI_OPTIONS { + display "Freescale DSPI driver build options" + flavor none + description " + Package specific build options including control over + compiler flags used only in building this package, + and details of which tests are built." + + cdl_option CYGPKG_DEVS_SPI_FREESCALE_DSPI_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building the Freescale DSPI driver. These flags are used in addition + to the set of global flags." + } + + cdl_option CYGPKG_DEVS_SPI_FREESCALE_DSPI_CFLAGS_REMOVE { + display "Suppressed compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building the Freescale DSPI driver. These flags are removed from + the set of global flags if present." + } + + cdl_option CYGBLD_DEVS_SPI_FREESCALE_DSPI_LOOPBACK_TEST { + display "Build Freescale DSPI loopback test" + flavor bool + no_define + default_value 0 + requires { CYGHWR_DEVS_SPI_FREESCALE_DSPI0 || + CYGHWR_DEVS_SPI_FREESCALE_DSPI1 || + CYGHWR_DEVS_SPI_FREESCALE_DSPI2 } + description " + This option enables the building of the Freescale DSPI loopback test. + Refer to the comments in tests/loopback.c for details of how to + use this test." + } + + cdl_option CYGPKG_DEVS_SPI_FREESCALE_DSPI_TESTS { + display "Freescale DSPI tests" + flavor data + no_define + calculated { CYGBLD_DEVS_SPI_FREESCALE_DSPI_LOOPBACK_TEST ? "tests/loopback" : "" } + } + } + +} +# EOF spi_freescale_dspi.cdl diff --git a/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi.h b/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi.h new file mode 100644 --- /dev/null +++ b/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi.h @@ -0,0 +1,206 @@ +#ifndef CYGONCE_DEVS_SPI_FREESCALE_DSPI_H +#define CYGONCE_DEVS_SPI_FREESCALE_DSPI_H +//============================================================================= +// +// spi_freescale_dspi.h +// +// Header definitions for Freescale DSPI driver. +// +//============================================================================= +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later +// version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License +// along with eCos; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// As a special exception, if other files instantiate templates or use +// macros or inline functions from this file, or you compile this file +// and link it with other works to produce a work based on this file, +// this file does not by itself cause the resulting work to be covered by +// the GNU General Public License. However the source code for this file +// must still be made available in accordance with section (3) of the GNU +// General Public License v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//============================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): ilijak +// Date: 2011-11-03 +// Purpose: Freescale DSPI driver definitions. +// Description: +// Usage: #include +// +//####DESCRIPTIONEND#### +// +//============================================================================= + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +//----------------------------------------------------------------------------- +// Macro for defining a SPI device and attaching it to the appropriate bus. +// +// _name_ is the name of the SPI device. This will be used to reference a +// data structure of type cyg_spi_device which can be passed to the +// SPI driver API without needing a cast. +// _bus_ is the bus number to which this device is attached (0, 1 or 2). +// _csnum_ is the chip select line used for this device, numbered from 0. +// _fmsz_ is set device SPI frame size (bits) +// _clpol_ is the SPI bus clock polarity used by the device. This must be +// set to 1 if clock inactive state is high, 0 if clock inactive +// state is low. +// _clpha_ is the SPI bus clock phase used by the device. +// _brate_ is the SPI bus clock baud rate used by the device, measured in Hz. +// _csup_dly_ is the minimum delay between chip select assert and transfer +// start, measured in microseconds. +// _csdw_dly_ is the minimum delay between transfer end and chip select deassert, +// measured in delay units. +// _trbt_dly_ is the minimum delay between consecutive transfers. +// _dlu_ is delay unit in ns +// _dbr_ is enabling double baud rate feature + + +#define CYGNUM_DSPI_DELAY_UNIT(__val) (__val/10) + +#define CYG_SPI_BUS_NAME(_b_) cyg_spi_dspi_bus ## _b_ + +#define CYG_DEVS_SPI_FREESCALE_DSPI_DEVICE( \ + _name_, _bus_, _csnum_, _fmsz_, _clpol_, _clpha_, _brate_, _csup_dly_, _csdw_dly_, _trbt_dly_, _dlu_, _dbr_ \ +) \ + cyg_spi_freescale_dspi_device_t _name_ ##_fs_dspi CYG_SPI_DEVICE_ON_BUS(_bus_) = { \ +{ .spi_bus = (cyg_spi_bus*) &CYG_SPI_BUS_NAME(_bus_) }, \ + .dev_num = _csnum_, \ + .clocking.bus_16bit = _fmsz_ > 8 ? 1 : 0, \ + .clocking.frame_size = _fmsz_, \ + .clocking.cl_pol = _clpol_, \ + .clocking.cl_pha = _clpha_, \ + .clocking.cl_brate = _brate_, \ + .clocking.cs_up_udly = _csup_dly_, \ + .clocking.cs_dw_udly = _csdw_dly_, \ + .clocking.tr_bt_udly = _trbt_dly_, \ + .clocking.dl_unit = CYGNUM_DSPI_DELAY_UNIT(_dlu_), \ + .clocking.cl_dbr = _dbr_, \ + .clocking.dspi_ctar = 0 \ +}; \ +extern cyg_spi_device _name_ __attribute__((alias ( #_name_ "_fs_dspi" ))) + +enum { SPI_DMA_CHAN_TX_I, SPI_DMA_CHAN_RX_I }; + +//----------------------------------------------------------------------------- +// Freescale DSPI bus configuration and state. + +typedef struct cyg_spi_freescale_dspi_bus_setup_s +{ + cyghwr_devs_freescale_dspi_t* dspi_p; // Base address of SPI register block. + cyghwr_hal_freescale_dma_set_t* dma_set_p; // DMA configuration block. + cyg_vector_t intr_num; // DSPI interrupt vector + cyg_priority_t intr_prio; // Interrupt priority + cyg_uint32 mcr_opt ; // Module Configuratyon Register options + const cyg_uint32* spi_pin_list_p; // List of GPIOs used by the SPI interface. + const cyg_uint32* cs_pin_list_p; // List of GPIOs used as chip selects. + cyg_uint8 cs_pin_num; // Number of chip selects for this bus. +} cyg_spi_freescale_dspi_bus_setup_t; + +#define SPI_DMA_CHAN_I(__dma_set,__rt) (__dma_set->chan_p[SPI_DMA_CHAN_ ## __rt ## _I].dma_chan_i) + +typedef struct cyg_spi_freescale_dspi_bus_s +{ + // ---- Upper layer data ---- + cyg_spi_bus spi_bus; // Upper layer SPI bus data. + + // ---- Bus configuration constants ---- + const cyg_spi_freescale_dspi_bus_setup_t* setup_p; + // ---- Driver state (private) ---- + // DMA transfer control descriptors + const cyghwr_hal_freescale_edma_tcd_t* tx_dma_tcd_ini_p; // TCD init. + const cyghwr_hal_freescale_edma_tcd_t* rx_dma_tcd_ini_p; // data + volatile cyghwr_hal_freescale_edma_tcd_t* rx_dma_tcd_p; // DMA TCD (RX) + volatile cyghwr_hal_freescale_edma_tcd_t* tx_dma_tcd_p; // DMA TCD (TX) + volatile cyg_uint32* pushque_p; // Tx command queue + cyg_uint16 pushque_n; // Tx command buffer size + cyg_uint8 txfifo_n; // TxFIFO size + cyg_uint8 rxfifo_n; // RxFIFO size + cyg_interrupt intr_data; // Interrupt state + cyg_handle_t intr_handle; // Interrupt handle + cyg_drv_mutex_t transfer_mutex; // Transfer mutex. + cyg_drv_cond_t transfer_done; // Transfer condition variable. + cyg_uint32 clock_freq; // Clock provided by hal +} cyg_spi_freescale_dspi_bus_t; + +//----------------------------------------------------------------------------- +// Freescale DSPI device. + +typedef struct cyg_freescale_dspi_clocking_s { + cyg_uint32 dspi_ctar; // DSPI Clock and Transfer Attributes Rregister shadow. + cyg_uint32 cl_brate; // Clock baud rate. + cyg_uint8 bus_16bit; // Use 16 bit (1) or 8 bit (0) transfers. + cyg_uint8 cl_pol; // Clock polarity (0 or 1). + cyg_uint8 cl_pha; // Clock phase (0 or 1). + cyg_uint8 cl_dbr; // Use double baud-rate feature if needed + cyg_uint8 cs_up_udly; // Minimum delay in us/ns between CS up and transfer start. + cyg_uint8 cs_dw_udly; // Minimum delay in us/ns between transfer end and CS down. + cyg_uint8 tr_bt_udly; // Minimum delay in us/ns between two transfers. + cyg_uint8 dl_unit; // Delay unit (1/10 * ns) + cyg_uint8 lsb_first; // LSbit shifted first. + cyg_uint8 frame_size; // Device SPI frame size (bits). +} cyg_freescale_dspi_clocking_t;; + +typedef struct cyg_spi_freescale_dspi_device_s +{ + // ---- Upper layer data ---- + cyg_spi_device spi_device; // Upper layer SPI device data. + + // ---- Device setup (user configurable) ---- + cyg_freescale_dspi_clocking_t clocking; + cyg_uint8 dev_num; // Device SPI select. + cyg_uint8 chip_sel; + // ---- Device state (private) ---- +} cyg_spi_freescale_dspi_device_t; + +//----------------------------------------------------------------------------- +// Exported bus data structures. + +#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI0 +externC cyg_spi_freescale_dspi_bus_t cyg_spi_dspi_bus0; +#endif + +#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI1 +externC cyg_spi_freescale_dspi_bus_t cyg_spi_dspi_bus1; +#endif + +#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI2 +externC cyg_spi_freescale_dspi_bus_t cyg_spi_dspi_bus2; +#endif + +__externC void cyghwr_devs_freescale_dspi_diag(cyg_spi_freescale_dspi_bus_t* spi_bus_p); +__externC void cyghwr_devs_freescale_dspi_diag_array(char* name_p, + volatile cyg_uint32* fifo_p, + cyg_uint32 fifo_n); + +//============================================================================= +#endif // CYGONCE_DEVS_SPI_FREESCALE_DSPI_H diff --git a/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi_buses.inl b/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi_buses.inl new file mode 100644 --- /dev/null +++ b/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi_buses.inl @@ -0,0 +1,525 @@ +#ifndef SPI_FREESCALE_DSPI_BUSES_INL +#define SPI_FREESCALE_DSPI_BUSES_INL +//============================================================================= +// +// spi_freescale_dspi_buses.inl +// +// SPI bus instantiation for Freescale DSPI +// +//============================================================================= +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later +// version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License +// along with eCos; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// As a special exception, if other files instantiate templates or use +// macros or inline functions from this file, or you compile this file +// and link it with other works to produce a work based on this file, +// this file does not by itself cause the resulting work to be covered by +// the GNU General Public License. However the source code for this file +// must still be made available in accordance with section (3) of the GNU +// General Public License v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//============================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): ilijak +// Date: 2011-11-09 +// Purpose: Freescale DSPI DSPI bus instantiation +// +//####DESCRIPTIONEND#### +// +//============================================================================= + + +#define PUSHQUE_ALIGN CYGBLD_ATTRIB_ALIGN(4) + +#define DSPI_DMA_BANDWIDTH FREESCALE_EDMA_CSR_BWC_0 + +//----------------------------------------------------------------------------- +// Instantiate the bus state data structures. + + +// DSPI0 BUS ================================================================= +#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI0 + +#define CYGBLD_DSPI0_TCD_SECTION \ + CYGBLD_ATTRIB_SECTION(CYGOPT_DEVS_SPI_FREESCALE_DSPI0_TCD_SECTION) + +extern cyg_spi_freescale_dspi_bus_t cyg_spi_dspi_bus1; + +// Pinonomy ------------------------------------------------------------------- + +#ifdef CYHGWR_DEVS_SPI_FREESCALE_DSPI0_PCSS +#define CYGHWR_FREESCALE_DSPI0_MCR_PCSSE FREESCALE_DSPI_MCR_PCSSE_M +#else +#define CYGHWR_FREESCALE_DSPI0_MCR_PCSSE 0 +#endif + +static const cyg_uint32 spi0_pins[] = { + CYGHWR_IO_FREESCALE_SPI0_PIN_SIN, + CYGHWR_IO_FREESCALE_SPI0_PIN_SOUT, + CYGHWR_IO_FREESCALE_SPI0_PIN_SCK +}; + +// SPI chip select pins. +static const cyg_uint32 spi0_cs_pins[] = { +#ifdef CYGHWR_FREESCALE_DSPI0_CS0 + CYGHWR_IO_FREESCALE_SPI0_PIN_CS0, +#endif +#ifdef CYGHWR_FREESCALE_DSPI0_CS1 + CYGHWR_IO_FREESCALE_SPI0_PIN_CS1, +#endif +#ifdef CYGHWR_FREESCALE_DSPI0_CS2 + CYGHWR_IO_FREESCALE_SPI0_PIN_CS2, +#endif +#ifdef CYGHWR_FREESCALE_DSPI0_CS3 + CYGHWR_IO_FREESCALE_SPI0_PIN_CS3, +#endif +#ifdef CYGHWR_FREESCALE_DSPI0_CS4 + CYGHWR_IO_FREESCALE_SPI0_PIN_CS4, +#endif +#ifdef CYGHWR_FREESCALE_DSPI0_CS5 + CYGHWR_IO_FREESCALE_SPI0_PIN_CS5 +#endif +}; + +#ifdef CYGINT_DEVS_SPI_DSPI0_USES_DMA +static volatile +cyg_uint32 dspi0_pushque[CYGNUM_DEVS_SPI_FREESCALE_DSPI0_PUSHQUE_SIZE+4] PUSHQUE_ALIGN; + +static const cyghwr_hal_freescale_dma_chan_set_t dspi0_dma_chan[] = { + { + .dma_src = FREESCALE_DMAMUX_SRC_SPI0_TX + | FREESCALE_DMAMUX_CHCFG_ENBL_M, + .dma_chan_i = CYGHWR_DEVS_SPI_FREESCALE_DSPI0_TX_DMA_CHAN, + .dma_prio = CYGNUM_DEVS_SPI_FREESCALE_DSPI0_TX_DMA_PRI, + }, + { + .dma_src = FREESCALE_DMAMUX_SRC_SPI0_RX + | FREESCALE_DMAMUX_CHCFG_ENBL_M, + .dma_chan_i = CYGHWR_DEVS_SPI_FREESCALE_DSPI0_RX_DMA_CHAN, + .dma_prio = CYGNUM_DEVS_SPI_FREESCALE_DSPI0_RX_DMA_PRI, + } +}; + +static cyghwr_hal_freescale_dma_set_t dspi0_dma_set = { + .edma_p = CYGHWR_IO_FREESCALE_EDMA0_P, + .dmamux_p = CYGHWR_IO_FREESCALE_DMAMUX0_P, + .chan_p = dspi0_dma_chan, + .chan_n = 2 +}; + +static const cyghwr_hal_freescale_edma_tcd_t dspi0_dma_tcd_tx_ini = +{ + .saddr = (cyg_uint32 *) dspi0_pushque, + .soff = 4, + .attr = FREESCALE_EDMA_ATTR_SSIZE(FREESCALE_EDMA_ATTR_SIZE_32) | + FREESCALE_EDMA_ATTR_DSIZE(FREESCALE_EDMA_ATTR_SIZE_32) | + FREESCALE_EDMA_ATTR_SMOD(0) | + FREESCALE_EDMA_ATTR_DMOD(0), + .daddr = (cyg_uint32 *)&CYGADDR_IO_SPI_FREESCALE_DSPI0_P->pushr, + .doff = 0, + .nbytes.mlno = 4, + .slast = 0, + .citer.elinkno = 1, + {.dlast = 0}, + .biter.elinkno = 1, + .csr = DSPI_DMA_BANDWIDTH +}; + + +static const cyghwr_hal_freescale_edma_tcd_t dspi0_dma_tcd_rx_ini = +{ + .saddr = (cyg_uint32 *)&CYGADDR_IO_SPI_FREESCALE_DSPI0_P->popr, + .soff = 0, + .attr = FREESCALE_EDMA_ATTR_SSIZE(FREESCALE_EDMA_ATTR_SIZE_32) | + FREESCALE_EDMA_ATTR_DSIZE(FREESCALE_EDMA_ATTR_SIZE_32) | + FREESCALE_EDMA_ATTR_SMOD(0) | + FREESCALE_EDMA_ATTR_DMOD(0), + .daddr = NULL, + .doff = 4, + .nbytes.mlno = 4, + .slast = 0, + .citer.elinkno = 1, + {.dlast = 0}, + .biter.elinkno = 1, + .csr = DSPI_DMA_BANDWIDTH +}; + +#endif // CYGINT_DEVS_SPI_DSPI0_USES_DMA + +static const cyg_spi_freescale_dspi_bus_setup_t dspi0_setup = { + .dspi_p = CYGADDR_IO_SPI_FREESCALE_DSPI0_P, +#ifdef CYGINT_DEVS_SPI_DSPI0_USES_DMA + .dma_set_p = &dspi0_dma_set, +#else + .dma_set_p = NULL, +#endif + .intr_num = CYGNUM_HAL_INTERRUPT_SPI0, + .intr_prio = CYGNUM_DEVS_SPI_FREESCALE_DSPI0_ISR_PRI, + .spi_pin_list_p = spi0_pins, + .cs_pin_list_p = spi0_cs_pins, + .cs_pin_num = sizeof(spi0_cs_pins)/sizeof(spi0_cs_pins[0]), + .mcr_opt = CYGHWR_FREESCALE_DSPI0_MCR_PCSSE | + FREESCALE_DSPI_MCR_PCSIS(CYGHWR_DEVS_SPI_FREESCALE_DSPI0_PCSIS) +}; + +cyg_spi_freescale_dspi_bus_t cyg_spi_dspi_bus1 = { + .spi_bus.spi_transaction_begin = dspi_transaction_begin, + .spi_bus.spi_transaction_transfer = dspi_transaction_transfer, + .spi_bus.spi_transaction_tick = dspi_transaction_tick, + .spi_bus.spi_transaction_end = dspi_transaction_end, + .spi_bus.spi_get_config = dspi_get_config, + .spi_bus.spi_set_config = dspi_set_config, + .setup_p = &dspi0_setup, +#ifdef CYGINT_DEVS_SPI_DSPI0_USES_DMA + .tx_dma_tcd_p = &CYGHWR_IO_FREESCALE_EDMA0_P-> + tcd[CYGHWR_DEVS_SPI_FREESCALE_DSPI0_TX_DMA_CHAN], + .rx_dma_tcd_p = &CYGHWR_IO_FREESCALE_EDMA0_P-> + tcd[CYGHWR_DEVS_SPI_FREESCALE_DSPI0_RX_DMA_CHAN], + .tx_dma_tcd_ini_p = &dspi0_dma_tcd_tx_ini, + .rx_dma_tcd_ini_p = &dspi0_dma_tcd_rx_ini, + .pushque_p = dspi0_pushque, +#else // CYGINT_DEVS_SPI_DSPI0_USES_DMA + .tx_dma_tcd_p = NULL, + .rx_dma_tcd_p = NULL, + .tx_dma_tcd_ini_p = NULL, + .rx_dma_tcd_ini_p = NULL, + .pushque_p = NULL, +#endif // CYGINT_DEVS_SPI_DSPI0_USES_DMA + .pushque_n = CYGNUM_DEVS_SPI_FREESCALE_DSPI0_PUSHQUE_SIZE, + .txfifo_n = CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE, + .rxfifo_n = CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE +}; +#endif + +// DSPI1 BUS ================================================================= +#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI1 + +#define CYGBLD_DSPI1_TCD_SECTION \ + CYGBLD_ATTRIB_SECTION(CYGOPT_DEVS_SPI_FREESCALE_DSPI1_TCD_SECTION) + +extern cyg_spi_freescale_dspi_bus_t cyg_spi_dspi_bus1; + +// Pinonomy ------------------------------------------------------------------- + +#ifdef CYHGWR_DEVS_SPI_FREESCALE_DSPI1_PCSS +#define CYGHWR_FREESCALE_DSPI1_MCR_PCSSE FREESCALE_DSPI_MCR_PCSSE_M +#else +#define CYGHWR_FREESCALE_DSPI1_MCR_PCSSE 0 +#endif + +static const cyg_uint32 spi1_pins[] = { + CYGHWR_IO_FREESCALE_SPI1_PIN_SIN, + CYGHWR_IO_FREESCALE_SPI1_PIN_SOUT, + CYGHWR_IO_FREESCALE_SPI1_PIN_SCK +}; + +// SPI chip select pins. +static const cyg_uint32 spi1_cs_pins[] = { +#ifdef CYGHWR_FREESCALE_DSPI1_CS0 + CYGHWR_IO_FREESCALE_SPI1_PIN_CS0, +#endif +#ifdef CYGHWR_FREESCALE_DSPI1_CS1 + CYGHWR_IO_FREESCALE_SPI1_PIN_CS1, +#endif +#ifdef CYGHWR_FREESCALE_DSPI1_CS2 + CYGHWR_IO_FREESCALE_SPI1_PIN_CS2, +#endif +#ifdef CYGHWR_FREESCALE_DSPI1_CS3 + CYGHWR_IO_FREESCALE_SPI1_PIN_CS3, +#endif +#ifdef CYGHWR_FREESCALE_DSPI1_CS4 + CYGHWR_IO_FREESCALE_SPI1_PIN_CS4, +#endif +#ifdef CYGHWR_FREESCALE_DSPI1_CS5 + CYGHWR_IO_FREESCALE_SPI1_PIN_CS5 +#endif +}; + +#ifdef CYGINT_DEVS_SPI_DSPI1_USES_DMA +static volatile +cyg_uint32 dspi1_pushque[CYGNUM_DEVS_SPI_FREESCALE_DSPI1_PUSHQUE_SIZE+4] PUSHQUE_ALIGN; + +static const cyghwr_hal_freescale_dma_chan_set_t dspi1_dma_chan[] = { + { + .dma_src = FREESCALE_DMAMUX_SRC_SPI1_TX + | FREESCALE_DMAMUX_CHCFG_ENBL_M, + .dma_chan_i = CYGHWR_DEVS_SPI_FREESCALE_DSPI1_TX_DMA_CHAN, + .dma_prio = CYGNUM_DEVS_SPI_FREESCALE_DSPI1_TX_DMA_PRI, + }, + { + .dma_src = FREESCALE_DMAMUX_SRC_SPI1_RX + | FREESCALE_DMAMUX_CHCFG_ENBL_M, + .dma_chan_i = CYGHWR_DEVS_SPI_FREESCALE_DSPI1_RX_DMA_CHAN, + .dma_prio = CYGNUM_DEVS_SPI_FREESCALE_DSPI1_RX_DMA_PRI, + } +}; + +static cyghwr_hal_freescale_dma_set_t dspi1_dma_set = { + .edma_p = CYGHWR_IO_FREESCALE_EDMA0_P, + .dmamux_p = CYGHWR_IO_FREESCALE_DMAMUX0_P, + .chan_p = dspi1_dma_chan, + .chan_n = 2 +}; + +static const cyghwr_hal_freescale_edma_tcd_t dspi1_dma_tcd_tx_ini = +{ + .saddr = (cyg_uint32 *) dspi1_pushque, + .soff = 4, + .attr = FREESCALE_EDMA_ATTR_SSIZE(FREESCALE_EDMA_ATTR_SIZE_32) | + FREESCALE_EDMA_ATTR_DSIZE(FREESCALE_EDMA_ATTR_SIZE_32) | + FREESCALE_EDMA_ATTR_SMOD(0) | + FREESCALE_EDMA_ATTR_DMOD(0), + .daddr = (cyg_uint32 *)&CYGADDR_IO_SPI_FREESCALE_DSPI1_P->pushr, + .doff = 0, + .nbytes.mlno = 4, + .slast = 0, + .citer.elinkno = 1, + {.dlast = 0}, + .biter.elinkno = 1, + .csr = DSPI_DMA_BANDWIDTH +}; + + +static const cyghwr_hal_freescale_edma_tcd_t dspi1_dma_tcd_rx_ini = +{ + .saddr = (cyg_uint32 *)&CYGADDR_IO_SPI_FREESCALE_DSPI1_P->popr, + .soff = 0, + .attr = FREESCALE_EDMA_ATTR_SSIZE(FREESCALE_EDMA_ATTR_SIZE_32) | + FREESCALE_EDMA_ATTR_DSIZE(FREESCALE_EDMA_ATTR_SIZE_32) | + FREESCALE_EDMA_ATTR_SMOD(0) | + FREESCALE_EDMA_ATTR_DMOD(0), + .daddr = NULL, + .doff = 4, + .nbytes.mlno = 4, + .slast = 0, + .citer.elinkno = 1, + {.dlast = 0}, + .biter.elinkno = 1, + .csr = DSPI_DMA_BANDWIDTH +}; + +#endif // CYGINT_DEVS_SPI_DSPI1_USES_DMA + +static const cyg_spi_freescale_dspi_bus_setup_t dspi1_setup = { + .dspi_p = CYGADDR_IO_SPI_FREESCALE_DSPI1_P, +#ifdef CYGINT_DEVS_SPI_DSPI1_USES_DMA + .dma_set_p = &dspi1_dma_set, +#else + .dma_set_p = NULL, +#endif + .intr_num = CYGNUM_HAL_INTERRUPT_SPI1, + .intr_prio = CYGNUM_DEVS_SPI_FREESCALE_DSPI1_ISR_PRI, + .spi_pin_list_p = spi1_pins, + .cs_pin_list_p = spi1_cs_pins, + .cs_pin_num = sizeof(spi1_cs_pins)/sizeof(spi1_cs_pins[0]), + .mcr_opt = CYGHWR_FREESCALE_DSPI1_MCR_PCSSE | + FREESCALE_DSPI_MCR_PCSIS(CYGHWR_DEVS_SPI_FREESCALE_DSPI1_PCSIS) +}; + +cyg_spi_freescale_dspi_bus_t cyg_spi_dspi_bus1 = { + .spi_bus.spi_transaction_begin = dspi_transaction_begin, + .spi_bus.spi_transaction_transfer = dspi_transaction_transfer, + .spi_bus.spi_transaction_tick = dspi_transaction_tick, + .spi_bus.spi_transaction_end = dspi_transaction_end, + .spi_bus.spi_get_config = dspi_get_config, + .spi_bus.spi_set_config = dspi_set_config, + .setup_p = &dspi1_setup, +#ifdef CYGINT_DEVS_SPI_DSPI1_USES_DMA + .tx_dma_tcd_p = &CYGHWR_IO_FREESCALE_EDMA0_P-> + tcd[CYGHWR_DEVS_SPI_FREESCALE_DSPI1_TX_DMA_CHAN], + .rx_dma_tcd_p = &CYGHWR_IO_FREESCALE_EDMA0_P-> + tcd[CYGHWR_DEVS_SPI_FREESCALE_DSPI1_RX_DMA_CHAN], + .tx_dma_tcd_ini_p = &dspi1_dma_tcd_tx_ini, + .rx_dma_tcd_ini_p = &dspi1_dma_tcd_rx_ini, + .pushque_p = dspi1_pushque, +#else // CYGINT_DEVS_SPI_DSPI1_USES_DMA + .tx_dma_tcd_p = NULL, + .rx_dma_tcd_p = NULL, + .tx_dma_tcd_ini_p = NULL, + .rx_dma_tcd_ini_p = NULL, + .pushque_p = NULL, +#endif // CYGINT_DEVS_SPI_DSPI1_USES_DMA + .pushque_n = CYGNUM_DEVS_SPI_FREESCALE_DSPI1_PUSHQUE_SIZE, + .txfifo_n = CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE, + .rxfifo_n = CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE +}; +#endif + +// DSPI2 BUS ================================================================= +#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI2 + +#define CYGBLD_DSPI2_TCD_SECTION \ + CYGBLD_ATTRIB_SECTION(CYGOPT_DEVS_SPI_FREESCALE_DSPI2_TCD_SECTION) + +extern cyg_spi_freescale_dspi_bus_t cyg_spi_dspi_bus1; + +// Pinonomy ------------------------------------------------------------------- + +#ifdef CYHGWR_DEVS_SPI_FREESCALE_DSPI2_PCSS +#define CYGHWR_FREESCALE_DSPI2_MCR_PCSSE FREESCALE_DSPI_MCR_PCSSE_M +#else +#define CYGHWR_FREESCALE_DSPI2_MCR_PCSSE 0 +#endif + +static const cyg_uint32 spi2_pins[] = { + CYGHWR_IO_FREESCALE_SPI2_PIN_SIN, + CYGHWR_IO_FREESCALE_SPI2_PIN_SOUT, + CYGHWR_IO_FREESCALE_SPI2_PIN_SCK +}; + +// SPI chip select pins. +static const cyg_uint32 spi2_cs_pins[] = { +#ifdef CYGHWR_FREESCALE_DSPI2_CS0 + CYGHWR_IO_FREESCALE_SPI2_PIN_CS0, +#endif +#ifdef CYGHWR_FREESCALE_DSPI2_CS1 + CYGHWR_IO_FREESCALE_SPI2_PIN_CS1, +#endif +#ifdef CYGHWR_FREESCALE_DSPI2_CS2 + CYGHWR_IO_FREESCALE_SPI2_PIN_CS2, +#endif +#ifdef CYGHWR_FREESCALE_DSPI2_CS3 + CYGHWR_IO_FREESCALE_SPI2_PIN_CS3, +#endif +#ifdef CYGHWR_FREESCALE_DSPI2_CS4 + CYGHWR_IO_FREESCALE_SPI2_PIN_CS4, +#endif +#ifdef CYGHWR_FREESCALE_DSPI2_CS5 + CYGHWR_IO_FREESCALE_SPI2_PIN_CS5 +#endif +}; + +#ifdef CYGINT_DEVS_SPI_DSPI2_USES_DMA +static volatile +cyg_uint32 dspi2_pushque[CYGNUM_DEVS_SPI_FREESCALE_DSPI2_PUSHQUE_SIZE+4] PUSHQUE_ALIGN; + +static const cyghwr_hal_freescale_dma_chan_set_t dspi2_dma_chan[] = { + { + .dma_src = FREESCALE_DMAMUX_SRC_SPI2_TX + | FREESCALE_DMAMUX_CHCFG_ENBL_M, + .dma_chan_i = CYGHWR_DEVS_SPI_FREESCALE_DSPI2_TX_DMA_CHAN, + .dma_prio = CYGNUM_DEVS_SPI_FREESCALE_DSPI2_TX_DMA_PRI, + }, + { + .dma_src = FREESCALE_DMAMUX_SRC_SPI2_RX + | FREESCALE_DMAMUX_CHCFG_ENBL_M, + .dma_chan_i = CYGHWR_DEVS_SPI_FREESCALE_DSPI2_RX_DMA_CHAN, + .dma_prio = CYGNUM_DEVS_SPI_FREESCALE_DSPI2_RX_DMA_PRI, + } +}; + +static cyghwr_hal_freescale_dma_set_t dspi2_dma_set = { + .edma_p = CYGHWR_IO_FREESCALE_EDMA0_P, + .dmamux_p = CYGHWR_IO_FREESCALE_DMAMUX0_P, + .chan_p = dspi2_dma_chan, + .chan_n = 2 +}; + +static const cyghwr_hal_freescale_edma_tcd_t dspi2_dma_tcd_tx_ini = +{ + .saddr = (cyg_uint32 *) dspi2_pushque, + .soff = 4, + .attr = FREESCALE_EDMA_ATTR_SSIZE(FREESCALE_EDMA_ATTR_SIZE_32) | + FREESCALE_EDMA_ATTR_DSIZE(FREESCALE_EDMA_ATTR_SIZE_32) | + FREESCALE_EDMA_ATTR_SMOD(0) | + FREESCALE_EDMA_ATTR_DMOD(0), + .daddr = (cyg_uint32 *)&CYGADDR_IO_SPI_FREESCALE_DSPI2_P->pushr, + .doff = 0, + .nbytes.mlno = 4, + .slast = 0, + .citer.elinkno = 1, + {.dlast = 0}, + .biter.elinkno = 1, + .csr = DSPI_DMA_BANDWIDTH +}; + + +static const cyghwr_hal_freescale_edma_tcd_t dspi2_dma_tcd_rx_ini = +{ + .saddr = (cyg_uint32 *)&CYGADDR_IO_SPI_FREESCALE_DSPI2_P->popr, + .soff = 0, + .attr = FREESCALE_EDMA_ATTR_SSIZE(FREESCALE_EDMA_ATTR_SIZE_32) | + FREESCALE_EDMA_ATTR_DSIZE(FREESCALE_EDMA_ATTR_SIZE_32) | + FREESCALE_EDMA_ATTR_SMOD(0) | + FREESCALE_EDMA_ATTR_DMOD(0), + .daddr = NULL, + .doff = 4, + .nbytes.mlno = 4, + .slast = 0, + .citer.elinkno = 1, + {.dlast = 0}, + .biter.elinkno = 1, + .csr = DSPI_DMA_BANDWIDTH +}; + +#endif // CYGINT_DEVS_SPI_DSPI2_USES_DMA + +static const cyg_spi_freescale_dspi_bus_setup_t dspi2_setup = { + .dspi_p = CYGADDR_IO_SPI_FREESCALE_DSPI2_P, +#ifdef CYGINT_DEVS_SPI_DSPI2_USES_DMA + .dma_set_p = &dspi2_dma_set, +#else + .dma_set_p = NULL, +#endif + .intr_num = CYGNUM_HAL_INTERRUPT_SPI2, + .intr_prio = CYGNUM_DEVS_SPI_FREESCALE_DSPI2_ISR_PRI, + .spi_pin_list_p = spi2_pins, + .cs_pin_list_p = spi2_cs_pins, + .cs_pin_num = sizeof(spi2_cs_pins)/sizeof(spi2_cs_pins[0]), + .mcr_opt = CYGHWR_FREESCALE_DSPI2_MCR_PCSSE | + FREESCALE_DSPI_MCR_PCSIS(CYGHWR_DEVS_SPI_FREESCALE_DSPI2_PCSIS) +}; + +cyg_spi_freescale_dspi_bus_t cyg_spi_dspi_bus1 = { + .spi_bus.spi_transaction_begin = dspi_transaction_begin, + .spi_bus.spi_transaction_transfer = dspi_transaction_transfer, + .spi_bus.spi_transaction_tick = dspi_transaction_tick, + .spi_bus.spi_transaction_end = dspi_transaction_end, + .spi_bus.spi_get_config = dspi_get_config, + .spi_bus.spi_set_config = dspi_set_config, + .setup_p = &dspi2_setup, +#ifdef CYGINT_DEVS_SPI_DSPI2_USES_DMA + .tx_dma_tcd_p = &CYGHWR_IO_FREESCALE_EDMA0_P-> + tcd[CYGHWR_DEVS_SPI_FREESCALE_DSPI2_TX_DMA_CHAN], + .rx_dma_tcd_p = &CYGHWR_IO_FREESCALE_EDMA0_P-> + tcd[CYGHWR_DEVS_SPI_FREESCALE_DSPI2_RX_DMA_CHAN], + .tx_dma_tcd_ini_p = &dspi2_dma_tcd_tx_ini, + .rx_dma_tcd_ini_p = &dspi2_dma_tcd_rx_ini, + .pushque_p = dspi2_pushque, +#else // CYGINT_DEVS_SPI_DSPI2_USES_DMA + .tx_dma_tcd_p = NULL, + .rx_dma_tcd_p = NULL, + .tx_dma_tcd_ini_p = NULL, + .rx_dma_tcd_ini_p = NULL, + .pushque_p = NULL, +#endif // CYGINT_DEVS_SPI_DSPI2_USES_DMA + .pushque_n = CYGNUM_DEVS_SPI_FREESCALE_DSPI2_PUSHQUE_SIZE, + .txfifo_n = CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE, + .rxfifo_n = CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE +}; +#endif + + +//============================================================================= +#endif // SPI_FREESCALE_DSPI_BUSES_INL diff --git a/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi_io.h b/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi_io.h new file mode 100644 --- /dev/null +++ b/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi_io.h @@ -0,0 +1,291 @@ +#ifndef CYGONCE_DEVS_SPI_FREESCALE_DSPI_IO_H +#define CYGONCE_DEVS_SPI_FREESCALE_DSPI_IO_H +//============================================================================= +// +// spi_freescale_dspi_io.h +// +// IO definitions for Freescale DSPI. +// +//============================================================================= +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later +// version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License +// along with eCos; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// As a special exception, if other files instantiate templates or use +// macros or inline functions from this file, or you compile this file +// and link it with other works to produce a work based on this file, +// this file does not by itself cause the resulting work to be covered by +// the GNU General Public License. However the source code for this file +// must still be made available in accordance with section (3) of the GNU +// General Public License v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//============================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): ilijak +// Date: 2011-11-03 +// Purpose: Freescale DSPI I/O definitions. +// Description: +// Usage: #include +// +//####DESCRIPTIONEND#### +// +//============================================================================= + + +// ---------------------------------------------------------------------------- +// DSPI + +typedef volatile struct cyghwr_devs_freescale_dspi_s { + cyg_uint32 mcr; // Module Configuration Register + cyg_uint32 reserved_0; + cyg_uint32 tcr; // Transfer Count Register + // Clock and Transfer Attributes Register + cyg_uint32 ctar[CYGHWR_DEVS_SPI_FREESCALE_DSPI_CTAR_NUM]; +#if CYGHWR_DEVS_SPI_FREESCALE_DSPI_CTAR_NUM < 8 + cyg_uint32 reserved_1[8-CYGHWR_DEVS_SPI_FREESCALE_DSPI_CTAR_NUM]; +#endif + cyg_uint32 sr; // Status Register + cyg_uint32 rser; // DMA/IRQ Request Select and Enable Register + cyg_uint32 pushr; // TX FIFO PUSH Register + cyg_uint32 popr; // RX FIFO POP Register + // Transmit FIFO Registers + cyg_uint32 txfr[CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE]; +#if CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE < 16 + cyg_uint32 reserved_2[16-CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE]; +#endif + // Receive FIFO Registers + cyg_uint32 rxfr[CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE]; +#if CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE < 16 + cyg_uint32 reserved_3[16-CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE]; +#endif +} cyghwr_devs_freescale_dspi_t; + +// MCR Bit Fields +#define FREESCALE_DSPI_MCR_HALT_M 0x1 +#define FREESCALE_DSPI_MCR_HALT_S 0 +#define FREESCALE_DSPI_MCR_SMPL_PT_M 0x300 +#define FREESCALE_DSPI_MCR_SMPL_PT_S 8 +#define FREESCALE_DSPI_MCR_SMPL_PT(__val) \ + VALUE_(FREESCALE_DSPI_MCR_SMPL_PT_S, __val) +#define FREESCALE_DSPI_MCR_CLR_RXF_M 0x400 +#define FREESCALE_DSPI_MCR_CLR_RXF_S 10 +#define FREESCALE_DSPI_MCR_CLR_TXF_M 0x800 +#define FREESCALE_DSPI_MCR_CLR_TXF_S 11 +#define FREESCALE_DSPI_MCR_DIS_RXF_M 0x1000 +#define FREESCALE_DSPI_MCR_DIS_RXF_S 12 +#define FREESCALE_DSPI_MCR_DIS_TXF_M 0x2000 +#define FREESCALE_DSPI_MCR_DIS_TXF_S 13 +#define FREESCALE_DSPI_MCR_MDIS_M 0x4000 +#define FREESCALE_DSPI_MCR_MDIS_S 14 +#define FREESCALE_DSPI_MCR_DOZE_M 0x8000 +#define FREESCALE_DSPI_MCR_DOZE_S 15 +#define FREESCALE_DSPI_MCR_PCSIS_M 0x3F0000 +#define FREESCALE_DSPI_MCR_PCSIS_S 16 +#define FREESCALE_DSPI_MCR_PCSIS(__val) \ + VALUE_(FREESCALE_DSPI_MCR_PCSIS_S, __val) +#define FREESCALE_DSPI_MCR_ROOE_M 0x1000000 +#define FREESCALE_DSPI_MCR_ROOE_S 24 +#define FREESCALE_DSPI_MCR_PCSSE_M 0x2000000 +#define FREESCALE_DSPI_MCR_PCSSE_S 25 +#define FREESCALE_DSPI_MCR_MTFE_M 0x4000000 +#define FREESCALE_DSPI_MCR_MTFE_S 26 +#define FREESCALE_DSPI_MCR_FRZ_M 0x8000000 +#define FREESCALE_DSPI_MCR_FRZ_S 27 +#define FREESCALE_DSPI_MCR_DCONF_M 0x30000000 +#define FREESCALE_DSPI_MCR_DCONF_S 28 +#define FREESCALE_DSPI_MCR_DCONF(__val) \ + VALUE_(FREESCALE_DSPI_MCR_DCONF_S, __val) +#define FREESCALE_DSPI_MCR_CONT_SCKE_M 0x40000000 +#define FREESCALE_DSPI_MCR_CONT_SCKE_S 30 +#define FREESCALE_DSPI_MCR_MSTR_M 0x80000000 +#define FREESCALE_DSPI_MCR_MSTR_S 31 +// TCR Bit Fields +#define FREESCALE_DSPI_TCR_DSPI_TCNT_M 0xFFFF0000 +#define FREESCALE_DSPI_TCR_DSPI_TCNT_S 16 +#define FREESCALE_DSPI_TCR_DSPI_TCNT(__val) \ + VALUE_(FREESCALE_DSPI_TCR_DSPI_TCNT_S, __val) +// CTAR Bit Fields +#define FREESCALE_DSPI_CTAR_BR_M 0xF +#define FREESCALE_DSPI_CTAR_BR_S 0 +#define FREESCALE_DSPI_CTAR_BR(__val) \ + VALUE_(FREESCALE_DSPI_CTAR_BR_S, __val) +#define FREESCALE_DSPI_CTAR_DT_M 0xF0 +#define FREESCALE_DSPI_CTAR_DT_S 4 +#define FREESCALE_DSPI_CTAR_DT(__val) \ + VALUE_(FREESCALE_DSPI_CTAR_DT_S, __val) +#define FREESCALE_DSPI_CTAR_ASC_M 0xF00 +#define FREESCALE_DSPI_CTAR_ASC_S 8 +#define FREESCALE_DSPI_CTAR_ASC(__val) \ + VALUE_(FREESCALE_DSPI_CTAR_ASC_S, __val) +#define FREESCALE_DSPI_CTAR_CSSCK_M 0xF000 +#define FREESCALE_DSPI_CTAR_CSSCK_S 12 +#define FREESCALE_DSPI_CTAR_CSSCK(__val) \ + VALUE_(FREESCALE_DSPI_CTAR_CSSCK_S, __val) +#define FREESCALE_DSPI_CTAR_PBR_M 0x30000 +#define FREESCALE_DSPI_CTAR_PBR_S 16 +#define FREESCALE_DSPI_CTAR_PBR(__val) \ + VALUE_(FREESCALE_DSPI_CTAR_PBR_S, __val) +#define FREESCALE_DSPI_CTAR_PDT_M 0xC0000 +#define FREESCALE_DSPI_CTAR_PDT_S 18 +#define FREESCALE_DSPI_CTAR_PDT(__val) \ + VALUE_(FREESCALE_DSPI_CTAR_PDT_S, __val) +#define FREESCALE_DSPI_CTAR_PASC_M 0x300000 +#define FREESCALE_DSPI_CTAR_PASC_S 20 +#define FREESCALE_DSPI_CTAR_PASC(__val) \ + VALUE_(FREESCALE_DSPI_CTAR_PASC_S, __val) +#define FREESCALE_DSPI_CTAR_PCSSCK_S 22 +#define FREESCALE_DSPI_CTAR_PCSSCK(__val) \ + VALUE_(FREESCALE_DSPI_CTAR_PCSSCK_S, __val) +#define FREESCALE_DSPI_CTAR_LSBFE_S 24 +#define FREESCALE_DSPI_CTAR_LSBFE_M 0x1000000 + +#define FREESCALE_DSPI_CTAR_FMSZ_M 0x78000000 +#define FREESCALE_DSPI_CTAR_FMSZ_S 27 +#define FREESCALE_DSPI_CTAR_FMSZ(__val) \ + VALUE_(FREESCALE_DSPI_CTAR_FMSZ_S, __val) +#define FREESCALE_DSPI_CTAR_DBR_M 0x80000000 +#define FREESCALE_DSPI_CTAR_DBR_S 31 +// CTAR_SLAVE Bit Fields +#define FREESCALE_DSPI_CTAR_SLAVE_CPHA_M 0x2000000 +#define FREESCALE_DSPI_CTAR_SLAVE_CPHA_S 25 +#define FREESCALE_DSPI_CTAR_SLAVE_CPOL_M 0x4000000 +#define FREESCALE_DSPI_CTAR_SLAVE_CPOL_S 26 +#define FREESCALE_DSPI_CTAR_SLAVE_FMSZ_M 0xF8000000 +#define FREESCALE_DSPI_CTAR_SLAVE_FMSZ_S 27 +#define FREESCALE_DSPI_CTAR_SLAVE_FMSZ(__val) \ + VALUE_(FREESCALE_DSPI_CTAR_SLAVE_FMSZ_S, __val) +// SR Bit Fields +#define FREESCALE_DSPI_SR_POPNXTPTR_M 0xF +#define FREESCALE_DSPI_SR_POPNXTPTR_S 0 +#define FREESCALE_DSPI_SR_POPNXTPTR(__val) \ + VALUE_(FREESCALE_DSPI_SR_POPNXTPTR_S, __val) +#define FREESCALE_DSPI_SR_RXCTR_M 0xF0 +#define FREESCALE_DSPI_SR_RXCTR_S 4 +#define FREESCALE_DSPI_SR_RXCTR(__val) \ + VALUE_(FREESCALE_DSPI_SR_RXCTR_S, __val) +#define FREESCALE_DSPI_SR_TXNXTPTR_M 0xF00 +#define FREESCALE_DSPI_SR_TXNXTPTR_S 8 +#define FREESCALE_DSPI_SR_TXNXTPTR(__val) \ + VALUE_(FREESCALE_DSPI_SR_TXNXTPTR_S, __val) +#define FREESCALE_DSPI_SR_TXCTR_M 0xF000 +#define FREESCALE_DSPI_SR_TXCTR_S 12 +#define FREESCALE_DSPI_SR_TXCTR(__val) \ + VALUE_(FREESCALE_DSPI_SR_TXCTR_S, __val) +#define FREESCALE_DSPI_SR_RFDF_M 0x20000 +#define FREESCALE_DSPI_SR_RFDF_S 17 +#define FREESCALE_DSPI_SR_RFOF_M 0x80000 +#define FREESCALE_DSPI_SR_RFOF_S 19 +#define FREESCALE_DSPI_SR_TFFF_M 0x2000000 +#define FREESCALE_DSPI_SR_TFFF_S 25 +#define FREESCALE_DSPI_SR_TFUF_M 0x8000000 +#define FREESCALE_DSPI_SR_TFUF_S 27 +#define FREESCALE_DSPI_SR_EOQF_M 0x10000000 +#define FREESCALE_DSPI_SR_EOQF_S 28 +#define FREESCALE_DSPI_SR_TXRXS_M 0x40000000 +#define FREESCALE_DSPI_SR_TXRXS_S 30 +#define FREESCALE_DSPI_SR_TCF_M 0x80000000 +#define FREESCALE_DSPI_SR_TCF_S 31 + +#define FREESCALE_DSPI_CLEAR_FIFOS (FREESCALE_DSPI_SR_TFUF_M |\ + FREESCALE_DSPI_SR_RFOF_M) + +// RSER Bit Fields +#define FREESCALE_DSPI_RSER_RFDF_DIRS_M 0x10000 +#define FREESCALE_DSPI_RSER_RFDF_DIRS_S 16 +#define FREESCALE_DSPI_RSER_RFDF_RE_M 0x20000 +#define FREESCALE_DSPI_RSER_RFDF_RE_S 17 +#define FREESCALE_DSPI_RSER_RFOF_RE_M 0x80000 +#define FREESCALE_DSPI_RSER_RFOF_RE_S 19 +#define FREESCALE_DSPI_RSER_TFFF_DIRS_M 0x1000000 +#define FREESCALE_DSPI_RSER_TFFF_DIRS_S 24 +#define FREESCALE_DSPI_RSER_TFFF_RE_M 0x2000000 +#define FREESCALE_DSPI_RSER_TFFF_RE_S 25 +#define FREESCALE_DSPI_RSER_TFUF_RE_M 0x8000000 +#define FREESCALE_DSPI_RSER_TFUF_RE_S 27 +#define FREESCALE_DSPI_RSER_EOQF_RE_M 0x10000000 +#define FREESCALE_DSPI_RSER_EOQF_RE_S 28 +#define FREESCALE_DSPI_RSER_TCF_RE_M 0x80000000 +#define FREESCALE_DSPI_RSER_TCF_RE_S 31 +// PUSHR Bit Fields +#define FREESCALE_DSPI_PUSHR_TXDATA_M 0xFFFF +#define FREESCALE_DSPI_PUSHR_TXDATA_S 0 +#define FREESCALE_DSPI_PUSHR_TXDATA(__val) \ + VALUE_(FREESCALE_DSPI_PUSHR_TXDATA_S, __val) +#define FREESCALE_DSPI_PUSHR_PCS_M 0x3F0000 +#define FREESCALE_DSPI_PUSHR_PCS_S 16 +#define FREESCALE_DSPI_PUSHR_PCS(__val) VALUE_(FREESCALE_DSPI_PUSHR_PCS_S, __val) +#define FREESCALE_DSPI_PUSHR_CTCNT_M 0x4000000 +#define FREESCALE_DSPI_PUSHR_CTCNT_S 26 +#define FREESCALE_DSPI_PUSHR_EOQ_M 0x8000000 +#define FREESCALE_DSPI_PUSHR_EOQ_S 27 +#define FREESCALE_DSPI_PUSHR_CTAS_M 0x70000000 +#define FREESCALE_DSPI_PUSHR_CTAS_S 28 +#define FREESCALE_DSPI_PUSHR_CTAS(__val) \ + VALUE_(FREESCALE_DSPI_PUSHR_CTAS_S, __val) +#define FREESCALE_DSPI_PUSHR_CONT_M 0x80000000 +#define FREESCALE_DSPI_PUSHR_CONT_S 31 +// PUSHR_SLAVE Bit Fields +#define FREESCALE_DSPI_PUSHR_SLAVE_TXDATA_M 0xFFFFFFFF +#define FREESCALE_DSPI_PUSHR_SLAVE_TXDATA_S 0 +#define FREESCALE_DSPI_PUSHR_SLAVE_TXDATA(__val) \ +VALUE_(FREESCALE_DSPI_PUSHR_SLAVE_TXDATA_S, __val) + +#define FREESCALE_DSPI_PUSHR_PCS_CLEAR(__val)\ +CYG_MACRO_START\ + __val &= ~FREESCALE_DSPI_PUSHR_PCS_M; \ +CYG_MACRO_END + +// POPR Bit Fields +#define FREESCALE_DSPI_POPR_RXDATA_M 0xFFFFFFFF +#define FREESCALE_DSPI_POPR_RXDATA_S 0 +#define FREESCALE_DSPI_POPR_RXDATA(__val) \ + VALUE_(FREESCALE_DSPI_POPR_RXDATA_S, __val) +// TXFR Bit Fields +#define FREESCALE_DSPI_TXFR_TXDATA_M 0xFFFF +#define FREESCALE_DSPI_TXFR_TXDATA_S 0 +#define FREESCALE_DSPI_TXFR_TXCMD_TXDATA_M 0xFFFF0000 +#define FREESCALE_DSPI_TXFR_TXCMD_TXDATA_S 16 +#define FREESCALE_DSPI_TXFR_TXCMD_TXDATA(__fr,__val) \ + VALUE_(FREESCALE_DSPI_TXFR##__fr##_TXCMD_TXDATA_S, __val) +// RXFR Bit Fields +#define FREESCALE_DSPI_RXFR_RXDATA_M 0xFFFFFFFF +#define FREESCALE_DSPI_RXFR_RXDATA_S 0 +#define FREESCALE_DSPI_RXFR_RXDATA(__fr,__val) \ + VALUE_(FREESCALE_DSPI_RXFR##_fr##_RXDATA_S, __val) + +// Borrow following macros from HAL + +// CYGADDR_IO_SPI_FREESCALE_DSPI0_P +// CYGADDR_IO_SPI_FREESCALE_DSPI1_P +// CYGADDR_IO_SPI_FREESCALE_DSPI2_P + +// CYGHWR_IO_FREESCALE_DSPI_PIN(__pin) + +// CYGHWR_IO_FREESCALE_SPIx_PIN_SIN +// CYGHWR_IO_FREESCALE_SPIx_PIN_SOUT +// CYGHWR_IO_FREESCALE_SPIx_PIN_SCK + +// CYGHWR_IO_FREESCALE_SPIx_PIN_CSn + +//============================================================================= +#endif // CYGONCE_DEVS_SPI_FREESCALE_DSPI_IO_H diff --git a/packages/devs/spi/freescale/dspi/current/src/spi_freescale_dspi.c b/packages/devs/spi/freescale/dspi/current/src/spi_freescale_dspi.c new file mode 100644 --- /dev/null +++ b/packages/devs/spi/freescale/dspi/current/src/spi_freescale_dspi.c @@ -0,0 +1,1129 @@ +//============================================================================= +// +// spi_freescale_dspi.c +// +// SPI driver implementation for Freescale DSPI +// +//============================================================================= +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later +// version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License +// along with eCos; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// As a special exception, if other files instantiate templates or use +// macros or inline functions from this file, or you compile this file +// and link it with other works to produce a work based on this file, +// this file does not by itself cause the resulting work to be covered by +// the GNU General Public License. However the source code for this file +// must still be made available in accordance with section (3) of the GNU +// General Public License v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//============================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): ilijak +// Date: 2011-11-04 +// Purpose: Freescale DSPI SPI driver implementation +// +//####DESCRIPTIONEND#### +// +//============================================================================= + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#if defined(CYGHWR_DEVS_SPI_FREESCALE_DSPI0) || \ + defined(CYGHWR_DEVS_SPI_FREESCALE_DSPI1) || \ + defined(CYGHWR_DEVS_SPI_FREESCALE_DSPI2) + +#include + + +#define DEBUG_SPI CYGPKG_DEVS_SPI_FREESCALE_DSPI_DEBUG_LEVEL + +#if DEBUG_SPI >= 3 +# define DEBUG3_PRINTF(args...) diag_printf(args) +#else +# define DEBUG3_PRINTF(args...) +#endif + +#if DEBUG_SPI >= 2 +# define DEBUG2_PRINTF(args...) diag_printf(args) +#else +# define DEBUG2_PRINTF(args...) +#endif + +#if DEBUG_SPI >= 1 +# define DEBUG1_PRINTF(args...) diag_printf(args) +#else +# define DEBUG1_PRINTF(args...) +#endif + +# define DEBUG0_PRINTF(args...) diag_printf(args) + + +//----------------------------------------------------------------------------- +// API function call forward references. + +static void dspi_transaction_begin (cyg_spi_device*); +static void dspi_transaction_transfer (cyg_spi_device*, cyg_bool, cyg_uint32, + const cyg_uint8*, cyg_uint8*, cyg_bool); +static void dspi_transaction_tick (cyg_spi_device*, cyg_bool, cyg_uint32); +static void dspi_transaction_end (cyg_spi_device*); +static int dspi_get_config (cyg_spi_device*, cyg_uint32, + void*, cyg_uint32*); +static int dspi_set_config (cyg_spi_device*, cyg_uint32, + const void*, cyg_uint32*); + +//----------------------------------------------------------------------------- +// Instantiate the bus state data structures. + +#include + +// Some hardware manipulation inline functions and macros + +static inline void dspi_disable(cyghwr_devs_freescale_dspi_t* dspi_p) +{ + dspi_p->mcr |= FREESCALE_DSPI_MCR_MDIS_M; +} + +static inline void dspi_enable(cyghwr_devs_freescale_dspi_t* dspi_p) +{ + dspi_p->mcr &= ~FREESCALE_DSPI_MCR_MDIS_M; +} + +static inline void dspi_halt(cyghwr_devs_freescale_dspi_t* dspi_p) +{ + dspi_p->mcr |= FREESCALE_DSPI_MCR_HALT_M; +} + +static inline void dspi_tlah(cyghwr_devs_freescale_dspi_t* dspi_p) +{ + dspi_p->mcr &= ~FREESCALE_DSPI_MCR_HALT_M; +} + +static inline void +dspi_irq_enable(cyghwr_devs_freescale_dspi_t* dspi_p, cyg_uint32 irq_mask) +{ + dspi_p->rser |= irq_mask; +} + +static inline void +dspi_irq_disable(cyghwr_devs_freescale_dspi_t* dspi_p, cyg_uint32 irq_mask) +{ + dspi_p->rser &= ~irq_mask; +} + +static inline void +dspi_status_clear(cyghwr_devs_freescale_dspi_t* dspi_p, cyg_uint32 sr_mask) +{ + dspi_p->sr |= sr_mask; +} + +static inline void +dspi_fifo_clear(cyghwr_devs_freescale_dspi_t* dspi_p) +{ + dspi_p->mcr |= FREESCALE_DSPI_MCR_CLR_RXF_M | FREESCALE_DSPI_MCR_CLR_TXF_M; +} + +static inline void +dspi_fifo_drain(cyghwr_devs_freescale_dspi_t* dspi_p) +{ + dspi_p->sr |= FREESCALE_DSPI_SR_RFDF_M; +} + + +#define DSPI_IRQ_ENABLE(__dspi_p) \ + dspi_irq_enable(__dspi_p, FREESCALE_DSPI_RSER_EOQF_RE_M) +#define DSPI_IRQ_DISABLE(__dspi_p) \ + dspi_irq_disable(__dspi_p, FREESCALE_DSPI_RSER_EOQF_RE_M) +#define DSPI_EOQ_CLEAR(__dspi_p) \ + dspi_status_clear(__dspi_p, FREESCALE_DSPI_SR_EOQF_M | \ + FREESCALE_DSPI_SR_TCF_M | \ + FREESCALE_DSPI_SR_RFDF_M) +#define DSPI_TXRX_ENABLE(__dspi_p) \ + dspi_status_clear(__dspi_p, FREESCALE_DSPI_SR_TXRXS_M) + +// Alternate clocking for spi_transaction_end() +// Used to initialize CTAR1. +static const cyg_freescale_dspi_clocking_t aux_clocking = +{ + .frame_size = 4, + .cl_pol = 0, + .cl_pha = 0, + .cl_brate = CYGHWR_DEVS_FREESCALEDSPI_DSPI_CTAR1_AUX_SPEED, + .cs_up_udly = CYGHWR_DEVS_FREESCALEDSPI_DSPI_CTAR1_AUX_CS_DELAY, + .cs_dw_udly = CYGHWR_DEVS_FREESCALEDSPI_DSPI_CTAR1_AUX_CS_DELAY, + .tr_bt_udly =CYGHWR_DEVS_FREESCALEDSPI_DSPI_CTAR1_AUX_CS_DELAY, + .dl_unit = CYGNUM_DSPI_DELAY_UNIT( + CYGHWR_DEVS_FREESCALE_DSPI_DSPI_CTAR1_AUX_DELAY_UNIT), + .cl_dbr = CYGHWR_DEVS_FREESCALEDSPI_DSPI_CTAR1_AUX_USE_DBR +}; + +//----------------------------------------------------------------------------- +// Implement DSPI ISRs. + +// ISR for DSPI with DMA +// Disable DSPI IRQ and Tx DMA channel and schedule DSR. +static cyg_uint32 dspi_dma_ISR(cyg_vector_t vector, cyg_addrword_t data) +{ + cyg_spi_freescale_dspi_bus_t* dspi_bus_p = + (cyg_spi_freescale_dspi_bus_t*) data; + cyghwr_devs_freescale_dspi_t* dspi_p = dspi_bus_p->setup_p->dspi_p; + cyghwr_hal_freescale_dma_set_t *dma_set_p = dspi_bus_p->setup_p->dma_set_p; + cyghwr_hal_freescale_edma_t *edma_p; + edma_p = dma_set_p->edma_p; + + cyg_drv_isr_lock(); + + // Disable the Tx DMA channel and DSPI IRQ. + hal_freescale_edma_erq_disable(edma_p, SPI_DMA_CHAN_I(dma_set_p, TX)); + DSPI_IRQ_DISABLE(dspi_p); + + cyg_drv_interrupt_acknowledge(vector); + cyg_drv_isr_unlock(); + return (CYG_ISR_CALL_DSR | CYG_ISR_HANDLED); +} + +// ISR for DSPI without DMA +// Disable DSPI IRQ and schedule DSR. +static cyg_uint32 dspi_nodma_ISR(cyg_vector_t vector, cyg_addrword_t data) +{ + cyg_spi_freescale_dspi_bus_t* dspi_bus_p = + (cyg_spi_freescale_dspi_bus_t*) data; + cyghwr_devs_freescale_dspi_t* dspi_p = dspi_bus_p->setup_p->dspi_p; + + cyg_drv_isr_lock(); + + // Disable the DSPI IRQ. + DSPI_IRQ_DISABLE(dspi_p); + + cyg_drv_interrupt_acknowledge(vector); + cyg_drv_isr_unlock(); + return (CYG_ISR_CALL_DSR | CYG_ISR_HANDLED); +} + +// DSPI DSR +static void dspi_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + cyg_spi_freescale_dspi_bus_t* dspi_bus = (cyg_spi_freescale_dspi_bus_t*) data; + + cyg_drv_dsr_lock(); + cyg_drv_cond_signal(&dspi_bus->transfer_done); + cyg_drv_dsr_unlock(); +} + +//----------------------------------------------------------------------------- +// Calculate best fit CTAR baud rate setting (using some brute force). +// Best fit is considered the highest frequency that is not highe than set point. + +static const cyg_uint16 ctar_br[16] = { 2/2, 4/2, 6/2, 8/2, 16/2, 32/2, 64/2, + 128/2, 256/2, 512/2, 1024/2, 2048/2, 4096/2, 8192/2, 16384/2, 32768/2 }; +static const cyg_uint8 ctar_pbr[4] = { 2, 3, 5, 7 }; + +static const cyg_uint16 ctar_cssck[16] = { 2/2, 4/2, 8/2, 16/2, 32/2, 64/2, + 128/2, 256/2, 512/2, 1024/2, 2048/2, 4096/2, 8192/2, 16384/2, 32768/2, + 65536/2 }; +static const cyg_uint8 ctar_pcssck[4] = { 1, 3, 5, 7 }; + +typedef struct ctar_br_s { + cyg_uint8 valid; + cyg_uint8 br; + cyg_uint8 dbr; + cyg_uint8 pbr; +} ctar_br_t; + +static int dspi_ctar_brbf (const cyg_freescale_dspi_clocking_t* spi_cocking, + ctar_br_t* brs_p, const cyg_uint16* br_p, + const cyg_uint8* pbr_p, cyg_uint32* alt_brate, + cyg_uint32 sys_clk) +{ + cyg_uint32 pbr_i; + cyg_uint32 br_i; + cyg_uint32 dbr; + cyg_uint32 clk; + cyg_uint32 baud_bf = 0; // Best fit + cyg_uint32 baud_tmp; + cyg_uint32 baud_sp = alt_brate ? *alt_brate : + spi_cocking->cl_brate; // Set point + + // Calculate the maximal viable bus speed. + clk = sys_clk; + // Desired baud rate very high, use DBR if allowed + dbr = (baud_sp > (clk / 4)) && spi_cocking->cl_dbr && (br_p == ctar_br); + + for(pbr_i = 0; pbr_i < 3; pbr_i++) { + for(br_i = 0; br_i < 15; br_i++) { + if((baud_tmp = (clk * (1+dbr)) / (pbr_p[pbr_i] * (2*br_p[br_i]))) + <= baud_sp) + { + if(baud_tmp > baud_bf) { + DEBUG3_PRINTF("DSPI Baud:" + " SP=%d pbr=0x%x br=0x%x dbr=%d Temp=%d (SysClk=%d)\n", + baud_sp, pbr_i, br_i, dbr, baud_tmp, clk); + brs_p->br = br_i; + brs_p->pbr = pbr_i; + brs_p->valid = 1; + baud_bf = baud_tmp; + if(baud_tmp == baud_sp) + goto baud_found; + } + } + } + } + if(!brs_p->valid) { + pbr_i = 3; + br_i = 15; + DEBUG1_PRINTF("DSPI Baud too low:" + " SP=%d pbr=0x%x br=0x%x Actual=%d (SysClk=%d)\n", + baud_sp, pbr_i, br_i, + (clk * (1+dbr)) / (pbr_p[pbr_i] * (2*br_p[br_i])), clk); + brs_p->br = br_i; + brs_p->pbr = pbr_i; + + return -1; + } else { +baud_found: + brs_p->dbr = dbr; + DEBUG1_PRINTF("DSPI Baud found:" + " SP=%d pbr=0x%x br=0x%x dbr=%d Actual=%dHz (%dns) (SysClk=%d)\n", + baud_sp, brs_p->pbr, brs_p->br, dbr, baud_bf, 1000000000/baud_bf, clk); + + return 0; + } +} + +// Set Clock and Transfer Attributes Register +#define CYG_ASSERT_LOW_FREQ \ + CYG_ASSERT (false, "Freescale DSPI: Cannot run bus as slowly as requested.") +cyg_uint32 +dspi_calc_ctar(const cyg_freescale_dspi_clocking_t* spi_clocking, cyg_uint32 sys_clk) +{ + cyg_uint32 regval; + ctar_br_t brs; + cyg_uint32 delay_brate; + + regval = FREESCALE_DSPI_CTAR_FMSZ(spi_clocking->frame_size - 1); + if(spi_clocking->cl_pol) + regval |= FREESCALE_DSPI_CTAR_SLAVE_CPOL_M; + if(spi_clocking->cl_pha) + regval |= FREESCALE_DSPI_CTAR_SLAVE_CPHA_M; + if(spi_clocking->lsb_first) + regval |= FREESCALE_DSPI_CTAR_LSBFE_M; + + // Get divider bits + // Baud rate + brs.dbr = 0; + if (!dspi_ctar_brbf(spi_clocking, &brs, ctar_br, ctar_pbr, NULL, sys_clk)) + { + regval |= FREESCALE_DSPI_CTAR_BR(brs.br) | + FREESCALE_DSPI_CTAR_PBR(brs.pbr) | + (brs.dbr ? FREESCALE_DSPI_CTAR_DBR_M : 0); + } else + CYG_ASSERT_LOW_FREQ; + + delay_brate = 100000000 / (spi_clocking->dl_unit * spi_clocking->cs_up_udly); + if (!dspi_ctar_brbf(spi_clocking, &brs, ctar_cssck, ctar_pcssck, + &delay_brate, sys_clk)) + { + regval |= FREESCALE_DSPI_CTAR_CSSCK(brs.br) | + FREESCALE_DSPI_CTAR_PCSSCK(brs.pbr); + } else + CYG_ASSERT_LOW_FREQ; + + // Delay between clock and CS negation + delay_brate = 100000000 / (spi_clocking->dl_unit * spi_clocking->cs_dw_udly); + if (!dspi_ctar_brbf(spi_clocking, &brs, ctar_cssck, ctar_pcssck, + &delay_brate, sys_clk)) + { + regval |= FREESCALE_DSPI_CTAR_ASC(brs.br) | + FREESCALE_DSPI_CTAR_PASC(brs.pbr); + } else + CYG_ASSERT_LOW_FREQ; + + // Delay between clock and CS negation and assertion + delay_brate = 100000000 / (spi_clocking->dl_unit * spi_clocking->tr_bt_udly); + if (!dspi_ctar_brbf(spi_clocking, &brs, ctar_cssck, ctar_pcssck, + &delay_brate, sys_clk)) + { + regval |= FREESCALE_DSPI_CTAR_DT(brs.br) | + FREESCALE_DSPI_CTAR_PDT(brs.pbr); + } else + CYG_ASSERT_LOW_FREQ; + return regval; +} + +//---------------------------------------------------------------------------- +//Set up SPI bus pins + +static void dspi_pin_setup(const cyg_uint32* spi_pins_p, + const cyg_uint32* cs_pins_p, cyg_uint32 cs_pin_n) +{ + const cyg_uint32* pin_p; + + for(pin_p = spi_pins_p; + pin_p < spi_pins_p + 3; + CYGHWR_IO_FREESCALE_DSPI_PIN(*pin_p++)); + + for(pin_p = cs_pins_p; + pin_p < cs_pins_p + cs_pin_n; + CYGHWR_IO_FREESCALE_DSPI_PIN(*pin_p++)); +} + +//----------------------------------------------------------------------------- +// Set up a new SPI bus on initialisation. + +static void dspi_bus_setup(cyg_spi_freescale_dspi_bus_t* spi_bus_p) +{ + cyghwr_devs_freescale_dspi_t* dspi_p = spi_bus_p->setup_p->dspi_p; + cyghwr_hal_freescale_dma_set_t* dma_set_p; + cyghwr_hal_freescale_edma_t* edma_p; + cyg_uint32 dma_chan_i; + + // Get the clock frequency from HAL. + spi_bus_p->clock_freq = CYGHWR_IO_SPI_FREESCALE_DSPI_CLOCK; + DEBUG1_PRINTF("DSPI BUS %p: SysClk=%d\n", spi_bus_p, spi_bus_p->clock_freq); + + // Set up the pins. + dspi_pin_setup(spi_bus_p->setup_p->spi_pin_list_p, + spi_bus_p->setup_p->cs_pin_list_p, + spi_bus_p->setup_p->cs_pin_num); + + // Set up default SPI configuration. + dspi_p->mcr = spi_bus_p->setup_p->mcr_opt | FREESCALE_DSPI_MCR_MSTR_M | + FREESCALE_DSPI_MCR_CLR_RXF_M | FREESCALE_DSPI_MCR_CLR_TXF_M | + FREESCALE_DSPI_MCR_MDIS_M; + + // Enable DSPI controller. + dspi_enable(dspi_p); + + if((dma_set_p=spi_bus_p->setup_p->dma_set_p)) { + // Initialize DMA channels + hal_freescale_edma_init_chanset(dma_set_p); +#if DEBUG_SPI >= 1 + hal_freescale_edma_diag(dma_set_p, 0xffff); + cyghwr_devs_freescale_dspi_diag(spi_bus_p); +#endif + // Set up DMA transfer control descriptors + edma_p = dma_set_p->edma_p; + dma_chan_i = dma_set_p->chan_p[SPI_DMA_CHAN_TX_I].dma_chan_i; + hal_freescale_edma_transfer_init(edma_p, dma_chan_i, + spi_bus_p->tx_dma_tcd_ini_p); +#if DEBUG_SPI >= 1 + hal_freescale_edma_transfer_diag(edma_p, dma_chan_i, true); +#endif + dma_chan_i = dma_set_p->chan_p[SPI_DMA_CHAN_RX_I].dma_chan_i; + hal_freescale_edma_transfer_init(edma_p, dma_chan_i, + spi_bus_p->rx_dma_tcd_ini_p); +#if DEBUG_SPI >= 1 + hal_freescale_edma_transfer_diag(edma_p, dma_chan_i, true); +#endif + // Enable SPI DMA requests + dspi_p->rser = FREESCALE_DSPI_RSER_TFFF_DIRS_M | + FREESCALE_DSPI_RSER_RFDF_DIRS_M | + FREESCALE_DSPI_RSER_TFFF_RE_M | + FREESCALE_DSPI_RSER_RFDF_RE_M; + } +#if DEBUG_SPI >= 1 + cyghwr_devs_freescale_dspi_diag(spi_bus_p); +#endif + // Initialise the synchronisation primitivies. + cyg_drv_mutex_init (&spi_bus_p->transfer_mutex); + cyg_drv_cond_init (&spi_bus_p->transfer_done, &spi_bus_p->transfer_mutex); + + // Hook up the ISR and DSR. + cyg_drv_interrupt_create (spi_bus_p->setup_p->intr_num, + spi_bus_p->setup_p->intr_prio, + (cyg_addrword_t) spi_bus_p, + dma_set_p ? dspi_dma_ISR : dspi_nodma_ISR, + dspi_DSR, &spi_bus_p->intr_handle, + &spi_bus_p->intr_data); + cyg_drv_interrupt_attach (spi_bus_p->intr_handle); + + dspi_p->ctar[1] = dspi_calc_ctar(&aux_clocking, spi_bus_p->clock_freq); + + // Call upper layer bus init. + CYG_SPI_BUS_COMMON_INIT(&spi_bus_p->spi_bus); +} + +//----------------------------------------------------------------------------- +// Set up Rx DMA channel +static void +rx_dma_channel_setup(cyghwr_hal_freescale_dma_set_t *dma_set_p, + cyg_uint8* data_buf, cyg_uint32 bus_16bit, + volatile cyghwr_hal_freescale_edma_tcd_t *tcd_p) +{ + cyg_uint32 step, sdsize; + static cyg_uint8 popr_sink; + + // Set the correct transfer size. + if(bus_16bit) { + step = 2; + sdsize = FREESCALE_EDMA_ATTR_SIZE_16; + } else { + step = 1; + sdsize = FREESCALE_EDMA_ATTR_SIZE_8; + } + if(data_buf) { + tcd_p->doff = step; + tcd_p->daddr = data_buf; + } else { + tcd_p->doff = 0; + tcd_p->daddr = &popr_sink; + } + tcd_p->nbytes.mlno = step; + tcd_p->attr = FREESCALE_EDMA_ATTR_SSIZE(sdsize) | + FREESCALE_EDMA_ATTR_DSIZE(sdsize) | + FREESCALE_EDMA_ATTR_SMOD(0) | + FREESCALE_EDMA_ATTR_DMOD(0); +#if DEBUG_SPI >= 3 + hal_freescale_edma_tcd_diag(tcd_p, -1, "[DSPI Rx]"); +#endif +} + +//---------------------------------------------------------------------------- +// Set up Tx FIFO queue +// Set up Tx FIFO command queue +// DSPI requires sending command for every transfer. +// Used for transfers that fit within DSPI FIFO. + +#if DEBUG_SPI >= 2 +static const char debug_format[] = "BUFF %dbit %s: %p 0x%08x remain %d:\n"; +#endif + +static inline volatile cyg_uint32 +fifo_pushque_fill(cyg_spi_freescale_dspi_bus_t* dspi_bus, cyg_uint8* + data_p, cyg_uint32 count, cyg_bool bus_16bit, cyg_uint32 pushr, + cyg_bool drop_cs) +{ + cyghwr_devs_freescale_dspi_t* dspi_p = dspi_bus->setup_p->dspi_p; + cyg_uint32 txfifo_n = dspi_bus->txfifo_n; + + if(data_p) { + if(!bus_16bit) { + for(; count > 1; count--) { + if(!(--txfifo_n)) { + dspi_p->pushr = pushr |= *data_p | FREESCALE_DSPI_PUSHR_EOQ_M; + count--; + DEBUG2_PRINTF(debug_format, 8, "FBK", &dspi_p->pushr, + pushr | *data_p, count); + return count; + } + dspi_p->pushr = pushr | *data_p++; + DEBUG3_PRINTF(debug_format, 8, "FAD", &dspi_p->pushr, + pushr | data_p[-1], count-1); + } + pushr |= *data_p; + } else { + cyg_uint16* data16_p = (cyg_uint16 *)data_p; + cyg_uint16 data_word; + + for(; count > 2; count-=2) { + if(!(--txfifo_n)) { + dspi_p->pushr = pushr |= *data16_p | FREESCALE_DSPI_PUSHR_EOQ_M; + count-=2; + DEBUG2_PRINTF(debug_format, 16, "FBK", &dspi_p->pushr, + pushr, count); + return count; + } + data_word = *data16_p++; + dspi_p->pushr = pushr | data_word; + DEBUG3_PRINTF(debug_format, 16, "FAD", &dspi_p->pushr, + pushr | data_word, (count-1)*2); + } + data_word = *data16_p; + pushr |= data_word; + } + } else { + for(; count > 1; count--) { + if(!(--txfifo_n)) { + dspi_p->pushr = pushr |= FREESCALE_DSPI_PUSHR_EOQ_M; + count--; + DEBUG2_PRINTF(debug_format, 0, "FBK", &dspi_p->pushr, + pushr, count); + return count; + } + dspi_p->pushr = pushr; + DEBUG3_PRINTF(debug_format, 0, "FAD", &dspi_p->pushr, pushr, + count-1); + } + } + if(drop_cs) + pushr &= ~FREESCALE_DSPI_PUSHR_CONT_M; + dspi_p->pushr = pushr |= FREESCALE_DSPI_PUSHR_EOQ_M; + DEBUG3_PRINTF(debug_format, data_p ? (bus_16bit ? 16 :8) : pushr, + (drop_cs ? "FEN" : "FSG"), &dspi_p->pushr, pushr, 0); + return 0; +} + +//---------------------------------------------------------------------------- +// Set up Tx +// Set up Tx DMA command queue +// DSPI requires sending command for every transfer. +// Used for transfers larger than DSPI FIFO + +static inline volatile cyg_uint32 +dma_pushque_fill(cyg_spi_freescale_dspi_bus_t* dspi_bus, cyg_uint8* data_p, + cyg_uint32 count, cyg_bool bus_16bit, cyg_uint32 pushr, + cyg_bool drop_cs) +{ + volatile cyg_uint32* pushque_p; + volatile cyg_uint32* pushque_end; + + pushque_p = dspi_bus->pushque_p; + pushque_end = pushque_p + dspi_bus->pushque_n; + pushque_p = dspi_bus->pushque_p; + if(data_p) { + if(!bus_16bit) { + do { + if(pushque_p == pushque_end) { + pushque_p[0] = pushr; + pushque_p[-1] |= FREESCALE_DSPI_PUSHR_EOQ_M; + DEBUG2_PRINTF(debug_format, 8, "BRK", pushque_p-1, + pushque_p[-1], count); + return count; + } + *pushque_p++ = pushr | *data_p++; + DEBUG3_PRINTF(debug_format, 8, "ADD", pushque_p-1, + pushque_p[-1], count-1); + } while(--count > 1); + pushr |= *data_p; + } else { + cyg_uint16* data16_p = (cyg_uint16 *)data_p; + cyg_uint16 data_word; + do { + if(pushque_p == pushque_end) { + pushque_p[0] = pushr; + pushque_p[-1] |= FREESCALE_DSPI_PUSHR_EOQ_M; + DEBUG2_PRINTF(debug_format, 16, "BRK", pushque_p-1, + pushque_p[-1], count); + return count; + } + data_word = *data16_p++; + *pushque_p++ = pushr | data_word; + DEBUG3_PRINTF(debug_format, 16, "ADD", pushque_p-1, + pushque_p[-1], count-2); + } while((count -= 2) > 2); + data_word = *data16_p; + pushr |= data_word; + } + } else { + do { + if(pushque_p == pushque_end) { + pushque_p[0] = pushr; + pushque_p[-1] |= FREESCALE_DSPI_PUSHR_EOQ_M; + DEBUG2_PRINTF(debug_format, 0, "BRK", pushque_p-1, + pushque_p[-1], count); + return count; + } + *pushque_p++ = pushr; + DEBUG3_PRINTF(debug_format, 0, "BRK", pushque_p-1, pushque_p[-1], + count-1); + } while(--count > 1); + } + if(drop_cs) pushr &= ~FREESCALE_DSPI_PUSHR_CONT_M; + pushque_p[1] = pushr; + *pushque_p = pushr |= FREESCALE_DSPI_PUSHR_EOQ_M; + DEBUG2_PRINTF(debug_format, data_p ? (bus_16bit ? 16 :8) : 0, + (drop_cs ? "END" : "SGM"), pushque_p, pushque_p[0], 0); + return 0; +} + +// Set up Tx DMA channel +// Used for transfers larger than DSPI FIFO + +static inline cyg_uint32 +tx_dma_channel_setup(cyg_spi_freescale_dspi_bus_t* dspi_bus, + cyg_uint8* data_buf, cyg_uint32 count, + cyg_bool bus_16bit, + cyg_uint32 pushr, cyg_bool drop_cs) +{ + cyghwr_hal_freescale_dma_set_t *dma_set_p = dspi_bus->setup_p->dma_set_p; + cyghwr_hal_freescale_edma_t *edma_p = dma_set_p->edma_p; + volatile cyghwr_hal_freescale_edma_tcd_t *tcd_p; + cyg_uint32 remain=0; + cyg_uint32 dma_chan_i; + + remain = dma_pushque_fill(dspi_bus, data_buf, count, bus_16bit, pushr, drop_cs); + dma_chan_i = SPI_DMA_CHAN_I(dma_set_p, TX); + tcd_p = &edma_p->tcd[dma_chan_i]; + tcd_p->saddr = dspi_bus->pushque_p; + DEBUG2_PRINTF("DSPI: Tx channel setup\n"); +#if DEBUG_SPI >= 3 + hal_freescale_edma_transfer_diag(edma_p, dma_chan_i, true); +#endif + return remain; +} + +//----------------------------------------------------------------------------- +// Set SPI peripheral chip select. + +static inline cyg_uint32 +dspi_chip_select_set(cyg_int32 cs_i, cyg_bool pccse, cyg_bool assert) +{ + cyg_uint32 spi_pushr; + + if(cs_i < 0) { + spi_pushr = 0; + } else { + if(pccse) { + spi_pushr = cs_i; + } else { + if(cs_i < 5) { + if(assert) { + cs_i = 1 << cs_i; + spi_pushr = FREESCALE_DSPI_PUSHR_PCS(cs_i); + } else + spi_pushr = 0; + } else { + CYG_ASSERT(1, "DSPI: Peripheral Chip Select out of range.\n"); + spi_pushr = 1 << 5; + } + } + } + return spi_pushr; +} + +//----------------------------------------------------------------------------- +// Execute SPI transaction. + +static void spi_transaction_do (cyg_spi_device* device, cyg_bool tick_only, + cyg_bool polled, cyg_uint32 count, + const cyg_uint8* tx_data, cyg_uint8* rx_data, + cyg_bool drop_cs) +{ + cyg_spi_freescale_dspi_bus_t* dspi_bus = + (cyg_spi_freescale_dspi_bus_t*) device->spi_bus; + cyg_spi_freescale_dspi_device_t* dspi_device = + (cyg_spi_freescale_dspi_device_t*) device; + cyg_bool bus_16bit = dspi_device->clocking.bus_16bit; + cyghwr_devs_freescale_dspi_t* dspi_p = dspi_bus->setup_p->dspi_p; + + cyghwr_hal_freescale_dma_set_t* dma_set_p; + cyghwr_hal_freescale_edma_t* edma_p = NULL; + + cyg_uint32 count_down; + cyg_uint32 txfifo_n = dspi_bus->txfifo_n; + cyg_uint32 pushr; + cyg_uint32 pushque_n; + cyg_uint32 dma_chan_rx_i = 0; + cyg_uint32 dma_chan_tx_i = 0; + +#if DEBUG_SPI >= 2 + cyg_uint32 first_turn = 1; +#endif + + DEBUG2_PRINTF("DSPI: transaction: count=%d drop_cs=%d\n", count, drop_cs); + + // Set up peripheral CS field. DSPI automatically asserts and deasserts CS + pushr = dspi_chip_select_set(tick_only ? -1 : dspi_device->dev_num, + dspi_p->mcr & FREESCALE_DSPI_MCR_PCSSE_M, true); + pushr |= FREESCALE_DSPI_PUSHR_CONT_M; + + dspi_fifo_clear(dspi_p); + dspi_fifo_drain(dspi_p); + + pushque_n = dspi_bus->pushque_n; + if(bus_16bit) + txfifo_n *= 2; + + if((dma_set_p=dspi_bus->setup_p->dma_set_p)) { + edma_p = dma_set_p->edma_p; + // Set up the DMA channels. + dma_chan_rx_i = SPI_DMA_CHAN_I(dma_set_p, RX); + dma_chan_tx_i = SPI_DMA_CHAN_I(dma_set_p, TX); + rx_dma_channel_setup(dma_set_p, (cyg_uint8*) rx_data, + bus_16bit, &edma_p->tcd[dma_chan_rx_i]); + hal_freescale_edma_erq_enable(edma_p, dma_chan_rx_i); + } + + if(!polled) + cyg_drv_interrupt_unmask(dspi_bus->setup_p->intr_num); + count_down = count; + while(count_down) { +#if DEBUG_SPI >= 2 + if(first_turn) { + if(dspi_bus->pushque_p) + dspi_bus->pushque_p[0] |= FREESCALE_DSPI_PUSHR_CTCNT_M; + first_turn = 0; + } +#endif + if(dma_set_p && (count_down > txfifo_n)) { + // Transfer size is larger than DSPI FIFO + // Use DMA Tx + count_down = tx_dma_channel_setup(dspi_bus, (cyg_uint8*) tx_data, + count_down, bus_16bit, + pushr, drop_cs); +#if DEBUG_SPI >= 3 + hal_freescale_edma_transfer_diag(edma_p, dma_chan_rx_i, true); +#endif + // Enable the Tx DMA / SPI controller. + hal_freescale_edma_erq_enable(edma_p, dma_chan_tx_i); + DSPI_EOQ_CLEAR(dspi_p); + } else { + // Transfer size fits within DSPI FIFO + // No need for DMA Tx + DSPI_EOQ_CLEAR(dspi_p); + count_down = fifo_pushque_fill(dspi_bus, (cyg_uint8*) tx_data, + count_down, bus_16bit, + pushr, drop_cs); +#if DEBUG_SPI >= 3 + cyghwr_devs_freescale_dspi_diag(dspi_bus); +#endif + } + + if(polled) { + DEBUG2_PRINTF("DSPI Polled:\n"); + // Busy-wait for DSPI/DMA (polling for completion). + while(!(dspi_p->sr & FREESCALE_DSPI_SR_EOQF_M)); + + if(dma_set_p) // Disable the Tx DMA channel on completion. + hal_freescale_edma_erq_disable(edma_p, dma_chan_tx_i); + } else { + // Wait for DSPI/DMA completion. (interrupt driven). + cyg_drv_mutex_lock(&dspi_bus->transfer_mutex); + cyg_drv_dsr_lock(); + + DSPI_IRQ_ENABLE(dspi_p); + DEBUG2_PRINTF("DSPI IRQ: Enabled\n"); + + // Sit back and wait for the ISR/DSRs to signal completion. + cyg_drv_cond_wait (&dspi_bus->transfer_done); + + cyg_drv_dsr_unlock(); + cyg_drv_mutex_unlock(&dspi_bus->transfer_mutex); + } + + if(dma_set_p) { + // Make sure that Rx has been drained by DMA. + if(rx_data) + while((dspi_p->sr & FREESCALE_DSPI_SR_RFDF_M)); + } else { + // No DMA - "manually" drain Rx FIFO + DEBUG2_PRINTF("DSPI FIFO: 'Manually' drain Rx fifo\n"); +#if DEBUG_SPI >= 3 + cyghwr_devs_freescale_dspi_diag(dspi_bus); +#endif + if(rx_data) { + if(bus_16bit) { + cyg_uint16* rx_data16 = (cyg_uint16*) rx_data; + while(dspi_p->sr & FREESCALE_DSPI_SR_RXCTR_M) + *rx_data16++ = dspi_p->popr; + rx_data = (cyg_uint8*) rx_data16; + } else { + while(dspi_p->sr & FREESCALE_DSPI_SR_RXCTR_M) + *rx_data++ = dspi_p->popr; + } + } else { + dspi_fifo_drain(dspi_p); + } + } + dspi_fifo_clear(dspi_p); + // Prepare for next iteration + if(tx_data) { + tx_data += pushque_n; + if(bus_16bit) + tx_data += pushque_n; + } + } + if(!polled) + cyg_drv_interrupt_mask(dspi_bus->setup_p->intr_num); + + dspi_device->chip_sel = !drop_cs; +} + +//----------------------------------------------------------------------------- +// Initialise SPI interfaces on startup. + +static void CYGBLD_ATTRIB_C_INIT_PRI(CYG_INIT_BUS_SPI) +dspi_spi_init(void) +{ +#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI0 + dspi_bus_setup (&cyg_spi_dspi_bus0); +#endif + +#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI1 + dspi_bus_setup (&cyg_spi_dspi_bus1); +#endif + +#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI2 + dspi_bus_setup (&cyg_spi_dspi_bus2); +#endif +} + + +//----------------------------------------------------------------------------- +// Start a SPI transaction. + +static void dspi_transaction_begin(cyg_spi_device* device) +{ + cyg_spi_freescale_dspi_bus_t* dspi_bus = + (cyg_spi_freescale_dspi_bus_t*) device->spi_bus; + cyg_spi_freescale_dspi_device_t* dspi_device = + (cyg_spi_freescale_dspi_device_t*) device; + + // On the first transaction, generate the values to be programmed into the + // SPI configuration registers for this device and cache them. This avoids + // having to recalculate the prescaler for every transaction. + if(!(dspi_device->clocking.dspi_ctar)) + dspi_device->clocking.dspi_ctar = dspi_calc_ctar(&dspi_device->clocking, + dspi_bus->clock_freq); + // Set up the SPI controller. + dspi_bus->setup_p->dspi_p->ctar[0] = dspi_device->clocking.dspi_ctar; +#if DEBUG_SPI >= 2 + cyghwr_devs_freescale_dspi_diag(dspi_bus); +#endif +} + +//----------------------------------------------------------------------------- +// Run a transaction transfer. + +static void dspi_transaction_transfer(cyg_spi_device* device, cyg_bool polled, + cyg_uint32 count, + const cyg_uint8* tx_data, + cyg_uint8* rx_data, + cyg_bool drop_cs) +{ + cyg_spi_freescale_dspi_device_t* dspi_device = + (cyg_spi_freescale_dspi_device_t*) device; + + DEBUG3_PRINTF("Transaction tx_data = %p count=%d\n", tx_data, count); + + // Check for unsupported transactions. + CYG_ASSERT (count > 0, "DSPI: Null transfer requested."); + + // We check that the buffers are half-word aligned and that count is a + // multiple of two in order to carry out the 16-bit transfer. + if (dspi_device->clocking.bus_16bit) { + CYG_ASSERT (!(count & 1) && !((cyg_uint32) tx_data & 1) && + !((cyg_uint32) rx_data & 1), + "DSPI: Misaligned data in 16-bit transfer."); + } + spi_transaction_do (device, false, polled, count, tx_data, rx_data, drop_cs); +} + +//----------------------------------------------------------------------------- +// Carry out a bus tick operation - this drops chip select then pushes the +// required number of zeros onto the bus. + +static void dspi_transaction_tick(cyg_spi_device* device, cyg_bool polled, + cyg_uint32 count) +{ + cyg_spi_freescale_dspi_device_t* dspi_device = + (cyg_spi_freescale_dspi_device_t*) device; + + // Check for unsupported transactions. + CYG_ASSERT (count > 0, "DSPI: Null transfer requested."); + + // We check that count is a multiple of two in order + // to carry out the 16-bit transfer. + if (dspi_device->clocking.bus_16bit) { + CYG_ASSERT (!(count & 1), + "DSPI: Misaligned data in 16-bit transfer."); + } + + // Perform null transfer + spi_transaction_do (device, true, polled, count, NULL, NULL, true); +} + +//----------------------------------------------------------------------------- +// Terminate a SPI transaction, disabling the SPI controller. + +static void dspi_transaction_end(cyg_spi_device* device) +{ + cyg_spi_freescale_dspi_bus_t* dspi_bus = + (cyg_spi_freescale_dspi_bus_t*) device->spi_bus; + cyg_spi_freescale_dspi_device_t* dspi_device = + (cyg_spi_freescale_dspi_device_t*) device; + + cyghwr_hal_freescale_dma_set_t *dma_set_p = dspi_bus->setup_p->dma_set_p; + cyghwr_hal_freescale_edma_t *edma_p; + cyghwr_devs_freescale_dspi_t* dspi_p = dspi_bus->setup_p->dspi_p; + + if(dma_set_p) { + edma_p = dma_set_p->edma_p; + hal_freescale_edma_erq_disable(edma_p, SPI_DMA_CHAN_I(dma_set_p, TX)); + hal_freescale_edma_erq_disable(edma_p, SPI_DMA_CHAN_I(dma_set_p, RX)); + } + + if(dspi_device->chip_sel){ + // Clear peripheral CS by executing a dummy 4 bit transfer. + dspi_p->pushr = FREESCALE_DSPI_PUSHR_EOQ_M | FREESCALE_DSPI_PUSHR_CTAS(1); + DSPI_EOQ_CLEAR(dspi_p); + while(!(dspi_p->sr & FREESCALE_DSPI_SR_EOQF_M)); + dspi_device->chip_sel = 0; + } +} + +//----------------------------------------------------------------------------- +// Get DSPI configuration parameter + +static int dspi_get_config (cyg_spi_device* device, cyg_uint32 key, + void* buf, cyg_uint32* len) +{ + cyg_spi_freescale_dspi_bus_t* dspi_bus = + (cyg_spi_freescale_dspi_bus_t*) device->spi_bus; + cyg_spi_freescale_dspi_device_t* dspi_device = + (cyg_spi_freescale_dspi_device_t*) device; + cyg_uint32* data_p = buf; + + switch (key) { + case CYG_IO_GET_CONFIG_SPI_CLOCKRATE : + // Sanity check + if (NULL == len) { + CYG_ASSERT (false, "Freescale DSPI:" + " Null pointer as len argument for dspi_get_config()."); + return -1; + } else if (sizeof(cyg_uint32) != *len) { + CYG_ASSERT (false, "Freescale DSPI:" + " Invalid length with dspi_get_config()."); + return -1; + } else if (NULL == buf) { + CYG_ASSERT (false, "Freescale DSPI:" + " Null poiter as buf argument for dspi_get_config()."); + return -1; + } else { + cyg_uint32 ctar, dbr, br, pbr; + + ctar = dspi_device->clocking.dspi_ctar; + dbr = (ctar & FREESCALE_DSPI_CTAR_DBR_M) >> + FREESCALE_DSPI_CTAR_DBR_S; + br = (ctar & FREESCALE_DSPI_CTAR_BR_M) >> + FREESCALE_DSPI_CTAR_BR_S; + pbr = (ctar & FREESCALE_DSPI_CTAR_PBR_M) >> + FREESCALE_DSPI_CTAR_PBR_S; + *data_p = (dspi_bus->clock_freq * (1+dbr)) / (pbr * br); + + DEBUG2_PRINTF("DSPI Get Config: baud = %d\n", *data_p); + + return 0; + } + + default : + break; + } + return -1; +} + +//----------------------------------------------------------------------------- +// Change some SPI device configuration parameters + +static int dspi_set_config(cyg_spi_device* device, cyg_uint32 key, + const void* buf, cyg_uint32* len) +{ + cyg_spi_freescale_dspi_device_t* dspi_device = + (cyg_spi_freescale_dspi_device_t*) device; + cyg_spi_freescale_dspi_bus_t* dspi_bus = + (cyg_spi_freescale_dspi_bus_t*) device->spi_bus; + + cyg_uint32 regval; + ctar_br_t brs; + + switch (key) { + case CYG_IO_SET_CONFIG_SPI_CLOCKRATE : + // Sanity check + if (NULL == len) { + CYG_ASSERT (false, "Freescale DSPI:" + " Null pointer as len argument for dspi_set_config()."); + return -1; + } else if (sizeof(cyg_uint32) != *len) { + CYG_ASSERT (false, "Freescale DSPI:" + " Invalid length with dspi_set_config()."); + return -1; + } else if (NULL == buf) { + CYG_ASSERT (false, "Freescale DSPI:" + " Null pointer as buf argument for dspi_set_config()."); + return -1; + } else { + // Get divider bits + if (!dspi_ctar_brbf(&dspi_device->clocking, &brs, + ctar_br, ctar_pbr, (cyg_uint32 *)buf, dspi_bus->clock_freq)) + { + // Update the cache of the configuration register settings. + regval = dspi_device->clocking.dspi_ctar; + regval &= ~(FREESCALE_DSPI_CTAR_BR_M | + FREESCALE_DSPI_CTAR_PBR_M); + regval |= FREESCALE_DSPI_CTAR_BR(brs.br) | + FREESCALE_DSPI_CTAR_PBR(brs.pbr); + dspi_device->clocking.dspi_ctar = regval; + + return 0; + + } else { + CYG_ASSERT (false, "Freescale DSPI:" + " Cannot run bus as slowly as requested."); + return -1; + } + } + default : + break; + } + return -1; +} + +#if DEBUG_SPI +//---------------------------------------------------------------------------- +// Print out a DSPI array state +// Helper for cyghwr_devs_freescale_dspi_diag() + +void cyghwr_devs_freescale_dspi_diag_array(char* name_p, + volatile cyg_uint32* array_p, + cyg_uint32 array_n) +{ + diag_printf("%s %p[%u]: ", name_p, array_p, array_n); + for(; array_n; array_n--) { + diag_printf(" 0x%08x", *array_p++); + } + diag_printf("\n"); +} + +//---------------------------------------------------------------------------- +// Print out DSPI state + +void cyghwr_devs_freescale_dspi_diag(cyg_spi_freescale_dspi_bus_t* dspi_bus_p) +{ + cyghwr_devs_freescale_dspi_t* dspi_p = dspi_bus_p->setup_p->dspi_p; + + diag_printf("DSPI %p\n", dspi_p); + diag_printf(" MCR = 0x%08x TCR = 0x%08x\n", dspi_p->mcr, dspi_p->tcr); + cyghwr_devs_freescale_dspi_diag_array(" CTAR", dspi_p->ctar, + CYGHWR_DEVS_SPI_FREESCALE_DSPI_CTAR_NUM); + diag_printf(" SR = 0x%08x RSER = 0x%08x PUSHR = 0x%08x POPR = 0x%08x\n", + dspi_p->sr, dspi_p->rser, dspi_p->pushr, dspi_p->popr); + cyghwr_devs_freescale_dspi_diag_array(" TXFR", dspi_p->txfr, dspi_bus_p->txfifo_n); + cyghwr_devs_freescale_dspi_diag_array(" RXFR", dspi_p->rxfr, dspi_bus_p->rxfifo_n); +} +#endif // DEBUG_SPI + +#endif // defined(CYGHWR_DEVS_SPI_FREESCALE_DSPIx) + +//=============================================================================