arch/nrf53: add QSPI support
This commit is contained in:
parent
5ff6c8b403
commit
8b89730e61
@ -29,6 +29,7 @@ config NRF53_APPCORE
|
|||||||
select NRF53_HAVE_I2C123
|
select NRF53_HAVE_I2C123
|
||||||
select NRF53_HAVE_SPI1234
|
select NRF53_HAVE_SPI1234
|
||||||
select NRF53_HAVE_HFCLK192M
|
select NRF53_HAVE_HFCLK192M
|
||||||
|
select NRF53_HAVE_QSPI
|
||||||
|
|
||||||
config NRF53_NETCORE
|
config NRF53_NETCORE
|
||||||
bool
|
bool
|
||||||
@ -103,6 +104,10 @@ config NRF53_HAVE_HFCLK192M
|
|||||||
bool
|
bool
|
||||||
default n
|
default n
|
||||||
|
|
||||||
|
config NRF53_HAVE_QSPI
|
||||||
|
bool
|
||||||
|
default n
|
||||||
|
|
||||||
# Peripheral Selection
|
# Peripheral Selection
|
||||||
|
|
||||||
config NRF53_I2C_MASTER
|
config NRF53_I2C_MASTER
|
||||||
@ -212,6 +217,11 @@ config NRF53_UART1
|
|||||||
select UART1_SERIALDRIVER
|
select UART1_SERIALDRIVER
|
||||||
select NRF53_UART
|
select NRF53_UART
|
||||||
|
|
||||||
|
config NRF53_QSPI
|
||||||
|
bool "QSPI"
|
||||||
|
default n
|
||||||
|
depends on NRF53_HAVE_QSPI
|
||||||
|
|
||||||
config NRF53_TIMER0
|
config NRF53_TIMER0
|
||||||
bool "TIMER0"
|
bool "TIMER0"
|
||||||
select NRF53_TIMER
|
select NRF53_TIMER
|
||||||
@ -325,6 +335,8 @@ config NRF53_HFCLK192M_48
|
|||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
|
endif # NRF53_USE_HFCLK192M
|
||||||
|
|
||||||
config NRF53_OSCILLATOR_LFXO
|
config NRF53_OSCILLATOR_LFXO
|
||||||
bool "Configure LFXO oscillator"
|
bool "Configure LFXO oscillator"
|
||||||
default y if NRF53_LFCLK_XTAL
|
default y if NRF53_LFCLK_XTAL
|
||||||
@ -610,6 +622,21 @@ config NRF53_I2C_MASTER_COPY_BUF_SIZE
|
|||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
|
menu "QSPI Configuration"
|
||||||
|
|
||||||
|
if NRF53_QSPI
|
||||||
|
|
||||||
|
config NRF53_QSPI_RXDELAY
|
||||||
|
int "QSPI RX delay"
|
||||||
|
default 2
|
||||||
|
range 0 7
|
||||||
|
---help---
|
||||||
|
The input serial data sampling delay.
|
||||||
|
|
||||||
|
endif # NRF53_QSPI
|
||||||
|
|
||||||
|
endmenu # QSPI Configuration
|
||||||
|
|
||||||
menuconfig NRF53_SOFTDEVICE_CONTROLLER
|
menuconfig NRF53_SOFTDEVICE_CONTROLLER
|
||||||
bool "SoftDevice Controller"
|
bool "SoftDevice Controller"
|
||||||
depends on ALLOW_BSDNORDIC_COMPONENTS
|
depends on ALLOW_BSDNORDIC_COMPONENTS
|
||||||
|
@ -95,6 +95,10 @@ ifeq ($(CONFIG_USBDEV),y)
|
|||||||
CHIP_CSRCS += nrf53_usbd.c
|
CHIP_CSRCS += nrf53_usbd.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_NRF53_QSPI),y)
|
||||||
|
CHIP_CSRCS += nrf53_qspi.c
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_NRF53_SOFTDEVICE_CONTROLLER),y)
|
ifeq ($(CONFIG_NRF53_SOFTDEVICE_CONTROLLER),y)
|
||||||
|
|
||||||
NRFXLIB_UNPACK := sdk-nrfxlib
|
NRFXLIB_UNPACK := sdk-nrfxlib
|
||||||
|
224
arch/arm/src/nrf53/hardware/nrf53_qspi.h
Normal file
224
arch/arm/src/nrf53/hardware/nrf53_qspi.h
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* arch/arm/src/nrf53/hardware/nrf53_qspi.h
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __ARCH_ARM_SRC_NRF53_HARDWARE_NRF53_QSPI_H
|
||||||
|
#define __ARCH_ARM_SRC_NRF53_HARDWARE_NRF53_QSPI_H
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include "hardware/nrf53_memorymap.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Register offsets *********************************************************/
|
||||||
|
|
||||||
|
#define NRF53_QSPI_TASKS_ACTIVATE_OFFSET 0x0000 /* Activate QSPI interface */
|
||||||
|
#define NRF53_QSPI_TASKS_READSTART_OFFSET 0x0004 /* Start transfer from external flash memory to internal RAM */
|
||||||
|
#define NRF53_QSPI_TASKS_WRITESTART_OFFSET 0x0008 /* Start transfer from internal RAM to external flash memory */
|
||||||
|
#define NRF53_QSPI_TASKS_ERASESTART_OFFSET 0x000c /* Start external flash memory erase operation */
|
||||||
|
#define NRF53_QSPI_TASKS_DEACTIVATE_OFFSET 0x0010 /* Deactivate QSPI interface */
|
||||||
|
#define NRF53_QSPI_EVENTS_READY_OFFSET 0x0100 /* QSPI peripheral is ready */
|
||||||
|
#define NRF53_QSPI_INTEN_OFFSET 0x0300 /* Enable or disable interrupt */
|
||||||
|
#define NRF53_QSPI_INTENSET_OFFSET 0x0304 /* Enable interrupt */
|
||||||
|
#define NRF53_QSPI_INTENCLR_OFFSET 0x0308 /* Disable interrupt */
|
||||||
|
#define NRF53_QSPI_ENABLE_OFFSET 0x0500 /* Enable QSPI peripheral */
|
||||||
|
#define NRF53_QSPI_READ_SRC_OFFSET 0x0504 /* Flash memory source address */
|
||||||
|
#define NRF53_QSPI_READ_DST_OFFSET 0x0508 /* RAM destination address */
|
||||||
|
#define NRF53_QSPI_READ_CNT_OFFSET 0x050c /* Read transfer length */
|
||||||
|
#define NRF53_QSPI_WRITE_SRC_OFFSET 0x0510 /* Flash destination address */
|
||||||
|
#define NRF53_QSPI_WRITE_DST_OFFSET 0x0514 /* RAM source address */
|
||||||
|
#define NRF53_QSPI_WRITE_CNT_OFFSET 0x0518 /* Write transfer length */
|
||||||
|
#define NRF53_QSPI_ERASE_PTR_OFFSET 0x051c /* Start address of flash block to be erased */
|
||||||
|
#define NRF53_QSPI_ERASE_LEN_OFFSET 0x0520 /* Size of block to be erased */
|
||||||
|
#define NRF53_QSPI_PSEL_SCK_OFFSET 0x0524 /* Pin select for serial clock SCK */
|
||||||
|
#define NRF53_QSPI_PSEL_CSN_OFFSET 0x0528 /* Pin select for chip select signal CSN */
|
||||||
|
#define NRF53_QSPI_PSEL_IO0_OFFSET 0x0530 /* Pin select for serial data MOSI/IO0 */
|
||||||
|
#define NRF53_QSPI_PSEL_IO1_OFFSET 0x0534 /* Pin select for serial data MISO/IO1 */
|
||||||
|
#define NRF53_QSPI_PSEL_IO2_OFFSET 0x0538 /* Pin select for serial data IO2 */
|
||||||
|
#define NRF53_QSPI_PSEL_IO3_OFFSET 0x053c /* Pin select for serial data IO3 */
|
||||||
|
#define NRF53_QSPI_XIPOFFSET_OFFSET 0x0540 /* Address offset into the external memory for XIP */
|
||||||
|
#define NRF53_QSPI_IFCONFIG0_OFFSET 0x0544 /* Interface configuration */
|
||||||
|
#define NRF53_QSPI_XIPEN_OFFSET 0x054c /* Enable Execute in Place operation. */
|
||||||
|
#define NRF53_QSPI_XIPENC_KEY0_OFFSET 0x0560 /* Bits 31:0 of XIP AES KEY */
|
||||||
|
#define NRF53_QSPI_XIPENC_KEY1_OFFSET 0x0564 /* Bits 63:32 of XIP AES KEY */
|
||||||
|
#define NRF53_QSPI_XIPENC_KEY2_OFFSET 0x0568 /* Bits 95:64 of XIP AES KEY */
|
||||||
|
#define NRF53_QSPI_XIPENC_KEY3_OFFSET 0x056c /* Bits 95:64 of XIP AES KEY */
|
||||||
|
#define NRF53_QSPI_XIPENC_NONCE0_OFFSET 0x0570 /* Bits 127:96 of XIP AES KEY */
|
||||||
|
#define NRF53_QSPI_XIPENC_NONCE1_OFFSET 0x0574 /* Bits 31:0 of XIP NONCE */
|
||||||
|
#define NRF53_QSPI_XIPENC_NONCE2_OFFSET 0x0578 /* Bits 63:32 of XIP NONCE */
|
||||||
|
#define NRF53_QSPI_XIPENC_ENABLE_OFFSET 0x057c /* Enable stream cipher for XIP */
|
||||||
|
#define NRF53_QSPI_DMAENC_KEY0_OFFSET 0x0580 /* Bits 31:0 of DMA AES KEY */
|
||||||
|
#define NRF53_QSPI_DMAENC_KEY1_OFFSET 0x0584 /* Bits 63:32 of DMA AES KEY */
|
||||||
|
#define NRF53_QSPI_DMAENC_KEY2_OFFSET 0x0588 /* Bits 95:64 of DMA AES KEY */
|
||||||
|
#define NRF53_QSPI_DMAENC_KEY3_OFFSET 0x058c /* Bits 127:96 of DMA AES KEY */
|
||||||
|
#define NRF53_QSPI_DMAENC_NONCE0_OFFSET 0x0590 /* Bits 31:0 of DMA NONCE */
|
||||||
|
#define NRF53_QSPI_DMAENC_NONCE1_OFFSET 0x0594 /* Bits 63:32 of DMA NONCE */
|
||||||
|
#define NRF53_QSPI_DMAENC_NONCE2_OFFSET 0x0598 /* Bits 95:64 of DMA NONCE */
|
||||||
|
#define NRF53_QSPI_DMAENC_ENABLE_OFFSET 0x059c /* Enable stream cipher for EasyDMA */
|
||||||
|
#define NRF53_QSPI_IFCONFIG1_OFFSET 0x0600 /* Interface configuration */
|
||||||
|
#define NRF53_QSPI_STATUS_OFFSET 0x0604 /* Status register */
|
||||||
|
#define NRF53_QSPI_DPMDUR_OFFSET 0x0614 /* DPM duration */
|
||||||
|
#define NRF53_QSPI_ADDRCONF_OFFSET 0x0624 /* Extended address configuration. */
|
||||||
|
#define NRF53_QSPI_CINSTRCONF_OFFSET 0x0634 /* Custom instruction configuration register. */
|
||||||
|
#define NRF53_QSPI_CINSTRDAT0_OFFSET 0x0638 /* Custom instruction data register 0. */
|
||||||
|
#define NRF53_QSPI_CINSTRDAT1_OFFSET 0x063c /* Custom instruction data register 1. */
|
||||||
|
#define NRF53_QSPI_IFTIMING_OFFSET 0x0640 /* SPI interface timing. */
|
||||||
|
|
||||||
|
/* Register Bitfield Definitions ********************************************/
|
||||||
|
|
||||||
|
/* INTEN/INTENSET/INTENCLR */
|
||||||
|
|
||||||
|
#define QSPI_INT_READY (1 << 0)
|
||||||
|
|
||||||
|
/* ENABLE */
|
||||||
|
|
||||||
|
#define QSPI_ENABLE_EN (1)
|
||||||
|
#define QSPI_ENABLE_DIS (0)
|
||||||
|
|
||||||
|
/* ERASE.LEN */
|
||||||
|
|
||||||
|
#define QSPI_ERASE_SECTOR (0)
|
||||||
|
#define QSPI_ERASE_PAGE (1)
|
||||||
|
#define QSPI_ERASE_ALL (2)
|
||||||
|
|
||||||
|
/* PSEL */
|
||||||
|
|
||||||
|
#define QSPI_PSEL_PIN_SHIFT (0)
|
||||||
|
#define QSPI_PSEL_PORT_SHIFT (5)
|
||||||
|
#define QSPI_PSEL_CONNECT (1 << 31)
|
||||||
|
|
||||||
|
/* IFCONFIG0 */
|
||||||
|
|
||||||
|
#define QSPI_IFCONFIG0_READOC_SHIFT (0)
|
||||||
|
#define QSPI_IFCONFIG0_READOC_MASK (0x7 << QSPI_IFCONFIG0_READOC_SHIFT)
|
||||||
|
# define QSPI_IFCONFIG0_READOC_FASTREAD (0 << QSPI_IFCONFIG0_READOC_SHIFT)
|
||||||
|
# define QSPI_IFCONFIG0_READOC_READ2O (1 << QSPI_IFCONFIG0_READOC_SHIFT)
|
||||||
|
# define QSPI_IFCONFIG0_READOC_READ2IO (2 << QSPI_IFCONFIG0_READOC_SHIFT)
|
||||||
|
# define QSPI_IFCONFIG0_READOC_READ4O (3 << QSPI_IFCONFIG0_READOC_SHIFT)
|
||||||
|
# define QSPI_IFCONFIG0_READOC_READ4IO (4 << QSPI_IFCONFIG0_READOC_SHIFT)
|
||||||
|
#define QSPI_IFCONFIG0_WRITEOC_SHIFT (3)
|
||||||
|
#define QSPI_IFCONFIG0_WRITEOC_MASK (0x7 << QSPI_IFCONFIG0_WRITEOC_SHIFT)
|
||||||
|
# define QSPI_IFCONFIG0_WRITEOC_PP (0 << QSPI_IFCONFIG0_WRITEOC_SHIFT)
|
||||||
|
# define QSPI_IFCONFIG0_WRITEOC_PP2O (1 << QSPI_IFCONFIG0_WRITEOC_SHIFT)
|
||||||
|
# define QSPI_IFCONFIG0_WRITEOC_PP4O (2 << QSPI_IFCONFIG0_WRITEOC_SHIFT)
|
||||||
|
# define QSPI_IFCONFIG0_WRITEOC_PP4IO (3 << QSPI_IFCONFIG0_WRITEOC_SHIFT)
|
||||||
|
#define QSPI_IFCONFIG0_ADDRMODE_24 (0 << 6)
|
||||||
|
#define QSPI_IFCONFIG0_ADDRMODE_32 (1 << 6)
|
||||||
|
#define QSPI_IFCONFIG0_DPMENABLE (1 << 7)
|
||||||
|
#define QSPI_IFCONFIG0_PPSIZE_512 (1 << 12)
|
||||||
|
|
||||||
|
/* IFCONFIG1 */
|
||||||
|
|
||||||
|
#define QSPI_IFCONFIG1_SCKDELAY_SHIFT (0)
|
||||||
|
#define QSPI_IFCONFIG1_SCKDELAY_MASK (0xff << QSPI_IFCONFIG1_SCKDELAY_SHIFT)
|
||||||
|
#define QSPI_IFCONFIG1_DPMEN_EXIT (0 << 24)
|
||||||
|
#define QSPI_IFCONFIG1_DPMEN_ENTER (1 << 24)
|
||||||
|
#define QSPI_IFCONFIG1_SPIMODE_0 (0 << 25)
|
||||||
|
#define QSPI_IFCONFIG1_SPIMODE_3 (1 << 25)
|
||||||
|
#define QSPI_IFCONFIG1_SCKFREQ_SHIFT (28)
|
||||||
|
#define QSPI_IFCONFIG1_SCKFREQ_MASK (0xf << QSPI_IFCONFIG1_SCKFREQ_SHIFT)
|
||||||
|
|
||||||
|
/* STATUS */
|
||||||
|
|
||||||
|
#define QSPI_STATUS_DPM (1 << 2)
|
||||||
|
#define QSPI_STATUS_READY (1 << 3)
|
||||||
|
#define QSPI_STATUS_SREG_SHIFT (24)
|
||||||
|
#define QSPI_STATUS_SREG_MASK (0xff << QSPI_STATUS_SREG_SHIFT)
|
||||||
|
|
||||||
|
/* DPMDUR */
|
||||||
|
|
||||||
|
#define QSPI_DPMDUR_ENTER_SHIFT (0)
|
||||||
|
#define QSPI_DPMDUR_ENTER_MASK (0xffff << QSPI_DPMDUR_ENTER_SHIFT)
|
||||||
|
#define QSPI_DPMDUR_EXIT_SHIFT (16)
|
||||||
|
#define QSPI_DPMDUR_EXIT_MASK (0xffff << QSPI_DPMDUR_EXIT_SHIFT)
|
||||||
|
|
||||||
|
/* ADDRCONF */
|
||||||
|
|
||||||
|
#define QSPI_ADDRCONF_OPCODE_SHIFT (0)
|
||||||
|
#define QSPI_ADDRCONF_OPCODE_MASK (0xff << QSPI_ADDRCONF_OPCODE_SHIFT)
|
||||||
|
#define QSPI_ADDRCONF_BYTE0_SHIFT (8)
|
||||||
|
#define QSPI_ADDRCONF_BYTE0_MASK (0xff << QSPI_ADDRCONF_BYTE0_SHIFT)
|
||||||
|
#define QSPI_ADDRCONF_BYTE1_SHIFT (16)
|
||||||
|
#define QSPI_ADDRCONF_BYTE1_MASK (0xff << QSPI_ADDRCONF_BYTE1_SHIFT)
|
||||||
|
#define QSPI_ADDRCONF_MODE_SHIFT (24)
|
||||||
|
#define QSPI_ADDRCONF_MODE_MASK (0x3 << QSPI_ADDRCONF_MODE_SHIFT)
|
||||||
|
# define QSPI_ADDRCONF_MODE_NOINSTR (0 << QSPI_ADDRCONF_MODE_SHIFT)
|
||||||
|
# define QSPI_ADDRCONF_MODE_OPCODE (1 << QSPI_ADDRCONF_MODE_SHIFT)
|
||||||
|
# define QSPI_ADDRCONF_MODE_OPBYTE0 (2 << QSPI_ADDRCONF_MODE_SHIFT)
|
||||||
|
# define QSPI_ADDRCONF_MODE_ALL (3 << QSPI_ADDRCONF_MODE_SHIFT)
|
||||||
|
#define QSPI_ADDRCONF_WIPWAIT (1 << 26)
|
||||||
|
#define QSPI_ADDRCONF_WREN (1 << 27)
|
||||||
|
|
||||||
|
/* CINSTRCONF */
|
||||||
|
|
||||||
|
#define QSPI_CINSTRCONF_OPCODE_SHIFT (0)
|
||||||
|
#define QSPI_CINSTRCONF_OPCODE_MASK (0xff << QSPI_CINSTRCONF_OPCODE_SHIFT)
|
||||||
|
#define QSPI_CINSTRCONF_LENGTH_SHIFT (8)
|
||||||
|
#define QSPI_CINSTRCONF_LENGTH_MASK (0xf << QSPI_CINSTRCONF_LENGTH_SHIFT)
|
||||||
|
#define QSPI_CINSTRCONF_LENGTH(n) ((n) << QSPI_CINSTRCONF_LENGTH_SHIFT)
|
||||||
|
#define QSPI_CINSTRCONF_LIO2 (1 << 12)
|
||||||
|
#define QSPI_CINSTRCONF_LIO3 (1 << 13)
|
||||||
|
#define QSPI_CINSTRCONF_WIPWAIT (1 << 14)
|
||||||
|
#define QSPI_CINSTRCONF_WREN (1 << 15)
|
||||||
|
#define QSPI_CINSTRCONF_LFEN (1 << 16)
|
||||||
|
#define QSPI_CINSTRCONF_LFSTOP_STOP (1 << 17)
|
||||||
|
|
||||||
|
/* CINSTRDAT0 */
|
||||||
|
|
||||||
|
#define QSPI_CINSTRDAT0_BYTE0_SHIFT (0)
|
||||||
|
#define QSPI_CINSTRDAT0_BYTE0_MASK (0xff << QSPI_CINSTRDAT0_BYTE0_SHIFT)
|
||||||
|
#define QSPI_CINSTRDAT0_BYTE0(n) ((n) << QSPI_CINSTRDAT0_BYTE0_SHIFT)
|
||||||
|
#define QSPI_CINSTRDAT0_BYTE1_SHIFT (8)
|
||||||
|
#define QSPI_CINSTRDAT0_BYTE1_MASK (0xff << QSPI_CINSTRDAT0_BYTE1_SHIFT)
|
||||||
|
#define QSPI_CINSTRDAT0_BYTE1(n) ((n) << QSPI_CINSTRDAT0_BYTE1_SHIFT)
|
||||||
|
#define QSPI_CINSTRDAT0_BYTE2_SHIFT (16)
|
||||||
|
#define QSPI_CINSTRDAT0_BYTE2_MASK (0xff << QSPI_CINSTRDAT0_BYTE2_SHIFT)
|
||||||
|
#define QSPI_CINSTRDAT0_BYTE2(n) ((n) << QSPI_CINSTRDAT0_BYTE2_SHIFT)
|
||||||
|
#define QSPI_CINSTRDAT0_BYTE3_SHIFT (24)
|
||||||
|
#define QSPI_CINSTRDAT0_BYTE3_MASK (0xff << QSPI_CINSTRDAT0_BYTE3_SHIFT)
|
||||||
|
#define QSPI_CINSTRDAT0_BYTE3(n) ((n) << QSPI_CINSTRDAT0_BYTE3_SHIFT)
|
||||||
|
|
||||||
|
/* CINSTRDAT1 */
|
||||||
|
|
||||||
|
#define QSPI_CINSTRDAT1_BYTE0_SHIFT (0)
|
||||||
|
#define QSPI_CINSTRDAT1_BYTE0_MASK (0xff << QSPI_CINSTRDAT1_BYTE0_SHIFT)
|
||||||
|
#define QSPI_CINSTRDAT1_BYTE0(n) ((n) << QSPI_CINSTRDAT1_BYTE0_SHIFT)
|
||||||
|
#define QSPI_CINSTRDAT1_BYTE1_SHIFT (8)
|
||||||
|
#define QSPI_CINSTRDAT1_BYTE1_MASK (0xff << QSPI_CINSTRDAT1_BYTE1_SHIFT)
|
||||||
|
#define QSPI_CINSTRDAT1_BYTE1(n) ((n) << QSPI_CINSTRDAT1_BYTE1_SHIFT)
|
||||||
|
#define QSPI_CINSTRDAT1_BYTE2_SHIFT (16)
|
||||||
|
#define QSPI_CINSTRDAT1_BYTE2_MASK (0xff << QSPI_CINSTRDAT1_BYTE2_SHIFT)
|
||||||
|
#define QSPI_CINSTRDAT1_BYTE2(n) ((n) << QSPI_CINSTRDAT1_BYTE2_SHIFT)
|
||||||
|
#define QSPI_CINSTRDAT1_BYTE3_SHIFT (24)
|
||||||
|
#define QSPI_CINSTRDAT1_BYTE3_MASK (0xff << QSPI_CINSTRDAT1_BYTE3_SHIFT)
|
||||||
|
#define QSPI_CINSTRDAT1_BYTE3(n) ((n) << QSPI_CINSTRDAT1_BYTE3_SHIFT)
|
||||||
|
|
||||||
|
/* IFTIMING */
|
||||||
|
|
||||||
|
#define QSPI_IFTIMING_RXDELAY_SHIFT (8)
|
||||||
|
#define QSPI_IFTIMING_RXDELAY_MASK (0xff << QSPI_IFTIMING_RXDELAY_SHIFT)
|
||||||
|
#define QSPI_IFTIMING_RXDELAY(n) ((n) << QSPI_IFTIMING_RXDELAY_SHIFT)
|
||||||
|
|
||||||
|
#endif /* __ARCH_ARM_SRC_NRF53_HARDWARE_NRF53_QSPI_H */
|
@ -111,11 +111,11 @@ void nrf53_clockconfig(void)
|
|||||||
/* Initialize HFCLK192M */
|
/* Initialize HFCLK192M */
|
||||||
|
|
||||||
#if defined(CONFIG_NRF53_HFCLK192M_192)
|
#if defined(CONFIG_NRF53_HFCLK192M_192)
|
||||||
putreg32(NRF53_CLOCK_HFCLK192MSRC, CLOCK_HFCLK192MSRC_DIV1);
|
putreg32(CLOCK_HFCLK192MSRC_DIV1, NRF53_CLOCK_HFCLK192MSRC);
|
||||||
#elif defined(CONFIG_NRF53_HFCLK192M_96)
|
#elif defined(CONFIG_NRF53_HFCLK192M_96)
|
||||||
putreg32(NRF53_CLOCK_HFCLK192MSRC, CLOCK_HFCLK192MSRC_DIV2);
|
putreg32(CLOCK_HFCLK192MSRC_DIV2, NRF53_CLOCK_HFCLK192MSRC);
|
||||||
#elif defined(CONFIG_NRF53_HFCLK192M_48)
|
#elif defined(CONFIG_NRF53_HFCLK192M_48)
|
||||||
putreg32(NRF53_CLOCK_HFCLK192MSRC, CLOCK_HFCLK192MSRC_DIV4);
|
putreg32(CLOCK_HFCLK192MSRC_DIV4, NRF53_CLOCK_HFCLK192MSRC);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Trigger HFCLK192M start */
|
/* Trigger HFCLK192M start */
|
||||||
|
942
arch/arm/src/nrf53/nrf53_qspi.c
Normal file
942
arch/arm/src/nrf53/nrf53_qspi.c
Normal file
@ -0,0 +1,942 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* arch/arm/src/nrf53/nrf53_qspi.c
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/arch.h>
|
||||||
|
#include <nuttx/kmalloc.h>
|
||||||
|
#include <nuttx/mutex.h>
|
||||||
|
#include <nuttx/semaphore.h>
|
||||||
|
#include <arch/board/board.h>
|
||||||
|
|
||||||
|
#include "arm_internal.h"
|
||||||
|
|
||||||
|
#include "hardware/nrf53_qspi.h"
|
||||||
|
|
||||||
|
#include "nrf53_clockconfig.h"
|
||||||
|
#include "nrf53_gpio.h"
|
||||||
|
#include "nrf53_qspi.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if ((NRF53_PCLK192M_FREQ != 192000000) && (NRF53_PCLK192M_FREQ != 96000000))
|
||||||
|
# error not supported PCLK192M frequency
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* QSPI frequency limits */
|
||||||
|
|
||||||
|
#define NRF53_QSPI_FREQMAX (NRF53_PCLK192M_FREQ / (2 * 1))
|
||||||
|
#define NRF53_QSPI_FREQMIN (NRF53_PCLK192M_FREQ / (2 * 16))
|
||||||
|
|
||||||
|
/* Instruction handled by the NRF53 QSPI peripheral */
|
||||||
|
|
||||||
|
#define QSPI_SECTOR_ERASE 0x20
|
||||||
|
#define QSPI_BLOCK_ERASE 0xd8
|
||||||
|
#define QSPI_ALL_ERASE 0xc7
|
||||||
|
|
||||||
|
/* QSPI memory synchronization */
|
||||||
|
|
||||||
|
#define MEMORY_SYNC() do { ARM_DSB(); ARM_ISB(); } while (0)
|
||||||
|
|
||||||
|
/* Ensure that the DMA buffers are word-aligned. */
|
||||||
|
|
||||||
|
#define ALIGN_SHIFT 2
|
||||||
|
#define ALIGN_MASK 3
|
||||||
|
#define ALIGN_UP(n) (((n)+ALIGN_MASK) & ~ALIGN_MASK)
|
||||||
|
#define IS_ALIGNED(n) (((uint32_t)(n) & ALIGN_MASK) == 0)
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
struct nrf53_qspidev_s
|
||||||
|
{
|
||||||
|
struct qspi_dev_s qspi; /* Externally visible part of the QSPI interface */
|
||||||
|
mutex_t lock; /* Assures mutually exclusive access to QSPI */
|
||||||
|
uint32_t base; /* QSPI base address */
|
||||||
|
uint32_t actual; /* Actual clock frequency */
|
||||||
|
uint32_t frequency; /* Requested clock frequency */
|
||||||
|
bool initialized; /* TRUE: Controller has been initialized */
|
||||||
|
uint8_t intf; /* QSPI controller number (0) */
|
||||||
|
uint8_t mode; /* Mode 0,3 */
|
||||||
|
sem_t op_sem; /* Block until complete */
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Helpers */
|
||||||
|
|
||||||
|
static inline void nrf53_qspi_putreg(struct nrf53_qspidev_s *priv,
|
||||||
|
uint32_t offset,
|
||||||
|
uint32_t value);
|
||||||
|
static inline uint32_t nrf53_qspi_getreg(struct nrf53_qspidev_s *priv,
|
||||||
|
uint32_t offset);
|
||||||
|
static void nrf53_qspi_cinstrdata_get(struct nrf53_qspidev_s *priv,
|
||||||
|
struct qspi_cmdinfo_s *cmdinfo);
|
||||||
|
static void nrf53_qspi_cinstrdata_put(struct nrf53_qspidev_s *priv,
|
||||||
|
struct qspi_cmdinfo_s *cmdinfo);
|
||||||
|
|
||||||
|
/* QSPI operations */
|
||||||
|
|
||||||
|
static int nrf53_qspi_lock(struct qspi_dev_s *dev, bool lock);
|
||||||
|
|
||||||
|
static int nrf53_qspi_lock(struct qspi_dev_s *dev, bool lock);
|
||||||
|
static uint32_t nrf53_qspi_setfrequency(struct qspi_dev_s *dev,
|
||||||
|
uint32_t frequency);
|
||||||
|
static void nrf53_qspi_setmode(struct qspi_dev_s *dev,
|
||||||
|
enum qspi_mode_e mode);
|
||||||
|
static void nrf53_qspi_setbits(struct qspi_dev_s *dev, int nbits);
|
||||||
|
static int nrf53_qspi_command(struct qspi_dev_s *dev,
|
||||||
|
struct qspi_cmdinfo_s *cmdinfo);
|
||||||
|
static int nrf53_qspi_memory(struct qspi_dev_s *dev,
|
||||||
|
struct qspi_meminfo_s *meminfo);
|
||||||
|
static void *nrf53_qspi_alloc(struct qspi_dev_s *dev, size_t buflen);
|
||||||
|
static void nrf53_qspi_free(struct qspi_dev_s *dev, void *buffer);
|
||||||
|
|
||||||
|
static int nrf53_qspi_interrupt(int irq, void *context, void *arg);
|
||||||
|
static int nrf53_qspi_hw_initialize(struct nrf53_qspidev_s *priv);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static const struct qspi_ops_s g_qspi_ops =
|
||||||
|
{
|
||||||
|
.lock = nrf53_qspi_lock,
|
||||||
|
.setfrequency = nrf53_qspi_setfrequency,
|
||||||
|
.setmode = nrf53_qspi_setmode,
|
||||||
|
.setbits = nrf53_qspi_setbits,
|
||||||
|
.command = nrf53_qspi_command,
|
||||||
|
.memory = nrf53_qspi_memory,
|
||||||
|
.alloc = nrf53_qspi_alloc,
|
||||||
|
.free = nrf53_qspi_free,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct nrf53_qspidev_s g_qspi0_dev =
|
||||||
|
{
|
||||||
|
.qspi =
|
||||||
|
{
|
||||||
|
.ops = &g_qspi_ops,
|
||||||
|
},
|
||||||
|
.lock = NXMUTEX_INITIALIZER,
|
||||||
|
.op_sem = SEM_INITIALIZER(0),
|
||||||
|
.base = NRF53_QSPI_BASE,
|
||||||
|
.intf = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_qspi_putreg
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Put a 32-bit register value by offset
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline void nrf53_qspi_putreg(struct nrf53_qspidev_s *priv,
|
||||||
|
uint32_t offset,
|
||||||
|
uint32_t value)
|
||||||
|
{
|
||||||
|
putreg32(value, priv->base + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_qspi_getreg
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Get a 32-bit register value by offset
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline uint32_t nrf53_qspi_getreg(struct nrf53_qspidev_s *priv,
|
||||||
|
uint32_t offset)
|
||||||
|
{
|
||||||
|
return getreg32(priv->base + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_qspi_lock
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* On QSPI buses where there are multiple devices, it will be necessary to
|
||||||
|
* lock QSPI to have exclusive access to the buses for a sequence of
|
||||||
|
* transfers. The bus should be locked before the chip is selected. After
|
||||||
|
* locking the QSPI bus, the caller should then also call the setfrequency,
|
||||||
|
* setbits, and setmode methods to make sure that the QSPI is properly
|
||||||
|
* configured for the device. If the QSPI bus is being shared, then it
|
||||||
|
* may have been left in an incompatible state.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device-specific state data
|
||||||
|
* lock - true: Lock QSPI bus, false: unlock QSPI bus
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int nrf53_qspi_lock(struct qspi_dev_s *dev, bool lock)
|
||||||
|
{
|
||||||
|
struct nrf53_qspidev_s *priv = (struct nrf53_qspidev_s *)dev;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
spiinfo("lock=%d\n", lock);
|
||||||
|
if (lock)
|
||||||
|
{
|
||||||
|
ret = nxmutex_lock(&priv->lock);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = nxmutex_unlock(&priv->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_qspi_setfrequency
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Set the QSPI frequency.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device-specific state data
|
||||||
|
* frequency - The QSPI frequency requested
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Returns the actual frequency selected
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static uint32_t nrf53_qspi_setfrequency(struct qspi_dev_s *dev,
|
||||||
|
uint32_t frequency)
|
||||||
|
{
|
||||||
|
struct nrf53_qspidev_s *priv = (struct nrf53_qspidev_s *)dev;
|
||||||
|
uint32_t sckfreq = 0;
|
||||||
|
uint32_t actual = 0;
|
||||||
|
uint32_t regval = 0;
|
||||||
|
|
||||||
|
spiinfo("frequency=%ld\n", frequency);
|
||||||
|
DEBUGASSERT(priv);
|
||||||
|
|
||||||
|
/* Check if the requested frequency is the same as the frequency
|
||||||
|
* selection
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (priv->frequency == frequency)
|
||||||
|
{
|
||||||
|
/* We are already at this frequency. Return the actual. */
|
||||||
|
|
||||||
|
return priv->actual;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get prescaler */
|
||||||
|
|
||||||
|
if (frequency <= NRF53_QSPI_FREQMIN)
|
||||||
|
{
|
||||||
|
sckfreq = 15;
|
||||||
|
}
|
||||||
|
else if (frequency <= NRF53_QSPI_FREQMAX)
|
||||||
|
{
|
||||||
|
sckfreq = ((NRF53_PCLK192M_FREQ / 2) / frequency) - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sckfreq = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Modify register */
|
||||||
|
|
||||||
|
regval = nrf53_qspi_getreg(priv, NRF53_QSPI_IFCONFIG1_OFFSET);
|
||||||
|
regval &= ~QSPI_IFCONFIG1_SCKFREQ_MASK;
|
||||||
|
regval |= sckfreq << QSPI_IFCONFIG1_SCKFREQ_SHIFT;
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_IFCONFIG1_OFFSET, regval);
|
||||||
|
|
||||||
|
/* Calculate the new actual frequency */
|
||||||
|
|
||||||
|
actual = NRF53_PCLK192M_FREQ / (2 * (sckfreq + 1));
|
||||||
|
|
||||||
|
/* Save the frequency setting */
|
||||||
|
|
||||||
|
priv->frequency = frequency;
|
||||||
|
priv->actual = actual;
|
||||||
|
|
||||||
|
spiinfo("Frequency %ld->%ld\n", frequency, actual);
|
||||||
|
|
||||||
|
return actual;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_qspi_setmode
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Set the QSPI mode. Optional. See enum qspi_mode_e for mode definitions.
|
||||||
|
* NOTE: the NRF53 QSPI supports only modes 0 and 3.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device-specific state data
|
||||||
|
* mode - The QSPI mode requested
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* none
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void nrf53_qspi_setmode(struct qspi_dev_s *dev, enum qspi_mode_e mode)
|
||||||
|
{
|
||||||
|
struct nrf53_qspidev_s *priv = (struct nrf53_qspidev_s *)dev;
|
||||||
|
uint32_t regval = 0;
|
||||||
|
|
||||||
|
spiinfo("mode=%d\n", mode);
|
||||||
|
|
||||||
|
/* Has the mode changed? */
|
||||||
|
|
||||||
|
if (mode != priv->mode)
|
||||||
|
{
|
||||||
|
regval = nrf53_qspi_getreg(priv, NRF53_QSPI_IFCONFIG1_OFFSET);
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case QSPIDEV_MODE0:
|
||||||
|
{
|
||||||
|
regval |= (QSPI_IFCONFIG1_SPIMODE_0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QSPIDEV_MODE3:
|
||||||
|
{
|
||||||
|
regval |= (QSPI_IFCONFIG1_SPIMODE_3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QSPIDEV_MODE1:
|
||||||
|
case QSPIDEV_MODE2:
|
||||||
|
{
|
||||||
|
spiinfo("unsupported mode=%d\n", mode);
|
||||||
|
|
||||||
|
/* No break here */
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
DEBUGASSERT(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write new mode */
|
||||||
|
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_IFCONFIG1_OFFSET, regval);
|
||||||
|
|
||||||
|
/* Save the mode so that subsequent re-configurations will be faster */
|
||||||
|
|
||||||
|
priv->mode = mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_qspi_setbits
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Set the number of bits per word.
|
||||||
|
* NOTE: the NRF53 QSPI only supports 8 bits, so this does nothing.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device-specific state data
|
||||||
|
* nbits - The number of bits requests
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* none
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void nrf53_qspi_setbits(struct qspi_dev_s *dev, int nbits)
|
||||||
|
{
|
||||||
|
if (nbits != 8)
|
||||||
|
{
|
||||||
|
spiinfo("unsupported nbits=%d\n", nbits);
|
||||||
|
DEBUGASSERT(FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_qspi_cinstrdata_get
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Get command data
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* priv - Device state structure.
|
||||||
|
* cmdinfo - Describes the command transfer to be performed.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) on SUCCESS, a negated errno on value of failure
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void nrf53_qspi_cinstrdata_get(struct nrf53_qspidev_s *priv,
|
||||||
|
struct qspi_cmdinfo_s *cmdinfo)
|
||||||
|
{
|
||||||
|
uint32_t regval = 0;
|
||||||
|
int i = 0;
|
||||||
|
uint8_t *buffer = cmdinfo->buffer;
|
||||||
|
|
||||||
|
DEBUGASSERT(cmdinfo->buflen <= 8);
|
||||||
|
|
||||||
|
/* Get Bytes 0-3 */
|
||||||
|
|
||||||
|
regval = nrf53_qspi_getreg(priv, NRF53_QSPI_CINSTRDAT0_OFFSET);
|
||||||
|
|
||||||
|
if (cmdinfo->buflen > 0)
|
||||||
|
{
|
||||||
|
for (i = 0; (i < 4) && (i < cmdinfo->buflen); i += 1)
|
||||||
|
{
|
||||||
|
buffer[i] = (regval >> (i * 8)) & 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write Bytes 4-7 */
|
||||||
|
|
||||||
|
regval = nrf53_qspi_getreg(priv, NRF53_QSPI_CINSTRDAT1_OFFSET);
|
||||||
|
|
||||||
|
if (cmdinfo->buflen > 4)
|
||||||
|
{
|
||||||
|
for (i = 4; (i < 8) && (i < cmdinfo->buflen); i += 1)
|
||||||
|
{
|
||||||
|
buffer[i] = (regval >> ((i - 4) * 8)) & 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_qspi_cinstrdata_put
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Put command data
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* priv - Device state structure.
|
||||||
|
* cmdinfo - Describes the command transfer to be performed.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) on SUCCESS, a negated errno on value of failure
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void nrf53_qspi_cinstrdata_put(struct nrf53_qspidev_s *priv,
|
||||||
|
struct qspi_cmdinfo_s *cmdinfo)
|
||||||
|
{
|
||||||
|
uint32_t regval = 0;
|
||||||
|
int i = 0;
|
||||||
|
uint8_t *buffer = cmdinfo->buffer;
|
||||||
|
|
||||||
|
DEBUGASSERT(cmdinfo->buflen <= 8);
|
||||||
|
|
||||||
|
regval = 0;
|
||||||
|
|
||||||
|
if (cmdinfo->buflen > 0)
|
||||||
|
{
|
||||||
|
for (i = 0; (i < 4) && (i < cmdinfo->buflen); i += 1)
|
||||||
|
{
|
||||||
|
regval |= (buffer[i] << (i * 8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write Bytes 0-3 */
|
||||||
|
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_CINSTRDAT0_OFFSET, regval);
|
||||||
|
|
||||||
|
regval = 0;
|
||||||
|
if (cmdinfo->buflen > 4)
|
||||||
|
{
|
||||||
|
for (i = 4; (i < 8) && (i < cmdinfo->buflen); i += 1)
|
||||||
|
{
|
||||||
|
regval |= (buffer[i] << ((i - 4) * 8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write Bytes 4-7 */
|
||||||
|
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_CINSTRDAT1_OFFSET, regval);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_qspi_command
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Perform one QSPI data transfer
|
||||||
|
*
|
||||||
|
* TODO: long frame mode not supported
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device-specific state data
|
||||||
|
* cmdinfo - Describes the command transfer to be performed.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) on SUCCESS, a negated errno on value of failure
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int nrf53_qspi_command(struct qspi_dev_s *dev,
|
||||||
|
struct qspi_cmdinfo_s *cmdinfo)
|
||||||
|
{
|
||||||
|
struct nrf53_qspidev_s *priv = (struct nrf53_qspidev_s *)dev;
|
||||||
|
uint32_t regval = 0;
|
||||||
|
|
||||||
|
DEBUGASSERT(cmdinfo->cmd < 256);
|
||||||
|
|
||||||
|
if (QSPICMD_ISADDRESS(cmdinfo->flags))
|
||||||
|
{
|
||||||
|
/* Only ERASE commands supported */
|
||||||
|
|
||||||
|
switch (cmdinfo->cmd)
|
||||||
|
{
|
||||||
|
case QSPI_SECTOR_ERASE:
|
||||||
|
{
|
||||||
|
regval = QSPI_ERASE_SECTOR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QSPI_BLOCK_ERASE:
|
||||||
|
{
|
||||||
|
regval = QSPI_ERASE_PAGE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QSPI_ALL_ERASE:
|
||||||
|
{
|
||||||
|
regval = QSPI_ERASE_ALL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
/* Not supported addressed command */
|
||||||
|
|
||||||
|
DEBUGASSERT(0);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure erase length */
|
||||||
|
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_ERASE_LEN_OFFSET, regval);
|
||||||
|
|
||||||
|
/* Configure erase address */
|
||||||
|
|
||||||
|
regval = cmdinfo->addr;
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_ERASE_PTR_OFFSET, regval);
|
||||||
|
|
||||||
|
/* Start erase operation */
|
||||||
|
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_TASKS_ERASESTART_OFFSET, 1);
|
||||||
|
|
||||||
|
/* Wait for the READY event.
|
||||||
|
* TODO: add timeout.
|
||||||
|
*
|
||||||
|
* NOTE: READ event only signals that the erase operation
|
||||||
|
* has been started.
|
||||||
|
*/
|
||||||
|
|
||||||
|
nxsem_wait(&priv->op_sem);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QSPICMD_ISWRITE(cmdinfo->flags))
|
||||||
|
{
|
||||||
|
/* Write data to CINSTRDAT registers */
|
||||||
|
|
||||||
|
nrf53_qspi_cinstrdata_put(priv, cmdinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure custom instruction */
|
||||||
|
|
||||||
|
regval = cmdinfo->cmd << QSPI_ADDRCONF_OPCODE_SHIFT;
|
||||||
|
regval |= QSPI_CINSTRCONF_LENGTH(cmdinfo->buflen + 1);
|
||||||
|
|
||||||
|
if (QSPICMD_ISWRITE(cmdinfo->flags))
|
||||||
|
{
|
||||||
|
/* Write request */
|
||||||
|
|
||||||
|
regval |= QSPI_CINSTRCONF_WREN;
|
||||||
|
|
||||||
|
/* Wait for write complete before sending command */
|
||||||
|
|
||||||
|
regval |= QSPI_CINSTRCONF_WIPWAIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* IO2 and IO3 high during transmission of custom instruction */
|
||||||
|
|
||||||
|
regval |= QSPI_CINSTRCONF_LIO2 | QSPI_CINSTRCONF_LIO3;
|
||||||
|
|
||||||
|
/* Write CINSTRCONF register to initiate transfer */
|
||||||
|
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_CINSTRCONF_OFFSET, regval);
|
||||||
|
|
||||||
|
/* Wait for the READY event.
|
||||||
|
* TODO: add timeout.
|
||||||
|
*/
|
||||||
|
|
||||||
|
nxsem_wait(&priv->op_sem);
|
||||||
|
|
||||||
|
if (QSPICMD_ISREAD(cmdinfo->flags))
|
||||||
|
{
|
||||||
|
/* Get response */
|
||||||
|
|
||||||
|
nrf53_qspi_cinstrdata_get(priv, cmdinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_qspi_memory
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Perform one QSPI memory transfer
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device-specific state data
|
||||||
|
* meminfo - Describes the memory transfer to be performed.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) on SUCCESS, a negated errno on value of failure
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int nrf53_qspi_memory(struct qspi_dev_s *dev,
|
||||||
|
struct qspi_meminfo_s *meminfo)
|
||||||
|
{
|
||||||
|
struct nrf53_qspidev_s *priv = (struct nrf53_qspidev_s *)dev;
|
||||||
|
|
||||||
|
DEBUGASSERT(meminfo->buffer != NULL && meminfo->buflen > 0);
|
||||||
|
|
||||||
|
if (QSPIMEM_ISWRITE(meminfo->flags))
|
||||||
|
{
|
||||||
|
/* Configure data transfer */
|
||||||
|
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_WRITE_SRC_OFFSET,
|
||||||
|
meminfo->addr);
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_WRITE_DST_OFFSET,
|
||||||
|
(uint32_t) meminfo->buffer);
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_WRITE_CNT_OFFSET,
|
||||||
|
meminfo->buflen);
|
||||||
|
|
||||||
|
/* Start WRITE task */
|
||||||
|
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_TASKS_WRITESTART_OFFSET, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Configure data transfer */
|
||||||
|
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_READ_SRC_OFFSET,
|
||||||
|
meminfo->addr);
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_READ_DST_OFFSET,
|
||||||
|
(uint32_t) meminfo->buffer);
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_READ_CNT_OFFSET,
|
||||||
|
meminfo->buflen);
|
||||||
|
|
||||||
|
/* Start READ task */
|
||||||
|
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_TASKS_READSTART_OFFSET, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for the READY event.
|
||||||
|
* TODO: add timeout.
|
||||||
|
*/
|
||||||
|
|
||||||
|
nxsem_wait(&priv->op_sem);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_qspi_alloc
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Allocate a buffer suitable for DMA data transfer
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device-specific state data
|
||||||
|
* buflen - Buffer length to allocate in bytes
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Address of the allocated memory on success; NULL is returned on any
|
||||||
|
* failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void *nrf53_qspi_alloc(struct qspi_dev_s *dev, size_t buflen)
|
||||||
|
{
|
||||||
|
return kmm_malloc(ALIGN_UP(buflen));
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_qspi_free
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Free memory returned by QSPI_ALLOC
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device-specific state data
|
||||||
|
* buffer - Buffer previously allocated via QSPI_ALLOC
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void nrf53_qspi_free(struct qspi_dev_s *dev, void *buffer)
|
||||||
|
{
|
||||||
|
if (buffer)
|
||||||
|
{
|
||||||
|
kmm_free(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_qspi_interrupt
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Interrupt handler; we handle all QSPI cases -- reads, writes,
|
||||||
|
* automatic status polling, etc.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* irq -
|
||||||
|
* context -
|
||||||
|
* qrg -
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* OK means we handled it
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int nrf53_qspi_interrupt(int irq, void *context, void *arg)
|
||||||
|
{
|
||||||
|
struct nrf53_qspidev_s *priv = arg;
|
||||||
|
|
||||||
|
/* Clear READY event */
|
||||||
|
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_EVENTS_READY_OFFSET, 0);
|
||||||
|
|
||||||
|
/* Signal TASK complete */
|
||||||
|
|
||||||
|
nxsem_post(&g_qspi0_dev.op_sem);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_qspi_hw_initialize
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initialize the QSPI peripheral from hardware reset.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* priv - Device state structure.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) on SUCCESS, a negated errno on value of failure
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int nrf53_qspi_hw_initialize(struct nrf53_qspidev_s *priv)
|
||||||
|
{
|
||||||
|
uint32_t regval = 0;
|
||||||
|
int pin = 0;
|
||||||
|
int port = 0;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
/* Only for QSPI0 */
|
||||||
|
|
||||||
|
DEBUGASSERT(priv->intf == 0);
|
||||||
|
|
||||||
|
/* Attach the interrupt handler */
|
||||||
|
|
||||||
|
ret = irq_attach(NRF53_IRQ_QSPI, nrf53_qspi_interrupt, priv);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
spierr("ERROR: Failed to attach QSPI irq\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SCK pin */
|
||||||
|
|
||||||
|
nrf53_gpio_config(NRF53_QSPI0_SCK_PIN | GPIO_DRIVE_H0H1);
|
||||||
|
pin = GPIO_PIN_DECODE(NRF53_QSPI0_SCK_PIN);
|
||||||
|
port = GPIO_PORT_DECODE(NRF53_QSPI0_SCK_PIN);
|
||||||
|
regval = (pin << QSPI_PSEL_PIN_SHIFT) | (port << QSPI_PSEL_PORT_SHIFT);
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_PSEL_SCK_OFFSET, regval);
|
||||||
|
|
||||||
|
/* CSN pin */
|
||||||
|
|
||||||
|
nrf53_gpio_config(NRF53_QSPI0_CSN_PIN | GPIO_DRIVE_H0H1);
|
||||||
|
pin = GPIO_PIN_DECODE(NRF53_QSPI0_CSN_PIN);
|
||||||
|
port = GPIO_PORT_DECODE(NRF53_QSPI0_CSN_PIN);
|
||||||
|
regval = (pin << QSPI_PSEL_PIN_SHIFT) | (port << QSPI_PSEL_PORT_SHIFT);
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_PSEL_CSN_OFFSET, regval);
|
||||||
|
|
||||||
|
/* IO0 pin */
|
||||||
|
|
||||||
|
nrf53_gpio_config(NRF53_QSPI0_IO0_PIN | GPIO_DRIVE_H0H1);
|
||||||
|
pin = GPIO_PIN_DECODE(NRF53_QSPI0_IO0_PIN);
|
||||||
|
port = GPIO_PORT_DECODE(NRF53_QSPI0_IO0_PIN);
|
||||||
|
regval = (pin << QSPI_PSEL_PIN_SHIFT) | (port << QSPI_PSEL_PORT_SHIFT);
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_PSEL_IO0_OFFSET, regval);
|
||||||
|
|
||||||
|
/* IO1 pin */
|
||||||
|
|
||||||
|
nrf53_gpio_config(NRF53_QSPI0_IO1_PIN | GPIO_DRIVE_H0H1);
|
||||||
|
pin = GPIO_PIN_DECODE(NRF53_QSPI0_IO1_PIN);
|
||||||
|
port = GPIO_PORT_DECODE(NRF53_QSPI0_IO1_PIN);
|
||||||
|
regval = (pin << QSPI_PSEL_PIN_SHIFT) | (port << QSPI_PSEL_PORT_SHIFT);
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_PSEL_IO1_OFFSET, regval);
|
||||||
|
|
||||||
|
/* IO2 pin */
|
||||||
|
|
||||||
|
nrf53_gpio_config(NRF53_QSPI0_IO2_PIN | GPIO_DRIVE_H0H1);
|
||||||
|
pin = GPIO_PIN_DECODE(NRF53_QSPI0_IO2_PIN);
|
||||||
|
port = GPIO_PORT_DECODE(NRF53_QSPI0_IO2_PIN);
|
||||||
|
regval = (pin << QSPI_PSEL_PIN_SHIFT) | (port << QSPI_PSEL_PORT_SHIFT);
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_PSEL_IO2_OFFSET, regval);
|
||||||
|
|
||||||
|
/* IO3 pin */
|
||||||
|
|
||||||
|
nrf53_gpio_config(NRF53_QSPI0_IO3_PIN | GPIO_DRIVE_H0H1);
|
||||||
|
pin = GPIO_PIN_DECODE(NRF53_QSPI0_IO3_PIN);
|
||||||
|
port = GPIO_PORT_DECODE(NRF53_QSPI0_IO3_PIN);
|
||||||
|
regval = (pin << QSPI_PSEL_PIN_SHIFT) | (port << QSPI_PSEL_PORT_SHIFT);
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_PSEL_IO3_OFFSET, regval);
|
||||||
|
|
||||||
|
/* Configure quad data line SPI */
|
||||||
|
|
||||||
|
regval = (QSPI_IFCONFIG0_READOC_READ4IO | QSPI_IFCONFIG0_WRITEOC_PP4IO);
|
||||||
|
regval |= QSPI_IFCONFIG0_PPSIZE_512;
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_IFCONFIG0_OFFSET, regval);
|
||||||
|
|
||||||
|
/* Enable READY interrupt */
|
||||||
|
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_INTENSET_OFFSET, QSPI_INT_READY);
|
||||||
|
|
||||||
|
/* Configure RX delay */
|
||||||
|
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_IFTIMING_OFFSET,
|
||||||
|
QSPI_IFTIMING_RXDELAY(CONFIG_NRF53_QSPI_RXDELAY));
|
||||||
|
|
||||||
|
/* Enable QSPI interrupts */
|
||||||
|
|
||||||
|
up_enable_irq(NRF53_IRQ_QSPI);
|
||||||
|
|
||||||
|
/* Enable QSPI */
|
||||||
|
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_ENABLE_OFFSET, 1);
|
||||||
|
|
||||||
|
/* Activate QSPI */
|
||||||
|
|
||||||
|
nrf53_qspi_putreg(priv, NRF53_QSPI_TASKS_ACTIVATE_OFFSET, 1);
|
||||||
|
|
||||||
|
/* Wait for READY event.
|
||||||
|
* TODO: add timeout.
|
||||||
|
*/
|
||||||
|
|
||||||
|
nxsem_wait(&priv->op_sem);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_qspi_initialize
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initialize the selected QSPI port in master mode
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* intf - Interface number(must be zero)
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Valid QSPI device structure reference on success; a NULL on failure
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
struct qspi_dev_s *nrf53_qspi_initialize(int intf)
|
||||||
|
{
|
||||||
|
struct nrf53_qspidev_s *priv = NULL;
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
|
/* The NRF53 has only a single QSPI port */
|
||||||
|
|
||||||
|
spiinfo("intf: %d\n", intf);
|
||||||
|
DEBUGASSERT(intf == 0);
|
||||||
|
|
||||||
|
/* Select the QSPI interface */
|
||||||
|
|
||||||
|
if (intf == 0)
|
||||||
|
{
|
||||||
|
/* Select QSPI0 */
|
||||||
|
|
||||||
|
priv = &g_qspi0_dev;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spierr("ERROR: QSPI%d not supported\n", intf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Has the QSPI hardware been initialized? */
|
||||||
|
|
||||||
|
if (!priv->initialized)
|
||||||
|
{
|
||||||
|
/* Perform hardware initialization. Puts the QSPI into an active
|
||||||
|
* state.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = nrf53_qspi_hw_initialize(priv);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
spierr("ERROR: Failed to initialize QSPI hardware\n");
|
||||||
|
irq_detach(NRF53_IRQ_QSPI);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable interrupts at the NVIC */
|
||||||
|
|
||||||
|
priv->initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &priv->qspi;
|
||||||
|
}
|
52
arch/arm/src/nrf53/nrf53_qspi.h
Normal file
52
arch/arm/src/nrf53/nrf53_qspi.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* arch/arm/src/nrf53/nrf53_qspi.h
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __ARCH_ARM_SRC_NRF53_NRF53_QSPI_H
|
||||||
|
#define __ARCH_ARM_SRC_NRF53_NRF53_QSPI_H
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <nuttx/spi/qspi.h>
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_qspi_initialize
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initialize the selected QSPI port in master mode
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* intf - Interface number(must be zero)
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Valid QSPI device structure reference on success; a NULL on failure
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
struct qspi_dev_s *nrf53_qspi_initialize(int intf);
|
||||||
|
|
||||||
|
#endif /* __ARCH_ARM_SRC_NRF53_NRF53_QSPI_H */
|
Loading…
Reference in New Issue
Block a user