From 2a32f365405613689086b26cdd67554110300821 Mon Sep 17 00:00:00 2001 From: Alin Jerpelea Date: Tue, 18 Jun 2019 12:46:43 +0000 Subject: [PATCH] Merged in alinjerpelea/nuttx (pull request #909) arch: arm: cxd56xx: SCU, ADC, I2C * nuttx: configs: spresense: LEDS: fix warnings In the initial code several errors were missed because I pushed the dirty code. Signed-off-by: Alin Jerpelea * arch: arm: cxd56xx: add Sensor Control Unit (SCU) Add Sensor Control Unit (SCU) on cxd56xx chip Signed-off-by: Alin Jerpelea * arch: arm: cxd56xx: add I2C support add I2C support on cxd56xx chip Signed-off-by: Alin Jerpelea * arch: arm: cxd56xx: add ADC interface support Add ADC interface support on cxd56xx chip Signed-off-by: Alin Jerpelea * arch: arm: cxd56xx: Use DMAC for reading sensing data Use DMAC for reading sensing data from SCU on cxd56xx chip Signed-off-by: Alin Jerpelea * arch: arm: cxd56xx: code style sanitization NuttX does not use Deoxygen for documentation and no file should contain Doxygen tags or Doxygen style comments. Signed-off-by: Alin Jerpelea * configs: spresense: enable I2CDEV add enable I2CDEV for spresense board Signed-off-by: Alin Jerpelea * configs: spresense: add notification LEDs Add usefull diagnostic LEDs on the speresense board Signed-off-by: Alin Jerpelea Approved-by: Gregory Nutt --- arch/arm/include/cxd56xx/adc.h | 96 + arch/arm/include/cxd56xx/pm.h | 3 - arch/arm/include/cxd56xx/scu.h | 560 +++ arch/arm/include/cxd56xx/timer.h | 9 +- arch/arm/src/cxd56xx/Kconfig | 620 +++ arch/arm/src/cxd56xx/Make.defs | 15 + arch/arm/src/cxd56xx/cxd56_adc.c | 1065 +++++ arch/arm/src/cxd56xx/cxd56_adc.h | 79 + arch/arm/src/cxd56xx/cxd56_dmac.h | 3 - arch/arm/src/cxd56xx/cxd56_dmac_common.h | 79 + arch/arm/src/cxd56xx/cxd56_i2c.c | 1110 ++++++ arch/arm/src/cxd56xx/cxd56_i2c.h | 102 + arch/arm/src/cxd56xx/cxd56_scu.c | 3499 +++++++++++++++++ arch/arm/src/cxd56xx/cxd56_scufifo.c | 214 + arch/arm/src/cxd56xx/cxd56_scufifo.h | 84 + arch/arm/src/cxd56xx/cxd56_sysctl.h | 3 - arch/arm/src/cxd56xx/cxd56_udmac.c | 780 ++++ arch/arm/src/cxd56xx/cxd56_udmac.h | 273 ++ arch/arm/src/cxd56xx/hardware/cxd5602_isop.h | 444 +++ arch/arm/src/cxd56xx/hardware/cxd56_adc.h | 75 + .../src/cxd56xx/hardware/cxd56_dmac_common.h | 3 - arch/arm/src/cxd56xx/hardware/cxd56_i2c.h | 209 + arch/arm/src/cxd56xx/hardware/cxd56_scu.h | 197 + arch/arm/src/cxd56xx/hardware/cxd56_scufifo.h | 425 ++ arch/arm/src/cxd56xx/hardware/cxd56_scuseq.h | 55 + arch/arm/src/cxd56xx/hardware/cxd56_udmac.h | 166 + configs/spresense/include/board.h | 34 +- configs/spresense/include/cxd56_i2cdev.h | 86 + configs/spresense/src/cxd56_bringup.c | 4 + configs/spresense/src/cxd56_i2cdev.c | 83 + configs/spresense/src/cxd56_leds.c | 87 +- configs/spresense/src/cxd56_userleds.c | 30 +- 32 files changed, 10428 insertions(+), 64 deletions(-) create mode 100644 arch/arm/include/cxd56xx/adc.h create mode 100644 arch/arm/include/cxd56xx/scu.h create mode 100644 arch/arm/src/cxd56xx/cxd56_adc.c create mode 100644 arch/arm/src/cxd56xx/cxd56_adc.h create mode 100644 arch/arm/src/cxd56xx/cxd56_dmac_common.h create mode 100644 arch/arm/src/cxd56xx/cxd56_i2c.c create mode 100644 arch/arm/src/cxd56xx/cxd56_i2c.h create mode 100644 arch/arm/src/cxd56xx/cxd56_scu.c create mode 100644 arch/arm/src/cxd56xx/cxd56_scufifo.c create mode 100644 arch/arm/src/cxd56xx/cxd56_scufifo.h create mode 100644 arch/arm/src/cxd56xx/cxd56_udmac.c create mode 100644 arch/arm/src/cxd56xx/cxd56_udmac.h create mode 100644 arch/arm/src/cxd56xx/hardware/cxd5602_isop.h create mode 100644 arch/arm/src/cxd56xx/hardware/cxd56_adc.h create mode 100644 arch/arm/src/cxd56xx/hardware/cxd56_i2c.h create mode 100644 arch/arm/src/cxd56xx/hardware/cxd56_scu.h create mode 100644 arch/arm/src/cxd56xx/hardware/cxd56_scufifo.h create mode 100644 arch/arm/src/cxd56xx/hardware/cxd56_scuseq.h create mode 100644 arch/arm/src/cxd56xx/hardware/cxd56_udmac.h create mode 100644 configs/spresense/include/cxd56_i2cdev.h create mode 100644 configs/spresense/src/cxd56_i2cdev.c diff --git a/arch/arm/include/cxd56xx/adc.h b/arch/arm/include/cxd56xx/adc.h new file mode 100644 index 0000000000..83dcb7975a --- /dev/null +++ b/arch/arm/include/cxd56xx/adc.h @@ -0,0 +1,96 @@ +/**************************************************************************** + * arch/arm/include/cxd56xx/adc.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_CXD56XX_CXD56_ADC_H +#define __ARCH_ARM_INCLUDE_CXD56XX_CXD56_ADC_H + +/**************************************************************************** + * include files + ***************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ANIOC_USER (AN_FIRST + AN_NCMDS) + +/* Start sampling + * + * param None + * return ioctl return value provides success/failure indication + */ + +#define ANIOC_CXD56_START _ANIOC(ANIOC_USER + 0) + +/* Stop sampling + * + * param None + * return ioctl return value provides success/failure indication + */ + +#define ANIOC_CXD56_STOP _ANIOC(ANIOC_USER + 1) + +/* Set sampling frequency + * + * param None + * return ioctl return value provides success/failure indication + */ + +#define ANIOC_CXD56_FREQ _ANIOC(ANIOC_USER + 2) + +/* Set fifo size + * + * param None + * return ioctl return value provides success/failure indication + */ + +#define ANIOC_CXD56_FIFOSIZE _ANIOC(ANIOC_USER + 3) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Initialize valid ADC channels + * + * return OK(0) is success. negative value is failure. + */ + +int cxd56_adcinitialize(void); + +#endif /* __ARCH_ARM_INCLUDE_CXD56XX_CXD56_ADC_H */ diff --git a/arch/arm/include/cxd56xx/pm.h b/arch/arm/include/cxd56xx/pm.h index 50b0527102..5f0ba2c027 100644 --- a/arch/arm/include/cxd56xx/pm.h +++ b/arch/arm/include/cxd56xx/pm.h @@ -32,9 +32,6 @@ * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************/ -/** - * @file pm.h - */ #ifndef __ARCH_ARM_INCLUDE_CXD56XX_PM_H #define __ARCH_ARM_INCLUDE_CXD56XX_PM_H diff --git a/arch/arm/include/cxd56xx/scu.h b/arch/arm/include/cxd56xx/scu.h new file mode 100644 index 0000000000..b1a3409218 --- /dev/null +++ b/arch/arm/include/cxd56xx/scu.h @@ -0,0 +1,560 @@ +/**************************************************************************** + * arch/arm/include/cxd56xx/scu.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_CXD56XX_CXD56_SCU_H +#define __ARCH_ARM_INCLUDE_CXD56XX_CXD56_SCU_H + +/**************************************************************************** + * include files + ****************************************************************************/ + +#include +#include +#include + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define _SCUIOCBASE (0xa000) + +#define _SCUIOCVALID(c) (_IOC_TYPE(c)==_SCUIOCBASE) +#define _SCUIOC(nr) _IOC(_SCUIOCBASE,nr) + +/* + * Set FIFO size used by sequencer + * + * uint16_t FIFO size in bytes + * return ioctl return value provides success/failure indication + */ + +#define SCUIOC_SETFIFO _SCUIOC(0x0001) + +/* + * Free FIFO used by sequencer + * + * param: none + * return: ioctl return value provides success/failure indication + */ + +#define SCUIOC_FREEFIFO _SCUIOC(0x0002) + +/* + * Set sequencer sampling rate + * + * param: uint8_t: sampling rate + * return: ioctl return value provides success/failure indication + */ + +#define SCUIOC_SETSAMPLE _SCUIOC(0x0003) + +/* + * Enable/Disable sign conversion preprocessing + * + * param: unsigned long: 0 = disable, 1 = enable + * return: ioctl return value provides success/failure indication + */ + +#define SCUIOC_SETSIGNCONV _SCUIOC(0x0004) + +/* + * Set offset/gain adjustment parameter + * + * param: Pointer to struct adjust_xyz_s. + * return: ioctl return value provides success/failure indication + */ + +#define SCUIOC_SETOGADJUST _SCUIOC(0x0005) + +/* + * Clear offset/gain adjustment parameter + * + * param: none + * return: ioctl return value provides success/failure indication + */ + +#define SCUIOC_CLROGADJUST _SCUIOC(0x0006) + +/* + * Set IIR filter coefficiencies + * + * param: Pointer to struct math_filter_s + * return: ioctl return value provides success/failure indication + */ + +#define SCUIOC_SETFILTER _SCUIOC(0x0007) + +/* + * Set event notifier parameters + * + * Set event notifier. This command must use with IIR filter, so it will be + * error when no filter set by SCUIOC_SETFILTER. + * + * param: Pointer to struct scuev_notify_s + * return: ioctl return value provides success/failure indication + */ + +#define SCUIOC_SETNOTIFY _SCUIOC(0x0008) + +/* + * Set elements per sample + * + * SCU can be treat 3 axis sample data as 1 or 2 axis data. For example, + * user can be used to detect via event notifier, about the board is + * tilting, by X and Y axis data from accelerometer. + * This setting will be affected for IIR Filter and event notifier. + * + * param: unsigned long: 1 - 3 + * return: ioctl return value provides success/failure indication + */ + +#define SCUIOC_SETELEMENTS _SCUIOC(0x0009) + +/* + * Set decimation parameters (Decimator only) + * + * param: Pointer to struct decimation_s + * return: ioctl return value provides success/failure indication + */ + +#define SCUIOC_SETDECIMATION _SCUIOC(0x000a) + +/* + * Set FIFO sample data watermark + * + * param: Pointer of struct scufifo_wm_s + * return: ioctl return value provides success/failure indication + */ + +#define SCUIOC_SETWATERMARK _SCUIOC(0x000b) + +/* + * Start sequencer + * + * param: None + * return: ioctl return value provides success/failure indication + */ + +#define SCUIOC_START _SCUIOC(0x0010) + +/* + * Stop sequencer + * + * param: None + * return: ioctl return value provides success/failure indication + */ + +#define SCUIOC_STOP _SCUIOC(0x0011) + +/* + * Set FIFO overwrite mode + * + * param: unsigned long: 0 = overwrite disable, 1 = overwrite enable + * return: ioctl return value provides success/failure indication + */ + +#define SCUIOC_SETFIFOMODE _SCUIOC(0x0012) + +/* + * Delete FIFO data + * + * param: uint16_t delete size + * return: ioctl return value provides success/failure indication + */ + +#define SCUIOC_DELFIFODATA _SCUIOC(0x0013) + +#define SCU_BUS_SPI 1 /*< SPI bus */ +#define SCU_BUS_I2C0 2 /*< I2C0 bus */ +#define SCU_BUS_I2C1 3 /*< I2C1 bus */ +#define SCU_BUS_LPADC0 0x10 /*< LPADC0 */ +#define SCU_BUS_LPADC1 0x11 /*< LPADC1 */ +#define SCU_BUS_LPADC2 0x12 /*< LPADC2 */ +#define SCU_BUS_LPADC3 0x13 /*< LPADC3 */ +#define SCU_BUS_HPADC0 0x14 /*< HPADC1 */ +#define SCU_BUS_HPADC1 0x15 /*< HPADC2 */ + +/* Send 1 byte instruction */ + +#define SCU_INST_SEND(val) ((val) & 0xff) + +/* Receive n byte instruction (n: 1 - 8) */ + +#define SCU_INST_RECV(n) ((1 << 8) | (((n) - 1) & 0x7) << 12) + +#define SCU_INST_TERM (1 << 11) +#define SCU_INST_RESTART (1 << 10) +#define SCU_INST_STOP (1 << 9) + +/* Indicate this instruction is last */ + +#define SCU_INST_LAST (SCU_INST_TERM|SCU_INST_STOP) + +/* Sequencer types */ + +#define SEQ_TYPE_NORMAL 0 /*< Normal sequencer */ +#define SEQ_TYPE_DECI 1 /*< Decimator */ + +/* Event control */ + +#define SCU_EV_RISE_EN (1 << 31) /*< Rise event enable */ +#define SCU_EV_FALL_EN (1 << 30) /*< Fall event enable */ +#define SCU_EV_OUT8BITS (1 << 29) /*< Output only upper 8 bits */ + +#define SCU_EV_OUTSHIFT 16 +#define SCU_EV_OUTMASK (3 << SCU_EV_OUTSHIFT) +#define SCU_EV_OUTALWAYS (0 << SCU_EV_OUTSHIFT) /*< Always output to FIFO */ +#define SCU_EV_OUTSTART (1 << SCU_EV_OUTSHIFT) /*< Output start after event occurred */ +#define SCU_EV_OUTSTOP (2 << SCU_EV_OUTSHIFT) /*< Output stop after event occurred */ +#define SCU_EV_NOTOUT (3 << SCU_EV_OUTSHIFT) /*< No output to FIFO */ + +#define SCU_EV_WRITESAMPLEMASK 0xfff + +/* Output samples when event occurred */ + +#define SCU_EV_WRITESAMPLES(sample) ((sample) & SCU_EV_WRITESAMPLEMASK) + +/* Event type flags */ + +#define SCU_EV_RISE (1) /*< Rise (low to high) event occurred */ +#define SCU_EV_FALL (2) /*< Fall (high to low) event occurred */ + +/* Level adjustment (decimator only) */ + +#define SCU_LEVELADJ_X1 (0) /*< Level adjustment x1 */ +#define SCU_LEVELADJ_X2 (1) /*< Level adjustment x2 */ +#define SCU_LEVELADJ_X4 (2) /*< Level adjustment x4 */ +#define SCU_LEVELADJ_X8 (3) /*< Level adjustment x8 */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* + * IIR filter position + * details IIR filter can be set 2 filters on data path. + * image html scu_IIR_filter_path.png + */ + +enum filter_pos_e +{ + FILTER_POS_NONE = 0, /*< Filter none */ + FILTER_POS_AA, /*< 2 for all */ + FILTER_POS_FF, /*< 2 for FIFO */ + FILTER_POS_AF, /*< 1 for all, 1 for FIFO */ + FILTER_POS_EE, /*< 2 for Event detector */ + FILTER_POS_AE, /*< 1 for all, 1 for Event detector */ + FILTER_POS_FE, /*< 1 for FIFO, 1 for Event detector */ +}; + +/* Sample timestamp */ + +struct scutimestamp_s +{ + uint32_t sec; /*< Seconds */ + uint16_t tick; /*< Clock tick (based on 32768 Hz) */ +}; + +/* IIR filter coefficiencies */ + +struct iir_coeff_s +{ + uint32_t h; /* High 32 bit */ + uint8_t l; /* Low 8 bit */ +}; + +/* IIR filter setting */ + +struct iir_filter_s +{ + uint8_t ishift; /*< Input shift */ + uint8_t oshift; /*< Output shift */ + struct iir_coeff_s coeff[5]; /*< IIR filter coefficiencies */ +}; + +/* Math Function IIR filter setting */ + +struct math_filter_s +{ + enum filter_pos_e pos; /*< Insert position identifier */ + struct iir_filter_s filter[2]; /*< IIR filter parameters */ +}; + +/* + * Event configuration + * + * a threshold is rise/fall threshold for input data. + * When set this member for a rise in struct scuev_notify_s, counting data + * if higher than threshold, and a fall is vise-versa. + * a count0 is used for prevent chattering. a count1 is used for counting + * continuously input. + * When configured for a rise, SCU processing as follows: + * + * - Counting higher value than threshold coninuously + * - If counter reached to a count0, start actual couning + * - If input data fall less than threshold before reached to a count0, + * then stop and reset counts + * - If total count is reached to a count0 + a count1, then raise rise event + * - If count1 is zero, then notify when count reached to a count0 + * immediately + * - If threshold or count0 is zero, configuration is ignored + */ + +struct sensor_event_s +{ + uint16_t threshold; /*< Threshold */ + uint16_t count0; /*< Preventing counts */ + uint16_t count1; /*< Actual counts */ + uint16_t delaysamples; /*< Event notification delay in samples */ +}; + +/* Arguments for event signal */ + +struct scuev_arg_s +{ + struct scutimestamp_s ts; /*< timestamp stored when event occurred. */ + uint32_t type; /*< Event type (SCU_EV_RISE or SCU_EV_FALL) */ +}; + +/* Event notifier setting */ + +struct scuev_notify_s +{ + int signo; /*< Signal number (0 - 31, except system reserved) */ + + struct sensor_event_s rise; /*< Rise threshold */ + struct sensor_event_s fall; /*< Fall threshold */ + + uint32_t ctrl; /*< Event control */ + + FAR struct scuev_arg_s *arg; /*< Arguments for event raised */ +}; + +/* Offset/gain adjustment parameter */ + +struct adjust_s { + uint16_t offset; /*< Offset value */ + uint16_t gain; /*< Gain value */ +}; + +/* Offset/gain adjustment parameter for 3 axis */ + +struct adjust_xyz_s { + struct adjust_s x; /*< For X axis */ + struct adjust_s y; /*< For Y axis */ + struct adjust_s z; /*< For Z axis */ +}; + +/* Decimation parameter */ + +struct decimation_s +{ + uint8_t ratio; /*< Decimation ratio (1 / (2 ^ ratio)), 0 - 9 */ + uint8_t leveladj; /*< Output data multiplier */ + uint8_t forcethrough; /*< Force through */ +}; + +/* Watermark notification */ + +struct scufifo_wm_s +{ + int signo; /*< Signal number (0 - 31, except system reserved) */ + + /* Pointer to memomry to be timestamp stored */ + + FAR struct scutimestamp_s *ts; + + /* + * Watermark value. SCU notifies when + * stored samples over watermark in FIFO. + * Valid value range: 1 - 65535 + */ + + uint16_t watermark; +}; + +struct seq_s; /* The sequencer object */ + +/* + * Open sequencer + * + * param [in] type : Sequencer type. Set one of the following definitions. + * - #SEQ_TYPE_NORMAL + * - #SEQ_TYPE_DECI + * param [in] bustype : Bustype. Set one of the foollowing definitions. + * - #SCU_BUS_I2C0 + * - #SCU_BUS_I2C1 + * - #SCU_BUS_SPI + * + * return: struct seq_s pointer is success. NULL is failure. + */ + +FAR struct seq_s *seq_open(int type, int bustype); + +/* + * Close sequencer device + * + * param [in] seq : Sequencer instance + */ + +void seq_close(FAR struct seq_s *seq); + +/* + * Read sequencer FIFO data + * + * param [in] seq : Sequencer instance + * param [in] fifoid : FIFO ID (decimator only) + * param [out] buffer : Pointer to data receive buffer + * param [in] length : Buffer length + * + * return : OK(0) is success. negative value is failure. + */ + +int seq_read(FAR struct seq_s *seq, int fifoid, char *buffer, int length); + +/* + * Sequencer specific ioctl + * + * This API should be called from each sensor driver ioctl(). + * + * param [in] seq : Sequencer instance + * param [in] fifoid : FIFO ID (decimator only) + * param [in] cmd : ioctl commands (SCUIOC_*). + * param [in,out] arg : Argument for each commands + * + * see #scu_ioctl + * + * return: OK(0) is success. negative value is failure. + */ + +int seq_ioctl(FAR struct seq_s *seq, int fifoid, int cmd, unsigned long arg); + +/* + * Set cyclic sequencer instruction + * + * param [in] seq : Sequencer instance + * param [in] inst : Pointer to instruction array + * param [in] nr_insts : Number of instructions + * + * return OK(0) is success. negative value is failure. + */ + +int seq_setinstruction(FAR struct seq_s *seq, const uint16_t *inst, + uint16_t nr_insts); + +/* + * Set sample data format + * + * param [in] seq : Sequencer instance + * param [in] sample : Bytes per sample + * param [in] offset : Start offset of sampling data + * param [in] elemsize : Bytes of 1 element in sample + * param [in] swapbyte : Enable/Disable byte swapping + * + * return OK(0) is success. negative value is failure. + */ + +void seq_setsample(FAR struct seq_s *seq, uint8_t sample, uint8_t offset, + uint8_t elemsize, bool swapbyte); + +/* + * Set slave ID or address + * + * param [in] seq : An instance of sequencer + * param [in] slave_addr : In SPI, slave select ID. In I2C, bus address. + */ + +void seq_setaddress(FAR struct seq_s *seq, uint32_t slave_addr); + +/* + * SPI data transfer via sequencer. + * + * This function use 'oneshot' feature on SCU. So user unnecessary to specify + * any opened sequencer. + * This function usefull for accessing register directly. + * + * param [in] slavesel : Slave select + * param [in] inst : Sequencer instruction + * param [in] nr_insts : Number of instructions + * param [out] buffer : Pointer to receive buffer, if no need to receive, + * then NULL. + * param [in] len : buffer length (ignored when buffer is NULL) + * + * return OK(0) is success. negative value is failure. + */ + +int scu_spitransfer(int slavesel, uint16_t *inst, uint32_t nr_insts, + uint8_t *buffer, int len); + +/* + * I2C data transfer via sequencer + * + * This function use 'oneshot' feature on SCU. So user unnecessary to + * specify any opened sequencer. + * This function usefull for accessing register directly. + * + * param [in] port : I2C port (0 or 1) + * param [in] slave : Slave address + * param [in] inst : Sequencer instruction + * param [in] nr_insts : Number of instructions + * param [out] buffer : Pointer to receive buffer, if no need to receive, + * then NULL. + * param [in] len : buffer length (ignored when buffer is NULL) + * + * return OK(0) is success. negative value is failure. + */ + +int scu_i2ctransfer(int port, int slave, uint16_t *inst, uint32_t nr_insts, + uint8_t *buffer, int len); + +/* + * Initialize SCU + * + * warning: This API called from board_app_initialize(). + * Do not call this API from each sensor drivers. + */ + +void scu_initialize(void); + +/* + * Uninitialize SCU + * + * warning: This API called from board_app_initialize(). + * Do not call this API from each sensor drivers. + */ + +void scu_uninitialize(void); + +#endif /* __ARCH_ARM_INCLUDE_CXD56XX_CXD56_SCU_H */ diff --git a/arch/arm/include/cxd56xx/timer.h b/arch/arm/include/cxd56xx/timer.h index 8c4e9cfe20..5a33ea18e9 100644 --- a/arch/arm/include/cxd56xx/timer.h +++ b/arch/arm/include/cxd56xx/timer.h @@ -32,9 +32,6 @@ * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************/ -/** - * @file timer.h - */ #ifndef __ARCH_ARM_INCLUDE_CXD56XX_TIMER_H #define __ARCH_ARM_INCLUDE_CXD56XX_TIMER_H @@ -45,11 +42,11 @@ * Pre-processor Definitions ****************************************************************************/ -/** +/* * Set callback handler * - * @param A pointer to struct timer_sethandler_s - * @return ioctl return value provides success/failure indication + * param A pointer to struct timer_sethandler_s + * return ioctl return value provides success/failure indication */ #define TCIOC_SETHANDLER _TCIOC(0x0020) diff --git a/arch/arm/src/cxd56xx/Kconfig b/arch/arm/src/cxd56xx/Kconfig index 694cace710..d8c4e9f723 100644 --- a/arch/arm/src/cxd56xx/Kconfig +++ b/arch/arm/src/cxd56xx/Kconfig @@ -358,6 +358,43 @@ config CXD56_DMAC_SPI5_RX_MAXSIZE endif # CXD56_DMAC_SPI5_RX endif # CXD56_SPI5 +endif + +config CXD56_I2C + bool "I2C" + +if CXD56_I2C + +menuconfig CXD56_I2C0 + bool "I2C0" + +if CXD56_I2C0 + +config CXD56_I2C0_SCUSEQ + bool "SCU Sequencer" + default y + depends on CXD56_SCU + ---help--- + Use the sensor control unit (SCU) sequencer. + +endif # CXD56_I2C0 + +menuconfig CXD56_I2C1 + bool "I2C1" + +if CXD56_I2C1 + +config CXD56_I2C1_SCUSEQ + bool "SCU Sequencer" + default y + depends on CXD56_SCU + ---help--- + Use the sensor control unit (SCU) sequencer. + +endif # CXD56_I2C1 + +config CXD56_I2C2 + bool "I2C2" endif @@ -397,6 +434,589 @@ config CXD56_PWM3 Enable PWM channel 3 endif # CXD56_PWM + +config CXD56_ADC + bool "ADC" + default n + depends on CXD56_SCU + ---help--- + Support ADC interface + +if CXD56_ADC + +menuconfig CXD56_HPADC0 + bool "HPADC0" + default n + +if CXD56_HPADC0 + +config CXD56_HPADC0_FREQ + int "Coefficient of sampling frequency" + default 11 if CXD56_SCU_32K + default 7 if CXD56_SCU_RCOSC + default 7 if CXD56_SCU_XOSC + range 9 11 if CXD56_SCU_32K + range 0 7 if CXD56_SCU_RCOSC + range 0 7 if CXD56_SCU_XOSC + ---help--- + This configuration set to sampling frequency calculated by the following formula. + Sampling frequency = adc clock / 2 ^ n [Hz] + adc clock = SCU32K : if SCU clock is SCU32K. + adc clock = RCOSC / 4 : if SCU clock is RCOSC. + adc clock = XOSC / 3 / 4 : if SCU clock is XOSC 26MHz. + Note. Setable range depends on the SCU clock mode. + SCU32K : 9 to 11 + RCOSC : 0 to 7 (0 ~ 6 : over-sampling mode) + XOSC : 0 to 7 (0 ~ 6 : over-sampling mode) + +config CXD56_HPADC0_OFFSET + int "Offset" + default 0 + range 0 65535 + +config CXD56_HPADC0_GAIN + int "Gain" + default 0 + range 0 65535 + +config CXD56_HPADC0_FSIZE + int "SCU FIFO size" + default 64 + range 2 40960 + ---help--- + SCU FIFO size + +endif # CXD56_HPADC0 + +menuconfig CXD56_HPADC1 + bool "HPADC1" + default n + +if CXD56_HPADC1 + +config CXD56_HPADC1_FREQ + int "Coefficient of sampling frequency" + default 11 if CXD56_SCU_32K + default 7 if CXD56_SCU_RCOSC + default 7 if CXD56_SCU_XOSC + range 9 11 if CXD56_SCU_32K + range 0 7 if CXD56_SCU_RCOSC + range 0 7 if CXD56_SCU_XOSC + ---help--- + This configuration set to sampling frequency calculated by the following formula. + Sampling frequency = adc clock / 2 ^ n [Hz] + adc clock = SCU32K : if SCU clock is SCU32K. + adc clock = RCOSC / 4 : if SCU clock is RCOSC. + adc clock = XOSC / 3 / 4 : if SCU clock is XOSC 26MHz. + Note. Setable range depends on the SCU clock mode. + SCU32K : 9 to 11 + RCOSC : 0 to 7 (0 ~ 6 : over-sampling mode) + XOSC : 0 to 7 (0 ~ 6 : over-sampling mode) + +config CXD56_HPADC1_OFFSET + int "Offset" + default 0 + range 0 65535 + +config CXD56_HPADC1_GAIN + int "Gain" + default 0 + range 0 65535 + +config CXD56_HPADC1_FSIZE + int "SCU FIFO size" + default 64 + range 2 40960 + ---help--- + SCU FIFO size + +endif # CXD56_HPADC1 + +config CXD56_LPADC + bool "LPADC" + default n + +if CXD56_LPADC + +choice + prompt "Select LPADC channel" + default CXD56_LPADC0 + +config CXD56_LPADC0 + bool "LPADC channel 0" + ---help--- + Enable LPADC channel 0. + Other LPADC channel can not be used. + +config CXD56_LPADC1 + bool "LPADC channel 1" + ---help--- + Enable LPADC channel 1. + Other LPADC channel can not be used. + +config CXD56_LPADC2 + bool "LPADC channel 2" + ---help--- + Enable LPADC channel 2. + Other LPADC channel can not be used. + +config CXD56_LPADC3 + bool "LPADC channel 3" + ---help--- + Enable LPADC channel 3. + Other LPADC channel can not be used. + +config CXD56_LPADC0_1 + bool "LPADC channel 0 and channel 1" + ---help--- + Enable LPADC channel 0 and LPADC channel 1. + Switch the LPADC channel 0 sampling and LPADC channel 1 sampling in time division. + +config CXD56_LPADC_ALL + bool "LPADC all channels" + ---help--- + Enable LPADC all channels. + Switch the LPADC all channels sampling in time division. +endchoice + +menu "LADC0" + depends on CXD56_LPADC0 + +config CXD56_LPADC0_FREQ + int "Coefficient of sampling frequency" + default 12 + range 11 15 if CXD56_SCU_32K + range 3 15 if CXD56_SCU_RCOSC + range 2 15 if CXD56_SCU_XOSC + ---help--- + This configuration set to sampling frequency calculated by the following formula. + Sampling frequency = SCU32K / 2 ^ n [Hz] + Note. Setable range depends on the SCU clock mode. + SCU32K : 11 to 15 + RCOSC : 3 to 15 + XOSC : 2 to 15 + +config CXD56_LPADC0_OFFSET + int "Offset" + default 0 + range 0 65535 + +config CXD56_LPADC0_GAIN + int "Gain" + default 0 + range 0 65535 + +config CXD56_LPADC0_FSIZE + int "SCU FIFO size" + default 16 + range 2 40960 + ---help--- + SCU FIFO size + +endmenu # CXD56_LPADC0 + +menu "LADC1" + depends on CXD56_LPADC1 + +config CXD56_LPADC1_FREQ + int "Coefficient of sampling frequency" + default 12 + range 11 15 if CXD56_SCU_32K + range 3 15 if CXD56_SCU_RCOSC + range 2 15 if CXD56_SCU_XOSC + ---help--- + This configuration set to sampling frequency calculated by the following formula. + Sampling frequency = SCU32K / 2 ^ n [Hz] + Note. Setable range depends on the SCU clock mode. + SCU32K : 11 to 15 + RCOSC : 3 to 15 + XOSC : 2 to 15 + +config CXD56_LPADC1_OFFSET + int "Offset" + default 0 + range 0 65535 + +config CXD56_LPADC1_GAIN + int "Gain" + default 0 + range 0 65535 + +config CXD56_LPADC1_FSIZE + int "SCU FIFO size" + default 16 + range 2 40960 + ---help--- + SCU FIFO size + +endmenu # CXD56_LPADC1 + +menu "LADC2" + depends on CXD56_LPADC2 + +config CXD56_LPADC2_FREQ + int "Coefficient of sampling frequency" + default 12 + range 11 15 if CXD56_SCU_32K + range 3 15 if CXD56_SCU_RCOSC + range 2 15 if CXD56_SCU_XOSC + ---help--- + This configuration set to sampling frequency calculated by the following formula. + Sampling frequency = SCU32K / 2 ^ n [Hz] + Note. Setable range depends on the SCU clock mode. + SCU32K : 11 to 15 + RCOSC : 3 to 15 + XOSC : 2 to 15 + +config CXD56_LPADC2_OFFSET + int "Offset" + default 0 + range 0 65535 + +config CXD56_LPADC2_GAIN + int "Gain" + default 0 + range 0 65535 + +config CXD56_LPADC2_FSIZE + int "SCU FIFO size" + default 16 + range 2 40960 + ---help--- + SCU FIFO size + +endmenu # CXD56_LPADC2 + +menu "LADC3" + depends on CXD56_LPADC3 + +config CXD56_LPADC3_FREQ + int "Coefficient of sampling frequency" + default 12 + range 11 15 if CXD56_SCU_32K + range 3 15 if CXD56_SCU_RCOSC + range 2 15 if CXD56_SCU_XOSC + ---help--- + This configuration set to sampling frequency calculated by the following formula. + Sampling frequency = SCU32K / 2 ^ n [Hz] + Note. Setable range depends on the SCU clock mode. + SCU32K : 11 to 15 + RCOSC : 3 to 15 + XOSC : 2 to 15 + +config CXD56_LPADC3_OFFSET + int "Offset" + default 0 + range 0 65535 + +config CXD56_LPADC3_GAIN + int "Gain" + default 0 + range 0 65535 + +config CXD56_LPADC3_FSIZE + int "SCU FIFO size" + default 16 + range 2 40960 + ---help--- + SCU FIFO size + +endmenu # CXD56_LPADC3 + +menu "LADC0" + depends on CXD56_LPADC0_1 + +config CXD56_LPADC0_FREQ + int "Coefficient of sampling frequency" + default 12 + range 12 15 if CXD56_SCU_32K + range 6 15 if CXD56_SCU_RCOSC + range 6 15 if CXD56_SCU_XOSC + ---help--- + This configuration set to sampling frequency calculated by the following formula. + Sampling frequency = SCU32K / 2 ^ (n+1) [Hz] + Note. Setable range depends on the SCU clock mode. + SCU32K : 12 to 15 + RCOSC : 6 to 15 + XOSC : 6 to 15 + +config CXD56_LPADC0_OFFSET + int "Offset" + default 0 + range 0 65535 + +config CXD56_LPADC0_GAIN + int "Gain" + default 0 + range 0 65535 + +config CXD56_LPADC0_FSIZE + int "SCU FIFO size" + default 16 + range 2 40960 + ---help--- + SCU FIFO size + +endmenu # CXD56_LPADC0_1 + +menu "LADC1" + depends on CXD56_LPADC0_1 + +config CXD56_LPADC1_FREQ + int "Coefficient of sampling frequency" + default 12 + range 12 15 if CXD56_SCU_32K + range 6 15 if CXD56_SCU_RCOSC + range 6 15 if CXD56_SCU_XOSC + ---help--- + This configuration set to sampling frequency calculated by the following formula. + Sampling frequency = SCU32K / 2 ^ (n+1) [Hz] + Note. Setable range depends on the SCU clock mode. + SCU32K : 12 to 15 + RCOSC : 6 to 15 + XOSC : 6 to 15 + +config CXD56_LPADC1_OFFSET + int "Offset" + default 0 + range 0 65535 + +config CXD56_LPADC1_GAIN + int "Gain" + default 0 + range 0 65535 + +config CXD56_LPADC1_FSIZE + int "SCU FIFO size" + default 16 + range 2 40960 + ---help--- + SCU FIFO size + +endmenu # CXD56_LPADC0_1 + +menu "LADC0" + depends on CXD56_LPADC_ALL + +config CXD56_LPADC0_FREQ + int "Coefficient of sampling frequency" + default 12 + range 11 15 if CXD56_SCU_32K + range 7 15 if CXD56_SCU_RCOSC + range 7 15 if CXD56_SCU_XOSC + ---help--- + This configuration set to sampling frequency calculated by the following formula. + Sampling frequency = SCU32K / 2 ^ (n+2) [Hz] + Note. Setable range depends on the SCU clock mode. + SCU32K : 11 to 15 + RCOSC : 7 to 15 + XOSC : 7 to 15 + +config CXD56_LPADC0_OFFSET + int "Offset" + default 0 + range 0 65535 + +config CXD56_LPADC0_GAIN + int "Gain" + default 0 + range 0 65535 + +config CXD56_LPADC0_FSIZE + int "SCU FIFO size" + default 16 + range 2 40960 + ---help--- + SCU FIFO size + +endmenu # CXD56_LPADC_ALL + +menu "LADC1" + depends on CXD56_LPADC_ALL + +config CXD56_LPADC1_FREQ + int "Coefficient of sampling frequency" + default 12 + range 11 15 if CXD56_SCU_32K + range 7 15 if CXD56_SCU_RCOSC + range 7 15 if CXD56_SCU_XOSC + ---help--- + This configuration set to sampling frequency calculated by the following formula. + Sampling frequency = SCU32K / 2 ^ (n+2) [Hz] + Note. Setable range depends on the SCU clock mode. + SCU32K : 11 to 15 + RCOSC : 7 to 15 + XOSC : 7 to 15 + +config CXD56_LPADC1_OFFSET + int "Offset" + default 0 + range 0 65535 + +config CXD56_LPADC1_GAIN + int "Gain" + default 0 + range 0 65535 + +config CXD56_LPADC1_FSIZE + int "SCU FIFO size" + default 16 + range 2 40960 + ---help--- + SCU FIFO size + +endmenu # CXD56_LPADC_ALL + +menu "LADC2" + depends on CXD56_LPADC_ALL + +config CXD56_LPADC2_FREQ + int "Coefficient of sampling frequency" + default 12 + range 11 15 if CXD56_SCU_32K + range 7 15 if CXD56_SCU_RCOSC + range 7 15 if CXD56_SCU_XOSC + ---help--- + This configuration set to sampling frequency calculated by the following formula. + Sampling frequency = SCU32K / 2 ^ (n+2) [Hz] + Note. Setable range depends on the SCU clock mode. + SCU32K : 11 to 15 + RCOSC : 7 to 15 + XOSC : 7 to 15 + +config CXD56_LPADC2_OFFSET + int "Offset" + default 0 + range 0 65535 + +config CXD56_LPADC2_GAIN + int "Gain" + default 0 + range 0 65535 + +config CXD56_LPADC2_FSIZE + int "SCU FIFO size" + default 16 + range 2 40960 + ---help--- + SCU FIFO size + +endmenu # CXD56_LPADC_ALL + +menu "LADC3" + depends on CXD56_LPADC_ALL + +config CXD56_LPADC3_FREQ + int "Coefficient of sampling frequency" + default 12 + range 11 15 if CXD56_SCU_32K + range 7 15 if CXD56_SCU_RCOSC + range 7 15 if CXD56_SCU_XOSC + ---help--- + This configuration set to sampling frequency calculated by the following formula. + Sampling frequency = SCU32K / 2 ^ (n+2) [Hz] + Note. Setable range depends on the SCU clock mode. + SCU32K : 11 to 15 + RCOSC : 7 to 15 + XOSC : 7 to 15 + +config CXD56_LPADC3_OFFSET + int "Offset" + default 0 + range 0 65535 + +config CXD56_LPADC3_GAIN + int "Gain" + default 0 + range 0 65535 + +config CXD56_LPADC3_FSIZE + int "SCU FIFO size" + default 16 + range 2 40960 + ---help--- + SCU FIFO size + +endmenu # CXD56_LPADC_ALL + +endif # CXD56_LPADC + +endif # CXD56_ADC + +menuconfig CXD56_SCU + bool "Sensor Control Unit (SCU)" + default y + +if CXD56_SCU + +config CXD56_SCU_PREDIV + int "Sequencer Sampling Predivider" + default 64 + range 1 256 + ---help--- + This configuration ralated to maximum sampling rate based + on 32.768KHz. + e.g. 32768 / 64 = 512 (samples) + +choice + prompt "SCU clock mode" + default CXD56_SCU_RCOSC + +config CXD56_SCU_32K + bool "Same with SCU32K" + +config CXD56_SCU_RCOSC + bool "RCOSC" + +config CXD56_SCU_XOSC + bool "XOSC" +endchoice + +if CXD56_SCU_XOSC +config CXD56_SCU_XOSC_DIV + int "SCU XOSC predivider" + default 2 + range 1 4 +endif + +choice + prompt "SCU32K clock source" + default CXD56_SCU32K_RTC + +config CXD56_SCU32K_RCRTC + bool "RCRTC" + +config CXD56_SCU32K_RTC + bool "RTC" +endchoice + +config CXD56_SCU_DEBUG + bool "SCU Debug" + default n + +config CXD56_SCU_DEBUG_ERR + bool "Error Messages" + default n + depends on CXD56_SCU_DEBUG + +config CXD56_SCU_DEBUG_WARN + bool "Warning Messages" + default n + depends on CXD56_SCU_DEBUG_ERR + +config CXD56_SCU_DEBUG_INFO + bool "Info Messages" + default n + depends on CXD56_SCU_DEBUG_WARN + +config CXD56_UDMAC + bool "DMAC support" + default y + select ARCH_DMA + ---help--- + Use DMAC for reading sensing data from SCU FIFO. +endif # CXD56_SCU + endmenu comment "Storage Options" diff --git a/arch/arm/src/cxd56xx/Make.defs b/arch/arm/src/cxd56xx/Make.defs index 3be6dd357b..c4c7abd24c 100644 --- a/arch/arm/src/cxd56xx/Make.defs +++ b/arch/arm/src/cxd56xx/Make.defs @@ -131,6 +131,10 @@ ifeq ($(CONFIG_CXD56_SPI),y) CHIP_CSRCS += cxd56_spi.c endif +ifeq ($(CONFIG_CXD56_I2C),y) +CHIP_CSRCS += cxd56_i2c.c +endif + ifeq ($(CONFIG_CXD56_DMAC),y) CHIP_CSRCS += cxd56_dmac.c endif @@ -139,6 +143,17 @@ ifeq ($(CONFIG_CXD56_PWM),y) CHIP_CSRCS += cxd56_pwm.c endif +ifeq ($(CONFIG_CXD56_SCU),y) +CHIP_CSRCS += cxd56_scu.c cxd56_scufifo.c +ifeq ($(CONFIG_CXD56_ADC),y) +CHIP_CSRCS += cxd56_adc.c +endif +ifeq ($(CONFIG_CXD56_UDMAC),y) +CHIP_CSRCS += cxd56_udmac.c +endif +endif + + ifeq ($(CONFIG_CXD56_TIMER),y) CHIP_CSRCS += cxd56_timer.c endif diff --git a/arch/arm/src/cxd56xx/cxd56_adc.c b/arch/arm/src/cxd56xx/cxd56_adc.c new file mode 100644 index 0000000000..85cff79df7 --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_adc.c @@ -0,0 +1,1065 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_adc.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "hardware/cxd56_adc.h" +#include "hardware/cxd56_scuseq.h" +#include "cxd56_clock.h" +#include "cxd56_adc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_CXD56_HPADC0_FSIZE +#define CONFIG_CXD56_HPADC0_FSIZE 64 +#endif +#ifndef CONFIG_CXD56_HPADC1_FSIZE +#define CONFIG_CXD56_HPADC1_FSIZE 64 +#endif +#ifndef CONFIG_CXD56_LPADC0_FSIZE +#define CONFIG_CXD56_LPADC0_FSIZE 16 +#endif +#ifndef CONFIG_CXD56_LPADC1_FSIZE +#define CONFIG_CXD56_LPADC1_FSIZE 16 +#endif +#ifndef CONFIG_CXD56_LPADC2_FSIZE +#define CONFIG_CXD56_LPADC2_FSIZE 16 +#endif +#ifndef CONFIG_CXD56_LPADC3_FSIZE +#define CONFIG_CXD56_LPADC3_FSIZE 16 +#endif + +#ifndef CONFIG_CXD56_HPADC0_OFFSET +#define CONFIG_CXD56_HPADC0_OFFSET 0 +#endif +#ifndef CONFIG_CXD56_HPADC1_OFFSET +#define CONFIG_CXD56_HPADC1_OFFSET 0 +#endif +#ifndef CONFIG_CXD56_LPADC0_OFFSET +#define CONFIG_CXD56_LPADC0_OFFSET 0 +#endif +#ifndef CONFIG_CXD56_LPADC1_OFFSET +#define CONFIG_CXD56_LPADC1_OFFSET 0 +#endif +#ifndef CONFIG_CXD56_LPADC2_OFFSET +#define CONFIG_CXD56_LPADC2_OFFSET 0 +#endif +#ifndef CONFIG_CXD56_LPADC3_OFFSET +#define CONFIG_CXD56_LPADC3_OFFSET 0 +#endif + +#ifndef CONFIG_CXD56_HPADC0_GAIN +#define CONFIG_CXD56_HPADC0_GAIN 0 +#endif +#ifndef CONFIG_CXD56_HPADC1_GAIN +#define CONFIG_CXD56_HPADC1_GAIN 0 +#endif +#ifndef CONFIG_CXD56_LPADC0_GAIN +#define CONFIG_CXD56_LPADC0_GAIN 0 +#endif +#ifndef CONFIG_CXD56_LPADC1_GAIN +#define CONFIG_CXD56_LPADC1_GAIN 0 +#endif +#ifndef CONFIG_CXD56_LPADC2_GAIN +#define CONFIG_CXD56_LPADC2_GAIN 0 +#endif +#ifndef CONFIG_CXD56_LPADC3_GAIN +#define CONFIG_CXD56_LPADC3_GAIN 0 +#endif + +#define ADC_BYTESPERSAMPLE 2 +#define ADC_ELEMENTSIZE 0 + +typedef enum adc_ch +{ + CH0 = 0, /* LPADC0 */ + CH1, /* LPADC1 */ + CH2, /* LPADC2 */ + CH3, /* LPADC3 */ + CH4, /* HPADC0 */ + CH5, /* HPADC1 */ + CH_MAX, +} adc_ch_t; + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure represents the state of one ADC channel */ + +struct cxd56adc_dev_s +{ + adc_ch_t ch; /* adc cnannel number */ + FAR struct seq_s *seq; /* sequencer */ + uint8_t freq; /* coefficient of adc sampling frequency */ + uint16_t fsize; /* SCU FIFO size */ + uint16_t ofst; /* offset */ + uint16_t gain; /* gain */ + uint8_t fifomode; /* fifo mode */ + struct scufifo_wm_s *wm; /* water mark */ + struct math_filter_s *filter; /* math filter */ + struct scuev_notify_s * notify; /* notify */ +}; + +/**************************************************************************** + * Static Function Prototypes + ****************************************************************************/ + +/* Character driver methods */ + +static int cxd56_adc_open(FAR struct file *filep); +static int cxd56_adc_close(FAR struct file *filep); +static ssize_t cxd56_adc_read(FAR struct file *filep, FAR char *buffer, + size_t len); +static int cxd56_adc_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* ADC interface operations */ + +static const struct file_operations g_adcops = +{ + cxd56_adc_open, /* open */ + cxd56_adc_close, /* close */ + cxd56_adc_read, /* read */ + 0, /* write */ + 0, /* seek */ + cxd56_adc_ioctl, /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + 0, /* poll */ +#endif +}; + +#if defined (CONFIG_CXD56_LPADC0) || defined (CONFIG_CXD56_LPADC0_1) || defined (CONFIG_CXD56_LPADC_ALL) +static struct cxd56adc_dev_s g_lpadc0priv = +{ + .ch = CH0, + .seq = NULL, + .freq = CONFIG_CXD56_LPADC0_FREQ, + .fsize = CONFIG_CXD56_LPADC0_FSIZE, + .ofst = CONFIG_CXD56_LPADC0_OFFSET, + .gain = CONFIG_CXD56_LPADC0_GAIN, + .wm = NULL, + .filter = NULL, + .notify = NULL, +}; +#endif + +#if defined (CONFIG_CXD56_LPADC1) || defined (CONFIG_CXD56_LPADC0_1) || defined (CONFIG_CXD56_LPADC_ALL) +static struct cxd56adc_dev_s g_lpadc1priv = +{ + .ch = CH1, + .seq = NULL, + .freq = CONFIG_CXD56_LPADC1_FREQ, + .fsize = CONFIG_CXD56_LPADC1_FSIZE, + .ofst = CONFIG_CXD56_LPADC1_OFFSET, + .gain = CONFIG_CXD56_LPADC1_GAIN, + .wm = NULL, + .filter = NULL, + .notify = NULL, +}; +#endif + +#if defined (CONFIG_CXD56_LPADC2) || defined (CONFIG_CXD56_LPADC_ALL) +static struct cxd56adc_dev_s g_lpadc2priv = +{ + .ch = CH2, + .seq = NULL, + .freq = CONFIG_CXD56_LPADC2_FREQ, + .fsize = CONFIG_CXD56_LPADC2_FSIZE, + .ofst = CONFIG_CXD56_LPADC2_OFFSET, + .gain = CONFIG_CXD56_LPADC2_GAIN, + .wm = NULL, + .filter = NULL, + .notify = NULL, +}; +#endif + +#if defined (CONFIG_CXD56_LPADC3) || defined (CONFIG_CXD56_LPADC_ALL) +static struct cxd56adc_dev_s g_lpadc3priv = +{ + .ch = CH3, + .seq = NULL, + .freq = CONFIG_CXD56_LPADC3_FREQ, + .fsize = CONFIG_CXD56_LPADC3_FSIZE, + .ofst = CONFIG_CXD56_LPADC3_OFFSET, + .gain = CONFIG_CXD56_LPADC3_GAIN, + .wm = NULL, + .filter = NULL, + .notify = NULL, +}; +#endif + +#ifdef CONFIG_CXD56_HPADC0 +static struct cxd56adc_dev_s g_hpadc0priv = +{ + .ch = CH4, + .seq = NULL, + .freq = CONFIG_CXD56_HPADC0_FREQ, + .fsize = CONFIG_CXD56_HPADC0_FSIZE, + .ofst = CONFIG_CXD56_HPADC0_OFFSET, + .gain = CONFIG_CXD56_HPADC0_GAIN, + .wm = NULL, + .filter = NULL, + .notify = NULL, +}; +#endif + +#ifdef CONFIG_CXD56_HPADC1 +static struct cxd56adc_dev_s g_hpadc1priv = +{ + .ch = CH5, + .seq = NULL, + .freq = CONFIG_CXD56_HPADC1_FREQ, + .fsize = CONFIG_CXD56_HPADC1_FSIZE, + .ofst = CONFIG_CXD56_HPADC1_OFFSET, + .gain = CONFIG_CXD56_HPADC1_GAIN, + .wm = NULL, + .filter = NULL, + .notify = NULL, +}; +#endif + +static bool adc_active[CH_MAX] = { + false, false, false, false, false, false +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: set_ofstgain + * + * Description: + * Set parameters for offset/gain. + * + ****************************************************************************/ + +static int set_ofstgain(FAR struct cxd56adc_dev_s *priv) +{ + int ret = OK; + uint32_t addr; + + if (priv->ch == CH5) + { + addr = SCUSEQ_ADC_MATH_PROC_OFST_GAIN(priv->ch + 1); + } + else + { + addr = SCUSEQ_ADC_MATH_PROC_OFST_GAIN(priv->ch); + } + + if ((priv->ofst > 0) || (priv->gain > 0)) + { + putreg32(priv->gain << 16 | priv->ofst, addr); + ret = seq_ioctl(priv->seq, 0, SCUIOC_SETOGADJUST, 0); + if (ret < 0) + { + aerr("SETOGADJUST failed. %d\n", ret); + return ret; + } + } + else + { + putreg32(0x08000000, addr); + ret = seq_ioctl(priv->seq, 0, SCUIOC_CLROGADJUST, 0); + if (ret < 0) + { + aerr("CLROGADJUST failed. %d\n", ret); + return ret; + } + } + + return ret; +} + +/**************************************************************************** + * Name: adc_start + * + * Description: + * Start ADC channel. + * + ****************************************************************************/ + +static int adc_start(adc_ch_t ch, uint8_t freq, FAR struct seq_s *seq, + int fsize, int fifomode, + struct scufifo_wm_s *wm, + struct math_filter_s *filter, + struct scuev_notify_s *notify) +{ + uint32_t *addr; + uint32_t val; + uint32_t mask; + uint32_t div; + int ret; + + if (adc_active[ch]) + { + return OK; + } + + ret = seq_ioctl(seq, 0, SCUIOC_SETFIFO, fsize); + if (ret < 0) + { + aerr("SETFIFO failed. %d\n", ret); + return ret; + } + ret = seq_ioctl(seq, 0, SCUIOC_SETFIFOMODE, fifomode); + if (ret < 0) + { + aerr("SETFIFOMODE failed. %d\n", ret); + return ret; + } + if (wm) + { + ret = seq_ioctl(seq, 0, SCUIOC_SETWATERMARK, (unsigned long)wm); + if (ret < 0) + { + aerr("SETWATERMARK failed. %d\n", ret); + return ret; + } + } + if (filter) + { + ret = seq_ioctl(seq, 0, SCUIOC_SETFILTER, (unsigned long)filter); + if (ret < 0) + { + aerr("SETFILTER failed. %d\n", ret); + return ret; + } + } + if (notify) + { + ret = seq_ioctl(seq, 0, SCUIOC_SETNOTIFY, (unsigned long)notify); + if (ret < 0) + { + aerr("SETNOTIFY failed. %d\n", ret); + return ret; + } + } + if (ch <= CH3) + { + /* LPADC.A1 LPADC_CH : todo: GPS ch */ + + val = ch; +#ifdef CONFIG_CXD56_LPADC0_1 + val = 4; +#endif +#ifdef CONFIG_CXD56_LPADC_ALL + val = 5; +#endif + putreg32(val, SCUADCIF_LPADC_A1); + + /* LPADC_D1/D4/D5/D6 ratio */ + + div = (freq <= 15) ? freq : 15; + addr = (ch == CH0) ? (uint32_t *)SCUADCIF_LPADC_D1 : + (uint32_t *)(SCUADCIF_LPADC_D4 + 4 * (ch - CH1)); + mask = 0x00000f00; + val = getreg32(addr) & ~mask; + val |= (div << 8); + putreg32(val, addr); + + /* LPADC_AT1 */ + + mask = 0x000000ff; + val = getreg32(SCUADCIF_LPADC_AT1) & ~mask; + val |= 0x00000004; + putreg32(val, SCUADCIF_LPADC_AT1); + + /* LPADC_AT0 */ + + mask = 0x00000001; + val = getreg32(SCUADCIF_LPADC_AT0) & ~mask; + putreg32(val, SCUADCIF_LPADC_AT0); + + /* power and clock */ + + div = (freq <= 15) ? 0 : freq - 15; + cxd56_lpadc_clock_enable(div); + + /* LPADC.A0 */ + + putreg32(1, SCUADCIF_LPADC_A0); + + /* LPADC.D0 */ + + putreg32(1, SCUADCIF_LPADC_D0); + } + else + { + /* HPADC.AC0 */ + +#ifndef CONFIG_CXD56_SCU_32K +#ifdef CONFIG_CXD56_SCU_RCOSC + val = 0x00000001; +#else + uint32_t xoscfreq = cxd56_get_xosc_clock(); + if (xoscfreq <= 24000000) + { + val = 0x00000000; + } + else if (xoscfreq <= 30000000) + { + val = 0x00000010; + } + else if (xoscfreq <= 45000000) + { + val = 0x00000020; + } + else + { + val = 0x00000030; + } +#endif + putreg32(val, SCUADCIF_HPADC_AC0); +#endif + + /* HPADC.AC1 */ + + putreg32(1, SCUADCIF_HPADC_AC1); + + /* HPADCn.A0 */ + + addr = (ch == CH4) ? (uint32_t *)SCUADCIF_HPADC0_A0 : + (uint32_t *)SCUADCIF_HPADC1_A0; +#ifdef CONFIG_CXD56_SCU_32K + val = 0x00000001; +#else + val = 0x00000000; +#endif + putreg32(val, addr); + + /* HPADC.DC : todo: HPADC0 16bit x 2 */ + + /* HPADCn.AT0 */ + + addr = (ch == CH4) ? (uint32_t *)SCUADCIF_HPADC0_AT0 : + (uint32_t *)SCUADCIF_HPADC1_AT0; + mask = 0x000000f1; + val = getreg32(addr) & ~mask; + val |= 0x000000c0; + putreg32(val, addr); + + /* power and clock */ + + div = (freq <= 7) ? 0 : freq - 7; + cxd56_hpadc_clock_enable(div); + + /* HPADC.A1 */ + + addr = (ch == CH4) ? (uint32_t *)SCUADCIF_HPADC0_A1 : + (uint32_t *)SCUADCIF_HPADC1_A1; + putreg32(7, addr); + + /* HPADC.A2 */ + + addr = (ch == CH4) ? (uint32_t *)SCUADCIF_HPADC0_A2 : + (uint32_t *)SCUADCIF_HPADC1_A2; + putreg32(1, addr); + + /* HPADC.D0 */ + + addr = (ch == CH4) ? (uint32_t *)SCUADCIF_HPADC0_D0 : + (uint32_t *)SCUADCIF_HPADC1_D0; + putreg32(1, addr); + + /* HPADC.D1 */ + + div = (freq <= 7) ? freq : 7; + addr = (ch == CH4) ? (uint32_t *)SCUADCIF_HPADC0_D1 : + (uint32_t *)SCUADCIF_HPADC1_D1; + mask = 0x00000700; + val = getreg32(addr) & ~mask; + val |= (div << 8); + putreg32(val, addr); + } + + ret = seq_ioctl(seq, 0, SCUIOC_START, 0); + + if (!ret) + { + if (ch <= CH3) + { + /* LPADC.D2 */ + + mask = 0x1 << ch; + val = getreg32(SCUADCIF_LPADC_D2) & ~mask; + val |= mask; + putreg32(val, SCUADCIF_LPADC_D2); + } + else + { + /* HPADC.D2 */ + + addr = (ch == CH4) ? (uint32_t *)SCUADCIF_HPADC0_D2 : + (uint32_t *)SCUADCIF_HPADC1_D2; + putreg32(1, addr); + } + adc_active[ch] = true; + } + else + { + /* todo:err case */ + } + + return ret; +} + +/**************************************************************************** + * Name: adc_stop + * + * Description: + * Stop ADC channel. + * + ****************************************************************************/ + +static int adc_stop(adc_ch_t ch, FAR struct seq_s *seq) +{ + uint32_t *addr; + uint32_t val; + uint32_t mask; + int i; + bool is_clockdisable = true; + + if (!adc_active[ch]) + { + return OK; + } + + (void) seq_ioctl(seq, 0, SCUIOC_STOP, 0); + + if (ch <= CH3) + { + /* LPADC.D2 */ + + mask = 0x1 << ch; + val = getreg32(SCUADCIF_LPADC_D2) & ~mask; + putreg32(val, SCUADCIF_LPADC_D2); + + for (i = 0; i < CH4; i++) + { + if ((i != ch) && adc_active[i]) + { + is_clockdisable = false; + break; + } + } + if (is_clockdisable) + { + cxd56_lpadc_clock_disable(); + } + } + else + { + /* HPADC.D2 */ + + addr = (ch == CH4) ? (uint32_t *)SCUADCIF_HPADC0_D2 : + (uint32_t *)SCUADCIF_HPADC1_D2; + putreg32(0, addr); + + if (((ch == CH4) && !adc_active[CH5]) || + ((ch == CH5) && !adc_active[CH4])) + { + cxd56_hpadc_clock_disable(); + } + } + + adc_active[ch] = false; + + return OK; +} + +/**************************************************************************** + * Name: adc_validcheck + * + * Description: + * Check ioctl command to pass to scu driver. + * + ****************************************************************************/ + +static bool adc_validcheck(int cmd) +{ + if ((cmd == SCUIOC_SETFILTER) || + (cmd == SCUIOC_SETNOTIFY) || + (cmd == SCUIOC_SETWATERMARK) || + (cmd == SCUIOC_SETFIFOMODE) || + (cmd == SCUIOC_DELFIFODATA)) + { + return true; + } + return false; +} + +/**************************************************************************** + * Name: cxd56_adc_open + * + * Description: + * Standard character driver open method. + * + ****************************************************************************/ + +static int cxd56_adc_open(FAR struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct cxd56adc_dev_s *priv = inode->i_private; + int ret = OK; + int type; + + DEBUGASSERT(priv != NULL); + DEBUGASSERT(priv->seq == NULL); + DEBUGASSERT(priv->ch < CH_MAX); + + type = SCU_BUS_LPADC0 + priv->ch; + + /* Open sequencer */ + + priv->seq = seq_open(SEQ_TYPE_NORMAL, type); + if (!priv->seq) + { + return -ENOENT; + } + + /* Set sample data information to sequencer */ + + seq_setsample(priv->seq, ADC_BYTESPERSAMPLE, 0, ADC_ELEMENTSIZE, false); + + /* Set offset/gain */ + + ret = set_ofstgain(priv); + if (ret < 0) + { + return ret; + } + ainfo("open ch%d freq%d scufifo%d\n", priv->ch, priv->freq, priv->fsize); + + return OK; +} + +/**************************************************************************** + * Name: cxd56_adc_close + * + * Description: + * Standard character driver close method. + * + ****************************************************************************/ + +static int cxd56_adc_close(FAR struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct cxd56adc_dev_s *priv = inode->i_private; + + DEBUGASSERT(priv != NULL); + DEBUGASSERT(priv->seq != NULL); + DEBUGASSERT(priv->ch < CH_MAX); + + /* Close sequencer */ + + seq_close(priv->seq); + priv->seq = NULL; + + if (priv->wm) + { + kmm_free(priv->wm); + priv->wm = NULL; + } + if (priv->filter) + { + kmm_free(priv->filter); + priv->filter = NULL; + } + if (priv->notify) + { + kmm_free(priv->notify); + priv->notify = NULL; + } + + return OK; +} + +/**************************************************************************** + * Name: cxd56_adc_read + * + * Description: + * Standard character driver read method. + * + ****************************************************************************/ + +static ssize_t cxd56_adc_read(FAR struct file *filep, FAR char *buffer, + size_t len) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct cxd56adc_dev_s *priv = inode->i_private; + int ret = OK; + + DEBUGASSERT(priv != NULL); + DEBUGASSERT(priv->seq != NULL); + DEBUGASSERT(priv->ch < CH_MAX); + + len = len / ADC_BYTESPERSAMPLE * ADC_BYTESPERSAMPLE; + ret = seq_read(priv->seq, 0, buffer, len); + + return ret; +} + +/**************************************************************************** + * Name: cxd56_adc_ioctl + * + * Description: + * Standard character driver ioctl method. + * + ****************************************************************************/ + +static int cxd56_adc_ioctl(FAR struct file *filep, int cmd, + unsigned long arg) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct cxd56adc_dev_s *priv = inode->i_private; + int ret = OK; + DEBUGASSERT(priv != NULL); + DEBUGASSERT(priv->seq != NULL); + DEBUGASSERT(priv->ch < CH_MAX); + + switch (cmd) + { + case ANIOC_TRIGGER: + case ANIOC_CXD56_START: + ret = adc_start(priv->ch, priv->freq, priv->seq, + priv->fsize, priv->fifomode, + priv->wm, priv->filter, priv->notify); + break; + + case ANIOC_CXD56_STOP: + ret = adc_stop(priv->ch, priv->seq); + break; + + case ANIOC_CXD56_FREQ: + priv->freq = arg; + break; + + case ANIOC_CXD56_FIFOSIZE: + priv->fsize = arg; + break; + + case SCUIOC_SETFIFOMODE: + priv->fifomode = arg; + break; + + case SCUIOC_SETWATERMARK: + if (adc_active[priv->ch] == false) /* before start */ + { + struct scufifo_wm_s *wm = (struct scufifo_wm_s *)arg; + priv->wm = (struct scufifo_wm_s *) + kmm_malloc(sizeof(struct scufifo_wm_s)); + *(priv->wm) = *wm; + } + else + { + ret = seq_ioctl(priv->seq, 0, cmd, arg); + } + break; + + case SCUIOC_SETFILTER: + if (adc_active[priv->ch] == false) /* before start */ + { + struct math_filter_s *filter = (struct math_filter_s *)arg; + priv->filter = (struct math_filter_s *) + kmm_malloc(sizeof(struct math_filter_s)); + *(priv->filter) = *filter; + } + else + { + ret = seq_ioctl(priv->seq, 0, cmd, arg); + } + break; + + case SCUIOC_SETNOTIFY: + if (adc_active[priv->ch] == false) /* before start */ + { + struct scuev_notify_s *notify = (struct scuev_notify_s *)arg; + priv->notify = (struct scuev_notify_s *) + kmm_malloc(sizeof(struct scuev_notify_s)); + *(priv->notify) = *notify; + } + else + { + ret = seq_ioctl(priv->seq, 0, cmd, arg); + } + break; + + default: + { + if (adc_validcheck(cmd)) + { + /* Redirect SCU commands */ + + ret = seq_ioctl(priv->seq, 0, cmd, arg); + } + else + { + aerr("Unrecognized cmd: %d\n", cmd); + ret = -EINVAL; + } + } + break; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: cxd56_adc_getinterval + * + * Description: + * get sampling interval of ADC. + * + * Input Parameters: + * bustype - SCU_BUS_LPADC0, SCU_BUS_LPADC1, SCU_BUS_LPADC2, SCU_BUS_LPADC3, + * SCU_BUS_HPADC0, SCU_BUS_HPADC1 + * *interval - Sampling interval + * *adjust - Adjustment value used for timestamp calculation + * + * Returned Value: + * None + * + ****************************************************************************/ + +void cxd56_adc_getinterval(int adctype, uint32_t *interval, uint16_t *adjust) +{ + uint32_t intval = 0; + uint32_t div = 0; + + DEBUGASSERT(interval != NULL && adjust != NULL); + + if ((adctype >= SCU_BUS_LPADC0) && (adctype <= SCU_BUS_LPADC3)) + { + uint32_t chmodediv = 0; + + *adjust = 0; +#ifdef CONFIG_CXD56_LPADC0_1 + chmodediv = 1; +#endif +#ifdef CONFIG_CXD56_LPADC_ALL + chmodediv = 2; +#endif + + if (adctype == SCU_BUS_LPADC0) + { +#if defined (CONFIG_CXD56_LPADC0) || defined (CONFIG_CXD56_LPADC0_1) || defined (CONFIG_CXD56_LPADC_ALL) + div = g_lpadc0priv.freq; +#endif + } + else if (adctype == SCU_BUS_LPADC1) + { +#if defined (CONFIG_CXD56_LPADC1) || defined (CONFIG_CXD56_LPADC0_1) || defined (CONFIG_CXD56_LPADC_ALL) + div = g_lpadc1priv.freq; +#endif + } + else if (adctype == SCU_BUS_LPADC2) + { +#if defined (CONFIG_CXD56_LPADC2) || defined (CONFIG_CXD56_LPADC_ALL) + div = g_lpadc2priv.freq; +#endif + } + else if (adctype == SCU_BUS_LPADC3) + { +#if defined (CONFIG_CXD56_LPADC3) || defined (CONFIG_CXD56_LPADC_ALL) + div = g_lpadc3priv.freq; +#endif + } + + *interval = 1 << (chmodediv + div); + } + else if ((adctype == SCU_BUS_HPADC0) || (adctype == SCU_BUS_HPADC1)) + { + *adjust = 1; + if (adctype == SCU_BUS_HPADC0) + { +#ifdef CONFIG_CXD56_HPADC0 + div = g_hpadc0priv.freq; +#endif + } + else if (adctype == SCU_BUS_HPADC1) + { +#ifdef CONFIG_CXD56_HPADC1 + div = g_hpadc1priv.freq; +#endif + } + +#ifdef CONFIG_CXD56_SCU_32K + *interval = 1 << div; +#else + uint32_t freq = 0; +#ifdef CONFIG_CXD56_SCU_RCOSC + freq = cxd56_get_rcosc_clock(); +#else + freq = cxd56_get_xosc_clock(); + if (freq <= 24000000) + { + freq /= 2; + } + else if (freq <= 30000000) + { + freq /= 3; + } + else if (freq <= 45000000) + { + freq /= 4; + } + else + { + freq /= 6; + } +#endif + if (freq > 0) + { + intval = (32768 << (2 + div + 1)) / freq; + if (intval & 1) + { + *interval = (intval >> 1) + 1; + } + else + { + *interval = (intval >> 1); + } + } +#endif + } +} + +/**************************************************************************** + * Name: cxd56_adcinitialize + * + * Description: + * Initialize ADC channel for use with the upper_level ADC driver. + * + * Input Parameters: + * channel - adc channel number. + * + * Returned Value: + * On success, a pointer to the CXD56 lower half ADC driver is returned. + * NULL is returned on any failure. + * + ****************************************************************************/ + +int cxd56_adcinitialize(void) +{ + int ret; + + /* Avoid warnings when no ADC options enabled */ + + (void) ret; + +#if defined (CONFIG_CXD56_LPADC0) || defined (CONFIG_CXD56_LPADC0_1) || defined (CONFIG_CXD56_LPADC_ALL) + ret = register_driver("/dev/lpadc0", &g_adcops, 0666, &g_lpadc0priv); + if (ret < 0) + { + aerr("Failed to register driver(lpadc0): %d\n", ret); + return ret; + } +#endif +#if defined (CONFIG_CXD56_LPADC1) || defined (CONFIG_CXD56_LPADC0_1) || defined (CONFIG_CXD56_LPADC_ALL) + ret = register_driver("/dev/lpadc1", &g_adcops, 0666, &g_lpadc1priv); + if (ret < 0) + { + aerr("Failed to register driver(lpadc1): %d\n", ret); + return ret; + } +#endif +#if defined (CONFIG_CXD56_LPADC2) || defined (CONFIG_CXD56_LPADC_ALL) + ret = register_driver("/dev/lpadc2", &g_adcops, 0666, &g_lpadc2priv); + if (ret < 0) + { + aerr("Failed to register driver(lpadc2): %d\n", ret); + return ret; + } +#endif +#if defined (CONFIG_CXD56_LPADC3) || defined (CONFIG_CXD56_LPADC_ALL) + ret = register_driver("/dev/lpadc3", &g_adcops, 0666, &g_lpadc3priv); + if (ret < 0) + { + aerr("Failed to register driver(lpadc3): %d\n", ret); + return ret; + } +#endif +#ifdef CONFIG_CXD56_HPADC0 + ret = register_driver("/dev/hpadc0", &g_adcops, 0666, &g_hpadc0priv); + if (ret < 0) + { + aerr("Failed to register driver(hpadc0): %d\n", ret); + return ret; + } +#endif +#ifdef CONFIG_CXD56_HPADC1 + ret = register_driver("/dev/hpadc1", &g_adcops, 0666, &g_hpadc1priv); + if (ret < 0) + { + aerr("Failed to register driver(hpadc1): %d\n", ret); + return ret; + } +#endif + + return OK; +} diff --git a/arch/arm/src/cxd56xx/cxd56_adc.h b/arch/arm/src/cxd56xx/cxd56_adc.h new file mode 100644 index 0000000000..8531d5c79c --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_adc.h @@ -0,0 +1,79 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_adc.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_ADC_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_ADC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#ifndef __ASSEMBLY__ +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: cxd56_adc_getinterval + * + * Description: + * + ****************************************************************************/ + +#ifdef CONFIG_CXD56_ADC +void cxd56_adc_getinterval(int adctype, uint32_t *interval, uint16_t *adjust); +#else +#define cxd56_adc_getinterval(adctype, interval, adjust) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_ADC_H */ diff --git a/arch/arm/src/cxd56xx/cxd56_dmac.h b/arch/arm/src/cxd56xx/cxd56_dmac.h index 1cc55d9816..fe84e393b3 100644 --- a/arch/arm/src/cxd56xx/cxd56_dmac.h +++ b/arch/arm/src/cxd56xx/cxd56_dmac.h @@ -33,9 +33,6 @@ * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************/ -/** - * @file cxd56_dmac.h - */ #ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_DMAC_H #define __ARCH_ARM_SRC_CXD56XX_CXD56_DMAC_H diff --git a/arch/arm/src/cxd56xx/cxd56_dmac_common.h b/arch/arm/src/cxd56xx/cxd56_dmac_common.h new file mode 100644 index 0000000000..a642c554e8 --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_dmac_common.h @@ -0,0 +1,79 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_dmac_common.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_DMAC_COMMON_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_DMAC_COMMON_H + +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* DMA_HANDLE provides an opaque are reference that can be used to represent a + * DMA channel. + */ + +typedef FAR void *DMA_HANDLE; + +/* Description: + * This is the type of the callback that is used to inform the user of the + * completion of the DMA. + * + * Input Parameters: + * handle - Refers tot he DMA channel or stream + * status - A bit encoded value that provides the completion status. + * See the DMASTATUS_* definitions above. + * arg - A user-provided value that was provided when cxd56_dmastart() + * was called. + */ + +typedef void (*dma_callback_t)(DMA_HANDLE handle, uint8_t status, void *arg); + +/* Type of 'config' argument passed to cxd56_rxdmasetup() and + * cxd56_txdmasetup. + * See CXD56_DMA_* encodings above. If these encodings exceed 16-bits, then + * this should be changed to a uint32_t. + */ + +typedef struct { + uint16_t channel_cfg; + uint8_t dest_width; + uint8_t src_width; +} dma_config_t; + +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_DMAC_COMMON_H */ diff --git a/arch/arm/src/cxd56xx/cxd56_i2c.c b/arch/arm/src/cxd56xx/cxd56_i2c.c new file mode 100644 index 0000000000..b823e09298 --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_i2c.c @@ -0,0 +1,1110 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_i2c.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + * + ****************************************************************************/ +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "cxd56_clock.h" +#include "cxd56_i2c.h" +#include "hardware/cxd56_i2c.h" +#include "cxd56_pinconfig.h" + +#if defined(CONFIG_CXD56_I2C0_SCUSEQ) || defined(CONFIG_CXD56_I2C1_SCUSEQ) +#include +#endif + +#ifdef CONFIG_CXD56_I2C + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define I2C_TIMEOUT (20*1000/CONFIG_USEC_PER_TICK) /* 20 mS */ + +#define I2C_DEFAULT_FREQUENCY 400000 +#define I2C_FIFO_MAX_SIZE 32 + +#define I2C_INTR_ENABLE ((INTR_STOP_DET) | \ + (INTR_TX_ABRT) | \ + (INTR_TX_OVER) | \ + (INTR_RX_OVER) | \ + (INTR_RX_UNDER)) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct cxd56_i2cdev_s +{ + struct i2c_master_s dev; /* Generic I2C device */ + unsigned int base; /* Base address of registers */ + uint16_t irqid; /* IRQ for this device */ + int8_t port; /* Port number */ + uint32_t baseFreq; /* branch frequency */ + + sem_t mutex; /* Only one thread can access at a time */ + sem_t wait; /* Place to wait for transfer completion */ + WDOG_ID timeout; /* watchdog to timeout when bus hung */ + uint32_t frequency; /* Current I2C frequency */ + ssize_t reg_buff_offset; + ssize_t rw_size; + + struct i2c_msg_s *msgs; + + int error; /* Error status of each transfers */ + int refs; /* Reference count */ +}; + +/* Channel 0 as SCU_I2C0 + * Channel 1 as SCU_I2C1 + * Channel 2 as I2CM + */ + +#ifdef CONFIG_CXD56_I2C0 +static struct cxd56_i2cdev_s g_i2c0dev = +{ + .port = 0, + .base = CXD56_SCU_I2C0_BASE, + .irqid = CXD56_IRQ_SCU_I2C0, + .refs = 0, +}; +#endif +#ifdef CONFIG_CXD56_I2C1 +static struct cxd56_i2cdev_s g_i2c1dev = +{ + .port = 1, + .base = CXD56_SCU_I2C1_BASE, + .irqid = CXD56_IRQ_SCU_I2C1, + .refs = 0, +}; +#endif +#ifdef CONFIG_CXD56_I2C2 +static struct cxd56_i2cdev_s g_i2c2dev = +{ + .port = 2, + .base = CXD56_I2CM_BASE, + .irqid = CXD56_IRQ_I2CM, + .refs = 0, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static inline uint32_t i2c_reg_read(struct cxd56_i2cdev_s *priv, + uint32_t offset); +static inline void i2c_reg_write(struct cxd56_i2cdev_s *priv, uint32_t offset, + uint32_t val); +static inline void i2c_reg_rmw(struct cxd56_i2cdev_s *dev, uint32_t offset, + uint32_t val, uint32_t mask); + +static int cxd56_i2c_disable(struct cxd56_i2cdev_s *priv); +static void cxd56_i2c_enable(struct cxd56_i2cdev_s *priv); + +static int cxd56_i2c_interrupt(int irq, FAR void *context, FAR void *arg); +static void cxd56_i2c_timeout(int argc, uint32_t arg, ...); +static void cxd56_i2c_setfrequency(struct cxd56_i2cdev_s *priv, + uint32_t frequency); +static int cxd56_i2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count); +#ifdef CONFIG_I2C_RESET +static int cxd56_i2c_reset(FAR struct i2c_master_s * dev); +#endif +#if defined(CONFIG_CXD56_I2C0_SCUSEQ) || defined(CONFIG_CXD56_I2C1_SCUSEQ) +static int cxd56_i2c_transfer_scu(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count); +#endif + +/**************************************************************************** + * Name: cxd56_i2c_pincontrol + * + * Description: + * Configure the I2C pin + * + * Input Parameter: + * on - true: enable pin, false: disable pin + * + ****************************************************************************/ + +static void cxd56_i2c_pincontrol(int ch, bool on) +{ + switch (ch) + { +#ifdef CONFIG_CXD56_I2C0 + case 0: + if (on) + { + CXD56_PIN_CONFIGS(PINCONFS_I2C0); + } + else + { + CXD56_PIN_CONFIGS(PINCONFS_I2C0_GPIO); + } + break; +#endif /* CONFIG_CXD56_I2C0 */ + +#ifdef CONFIG_CXD56_I2C1 + case 1: + if (on) + { + CXD56_PIN_CONFIGS(PINCONFS_PWMB_I2C1); + } + else + { + CXD56_PIN_CONFIGS(PINCONFS_PWMB_GPIO); + } + break; +#endif /* CONFIG_CXD56_I2C1 */ + +#ifdef CONFIG_CXD56_I2C2 + case 2: + if (on) + { + CXD56_PIN_CONFIGS(PINCONFS_SPI0B_I2C2); + } + else + { + CXD56_PIN_CONFIGS(PINCONFS_SPI0B_GPIO); + } + break; +#endif /* CONFIG_CXD56_I2C2 */ + + default: + break; + } +} + +/**************************************************************************** + * I2C device operations + ****************************************************************************/ + +struct i2c_ops_s cxd56_i2c_ops = +{ + .transfer = cxd56_i2c_transfer, +#ifdef CONFIG_I2C_RESET + .reset = cxd56_i2c_reset, +#endif +}; + +#if defined(CONFIG_CXD56_I2C0_SCUSEQ) || defined(CONFIG_CXD56_I2C1_SCUSEQ) +struct i2c_ops_s cxd56_i2c_scu_ops = +{ + .transfer = cxd56_i2c_transfer_scu, +#ifdef CONFIG_I2C_RESET + .reset = cxd56_i2c_reset, +#endif +}; +#endif + +/**************************************************************************** + * Name: cxd56_i2c_setfrequency + * + * Description: + * Set the frequency for the next transfer + * + ****************************************************************************/ + +static void cxd56_i2c_setfrequency(struct cxd56_i2cdev_s *priv, + uint32_t frequency) +{ + int32_t lcnt; + int32_t hcnt; + uint64_t lcnt64; + uint64_t hcnt64; + uint64_t speed; + uint64_t tLow; + uint64_t tHigh; + uint32_t base = cxd56_get_i2c_baseclock(priv->port); + uint32_t spklen; + + ASSERT(base); + + if ((priv->frequency == frequency) && (priv->baseFreq == base)) + { + return; + } + + priv->frequency = frequency; + priv->baseFreq = base; + + base /= 1000; + + switch (frequency) + { + case 100000: + tLow = 4700000; + tHigh = 4000000; + break; + + case 400000: + tLow = 1300000; + tHigh = 600000; + break; + + case 1000000: + tLow = 500000; + tHigh = 260000; + break; + + default: + return; + } + + if (frequency > 100000) + { + if (base < 20032) + { + spklen = 1; + } + else if (base < 40064) + { + spklen = 2; + } + else + { + spklen = 3; + } + } + else + { + spklen = 1; + } + + lcnt64 = (tLow + 6500ull / 20000ull) * base; + lcnt = ((lcnt64 + 999999999ull) / 1000000000ull) - 1; /* ceil */ + lcnt = lcnt < 8 ? 8 : lcnt; + + hcnt64 = (tHigh - 6500ull) * base; + hcnt = ((hcnt64 + 999999999ull) / 1000000000ull) - 6 - spklen; /* ceil */ + hcnt = hcnt < 6 ? 6 : hcnt; + + speed = + 1000000000000000000ull / + (((lcnt + 1) * 1000000000000ull + + (hcnt + 6 + spklen) * 1000000000000ull) / base + + 20000ull / 1000ull * 1000000ull); + + if (speed > (frequency * 1000ull)) + { + uint64_t adj; + adj = ((1000000000000000000ull / (frequency * 1000ull)) - + (1000000000000000000ull / speed)) * + base; + hcnt += (adj + 999999999999ull) / 1000000000000ull; + } + + /* use FS register in SS and FS mode */ + + i2c_reg_write(priv, CXD56_IC_FS_SCL_HCNT, hcnt); + i2c_reg_write(priv, CXD56_IC_FS_SCL_LCNT, lcnt); + i2c_reg_rmw(priv, CXD56_IC_CON, IC_SPEED_FS, IC_MAX_SPEED_MODE); + + i2c_reg_write(priv, CXD56_IC_FS_SPKLEN, spklen); +} + +/**************************************************************************** + * Name: cxd56_i2c_timeout + * + * Description: + * Watchdog timer for timeout of I2C operation + * + ****************************************************************************/ + +static void cxd56_i2c_timeout(int argc, uint32_t arg, ...) +{ + struct cxd56_i2cdev_s *priv = (struct cxd56_i2cdev_s *)arg; + irqstate_t flags = enter_critical_section(); + + priv->error = -ENODEV; + sem_post(&priv->wait); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: cxd56_i2c_drainrxfifo + * + * Description: + * Receive I2C data + * + ****************************************************************************/ + +static void cxd56_i2c_drainrxfifo(struct cxd56_i2cdev_s *priv) +{ + struct i2c_msg_s *msg = priv->msgs; + uint32_t status; + uint32_t dat; + ssize_t i; + + DEBUGASSERT(msg != NULL); + + status = i2c_reg_read(priv, CXD56_IC_STATUS); + + for (i = 0; i < priv->rw_size && status & STATUS_RFNE; i++) + { + dat = i2c_reg_read(priv, CXD56_IC_DATA_CMD); + msg->buffer[priv->reg_buff_offset + i] = dat & 0xff; + status = i2c_reg_read(priv, CXD56_IC_STATUS); + } + + priv->reg_buff_offset += priv->rw_size; +} + +/**************************************************************************** + * Name: cxd56_i2c_interrupt + * + * Description: + * The I2C Interrupt Handler + * + ****************************************************************************/ + +static int cxd56_i2c_interrupt(int irq, FAR void *context, FAR void *arg) +{ + FAR struct cxd56_i2cdev_s *priv = (FAR struct cxd56_i2cdev_s *)arg; + uint32_t state; + int ret; + + state = i2c_reg_read(priv, CXD56_IC_INTR_STAT); + + if (state & INTR_TX_ABRT) + { + i2c_reg_read(priv, CXD56_IC_CLR_TX_ABRT); + priv->error = -ENODEV; + } + + if (state & INTR_TX_OVER) + { + i2c_reg_read(priv, CXD56_IC_CLR_TX_OVER); + priv->error = -EIO; + } + + if (state & INTR_RX_OVER) + { + i2c_reg_read(priv, CXD56_IC_CLR_RX_OVER); + priv->error = -EIO; + } + + if (state & INTR_RX_UNDER) + { + i2c_reg_read(priv, CXD56_IC_CLR_RX_UNDER); + priv->error = -EIO; + } + + if (state & INTR_TX_EMPTY) + { + /* TX_EMPTY is automatically cleared by hardware + * when the buffer level goes above the threshold. + */ + + i2c_reg_rmw(priv, CXD56_IC_INTR_MASK, 0, INTR_TX_EMPTY); + } + + if (state & INTR_RX_FULL) + { + /* RX_FULL is automatically cleared by hardware + * when the buffer level goes below the threshold. + */ + + i2c_reg_rmw(priv, CXD56_IC_INTR_MASK, 0, INTR_RX_FULL); + cxd56_i2c_drainrxfifo(priv); + } + + if (state & INTR_STOP_DET) + { + i2c_reg_read(priv, CXD56_IC_CLR_STOP_DET); + } + + if ((priv->error) || (state & INTR_TX_EMPTY) || (state & INTR_RX_FULL)) + { + /* Failure of wd_cancel() means that the timer expired. + * In this case, sem_post() has already been called. + * Therefore, call sem_post() only when wd_cancel() succeeds. + */ + + ret = wd_cancel(priv->timeout); + if (ret == OK) + { + sem_post(&priv->wait); + } + } + + return OK; +} + +/**************************************************************************** + * Name: cxd56_i2c_receive + * + * Description: + * Receive data from I2C bus. + * Prohibit all interrupt because the STOP condition might happen + * if the interrupt occurs when the writing request. + * Actual receiving data is in RX_FULL interrupt handler. + * + * TODO : The argument "last" is not used. + ****************************************************************************/ + +static int cxd56_i2c_receive(struct cxd56_i2cdev_s *priv, int last) +{ + struct i2c_msg_s *msg = priv->msgs; + int i; + int en; + ssize_t msg_length; + irqstate_t flags; + + priv->reg_buff_offset = 0; + + DEBUGASSERT(msg != NULL); + + for (msg_length = msg->length; msg_length > 0; msg_length -= priv->rw_size) + { + if (msg_length <= I2C_FIFO_MAX_SIZE) + { + priv->rw_size = msg_length; + en = 1; + } + else + { + priv->rw_size = I2C_FIFO_MAX_SIZE; + en = 0; + } + + /* update threshold value of the receive buffer */ + + i2c_reg_write(priv, CXD56_IC_RX_TL, priv->rw_size - 1); + + for (i = 0; i < priv->rw_size - 1; i++) + { + i2c_reg_write(priv, CXD56_IC_DATA_CMD, CMD_READ); + } + + flags = enter_critical_section(); + wd_start(priv->timeout, I2C_TIMEOUT, cxd56_i2c_timeout, 1, + (uint32_t)priv); + + /* Set stop flag for indicate the last data */ + + i2c_reg_write(priv, CXD56_IC_DATA_CMD, CMD_READ | (en ? CMD_STOP : 0)); + + i2c_reg_rmw(priv, CXD56_IC_INTR_MASK, INTR_RX_FULL, INTR_RX_FULL); + leave_critical_section(flags); + sem_wait(&priv->wait); + + if (priv->error != OK) + { + break; + } + } + + return 0; +} + +/**************************************************************************** + * Name: cxd56_i2c_send + * + * Description: + * Send data to I2C bus. + * + ****************************************************************************/ + +static int cxd56_i2c_send(struct cxd56_i2cdev_s *priv, int last) +{ + struct i2c_msg_s *msg = priv->msgs; + ssize_t i; + irqstate_t flags; + + DEBUGASSERT(msg != NULL); + + for (i = 0; i < msg->length - 1; i++) + { + while (!(i2c_reg_read(priv, CXD56_IC_STATUS) & STATUS_TFNF)); + + i2c_reg_write(priv, CXD56_IC_DATA_CMD, (uint32_t)msg->buffer[i]); + } + + while (!(i2c_reg_read(priv, CXD56_IC_STATUS) & STATUS_TFNF)); + + flags = enter_critical_section(); + wd_start(priv->timeout, I2C_TIMEOUT, cxd56_i2c_timeout, 1, (uint32_t)priv); + i2c_reg_write(priv, CXD56_IC_DATA_CMD, + (uint32_t)msg->buffer[i] | (last ? CMD_STOP : 0)); + + /* Enable TX_EMPTY interrupt for determine transfer done. */ + + i2c_reg_rmw(priv, CXD56_IC_INTR_MASK, INTR_TX_EMPTY, INTR_TX_EMPTY); + leave_critical_section(flags); + + sem_wait(&priv->wait); + + return 0; +} + +/**************************************************************************** + * Name: cxd56_i2c_transfer + * + * Description: + * Perform a sequence of I2C transfers + * + * TODO: Multiple i2c_msg_s read operations with the same address are not + * currently guaranteed. + ****************************************************************************/ + +static int cxd56_i2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count) +{ + struct cxd56_i2cdev_s *priv = (struct cxd56_i2cdev_s *)dev; + int i; + int ret = 0; + int semval = 0; + int addr = -1; + static int wostop = 0; + + DEBUGASSERT(dev != NULL); + + /* Get exclusive access to the I2C bus */ + + sem_wait(&priv->mutex); + + /* Check wait semaphore value. If the value is not 0, the transfer can not + * be performed normally. + */ + + ret = sem_getvalue(&priv->wait, &semval); + DEBUGASSERT(ret == OK && semval == 0); + + /* Disable clock gating (clock enable) */ + + cxd56_i2c_clock_gate_disable(priv->port); + + for (i = 0; i < count; i++, msgs++) + { + /* Pass msg descriptor via device context */ + + priv->msgs = msgs; + priv->error = OK; + + if ((addr != msgs->addr) && !wostop) + { + cxd56_i2c_disable(priv); + + cxd56_i2c_setfrequency(priv, msgs->frequency); + + i2c_reg_rmw(priv, CXD56_IC_CON, IC_RESTART_EN, IC_RESTART_EN); + i2c_reg_write(priv, CXD56_IC_TAR, msgs->addr & 0x7f); + + cxd56_i2c_enable(priv); + addr = msgs->addr; + } + + if (msgs->flags & I2C_M_NOSTOP) + { + /* Don't send stop condition even if the last data */ + + wostop = 1; + } + else + { + wostop = 0; + } + + if (msgs->flags & I2C_M_READ) + { + ret = cxd56_i2c_receive(priv, (wostop) ? 0 : (i + 1 == count)); + } + else + { + ret = cxd56_i2c_send(priv, (wostop) ? 0 : (i + 1 == count)); + } + + if (ret < 0) + { + break; + } + + if (priv->error != OK) + { + ret = priv->error; + break; + } + + /* Clear msg descriptor for prevent illegal access in interrupt */ + + priv->msgs = NULL; + } + + if (!wostop) + { + cxd56_i2c_disable(priv); + } + + /* Enable clock gating (clock disable) */ + + cxd56_i2c_clock_gate_enable(priv->port); + + sem_post(&priv->mutex); + return ret; +} + +/**************************************************************************** + * Name: cxd56_i2c_reset + * + * Description: + * Perform an I2C bus reset in an attempt to break loose stuck I2C devices. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_I2C_RESET +static int cxd56_i2c_reset(FAR struct i2c_master_s *dev) +{ + return OK; +} +#endif /* CONFIG_I2C_RESET */ + +/**************************************************************************** + * Name: cxd56_i2c_transfer_scu + * + * Description: + * Perform a sequence of I2C transfers with scu oneshot sequencer. + * + ****************************************************************************/ + +#if defined(CONFIG_CXD56_I2C0_SCUSEQ) || defined(CONFIG_CXD56_I2C1_SCUSEQ) + +static int cxd56_i2c_scurecv(int port, int addr, uint8_t *buf, ssize_t buflen) +{ + uint16_t inst[2]; + int instn; + int len0; + int len1; + ssize_t rem; + int ret = OK; + + /* Ignore buffer is NULL */ + + if (buf == NULL) + { + return OK; + } + + rem = buflen; + while (rem) + { + len0 = rem > 8 ? 8 : rem; + rem -= len0; + len1 = rem > 8 ? 8 : rem; + rem -= len1; + + inst[0] = SCU_INST_RECV(len0); + if (len1) + { + inst[1] = SCU_INST_RECV(len1); + instn = 2; + } + else + { + instn = 1; + } + + if (rem == 0) + { + inst[instn - 1] |= SCU_INST_LAST; + } + + ret = scu_i2ctransfer(port, addr, inst, instn, buf, len0 + len1); + if (ret < 0) + { + syslog(LOG_ERR, "I2C recieve failed. port %d addr %d\n", + port, addr); + break; + } + + buf += len0 + len1; + } + + return ret; +} + +static int cxd56_i2c_scusend(int port, int addr, uint8_t *buf, ssize_t buflen) +{ + uint16_t inst[12]; + ssize_t rem; + int i; + int ret = OK; + + rem = buflen; + + while (rem) + { + for (i = 0; i < 12 && rem > 0; i++) + { + inst[i] = SCU_INST_SEND(*buf++); + rem--; + } + + if (rem == 0) + { + inst[i - 1] |= SCU_INST_LAST; + } + + if (i > 0) + { + ret = scu_i2ctransfer(port, addr, inst, i, NULL, i); + if (ret < 0) + { + syslog(LOG_ERR, "I2C send failed. port %d addr %d\n", + port, addr); + break; + } + } + } + + return ret; +} + +static int cxd56_i2c_transfer_scu(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count) +{ + FAR struct cxd56_i2cdev_s *priv = (FAR struct cxd56_i2cdev_s *)dev; + ssize_t len = 0; + uint8_t *buf = NULL; + uint8_t addr = msgs->addr; + int i; + int ret = 0; + + DEBUGASSERT(dev != NULL); + + /* Get exclusive access to the I2C bus */ + + sem_wait(&priv->mutex); + + /* Apply frequency for request msgs */ + + if (priv->frequency != msgs->frequency) + { + cxd56_i2c_clock_gate_disable(priv->port); + cxd56_i2c_disable(priv); + cxd56_i2c_setfrequency(priv, msgs->frequency); + i2c_reg_rmw(priv, CXD56_IC_CON, IC_RESTART_EN, IC_RESTART_EN); + i2c_reg_write(priv, CXD56_IC_TAR, msgs->addr & 0x7f); + cxd56_i2c_enable(priv); + cxd56_i2c_clock_gate_enable(priv->port); + + priv->frequency = msgs->frequency; + } + + for (i = 0; i < count; i++, msgs++) + { + len = msgs->length; + buf = msgs->buffer; + + if (msgs->flags & I2C_M_READ) + { + ret = cxd56_i2c_scurecv(priv->port, addr, buf, len); + } + else + { + ret = cxd56_i2c_scusend(priv->port, addr, buf, len); + } + + if (ret < 0) + { + break; + } + } + + sem_post(&priv->mutex); + + return ret; +} +#endif + +static inline uint32_t i2c_reg_read(struct cxd56_i2cdev_s *priv, + uint32_t offset) +{ + return getreg32(priv->base + offset); +} + +static inline void i2c_reg_write(struct cxd56_i2cdev_s *priv, uint32_t offset, + uint32_t val) +{ + putreg32(val, priv->base + offset); +} + +static inline void i2c_reg_rmw(struct cxd56_i2cdev_s *priv, uint32_t offset, + uint32_t val, uint32_t mask) +{ + uint32_t regval; + regval = getreg32(priv->base + offset); + putreg32((regval & ~mask) | val, priv->base + offset); +} + +static int cxd56_i2c_disable(struct cxd56_i2cdev_s *priv) +{ + int retry = 25000; + uint32_t stat; + + /* disable all interrupt */ + + i2c_reg_write(priv, CXD56_IC_INTR_MASK, 0x0); + + /* clear all interrupt status */ + + i2c_reg_read(priv, CXD56_IC_CLR_INTR); + i2c_reg_write(priv, CXD56_IC_ENABLE, 0); + + do + { + stat = i2c_reg_read(priv, CXD56_IC_ENABLE_STATUS); + } + while (--retry && (stat & ESTATUS_IC_EN)); + + if (!retry) + { + i2cerr("i2c wait timeout.\n"); + return -EBUSY; + } + + /* clear all interrupt status again */ + + i2c_reg_read(priv, CXD56_IC_CLR_INTR); + + return 0; +} + +static void cxd56_i2c_enable(struct cxd56_i2cdev_s *priv) +{ + i2c_reg_write(priv, CXD56_IC_INTR_MASK, I2C_INTR_ENABLE); + i2c_reg_write(priv, CXD56_IC_ENABLE, 1); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: cxd56_i2cbus_initialize + * + * Description: + * Initialise an I2C device + * + ****************************************************************************/ + +struct i2c_master_s *cxd56_i2cbus_initialize(int port) +{ + struct cxd56_i2cdev_s *priv; + + irqstate_t flags; + + flags = enter_critical_section(); + +#ifdef CONFIG_CXD56_I2C0 + if (port == 0) + { + priv = &g_i2c0dev; +# ifndef CONFIG_CXD56_I2C0_SCUSEQ + priv->dev.ops = &cxd56_i2c_ops; +# else + priv->dev.ops = &cxd56_i2c_scu_ops; +# endif + } + else +#endif +#ifdef CONFIG_CXD56_I2C1 + if (port == 1) + { + priv = &g_i2c1dev; +# ifndef CONFIG_CXD56_I2C1_SCUSEQ + priv->dev.ops = &cxd56_i2c_ops; +# else + priv->dev.ops = &cxd56_i2c_scu_ops; +# endif + } + else +#endif +#ifdef CONFIG_CXD56_I2C2 + if (port == 2) + { + priv = &g_i2c2dev; + priv->dev.ops = &cxd56_i2c_ops; + } + else +#endif + { + leave_critical_section(flags); + i2cerr("I2C Only support 0,1,2\n"); + return NULL; + } + + priv->refs++; + + /* Test if already initialized or not */ + + if (1 < priv->refs) + { + leave_critical_section(flags); + return &priv->dev; + } + + priv->port = port; + priv->frequency = 0; + + cxd56_i2c_clock_enable(priv->port); + priv->baseFreq = cxd56_get_i2c_baseclock(priv->port); + + cxd56_i2c_disable(priv); + + i2c_reg_write(priv, CXD56_IC_INTR_MASK, 0x00); + i2c_reg_read(priv, CXD56_IC_CLR_INTR); + + /* set threshold level of the Rx/Tx FIFO */ + + i2c_reg_write(priv, CXD56_IC_RX_TL, 0xff); + i2c_reg_write(priv, CXD56_IC_TX_TL, 0); + + /* set hold time for margin */ + + i2c_reg_write(priv, CXD56_IC_SDA_HOLD, 1); + + i2c_reg_write(priv, CXD56_IC_CON, + (IC_SLAVE_DISABLE | IC_MASTER_MODE | IC_TX_EMPTY_CTRL)); + cxd56_i2c_setfrequency(priv, I2C_DEFAULT_FREQUENCY); + + leave_critical_section(flags); + + /* Configure pin */ + + cxd56_i2c_pincontrol(port, true); + + sem_init(&priv->mutex, 0, 1); + sem_init(&priv->wait, 0, 0); + + priv->timeout = wd_create(); + + /* Attach Interrupt Handler */ + + irq_attach(priv->irqid, cxd56_i2c_interrupt, priv); + + /* Enable Interrupt Handler */ + + up_enable_irq(priv->irqid); + + /* Enable Interrupt in SCU */ + + if (port == 0 || port == 1) + { + putreg32(getreg32(CXD56_SCU_BASE + 0x400) | (1u << (port + 1)), + CXD56_SCU_BASE + 0x400); + } + + /* Enable clock gating (clock disable) */ + + cxd56_i2c_clock_gate_enable(port); + + return &priv->dev; +} + +/**************************************************************************** + * Name: cxd56_i2cbus_uninitialize + * + * Description: + * Uninitialise an I2C device + * + ****************************************************************************/ + +int cxd56_i2cbus_uninitialize(FAR struct i2c_master_s *dev) +{ + struct cxd56_i2cdev_s *priv = (struct cxd56_i2cdev_s *)dev; + + /* Decrement reference count and check for underflow */ + + if (priv->refs == 0) + { + return ERROR; + } + + if (--priv->refs) + { + return OK; + } + + /* Configure pin */ + + cxd56_i2c_pincontrol(priv->port, false); + + /* Disable clock gating (clock enable) */ + + cxd56_i2c_clock_gate_disable(priv->port); + + cxd56_i2c_disable(priv); + cxd56_i2c_clock_disable(priv->port); + + up_disable_irq(priv->irqid); + irq_detach(priv->irqid); + + wd_delete(priv->timeout); + priv->timeout = NULL; + sem_destroy(&priv->mutex); + sem_destroy(&priv->wait); + + return OK; +} + +#endif diff --git a/arch/arm/src/cxd56xx/cxd56_i2c.h b/arch/arm/src/cxd56xx/cxd56_i2c.h new file mode 100644 index 0000000000..256e00279c --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_i2c.h @@ -0,0 +1,102 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_i2c.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_I2C_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_I2C_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "hardware/cxd56_i2c.h" + +#ifndef __ASSEMBLY__ +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: cxd56_i2cbus_initialize + * + * Description: + * Initialize the selected I2C port. And return a unique instance of struct + * struct i2c_master_s. This function may be called to obtain multiple + * instances of the interface, each of which may be set up with a + * different frequency and slave address. + * + * Input Parameter: + * Port number (for hardware that has multiple I2C interfaces) + * + * Returned Value: + * Valid I2C device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct i2c_master_s *cxd56_i2cbus_initialize(int port); + +/**************************************************************************** + * Name: cxd56_i2cbus_uninitialize + * + * Description: + * De-initialize the selected I2C port, and power down the device. + * + * Input Parameter: + * Device structure as returned by the cxd56_i2cbus_initialize() + * + * Returned Value: + * OK on success, ERROR when internal reference count mismatch or dev + * points to invalid hardware device. + * + ****************************************************************************/ + +int cxd56_i2cbus_uninitialize(FAR struct i2c_master_s *dev); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_I2C_H */ diff --git a/arch/arm/src/cxd56xx/cxd56_scu.c b/arch/arm/src/cxd56xx/cxd56_scu.c new file mode 100644 index 0000000000..6a1b60cb8e --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_scu.c @@ -0,0 +1,3499 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_scu.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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 files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "chip.h" +#include "up_arch.h" + +#include "cxd56_scufifo.h" +#include "cxd56_clock.h" +#include "cxd56_adc.h" + +#ifdef CONFIG_CXD56_UDMAC +#include "cxd56_udmac.h" +#include +#endif + +#include "hardware/cxd56_scu.h" +#include "hardware/cxd56_scuseq.h" +#include "hardware/cxd56_scufifo.h" + +/* SCU firmware (iSoP) binary */ + +#include "hardware/cxd5602_isop.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_CXD56_SCU_DEBUG_ERR +#define scuerr(fmt, ...) syslog(LOG_ERR, fmt, ## __VA_ARGS__) +#else +#define scuerr(x, ...) +#endif +#ifdef CONFIG_CXD56_SCU_DEBUG_WARN +#define scuwarn(fmt, ...) syslog(LOG_WARN, fmt, ## __VA_ARGS__) +#else +#define scuwarn(x, ...) +#endif +#ifdef CONFIG_CXD56_SCU_DEBUG_INFO +#define scuinfo(fmt, ...) syslog(LOG_INFO, fmt, ## __VA_ARGS__) +#else +#define scuinfo(x, ...) +#endif + +/* Sequencer has 128 instruction area (16bits/inst) + * We allocate statically 12 instructions for each sequencers. + */ + +#define INSTRUCTION_PER_SEQ 12 + +/* Sequencer request code */ + +#define REQ_DONE 3 +#define REQ_SLEEP 4 +#define REQ_STOP 5 + +/* Disable decimation by set 15 to ratio (N bit field) */ + +#define DECIMATION_OFF 15 + +#ifndef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct ev_notify_s +{ + int signo; /* Signal number */ + int pid; /* Target PID */ + struct scuev_arg_s *arg; /* Event argument */ + struct scufifo_s *fifo; /* Reverse reference to FIFO */ +}; + +struct wm_notify_s +{ + int signo; /* Signal number */ + int pid; /* Target PID */ + struct scutimestamp_s *ts; /* Event argument */ + struct scufifo_s *fifo; /* Reverse reference to FIFO */ +}; + +/* SCU FIFO management structure */ + +struct scufifo_s +{ + int8_t wid; /* FIFO ID (Write side) */ + int8_t rid; /* FIFO ID (Read side) */ + uint8_t type; /* Normal or Decimator */ + int8_t mid; /* Combined MATHFUNC */ + + uint16_t start; /* Start of FIFO memory */ + uint16_t size; /* Size of FIFO memory */ + + uint32_t interval; /* Sample interval used for timestamp calculation */ + uint16_t adjust; /* Adjustment value used for timestamp calculation */ + +#ifdef CONFIG_CXD56_UDMAC + DMA_HANDLE dma; /* DMA for reading sensing data */ + sem_t dmawait; /* Wait semaphore for DMA complete */ + int dmaresult; /* DMA result */ +#endif +}; + +/* Sequencer */ + +struct seq_s +{ + int8_t id; /* Sequencer ID */ + uint8_t type; /* Normal or Decimator */ + uint8_t bustype; /* I2C[01] or SPI or ADC */ + int8_t active; /* Indicate active status. + * When active, any APIs will be returned state + * error. + */ + uint8_t sample; /* Bytes per sample */ + uint8_t rate; /* Sampling rate must be 2^rate (rate = 0 - 9) */ + + int8_t nr_fifos; /* For decimation, max 3 decimators can be used. */ + struct scufifo_s *fifo; /* Owned FIFO (normal only) */ +}; + +/* Decimation FIFO */ + +struct decimation_fifo_s +{ + struct scufifo_s *fifo; /* Pointer to decimation FIFO */ + uint8_t ratio; /* Decimation ratio */ + uint8_t leveladj; /* Output data level adjustment */ + uint8_t forcethrough; /* Force through */ +}; + +/* Decimator, sub class of sequencer */ + +struct decimator_s +{ + struct seq_s seq; /* Inherit, must be top of the structure */ + struct decimation_fifo_s dfifo[3]; /* Decimation FIFO */ +}; + +struct cxd56_scudev_s +{ + sem_t syncwait; /* Semaphore for synchronize with SCU firmware */ + sem_t syncexc; /* Semaphore for exclusive access to sync */ + + /* SCU hardware resource management bitmaps (1 = allocated) */ + + uint8_t decimators; /* Bitmap for decimators */ + uint8_t sequencers; /* Bitmap for normal sequencers */ + uint8_t mathfuncs; /* Bitmap for MATHFUNC */ + uint8_t oneshot; /* Bitmap for Oneshots */ + + sem_t oneshotwait[3]; /* Semaphore for wait oneshot sequence is done */ +#ifndef CONFIG_DISABLE_SIGNAL + struct ev_notify_s event[3]; /* MATHFUNC event notify */ + struct wm_notify_s wm[14]; /* Watermark notify */ +#endif + int currentreq; +}; + +struct coeff_addr_s +{ + uint32_t s; + uint32_t c0; + uint32_t c1; + uint32_t c2; + uint32_t c3; + uint32_t c4; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* SCU hardware resource management *****************************************/ + +static int findzeroandset(FAR uint8_t *bitmap, int nbits); +static void bitmapclear(FAR uint8_t *bitmap, int bit); +static inline int8_t deci_alloc(void); +static inline void deci_free(int8_t sid); +static inline int8_t mathf_alloc(void); +static inline void mathf_free(int8_t mid); +static int8_t seq_alloc(void); +static inline void seq_free(int8_t sid); +static inline int8_t oneshot_alloc(void); +static inline void oneshot_free(int8_t tid); +static int seq_semtake(sem_t *id); +static void seq_semgive(sem_t *id); +static void seq_fifosetactive(FAR struct seq_s *seq, int fifoid); +static void seq_fifosetinactive(FAR struct seq_s *seq, int fifoid); +static int seq_fifoisactive(FAR struct seq_s *seq, int fifoid); +static int seq_isactive(FAR struct seq_s *seq); + +/* Sequencer control ********************************************************/ + +static FAR struct seq_s *seq_new(void); +static FAR struct seq_s *deci_new(void); + +static void seq_inhibitrequest(int req, bool set); +static void seq_sync(FAR struct seq_s *seq, int req); +static void seq_setproperty(int sid, int slave, int dest, + int offset, int len); +static void seq_setinst(int sid, int offset, int len); +static void seq_setbus(int sid, int bustype); +static void seq_setdataformat(int sid, int start, int size, int swap, + int sample); +static void seq_setmathwritevecelenum(int sid, uint8_t elem); +static void seq_setsignconversion(int sid, int sign); +static void seq_setstartmode(int sid, int mode); +static void seq_setstartinterval(int sid, int interval); +static void seq_setstartphase(int sid, int phase); +static void seq_startseq(int sid); +static void seq_stopseq(int sid); +static int seq_setadjustment(FAR struct seq_s *seq, struct adjust_xyz_s *adj); +static int seq_setfilter(FAR struct scufifo_s *fifo, int pos, + struct iir_filter_s iir[2]); +static int seq_seteventnotifier(FAR struct scufifo_s *fifo, + struct scuev_notify_s *ev); +static void seq_offsetgainenable(int sid, bool enable); +static int seq_start(FAR struct seq_s *seq, int fifoid); +static int seq_stop(FAR struct seq_s *seq, int fifoid); +static int seq_setsamplingrate(FAR struct seq_s *seq, uint8_t samplingrate); +static int seq_fifoinit(FAR struct seq_s *seq, int fifoid, uint16_t fsize); +static void seq_fifofree(FAR struct scufifo_s *fifo); +static inline struct scufifo_s *seq_getfifo(FAR struct seq_s *seq, + int fifoid); +static void seq_setdecimation(int wid, uint8_t ratio, uint8_t leveladj, + uint8_t forcethrough); +static int seq_setwatermark(FAR struct seq_s *seq, int fifoid, + FAR struct scufifo_wm_s *wm); +#ifndef CONFIG_DISABLE_SIGNAL +static void convert_firsttimestamp(struct scutimestamp_s *tm, + uint16_t interval, uint16_t sample, + uint16_t adjust); +static void latest_timestamp(struct scufifo_s *fifo, uint32_t interval, + struct scutimestamp_s *tm, uint16_t *samples); +static void seq_gettimestamp(struct scufifo_s *fifo, + struct scutimestamp_s *tm); +#endif + +static int seq_oneshot(int bustype, int slave, FAR uint16_t *inst, + uint32_t nr_insts, FAR uint8_t *buffer, int len); +static void seq_setfifomode(FAR struct seq_s *seq, int fifoid, int enable); +#ifdef CONFIG_CXD56_UDMAC +static void seq_fifodmadone(DMA_HANDLE handle, uint8_t status, void *arg); +#endif +static uint16_t seq_remakeinstruction(int bustype, uint16_t inst); + +/* Mathfunction *************************************************************/ + +static void mathf_enable(int8_t mid, uint8_t wid); +static void mathf_disable(int8_t mid); +static inline void mathf_set_coeff(uint32_t caddr, + FAR struct iir_coeff_s *c); +static void mathf_setiirfilter(int mid, int n, + FAR struct iir_filter_s *filter); + +/* Interrupt handlers *******************************************************/ + +static int seq_scuirqhandler(int irq, FAR void *context, FAR void *arg); +static void seq_handlefifointr(FAR struct cxd56_scudev_s *priv, + uint32_t intr); +static void seq_handlemathfintr(FAR struct cxd56_scudev_s *priv, + uint32_t intr); +static void seq_handleoneshot(FAR struct cxd56_scudev_s *priv, + uint32_t intr); +static void seq_handleisopdoneintr(FAR struct cxd56_scudev_s *priv, + uint32_t intr); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct cxd56_scudev_s g_scudev; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* SCU firmware (iSoP) */ + +extern const unsigned long scuIsopProgArray[]; +extern const unsigned long sizeOfscuIsopProgArray; + +/* XXX: Convert coefficiencies register address. */ + +#define __CADDR(m, n) \ + { \ + .s = SCU_MATHFUNC_PARAM_##m##_##n, \ + .c0 = SCU_MATHFUNC_PARAM_C0_##m##_##n##_MSB, \ + .c1 = SCU_MATHFUNC_PARAM_C1_##m##_##n##_MSB, \ + .c2 = SCU_MATHFUNC_PARAM_C2_##m##_##n##_MSB, \ + .c3 = SCU_MATHFUNC_PARAM_C3_##m##_##n##_MSB, \ + .c4 = SCU_MATHFUNC_PARAM_C4_##m##_##n##_MSB, \ + } + +static const struct coeff_addr_s g_caddrs[3][2] = +{ + { + __CADDR(0, 0), + __CADDR(0, 1) + }, + { + __CADDR(1, 0), + __CADDR(1, 1) + }, + { + __CADDR(2, 0), + __CADDR(2, 1) + } +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Name: seq_semtake + ****************************************************************************/ + +static int seq_semtake(sem_t *id) +{ + while (sem_wait(id) != 0) + { + ASSERT(errno == EINTR); + } + return OK; +} + +/**************************************************************************** + * Name: seq_semgive + ****************************************************************************/ + +static void seq_semgive(sem_t *id) +{ + sem_post(id); +} + +/**************************************************************************** + * Name: seq_fifosetactive + ****************************************************************************/ + +static void seq_fifosetactive(FAR struct seq_s *seq, int fifoid) +{ + irqstate_t flags = enter_critical_section(); + seq->active |= 1 << fifoid; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: seq_fifosetinactive + ****************************************************************************/ + +static void seq_fifosetinactive(FAR struct seq_s *seq, int fifoid) +{ + irqstate_t flags = enter_critical_section(); + seq->active &= ~(1 << fifoid); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: seq_fifoisactive + ****************************************************************************/ + +static int seq_fifoisactive(FAR struct seq_s *seq, int fifoid) +{ + irqstate_t flags = enter_critical_section(); + int8_t active = seq->active; + leave_critical_section(flags); + return active & (1 << fifoid); +} + +/**************************************************************************** + * Name: seq_isactive + ****************************************************************************/ + +static int seq_isactive(FAR struct seq_s *seq) +{ + irqstate_t flags = enter_critical_section(); + int8_t active = seq->active; + leave_critical_section(flags); + return active; +} + +/**************************************************************************** + * Name: findzeroandset + * + * Description: + * Find zero bit from LSB and set when found. + * + * Input Parameters: + * bitmap - Bitmap for searching + * nbits - Size of bitmap in bits + * + * Returned value: + * Bit number of set 1. -1 is not found. + * + ****************************************************************************/ + +static int findzeroandset(FAR uint8_t *bitmap, int nbits) +{ + int i; + irqstate_t flags; + + flags = enter_critical_section(); + for (i = 0; i < nbits; i++) + { + if (!(*bitmap & (1 << i))) + { + *bitmap |= 1 << i; + leave_critical_section(flags); + return i; + } + } + + leave_critical_section(flags); + return -1; +} + +/**************************************************************************** + * Name: bitmapclear + * + * Description: + * Common atomic bit clear + * + ****************************************************************************/ + +static void bitmapclear(FAR uint8_t *bitmap, int bit) +{ + irqstate_t flags = enter_critical_section(); + *bitmap &= ~(1 << bit); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: deci_alloc + * + * Description: + * Allocate sequencer for decimation. + * + * Returned Value: + * Sequencer ID is returned on success. -1 is returned on failure. + * + ****************************************************************************/ + +static inline int8_t deci_alloc(void) +{ + int8_t ret; + ret = findzeroandset(&g_scudev.decimators, 2); + if (ret >= 0) + { + /* Wakeup SCU anyway if sequencer allocated successfully */ + + seq_inhibitrequest(REQ_SLEEP, true); + } + return ret; +} + +/**************************************************************************** + * Name: deci_free + * + * Description: + * Free sequencer for decimation. + * + ****************************************************************************/ + +static void deci_free(int8_t sid) +{ + DEBUGASSERT(sid == 0 || sid == 1); + bitmapclear(&g_scudev.decimators, sid); + if (!g_scudev.decimators && !g_scudev.sequencers) + { + /* SCU goes sleep when no sequencers running */ + + seq_inhibitrequest(REQ_SLEEP, false); + } +} + +/**************************************************************************** + * Name: mathf_alloc + * + * Description: + * Allocate MATHFUNC filter. MATHFUNC is max 3. + * + * Returned Value: + * Allocated MATHFUNC ID is returned on success. -1 is returned on failure. + * + ****************************************************************************/ + +static inline int8_t mathf_alloc(void) +{ + return findzeroandset(&g_scudev.mathfuncs, 3); +} + +/**************************************************************************** + * Name: mathf_free + * + * Description: + * Free MATHFUNC + * + ****************************************************************************/ + +static inline void mathf_free(int8_t mid) +{ + DEBUGASSERT(mid >= 0 && mid < 3); + bitmapclear(&g_scudev.mathfuncs, mid); +} + +/**************************************************************************** + * Name: seq_alloc + * + * Description: + * Allocate sequencer + * + * Returned Value: + * Allocated sequencer ID is returned on success. -1 is returned on failure. + * + ****************************************************************************/ + +static int8_t seq_alloc(void) +{ + int8_t sid = findzeroandset(&g_scudev.sequencers, 8); + if (sid < 0) + { + return -1; + } + + /* Wakeup SCU anyway if sequencer allocated successfully */ + + seq_inhibitrequest(REQ_SLEEP, true); + + return sid + 2; +} + +/**************************************************************************** + * Name: seq_free + * + * Description: + * Free sequencer + * + ****************************************************************************/ + +static void seq_free(int8_t sid) +{ + DEBUGASSERT(sid >= 2 && sid < 10); + bitmapclear(&g_scudev.sequencers, sid - 2); + if (!g_scudev.decimators && !g_scudev.sequencers) + { + /* SCU goes sleep when no sequencers running */ + + seq_inhibitrequest(REQ_SLEEP, false); + } +} + +/**************************************************************************** + * Name: oneshot_alloc + * + * Description: + * Allocate oneshot sequencer + * + * Returned Value: + * Oneshot ID + * + ****************************************************************************/ + +static inline int8_t oneshot_alloc(void) +{ + return findzeroandset(&g_scudev.oneshot, 3); +} + +/**************************************************************************** + * Name: oneshot_free + * + * Description: + * Free oneshot sequencer + * + * Input Parameters: + * tid - Oneshot ID (0-2) + * + ****************************************************************************/ + +static inline void oneshot_free(int8_t tid) +{ + DEBUGASSERT(tid >= 0 && tid < 3); + bitmapclear(&g_scudev.oneshot, tid); +} + +/**************************************************************************** + * Name: seq_inhibitrequest + * + * Description: + * Get the contents of the SPI register at offset + * Holy terrible SEQ_ACCESS_INHIBIT register's bit field name is + * different from actual function. + * + * Input Parameters: + * req - REQ_DONE, REQ_SLEEP, REQ_STOP + * inhibit - false (release) or true (set) + * + * Returned Value: + * The contents of the 32-bit register + * + ****************************************************************************/ + +static void seq_inhibitrequest(int req, bool set) +{ + uint32_t val; + val = getreg32(SCU_SEQ_ACCESS_INHIBIT) & ~(1 << req); + if (set) + { + val |= 1 << req; + } + + putreg32(val, SCU_SEQ_ACCESS_INHIBIT); +} + +/**************************************************************************** + * Name: seq_setdecimation + * + * Description: + * Set decimation configurations + * + * Input Parameters: + * wid - FIFO ID (write side) + * ratio - Decimation ratio + * leveladj - Output data level adjustment (2^n) + * forcethrough - Bypassing decimation calculation (not same as ratio x1) + * + ****************************************************************************/ + +static void seq_setdecimation(int wid, uint8_t ratio, uint8_t leveladj, + uint8_t forcethrough) +{ + uint32_t val; + uint32_t addr; + int shift; + + shift = 8 * (wid & 3); + addr = wid < 4 ? SCU_DECIMATION_PARAM0 : SCU_DECIMATION_PARAM1; + + val = getreg32(addr) & ~(0xff << shift); + val |= (ratio & 0xf) << shift; /* N */ + val |= (leveladj & 0x3) << (shift + 4); /* LEVEL_ADJ */ + val |= (forcethrough & 1) << (shift + 7); + putreg32(val, addr); +} + +/**************************************************************************** + * Name: seq_setproperty + * + * Description: + * Set sequencer property parameters + * + * Input Parameters: + * sid - Sequender ID + * slave - Slave select (SPI) or address (I2C) + * dest - Output buffer (1 - 3, oneshot only) + * offset - Instruction start offset + * len - Instruction length + * + ****************************************************************************/ + +static void seq_setproperty(int sid, int slave, int out, int offset, int len) +{ + uint32_t val; + val = slave & 0x3ff; + val |= (out & 0x3) << 12; + val |= (offset & 0x7f) << 16; + val |= (len & 0xf) << 24; + putreg32(val, SCUSEQ_PROPERTY(sid)); +} + +/**************************************************************************** + * Name: seq_setinst + * + * Description: + * Set instruction and its length to sequencer property + * + * Input Parameters: + * sid - Sequender ID + * offset - Instruction start offset + * len - Instruction length + * + ****************************************************************************/ + +static void seq_setinst(int sid, int offset, int len) +{ + uint32_t val; + val = getreg32(SCUSEQ_PROPERTY(sid)) & ~((0xf << 24) | (0x7f << 16)); + val |= (offset & 0x7f) << 16; + val |= (len & 0xf) << 24; + putreg32(val, SCUSEQ_PROPERTY(sid)); +} + +/**************************************************************************** + * Name: seq_setbus + * + * Description: + * Set source bus type for sequencer + * + * Input Parameters: + * sid - Sequencer ID + * bustype - Bus type (SCU_BUS_*) + * + ****************************************************************************/ + +static void seq_setbus(int sid, int bustype) +{ + uint32_t val; + uint32_t mask; + uint32_t bit; + + bit = 1 << sid; + mask = bit | bit << 10 | bit << 20; + switch (bustype) + { + case SCU_BUS_I2C0: + { + bit <<= 10; + } + break; + case SCU_BUS_I2C1: + { + bit <<= 20; + } + break; + case SCU_BUS_SPI: + break; + case SCU_BUS_LPADC0: + case SCU_BUS_LPADC1: + case SCU_BUS_LPADC2: + case SCU_BUS_LPADC3: + case SCU_BUS_HPADC0: + case SCU_BUS_HPADC1: + default: + return; + } + + val = getreg32(SCUSEQ_SRC_SEL) & ~mask; + putreg32(val | bit, SCUSEQ_SRC_SEL); +} + +/**************************************************************************** + * Name: seq_setdataformat + * + * Description: + * Reading sensor data format + * + * Input Parameters: + * sid - Sequencer ID + * start - Sensor data start offset in sequencer picked + * bps - Bytes per sample + * swap - Wwap bytes + * elem - Number of elements in sample + * + ****************************************************************************/ + +static void seq_setdataformat(int sid, int start, int bps, int swap, int elem) +{ + uint32_t val; + val = start & 0xf; + val |= (bps & 0xf) << 4; + val |= (swap & 0x1) << 16; + val |= (elem & 0x3) << 28; + putreg32(val, SCUSEQ_OUT_FORMAT(sid)); +} + +/**************************************************************************** + * Name: seq_setmathwritevecelenum + * + * Description: + * Set number of elements in sample + * (MATH_WRITE_VEC_ELE_NUM field in SEQ_OUT_FORMAT_n) + * + * Input Parameters: + * sid - Sequencer ID + * elem - Number of elements in sample + * + ****************************************************************************/ + +static void seq_setmathwritevecelenum(int sid, uint8_t elem) +{ + uint32_t val; + + DEBUGASSERT(elem > 0 && elem <= 3); + + val = getreg32(SCUSEQ_OUT_FORMAT(sid)); + val = (val & ~(0x3 << 28)) | ((elem - 1) & 0x3) << 28; + putreg32(val, SCUSEQ_OUT_FORMAT(sid)); +} + +/**************************************************************************** + * Name: seq_setsignconversion + * + * Description: + * Enable or disable sensor data sign conversion feature for preprocessing. + * + * Input Parameters: + * sid - Sequencer ID + * sign - 0 to no conversion, 1 to convert unsigned to signed + * + ****************************************************************************/ + +static void seq_setsignconversion(int sid, int sign) +{ + uint32_t val; + int shift = sid < 2 ? sid * 4 : sid + 6; + + val = getreg32(SCU_UNSIGNED_TO_SIGNED); + val &= ~(1 << shift); + putreg32(val | (sign << shift), SCU_UNSIGNED_TO_SIGNED); +} + +/**************************************************************************** + * Name: seq_setstartmode + * + * Description: + * Set sequencer start mode + * + * Input Parameters: + * sid - Sequencer ID + * mode - Start mode + * + ****************************************************************************/ + +static void seq_setstartmode(int sid, int mode) +{ + uint32_t val; + uint32_t shift; + + shift = sid * 2; + val = getreg32(SCU_START_MODE1) & ~(3 << shift); + putreg32(val | (mode << shift), SCU_START_MODE1); +} + +/**************************************************************************** + * Name: seq_setstartinterval + * + * Description: + * Set sequencer interval + * + * Input Parameters: + * sid - Sequencer ID + * interval - Interval + * + ****************************************************************************/ + +static void seq_setstartinterval(int sid, int interval) +{ + uint32_t addr = SCU_START_INTERVAL3_0 + (sid & 0xc); + uint32_t val; + uint32_t shift; + + shift = (sid & 3) * 8; + val = getreg32(addr) & ~(0xf << shift); + putreg32(val | (interval << shift), addr); +} + +/**************************************************************************** + * Name: seq_setstartphase + * + * Description: + * Set sequencer start phase. + * This function always set to zero right now. I don't know what this + * parameter affects for. + * + * Input Parameters: + * sid - Sequencer ID + * phase - Phase value + * + ****************************************************************************/ + +static void seq_setstartphase(int sid, int phase) +{ + uint32_t addr = SCU_START_PHASE1_0 + ((sid & 0xe) << 1); + uint32_t val; + uint32_t shift; + + shift = (sid & 1) * 16; + val = getreg32(addr) & ~(0x1ff << shift); + putreg32(val | (phase << shift), addr); +} + +/**************************************************************************** + * Name: seq_startseq + * + * Description: + * Start sequencer + * + * Input Parameters: + * sid - Sequencer ID + * + ****************************************************************************/ + +static void seq_startseq(int sid) +{ + uint32_t val; + val = getreg32(SCU_START_MODE0); + putreg32(val | (1 << sid), SCU_START_MODE0); +} + +/**************************************************************************** + * Name: seq_stopseq + * + * Description: + * Stop sequencer + * + * Input Parameters: + * sid - Sequencer ID + * + ****************************************************************************/ + +static void seq_stopseq(int sid) +{ + uint32_t val; + val = getreg32(SCU_START_MODE0); + putreg32(val & ~(1 << sid), SCU_START_MODE0); +} + +/**************************************************************************** + * Name: seq_oneshot + * + * Description: + * Perform one shot feature, this function can be use for any register + * access to connected sensors. (e.g. configure power mode) + * This function use empty sequencer temporarily, other than allocated + * sequencer to the sensor device driver. Thus, this function fails when + * all of normal sequencers are allocated. + * + * Input Parameters: + * bustype - One of SCU_BUS_SPI, SCU_BUS_I2C0 and SCU_BUS_I2C1 + * slave - Slave select (SPI) or address (I2C) + * inst - Pointer to series of read/write instruction array + * nr_insts - Number of instructions + * buffer - Receive data buffer + * len - Length of receive data buffer + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * failure. + * + ****************************************************************************/ + +static int seq_oneshot(int bustype, int slave, FAR uint16_t *inst, + uint32_t nr_insts, FAR uint8_t *buffer, int len) +{ + struct cxd56_scudev_s *priv = &g_scudev; + irqstate_t flags; + int sid; + int tid; + int istart; + int i; + int ret = OK; + uint16_t lastinst; + + ASSERT(bustype == SCU_BUS_SPI || bustype == SCU_BUS_I2C0 || + bustype == SCU_BUS_I2C1); + + if (nr_insts > INSTRUCTION_PER_SEQ) + { + return -EINVAL; + } + + /* If buffer is non NULL, check receive length is valid */ + + if (buffer && (len <= 0 || len > 16)) + { + return -EINVAL; + } + + flags = enter_critical_section(); + sid = seq_alloc(); + if (sid < 0) + { + leave_critical_section(flags); + return -ENOENT; + } + + tid = oneshot_alloc(); + if (tid < 0) + { + seq_free(sid); + leave_critical_section(flags); + return -ENOENT; + } + leave_critical_section(flags); + + /* Remake last instruction, if needed. */ + + lastinst = seq_remakeinstruction(bustype, inst[nr_insts - 1]); + + /* Copy sequencer instruction */ + + istart = sid * INSTRUCTION_PER_SEQ; + for (i = 0; i < nr_insts - 1; i++) + { + putreg16(inst[i], SCUSEQ_INSTRUCTION(istart + i)); + } + putreg16(lastinst, SCUSEQ_INSTRUCTION(istart + nr_insts - 1)); + + /* Setup sequencer as oneshot mode + * Oneshot mode is special function, so can not be use to MATHFUNC, + * sign conversion and offset/gain adjustment. + */ + + seq_setbus(sid, bustype); + seq_setproperty(sid, slave, tid + 1, istart, nr_insts - 1); + seq_setsignconversion(sid, 0); + seq_offsetgainenable(sid, false); + seq_setdataformat(sid, 0, buffer ? len - 1 : 0, 0, 0); + + /* Mode set "Stop" */ + + seq_setstartmode(sid, 0); + + /* Set fixed value interval (0xa) for one shot sequencer */ + + seq_setstartinterval(sid, 0xa); + + /* Enable interrupt for one shot sequencer */ + + putreg32(1 << (tid + 24), SCU_INT_ENABLE_MAIN); + + scuinfo("Sequencer start.\n"); + + /* Start sequencer as one shot mode */ + + seq_startseq(sid); + putreg32(1 << sid, SCU_SINGLE_EXE); + + /* Wait for one shot is done */ + + seq_semtake(&priv->oneshotwait[tid]); + + /* Disable interrupt for one shot sequencer */ + + putreg32(1 << (tid + 24), SCU_INT_DISABLE_MAIN); + + scuinfo("Sequencer done.\n"); + + if (buffer) + { + /* Copy sequencer output results to user buffer. + * XXX: Sequencer output RAM offset is differ from document. + */ + + memcpy(buffer, (void *)(SCUSEQ_RAM_OUT_DATA0 + (0x10 * tid)), len); + } + + /* Stop sequencer */ + + seq_stopseq(sid); + + /* Destroy oneshot resources */ + + flags = enter_critical_section(); + oneshot_free(tid); + seq_free(sid); + leave_critical_section(flags); + + return ret; +} + +/**************************************************************************** + * Name: seq_enableoffsetgain + * + * Description: + * Enable offset/gain preprocessing + * + ****************************************************************************/ + +static void seq_offsetgainenable(int sid, bool enable) +{ + uint32_t val; + int n = sid < 2 ? sid * 4 : sid + 6; + + val = getreg32(SCU_OFST_GAIN_EN); + if (enable) + { + val |= 1 << n; + } + else + { + val &= ~(1 << n); + } + putreg32(val, SCU_OFST_GAIN_EN); +} + +/**************************************************************************** + * Name: seq_start + * + * Description: + * Start sequencer. This function is for SCUIOC_START. + * + * Input Parameters: + * seq - An instance of sequencer + * fifoid - FIFO ID (0-2, decimator only) + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * failure. + * + ****************************************************************************/ + +static int seq_start(FAR struct seq_s *seq, int fifoid) +{ + struct scufifo_s *fifo; + uint32_t interval; + + DEBUGASSERT(seq); + DEBUGASSERT(fifoid >= 0 && fifoid < 3); + + if (seq->type & SEQ_TYPE_DECI) + { + struct decimator_s *deci = (struct decimator_s *)seq; + struct decimation_fifo_s *dfifo = &deci->dfifo[fifoid]; + + /* Avoid confilict for DECIMATION_PARAM register access with SCU */ + + if (seq_isactive(seq)) + { + seq_sync(&deci->seq, REQ_STOP); + } + + seq_setdecimation(dfifo->fifo->wid, dfifo->ratio, dfifo->leveladj, + dfifo->forcethrough); + fifo = dfifo->fifo; + + interval = dfifo->ratio + seq->rate; + + /* Prevent SCU freeze by frequently REQ_STOP */ + + if (seq_isactive(seq)) + { + up_udelay(100); + } + } + else + { + fifo = seq->fifo; + interval = seq->rate; + } + + if (!fifo) + { + return -EPERM; + } + + if (!seq_isactive(seq)) + { + if (!(seq->bustype & 0x10)) + { + /* Calculate timestamp interval prediv * (2 ^ interval) */ + + fifo->interval = CONFIG_CXD56_SCU_PREDIV * (1 << interval); + fifo->adjust = 0; + + /* Go sequencer */ + + seq_setstartmode(seq->id, 1); + seq_setstartinterval(seq->id, seq->rate); + seq_setstartphase(seq->id, 1); + seq_startseq(seq->id); + } + else + { + uint32_t mask; + uint32_t val; + + /* Calculate timestamp interval for ADC */ + + cxd56_adc_getinterval(seq->bustype, &fifo->interval, &fifo->adjust); + + /* Enable ADC */ + + mask = 0x1 << (24 + (seq->bustype & 0x7)); + val = getreg32(SCUSEQ_ADC_PROPERTY) & ~mask; + val |= (0x1 << (24 + (seq->bustype & 0x7))); + putreg32(val, SCUSEQ_ADC_PROPERTY); + } + } + + seq_fifosetactive(seq, fifoid); + + return 0; +} + +/**************************************************************************** + * Name: seq_stop + * + * Description: + * Stop sequencer (external API) + * + ****************************************************************************/ + +static int seq_stop(FAR struct seq_s *seq, int fifoid) +{ + struct scufifo_s *fifo; + uint32_t val; + + DEBUGASSERT(seq); + DEBUGASSERT(fifoid >= 0 && fifoid < 3); + + fifo = seq_getfifo(seq, fifoid); + + if (fifo == NULL) + { + scuerr("missing FIFO\n"); + return -EPERM; + } + + if (!seq_isactive(seq)) + { + return OK; + } + + val = getreg32(SCUFIFO_R_CTRL1(fifo->rid)); + putreg32(val & ~(1 << 24), SCUFIFO_R_CTRL1(fifo->rid)); + + if (seq->type & SEQ_TYPE_DECI) + { + seq_sync(seq, REQ_STOP); + + /* Set ratio to 15 to disable decimator */ + + seq_setdecimation(fifo->wid, DECIMATION_OFF, 0, 0); + + /* Prevent SCU freeze by frequently REQ_STOP */ + + up_udelay(100); + } + + seq_fifosetinactive(seq, fifoid); + + /* If all of FIFOs are stopped, then stop sequencer. */ + + if (!seq_isactive(seq)) + { + if (!(seq->bustype & 0x10)) + { + seq_setstartmode(seq->id, 0); + seq_stopseq(seq->id); + + /* Wait for stop done */ + + seq_sync(seq, REQ_DONE); + } + else + { + /* Disable ADC */ + + uint32_t mask = 0x1 << (24 + (seq->bustype & 0x7)); + val = getreg32(SCUSEQ_ADC_PROPERTY) & ~mask; + putreg32(val, SCUSEQ_ADC_PROPERTY); + } + } + + return 0; +} + +/**************************************************************************** + * Name: mathf_enable + * + * Description: + * Enable MATHFUNC to specified FIFO + * + * Input Parameters: + * mid - MATHFUNC ID + * wid - FIFO ID (Write side) + * + ****************************************************************************/ + +static void mathf_enable(int8_t mid, uint8_t wid) +{ + uint32_t val; + + val = getreg32(SCU_MATHFUNC_SEL); + val &= ~(0xf << (mid * 8)); + val |= 1 << ((mid * 8) + 4); + putreg32(val | (wid << (mid * 8)), SCU_MATHFUNC_SEL); + putreg32(1 << mid, SCU_MATHFUNC_CLR); +} + +/**************************************************************************** + * Name: mathf_disable + * + * Description: + * Disable MATHFUNC + * + * Input Parameters: + * mid - MATHFUNC ID + * + ****************************************************************************/ + +static void mathf_disable(int8_t mid) +{ + uint32_t val; + val = getreg32(SCU_MATHFUNC_SEL); + val &= ~(1 << ((mid * 8) + 4)); + putreg32(val, SCU_MATHFUNC_SEL); +} + +/**************************************************************************** + * Name: mathf_set_coeff + * + * Description: + * Set 1 coefficiency value + * + ****************************************************************************/ + +static inline void mathf_set_coeff(uint32_t caddr, FAR struct iir_coeff_s *c) +{ + putreg32(c->h, caddr); + putreg32((c->l & 0x3) << 30, caddr + 4); +} + +/**************************************************************************** + * Name: mathf_setiirfilter + * + * Description: + * Set series of coefficiencies for 2 IIR filters + * + * Input Parameters: + * mid - MATHFUNC ID + * n - Filter ID + * filter - IIR filter setting + * + ****************************************************************************/ + +static void mathf_setiirfilter(int mid, int n, + FAR struct iir_filter_s *filter) +{ + const struct coeff_addr_s *caddr; + + caddr = g_caddrs[mid]; + + putreg32((filter->ishift & 0x7) | ((filter->oshift & 0x7) << 8), + caddr[0].s); + + mathf_set_coeff(caddr[n].c0, &filter->coeff[0]); + mathf_set_coeff(caddr[n].c1, &filter->coeff[1]); + mathf_set_coeff(caddr[n].c2, &filter->coeff[2]); + mathf_set_coeff(caddr[n].c3, &filter->coeff[3]); + mathf_set_coeff(caddr[n].c4, &filter->coeff[4]); +} + +/**************************************************************************** + * Name: seq_setsamplingrate + * + * Description: + * Set sequencer sampling rate + * + * Input Parameters: + * seq - An instance of sequencer + * samplingrate - Sampling rate. Sampling rate is based on + * 32768 Hz / predivider. + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * failure. + * + ****************************************************************************/ + +static int seq_setsamplingrate(FAR struct seq_s *seq, uint8_t samplingrate) +{ + DEBUGASSERT(seq); + + if (samplingrate > 9) + { + return -EINVAL; + } + seq->rate = samplingrate; + + return OK; +} + +/**************************************************************************** + * Name: seq_sync + * + * Description: + * Send specific request to SCU firmware + * + * Input Parameters: + * seq - An instance of sequencer + * req - Request code for SCU firmware (REQ_*) + * + ****************************************************************************/ + +static void seq_sync(FAR struct seq_s *seq, int req) +{ + FAR struct cxd56_scudev_s *priv = &g_scudev; + + seq_semtake(&priv->syncexc); + + /* Save current request */ + + priv->currentreq = req; + + putreg32(1 << 27, SCU_INT_CLEAR_MAIN); + putreg32(1 << 27, SCU_INT_ENABLE_MAIN); + + putreg32(seq->id & 0xf, SCUSEQ_SYNCRO_CPU2ISOP); + + /* Send request to SCU */ + + seq_inhibitrequest(req, true); + + /* Wait for interrupt from SCU firmware */ + + seq_semtake(&priv->syncwait); + + priv->currentreq = 0; + + seq_semgive(&priv->syncexc); +} + +/**************************************************************************** + * Name: seq_handlefifintr + * + * Description: + * Handle FIFO overrun error + * + ****************************************************************************/ + +static void seq_handlefifointr(FAR struct cxd56_scudev_s *priv, uint32_t intr) +{ + uint32_t bit; + int i; +#ifndef CONFIG_DISABLE_SIGNAL + struct wm_notify_s *notify; +# ifdef CONFIG_CAN_PASS_STRUCTS + union sigval value; +# endif +#endif + + if ((intr & 0x007ffe00) == 0) + { + return; + } + + /* Each FIFO almost full interrupt cause are starts with 9 */ + + for (i = 0, bit = 1 << 9; i < 14; i++, bit <<= 1) + { + if (intr & bit) + { + /* Clear interrupt */ + + putreg32(bit, SCU_INT_CLEAR_MAIN); + +#ifndef CONFIG_DISABLE_SIGNAL + notify = &priv->wm[i]; + + if (notify->ts) + { + seq_gettimestamp(notify->fifo, notify->ts); + } + + DEBUGASSERT(notify->pid != 0); + +# ifdef CONFIG_CAN_PASS_STRUCTS + value.sival_ptr = notify->ts; + (void)sigqueue(notify->pid, notify->signo, value); +# else + (void)sigqueue(notify->pid, notify->signo, (FAR void *)notify->ts); +# endif +#endif + } + } +} + +/**************************************************************************** + * Name: seq_handlemathfintr + * + * Description: + * Handle MATHFUNC rise and fall event interrupts + * + ****************************************************************************/ + +static void seq_handlemathfintr(FAR struct cxd56_scudev_s *priv, + uint32_t intr) +{ + int i; + uint32_t bit; + uint32_t rise; + uint32_t fall; +#ifndef CONFIG_DISABLE_SIGNAL + struct ev_notify_s *notify; + int detected = 0; +#endif + + rise = (intr >> 6) & 0x7; + fall = (intr >> 28) & 0x7; + + if (rise == 0 && fall == 0) + { + return; + } + + for (i = 0, bit = 1; i < 3; i++, bit <<= 1) + { +#ifndef CONFIG_DISABLE_SIGNAL + notify = &priv->event[i]; +#endif + /* Detect rise event */ + + if (rise & bit) + { + putreg32(bit << 6, SCU_INT_CLEAR_MAIN); + +#ifndef CONFIG_DISABLE_SIGNAL + /* Get rise event occurred timestamp */ + + if (notify->arg) + { + notify->arg->ts.sec = + getreg32(SCU_EVENT_TIMESTAMP0_R_MSB + (i * 8)); + notify->arg->ts.tick = + getreg32(SCU_EVENT_TIMESTAMP0_R_LSB + (i * 8)); + notify->arg->type = SCU_EV_RISE; + } + detected = 1; +#endif + } + + /* Detect fall event */ + + if (fall & bit) + { + putreg32(bit << 28, SCU_INT_CLEAR_MAIN); + +#ifndef CONFIG_DISABLE_SIGNAL + /* Get fall event occurred timestamp */ + + if (notify->arg) + { + notify->arg->ts.sec = + getreg32(SCU_EVENT_TIMESTAMP0_F_MSB + (i * 8)); + notify->arg->ts.tick = + getreg32(SCU_EVENT_TIMESTAMP0_F_LSB + (i * 8)); + notify->arg->type = SCU_EV_FALL; + } + detected = 1; +#endif + } + +#ifndef CONFIG_DISABLE_SIGNAL + if (detected) + { + DEBUGASSERT(notify->pid != 0); + +# ifdef CONFIG_CAN_PASS_STRUCTS + union sigval value; + value.sival_ptr = notify->arg; + (void)sigqueue(notify->pid, notify->signo, value); +# else + (void)sigqueue(notify->pid, notify->signo, (FAR void *)notify->arg); +# endif + detected = 0; + } +#endif + } +} + +/**************************************************************************** + * Name: seq_handleoneshot + * + * Description: + * Handle one shot sequencer done interrupt + * + ****************************************************************************/ + +static void seq_handleoneshot(FAR struct cxd56_scudev_s *priv, uint32_t intr) +{ + uint32_t bit; + int i; + + if ((intr & 0x07000000) == 0) + { + return; + } + + for (i = 0, bit = 1 << 24; i < 3; i++, bit <<= 1) + { + if (intr & bit) + { + putreg32(bit, SCU_INT_CLEAR_MAIN); + + seq_semgive(&priv->oneshotwait[i]); + } + } +} + +/**************************************************************************** + * Name: seq_handleisopdoneintr + * + * Description: + * Handle interrupts response against request for SCU firmware + * + ****************************************************************************/ + +static void seq_handleisopdoneintr(FAR struct cxd56_scudev_s *priv, + uint32_t intr) +{ + /* Detect ISOP3 as done or stop. */ + + if (intr & (1 << 27)) + { + DEBUGASSERT(priv->currentreq != 0); + + seq_inhibitrequest(priv->currentreq, false); + + putreg32(1 << 27, SCU_INT_DISABLE_MAIN); + putreg32(1 << 27, SCU_INT_CLEAR_MAIN); + + seq_semgive(&priv->syncwait); + } +} + +/**************************************************************************** + * Name: seq_scuirqhandler + * + * Description: + * Root interrupt handler for many SCU interrupts + * + ****************************************************************************/ + +static int seq_scuirqhandler(int irq, FAR void *context, FAR void *arg) +{ + FAR struct cxd56_scudev_s *priv = arg; + uint32_t intr; + uint32_t ierr0; + uint32_t ierr1; + uint32_t ierr2; + int i; + + intr = getreg32(SCU_INT_MASKED_STT_MAIN); + ierr0 = getreg32(SCU_INT_MASKED_STT_ERR_0); + ierr1 = getreg32(SCU_INT_MASKED_STT_ERR_1); + ierr2 = getreg32(SCU_INT_MASKED_STT_ERR_2); + + seq_handlefifointr(priv, intr); + + seq_handlemathfintr(priv, intr); + + seq_handleoneshot(priv, intr); + + seq_handleisopdoneintr(priv, intr); + + /* Detect all FIFO overrun errors */ + + if (ierr0 != 0) + { + scuerr("err0: %08x\n", ierr0); + ierr0 = (ierr0 >> 9) & 0x3fff; + for (i = 0; i < 14; i++) + { + if ((ierr0 & (0x1 << i)) != 0) + { + /* Clear FIFO overrun error */ + + putreg32(getreg32(SCUFIFO_R_CTRL1(i)) | SCUFIFO_OVERRUNCLR, + SCUFIFO_R_CTRL1(i)); + } + } + } + + /** + * Detect all FIFO underrun errors + * This error may not happened because check reading bytes at seq_read(). + * Thus, it is a program error when ERR1 detected. + */ + + if (ierr1 != 0) + { + scuerr("err1: %08x\n", ierr1); + ierr1 = (ierr1 >> 9) & 0x3fff; + for (i = 0; i < 14; i++) + { + if ((ierr1 & (0x1 << i)) != 0) + { + /* Clear FIFO underrun error */ + + putreg32(getreg32(SCUFIFO_R_CTRL1(i)) | SCUFIFO_UNDERRUNCLR, + SCUFIFO_R_CTRL1(i)); + } + } + } + + /* Detect sequencer error */ + + if (ierr2 != 0) + { + scuerr("err2: %08x\n", ierr2); + ierr2 &= 0x03ff; + for (i = 0; i < 10; i++) + { + if (ierr2 & (1 << i)) + { + seq_stopseq(i); + } + } + putreg32(0x03ff, SCU_INT_CLEAR_ERR_2); + } + + return 0; +} + +/**************************************************************************** + * Name: seq_new + * + * Description: + * Create new sequencer instance + * + * Returned Value: + * Created sequencer instance or NULL + * + ****************************************************************************/ + +static FAR struct seq_s *seq_new(void) +{ + FAR struct seq_s *seq; + int sid; + irqstate_t flags; + + flags = enter_critical_section(); + sid = seq_alloc(); + if (sid < 0) + { + /* Sequencer is full */ + + leave_critical_section(flags); + return NULL; + } + leave_critical_section(flags); + + seq = (FAR struct seq_s *)kmm_malloc(sizeof(struct seq_s)); + if (!seq) + { + seq_free(sid); + return NULL; + } + memset(seq, 0, sizeof(struct seq_s)); + + seq->id = sid; + + return seq; +} + +/**************************************************************************** + * Name: deci_new + * + * Description: + * Create new decimator instance + * + * Returned Value: + * Created decimator instance or NULL + * + ****************************************************************************/ + +static FAR struct seq_s *deci_new(void) +{ + FAR struct decimator_s *deci; + int sid; + irqstate_t flags; + + flags = enter_critical_section(); + sid = deci_alloc(); + if (sid < 0) + { + /* Sequencer is full */ + + leave_critical_section(flags); + return NULL; + } + leave_critical_section(flags); + + deci = (FAR struct decimator_s *)kmm_malloc(sizeof(struct decimator_s)); + if (!deci) + { + deci_free(sid); + return NULL; + } + memset(deci, 0, sizeof(struct decimator_s)); + + deci->seq.id = sid; + + return &deci->seq; +} + +/**************************************************************************** + * Name: seq_fifoinit + * + * Description: + * Initialize sequencer output FIFO + * + * Input Parameters: + * seq - Sequencer instance + * fifoid - FIFO ID (decimator only) + * fsize - Allocate FIFO memory size + * + ****************************************************************************/ + +static int seq_fifoinit(FAR struct seq_s *seq, int fifoid, uint16_t fsize) +{ + FAR struct scufifo_s *fifo; + FAR struct decimator_s *deci = (FAR struct decimator_s *)seq; + int wid; + int rid; + uint32_t val; + uint32_t mask; + uint16_t start; + uint16_t samples; + + DEBUGASSERT(seq); + DEBUGASSERT(fifoid >= 0 && fifoid < 3); + + if (seq->type & SEQ_TYPE_DECI) + { + if (deci->dfifo[fifoid].fifo) + { + return OK; + } + } + else + { + if (seq->fifo) + { + /* FIFO already initialized */ + + return OK; + } + } + + fifo = (FAR struct scufifo_s *)kmm_malloc(sizeof(struct scufifo_s)); + if (!fifo) + { + return -ENOMEM; + } + + memset(fifo, 0, sizeof(struct scufifo_s)); + + /* Setup FIFO, normal FIFO wid and rid are based on 8 and 4 respectively. */ + + start = scufifo_memalloc(fsize); + if (start == FIFOMEM_INVALID) + { + kmm_free(fifo); + return -ENOMEM; + } + + /** + * FIFO IDs (* is unavailable) + * D = Decimation FIFO + * N = Normal FIFO + * + * sid wid name rid name + * 0 0 D0_W0* + * 1 D0_W1 0 D0_R1 + * 2 D0_W2 1 D0_R2 + * 3 D0_W3 12 D0_R3 + * 1 4 D1_W0* + * 5 D1_W1 2 D1_R1 + * 6 D1_W2 3 D1_R2 + * 7 D1_W3 13 D1_R3 + * + * 2 8 N0_W 4 N0_R1 + * 3 9 N1_W 5 N0_R1 + * 4 10 N2_W 6 N0_R1 + * 5 11 N3_W 7 N0_R1 + * 6 12 N4_W 8 N0_R1 + * 7 13 N5_W 9 N0_R1 + * 8 14 N6_W 10 N0_R1 + * 9 15 N7_W 11 N0_R1 + */ + + if (seq->type & SEQ_TYPE_DECI) + { + wid = fifoid + 1 + (seq->id * 4); + if (fifoid < 2) + { + rid = fifoid + (seq->id * 2); + } + else + { + rid = seq->id + 12; + } + + if (!seq_isactive(seq)) + { + /* Additionally, reset first stage of decimation logic + * when other decimator not used. + */ + + putreg32(1 << (seq->id * 4), SCU_DEC_CLR); + } + + /* Reset decimator */ + + putreg32(1 << wid, SCU_DEC_CLR); + } + else + { + wid = seq->id + 6; + rid = seq->id + 2; + } + + /* Set FIFO start offset and its size */ + + DEBUGASSERT(seq->sample); + samples = fsize / seq->sample; + putreg32((uint32_t)start << 16 | (samples - 1), SCUFIFO_W_CTRL0(wid)); + + /* Set 1 sample size and FIFO reset */ + + val = seq->sample - 1; + val |= (1 << 16); + putreg32(val, SCUFIFO_W_CTRL1(wid)); + + /* Set watermark */ + + putreg32(0xffff, SCUFIFO_R_CTRL0(rid)); + + /* Perform enable FIFO outlet, reset and clear error */ + + val = (1 << 24) | (1 << 16) | (1 << 8) | 3; + putreg32(val, SCUFIFO_R_CTRL1(rid)); + + /* Clear write event control */ + + putreg32(0, SCUSEQ_FIFOWREVNTCTRL(wid)); + + /* Save instance data */ + + fifo->start = start; + fifo->size = fsize; + fifo->wid = wid; + fifo->rid = rid; + fifo->mid = -1; + +#ifdef CONFIG_CXD56_UDMAC + /* Allocate DMA for read sensing data */ + + fifo->dma = cxd56_udmachannel(); + + /* Initialize DMA done wait semaphore */ + + sem_init(&fifo->dmawait, 0, 0); + fifo->dmaresult = -1; +#endif + + if (seq->type & SEQ_TYPE_DECI) + { + FAR struct decimation_fifo_s *dec = &deci->dfifo[fifoid]; + dec->fifo = fifo; + dec->ratio = 0; + dec->leveladj = 0; + dec->forcethrough = 1; + } + else + { + seq->fifo = fifo; + } + + if (seq->bustype & 0x10) + { + /* Set wid to ADC_PROPERTY */ + + mask = 0xf << (4 * (seq->bustype & 0x7)); + val = getreg32(SCUSEQ_ADC_PROPERTY) & ~mask; + val |= (wid << (4 * (seq->bustype & 0x7))); + putreg32(val, SCUSEQ_ADC_PROPERTY); + } + + return OK; +} + +/**************************************************************************** + * Name: seq_fifofree + * + * Description: + * Free sequencer output FIFO + * + * Input Parameters: + * fifo - An instance of FIFO + * + ****************************************************************************/ + +static void seq_fifofree(FAR struct scufifo_s *fifo) +{ + int wid; + int rid; + int mid; + + if (!fifo) + { + return; + } + +#ifdef CONFIG_CXD56_UDMAC + /* Free DMA */ + + cxd56_udmafree(fifo->dma); +#endif + + wid = fifo->wid; + rid = fifo->rid; + mid = fifo->mid; + + if (mid >= 0 && mid < 3) + { + putreg32(3, SCUSEQ_FIFOWREVNTCTRL(wid)); + putreg32(0, SCU_EVENT_INTR_ENABLE(mid)); + putreg32(0x9 << mid, SCU_FIFO_WRITE_CTRL); + putreg32(1 << mid, SCU_EVENT_STT); + + putreg32((1 << (wid + 28)) | (1 << (wid + 6)), SCU_INT_DISABLE_MAIN); + + mathf_disable(mid); + mathf_free(mid); + } + + /* Disable watermark interrupt anyway */ + + putreg32(1 << (rid + 9), SCU_INT_DISABLE_MAIN); + + /* Make sure want to be FIFO disabled */ + + putreg32(0, SCUFIFO_R_CTRL1(rid)); + + scufifo_memfree(fifo->start); + +#ifdef CONFIG_CXD56_UDMAC + sem_destroy(&fifo->dmawait); +#endif + + kmm_free(fifo); +} + +/**************************************************************************** + * Name: seq_getfifo + * + * Description: + * Utility for ease of obtaining FIFO instans from sequencer. + * + * Input Parameters: + * seq - An instance of sequencer + * fifoid - FIFO ID (decimator only) + * + ****************************************************************************/ + +static inline struct scufifo_s *seq_getfifo(FAR struct seq_s *seq, int fifoid) +{ + DEBUGASSERT(fifoid >= 0 && fifoid < 3); + + if (seq->type & SEQ_TYPE_DECI) + { + struct decimator_s *deci = (struct decimator_s *)seq; + return deci->dfifo[fifoid].fifo; + } + else + { + return seq->fifo; + } +} + +/**************************************************************************** + * Name: seq_setadjustment + * + * Description: + * Set parameters for offset/gain adjustment, preprocessing of sequencer. + * + * Input Parameters: + * seq - An instance of sequencer + * adj - offset/gain adjustment parameter by 3 axis + * + ****************************************************************************/ + +static int seq_setadjustment(FAR struct seq_s *seq, + FAR struct adjust_xyz_s *adj) +{ + int sid; + uint32_t val; + + DEBUGASSERT(seq); + + /* offset/gain parameters can be set when sequencer not running */ + + if (seq_isactive(seq)) + { + return -EBUSY; + } + + sid = seq->id; + + /* Set offset/gain adjustment parameters for each 3 axis data */ + + val = adj->x.offset | ((uint32_t)adj->x.gain << 16); + putreg32(val, SCUSEQ_MATH_PROC_OFST_GAIN_X(sid)); + + val = adj->y.offset | ((uint32_t)adj->y.gain << 16); + putreg32(val, SCUSEQ_MATH_PROC_OFST_GAIN_Y(sid)); + + val = adj->z.offset | ((uint32_t)adj->z.gain << 16); + putreg32(val, SCUSEQ_MATH_PROC_OFST_GAIN_Z(sid)); + + return OK; +} + +/**************************************************************************** + * Name: seq_setfilter + * + * Description: + * Set MATHFUNC IIR filter feature + * + * Input Paramters: + * fifo - An instance of FIFO + * pos - Where to IIR filter inserted + * iir - IIR filter coefficiencies + * + ****************************************************************************/ + +static int seq_setfilter(FAR struct scufifo_s *fifo, int pos, + FAR struct iir_filter_s iir[2]) +{ + int mid; + + DEBUGASSERT(fifo); + + if (fifo->mid < 0) + { + mid = mathf_alloc(); + if (mid < 0) + { + return -ENOENT; + } + + fifo->mid = mid; + mathf_enable(mid, fifo->wid); + } + else + { + mid = fifo->mid; + } + + putreg32(pos, SCU_MATHFUNC_POS(mid)); + + mathf_setiirfilter(mid, 0, &iir[0]); + mathf_setiirfilter(mid, 1, &iir[1]); + + return OK; +} + +/**************************************************************************** + * Name: seq_seteventnotifier + * + * Description: + * Set event notifier + * + * Input Parameters: + * fifo - An instance of FIFO + * ev - Event notify setting + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * failure. + * + ****************************************************************************/ + +static int seq_seteventnotifier(FAR struct scufifo_s *fifo, + FAR struct scuev_notify_s *ev) +{ + struct cxd56_scudev_s *priv = &g_scudev; + uint32_t val; + uint32_t thresh; + uint32_t count0; + uint32_t count1; + uint32_t delaysample; + int riseint; + int fallint; + int mid; +#ifndef CONFIG_DISABLE_SIGNAL + irqstate_t flags; +#endif + + DEBUGASSERT(fifo && ev); + + /* Math Function must be assigned first. */ + + if (fifo->mid < 0) + { + return -ENOENT; + } + mid = fifo->mid; + +#ifndef CONFIG_DISABLE_SIGNAL + /* Save signal number and target PID */ + + flags = enter_critical_section(); + priv->event[mid].signo = ev->signo; + priv->event[mid].pid = getpid(); + priv->event[mid].arg = ev->arg; + priv->event[mid].fifo = fifo; + leave_critical_section(flags); +#endif + + thresh = count0 = count1 = delaysample = 0; + riseint = fallint = 0; + + thresh = ev->rise.threshold; + count0 = ev->rise.count0; + count1 = ev->rise.count1; + delaysample = ev->rise.delaysamples; + + thresh |= ev->fall.threshold << 16; + count0 |= ev->fall.count0 << 16; + count1 |= ev->fall.count1 << 16; + delaysample |= ev->fall.delaysamples << 16; + + if (ev->ctrl & SCU_EV_RISE_EN) + { + riseint = 1; + } + + if (ev->ctrl & SCU_EV_FALL_EN) + { + fallint = 1; + } + + putreg32(thresh, SCU_EVENT_PARAM_THRESH(mid)); + putreg32(count0, SCU_EVENT_PARAM_COUNT0(mid)); + putreg32(count1, SCU_EVENT_PARAM_COUNT1(mid)); + putreg32(delaysample, SCU_EVENT_PARAM_DELAY_SAMPLE(mid)); + + /* Enable interrupt */ + + putreg32(fallint << 8 | riseint, SCU_EVENT_INTR_ENABLE(mid)); + + val = (ev->ctrl & SCU_EV_OUTMASK) >> SCU_EV_OUTSHIFT; + val |= (mid & 0x3) << 4; + val |= (ev->ctrl & SCU_EV_WRITESAMPLEMASK) << 8; + val |= ev->ctrl & SCU_EV_OUT8BITS ? 1 << 24 : 0; + + putreg32(val, SCUSEQ_FIFOWREVNTCTRL(fifo->wid)); + + val = riseint << (mid + 6); + val |= fallint << (mid + 28); + putreg32(val, SCU_INT_ENABLE_MAIN); + + putreg32(1 << mid, SCU_EVENT_STT); + + return OK; +} + +#ifndef CONFIG_DISABLE_SIGNAL + +/**************************************************************************** + * Name: seq_setwatermark + * + * Description: + * Set watermark value for specified FIFO + * + ****************************************************************************/ + +static int seq_setwatermark(FAR struct seq_s *seq, int fifoid, + FAR struct scufifo_wm_s *wm) +{ + FAR struct cxd56_scudev_s *priv = &g_scudev; + struct scufifo_s *fifo = seq_getfifo(seq, fifoid); + struct wm_notify_s *notify; + int rid; + irqstate_t flags; + + DEBUGASSERT(fifo && wm); + + if (wm->watermark == 0) + { + return -EINVAL; + } + + rid = fifo->rid; + + notify = &priv->wm[rid]; + + flags = enter_critical_section(); + notify->signo = wm->signo; + notify->pid = getpid(); + notify->ts = wm->ts; + notify->fifo = fifo; + + /* Set watermark */ + + putreg32(wm->watermark, SCUFIFO_R_CTRL0(rid)); + + /* Enable FIFO almost full interrupt */ + + putreg32(1 << (rid + 9), SCU_INT_ENABLE_MAIN); + + leave_critical_section(flags); + + scuinfo("watermark = %04x, PID = %d, signo = %d\n", wm->watermark, + notify->pid, notify->signo); + + return OK; +} + +/**************************************************************************** + * Name: convert_firsttimestamp + * + * Description: + * + ****************************************************************************/ + +static void convert_firsttimestamp(struct scutimestamp_s *tm, + uint16_t interval, + uint16_t sample, uint16_t adjust) +{ + uint32_t delta; + uint32_t tick; + uint16_t mod; + + if (sample == 0 || interval == 0) + return; + + mod = sample & 0x7; + + if (adjust && mod) + { + delta = interval * (sample + (8 - mod)); + if (adjust == 1) + { + if (mod <= 2) + { + delta -= 2; + } + else if (mod <= 5) + { + delta -= 1; + } + } + } + else + { + delta = interval * sample; + } + + tick = tm->tick; + if (tick < delta) + { + tick += 0x80000000u - delta; + tm->tick = (tick & 0x00007fff); + tm->sec = tm->sec + (tick >> 15) - (0x80000000u >> 15); + } + else + { + tm->tick = tm->tick - delta; + } +} + +/**************************************************************************** + * Name: latest_timestamp + * + * Description: + * Get latest timestamp when data stored into FIFO. + * + ****************************************************************************/ + +static void latest_timestamp(struct scufifo_s *fifo, uint32_t interval, + struct scutimestamp_s *tm, uint16_t *samples) +{ + struct scutimestamp_s pre; + struct scutimestamp_s post; + uint16_t pres; + uint16_t posts; + int rid = fifo->rid; + int wid = fifo->wid; + + /* Get number of samples and timestamp twice for adapt roll over */ + + pres = getreg32(SCUFIFO_R_STATUS0(rid)) & 0xffff; + pre.sec = getreg32(SCUFIFO_W_TIMESTAMP0(wid)); + pre.tick = getreg16(SCUFIFO_W_TIMESTAMP1(wid)); + + posts = getreg32(SCUFIFO_R_STATUS0(rid)) & 0xffff; + post.sec = getreg32(SCUFIFO_W_TIMESTAMP0(wid)); + post.tick = getreg16(SCUFIFO_W_TIMESTAMP1(wid)); + + if (pres == posts) + { + *samples = pres; + tm->sec = pre.sec; + tm->tick = pre.tick; + } + else + { + *samples = posts; + tm->sec = post.sec; + tm->tick = post.tick; + if (tm->tick >= interval) + { + tm->tick -= interval; + } + else + { + tm->sec -= 1; + tm->tick += 0x8000 - interval; + } + } +} + +/**************************************************************************** + * Name: gettimestamp + * + * Description: + * Get timestamp of head of FIFO sensing data. + * + ****************************************************************************/ + +static void seq_gettimestamp(struct scufifo_s *fifo, + struct scutimestamp_s *tm) +{ + uint16_t sample; + uint16_t adjust = fifo->adjust; + uint32_t interval = fifo->interval; + + latest_timestamp(fifo, interval, tm, &sample); + + convert_firsttimestamp(tm, interval, sample, adjust); +} +#else +#define seq_setwatermark(seq, fifoid, wm) (-ENOSYS) +#endif + +/**************************************************************************** + * Name: seq_setfifomode + * + * Description: + * Enable or disable FIFO overwrite mode. + * + ****************************************************************************/ + +static void seq_setfifomode(FAR struct seq_s *seq, int fifoid, int enable) +{ + FAR struct scufifo_s *fifo = seq_getfifo(seq, fifoid); + uint32_t val; + irqstate_t flags; +#ifndef CONFIG_DISABLE_SIGNAL + FAR struct cxd56_scudev_s *priv = &g_scudev; + FAR struct wm_notify_s *notify = &priv->wm[fifo->rid]; + bool iswtmk = false; +#endif + + DEBUGASSERT(fifo); + + scuinfo("FIFO mode %d wid %d\n", enable, fifo->wid); + +#ifndef CONFIG_DISABLE_SIGNAL + if (notify->ts) + { + iswtmk = true; + } +#endif + + flags = enter_critical_section(); + + /* control SCU FIFO overwrite */ + + val = getreg32(SCUFIFO_W_CTRL1(fifo->wid)); + val &= ~(0x1 << 4); + if (enable) + { + val |= (0x1 << 4); + } + putreg32(val, SCUFIFO_W_CTRL1(fifo->wid)); + + if (enable) + { + /* disable overrun err interrupt */ + + val = 0x1 << (fifo->rid + 9); + putreg32(val, SCU_INT_DISABLE_ERR_0); + +#ifndef CONFIG_DISABLE_SIGNAL + + /* disable almostfull interrupt */ + + if (iswtmk) + { + putreg32(val, SCU_INT_DISABLE_MAIN); + } +#endif + } + else + { + /* clear overrun err */ + + putreg32(getreg32(SCUFIFO_R_CTRL1(fifo->rid)) | SCUFIFO_OVERRUNCLR, + SCUFIFO_R_CTRL1(fifo->rid)); + + /* enable overrun err interrupt */ + + val = 0x1 << (fifo->rid + 9); + putreg32(val, SCU_INT_ENABLE_ERR_0); + +#ifndef CONFIG_DISABLE_SIGNAL + + /* enable almostfull interrupt */ + + if (iswtmk) + { + val = 0x1 << (fifo->rid + 9); + putreg32(val, SCU_INT_ENABLE_MAIN); + } +#endif + } + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: seq_remakeinstruction + * + * Description: + * Workaround for the sequencer last instruction issue. + * If the last instruction is i2c write, clear TERMINATE bit. + * + ****************************************************************************/ + +static uint16_t seq_remakeinstruction(int bustype, uint16_t inst) +{ + uint16_t ret = inst; + + if (bustype == SCU_BUS_I2C0 || bustype == SCU_BUS_I2C1) + { + /* When the instruction is write, clear TERMINATE bit */ + + if (!(ret & (1 << 8))) + { + ret &= ~SCU_INST_TERM; + } + } + + return ret; +} + +/**************************************************************************** + * Name: scu_hwinit + ****************************************************************************/ + +static void scu_hwinit(void) +{ + int i; + + /* Request don't sleep */ + + seq_inhibitrequest(REQ_SLEEP, true); + + /* Disable all interrupts */ + + putreg32(0xffffffff, SCU_INT_DISABLE_MAIN); + putreg32(0xffffffff, SCU_INT_CLEAR_MAIN); + putreg32(0x0, SCU_LEVEL_SEL_MAIN); + + for (i = 0; i < 10; i++) + { + putreg32(0x08000000, SCUSEQ_MATH_PROC_OFST_GAIN_X(i)); + putreg32(0x08000000, SCUSEQ_MATH_PROC_OFST_GAIN_Y(i)); + putreg32(0x08000000, SCUSEQ_MATH_PROC_OFST_GAIN_Z(i)); + } + putreg32(0, SCU_OFST_GAIN_EN); + + putreg32(0x0f0f0f00, SCU_DECIMATION_PARAM0); + putreg32(0x0f0f0f00, SCU_DECIMATION_PARAM1); + putreg32(0xff, SCU_DEC_CLR); + + for (i = 0; i < 3; i++) + { + putreg32(0, SCU_EVENT_INTR_ENABLE(i)); + } + + /* Reset MATHFUNC */ + + putreg32(0, SCU_MATHFUNC_SEL); + putreg32(0x7, SCU_MATHFUNC_CLR); + + /* Clear MATHFUNC EVENT... */ + + putreg32(0x3f, SCU_FIFO_WRITE_CTRL); + putreg32(0x7, SCU_EVENT_STT); + + /* Reset all of FIFOs I/O */ + + for (i = 0; i < 16; i++) + { + putreg32(3, SCUSEQ_FIFOWREVNTCTRL(i)); + putreg32(0, SCUFIFO_W_CTRL0(i)); + putreg32(0x00010000, SCUFIFO_W_CTRL1(i)); + putreg32(0, SCUFIFO_W_CTRL1(i)); + } + for (i = 0; i < 14; i++) + { + putreg32(0x00010003, SCUFIFO_R_CTRL1(i)); + putreg32(0, SCUFIFO_R_CTRL1(i)); + } + + /* Decimation FIFO selection. + * All of decimation FIFO I/O linked to each IDs. + */ + + putreg32(0x00e400e4, SCUFIFO_DECI_PARTITION_SEL); + + /* Enable SPI and I2C[01] interrupts */ + + putreg32(7, SCU_INT_ENABLE_MAIN); + + /* Wait for sequencer ready */ + + while (!(getreg32(SCU_SEQ_ENABLE_ALL) & 2)); + + putreg32(((CONFIG_CXD56_SCU_PREDIV - 1) << 8), SCU_START_CTRL_COMMON); + + putreg32(1, SCU_SEQ_ENABLE_ALL); + + /* Enable SCU sleep */ + + seq_inhibitrequest(REQ_SLEEP, false); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: scu_spitransfer + ****************************************************************************/ + +int scu_spitransfer(int slavesel, FAR uint16_t *inst, uint32_t nr_insts, + FAR uint8_t *buffer, int len) +{ + return seq_oneshot(SCU_BUS_SPI, slavesel, inst, nr_insts, buffer, len); +} + +/**************************************************************************** + * Name: scu_i2ctransfer + ****************************************************************************/ + +int scu_i2ctransfer(int port, int slave, FAR uint16_t *inst, + uint32_t nr_insts, FAR uint8_t *buffer, int len) +{ + int bustype; + + if (port == 0) + { + bustype = SCU_BUS_I2C0; + } + else if (port == 1) + { + bustype = SCU_BUS_I2C1; + } + else + { + return -ENODEV; + } + + return seq_oneshot(bustype, slave, inst, nr_insts, buffer, len); +} + +/**************************************************************************** + * Name: seq_open + * + * Description: + * Open sequencer. This API should be call from board initialize or from + * drivers. + * + * Input Parameters: + * type - A type of sequencer (SEQ_TYPE_NORMAL or SEQ_TYPE_DECI) + * bustype - A type of bus under SCU (SCU_BUS_I2C0, SCU_BUS_I2C1 or + * SCU_BUS_SPI) + * + ****************************************************************************/ + +FAR struct seq_s *seq_open(int type, int bustype) +{ + FAR struct seq_s *seq; + + if (type == SEQ_TYPE_DECI) + { + seq = deci_new(); + } + else + { + seq = seq_new(); + } + if (!seq) + { + return NULL; + } + + seq->bustype = bustype; + seq->type = type; + + seq_setbus(seq->id, bustype); + + /* Disable all of data preprocessing */ + + seq_offsetgainenable(seq->id, false); + seq_setsignconversion(seq->id, 0); + + return seq; +} + +/**************************************************************************** + * Name: seq_setinstruction + * + * Description: + * Set instruction set array for sequencer execution. + * + * Input Parameters: + * seq - An instance of sequencer + * inst - Pointer of instruction array + * nr_insts - Number of instructions + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * failure. + * + ****************************************************************************/ + +int seq_setinstruction(FAR struct seq_s *seq, const uint16_t *inst, + uint16_t nr_insts) +{ + int istart; + int i; + uint16_t lastinst; + + if (nr_insts > INSTRUCTION_PER_SEQ) + { + return -EINVAL; + } + + /* Remake last instruction, if needed. */ + + lastinst = seq_remakeinstruction(seq->bustype, *(inst + nr_insts - 1)); + + /* Copy cyclic running instruction */ + + istart = seq->id * INSTRUCTION_PER_SEQ; + for (i = 0; i < nr_insts - 1; i++) + { + putreg16(inst[i], SCUSEQ_INSTRUCTION(istart + i)); + } + putreg16(lastinst, SCUSEQ_INSTRUCTION(istart + nr_insts - 1)); + + /* Set instruction parameters */ + + seq_setinst(seq->id, istart, nr_insts - 1); + + return OK; +} + +/**************************************************************************** + * Name: seq_setbytespersample + * + * Description: + * Set sample data format + * + * Input Parameters: + * seq - An instance of sequencer + * sample - Size of sample (e.g. 16 bit 3 axis data = 6) + * offset - Start offset of sampling data + * elemsize - Size of 1 element (e.g. 16 bit 3 axis data = 2) + * swapbyte - Enable/Disable byte swapping if available + * + ****************************************************************************/ + +void seq_setsample(FAR struct seq_s *seq, uint8_t sample, uint8_t offset, + uint8_t elemsize, bool swapbyte) +{ + DEBUGASSERT(seq); + + seq->sample = sample; + + seq_setdataformat(seq->id, offset, sample - 1, swapbyte ? 1 : 0, elemsize); +} + +/**************************************************************************** + * Name: seq_setaddress + * + * Description: + * Set slave ID or address + * + * Input Parameters: + * seq - An instance of sequencer + * slave_addr - In SPI, slave select ID. In I2C, bus address. + * + ****************************************************************************/ + +void seq_setaddress(FAR struct seq_s *seq, uint32_t slave_addr) +{ + seq_setproperty(seq->id, slave_addr, 0, 0, 0); +} + +#ifdef CONFIG_CXD56_UDMAC +/**************************************************************************** + * Name: seq_fifodmadone + * + * Description: + * Callback function for receive DMA done + * + ****************************************************************************/ + +static void seq_fifodmadone(DMA_HANDLE handle, uint8_t status, void *arg) +{ + struct scufifo_s *fifo = (struct scufifo_s *)arg; + fifo->dmaresult = status; + seq_semgive(&fifo->dmawait); +} +#else +/**************************************************************************** + * Name: seq_read8 + ****************************************************************************/ + +static inline void seq_read8(uint32_t addr, FAR uint8_t *buffer, int length) +{ + int i; + + for (i = 0; i < length; i++) + { + *buffer++ = getreg8(addr); + } +} + +/**************************************************************************** + * Name: seq_read16 + ****************************************************************************/ + +static inline void seq_read16(uint32_t addr, FAR uint16_t *buffer, int length) +{ + int i; + + for (i = 0; i < length / 2; i++) + { + *buffer++ = getreg16(addr); + } +} + +/**************************************************************************** + * Name: seq_read32 + ****************************************************************************/ + +static inline void seq_read32(uint32_t addr, FAR uint32_t *buffer, int length) +{ + int i; + + for (i = 0; i < length / 4; i++) + { + *buffer++ = getreg32(addr); + } +} +#endif + +/**************************************************************************** + * Name: seq_read + * + * Description: + * Read sensor data from sequencer FIFO + * + * Input Parameters: + * seq - An instance of sequencer + * fifoid - FIFO ID (decimator only) + * buffer - Pointer to data receive buffer + * length - Length of buffer + * + * Returned Value: + * Number of bytes of read data + * + ****************************************************************************/ + +int seq_read(FAR struct seq_s *seq, int fifoid, FAR char *buffer, int length) +{ + struct scufifo_s *fifo; + uint32_t outlet; + int avail; +#ifdef CONFIG_CXD56_UDMAC + dma_config_t config; + uint32_t dstbuf; + char *dst; + int maxlen = 1024; + int dmalen; + int rest; + int need_wakelock=0; + struct pm_cpu_wakelock_s wlock; + wlock.info = PM_CPUWAKELOCK_TAG('S', 'C', 0); + wlock.count = 0; +#else + int i; +#endif +#ifdef CONFIG_CXD56_SCU_DEBUG + uint32_t status; +#endif + DEBUGASSERT(seq); + DEBUGASSERT(fifoid >= 0 && fifoid < 3); + + fifo = seq_getfifo(seq, fifoid); + + DEBUGASSERT(fifo); + + outlet = SCUFIFO_FIFO_DATA(fifo->rid); + + avail = getreg32(SCUFIFO_R_STATUS0(fifo->rid)); + scuinfo("Available %d samples\n", avail); +#ifdef CONFIG_CXD56_SCU_DEBUG + status = getreg32(SCUFIFO_R_STATUS1(fifo->rid)); + scuinfo("Status: %08x\n", status); +#endif + avail *= seq->sample; + length = MIN(avail, length); + if (length == 0) + { + return 0; + } + +#ifdef CONFIG_CXD56_UDMAC + /* Get sensor data from FIFO by uDMAC (PL230) */ + /* TODO: Check DMA transfer limit or restart DMA to get all data. */ + + config.channel_cfg = CXD56_UDMA_SINGLE; + if (buffer != NULL) + { + config.channel_cfg |= CXD56_UDMA_MEMINCR; + dst = buffer; + } + else + { + config.channel_cfg |= CXD56_UDMA_NOINCR; + dst = (char *)&dstbuf; + } + + if (length & 1) + { + config.channel_cfg |= CXD56_UDMA_XFERSIZE_BYTE; + } + else if (length & 2) + { + config.channel_cfg |= CXD56_UDMA_XFERSIZE_HWORD; + maxlen = 2048; + } + else + { + config.channel_cfg |= CXD56_UDMA_XFERSIZE_WORD; + maxlen = 4096; + } + if (((uint32_t)dst >= CXD56_RAM_BASE) + && ((uint32_t)dst <= (CXD56_RAM_BASE + CXD56_RAM_SIZE))) + { + need_wakelock = 1; + up_pm_acquire_wakelock(&wlock); + } + rest = length; + while (rest > 0) + { + dmalen = MIN(rest, maxlen); + cxd56_rxudmasetup(fifo->dma, outlet, (uintptr_t)dst, dmalen, config); + cxd56_udmastart(fifo->dma, seq_fifodmadone, fifo); + + /* Wait for DMA is done */ + + seq_semtake(&fifo->dmawait); + if (fifo->dmaresult) + { + /* ERROR */ + + length = length - rest; + break; + } + dst += dmalen; + rest -= dmalen; + } + if (need_wakelock) + { + up_pm_release_wakelock(&wlock); + } +#else + /* Get sensor data from FIFO by PIO */ + + if (length & 1) + { + if (buffer != NULL) + { + seq_read8(outlet, (FAR uint8_t *)buffer, length); + } + else + { + for (i = 0; i < length; i++) + { + getreg8(outlet); + } + } + } + else if (length & 2) + { + if (buffer != NULL) + { + seq_read16(outlet, (FAR uint16_t *)buffer, length); + } + else + { + for (i = 0; i < length / 2; i++) + { + getreg16(outlet); + } + } + } + else + { + if (buffer != NULL) + { + seq_read32(outlet, (FAR uint32_t *)buffer, length); + } + else + { + for (i = 0; i < length / 4; i++) + { + getreg32(outlet); + } + } + } +#endif + + return length; +} + +/**************************************************************************** + * Name: seq_ioctl + * + * Description: + * Lower ioctl handler. SCU supported driver must call this API from it's + * ioctl(). + * + * Input Parameters: + * seq - An instance of sequencer + * fifoid - FIFO ID (0 - 3, decimator only) + * cmd - SCU ioctl command (SCUIOC_*) + * arg - Arguments for cmd + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * failure. + * + ****************************************************************************/ + +int seq_ioctl(FAR struct seq_s *seq, int fifoid, int cmd, unsigned long arg) +{ + int ret = OK; + + if (fifoid < 0 || fifoid > 2) + { + set_errno(-EINVAL); + return -1; + } + + scuinfo("cmd = %04x, arg = %08x\n", cmd, arg); + + switch (cmd) + { + /* Set FIFO memory and initialize it. Arg: uint16_t */ + + case SCUIOC_SETFIFO: + { + ret = seq_fifoinit(seq, fifoid, (uint16_t)arg); + } + break; + + /* Free FIFO memory. Arg: none */ + + case SCUIOC_FREEFIFO: + { + struct decimator_s *deci = (struct decimator_s *)seq; + FAR struct scufifo_s *fifo; + + /* Check sequencer already stopped. */ + + if (seq_fifoisactive(seq, fifoid)) + { + ret = -EBUSY; + break; + } + + if (seq->type & SEQ_TYPE_DECI) + { + fifo = deci->dfifo[fifoid].fifo; + deci->dfifo[fifoid].fifo = NULL; + } + else + { + fifo = seq->fifo; + seq->fifo = NULL; + } + seq_fifofree(fifo); + } + break; + + /* Set sampling rate. Arg: uint8_t */ + + case SCUIOC_SETSAMPLE: + { + ret = seq_setsamplingrate(seq, arg); + } + break; + + /** + * Enable/disable sign conversion feature + * Arg: unsigned long, 0 = off, other = on + */ + + case SCUIOC_SETSIGNCONV: + { + seq_setsignconversion(seq->id, arg); + } + break; + + /** + * Enable offset/gain adjustment preprocessing. + * Arg: Pointer of adjust_xyz_t + * If arg is null, just enable offset/gain (use current setting value). + */ + + case SCUIOC_SETOGADJUST: + { + if (arg) + { + FAR struct adjust_xyz_s *p = + (FAR struct adjust_xyz_s *)(uintptr_t)arg; + ret = seq_setadjustment(seq, p); + if (!ret) + { + seq_offsetgainenable(seq->id, true); + } + } + else + { + seq_offsetgainenable(seq->id, true); + } + } + break; + + /** + * Disable offset/gain adjustment preprocessing. + * Arg: None + */ + + case SCUIOC_CLROGADJUST: + { + seq_offsetgainenable(seq->id, false); + } + break; + + /** + * Set IIR filter position and coefficiencies. + * Arg: Pointer of struct math_filter_s + */ + + case SCUIOC_SETFILTER: + { + FAR struct math_filter_s *f = + (FAR struct math_filter_s *)(uintptr_t)arg; + FAR struct scufifo_s *fifo = seq_getfifo(seq, fifoid); + + if (seq_fifoisactive(seq, fifoid)) + { + ret = -EBUSY; + break; + } + + if (seq->type & SEQ_TYPE_DECI) + { + FAR struct decimator_s *dec = (struct decimator_s *)seq; + fifo = dec->dfifo[fifoid].fifo; + } + + ret = seq_setfilter(fifo, f->pos, f->filter); + } + break; + + /** + * Set event notifier + * Arg: Pointer of struct scuev_notify_s + */ + + case SCUIOC_SETNOTIFY: + { + FAR struct scuev_notify_s *en = + (FAR struct scuev_notify_s *)(uintptr_t)arg; + FAR struct scufifo_s *fifo = seq_getfifo(seq, fifoid); + + if (seq_fifoisactive(seq, fifoid)) + { + ret = -EBUSY; + break; + } + + if (seq->type & SEQ_TYPE_DECI) + { + FAR struct decimator_s *dec = (struct decimator_s *)seq; + fifo = dec->dfifo[fifoid].fifo; + } + + ret = seq_seteventnotifier(fifo, en); + } + break; + + /** + * Set number of elements per sample for mathfunc + * Arg: uint8_t + */ + + case SCUIOC_SETELEMENTS: + { + seq_setmathwritevecelenum(seq->id, (uint8_t)arg); + } + break; + + /** + * Set decimation parameters + * Arg: Pointer of struct decimation_s + */ + + case SCUIOC_SETDECIMATION: + { + FAR struct decimation_s *d = + (FAR struct decimation_s *)(uintptr_t)arg; + FAR struct decimator_s *deci = (FAR struct decimator_s *)seq; + FAR struct decimation_fifo_s *dfifo = &deci->dfifo[fifoid]; + + if (!(seq->type & SEQ_TYPE_DECI)) + { + ret = -EINVAL; + break; + } + + /** + * Now only save decimation parameters because decimation parameter + * cannot be set while sequencer running. + */ + + dfifo->ratio = d->ratio; + dfifo->leveladj = d->leveladj; + dfifo->forcethrough = d->forcethrough; + } + break; + + /** + * Set FIFO watermark + * Arg: Pointer of struct scufifo_wm_s + */ + + case SCUIOC_SETWATERMARK: + { + FAR struct scufifo_wm_s *wm = + (FAR struct scufifo_wm_s *)(uintptr_t)arg; + + ret = seq_setwatermark(seq, fifoid, wm); + } + break; + + /* Sequencer start */ + + case SCUIOC_START: + { + ret = seq_start(seq, fifoid); + } + break; + + /* Sequencer stop */ + + case SCUIOC_STOP: + { + seq_stop(seq, fifoid); + } + break; + + /* Set FIFO overwrite mode */ + + case SCUIOC_SETFIFOMODE: + { + seq_setfifomode(seq, fifoid, arg); + } + break; + + /* Delete FIFO data */ + + case SCUIOC_DELFIFODATA: + { + ret = seq_read(seq, fifoid, NULL, (uint16_t)arg); + } + break; + + default: + scuerr("Unrecognized cmd: %d\n", cmd); + ret = -EIO; + break; + } + + if (ret < 0) + { + set_errno(-ret); + } + + return ret; +} + +/**************************************************************************** + * Name: seq_close + * + * Description: + * Close sequencer + * + * Input Parameters: + * seq - An instance of sequencer + * + ****************************************************************************/ + +void seq_close(FAR struct seq_s *seq) +{ + irqstate_t flags; + + DEBUGASSERT(seq); + + if (seq->type & SEQ_TYPE_DECI) + { + FAR struct decimator_s *deci = (FAR struct decimator_s *)seq; + int i; + + flags = enter_critical_section(); + deci_free(seq->id); + leave_critical_section(flags); + + for (i = 0; i < 3; i++) + { + seq_fifofree(deci->dfifo[i].fifo); + deci->dfifo[i].fifo = NULL; + } + } + else + { + flags = enter_critical_section(); + seq_free(seq->id); + leave_critical_section(flags); + + seq_fifofree(seq->fifo); + seq->fifo = NULL; + } + + kmm_free(seq); +} + +/**************************************************************************** + * Name: scu_initialize + ****************************************************************************/ + +void scu_initialize(void) +{ + struct cxd56_scudev_s *priv = &g_scudev; + int i; + +#ifdef CONFIG_CXD56_UDMAC + cxd56_udmainitialize(); +#endif + + memset(priv, 0, sizeof(struct cxd56_scudev_s)); + + sem_init(&priv->syncwait, 0, 0); + sem_init(&priv->syncexc, 0, 1); + + for (i = 0; i < 3; i++) + { + sem_init(&priv->oneshotwait[i], 0, 0); + } + + scufifo_initialize(); + + /** + * If SCU clock has been already enabled, keep SCU running without loading + * and reset of SCU firmware. + */ + + if (false == cxd56_scuseq_clock_is_enabled()) + { + /** + * Enable SCU clock. This process must do before loading firmware + * because SCU instruction RAM is not accessible. + */ + + cxd56_scuseq_clock_enable(); + + /* Load firmware & clear data RAM */ + + memcpy((void *)CXD56_SCU_SEQ_IRAM_BASE, scuIsopProgArray, + sizeOfscuIsopProgArray); + memset((void *)CXD56_SCU_SEQ_DRAM_BASE, 0, 0x324); + + /* Release SCU reset to bring up SCU firmware */ + + cxd56_scuseq_release_reset(); + + /* Initialize SCU registers */ + + scu_hwinit(); + } + + /* Enable error interrupt */ + + putreg32(0x007ffe00, SCU_INT_ENABLE_ERR_0); + putreg32(0x03ff, SCU_INT_ENABLE_ERR_2); + + /* Enable SCU IRQ */ + + irq_attach(CXD56_IRQ_SCU_3, seq_scuirqhandler, &g_scudev); + up_enable_irq(CXD56_IRQ_SCU_3); +} + +/**************************************************************************** + * Name: scu_uninitialize + ****************************************************************************/ + +void scu_uninitialize(void) +{ + struct cxd56_scudev_s *priv = &g_scudev; + int i; + + /* Request don't sleep */ + + seq_inhibitrequest(REQ_SLEEP, true); + + up_disable_irq(CXD56_IRQ_SCU_3); + + cxd56_scuseq_clock_disable(); + + sem_destroy(&priv->syncwait); + sem_destroy(&priv->syncexc); + + for (i = 0; i < 3; i++) + { + sem_destroy(&priv->oneshotwait[i]); + } +} diff --git a/arch/arm/src/cxd56xx/cxd56_scufifo.c b/arch/arm/src/cxd56xx/cxd56_scufifo.c new file mode 100644 index 0000000000..8aa5c7110f --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_scufifo.c @@ -0,0 +1,214 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_scufifo.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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 files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "chip.h" +#include "up_arch.h" + +#include "cxd56_scufifo.h" +#include "hardware/cxd56_scufifo.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define FIFOMEMSIZE 40960 + +#define __unused __attribute__((unused)) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct memchunk +{ + struct memchunk *next; + uint16_t start; + uint16_t size; +}; + +struct fifomem +{ + struct memchunk chunk[14]; + struct memchunk *allocated; + struct memchunk *freelist; + uint16_t size; +}; + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +struct fifomem g_fifomem; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: fifomem_alloc + * + * Description: + * Allocate FIFO memory + * + ****************************************************************************/ + +uint16_t scufifo_memalloc(uint16_t size) +{ + struct memchunk *c; + struct memchunk *last; + uint16_t start; + + if (g_fifomem.size < size) + { + return FIFOMEM_INVALID; + } + + if (g_fifomem.freelist == NULL) + { + return FIFOMEM_INVALID; + } + + start = 0; + last = NULL; + for (c = g_fifomem.allocated; c; c = c->next) + { + start = c->start + c->size; + last = c; + if (c->next && c->next->start - start > size) + { + break; + } + } + + if (start + size > g_fifomem.size) + { + return FIFOMEM_INVALID; + } + + /* Remove from free list */ + + c = g_fifomem.freelist; + g_fifomem.freelist = c->next; + + /* Append file chunk */ + + if (last == NULL) + { + g_fifomem.allocated = c; + c->next = NULL; + } + else + { + c->next = last->next; + last->next = c; + } + + c->start = start; + c->size = size; + + return start; +} + +/**************************************************************************** + * Name: scufifo_memfree + * + * Description: + * Free allocated FIFO memory + * + ****************************************************************************/ + +void scufifo_memfree(uint16_t start) +{ + struct memchunk *c; + struct memchunk *prev; + + prev = g_fifomem.allocated; + for (c = g_fifomem.allocated; c; c = c->next) + { + if (c->start == start) + { + if (g_fifomem.allocated == c) + { + g_fifomem.allocated = c->next; + } + else + { + prev->next = c->next; + } + + c->next = g_fifomem.freelist; + g_fifomem.freelist = c; + break; + } + prev = c; + } +} + +/**************************************************************************** + * Name: scufifo_initialize + * + * Description: + * Initialize FIFO memory allocator + * + ****************************************************************************/ + +void scufifo_initialize(void) +{ + struct memchunk *c; + int i; + + g_fifomem.allocated = NULL; + g_fifomem.freelist = g_fifomem.chunk; + g_fifomem.size = FIFOMEMSIZE; + + for (i = 1, c = g_fifomem.freelist; i < 14; i++, c = c->next) + { + c->size = 0; + c->next = &g_fifomem.chunk[i]; + } + c->next = NULL; +} diff --git a/arch/arm/src/cxd56xx/cxd56_scufifo.h b/arch/arm/src/cxd56xx/cxd56_scufifo.h new file mode 100644 index 0000000000..a4031693f3 --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_scufifo.h @@ -0,0 +1,84 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_scufifo.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_SCUFIFO_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_SCUFIFO_H + +/**************************************************************************** + * include files + ****************************************************************************/ + +#define FIFOMEM_INVALID 0xffff + +/**************************************************************************** + * Name: scufifo_initialize + * + * Description: + * Initialize SCU FIFO memory management + * + ****************************************************************************/ + +void scufifo_initialize(void); + +/**************************************************************************** + * Name: scufifo_memalloc + * + * Description: + * Allocate SCU FIFO memory + * + * Input Parameters: + * size - Request memory size + * + * Returned Value: + * Allocated FIFO memory start offset. If error, return FIFOMEM_INVALID. + * + ****************************************************************************/ + +uint16_t scufifo_memalloc(uint16_t size); + +/**************************************************************************** + * Name: scufifo_memfree + * + * Description: + * Free allocated SCU FIFO memory + * + * Input Parameters: + * start - Start offset of FIFO memory + * + ****************************************************************************/ + +void scufifo_memfree(uint16_t start); + +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_SCUFIFO_H */ diff --git a/arch/arm/src/cxd56xx/cxd56_sysctl.h b/arch/arm/src/cxd56xx/cxd56_sysctl.h index 6742109dbc..c66f85e342 100644 --- a/arch/arm/src/cxd56xx/cxd56_sysctl.h +++ b/arch/arm/src/cxd56xx/cxd56_sysctl.h @@ -32,9 +32,6 @@ * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************/ -/** - * @file cxd56_sysctl.h - */ #ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_SYSCTL_H #define __ARCH_ARM_SRC_CXD56XX_CXD56_SYSCTL_H diff --git a/arch/arm/src/cxd56xx/cxd56_udmac.c b/arch/arm/src/cxd56xx/cxd56_udmac.c new file mode 100644 index 0000000000..2cc4023290 --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_udmac.c @@ -0,0 +1,780 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_udmac.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "cxd56_clock.h" +#include "hardware/cxd56_udmac.h" +#include "cxd56_udmac.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ALIGN_MASK(s) ((1 << s) - 1) +#define ALIGN_DOWN(v, m) ((v) & ~m) +#define ALIGN_UP(v, m) (((v) + (m)) & ~m) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* This structure describes one DMA channel */ + +struct dma_channel_s +{ + uint8_t chan; /* DMA channel number (0-CXD56_DMA_NCHANNELS) */ + bool inuse; /* TRUE: The DMA channel is in use */ + dma_config_t config; /* Current configuration */ + dma_callback_t callback; /* Callback invoked when the DMA completes */ + void *arg; /* Argument passed to callback function */ +}; + +/* This structure describes the state of the DMA controller */ + +struct dma_controller_s +{ + sem_t exclsem; /* Protects channel table */ + sem_t chansem; /* Count of free channels */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This is the overall state of the DMA controller */ + +static struct dma_controller_s g_dmac; + +/* This is the array of all DMA channels */ + +static struct dma_channel_s g_dmach[CXD56_DMA_NCHANNELS]; + +/* This array describes the available channel control data structures. Each + * structure must be aligned to a 256 address boundary. The last 8 or 9 + * bits of address are provided by the DMA controller: + * + * 8-Channels: + * Bit 7: Selects the alternate descriptor list + * Bits 4-6: The DMA channel (0-7) + * Bits 2-3: Selects the descriptor field + * Bits 0-1: Always zero + * + * 12-Channels: + * Bit 8: Selects the alternate descriptor list + * Bits 4-7: The DMA channel (0-11) + * Bits 2-3: Selects the descriptor field + * Bits 0-1: Always zero + */ + +#if CXD56_DMA_NCHANNELS <= 8 +#define DESC_TABLE_SIZE 8 +#define DESC_TABLE_ALIGN 256 /* 2*8*16 */ +#elif CXD56_DMA_NCHANNELS <= 16 +#define DESC_TABLE_SIZE 16 +#define DESC_TABLE_ALIGN 512 /* 2*16*16 */ +#elif CXD56_DMA_NCHANNELS <= 32 +#define DESC_TABLE_SIZE 32 +#define DESC_TABLE_ALIGN 1024 /* 2*16*16 */ +#else +# error Unknown descriptor table size +#endif + +static struct dma_descriptor_s g_descriptors[CXD56_DMA_NCHANNELS] + __attribute__((aligned(DESC_TABLE_ALIGN))); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: cxd56_align_shift + * + * Description: + * Set the channel control register + * + ****************************************************************************/ + +static inline unsigned int cxd56_align_shift(dma_config_t config) +{ + unsigned int shift; + + shift = (config.channel_cfg & CXD56_UDMA_XFERSIZE_MASK) >> + CXD56_UDMA_XFERSIZE_SHIFT; + DEBUGASSERT(shift != 3); + return shift; +} + +/**************************************************************************** + * Name: cxd56_get_descriptor + * + * Description: + * Get the address of the primary or alternate descriptor assigned to the + * DMA channel + * + ****************************************************************************/ + +static inline struct dma_descriptor_s *cxd56_get_descriptor( + struct dma_channel_s *dmach, bool alt) +{ + uintptr_t base; + + base = alt ? getreg32(CXD56_DMA_ALTCTRLBASE) : getreg32(CXD56_DMA_CTRLBASE); + return ((struct dma_descriptor_s *)base) + dmach->chan; +} + +/**************************************************************************** + * Name: cxd56_dmac_interrupt + * + * Description: + * DMA interrupt handler + * + ****************************************************************************/ + +static int cxd56_dmac_interrupt(int irq, void *context, FAR void *arg) +{ + struct dma_channel_s *dmach; + unsigned int chndx; + int done; + int err; + int mask; + int result = OK; + + chndx = irq - CXD56_IRQ_DMA_A_0; + + mask = 1 << chndx; + done = getreg32(CXD56_DMA_DONE); + err = getreg32(CXD56_DMA_ERR); + if (err & mask) + { + putreg32(mask, CXD56_DMA_ERR); + result = EIO; + } + if (done & mask) + { + /* Clear DMA done status */ + + putreg32(mask, CXD56_DMA_DONE); + } + + dmach = &g_dmach[chndx]; + + /* Put the DMA channel in the stopped state */ + + cxd56_udmastop((DMA_HANDLE)dmach); + + /* Call the DMA completion callback */ + + if (dmach->callback) + { + dmach->callback((DMA_HANDLE)dmach, result, dmach->arg); + dmach->callback = NULL; + } + + dmach->arg = NULL; + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: cxd56_udmainitialize + * + * Description: + * Initialize the DMA subsystem + * + * Returned Value: + * None + * + ****************************************************************************/ + +void cxd56_udmainitialize(void) +{ + int i; + + dmainfo("Initialize uDMAC\n"); + + /* Initialize the channel list */ + + sem_init(&g_dmac.exclsem, 0, 1); + sem_init(&g_dmac.chansem, 0, CXD56_DMA_NCHANNELS); + + for (i = 0; i < CXD56_DMA_NCHANNELS; i++) + { + g_dmach[i].chan = i; + } + + /* Enable clocking to the DMA module. */ + + cxd56_udmac_clock_enable(); + + /* Set the control base addresses. Note: CXD56_DMA_ALTCTRLBASE + * is a read-only register that provides the location where hardware + * will obtain the alternative descriptors. + */ + + putreg32((uint32_t)g_descriptors, CXD56_DMA_CTRLBASE); + + /* Enable the DMA controller */ + + putreg32(DMA_CFG_EN, CXD56_DMA_CFG); +} + +/**************************************************************************** + * Name: cxd56_udmachannel + * + * Description: + * Allocate a DMA channel. This function gives the caller mutually + * exclusive access to a DMA channel. + * + * If no DMA channel is available, then cxd56_udmachannel() will wait + * until the holder of a channel relinquishes the channel by calling + * cxd56_dmafree(). + * + * Input parameters: + * None + * + * Returned Value: + * This function ALWAYS returns a non-NULL, void* DMA channel handle. + * + * Assumptions: + * - The caller can wait for a DMA channel to be freed if it is not + * available. + * + ****************************************************************************/ + +DMA_HANDLE cxd56_udmachannel(void) +{ + struct dma_channel_s *dmach; + unsigned int ch; + uint32_t bit; + + /* Take a count from from the channel counting semaphore. We may block + * if there are no free channels. When we get the count, then we can + * be assured that a channel is available in the channel list and is + * reserved for us. + */ + + while (sem_wait(&g_dmac.chansem) < 0) + { + /* sem_wait should fail only if it is awakened by a a signal */ + + DEBUGASSERT(errno == EINTR); + } + + /* Get exclusive access to the DMA channel list */ + + while (sem_wait(&g_dmac.exclsem) < 0) + { + /* sem_wait should fail only if it is awakened by a a signal */ + + DEBUGASSERT(errno == EINTR); + } + + /* Search for an available DMA channel */ + + for (ch = 0, dmach = NULL; ch < CXD56_DMA_NCHANNELS; ch++) + { + struct dma_channel_s *candidate = &g_dmach[ch]; + if (!candidate->inuse) + { + dmach = candidate; + dmach->inuse = true; + + bit = 1 << ch; + + /* Disable the channel */ + + putreg32(bit, CXD56_DMA_CHENC); + break; + } + } + + sem_post(&g_dmac.exclsem); + + /* Attach DMA interrupt vector */ + + (void)irq_attach(CXD56_IRQ_DMA_A_0 + ch, cxd56_dmac_interrupt, NULL); + + /* Enable the IRQ at the AIC (still disabled at the DMA controller) */ + + up_enable_irq(CXD56_IRQ_DMA_A_0 + ch); + + /* Since we have reserved a DMA descriptor by taking a count from chansem, + * it would be a serious logic failure if we could not find a free channel + * for our use. + */ + + DEBUGASSERT(dmach); + return (DMA_HANDLE)dmach; +} + +/**************************************************************************** + * Name: cxd56_udmafree + * + * Description: + * Release a DMA channel. If another thread is waiting for this DMA channel + * in a call to cxd56_udmachannel, then this function will re-assign the + * DMA channel to that thread and wake it up. NOTE: The 'handle' used + * in this argument must NEVER be used again until cxd56_udmachannel() is + * called again to re-gain access to the channel. + * + * Returned Value: + * None + * + * Assumptions: + * - The caller holds the DMA channel. + * - There is no DMA in progress + * + ****************************************************************************/ + +void cxd56_udmafree(DMA_HANDLE handle) +{ + struct dma_channel_s *dmach = (struct dma_channel_s *)handle; + + DEBUGASSERT(dmach != NULL && dmach->inuse); + dmainfo("DMA channel %d\n", dmach->chan); + + /* Disable the channel */ + + putreg32(1 << dmach->chan, CXD56_DMA_CHENC); + + /* Mark the channel no longer in use. Clearing the in-use flag is an atomic + * operation and so should be safe. + */ + + dmach->inuse = false; + + /* And increment the count of free channels... possibly waking up a + * thread that may be waiting for a channel. + */ + + sem_post(&g_dmac.chansem); +} + +/**************************************************************************** + * Name: cxd56_rxudmasetup + * + * Description: + * Configure an RX (peripheral-to-memory) DMA before starting the transfer. + * + * Input Parameters: + * paddr - Peripheral address (source) + * maddr - Memory address (destination) + * nbytes - Number of bytes to transfer. Must be an even multiple of the + * configured transfer size. + * config - Channel configuration selections + * + ****************************************************************************/ + +void cxd56_rxudmasetup(DMA_HANDLE handle, uintptr_t paddr, uintptr_t maddr, + size_t nbytes, dma_config_t config) +{ + struct dma_channel_s *dmach = (struct dma_channel_s *)handle; + struct dma_descriptor_s *desc; + unsigned int xfersize; + unsigned int shift; + uint32_t regval; + uint32_t incr; + uint32_t mask; + + DEBUGASSERT(dmach != NULL && dmach->inuse); + + /* Get the properly alignment shift and mask */ + + shift = cxd56_align_shift(config); + mask = ALIGN_MASK(shift); + + /* Make sure that the number of bytes we are asked to transfer is a multiple + * of the transfer size. + */ + + xfersize = (1 << shift); + nbytes = ALIGN_DOWN(nbytes, mask); + DEBUGASSERT(nbytes > 0); + + /* Save the configuration (for cxd56_udmastart()). */ + + dmach->config = config; + + /* Configure the primary channel descriptor */ + + desc = cxd56_get_descriptor(dmach, false); + desc->srcend = (uint32_t *)paddr; + desc->dstend = (uint32_t *)(maddr + nbytes - xfersize); + + /* No source increment, destination increments according to transfer size. + * No privileges. Arbitrate after each transfer. Default priority. + */ + + regval = DMA_CTRL_SRC_INC_NONE | DMA_CTRL_DST_PROT_NON_PRIVILEGED | + DMA_CTRL_SRC_PROT_NON_PRIVILEGED | DMA_CTRL_R_POWER_2 | + DMA_CTRL_CYCLE_CTRL_AUTO; + + switch (shift) + { + default: + case 0: /* Byte transfer */ + regval |= DMA_CTRL_DST_SIZE_BYTE | DMA_CTRL_SRC_SIZE_BYTE; + incr = DMA_CTRL_DST_INC_BYTE; + break; + + case 1: /* Half word transfer */ + regval |= DMA_CTRL_DST_SIZE_HALFWORD | DMA_CTRL_SRC_SIZE_HALFWORD; + incr = DMA_CTRL_DST_INC_HALFWORD; + break; + + case 2: /* Word transfer */ + regval |= DMA_CTRL_DST_SIZE_WORD | DMA_CTRL_SRC_SIZE_WORD; + incr = DMA_CTRL_DST_INC_WORD; + break; + } + + /* Do we need to increment the memory address? */ + + if ((config.channel_cfg & CXD56_UDMA_MEMINCR_MASK) == CXD56_UDMA_MEMINCR) + { + regval |= incr; + } + else + { + regval |= DMA_CTRL_DST_INC_NONE; + } + + /* Set the number of transfers (minus 1) */ + + DEBUGASSERT((nbytes >> shift) < 1024); + regval |= DMA_CTRL_N_MINUS_1((nbytes >> shift) - 1); + desc->ctrl = regval; + desc->user = 0; +} + +/**************************************************************************** + * Name: cxd56_txudmasetup + * + * Description: + * Configure an TX (memory-to-memory) DMA before starting the transfer. + * + * Input Parameters: + * paddr - Peripheral address (destination) + * maddr - Memory address (source) + * nbytes - Number of bytes to transfer. Must be an even multiple of the + * configured transfer size. + * config - Channel configuration selections + * + ****************************************************************************/ + +void cxd56_txudmasetup(DMA_HANDLE handle, uintptr_t paddr, uintptr_t maddr, + size_t nbytes, dma_config_t config) +{ + struct dma_channel_s *dmach = (struct dma_channel_s *)handle; + struct dma_descriptor_s *desc; + unsigned int xfersize; + unsigned int shift; + uint32_t regval; + uint32_t incr; + uint32_t mask; + + DEBUGASSERT(dmach != NULL && dmach->inuse); + + /* Get the properly alignment shift and mask */ + + shift = cxd56_align_shift(config); + mask = ALIGN_MASK(shift); + + /* Make sure that the number of bytes we are asked to transfer is a multiple + * of the transfer size. + */ + + xfersize = (1 << shift); + nbytes = ALIGN_DOWN(nbytes, mask); + DEBUGASSERT(nbytes > 0); + + /* Save the configuration (for cxd56_udmastart()). */ + + dmach->config = config; + + /* Configure the primary channel descriptor */ + + desc = cxd56_get_descriptor(dmach, false); + desc->srcend = (uint32_t *)(maddr + nbytes - xfersize); + desc->dstend = (uint32_t *)paddr; + + /* No destination increment, source increments according to transfer size. + * No privileges. Arbitrate after each transfer. Default priority. + */ + + regval = DMA_CTRL_DST_INC_NONE | DMA_CTRL_DST_PROT_NON_PRIVILEGED | + DMA_CTRL_SRC_PROT_NON_PRIVILEGED | DMA_CTRL_R_POWER_2 | + DMA_CTRL_CYCLE_CTRL_AUTO; + + switch (shift) + { + default: + case 0: /* Byte transfer */ + regval |= DMA_CTRL_DST_SIZE_BYTE | DMA_CTRL_SRC_SIZE_BYTE; + incr = DMA_CTRL_SRC_INC_BYTE; + break; + + case 1: /* Half word transfer */ + regval |= DMA_CTRL_DST_SIZE_HALFWORD | DMA_CTRL_SRC_SIZE_HALFWORD; + incr = DMA_CTRL_SRC_INC_HALFWORD; + break; + + case 2: /* Word transfer */ + regval |= DMA_CTRL_DST_SIZE_WORD | DMA_CTRL_SRC_SIZE_WORD; + incr = DMA_CTRL_SRC_INC_WORD; + break; + } + + /* Do we need to increment the memory address? */ + + if ((config.channel_cfg & CXD56_UDMA_MEMINCR_MASK) == CXD56_UDMA_MEMINCR) + { + regval |= incr; + } + + /* Set the number of transfers (minus 1) */ + + DEBUGASSERT((nbytes >> shift) < 1024); + regval |= DMA_CTRL_N_MINUS_1((nbytes >> shift) - 1); + desc->ctrl = regval; + desc->user = 0; +} + +/**************************************************************************** + * Name: cxd56_udmastart + * + * Description: + * Start the DMA transfer + * + * Assumptions: + * - DMA handle allocated by cxd56_udmachannel() + * - No DMA in progress + * + ****************************************************************************/ + +void cxd56_udmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg) +{ + struct dma_channel_s *dmach = (struct dma_channel_s *)handle; + irqstate_t flags; + uint32_t bit; + + DEBUGASSERT(dmach && dmach->inuse); + + /* Save the DMA complete callback info */ + + dmach->callback = callback; + dmach->arg = arg; + + /* Finish configuring the channel */ + + bit = 1 << dmach->chan; + if ((dmach->config.channel_cfg & CXD56_UDMA_SINGLE_MASK) == + CXD56_UDMA_BUFFER_FULL) + { + /* Disable the single requests for the channel + * (i.e. do not react to data + * available, wait for buffer full) + */ + + putreg32(bit, CXD56_DMA_CHUSEBURSTS); + + /* Enable buffer-full requests for the channel */ + + putreg32(bit, CXD56_DMA_CHREQMASKC); + } + else + { + /* Enable the single requests for the channel */ + + putreg32(bit, CXD56_DMA_CHUSEBURSTC); + + /* Disable buffer-full requests for the channel */ + + putreg32(bit, CXD56_DMA_CHREQMASKS); + } + + /* Use the primary data structure for the channel */ + + putreg32(bit, CXD56_DMA_CHALTC); + + flags = enter_critical_section(); + + /* Enable the channel */ + + putreg32(bit, CXD56_DMA_CHENS); + + /* Generate a software DMA request */ + + putreg32(bit, CXD56_DMA_CHSWREQUEST); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: cxd56_udmastop + * + * Description: + * Cancel the DMA. After cxd56_udmastop() is called, the DMA channel is + * reset and cxd56_udmasetup() must be called before cxd56_udmastart() + * can be called again + * + * Assumptions: + * - DMA handle allocated by cxd56_udmachannel() + * + ****************************************************************************/ + +void cxd56_udmastop(DMA_HANDLE handle) +{ + struct dma_channel_s *dmach = (struct dma_channel_s *)handle; + irqstate_t flags; + uint32_t bit; + + DEBUGASSERT(dmach); + bit = 1 << dmach->chan; + + /* Disable the channel */ + + flags = enter_critical_section(); + putreg32(bit, CXD56_DMA_CHENC); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: cxd56_udmasample + * + * Description: + * Sample DMA register contents + * + * Assumptions: + * - DMA handle allocated by cxd56_udmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void cxd56_udmasample(DMA_HANDLE handle, struct cxd56_udmaregs_s *regs) +{ + struct dma_channel_s *dmach = (struct dma_channel_s *)handle; + struct dma_descriptor_s *desc; + irqstate_t flags; + + /* Sample DMA registers. */ + + flags = enter_critical_section(); + + regs->status = getreg32(CXD56_DMA_STATUS); + regs->ctrlbase = getreg32(CXD56_DMA_CTRLBASE); + regs->altctrlbase = getreg32(CXD56_DMA_ALTCTRLBASE); + regs->chwaitstatus = getreg32(CXD56_DMA_CHWAITSTATUS); + regs->chusebursts = getreg32(CXD56_DMA_CHUSEBURSTS); + regs->chreqmasks = getreg32(CXD56_DMA_CHREQMASKS); + regs->chens = getreg32(CXD56_DMA_CHENS); + regs->chalts = getreg32(CXD56_DMA_CHALTS); + regs->chpris = getreg32(CXD56_DMA_CHPRIS); + regs->errorc = getreg32(CXD56_DMA_ERRORC); + regs->done = getreg32(CXD56_DMA_DONE); + regs->err = getreg32(CXD56_DMA_ERR); + + desc = cxd56_get_descriptor(dmach, false); + + regs->srcend = (uint32_t)(uintptr_t)desc->srcend; + regs->dstend = (uint32_t)(uintptr_t)desc->dstend; + regs->ctrl = desc->ctrl; + + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: cxd56_udmadump + * + * Description: + * Dump previously sampled DMA register contents + * + * Assumptions: + * - DMA handle allocated by cxd56_udmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void cxd56_udmadump(DMA_HANDLE handle, const struct cxd56_udmaregs_s *regs, + const char *msg) +{ + dmainfo("%s\n", msg); + dmainfo(" DMA Registers:\n"); + dmainfo(" STATUS: %08x\n", regs->status); + dmainfo(" CTRLBASE: %08x\n", regs->ctrlbase); + dmainfo(" ALTCTRLBASE: %08x\n", regs->altctrlbase); + dmainfo(" CHWAITSTATUS: %08x\n", regs->chwaitstatus); + dmainfo(" CHUSEBURSTS: %08x\n", regs->chusebursts); + dmainfo(" CHREQMASKS: %08x\n", regs->chreqmasks); + dmainfo(" CHENS: %08x\n", regs->chens); + dmainfo(" CHALTS: %08x\n", regs->chalts); + dmainfo(" CHPRIS: %08x\n", regs->chpris); + dmainfo(" ERRORC: %08x\n", regs->errorc); + dmainfo(" DONE: %08x\n", regs->done); + dmainfo(" ERR: %08x\n", regs->err); + dmainfo(" Descriptors:\n"); + dmainfo(" SRCEND: %08x\n", regs->srcend); + dmainfo(" DSTEND: %08x\n", regs->dstend); + dmainfo(" CTRL: %08x\n", regs->ctrl); +} +#endif diff --git a/arch/arm/src/cxd56xx/cxd56_udmac.h b/arch/arm/src/cxd56xx/cxd56_udmac.h new file mode 100644 index 0000000000..fea1b5674d --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_udmac.h @@ -0,0 +1,273 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_udmac.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_UDMAC_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_UDMAC_H + +#include + +#include "cxd56_dmac_common.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Bit encoded input parameter to cxd56_channel(). These encodings must fit + * in the an unsigned integer of type dma_config_t. + * + * Current limitations/assumptions in the encoding: + * + * - RX transfers are peripheral to memory + * - TX transfers are memory to peripheral + * - Memory address is always incremented. + */ + +#define CXD56_UDMA_XFERSIZE_SHIFT (10) /* Bits 10-11: Transfer size */ +#define CXD56_UDMA_XFERSIZE_MASK (3 << CXD56_UDMA_XFERSIZE_SHIFT) +#define CXD56_UDMA_XFERSIZE_BYTE (0 << CXD56_UDMA_XFERSIZE_SHIFT) +#define CXD56_UDMA_XFERSIZE_HWORD (1 << CXD56_UDMA_XFERSIZE_SHIFT) +#define CXD56_UDMA_XFERSIZE_WORD (2 << CXD56_UDMA_XFERSIZE_SHIFT) + +#define CXD56_UDMA_SINGLE_MASK (1 << 12) /* Bit 12: Single or Buffer full request */ +#define CXD56_UDMA_SINGLE (1 << 12) /* 1=Buffer full request */ +#define CXD56_UDMA_BUFFER_FULL (0) /* 0=Buffer full request */ + +#define CXD56_UDMA_MEMINCR_MASK (1 << 13) /* Bit 13: Increment memory address */ +#define CXD56_UDMA_MEMINCR (1 << 13) /* 1=Increment memory address */ +#define CXD56_UDMA_NOINCR (0) /* 0=No memory address increment */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +struct cxd56_udmaregs_s +{ + uint32_t status; /* DMA Status Register */ + uint32_t ctrlbase; /* Channel Control Data Base Pointer Register */ + uint32_t altctrlbase; /* Channel Alternate Control Data Base Pointer Register */ + uint32_t chwaitstatus; /* Channel Wait on Request Status Register */ + uint32_t chusebursts; /* Channel Useburst Set Register */ + uint32_t chreqmasks; /* Channel Request Mask Set Register */ + uint32_t chens; /* Channel Enable Set Register */ + uint32_t chalts; /* Channel Alternate Set Register */ + uint32_t chpris; /* Channel Priority Set Register */ + uint32_t errorc; /* Bus Error Clear Register */ + uint32_t done; /* Done status (CXD5602 only) */ + uint32_t err; /* Error status (CXD5602 only) */ + + uint32_t srcend; + uint32_t dstend; + uint32_t ctrl; +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: cxd56_udmachannel + * + * Description: + * Allocate a DMA channel. This function gives the caller mutually + * exclusive access to a DMA channel. + * + * If no DMA channel is available, then cxd56_udmachannel() will wait until + * the holder of a channel relinquishes the channel by calling + * cxd56_udmafree(). + * + * Input parameters: + * None + * + * Returned Value: + * This function ALWAYS returns a non-NULL, void* DMA channel handle. + * + * Assumptions: + * - The caller can wait for a DMA channel to be freed if it is + * not available. + * + ****************************************************************************/ + +DMA_HANDLE cxd56_udmachannel(void); + +/**************************************************************************** + * Name: cxd56_udmafree + * + * Description: + * Release a DMA channel. If another thread is waiting for this DMA + * channel in a call to cxd56_udmachannel, then this function will re-assign + * the DMA channel to that thread and wake it up. + * NOTE: The 'handle' used in this argument must NEVER be used again until + * cxd56_udmachannel() is called again to re-gain access to the channel. + * + * Returned Value: + * None + * + * Assumptions: + * - The caller holds the DMA channel. + * - There is no DMA in progress + * + ****************************************************************************/ + +void cxd56_udmafree(DMA_HANDLE handle); + +/**************************************************************************** + * Name: cxd56_rxudmasetup + * + * Description: + * Configure an RX (peripheral-to-memory) DMA before starting the transfer. + * + * Input Parameters: + * paddr - Peripheral address (source) + * maddr - Memory address (destination) + * nbytes - Number of bytes to transfer. Must be an even multiple of the + * configured transfer size. + * config - Channel configuration selections + * + ****************************************************************************/ + +void cxd56_rxudmasetup(DMA_HANDLE handle, uintptr_t paddr, uintptr_t maddr, + size_t nbytes, dma_config_t config); + +/**************************************************************************** + * Name: cxd56_txudmasetup + * + * Description: + * Configure an TX (memory-to-memory) DMA before starting the transfer. + * + * Input Parameters: + * paddr - Peripheral address (destination) + * maddr - Memory address (source) + * nbytes - Number of bytes to transfer. Must be an even multiple of the + * configured transfer size. + * config - Channel configuration selections + * + ****************************************************************************/ + +void cxd56_txudmasetup(DMA_HANDLE handle, uintptr_t paddr, uintptr_t maddr, + size_t nbytes, dma_config_t config); + +/**************************************************************************** + * Name: cxd56_udmastart + * + * Description: + * Start the DMA transfer + * + * Assumptions: + * - DMA handle allocated by cxd56_udmachannel() + * - No DMA in progress + * + ****************************************************************************/ + +void cxd56_udmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg); + +/**************************************************************************** + * Name: cxd56_udmastop + * + * Description: + * Cancel the DMA. After cxd56_udmastop() is called, the DMA channel is + * reset and cxd56_udmasetup() must be called before cxd56_udmastart() can + * be called again. + * + * Assumptions: + * - DMA handle allocated by cxd56_udmachannel() + * + ****************************************************************************/ + +void cxd56_udmastop(DMA_HANDLE handle); + +/**************************************************************************** + * Name: cxd56_udmasample + * + * Description: + * Sample DMA register contents + * + * Assumptions: + * - DMA handle allocated by cxd56_udmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void cxd56_udmasample(DMA_HANDLE handle, struct cxd56_udmaregs_s *regs); +#else +#define cxd56_udmasample(handle,regs) +#endif + +/**************************************************************************** + * Name: cxd56_udmadump + * + * Description: + * Dump previously sampled DMA register contents + * + * Assumptions: + * - DMA handle allocated by cxd56_udmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void cxd56_udmadump(DMA_HANDLE handle, const struct cxd56_udmaregs_s *regs, + const char *msg); +#else +#define cxd56_udmadump(handle,regs,msg) +#endif + +void cxd56_udmainitialize(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_UDMAC_H */ diff --git a/arch/arm/src/cxd56xx/hardware/cxd5602_isop.h b/arch/arm/src/cxd56xx/hardware/cxd5602_isop.h new file mode 100644 index 0000000000..89e3d5c390 --- /dev/null +++ b/arch/arm/src/cxd56xx/hardware/cxd5602_isop.h @@ -0,0 +1,444 @@ +/* This file is generated at May 18 2016 16:19:52 */ + +const unsigned long scuIsopProgArray[] = { +0xf7f8d600, 0xa2024f86, 0x0001a200, 0x18004081, +0x00008014, 0x00000000, 0x0000a207, 0x00000000, +0x0000a070, 0xac2d4ec6, 0xd000ac27, 0x50a2e444, +0x70111801, 0x50011c01, 0xf34cd000, 0x0004800a, +0x40110114, 0x50031f43, 0x9ff42801, 0x90062911, +0x8fec5043, 0x00140003, 0x40640113, 0x1f344011, +0x9fe42121, 0xd2005001, 0x5203f356, 0x50155004, +0x04150845, 0x90082905, 0x2d444014, 0x00259ff2, +0x40110115, 0x21311f54, 0xd1009fe4, 0x5ff2e824, +0xe808d400, 0x01f8fc43, 0x07fffc33, 0xe804d000, +0xf000d700, 0x1c431c12, 0xe800d100, 0x1c025013, +0x0103fc40, 0x0300fc30, 0xf3d8d200, 0x1c135be4, +0xe418d100, 0x1c105003, 0xf47250a1, 0x1c230300, +0x0004f721, 0xf7235e61, 0xf7230005, 0xf7230016, +0x00250017, 0x4fc10215, 0xf7531d53, 0xf753fffe, +0x2141ffff, 0xd1009fee, 0xd209f33c, 0xd000ec00, +0x5004f4b8, 0x1c125005, 0x0304f470, 0x44020002, +0x0308f472, 0x41a10001, 0x00020053, 0x106350a7, +0x1c240132, 0x0004f727, 0x0005f724, 0x0016f724, +0x0017f724, 0x1d340013, 0xfffef734, 0xfffff734, +0x40434ff7, 0x9ff02907, 0x44014015, 0x9fca2925, +0xd3005001, 0x5004f340, 0xf398d200, 0x01150035, +0x1f544011, 0x9ff62941, 0xd4005fe3, 0x5005f344, +0x00415f67, 0x4fc30231, 0xfffef512, 0x1f154202, +0x9ff02173, 0xf334d200, 0xf000d100, 0xd4005003, +0x5005f538, 0x030cf412, 0xac115001, 0xa819ac19, +0x00470052, 0x00710112, 0x01211032, 0x00201c13, +0x70407052, 0x1f450104, 0x00740070, 0xf34cd700, +0x01200157, 0x1e724015, 0xf7131f02, 0xa8110016, +0x210550a0, 0x9fc44021, 0xf376d000, 0x1000fc11, +0x00345f02, 0x4ff30005, 0x21231014, 0x1d510245, +0x50029ff2, 0xf334d000, 0xf000d700, 0xf458d300, +0x1d025004, 0xf332d000, 0x0310f470, 0x00350041, +0x01151041, 0x0004f452, 0x0008f454, 0xf7524014, +0xf752000c, 0x1c52000d, 0x9fe22964, 0xd2005001, +0x1f21f330, 0x0001f721, 0xf5711d01, 0xf77102fe, +0xfc4102fc, 0xfc312016, 0xd2160518, 0x1c711951, +0x0427fc41, 0x9e21fc31, 0x0004f472, 0xe412d200, +0x0008f471, 0x1f215011, 0x0d86fa00, 0xa82da827, +0x41465000, 0x0000a070, 0xac3d4e46, 0xf601ac37, +0x28010005, 0xf6029178, 0xac200004, 0x10110021, +0xd100ac29, 0xa828f538, 0x10300120, 0x7050ac18, +0x1e150101, 0xfa000050, 0x00501890, 0x29006fb0, +0x0050901a, 0xfa004010, 0x00501880, 0xfa004020, +0x00501878, 0xfa004030, 0xd1001870, 0x5010e000, +0x08501811, 0x28010401, 0xac15906c, 0x0128fa00, +0x5003a822, 0xf6205005, 0xa8110004, 0xfa004062, +0xa8230290, 0xf538d400, 0x91022900, 0x5021a818, +0xf334d700, 0x1c410104, 0xf6305011, 0x1a720004, +0x05120801, 0xf6301d72, 0xf7400005, 0x28000016, +0x500090dc, 0x00320041, 0x01524010, 0xf6220151, +0xf7120006, 0x00050006, 0x0005f632, 0x24256ff5, +0x80ba9fe4, 0xd100a822, 0xf620e404, 0x18110004, +0x28016201, 0xd3009028, 0x6ff0f330, 0x0001f631, +0x90222101, 0x6ff01e30, 0x901a2910, 0x15f0fa00, +0x5030a822, 0xf330d100, 0x800a1f10, 0xf330d000, +0x1f015001, 0x0004f620, 0xf000d100, 0x01011050, +0x0005f620, 0x0024f213, 0xac1b2800, 0x0024f211, +0x905a0050, 0xac100015, 0x0562fa00, 0x0053a814, +0x904a2910, 0x60f31243, 0x61f34013, 0x903e2803, +0x5002a818, 0x60f05001, 0x0030ac18, 0x00470043, +0xf418d400, 0x10234011, 0xf2430134, 0x1a440002, +0x0152a81d, 0x0125a825, 0x0006f652, 0x00741f42, +0x00031f32, 0x6ff20012, 0x9fd02432, 0xa83da837, +0xa07041c6, 0xac454e06, 0xd000ac3f, 0xfc41e400, +0x18000400, 0x28000410, 0x5000915e, 0xfc41ac10, +0xd0000400, 0xac19e804, 0xd1001c01, 0x1810e080, +0xe084d100, 0x00021811, 0xf76260f2, 0x00620014, +0x0014fc02, 0x00040023, 0x13007022, 0x70131284, +0x1f346034, 0xf5611d20, 0x13010018, 0xe088d000, +0xf5615012, 0x1c02001a, 0x0014f265, 0x6ff5ac25, +0xfa000050, 0xa8220498, 0xf418d100, 0x90902910, +0xd0001025, 0x0017f000, 0xfc411282, 0x01500100, +0xf0004012, 0x6ff20280, 0x50010410, 0x903a2900, +0x50000075, 0x28020027, 0xf6629066, 0x00530014, +0x40101011, 0x01231022, 0x0002f232, 0x00641a33, +0x0014fc04, 0xf2410114, 0x1d310002, 0x00011d21, +0x24716ff1, 0x80389fd6, 0x50000075, 0x28020027, +0xf662902e, 0x00530014, 0x40101011, 0x01231022, +0x0002f232, 0x00641a33, 0x0014fc04, 0xf6410114, +0x1f310003, 0x00011f21, 0x24716ff1, 0xd0009fd6, +0x1800e400, 0x0410a819, 0x900c2800, 0x4010a810, +0x2c40ac10, 0xf6619efa, 0x50000014, 0x90142c41, +0x4fc00010, 0x90062e30, 0x80085010, 0x00fafc01, +0xd1000010, 0x1811e404, 0x28016201, 0xd5009022, +0x6ff0f330, 0x0001f651, 0x901c2101, 0x6ff01e50, +0x90142910, 0x13f8fa00, 0x1f505030, 0xd000800a, +0x5001f330, 0xa83f1f01, 0x4206a845, 0x4e06a070, +0xac3fac45, 0xe400d300, 0xfc431834, 0x04340200, +0x90322804, 0xd400ac21, 0x1841e404, 0x28016201, +0xd1009032, 0xf614f330, 0x21040001, 0x1e11902e, +0x29316ff1, 0xd0009026, 0xf001f000, 0x701102c8, +0x02c8f401, 0xe808d000, 0x05311801, 0x50001c01, +0xd1008108, 0x5003f330, 0x10501f13, 0xf000d100, +0xe808d300, 0xfdfffc45, 0xfffffc35, 0x01015007, +0xf210ac19, 0x18340026, 0xfc450454, 0x12c00200, +0xd3001c34, 0x1c35e804, 0x0026f213, 0xf214ac10, +0xf2100026, 0xf2150026, 0x12830026, 0x124512c4, +0x601060f3, 0x01326034, 0x28006075, 0x902a4014, +0x00615003, 0x40131017, 0x0014fc01, 0x01711e20, +0x0001f627, 0x10804022, 0x08500570, 0x00371d10, +0x24476ff7, 0x80289fde, 0x00605003, 0x40131017, +0x0014fc00, 0x01701e21, 0x0001f627, 0x10874022, +0x08570517, 0x00371d07, 0x24476ff7, 0xa8119fde, +0xf262a820, 0xd3000014, 0x1081e004, 0xfc211102, +0x05010300, 0xd2000521, 0x1c31e008, 0xfc000060, +0xf2610014, 0x70200018, 0x11011a00, 0x1c210501, +0xe00cd100, 0xf020a81a, 0x1c100028, 0xe010d100, +0x002cf020, 0xd1001c10, 0xf020e014, 0x1c100030, +0xd1005010, 0x1c10e018, 0xa845a83f, 0xa0704206, +0xac454e06, 0xd500ac3f, 0x5014e000, 0xa84d1857, +0x04470804, 0x901e2807, 0xac21ac32, 0xac1bac28, +0xfd04faff, 0xa828ac0d, 0xa832a821, 0xfa00a81b, +0x80240032, 0x2805ac32, 0x901cac28, 0x1811ac21, +0xa832a828, 0x0286fa00, 0xa828a830, 0x4ff5a821, +0x40412905, 0xa83f9fe8, 0x5010a845, 0xa0704206, +0xac654d06, 0xac22ac5f, 0xd100ac19, 0xfc44e808, +0xfc34fdff, 0x2623ffff, 0x04421812, 0x0200fc44, +0xd2001c12, 0x5001e804, 0xa86c1c24, 0x9014ac2c, +0x90322803, 0x90382913, 0xf000d100, 0x0268f011, +0x28338052, 0x29439038, 0xd200903e, 0xf021f000, +0xa8230274, 0x903c2913, 0x0278f022, 0xe010d300, +0x80301c32, 0xf000d100, 0x0264f011, 0x29238026, +0xd1009022, 0xf011f000, 0x8018026c, 0xf000d100, +0x0270f011, 0x2953800e, 0xd100900a, 0xf011f000, +0xd200027c, 0x1c21e00c, 0x2801a829, 0xa821911a, +0xd4005003, 0x1081e400, 0xac110501, 0xa8190030, +0xe004d500, 0x01011020, 0x00011810, 0x1101a812, +0x1c520512, 0x2911a821, 0x1300900a, 0xe008d100, +0xd0001c10, 0x5011e018, 0x1c01ac33, 0xfc401841, +0x04010400, 0x9ff62801, 0x04011841, 0x28015010, +0xfc4190bc, 0xd2000400, 0xac50e804, 0xe084d000, +0x1c21ac49, 0xe080d100, 0x18155012, 0xe088d100, +0x60f5ac45, 0xac381800, 0x00501c12, 0x00aefa00, +0x90742910, 0x1025a844, 0xf000d100, 0x0100fc42, +0x00400151, 0x0280f011, 0x0300fc20, 0x28010421, +0xd2009016, 0x1384f418, 0xf2230152, 0x1a220002, +0x1f341f24, 0xd2008014, 0x1304f418, 0xf2230152, +0x1a220002, 0x1d341d24, 0x902c2800, 0xf418d000, +0x01502801, 0xf2019016, 0x1a000002, 0xfc22a83a, +0x1282ff00, 0x1f121f02, 0xf201800e, 0x1a000002, +0x1d02a83a, 0xd4001d12, 0x1840e400, 0x0410a849, +0xa8502800, 0x2c409008, 0x9f484010, 0xa828a833, +0x21034013, 0xfc409ef8, 0xd1000200, 0x1c10e804, +0xa85f5010, 0x4306a865, 0xd200a070, 0x0001f000, +0x00231020, 0x50100103, 0x0280f033, 0x28036033, +0x29239078, 0x0014904c, 0xd3001021, 0x0112f376, +0xf0211014, 0x01430280, 0x12415094, 0x40a16031, +0x081460f1, 0xe404d100, 0x04141811, 0x904c2804, +0x50001a31, 0x90422801, 0x1000fc10, 0x90442101, +0x0280f020, 0xfc201280, 0x1d300fff, 0xa0705010, +0x90242913, 0x01121021, 0xf0205091, 0xd2000280, +0x1240e404, 0x40a06030, 0x080160f0, 0x04011820, +0xa3002901, 0x5000a070, 0xfc11a070, 0x1d311000, +0x4ff1a070, 0x1d315010, 0x4ec6a070, 0xac27ac2d, +0xac19ac12, 0xfaff0005, 0x2910ff54, 0x10259024, +0xf418d100, 0xf2100151, 0x1a110002, 0x2802a812, +0xa81a900a, 0x1c021c12, 0xa81a8008, 0x1d021d12, +0xa82da827, 0xa0704146, 0xac3d4e46, 0x0004ac37, +0x29051845, 0xd000901e, 0x2801e404, 0x00171803, +0xe410d000, 0x180290a0, 0x28036043, 0x704290b4, +0x2915809e, 0x00179332, 0x0004f641, 0x00126ff1, +0x10220040, 0xf6020120, 0xf6030019, 0x21230018, +0x10519026, 0xf000d200, 0xf0210112, 0xf0220020, +0x13010020, 0x67f11382, 0xf70161f2, 0x01210018, +0xf7014011, 0xac170019, 0xe444d200, 0x28075041, +0x08711823, 0xf000d700, 0xd1000513, 0x1c23d800, +0xd400d300, 0xa512a432, 0xf6410023, 0x00450004, +0x76c30074, 0x01141051, 0x0020f041, 0x1c345004, +0xfc240014, 0x28040400, 0xfc21902e, 0xfc3103ff, +0x80261000, 0x60231802, 0x91102803, 0x1c027022, +0xe804d000, 0x0400fc11, 0x50001c01, 0x0524f800, +0xac245fb1, 0x67f180fa, 0x1c217042, 0x50015012, +0xd2001c32, 0xf604d410, 0xac250018, 0x0017f754, +0x0005f751, 0xd1000003, 0xac1bd810, 0x2800a810, +0xa5120030, 0x0019f601, 0xac296ff1, 0xa82b0041, +0x25136ff1, 0x4014915a, 0xf7041011, 0x00740018, +0xf2470114, 0xf2450160, 0x12c50160, 0x00516075, +0x0160f243, 0xfc234011, 0x28030100, 0xa8209010, +0x0005f603, 0xf7030113, 0xa8180005, 0x0160fc04, +0x29030e53, 0xfc279008, 0x802607ff, 0x28210073, +0x05fffc23, 0x90161c23, 0x90122815, 0x4ff50071, +0x01fffc21, 0x1c214ff5, 0x9ffa2905, 0x03fffc27, +0xd7001c27, 0x1a41f000, 0x0018f604, 0x0800fc21, +0x9f7a2801, 0x0019f601, 0x90d42541, 0xd2001014, +0x0147c000, 0x0160f271, 0xe000fc21, 0x90ba2121, +0x0160fc07, 0x6ff11a71, 0xf5014011, 0xf601001a, +0x40110018, 0x0018f701, 0xac2480a6, 0x04125fd1, +0xe400d100, 0x50001c02, 0xfc211811, 0x280103ff, +0x0410f900, 0x280750a2, 0xd5005143, 0xa424f000, +0xf053a534, 0x0943000c, 0xf356d400, 0x00310413, +0x61f10045, 0x1e510115, 0x900a2951, 0x01341253, +0x40511e41, 0x903c2021, 0xd4005013, 0x5012e804, +0x1c430813, 0xa8230014, 0x01431024, 0x001af234, +0x90202804, 0xe408d100, 0xa8251814, 0x0004f655, +0x05420852, 0xf2311c12, 0x4ff1001a, 0x001af531, +0x001283a0, 0x6ff250a3, 0x93962032, 0x5010a824, +0x0004f741, 0x8dc61c40, 0xf5015001, 0xa824001a, +0x0005f640, 0x90162800, 0xd200a813, 0xd100d438, +0x4ff0d838, 0xa5122803, 0x80141c20, 0xd100a812, +0xd000d438, 0x2802d838, 0xa50151f2, 0xd0001c12, +0x1800e404, 0x0200fc20, 0x908e2800, 0xe41bd000, +0xd5005011, 0x1f01e408, 0xf6431852, 0x41030004, +0xd3000831, 0x0521e808, 0xfff8fc42, 0xfffffc32, +0xfc411c51, 0xfc31ffff, 0xfc151fff, 0xa8104000, +0xa5212800, 0x28001832, 0x1c320412, 0x2000fc13, +0x0001fc42, 0xd300a431, 0xa521e804, 0x8000d200, +0x1c312800, 0x0004fc41, 0x2800a512, 0x0002fc41, +0xa4521c32, 0xa5125005, 0xf6421c32, 0x00410004, +0x01211022, 0x001af515, 0x0017f642, 0x0018f712, +0x0de0fa00, 0x801ca824, 0xd100a812, 0xfc40e000, +0xd3000007, 0x5025e808, 0xa5012802, 0x05121832, +0x1c451c32, 0x2925a811, 0xd0009294, 0x0047e400, +0x18042801, 0x90220013, 0x0004fc42, 0x28040424, +0x1801902a, 0x0001fc42, 0x29010421, 0x1800901e, +0x0002fc41, 0x81c60410, 0x8000fc24, 0x900c2804, +0xfc211801, 0x28012000, 0x003291ae, 0xfffffc41, +0x1ffffc31, 0xfff8fc40, 0xfffffc30, 0xe808d300, +0x0004fc45, 0xac122802, 0x2802a501, 0x1830ac29, +0xfc110410, 0x1c302000, 0x0001fc40, 0xd300a414, +0xa5048000, 0xe804d000, 0x1c042802, 0x1c03a553, +0xf6150071, 0x28050005, 0xa810902e, 0xd410d500, +0xd810d700, 0xa5752800, 0x00725007, 0x40170010, +0x01206ff2, 0xf7021e52, 0x00700006, 0x0005f612, +0x24206ff0, 0xd0009fe6, 0x0017e404, 0xfc201800, +0x28000200, 0xd0009060, 0x5012e41b, 0xd0001f02, +0x1801e408, 0xac250075, 0x0004f657, 0x08724107, +0x1c020512, 0xe808d200, 0xa8291820, 0xd1000410, +0x1c20e804, 0xfc110017, 0xfc424000, 0x1c740002, +0x50031c73, 0x2800a810, 0x1c71a521, 0x0004f652, +0x10220051, 0xf5130121, 0xf652001a, 0xf7120017, +0x81600018, 0xd100a810, 0xd200d46c, 0x5004d86c, +0xa5212800, 0xd4001c14, 0x1c43e804, 0xe408d400, +0x18415013, 0xf6520075, 0x08230004, 0x05135042, +0x1c430802, 0xe444d400, 0x18420723, 0x1c420432, +0x0c50fa00, 0x50310050, 0xf000d300, 0xf6021c01, +0x00310004, 0x01211052, 0x0020f017, 0x12c10071, +0x28016031, 0x4ff19056, 0x12875012, 0xd1000812, +0x6307e414, 0x0724ac2a, 0x18120137, 0x02bcfc07, +0x60f40424, 0xf6041f14, 0x10540004, 0xf2340143, +0xf2330024, 0x60f40024, 0x01041243, 0x406460f3, +0x1e454013, 0x40144ff3, 0x1f752903, 0x9ff44017, +0x0532a82b, 0x1f1260f2, 0x0005800a, 0xf34cfaff, +0x50050050, 0x180080a6, 0x4000fc20, 0x90aa2800, +0xd46cd100, 0xd0002803, 0x5014d86c, 0x5000a501, +0xd1001c10, 0x0035e408, 0xac271812, 0xf6732805, +0x41030004, 0x05240834, 0xfc441c14, 0xfc34ffff, +0xfc411fff, 0xfc31fff8, 0xa442ffff, 0xe808d400, +0x1843a512, 0xfc412805, 0x04230001, 0xfc131c43, +0xfc142000, 0xa4324000, 0x8000d300, 0xd100a512, +0x2805e804, 0xfc421c12, 0xa5230004, 0xfc422805, +0x1c130002, 0xa523a443, 0xf6711c13, 0x00720004, +0x01121021, 0x001af520, 0x0017f670, 0x0018f720, +0xfa000050, 0xa8200b2e, 0x1c055005, 0xa3002905, +0xa83da837, 0xa07041c6, 0x1c755025, 0x48468ff0, +0xacf7acfd, 0xf000d500, 0xfa008006, 0x50030962, +0xf05180f0, 0x12c10260, 0x211260f1, 0xd00090e4, +0xf600f340, 0x6ff00003, 0x90d62900, 0x0260f050, +0xf80013b0, 0xf537092e, 0x5010001a, 0xd094d100, +0xd004d200, 0x1c105fd7, 0x50120021, 0x04701810, +0xd1001c10, 0x0013e408, 0xf6411830, 0x08120004, +0x1c320502, 0xe444d200, 0x18100021, 0x1c100470, +0x1c415031, 0x0004f640, 0x10500051, 0xf0130101, +0x00310020, 0x603112c1, 0x90102901, 0xfaff0040, +0xd300f1fa, 0x5007f3d8, 0xd7008372, 0x4ff1e414, +0x12835010, 0x63030810, 0x07021871, 0x60f20412, +0x00521f72, 0xf6430132, 0x00470004, 0xfc020054, +0x105302bc, 0xf2450134, 0x00730024, 0x0024f244, +0x60f51244, 0x60f40153, 0x40144063, 0x4ff41e35, +0x29044013, 0x40121f25, 0x05019ff4, 0xe414d000, +0xf000d500, 0xd3005007, 0x60f1f3d8, 0x830c1f01, +0x02fef250, 0xe404d100, 0xf5504010, 0x181002fe, +0x29006200, 0xd000900a, 0x1f03f330, 0xd0008020, +0x1e00f330, 0x90162900, 0xf330d000, 0x00015012, +0xf0501f12, 0x60f002c4, 0x0001f710, 0xe440d000, +0x00015082, 0x1d125000, 0x0836fa00, 0xfa005010, +0x54000830, 0xe440d100, 0xfaff1d10, 0x5010f2ba, +0xe440d100, 0xf3d8d400, 0x18401d10, 0x90802900, +0xe404d000, 0xe410d200, 0x18201801, 0x29016011, +0x5fe19248, 0xd1000410, 0x1c20e400, 0xfc211811, +0x280103ff, 0xf050929a, 0xd200000c, 0x0410f356, +0x61f10001, 0x1e210112, 0x900e2951, 0xd1001250, +0x0101f356, 0x40511e11, 0x200150a0, 0x5010901e, +0xe804d200, 0x1c200810, 0x00400012, 0x01201022, +0x001af202, 0xf9002902, 0x00100746, 0x6ff050a2, +0x924c2020, 0xf7415010, 0x1c400004, 0x2910800a, +0xf641923e, 0x6ff10004, 0x00430010, 0x01031020, +0x0019f630, 0x0018f632, 0x90242102, 0x00501051, +0xf0010110, 0xf0000020, 0x13010020, 0x67f11380, +0xf73161f0, 0x01010018, 0xf7314011, 0xd0000019, +0xd200e444, 0xd700d094, 0x0001d004, 0x70201810, +0xaca31c10, 0x50110023, 0x1c315fd2, 0x04201870, +0xd090d200, 0x1c211c70, 0xf6405002, 0x00510004, +0x01011050, 0x0020f010, 0xd098d100, 0x1c106ff0, +0xa8a31c32, 0x70201870, 0xf7421c70, 0xf6310005, +0xf7410018, 0xf6320017, 0x00100019, 0x25026ff0, +0x10109daa, 0x01054011, 0x0018f731, 0xf253acb5, +0xf2500160, 0xaca80160, 0xf25112c3, 0x00620160, +0x40136073, 0x0060fc02, 0x0100fc21, 0x90142801, +0x0005f641, 0x01320012, 0x0005f742, 0x01120042, +0x00354062, 0x5003acbb, 0xd7005004, 0xa8a8d008, +0x28056ff5, 0x6ff09014, 0x40115001, 0x00141c70, +0x24546ff4, 0x9ff4a8bc, 0xf33cd000, 0x18005007, +0xf9002800, 0xa8b00602, 0x0160fc00, 0x0047acb0, +0x6ff75005, 0x90062907, 0x80265004, 0xd00cd000, +0x60401800, 0x90182800, 0xd008d100, 0x18110020, +0x40150150, 0x00501f01, 0x24706ff0, 0x01529fe0, +0x50076ff4, 0x00400254, 0x28006ff0, 0xd000901e, +0x1800e404, 0x0200fc20, 0x90742900, 0xf33cd000, +0x18004013, 0x9fa82403, 0xd0008008, 0x1800f33c, +0xf9002030, 0xa8b00592, 0xf000d500, 0xf3d8d400, +0xa8a31a00, 0x0018f631, 0x0800fc20, 0x9ef82800, +0x0019f630, 0x9ca42510, 0x00501011, 0xc000d200, +0xf2010110, 0xfc210160, 0x2121e000, 0xfc009c8a, +0x1a000160, 0x40106ff0, 0x001af530, 0x0018f630, +0xf7304010, 0x8c740018, 0x1c207010, 0x50108058, +0xe41bd100, 0xd0001f10, 0xd300e408, 0x5012f3d8, +0xf000d500, 0x18400004, 0x0004f631, 0x08124101, +0x1c420502, 0x0004f630, 0x10200031, 0xf5170101, +0xf630001a, 0xf7100017, 0x1c370018, 0xe404d000, +0x60101800, 0x90182800, 0xe410d000, 0x18100001, +0x1c107010, 0xe804d000, 0x0400fc11, 0xd0001c01, +0x5401e440, 0xfaff1d01, 0x5020efde, 0xe440d100, +0xd0001d10, 0x5001f4b8, 0xf5b0faff, 0xe440d000, +0x1d015401, 0xefc0faff, 0xd1005040, 0x1d10e440, +0xf4b8d000, 0x44005011, 0xf590faff, 0xe440d000, +0x1d015401, 0xefa0faff, 0xd4005007, 0x5080e400, +0xe440d100, 0xf0511d10, 0xd2000260, 0xfc40f340, +0x01720100, 0xac8a0870, 0x1e200401, 0x90302901, +0x6ff10001, 0x90dc2911, 0x18420070, 0x41305011, +0x50000801, 0x28020412, 0x007290ca, 0xfc321022, +0x1823dc00, 0x04131843, 0x9ff82903, 0x007180b6, +0x41315012, 0xacaa0812, 0x6ff10001, 0xa6112801, +0xac81a501, 0xac970070, 0xaca01020, 0xdc00fc30, +0x5000ac98, 0x1840acb8, 0x0410a8a9, 0x90802800, +0x0260f055, 0x0905a8a0, 0x60f00050, 0xfa00acb0, +0x60b50638, 0xa8b52905, 0x0050901a, 0xfa004010, +0x00500628, 0xfa004020, 0x00500620, 0xfa004030, +0xa8980618, 0xe000d200, 0x50101801, 0xace10850, +0x04021822, 0x900e2902, 0x50026ff5, 0xfaff0050, +0x801cf46c, 0xeec0faff, 0x6ff55010, 0xac085002, +0xfc010061, 0x00500070, 0xfaffa893, 0xa8b8f1e6, +0xf000d500, 0xe400d400, 0x2c304010, 0xa8809f78, +0xa889a897, 0x29474017, 0x9efc1f10, 0xe440d000, +0x00055401, 0xfaff1d51, 0x5100ee7e, 0xf334d100, +0x1a101d50, 0x28005001, 0xacb9910a, 0xd3000010, +0x1010f538, 0xa8edace8, 0x01150030, 0x01501035, +0x1800aca8, 0x90922910, 0x01300050, 0x0016f604, +0x00320051, 0x01127051, 0x00511e20, 0x70410032, +0x01122804, 0xd2001e21, 0x1051f000, 0xf2210112, +0xacb10024, 0x0024f221, 0xaca09098, 0xfaffac99, +0xa89af31c, 0x2910a8a4, 0x12429088, 0x401260f2, +0x280261f2, 0xa8b0907c, 0x50017065, 0x015060f0, +0x5000acb0, 0x00420027, 0xf418d300, 0x10224010, +0xf2320123, 0x1a330002, 0xa8b40045, 0xd1000114, +0x0141f538, 0x1e110054, 0x1f211f31, 0x00010072, +0x24216ff1, 0x803a9fd0, 0x904e2920, 0xd1000050, +0x7060f538, 0x01010012, 0x0050acb1, 0x01027050, +0xfaffaca2, 0xa8a0eda2, 0xd2007045, 0x5003f538, +0x1e010152, 0xa8b21e20, 0xef06faff, 0x901a2910, +0xd200a8b9, 0x5010f334, 0x1a210810, 0x04010700, +0x50011d21, 0x1c01a8a8, 0x50a0a8b9, 0x21014011, +0xd0009efa, 0x5401e440, 0x1d510005, 0xed58faff, +0xd1005200, 0x5003f332, 0x1d505004, 0xf458d500, +0x28001a10, 0xacbc905e, 0x0004f050, 0x90122910, +0x000df652, 0xf6501851, 0xfaff000c, 0x8022f2d0, +0x2920a8bc, 0xfaff9036, 0xf053ed1e, 0xf6520008, +0xf650000d, 0x5011000c, 0x0051ac09, 0xf044faff, +0xd100a8bc, 0x5010f332, 0x00125003, 0x08401a21, +0x04010700, 0xf4531d21, 0x40140004, 0x29644105, +0xd0009fa6, 0xfc11e440, 0xd4000080, 0xd500e400, +0x1d01f000, 0x18401d01, 0x0263f651, 0xfc200002, +0x133203ff, 0x63f20412, 0x29020502, 0xd0009042, +0x1800e404, 0x29006100, 0xd0009036, 0x5fe1e444, +0x18500005, 0x1850acb8, 0x1c500410, 0xe8a6faff, +0xd400a8b8, 0x5003e400, 0xe804d200, 0x01f8fc41, +0x07fffc31, 0x1c507010, 0xf000d500, 0xd0001c21, +0x1800e404, 0x28006080, 0xf958f9ff, 0x02c4f051, +0xf34cd000, 0x60f11842, 0x03fffc22, 0x1e000110, +0x0013acb8, 0x10530054, 0x50130134, 0x0020f044, +0x00500813, 0xf0070035, 0xfc25000c, 0xfc2403ff, +0x04573000, 0x90062807, 0x908c2804, 0x000cf007, +0x045712a7, 0x90062807, 0x909a2804, 0x000cf007, +0x04571347, 0x90062807, 0x90ce2804, 0x0260f001, +0x0005a8ba, 0x60f11301, 0x901a2112, 0xf344d000, +0xf6005003, 0x29000002, 0xf8d8f9ff, 0x0260f050, +0x812e13c0, 0x0260f051, 0x13415003, 0x211260f1, +0xd0009018, 0xf600f344, 0x29000006, 0xf8b4f9ff, +0x0260f050, 0x810a13d0, 0x0260f051, 0x211260f1, +0xd0009056, 0x1e00f340, 0xf9ff2900, 0xf050f896, +0x13800260, 0x043280ec, 0x50030005, 0xf9ff2902, +0xd000f882, 0x1800f3d8, 0xf9ff2800, 0xd000f780, +0x801ef3d8, 0x00050432, 0x29025003, 0xf864f9ff, +0xf4b8d000, 0x28001800, 0xf762f9ff, 0xf4b8d000, +0x0004f600, 0xf0518046, 0x12410260, 0x211260f1, +0xd000907e, 0xf600f340, 0x29000001, 0xf834f9ff, +0x0260f050, 0x808a1390, 0x00050432, 0x29025003, +0xf820f9ff, 0xf4b8d000, 0x0040f000, 0xf9ff2800, +0xd000f71c, 0xf600f4b8, 0x20100044, 0xf804f9ff, +0xf70af8ff, 0xd1005010, 0x5fd2d094, 0xd1001c10, +0x1810d004, 0x1c100420, 0xfabef8ff, 0xe408d100, +0x00175013, 0xf6421871, 0x08230004, 0x1c730513, +0x001af201, 0xf5014ff1, 0xf8ff001a, 0xf051faf4, +0x12810260, 0x211260f1, 0xf6caf9ff, 0xf340d000, +0x0002f600, 0xf9ff2900, 0xf050f7aa, 0x13a00260, +0x29006010, 0xf79cf9ff, 0xf6a2f8ff, 0xe414d000, +0x60711801, 0x70820012, 0x1f011f02, 0x4dc6a070, +0xac47ac4d, 0xf000d200, 0x1000fc41, 0xf344d700, +0x0260f024, 0x00420801, 0x00010412, 0x10210073, +0x01132802, 0x0002f633, 0x6ff10031, 0x28019014, +0x00019042, 0x10210072, 0xf6250112, 0x80440003, +0x913e2911, 0x50140001, 0x41715003, 0xd1000814, +0x1812e400, 0x28020442, 0xd2009128, 0x0003dc80, +0x01231023, 0x18131833, 0x29030443, 0x50039ff2, +0x00018110, 0x50050072, 0x10215013, 0xf7250112, +0xac1b0003, 0x00720001, 0x10216ff5, 0x01122f85, +0xac3a1a22, 0x00019040, 0xd7005012, 0xd300dc80, +0x4171e400, 0x00010812, 0x1021ac20, 0x01740014, +0x04271837, 0x90b62807, 0xa8380057, 0x10274015, +0x01702c85, 0x1c071847, 0xd0009fe8, 0xf004f000, +0x80040260, 0x4101ac20, 0xac2c0914, 0x60f00040, +0xfa00ac30, 0xa82800e4, 0x290060b0, 0xa830901a, +0xfa004010, 0xa83000d4, 0xfa004020, 0xa83000cc, +0xfa004030, 0xa82000c4, 0x29005001, 0xd0009008, +0x1801de50, 0x5010ac29, 0xe000d200, 0x0810a831, +0x04011821, 0x90222801, 0xe96cfaff, 0xa830ac0d, +0xa825a82a, 0xa8390053, 0x6ff26ff0, 0xfaff4043, +0x0050ec92, 0x80285005, 0x90202805, 0xac38a838, +0x1801a838, 0xa82aa830, 0x6ff26ff0, 0xeedefaff, +0x4ff5a838, 0x40402905, 0x50059fe6, 0x0002a820, +0xf344d700, 0x00711022, 0xf7150121, 0xa81b0003, +0x01071020, 0x0002f773, 0xa84da847, 0xa0704246, +0xe404d100, 0x18112800, 0x60419012, 0x90262801, +0xe410d000, 0x70411801, 0x60218010, 0x90162801, +0xe410d000, 0x70211801, 0xd0001c01, 0xfc12e804, +0x1c020400, 0xd100a070, 0x0101f000, 0xf6111020, +0x00130314, 0x60130002, 0x2000fc02, 0x900e2803, +0xfc311011, 0xfc212000, 0x800621fc, 0xf338d100, +0xf418d300, 0x1d320103, 0x0002f531, 0x0000a070, +}; +const unsigned long sizeOfscuIsopProgArray = 7024; /* 0x00001b70 */ diff --git a/arch/arm/src/cxd56xx/hardware/cxd56_adc.h b/arch/arm/src/cxd56xx/hardware/cxd56_adc.h new file mode 100644 index 0000000000..c3529b1455 --- /dev/null +++ b/arch/arm/src/cxd56xx/hardware/cxd56_adc.h @@ -0,0 +1,75 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/hardware/cxd56_adc.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CHIP_CXD56_ADC_H +#define __ARCH_ARM_SRC_CXD56XX_CHIP_CXD56_ADC_H + +#define SCUADCIF_LPADC_A0 (CXD56_SCU_ADCIF_BASE + 0x200) +#define SCUADCIF_LPADC_A1 (CXD56_SCU_ADCIF_BASE + 0x204) +#define SCUADCIF_LPADC_D0 (CXD56_SCU_ADCIF_BASE + 0x210) +#define SCUADCIF_LPADC_D1 (CXD56_SCU_ADCIF_BASE + 0x214) +#define SCUADCIF_LPADC_D4 (CXD56_SCU_ADCIF_BASE + 0x21c) +#define SCUADCIF_LPADC_D5 (CXD56_SCU_ADCIF_BASE + 0x220) +#define SCUADCIF_LPADC_D6 (CXD56_SCU_ADCIF_BASE + 0x224) +#define SCUADCIF_LPADC_D2 (CXD56_SCU_ADCIF_BASE + 0x218) +#define SCUADCIF_HPADC_AC0 (CXD56_SCU_ADCIF_BASE + 0x240) +#define SCUADCIF_HPADC_AC1 (CXD56_SCU_ADCIF_BASE + 0x244) +#define SCUADCIF_HPADC_DC (CXD56_SCU_ADCIF_BASE + 0x250) +#define SCUADCIF_HPADC0_A0 (CXD56_SCU_ADCIF_BASE + 0x280) +#define SCUADCIF_HPADC0_A1 (CXD56_SCU_ADCIF_BASE + 0x284) +#define SCUADCIF_HPADC0_A2 (CXD56_SCU_ADCIF_BASE + 0x288) +#define SCUADCIF_HPADC0_A3 (CXD56_SCU_ADCIF_BASE + 0x28c) +#define SCUADCIF_HPADC0_D0 (CXD56_SCU_ADCIF_BASE + 0x290) +#define SCUADCIF_HPADC0_D1 (CXD56_SCU_ADCIF_BASE + 0x294) +#define SCUADCIF_HPADC0_D2 (CXD56_SCU_ADCIF_BASE + 0x298) +#define SCUADCIF_HPADC1_A0 (CXD56_SCU_ADCIF_BASE + 0x2c0) +#define SCUADCIF_HPADC1_A1 (CXD56_SCU_ADCIF_BASE + 0x2c4) +#define SCUADCIF_HPADC1_A2 (CXD56_SCU_ADCIF_BASE + 0x2c8) +#define SCUADCIF_HPADC1_A3 (CXD56_SCU_ADCIF_BASE + 0x2cc) +#define SCUADCIF_HPADC1_D0 (CXD56_SCU_ADCIF_BASE + 0x2d0) +#define SCUADCIF_HPADC1_D1 (CXD56_SCU_ADCIF_BASE + 0x2d4) +#define SCUADCIF_HPADC1_D2 (CXD56_SCU_ADCIF_BASE + 0x2d8) +#define SCUADCIF_LPADC_AT0 (CXD56_SCU_ADCIF_BASE + 0x300) +#define SCUADCIF_LPADC_AT1 (CXD56_SCU_ADCIF_BASE + 0x304) +#define SCUADCIF_HPADC_ACT0 (CXD56_SCU_ADCIF_BASE + 0x340) +#define SCUADCIF_HPADC_ACT1 (CXD56_SCU_ADCIF_BASE + 0x344) +#define SCUADCIF_HPADC0_AT0 (CXD56_SCU_ADCIF_BASE + 0x380) +#define SCUADCIF_HPADC0_AT1 (CXD56_SCU_ADCIF_BASE + 0x384) +#define SCUADCIF_HPADC1_AT0 (CXD56_SCU_ADCIF_BASE + 0x3c0) +#define SCUADCIF_HPADC1_AT1 (CXD56_SCU_ADCIF_BASE + 0x3c4) +#define SCUADCIF_ADCIF_DCT (CXD56_SCU_ADCIF_BASE + 0x3d0) +#define SCUADCIF_SCU_ADCIF_CKPOWER (CXD56_SCU_ADCIF_BASE + 0x3d4) + +#endif /* __ARCH_ARM_SRC_CXD56XX_CHIP_CXD56_ADC_H */ diff --git a/arch/arm/src/cxd56xx/hardware/cxd56_dmac_common.h b/arch/arm/src/cxd56xx/hardware/cxd56_dmac_common.h index 52aec4b8b9..be0da44ee3 100644 --- a/arch/arm/src/cxd56xx/hardware/cxd56_dmac_common.h +++ b/arch/arm/src/cxd56xx/hardware/cxd56_dmac_common.h @@ -33,9 +33,6 @@ * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************/ -/** - * @file cxd56_dmac_common.h - */ #ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_DMAC_COMMON_H #define __ARCH_ARM_SRC_CXD56XX_CXD56_DMAC_COMMON_H diff --git a/arch/arm/src/cxd56xx/hardware/cxd56_i2c.h b/arch/arm/src/cxd56xx/hardware/cxd56_i2c.h new file mode 100644 index 0000000000..0e7230b64c --- /dev/null +++ b/arch/arm/src/cxd56xx/hardware/cxd56_i2c.h @@ -0,0 +1,209 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/hardware/cxd56_i2c.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CHIP_CXD56_I2C_H +#define __ARCH_ARM_SRC_CXD56XX_CHIP_CXD56_I2C_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register offsets *********************************************************/ + +#define CXD56_IC_CON 0x0000 +#define CXD56_IC_TAR 0x0004 +#define CXD56_IC_SAR 0x0008 +#define CXD56_IC_HS_MADDR 0x000C +#define CXD56_IC_DATA_CMD 0x0010 +#define CXD56_IC_SS_SCL_HCNT 0x0014 +#define CXD56_IC_SS_SCL_LCNT 0x0018 +#define CXD56_IC_FS_SCL_HCNT 0x001C +#define CXD56_IC_FS_SCL_LCNT 0x0020 +#define CXD56_IC_HS_SCL_HCNT 0x0024 +#define CXD56_IC_HS_SCL_LCNT 0x0028 +#define CXD56_IC_INTR_STAT 0x002C +#define CXD56_IC_INTR_MASK 0x0030 +#define CXD56_IC_RAW_INTR_STAT 0x0034 +#define CXD56_IC_RX_TL 0x0038 +#define CXD56_IC_TX_TL 0x003C +#define CXD56_IC_CLR_INTR 0x0040 +#define CXD56_IC_CLR_RX_UNDER 0x0044 +#define CXD56_IC_CLR_RX_OVER 0x0048 +#define CXD56_IC_CLR_TX_OVER 0x004C +#define CXD56_IC_CLR_RD_REQ 0x0050 +#define CXD56_IC_CLR_TX_ABRT 0x0054 +#define CXD56_IC_CLR_RX_DONE 0x0058 +#define CXD56_IC_CLR_ACTIVITY 0x005C +#define CXD56_IC_CLR_STOP_DET 0x0060 +#define CXD56_IC_CLR_START_DET 0x0064 +#define CXD56_IC_CLR_GEN_CALL 0x0068 +#define CXD56_IC_ENABLE 0x006C +#define CXD56_IC_STATUS 0x0070 +#define CXD56_IC_TXFLR 0x0074 +#define CXD56_IC_RXFLR 0x0078 +#define CXD56_IC_SDA_HOLD 0x007C +#define CXD56_IC_TX_ABRT_SOURCE 0x0080 +#define CXD56_IC_SLV_DATA_NACK_ONLY 0x0084 +#define CXD56_IC_DMA_CR 0x0088 +#define CXD56_IC_DMA_TDLR 0x008C +#define CXD56_IC_DMA_RDLR 0x0090 +#define CXD56_IC_SDA_SETUP 0x0094 +#define CXD56_IC_ACK_GENERAL_CALL 0x0098 +#define CXD56_IC_ENABLE_STATUS 0x009C +#define CXD56_IC_FS_SPKLEN 0x00A0 +#define CXD56_IC_HS_SPKLEN 0x00A4 +#define CXD56_IC_TXDATA 0x00C0 +#define CXD56_IC_COMP_PARAM_1 0x00F4 +#define CXD56_IC_COMP_VERSION 0x00F8 +#define CXD56_IC_COMP_TYPE 0x00FC + +/* Register bit definitions *************************************************/ + +/* IC_CON */ + +#define IC_RX_FIFO_FULL_HLD_CTRL (1u<<9) +#define IC_TX_EMPTY_CTRL (1u<<8) +#define IC_STOP_DET_IFADDRESSED (1u<<7) +#define IC_SLAVE_DISABLE (1u<<6) +#define IC_RESTART_EN (1u<<5) +#define IC_10BITADDR_MASTER (1u<<4) +#define IC_10BITADDR_SLAVE (1u<<3) +#define IC_MAX_SPEED_MODE (3u<<1) +#define IC_MASTER_MODE (1u<<0) + +#define IC_SPEED_SS (1u<<1) +#define IC_SPEED_FS (2u<<1) +#define IC_SPEED_HS (3u<<1) + +/* IC_DATA_CMD */ + +#define CMD_FIRST_DATA_BYTE (1u<<11) +#define CMD_RESTART (1u<<10) +#define CMD_STOP (1u<<9) +#define CMD_READ (1u<<8) +#define CMD_DAT 0x000000FFu + +/* IC_INTR_STAT */ + +/* IC_INTR_MASK */ + +/* IC_RAW_INTR_STAT */ + +#define INTR_MST_ON_HOLD (1u<<13) +#define INTR_RESTART_DET (1u<<12) +#define INTR_GEN_CALL (1u<<11) +#define INTR_START_DET (1u<<10) +#define INTR_STOP_DET (1u<< 9) +#define INTR_ACTIVITY (1u<< 8) +#define INTR_RX_DONE (1u<< 7) +#define INTR_TX_ABRT (1u<< 6) +#define INTR_RD_REQ (1u<< 5) +#define INTR_TX_EMPTY (1u<< 4) +#define INTR_TX_OVER (1u<< 3) +#define INTR_RX_FULL (1u<< 2) +#define INTR_RX_OVER (1u<< 1) +#define INTR_RX_UNDER (1u<< 0) + +/* IC_STATUS */ + +#define STATUS_SLV_ACTIVITY (1u<< 6) +#define STATUS_MST_ACTIVITY (1u<< 5) +#define STATUS_RFF (1u<< 4) +#define STATUS_RFNE (1u<< 3) +#define STATUS_TFE (1u<< 2) +#define STATUS_TFNF (1u<< 1) +#define STATUS_ACTIVITY (1u<< 0) + +/* IC_ENABLE_STATUS */ + +#define ESTATUS_SLV_FIFO_FLUSHED (1u<< 2) +#define ESTATUS_SLV_RX_ABORTED (1u<< 1) +#define ESTATUS_IC_EN (1u<< 0) + +/* IC_TX_ABRT_SOURCE */ + +#define ABRT_USER_ABRT (1u<<16) +#define ABRT_SLVRD_INTX (1u<<15) +#define ABRT_SLV_ARBLOST (1u<<14) +#define ABRT_SLVFLUSH_TXFIFO (1u<<13) +#define ABRT_ARB_LOST (1u<<12) +#define ABRT_MASTER_DIS (1u<<11) +#define ABRT_10B_RD_NORSTRT (1u<<10) +#define ABRT_SBYTE_NORSTRT (1u<< 9) +#define ABRT_HS_NORSTRT (1u<< 8) +#define ABRT_SBYTE_ACKDET (1u<< 7) +#define ABRT_HS_ACKDET (1u<< 6) +#define ABRT_GCALL_READ (1u<< 5) +#define ABRT_GCALL_NOACK (1u<< 4) +#define ABRT_TXDATA_NOACK (1u<< 3) +#define ABRT_10ADDR2_NOACK (1u<< 2) +#define ABRT_10ADDR1_NOACK (1u<< 1) +#define ABRT_7B_ADDR_NOACK (1u<< 0) + +/* IC_DMA_CR */ + +#define DMA_TDMAE (1u<< 1) +#define DMA_RDMAE (1u<< 0) + +/* IC_COMP_PARAM_1 */ + +#define COMP_PARAM_1_TX_BUFFER_DEPTH 0x00FF0000UL +#define COMP_PARAM_1_RX_BUFFER_DEPTH 0x0000FF00UL +#define COMP_PARAM_1_ADD_ENCODED_PARAMS 0x00000080UL +#define COMP_PARAM_1_HAS_DMA 0x00000040UL +#define COMP_PARAM_1_INTR_IO 0x00000020UL +#define COMP_PARAM_1_HC_COUNT_VALUES 0x00000010UL +#define COMP_PARAM_1_MAX_SPEED_MODE 0x0000000CUL +#define COMP_PARAM_1_APB_DATA_WIDTH 0x00000003UL + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_CXD56XX_CHIP_CXD56_I2C_H */ diff --git a/arch/arm/src/cxd56xx/hardware/cxd56_scu.h b/arch/arm/src/cxd56xx/hardware/cxd56_scu.h new file mode 100644 index 0000000000..f242c09806 --- /dev/null +++ b/arch/arm/src/cxd56xx/hardware/cxd56_scu.h @@ -0,0 +1,197 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/hardware/cxd56_scu.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CHIP_CXD56_SCU_H +#define __ARCH_ARM_SRC_CXD56XX_CHIP_CXD56_SCU_H + +#define SCU_PWM0_PARAM (CXD56_SCU_BASE + 0x0000) +#define SCU_PWM0_EN (CXD56_SCU_BASE + 0x0004) +#define SCU_PWM0_UPDATE (CXD56_SCU_BASE + 0x0008) +#define SCU_PWM1_PARAM (CXD56_SCU_BASE + 0x000c) +#define SCU_PWM1_EN (CXD56_SCU_BASE + 0x0010) +#define SCU_PWM1_UPDATE (CXD56_SCU_BASE + 0x0014) +#define SCU_SEQ_ENABLE_ALL (CXD56_SCU_BASE + 0x0020) +#define SCU_SEQ_ACCESS_INHIBIT (CXD56_SCU_BASE + 0x0024) +#define SCU_START_CTRL_COMMON (CXD56_SCU_BASE + 0x0028) +#define SCU_START_MODE0 (CXD56_SCU_BASE + 0x002c) +#define SCU_START_MODE1 (CXD56_SCU_BASE + 0x0030) +#define SCU_START_INTERVAL3_0 (CXD56_SCU_BASE + 0x0034) +#define SCU_START_INTERVAL7_4 (CXD56_SCU_BASE + 0x0038) +#define SCU_START_INTERVAL9_8 (CXD56_SCU_BASE + 0x003c) +#define SCU_START_PHASE1_0 (CXD56_SCU_BASE + 0x0040) +#define SCU_START_PHASE3_2 (CXD56_SCU_BASE + 0x0044) +#define SCU_START_PHASE5_4 (CXD56_SCU_BASE + 0x0048) +#define SCU_START_PHASE7_6 (CXD56_SCU_BASE + 0x004c) +#define SCU_START_PHASE9_8 (CXD56_SCU_BASE + 0x0050) +#define SCU_SINGLE_EXE (CXD56_SCU_BASE + 0x0054) +#define SCU_START_CTRL_STT0 (CXD56_SCU_BASE + 0x0058) +#define SCU_START_CTRL_STT1 (CXD56_SCU_BASE + 0x005c) +#define SCU_DEBUG_CTRL (CXD56_SCU_BASE + 0x0060) +#define SCU_OFST_GAIN_EN (CXD56_SCU_BASE + 0x0070) +#define SCU_UNSIGNED_TO_SIGNED (CXD56_SCU_BASE + 0x0074) +#define SCU_DEC_CLR (CXD56_SCU_BASE + 0x0078) +#define SCU_MATHFUNC_CLR (CXD56_SCU_BASE + 0x007c) +#define SCU_EVENT_STT (CXD56_SCU_BASE + 0x0080) +#define SCU_DECIMATION_PARAM0 (CXD56_SCU_BASE + 0x0084) +#define SCU_DECIMATION_PARAM1 (CXD56_SCU_BASE + 0x0088) +#define SCU_MATHFUNC_SEL (CXD56_SCU_BASE + 0x008c) +#define SCU_MATHFUNC_POS0 (CXD56_SCU_BASE + 0x0090) +#define SCU_MATHFUNC_POS1 (CXD56_SCU_BASE + 0x0094) +#define SCU_MATHFUNC_POS2 (CXD56_SCU_BASE + 0x0098) +#define SCU_MATHFUNC_POS(n) (SCU_MATHFUNC_POS0 + (n * 4)) +#define SCU_MATHFUNC_PARAM_0_0 (CXD56_SCU_BASE + 0x00a0) +#define SCU_MATHFUNC_PARAM_C0_0_0_MSB (CXD56_SCU_BASE + 0x00a4) +#define SCU_MATHFUNC_PARAM_C0_0_0_LSB (CXD56_SCU_BASE + 0x00a8) +#define SCU_MATHFUNC_PARAM_C1_0_0_MSB (CXD56_SCU_BASE + 0x00b0) +#define SCU_MATHFUNC_PARAM_C1_0_0_LSB (CXD56_SCU_BASE + 0x00b4) +#define SCU_MATHFUNC_PARAM_C2_0_0_MSB (CXD56_SCU_BASE + 0x00b8) +#define SCU_MATHFUNC_PARAM_C2_0_0_LSB (CXD56_SCU_BASE + 0x00bc) +#define SCU_MATHFUNC_PARAM_C3_0_0_MSB (CXD56_SCU_BASE + 0x00d0) +#define SCU_MATHFUNC_PARAM_C3_0_0_LSB (CXD56_SCU_BASE + 0x00d4) +#define SCU_MATHFUNC_PARAM_C4_0_0_MSB (CXD56_SCU_BASE + 0x00d8) +#define SCU_MATHFUNC_PARAM_C4_0_0_LSB (CXD56_SCU_BASE + 0x00dc) +#define SCU_MATHFUNC_PARAM_0_1 (CXD56_SCU_BASE + 0x00e0) +#define SCU_MATHFUNC_PARAM_C0_0_1_MSB (CXD56_SCU_BASE + 0x00e4) +#define SCU_MATHFUNC_PARAM_C0_0_1_LSB (CXD56_SCU_BASE + 0x00e8) +#define SCU_MATHFUNC_PARAM_C1_0_1_MSB (CXD56_SCU_BASE + 0x00ec) +#define SCU_MATHFUNC_PARAM_C1_0_1_LSB (CXD56_SCU_BASE + 0x00f0) +#define SCU_MATHFUNC_PARAM_C2_0_1_MSB (CXD56_SCU_BASE + 0x00f4) +#define SCU_MATHFUNC_PARAM_C2_0_1_LSB (CXD56_SCU_BASE + 0x00f8) +#define SCU_MATHFUNC_PARAM_C3_0_1_MSB (CXD56_SCU_BASE + 0x00fc) +#define SCU_MATHFUNC_PARAM_C3_0_1_LSB (CXD56_SCU_BASE + 0x0100) +#define SCU_MATHFUNC_PARAM_C4_0_1_MSB (CXD56_SCU_BASE + 0x0104) +#define SCU_MATHFUNC_PARAM_C4_0_1_LSB (CXD56_SCU_BASE + 0x0108) +#define SCU_MATHFUNC_PARAM_1_0 (CXD56_SCU_BASE + 0x010c) +#define SCU_MATHFUNC_PARAM_C0_1_0_MSB (CXD56_SCU_BASE + 0x0110) +#define SCU_MATHFUNC_PARAM_C0_1_0_LSB (CXD56_SCU_BASE + 0x0114) +#define SCU_MATHFUNC_PARAM_C1_1_0_MSB (CXD56_SCU_BASE + 0x0118) +#define SCU_MATHFUNC_PARAM_C1_1_0_LSB (CXD56_SCU_BASE + 0x011c) +#define SCU_MATHFUNC_PARAM_C2_1_0_MSB (CXD56_SCU_BASE + 0x0120) +#define SCU_MATHFUNC_PARAM_C2_1_0_LSB (CXD56_SCU_BASE + 0x0124) +#define SCU_MATHFUNC_PARAM_C3_1_0_MSB (CXD56_SCU_BASE + 0x0128) +#define SCU_MATHFUNC_PARAM_C3_1_0_LSB (CXD56_SCU_BASE + 0x012c) +#define SCU_MATHFUNC_PARAM_C4_1_0_MSB (CXD56_SCU_BASE + 0x0130) +#define SCU_MATHFUNC_PARAM_C4_1_0_LSB (CXD56_SCU_BASE + 0x0134) +#define SCU_MATHFUNC_PARAM_1_1 (CXD56_SCU_BASE + 0x0138) +#define SCU_MATHFUNC_PARAM_C0_1_1_MSB (CXD56_SCU_BASE + 0x013c) +#define SCU_MATHFUNC_PARAM_C0_1_1_LSB (CXD56_SCU_BASE + 0x0140) +#define SCU_MATHFUNC_PARAM_C1_1_1_MSB (CXD56_SCU_BASE + 0x0144) +#define SCU_MATHFUNC_PARAM_C1_1_1_LSB (CXD56_SCU_BASE + 0x0148) +#define SCU_MATHFUNC_PARAM_C2_1_1_MSB (CXD56_SCU_BASE + 0x014c) +#define SCU_MATHFUNC_PARAM_C2_1_1_LSB (CXD56_SCU_BASE + 0x0150) +#define SCU_MATHFUNC_PARAM_C3_1_1_MSB (CXD56_SCU_BASE + 0x0154) +#define SCU_MATHFUNC_PARAM_C3_1_1_LSB (CXD56_SCU_BASE + 0x0158) +#define SCU_MATHFUNC_PARAM_C4_1_1_MSB (CXD56_SCU_BASE + 0x015c) +#define SCU_MATHFUNC_PARAM_C4_1_1_LSB (CXD56_SCU_BASE + 0x0160) +#define SCU_MATHFUNC_PARAM_2_0 (CXD56_SCU_BASE + 0x0164) +#define SCU_MATHFUNC_PARAM_C0_2_0_MSB (CXD56_SCU_BASE + 0x0168) +#define SCU_MATHFUNC_PARAM_C0_2_0_LSB (CXD56_SCU_BASE + 0x016c) +#define SCU_MATHFUNC_PARAM_C1_2_0_MSB (CXD56_SCU_BASE + 0x0170) +#define SCU_MATHFUNC_PARAM_C1_2_0_LSB (CXD56_SCU_BASE + 0x0174) +#define SCU_MATHFUNC_PARAM_C2_2_0_MSB (CXD56_SCU_BASE + 0x0178) +#define SCU_MATHFUNC_PARAM_C2_2_0_LSB (CXD56_SCU_BASE + 0x017c) +#define SCU_MATHFUNC_PARAM_C3_2_0_MSB (CXD56_SCU_BASE + 0x0180) +#define SCU_MATHFUNC_PARAM_C3_2_0_LSB (CXD56_SCU_BASE + 0x0184) +#define SCU_MATHFUNC_PARAM_C4_2_0_MSB (CXD56_SCU_BASE + 0x0188) +#define SCU_MATHFUNC_PARAM_C4_2_0_LSB (CXD56_SCU_BASE + 0x018c) +#define SCU_MATHFUNC_PARAM_2_1 (CXD56_SCU_BASE + 0x0190) +#define SCU_MATHFUNC_PARAM_C0_2_1_MSB (CXD56_SCU_BASE + 0x0194) +#define SCU_MATHFUNC_PARAM_C0_2_1_LSB (CXD56_SCU_BASE + 0x0198) +#define SCU_MATHFUNC_PARAM_C1_2_1_MSB (CXD56_SCU_BASE + 0x019c) +#define SCU_MATHFUNC_PARAM_C1_2_1_LSB (CXD56_SCU_BASE + 0x01a0) +#define SCU_MATHFUNC_PARAM_C2_2_1_MSB (CXD56_SCU_BASE + 0x01a4) +#define SCU_MATHFUNC_PARAM_C2_2_1_LSB (CXD56_SCU_BASE + 0x01a8) +#define SCU_MATHFUNC_PARAM_C3_2_1_MSB (CXD56_SCU_BASE + 0x01ac) +#define SCU_MATHFUNC_PARAM_C3_2_1_LSB (CXD56_SCU_BASE + 0x01b0) +#define SCU_MATHFUNC_PARAM_C4_2_1_MSB (CXD56_SCU_BASE + 0x01b4) +#define SCU_MATHFUNC_PARAM_C4_2_1_LSB (CXD56_SCU_BASE + 0x01b8) +#define SCU_EVENT_PARAM_THRESH(n) (SCU_EVENT_PARAM0_THRESH + ((n) * 0x10)) +#define SCU_EVENT_PARAM_COUNT0(n) (SCU_EVENT_PARAM0_COUNT0 + ((n) * 0x10)) +#define SCU_EVENT_PARAM_COUNT1(n) (SCU_EVENT_PARAM0_COUNT1 + ((n) * 0x10)) +#define SCU_EVENT_INTR_ENABLE(n) (SCU_EVENT_PARAM0_COUNT2 + ((n) * 0x10)) +#define SCU_EVENT_PARAM_DELAY_SAMPLE(n) (SCU_EVENT_PARAM0_DELAY_SAMPLE + ((n) * 0x4)) +#define SCU_EVENT_PARAM0_THRESH (CXD56_SCU_BASE + 0x01bc) +#define SCU_EVENT_PARAM0_COUNT0 (CXD56_SCU_BASE + 0x01c0) +#define SCU_EVENT_PARAM0_COUNT1 (CXD56_SCU_BASE + 0x01c4) +#define SCU_EVENT_PARAM0_COUNT2 (CXD56_SCU_BASE + 0x01c8) +#define SCU_EVENT_PARAM1_THRESH (CXD56_SCU_BASE + 0x01cc) +#define SCU_EVENT_PARAM1_COUNT0 (CXD56_SCU_BASE + 0x01d0) +#define SCU_EVENT_PARAM1_COUNT1 (CXD56_SCU_BASE + 0x01d4) +#define SCU_EVENT_PARAM1_COUNT2 (CXD56_SCU_BASE + 0x01d8) +#define SCU_EVENT_PARAM2_THRESH (CXD56_SCU_BASE + 0x01dc) +#define SCU_EVENT_PARAM2_COUNT0 (CXD56_SCU_BASE + 0x01e0) +#define SCU_EVENT_PARAM2_COUNT1 (CXD56_SCU_BASE + 0x01e4) +#define SCU_EVENT_PARAM2_COUNT2 (CXD56_SCU_BASE + 0x01e8) +#define SCU_EVENT_PARAM0_DELAY_SAMPLE (CXD56_SCU_BASE + 0x01ec) +#define SCU_EVENT_PARAM1_DELAY_SAMPLE (CXD56_SCU_BASE + 0x01f0) +#define SCU_EVENT_PARAM2_DELAY_SAMPLE (CXD56_SCU_BASE + 0x01f4) +#define SCU_EVENT_TIMESTAMP0_R_MSB (CXD56_SCU_BASE + 0x0200) +#define SCU_EVENT_TIMESTAMP0_R_LSB (CXD56_SCU_BASE + 0x0204) +#define SCU_EVENT_TIMESTAMP1_R_MSB (CXD56_SCU_BASE + 0x0208) +#define SCU_EVENT_TIMESTAMP1_R_LSB (CXD56_SCU_BASE + 0x020c) +#define SCU_EVENT_TIMESTAMP2_R_MSB (CXD56_SCU_BASE + 0x0210) +#define SCU_EVENT_TIMESTAMP2_R_LSB (CXD56_SCU_BASE + 0x0214) +#define SCU_EVENT_TIMESTAMP0_F_MSB (CXD56_SCU_BASE + 0x0218) +#define SCU_EVENT_TIMESTAMP0_F_LSB (CXD56_SCU_BASE + 0x021c) +#define SCU_EVENT_TIMESTAMP1_F_MSB (CXD56_SCU_BASE + 0x0220) +#define SCU_EVENT_TIMESTAMP1_F_LSB (CXD56_SCU_BASE + 0x0224) +#define SCU_EVENT_TIMESTAMP2_F_MSB (CXD56_SCU_BASE + 0x0228) +#define SCU_EVENT_TIMESTAMP2_F_LSB (CXD56_SCU_BASE + 0x022c) +#define SCU_FIFO_WRITE_CTRL (CXD56_SCU_BASE + 0x0230) +#define SCU_DMA0_SEL (CXD56_SCU_BASE + 0x0300) +#define SCU_INT_ENABLE_MAIN (CXD56_SCU_BASE + 0x0400) +#define SCU_INT_DISABLE_MAIN (CXD56_SCU_BASE + 0x0404) +#define SCU_INT_CLEAR_MAIN (CXD56_SCU_BASE + 0x0408) +#define SCU_LEVEL_SEL_MAIN (CXD56_SCU_BASE + 0x040c) +#define SCU_INT_RAW_STT_MAIN (CXD56_SCU_BASE + 0x0410) +#define SCU_INT_MASKED_STT_MAIN (CXD56_SCU_BASE + 0x0414) +#define SCU_INT_ENABLE_ERR_0 (CXD56_SCU_BASE + 0x0420) +#define SCU_INT_DISABLE_ERR_0 (CXD56_SCU_BASE + 0x0424) +#define SCU_INT_CLEAR_ERR_0 (CXD56_SCU_BASE + 0x0428) +#define SCU_INT_RAW_STT_ERR_0 (CXD56_SCU_BASE + 0x042c) +#define SCU_INT_MASKED_STT_ERR_0 (CXD56_SCU_BASE + 0x0430) +#define SCU_INT_ENABLE_ERR_1 (CXD56_SCU_BASE + 0x0440) +#define SCU_INT_DISABLE_ERR_1 (CXD56_SCU_BASE + 0x0444) +#define SCU_INT_CLEAR_ERR_1 (CXD56_SCU_BASE + 0x0448) +#define SCU_INT_RAW_STT_ERR_1 (CXD56_SCU_BASE + 0x044c) +#define SCU_INT_MASKED_STT_ERR_1 (CXD56_SCU_BASE + 0x0450) +#define SCU_INT_ENABLE_ERR_2 (CXD56_SCU_BASE + 0x0460) +#define SCU_INT_DISABLE_ERR_2 (CXD56_SCU_BASE + 0x0464) +#define SCU_INT_CLEAR_ERR_2 (CXD56_SCU_BASE + 0x0468) +#define SCU_INT_RAW_STT_ERR_2 (CXD56_SCU_BASE + 0x046c) +#define SCU_INT_MASKED_STT_ERR_2 (CXD56_SCU_BASE + 0x0470) +#define SCU_RAM_TEST (CXD56_SCU_BASE + 0x0500) + +#endif /* __ARCH_ARM_SRC_CXD56XX_CHIP_CXD56_SCU_H */ diff --git a/arch/arm/src/cxd56xx/hardware/cxd56_scufifo.h b/arch/arm/src/cxd56xx/hardware/cxd56_scufifo.h new file mode 100644 index 0000000000..478c89de02 --- /dev/null +++ b/arch/arm/src/cxd56xx/hardware/cxd56_scufifo.h @@ -0,0 +1,425 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/hardware/cxd56_scufifo.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CHIP_CXD56_SCUFIFO_H +#define __ARCH_ARM_SRC_CXD56XX_CHIP_CXD56_SCUFIFO_H + +#define SCUFIFO_R_CTRL0(fn) (((fn) * 0x20) + SCUFIFO_D0_R1_C_CTRL0) +#define SCUFIFO_R_CTRL1(fn) (((fn) * 0x20) + SCUFIFO_D0_R1_C_CTRL1) +#define SCUFIFO_R_STATUS0(fn) (((fn) * 0x20) + SCUFIFO_D0_R1_C_STATUS0) +#define SCUFIFO_R_STATUS1(fn) (((fn) * 0x20) + SCUFIFO_D0_R1_C_STATUS1) +#define SCUFIFO_R_TIMESTAMP0(fn) (((fn) * 0x20) + SCUFIFO_D0_R1_C_TIMSTAMP0) +#define SCUFIFO_R_TIMESTAMP1(fn) (((fn) * 0x20) + SCUFIFO_D0_R1_C_TIMSTAMP1) + +#define SCUFIFO_W_CTRL0(fn) (((fn) * 0x20) + SCUFIFO_D0_W0_S_CTRL0) +#define SCUFIFO_W_CTRL1(fn) (((fn) * 0x20) + SCUFIFO_D0_W0_S_CTRL1) +#define SCUFIFO_W_STATUS0(fn) (((fn) * 0x20) + SCUFIFO_D0_W0_S_STATUS0) +#define SCUFIFO_W_STATUS1(fn) (((fn) * 0x20) + SCUFIFO_D0_W0_S_STATUS1) +#define SCUFIFO_W_TIMESTAMP0(fn) (((fn) * 0x20) + SCUFIFO_D0_W0_S_TIMSTAMP0) +#define SCUFIFO_W_TIMESTAMP1(fn) (((fn) * 0x20) + SCUFIFO_D0_W0_S_TIMSTAMP1) + +/* SCUFIFO_[RW]_CTRL1 *******************************************************/ + +#define SCUFIFO_ENABLE (1 << 24) /* [R] Enable FIFO */ +#define SCUFIFO_DMAENABLE (1 << 25) /* [R] Enable FIFO DMA control signal */ +#define SCUFIFO_PHASERESET (1 << 8) /* [R] Reset sample phase */ +#define SCUFIFO_RESET (1 << 16) /* [RW] Reset FIFO */ +#define SCUFIFO_UNDERRUNCLR (1 << 1) /* [R] Clear FIFO under run error */ +#define SCUFIFO_OVERRUNCLR (1 << 0) /* [R] Clear FIFO over run error */ +#define SCUFIFO_OVERWRITE (1 << 4) /* [W] Over write when FIFO is full. */ +#define SCUFIFO_ENADCINTERVAL (1 << 12) /* [W] Enable ADC interval instead of + * PREDIV. */ +#define SCUFIFO_ADCINTERVAL(x) (((x) & 0xf) << 8) /* [W] ADC interval */ +#define SCUFIFO_BPS(x) ((x) & 0xf) /* [W] Bytes per sample */ + +#define SCUFIFO_D0_W0_S_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x0) +#define SCUFIFO_D0_W0_S_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x4) +#define SCUFIFO_D0_W0_S_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x8) +#define SCUFIFO_D0_W0_S_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0xc) +#define SCUFIFO_D0_W0_S_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x10) +#define SCUFIFO_D0_W1_S_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x20) +#define SCUFIFO_D0_W1_S_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x24) +#define SCUFIFO_D0_W1_S_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x28) +#define SCUFIFO_D0_W1_S_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x2c) +#define SCUFIFO_D0_W1_S_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x30) +#define SCUFIFO_D0_W2_S_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x40) +#define SCUFIFO_D0_W2_S_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x44) +#define SCUFIFO_D0_W2_S_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x48) +#define SCUFIFO_D0_W2_S_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x4c) +#define SCUFIFO_D0_W2_S_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x50) +#define SCUFIFO_D0_W3_S_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x60) +#define SCUFIFO_D0_W3_S_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x64) +#define SCUFIFO_D0_W3_S_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x68) +#define SCUFIFO_D0_W3_S_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x6c) +#define SCUFIFO_D0_W3_S_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x70) +#define SCUFIFO_D1_W0_S_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x80) +#define SCUFIFO_D1_W0_S_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x84) +#define SCUFIFO_D1_W0_S_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x88) +#define SCUFIFO_D1_W0_S_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x8c) +#define SCUFIFO_D1_W0_S_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x90) +#define SCUFIFO_D1_W1_S_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0xa0) +#define SCUFIFO_D1_W1_S_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0xa4) +#define SCUFIFO_D1_W1_S_STATUS (CXD56_SCU_FIFO_REG_BASE + 0xa8) +#define SCUFIFO_D1_W1_S_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0xac) +#define SCUFIFO_D1_W1_S_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0xb0) +#define SCUFIFO_D1_W2_S_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0xc0) +#define SCUFIFO_D1_W2_S_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0xc4) +#define SCUFIFO_D1_W2_S_STATUS (CXD56_SCU_FIFO_REG_BASE + 0xc8) +#define SCUFIFO_D1_W2_S_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0xcc) +#define SCUFIFO_D1_W2_S_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0xd0) +#define SCUFIFO_D1_W3_S_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0xe0) +#define SCUFIFO_D1_W3_S_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0xe4) +#define SCUFIFO_D1_W3_S_STATUS (CXD56_SCU_FIFO_REG_BASE + 0xe8) +#define SCUFIFO_D1_W3_S_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0xec) +#define SCUFIFO_D1_W3_S_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0xf0) +#define SCUFIFO_N0_W_S_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x100) +#define SCUFIFO_N0_W_S_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x104) +#define SCUFIFO_N0_W_S_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x108) +#define SCUFIFO_N0_W_S_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x10c) +#define SCUFIFO_N0_W_S_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x110) +#define SCUFIFO_N1_W_S_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x120) +#define SCUFIFO_N1_W_S_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x124) +#define SCUFIFO_N1_W_S_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x128) +#define SCUFIFO_N1_W_S_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x12c) +#define SCUFIFO_N1_W_S_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x130) +#define SCUFIFO_N2_W_S_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x140) +#define SCUFIFO_N2_W_S_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x144) +#define SCUFIFO_N2_W_S_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x148) +#define SCUFIFO_N2_W_S_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x14c) +#define SCUFIFO_N2_W_S_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x150) +#define SCUFIFO_N3_W_S_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x160) +#define SCUFIFO_N3_W_S_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x164) +#define SCUFIFO_N3_W_S_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x168) +#define SCUFIFO_N3_W_S_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x16c) +#define SCUFIFO_N3_W_S_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x170) +#define SCUFIFO_N4_W_S_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x180) +#define SCUFIFO_N4_W_S_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x184) +#define SCUFIFO_N4_W_S_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x188) +#define SCUFIFO_N4_W_S_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x18c) +#define SCUFIFO_N4_W_S_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x190) +#define SCUFIFO_N5_W_S_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1a0) +#define SCUFIFO_N5_W_S_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1a4) +#define SCUFIFO_N5_W_S_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x1a8) +#define SCUFIFO_N5_W_S_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1ac) +#define SCUFIFO_N5_W_S_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1b0) +#define SCUFIFO_N6_W_S_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1c0) +#define SCUFIFO_N6_W_S_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1c4) +#define SCUFIFO_N6_W_S_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x1c8) +#define SCUFIFO_N6_W_S_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1cc) +#define SCUFIFO_N6_W_S_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1d0) +#define SCUFIFO_N7_W_S_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1e0) +#define SCUFIFO_N7_W_S_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1e4) +#define SCUFIFO_N7_W_S_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x1e8) +#define SCUFIFO_N7_W_S_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1ec) +#define SCUFIFO_N7_W_S_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1f0) +#define SCUFIFO_V0_W_C_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x200) +#define SCUFIFO_V0_W_C_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x204) +#define SCUFIFO_V0_W_C_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x208) +#define SCUFIFO_V0_W_C_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x20c) +#define SCUFIFO_V0_W_C_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x210) +#define SCUFIFO_V0_W_C_TIMSTAMP_SET0 (CXD56_SCU_FIFO_REG_BASE + 0x214) +#define SCUFIFO_V0_W_C_TIMSTAMP_SET1 (CXD56_SCU_FIFO_REG_BASE + 0x218) +#define SCUFIFO_V1_W_C_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x220) +#define SCUFIFO_V1_W_C_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x224) +#define SCUFIFO_V1_W_C_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x228) +#define SCUFIFO_V1_W_C_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x22c) +#define SCUFIFO_V1_W_C_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x230) +#define SCUFIFO_V1_W_C_TIMSTAMP_SET0 (CXD56_SCU_FIFO_REG_BASE + 0x234) +#define SCUFIFO_V1_W_C_TIMSTAMP_SET1 (CXD56_SCU_FIFO_REG_BASE + 0x238) +#define SCUFIFO_V2_W_C_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x240) +#define SCUFIFO_V2_W_C_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x244) +#define SCUFIFO_V2_W_C_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x248) +#define SCUFIFO_V2_W_C_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x24c) +#define SCUFIFO_V2_W_C_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x250) +#define SCUFIFO_V2_W_C_TIMSTAMP_SET0 (CXD56_SCU_FIFO_REG_BASE + 0x254) +#define SCUFIFO_V2_W_C_TIMSTAMP_SET1 (CXD56_SCU_FIFO_REG_BASE + 0x258) +#define SCUFIFO_V3_W_C_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x260) +#define SCUFIFO_V3_W_C_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x264) +#define SCUFIFO_V3_W_C_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x268) +#define SCUFIFO_V3_W_C_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x26c) +#define SCUFIFO_V3_W_C_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x270) +#define SCUFIFO_V3_W_C_TIMSTAMP_SET0 (CXD56_SCU_FIFO_REG_BASE + 0x274) +#define SCUFIFO_V3_W_C_TIMSTAMP_SET1 (CXD56_SCU_FIFO_REG_BASE + 0x278) +#define SCUFIFO_V4_W_C_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x280) +#define SCUFIFO_V4_W_C_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x284) +#define SCUFIFO_V4_W_C_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x288) +#define SCUFIFO_V4_W_C_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x28c) +#define SCUFIFO_V4_W_C_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x290) +#define SCUFIFO_V4_W_C_TIMSTAMP_SET0 (CXD56_SCU_FIFO_REG_BASE + 0x294) +#define SCUFIFO_V4_W_C_TIMSTAMP_SET1 (CXD56_SCU_FIFO_REG_BASE + 0x298) +#define SCUFIFO_V5_W_C_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x2a0) +#define SCUFIFO_V5_W_C_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x2a4) +#define SCUFIFO_V5_W_C_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x2a8) +#define SCUFIFO_V5_W_C_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x2ac) +#define SCUFIFO_V5_W_C_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x2b0) +#define SCUFIFO_V5_W_C_TIMSTAMP_SET0 (CXD56_SCU_FIFO_REG_BASE + 0x2b4) +#define SCUFIFO_V5_W_C_TIMSTAMP_SET1 (CXD56_SCU_FIFO_REG_BASE + 0x2b8) +#define SCUFIFO_V6_W_C_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x2c0) +#define SCUFIFO_V6_W_C_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x2c4) +#define SCUFIFO_V6_W_C_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x2c8) +#define SCUFIFO_V6_W_C_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x2cc) +#define SCUFIFO_V6_W_C_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x2d0) +#define SCUFIFO_V6_W_C_TIMSTAMP_SET0 (CXD56_SCU_FIFO_REG_BASE + 0x2d4) +#define SCUFIFO_V6_W_C_TIMSTAMP_SET1 (CXD56_SCU_FIFO_REG_BASE + 0x2d8) +#define SCUFIFO_V7_W_C_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x2e0) +#define SCUFIFO_V7_W_C_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x2e4) +#define SCUFIFO_V7_W_C_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x2e8) +#define SCUFIFO_V7_W_C_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x2ec) +#define SCUFIFO_V7_W_C_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x2f0) +#define SCUFIFO_V7_W_C_TIMSTAMP_SET0 (CXD56_SCU_FIFO_REG_BASE + 0x2f4) +#define SCUFIFO_V7_W_C_TIMSTAMP_SET1 (CXD56_SCU_FIFO_REG_BASE + 0x2f8) +#define SCUFIFO_V8_W_C_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x300) +#define SCUFIFO_V8_W_C_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x304) +#define SCUFIFO_V8_W_C_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x308) +#define SCUFIFO_V8_W_C_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x30c) +#define SCUFIFO_V8_W_C_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x310) +#define SCUFIFO_V8_W_C_TIMSTAMP_SET0 (CXD56_SCU_FIFO_REG_BASE + 0x314) +#define SCUFIFO_V8_W_C_TIMSTAMP_SET1 (CXD56_SCU_FIFO_REG_BASE + 0x318) +#define SCUFIFO_V9_W_C_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x320) +#define SCUFIFO_V9_W_C_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x324) +#define SCUFIFO_V9_W_C_STATUS (CXD56_SCU_FIFO_REG_BASE + 0x328) +#define SCUFIFO_V9_W_C_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x32c) +#define SCUFIFO_V9_W_C_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x330) +#define SCUFIFO_V9_W_C_TIMSTAMP_SET0 (CXD56_SCU_FIFO_REG_BASE + 0x334) +#define SCUFIFO_V9_W_C_TIMSTAMP_SET1 (CXD56_SCU_FIFO_REG_BASE + 0x338) +#define SCUFIFO_D0_R1_C_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1000) +#define SCUFIFO_D0_R1_C_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1004) +#define SCUFIFO_D0_R1_C_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x1008) +#define SCUFIFO_D0_R1_C_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x100c) +#define SCUFIFO_D0_R1_C_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1010) +#define SCUFIFO_D0_R1_C_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1014) +#define SCUFIFO_D0_R2_C_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1020) +#define SCUFIFO_D0_R2_C_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1024) +#define SCUFIFO_D0_R2_C_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x1028) +#define SCUFIFO_D0_R2_C_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x102c) +#define SCUFIFO_D0_R2_C_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1030) +#define SCUFIFO_D0_R2_C_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1034) +#define SCUFIFO_D1_R1_C_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1040) +#define SCUFIFO_D1_R1_C_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1044) +#define SCUFIFO_D1_R1_C_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x1048) +#define SCUFIFO_D1_R1_C_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x104c) +#define SCUFIFO_D1_R1_C_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1050) +#define SCUFIFO_D1_R1_C_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1054) +#define SCUFIFO_D1_R2_C_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1060) +#define SCUFIFO_D1_R2_C_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1064) +#define SCUFIFO_D1_R2_C_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x1068) +#define SCUFIFO_D1_R2_C_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x106c) +#define SCUFIFO_D1_R2_C_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1070) +#define SCUFIFO_D1_R2_C_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1074) +#define SCUFIFO_N0_R1_C_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1080) +#define SCUFIFO_N0_R1_C_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1084) +#define SCUFIFO_N0_R1_C_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x1088) +#define SCUFIFO_N0_R1_C_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x108c) +#define SCUFIFO_N0_R1_C_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1090) +#define SCUFIFO_N0_R1_C_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1094) +#define SCUFIFO_N1_R1_C_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x10a0) +#define SCUFIFO_N1_R1_C_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x10a4) +#define SCUFIFO_N1_R1_C_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x10a8) +#define SCUFIFO_N1_R1_C_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x10ac) +#define SCUFIFO_N1_R1_C_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x10b0) +#define SCUFIFO_N1_R1_C_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x10b4) +#define SCUFIFO_N2_R1_C_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x10c0) +#define SCUFIFO_N2_R1_C_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x10c4) +#define SCUFIFO_N2_R1_C_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x10c8) +#define SCUFIFO_N2_R1_C_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x10cc) +#define SCUFIFO_N2_R1_C_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x10d0) +#define SCUFIFO_N2_R1_C_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x10d4) +#define SCUFIFO_N3_R1_C_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x10e0) +#define SCUFIFO_N3_R1_C_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x10e4) +#define SCUFIFO_N3_R1_C_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x10e8) +#define SCUFIFO_N3_R1_C_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x10ec) +#define SCUFIFO_N3_R1_C_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x10f0) +#define SCUFIFO_N3_R1_C_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x10f4) +#define SCUFIFO_N4_R1_C_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1100) +#define SCUFIFO_N4_R1_C_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1104) +#define SCUFIFO_N4_R1_C_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x1108) +#define SCUFIFO_N4_R1_C_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x110c) +#define SCUFIFO_N4_R1_C_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1110) +#define SCUFIFO_N4_R1_C_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1114) +#define SCUFIFO_N5_R1_C_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1120) +#define SCUFIFO_N5_R1_C_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1124) +#define SCUFIFO_N5_R1_C_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x1128) +#define SCUFIFO_N5_R1_C_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x112c) +#define SCUFIFO_N5_R1_C_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1130) +#define SCUFIFO_N5_R1_C_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1134) +#define SCUFIFO_N6_R1_C_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1140) +#define SCUFIFO_N6_R1_C_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1144) +#define SCUFIFO_N6_R1_C_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x1148) +#define SCUFIFO_N6_R1_C_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x114c) +#define SCUFIFO_N6_R1_C_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1150) +#define SCUFIFO_N6_R1_C_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1154) +#define SCUFIFO_N7_R1_C_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1160) +#define SCUFIFO_N7_R1_C_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1164) +#define SCUFIFO_N7_R1_C_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x1168) +#define SCUFIFO_N7_R1_C_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x116c) +#define SCUFIFO_N7_R1_C_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1170) +#define SCUFIFO_N7_R1_C_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1174) +#define SCUFIFO_D0_R3_CH_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1180) +#define SCUFIFO_D0_R3_CH_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1184) +#define SCUFIFO_D0_R3_CH_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x1188) +#define SCUFIFO_D0_R3_CH_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x118c) +#define SCUFIFO_D0_R3_CH_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1190) +#define SCUFIFO_D0_R3_CH_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1194) +#define SCUFIFO_D1_R3_CH_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x11a0) +#define SCUFIFO_D1_R3_CH_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x11a4) +#define SCUFIFO_D1_R3_CH_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x11a8) +#define SCUFIFO_D1_R3_CH_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x11ac) +#define SCUFIFO_D1_R3_CH_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x11b0) +#define SCUFIFO_D1_R3_CH_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x11b4) +#define SCUFIFO_D0_R0_H_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x11c0) +#define SCUFIFO_D0_R0_H_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x11c4) +#define SCUFIFO_D0_R0_H_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x11c8) +#define SCUFIFO_D0_R0_H_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x11cc) +#define SCUFIFO_D0_R0_H_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x11d0) +#define SCUFIFO_D0_R0_H_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x11d4) +#define SCUFIFO_D1_R0_H_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x11e0) +#define SCUFIFO_D1_R0_H_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x11e4) +#define SCUFIFO_D1_R0_H_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x11e8) +#define SCUFIFO_D1_R0_H_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x11ec) +#define SCUFIFO_D1_R0_H_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x11f0) +#define SCUFIFO_D1_R0_H_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x11f4) +#define SCUFIFO_N0_R0_H_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1200) +#define SCUFIFO_N0_R0_H_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1204) +#define SCUFIFO_N0_R0_H_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x1208) +#define SCUFIFO_N0_R0_H_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x120c) +#define SCUFIFO_N0_R0_H_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1210) +#define SCUFIFO_N0_R0_H_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1214) +#define SCUFIFO_N1_R0_H_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1220) +#define SCUFIFO_N1_R0_H_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1224) +#define SCUFIFO_N1_R0_H_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x1228) +#define SCUFIFO_N1_R0_H_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x122c) +#define SCUFIFO_N1_R0_H_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1230) +#define SCUFIFO_N1_R0_H_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1234) +#define SCUFIFO_N2_R0_H_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1240) +#define SCUFIFO_N2_R0_H_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1244) +#define SCUFIFO_N2_R0_H_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x1248) +#define SCUFIFO_N2_R0_H_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x124c) +#define SCUFIFO_N2_R0_H_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1250) +#define SCUFIFO_N2_R0_H_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1254) +#define SCUFIFO_N3_R0_H_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1260) +#define SCUFIFO_N3_R0_H_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1264) +#define SCUFIFO_N3_R0_H_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x1268) +#define SCUFIFO_N3_R0_H_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x126c) +#define SCUFIFO_N3_R0_H_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1270) +#define SCUFIFO_N3_R0_H_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1274) +#define SCUFIFO_N4_R0_H_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1280) +#define SCUFIFO_N4_R0_H_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1284) +#define SCUFIFO_N4_R0_H_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x1288) +#define SCUFIFO_N4_R0_H_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x128c) +#define SCUFIFO_N4_R0_H_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1290) +#define SCUFIFO_N4_R0_H_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1294) +#define SCUFIFO_N5_R0_H_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x12a0) +#define SCUFIFO_N5_R0_H_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x12a4) +#define SCUFIFO_N5_R0_H_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x12a8) +#define SCUFIFO_N5_R0_H_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x12ac) +#define SCUFIFO_N5_R0_H_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x12b0) +#define SCUFIFO_N5_R0_H_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x12b4) +#define SCUFIFO_N6_R0_H_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x12c0) +#define SCUFIFO_N6_R0_H_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x12c4) +#define SCUFIFO_N6_R0_H_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x12c8) +#define SCUFIFO_N6_R0_H_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x12cc) +#define SCUFIFO_N6_R0_H_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x12d0) +#define SCUFIFO_N6_R0_H_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x12d4) +#define SCUFIFO_N7_R0_H_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x12e0) +#define SCUFIFO_N7_R0_H_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x12e4) +#define SCUFIFO_N7_R0_H_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x12e8) +#define SCUFIFO_N7_R0_H_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x12ec) +#define SCUFIFO_N7_R0_H_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x12f0) +#define SCUFIFO_N7_R0_H_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x12f4) +#define SCUFIFO_V0_R_H_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1300) +#define SCUFIFO_V0_R_H_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1304) +#define SCUFIFO_V0_R_H_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x1308) +#define SCUFIFO_V0_R_H_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x130c) +#define SCUFIFO_V0_R_H_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1310) +#define SCUFIFO_V0_R_H_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1314) +#define SCUFIFO_V1_R_H_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1320) +#define SCUFIFO_V1_R_H_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1324) +#define SCUFIFO_V1_R_H_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x1328) +#define SCUFIFO_V1_R_H_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x132c) +#define SCUFIFO_V1_R_H_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1330) +#define SCUFIFO_V1_R_H_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1334) +#define SCUFIFO_V2_R_H_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1340) +#define SCUFIFO_V2_R_H_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1344) +#define SCUFIFO_V2_R_H_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x1348) +#define SCUFIFO_V2_R_H_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x134c) +#define SCUFIFO_V2_R_H_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1350) +#define SCUFIFO_V2_R_H_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1354) +#define SCUFIFO_V3_R_H_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1360) +#define SCUFIFO_V3_R_H_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1364) +#define SCUFIFO_V3_R_H_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x1368) +#define SCUFIFO_V3_R_H_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x136c) +#define SCUFIFO_V3_R_H_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1370) +#define SCUFIFO_V3_R_H_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1374) +#define SCUFIFO_V4_R_H_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1380) +#define SCUFIFO_V4_R_H_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1384) +#define SCUFIFO_V4_R_H_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x1388) +#define SCUFIFO_V4_R_H_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x138c) +#define SCUFIFO_V4_R_H_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1390) +#define SCUFIFO_V4_R_H_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1394) +#define SCUFIFO_V5_R_H_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x13a0) +#define SCUFIFO_V5_R_H_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x13a4) +#define SCUFIFO_V5_R_H_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x13a8) +#define SCUFIFO_V5_R_H_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x13ac) +#define SCUFIFO_V5_R_H_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x13b0) +#define SCUFIFO_V5_R_H_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x13b4) +#define SCUFIFO_V6_R_H_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x13c0) +#define SCUFIFO_V6_R_H_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x13c4) +#define SCUFIFO_V6_R_H_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x13c8) +#define SCUFIFO_V6_R_H_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x13cc) +#define SCUFIFO_V6_R_H_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x13d0) +#define SCUFIFO_V6_R_H_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x13d4) +#define SCUFIFO_V7_R_H_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x13e0) +#define SCUFIFO_V7_R_H_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x13e4) +#define SCUFIFO_V7_R_H_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x13e8) +#define SCUFIFO_V7_R_H_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x13ec) +#define SCUFIFO_V7_R_H_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x13f0) +#define SCUFIFO_V7_R_H_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x13f4) +#define SCUFIFO_V8_R_H_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1400) +#define SCUFIFO_V8_R_H_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1404) +#define SCUFIFO_V8_R_H_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x1408) +#define SCUFIFO_V8_R_H_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x140c) +#define SCUFIFO_V8_R_H_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1410) +#define SCUFIFO_V8_R_H_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1414) +#define SCUFIFO_V9_R_H_CTRL0 (CXD56_SCU_FIFO_REG_BASE + 0x1420) +#define SCUFIFO_V9_R_H_CTRL1 (CXD56_SCU_FIFO_REG_BASE + 0x1424) +#define SCUFIFO_V9_R_H_STATUS0 (CXD56_SCU_FIFO_REG_BASE + 0x1428) +#define SCUFIFO_V9_R_H_STATUS1 (CXD56_SCU_FIFO_REG_BASE + 0x142c) +#define SCUFIFO_V9_R_H_TIMSTAMP0 (CXD56_SCU_FIFO_REG_BASE + 0x1430) +#define SCUFIFO_V9_R_H_TIMSTAMP1 (CXD56_SCU_FIFO_REG_BASE + 0x1434) +#define SCUFIFO_DECI_PARTITION_SEL (CXD56_SCU_FIFO_REG_BASE + 0x1c00) + +#define SCUFIFO_FIFO_DATA(x) (CXD56_SCU_FIFO_REG_BASE + 0x2100 + (0x4 * (x))) + +#endif /* __ARCH_ARM_SRC_CXD56XX_CHIP_CXD56_SCUFIFO_H */ diff --git a/arch/arm/src/cxd56xx/hardware/cxd56_scuseq.h b/arch/arm/src/cxd56xx/hardware/cxd56_scuseq.h new file mode 100644 index 0000000000..3f97aa049d --- /dev/null +++ b/arch/arm/src/cxd56xx/hardware/cxd56_scuseq.h @@ -0,0 +1,55 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/hardware/cxd56_scuseq.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CHIP_CXD56_SCUSEQ_H +#define __ARCH_ARM_SRC_CXD56XX_CHIP_CXD56_SCUSEQ_H + +#define SCUSEQ_SRC_SEL (CXD56_SCU_SEQ_DRAM_BASE + 0x00c) +#define SCUSEQ_PROPERTY(s) (CXD56_SCU_SEQ_DRAM_BASE + 0x020 + ((s) * 0x20)) +#define SCUSEQ_OUT_FORMAT(s) (CXD56_SCU_SEQ_DRAM_BASE + 0x024 + ((s) * 0x20)) +#define SCUSEQ_MATH_PROC_OFST_GAIN_X(s) (CXD56_SCU_SEQ_DRAM_BASE + 0x028 + ((s) * 0x20)) +#define SCUSEQ_MATH_PROC_OFST_GAIN_Y(s) (CXD56_SCU_SEQ_DRAM_BASE + 0x02c + ((s) * 0x20)) +#define SCUSEQ_MATH_PROC_OFST_GAIN_Z(s) (CXD56_SCU_SEQ_DRAM_BASE + 0x030 + ((s) * 0x20)) + +#define SCUSEQ_INSTRUCTION(x) (CXD56_SCU_SEQ_DRAM_BASE + 0x160 + ((x) * 2)) +#define SCUSEQ_ADC_PROPERTY (CXD56_SCU_SEQ_DRAM_BASE + 0x260) +#define SCUSEQ_ADC_MATH_PROC_OFST_GAIN(s) (CXD56_SCU_SEQ_DRAM_BASE + 0x264 + ((s) * 4)) +#define SCUSEQ_FIFOWREVNTCTRL(x) (CXD56_SCU_SEQ_DRAM_BASE + 0x280 + ((x) * 4)) +#define SCUSEQ_FIFOSRAMPOWCTRL (CXD56_SCU_SEQ_DRAM_BASE + 0x2C0) +#define SCUSEQ_SYNCRO_CPU2ISOP (CXD56_SCU_SEQ_DRAM_BASE + 0x2C4) +#define SCUSEQ_SYNCRO_ISOP2CPU (CXD56_SCU_SEQ_DRAM_BASE + 0x2C8) +#define SCUSEQ_RAM_OUT_DATA0 (CXD56_SCU_SEQ_DRAM_BASE + 0x2CC) + +#endif /* __ARCH_ARM_SRC_CXD56XX_CHIP_CXD56_SCUSEQ_H */ diff --git a/arch/arm/src/cxd56xx/hardware/cxd56_udmac.h b/arch/arm/src/cxd56xx/hardware/cxd56_udmac.h new file mode 100644 index 0000000000..94f1cf5e78 --- /dev/null +++ b/arch/arm/src/cxd56xx/hardware/cxd56_udmac.h @@ -0,0 +1,166 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/hardware/cxd56_udmac.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CHIP_CXD56_UDMAC_H +#define __ARCH_ARM_SRC_CXD56XX_CHIP_CXD56_UDMAC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "hardware/cxd5602_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register offsets *********************************************************/ + +/* Common Register Offsets */ + +#define CXD56_UDMAC_DMA_STATUS 0x000 +#define CXD56_UDMAC_DMA_CFG 0x004 +#define CXD56_UDMAC_CTRL_BASE_PTR 0x008 +#define CXD56_UDMAC_ALT_CTRL_BASE_PTR 0x00c +#define CXD56_UDMAC_DMA_WAITONREQ_STATUS 0x010 +#define CXD56_UDMAC_CHNL_SW_REQUEST 0x014 +#define CXD56_UDMAC_CHNL_USEBURST_SET 0x018 +#define CXD56_UDMAC_CHNL_USEBURST_CLR 0x01c +#define CXD56_UDMAC_CHNL_REQ_MASK_SET 0x020 +#define CXD56_UDMAC_CHNL_REQ_MASK_CLR 0x024 +#define CXD56_UDMAC_CHNL_ENABLE_SET 0x028 +#define CXD56_UDMAC_CHNL_ENABLE_CLR 0x02c +#define CXD56_UDMAC_CHNL_PRI_ALT_SET 0x030 +#define CXD56_UDMAC_CHNL_PRI_ALT_CLR 0x034 +#define CXD56_UDMAC_CHNL_PRIORITY_SET 0x038 +#define CXD56_UDMAC_CHNL_PRIORITY_CLR 0x03c +#define CXD56_UDMAC_ERR_CLR 0x04c +#define CXD56_UDMAC_DMA_DONE 0x050 +#define CXD56_UDMAC_DMA_ERR 0x054 + +#define CXD56_DMA_STATUS (CXD56_DMAC0_BASE + CXD56_UDMAC_DMA_STATUS) +#define CXD56_DMA_CFG (CXD56_DMAC0_BASE + CXD56_UDMAC_DMA_CFG) +#define CXD56_DMA_CTRLBASE (CXD56_DMAC0_BASE + CXD56_UDMAC_CTRL_BASE_PTR) +#define CXD56_DMA_ALTCTRLBASE (CXD56_DMAC0_BASE + CXD56_UDMAC_ALT_CTRL_BASE_PTR) +#define CXD56_DMA_CHWAITSTATUS (CXD56_DMAC0_BASE + CXD56_UDMAC_DMA_WAITONREQ_STATUS) +#define CXD56_DMA_CHSWREQUEST (CXD56_DMAC0_BASE + CXD56_UDMAC_CHNL_SW_REQUEST) +#define CXD56_DMA_CHUSEBURSTS (CXD56_DMAC0_BASE + CXD56_UDMAC_CHNL_USEBURST_SET) +#define CXD56_DMA_CHUSEBURSTC (CXD56_DMAC0_BASE + CXD56_UDMAC_CHNL_USEBURST_CLR) +#define CXD56_DMA_CHREQMASKS (CXD56_DMAC0_BASE + CXD56_UDMAC_CHNL_REQ_MASK_SET) +#define CXD56_DMA_CHREQMASKC (CXD56_DMAC0_BASE + CXD56_UDMAC_CHNL_REQ_MASK_CLR) +#define CXD56_DMA_CHENS (CXD56_DMAC0_BASE + CXD56_UDMAC_CHNL_ENABLE_SET) +#define CXD56_DMA_CHENC (CXD56_DMAC0_BASE + CXD56_UDMAC_CHNL_ENABLE_CLR) +#define CXD56_DMA_CHALTS (CXD56_DMAC0_BASE + CXD56_UDMAC_CHNL_PRI_ALT_SET) +#define CXD56_DMA_CHALTC (CXD56_DMAC0_BASE + CXD56_UDMAC_CHNL_PRI_ALT_CLR) +#define CXD56_DMA_CHPRIS (CXD56_DMAC0_BASE + CXD56_UDMAC_CHNL_PRIORITY_SET) +#define CXD56_DMA_CHPRIC (CXD56_DMAC0_BASE + CXD56_UDMAC_CHNL_PRIORITY_CLR) +#define CXD56_DMA_ERRORC (CXD56_DMAC0_BASE + CXD56_UDMAC_ERR_CLR) +#define CXD56_DMA_DONE (CXD56_DMAC0_BASE + CXD56_UDMAC_DMA_DONE) +#define CXD56_DMA_ERR (CXD56_DMAC0_BASE + CXD56_UDMAC_DMA_ERR) + +#define DMA_CFG_EN 1 + +#define CXD56_DMA_NCHANNELS 32 + +#define DMA_CTRL_SRC_PROT_NON_PRIVILEGED (0 << 18) +#define DMA_CTRL_SRC_PROT_PRIVILEGED (1 << 18) +#define DMA_CTRL_DST_PROT_NON_PRIVILEGED (0 << 21) +#define DMA_CTRL_DST_PROT_PRIVILEGED (1 << 21) + +#define DMA_CTRL_SRC_SIZE_BYTE (0 << 24) +#define DMA_CTRL_SRC_SIZE_HALFWORD (1 << 24) +#define DMA_CTRL_SRC_SIZE_WORD (2 << 24) +#define DMA_CTRL_SRC_SIZE_NONE (3 << 24) + +#define DMA_CTRL_SRC_INC_BYTE (0 << 26) +#define DMA_CTRL_SRC_INC_HALFWORD (1 << 26) +#define DMA_CTRL_SRC_INC_WORD (2 << 26) +#define DMA_CTRL_SRC_INC_NONE (3 << 26) + +#define DMA_CTRL_DST_SIZE_BYTE (0 << 28) +#define DMA_CTRL_DST_SIZE_HALFWORD (1 << 28) +#define DMA_CTRL_DST_SIZE_WORD (2 << 28) +#define DMA_CTRL_DST_SIZE_NONE (3 << 28) + +#define DMA_CTRL_DST_INC_BYTE (0 << 30) +#define DMA_CTRL_DST_INC_HALFWORD (1 << 30) +#define DMA_CTRL_DST_INC_WORD (2 << 30) +#define DMA_CTRL_DST_INC_NONE (3 << 30) + +#define DMA_CTRL_R_POWER_1 (0 << 14) +#define DMA_CTRL_R_POWER_2 (1 << 14) +#define DMA_CTRL_R_POWER_4 (2 << 14) +#define DMA_CTRL_R_POWER_8 (3 << 14) +#define DMA_CTRL_R_POWER_16 (4 << 14) +#define DMA_CTRL_R_POWER_32 (5 << 14) +#define DMA_CTRL_R_POWER_64 (6 << 14) +#define DMA_CTRL_R_POWER_128 (7 << 14) +#define DMA_CTRL_R_POWER_256 (8 << 14) +#define DMA_CTRL_R_POWER_512 (9 << 14) +#define DMA_CTRL_R_POWER_1024 (10 << 14) + +#define DMA_CTRL_NEXT_USEBURST (1 << 3) + +#define DMA_CTRL_CYCLE_CTRL_INVALID 0x0 /* Invalid cycle type */ +#define DMA_CTRL_CYCLE_CTRL_BASIC 0x1 /* Basic cycle type */ +#define DMA_CTRL_CYCLE_CTRL_AUTO 0x2 /* Auto cycle type */ +#define DMA_CTRL_CYCLE_CTRL_PINGPONG 0x3 /* PingPong cycle type */ +#define DMA_CTRL_CYCLE_CTRL_MEM_SCATTER_GATHER 0x4 /* Memory scatter gather cycle type */ +#define DMA_CTRL_CYCLE_CTRL_MEM_SCATTER_GATHER_ALT 0x5 /* Memory scatter gather using alternate structure */ +#define DMA_CTRL_CYCLE_CTRL_PER_SCATTER_GATHER 0x6 /* Peripheral scatter gather cycle type */ +#define DMA_CTRL_CYCLE_CTRL_PER_SCATTER_GATHER_ALT 0x7 /* Peripheral scatter gather cycle type using alternate structure */ + +#define DMA_CTRL_N_MINUS_1(n) ((n) << 4) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct dma_descriptor_s { + volatile void * volatile srcend; + volatile void * volatile dstend; + volatile uint32_t ctrl; + volatile uint32_t user; +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_CXD56XX_CHIP_CXD56_UDMAC_H */ diff --git a/configs/spresense/include/board.h b/configs/spresense/include/board.h index 6a13990566..806905cee9 100644 --- a/configs/spresense/include/board.h +++ b/configs/spresense/include/board.h @@ -117,6 +117,11 @@ /* LED definitions *********************************************************/ +#define GPIO_LED1 (PIN_I2S1_BCK) +#define GPIO_LED2 (PIN_I2S1_LRCK) +#define GPIO_LED3 (PIN_I2S1_DATA_IN) +#define GPIO_LED4 (PIN_I2S1_DATA_OUT) + #define BOARD_LED1 (0) #define BOARD_LED2 (1) #define BOARD_LED3 (2) @@ -130,27 +135,16 @@ #define BOARD_LED3_BIT (1 << BOARD_LED3) #define BOARD_LED4_BIT (1 << BOARD_LED4) -/* LED pattern for use with board_autoled_on() and board_autoled_off() - * ON OFF - * LED1 LED2 LED1 LED2 - * PTN0: OFF OFF - - - * PTN1: ON OFF - - - * PTN2: - ON - OFF - * - */ +/* LED pattern for use with board_autoled_on() and board_autoled_off() */ -#define LED_AUTOLED_PTN0 (0) -#define LED_AUTOLED_PTN1 (1) -#define LED_AUTOLED_PTN2 (2) - -#define LED_STARTED (LED_AUTOLED_PTN0) -#define LED_HEAPALLOCATE (LED_AUTOLED_PTN1) -#define LED_IRQSENABLED (LED_AUTOLED_PTN1) -#define LED_STACKCREATED (LED_AUTOLED_PTN1) -#define LED_INIRQ (LED_AUTOLED_PTN2) -#define LED_SIGNAL (LED_AUTOLED_PTN2) -#define LED_ASSERTION (LED_AUTOLED_PTN2) -#define LED_PANIC (LED_AUTOLED_PTN2) +#define LED_STARTED (BOARD_LED1_BIT) +#define LED_HEAPALLOCATE (BOARD_LED2_BIT) +#define LED_IRQSENABLED (BOARD_LED1_BIT | BOARD_LED2_BIT) +#define LED_STACKCREATED (BOARD_LED3_BIT) +#define LED_INIRQ (BOARD_LED1_BIT | BOARD_LED3_BIT) +#define LED_SIGNAL (BOARD_LED2_BIT | BOARD_LED3_BIT) +#define LED_ASSERTION (BOARD_LED1_BIT | BOARD_LED2_BIT | BOARD_LED3_BIT) +#define LED_PANIC (BOARD_LED4_BIT) /* Buttons definitions *****************************************************/ diff --git a/configs/spresense/include/cxd56_i2cdev.h b/configs/spresense/include/cxd56_i2cdev.h new file mode 100644 index 0000000000..7c3e13e457 --- /dev/null +++ b/configs/spresense/include/cxd56_i2cdev.h @@ -0,0 +1,86 @@ +/**************************************************************************** + * configs/spresense/include/cxd56_i2cdev.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + * + ****************************************************************************/ + +#ifndef __BOARD_COMMON_INCLUDE_CXD56_I2CDEV_H +#define __BOARD_COMMON_INCLUDE_CXD56_I2CDEV_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: board_i2cdev_initialize + * + * Description: + * Initialize i2c driver and register the /dev/i2c device. + * + ****************************************************************************/ + +#ifdef CONFIG_SYSTEM_I2CTOOL +int board_i2cdev_initialize(int bus); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __BOARD_COMMON_INCLUDE_CXD56_I2CDEV_H */ diff --git a/configs/spresense/src/cxd56_bringup.c b/configs/spresense/src/cxd56_bringup.c index 143eeffd70..b0776bd1cc 100644 --- a/configs/spresense/src/cxd56_bringup.c +++ b/configs/spresense/src/cxd56_bringup.c @@ -53,6 +53,10 @@ #include #endif +#ifdef CONFIG_USERLED_LOWER +#include +#endif + #include #include "chip.h" diff --git a/configs/spresense/src/cxd56_i2cdev.c b/configs/spresense/src/cxd56_i2cdev.c new file mode 100644 index 0000000000..33cd2d4517 --- /dev/null +++ b/configs/spresense/src/cxd56_i2cdev.c @@ -0,0 +1,83 @@ +/**************************************************************************** + * configs/spresense/src/cxd56_i2cdev.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "cxd56_i2c.h" + +#if defined(CONFIG_CXD56_I2C) && defined(CONFIG_I2C_DRIVER) + +/**************************************************************************** + * Name: board_i2cdev_initialize + * + * Description: + * Initialize and register i2c driver for the specified i2c port + * + ****************************************************************************/ + +int board_i2cdev_initialize(int port) +{ + int ret; + FAR struct i2c_master_s *i2c; + + _info("Initializing /dev/i2c%d..\n", port); + + /* Initialize i2c deivce */ + + i2c = cxd56_i2cbus_initialize(port); + if (!i2c) + { + _err("ERROR: Failed to initialize i2c%d.\n", port); + return -ENODEV; + } + + ret = i2c_register(i2c, port); + if (ret < 0) + { + _err("ERROR: Failed to register i2c%d: %d\n", port, ret); + } + + return ret; +} + +#endif diff --git a/configs/spresense/src/cxd56_leds.c b/configs/spresense/src/cxd56_leds.c index 0c3bcf001d..6140a3cd4e 100644 --- a/configs/spresense/src/cxd56_leds.c +++ b/configs/spresense/src/cxd56_leds.c @@ -1,6 +1,8 @@ /**************************************************************************** * configs/spresense/src/cxd56_leds.c * + * Copyright (C) 2011-2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt * Copyright 2018 Sony Semiconductor Solutions Corporation * * Redistribution and use in source and binary forms, with or without @@ -13,7 +15,10 @@ * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. - * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * Neither the name of Sony Semiconductor Solutions Corporation nor * the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written * permission. @@ -46,8 +51,81 @@ #include #include +#include "cxd56_gpio.h" +#include "cxd56_pinconfig.h" + #ifdef CONFIG_ARCH_LEDS +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const unsigned int g_ledbits[8] = +{ + LED_STARTED, + LED_HEAPALLOCATE, + LED_IRQSENABLED, + LED_STACKCREATED, + LED_INIRQ, + LED_SIGNAL, + LED_ASSERTION, + LED_PANIC +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static inline void led_clrbits(unsigned int clrbits) +{ + if ((clrbits & BOARD_LED1_BIT) != 0) + { + cxd56_gpio_write(GPIO_LED1, false); + } + + if ((clrbits & BOARD_LED2_BIT) != 0) + { + cxd56_gpio_write(GPIO_LED2, false); + } + + if ((clrbits & BOARD_LED3_BIT) != 0) + { + cxd56_gpio_write(GPIO_LED3, false); + } + + if ((clrbits & BOARD_LED4_BIT) != 0) + { + cxd56_gpio_write(GPIO_LED4, false); + } +} + +static inline void led_setbits(unsigned int setbits) +{ + if ((setbits & BOARD_LED1_BIT) != 0) + { + cxd56_gpio_write(GPIO_LED1, true); + } + + if ((setbits & BOARD_LED2_BIT) != 0) + { + cxd56_gpio_write(GPIO_LED2, true); + } + + if ((setbits & BOARD_LED3_BIT) != 0) + { + cxd56_gpio_write(GPIO_LED3, true); + } + + if ((setbits & BOARD_LED4_BIT) != 0) + { + cxd56_gpio_write(GPIO_LED4, true); + } +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -58,6 +136,10 @@ void board_autoled_initialize(void) { + cxd56_gpio_config(GPIO_LED1,false); + cxd56_gpio_config(GPIO_LED2,false); + cxd56_gpio_config(GPIO_LED3,false); + cxd56_gpio_config(GPIO_LED4,false); } /**************************************************************************** @@ -66,6 +148,8 @@ void board_autoled_initialize(void) void board_autoled_on(int led) { + led_clrbits(BOARD_LED1_BIT | BOARD_LED2_BIT | BOARD_LED3_BIT | BOARD_LED4_BIT); + led_setbits(g_ledbits[led]); } /**************************************************************************** @@ -74,6 +158,7 @@ void board_autoled_on(int led) void board_autoled_off(int led) { + led_clrbits(g_ledbits[led]); } #endif /* CONFIG_ARCH_LEDS */ diff --git a/configs/spresense/src/cxd56_userleds.c b/configs/spresense/src/cxd56_userleds.c index 60bb3d2250..fa79af9f06 100644 --- a/configs/spresense/src/cxd56_userleds.c +++ b/configs/spresense/src/cxd56_userleds.c @@ -58,26 +58,6 @@ * Pre-processor Definitions ****************************************************************************/ -/* Check if the following are defined in the board.h */ - -#ifndef BOARD_LED1_BIT -#error "BOARD_LED1_BIT must be defined in board.h !!" -#endif -#ifndef BOARD_LED2_BIT -#error "BOARD_LED2_BIT must be defined in board.h !!" -#endif -#ifndef BOARD_LED3_BIT -#error "BOARD_LED3_BIT must be defined in board.h !!" -#endif -#ifndef BOARD_LED4_BIT -#error "BOARD_LED4_BIT must be defined in board.h !!" -#endif - -#define GPIO_LED1 (PIN_I2S1_BCK) -#define GPIO_LED2 (PIN_I2S1_LRCK) -#define GPIO_LED3 (PIN_I2S1_DATA_IN) -#define GPIO_LED4 (PIN_I2S1_DATA_OUT) - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -88,10 +68,10 @@ void board_userled_initialize(void) { - cxd56_gpio_write(GPIO_LED1, false); - cxd56_gpio_write(GPIO_LED2, false); - cxd56_gpio_write(GPIO_LED3, false); - cxd56_gpio_write(GPIO_LED4, false); + cxd56_gpio_config(GPIO_LED1, false); + cxd56_gpio_config(GPIO_LED2, false); + cxd56_gpio_config(GPIO_LED3, false); + cxd56_gpio_config(GPIO_LED4, false); } /**************************************************************************** @@ -100,7 +80,7 @@ void board_userled_initialize(void) void board_userled(int led, bool ledon) { - board_gpio_write(ledcfg, ledon); + cxd56_gpio_write(led, ledon); } /****************************************************************************