AM273x MCU+ SDK  09.02.00
QSPI Low Level Driver

Features Supported

  • Support for Single, Dual or Quad read operation.
  • Support for Interrupt mode.
  • Support for DMA read.
  • Programmable Signal Polarities
  • Programmable Active Clock Edge
  • Programmable Delay between chip select activation and output data from 0 to 3 QSPI clock cycles

SysConfig Features

Note
It is strongly recommend to use SysConfig where it is available instead of using direct SW API calls. This will help simplify the SW application and also catch common mistakes early in the development cycle.
  • QSPI instance name
  • Input clock frequency to be used for QSPI module
  • Input clock divider which decides the baud-rate at which the flash will be read
  • Chip Select
  • Enabling DMA mode
  • In advanced config, you can choose various parameters like frame format, decoder chip select polarity, read dummy cycles, SDK Infra and QSPI Interrupt.

Features NOT Supported

  • Dual and Quad writes are not supported.

Usage Overview

API Sequence

To use the QSPI driver to send data over the SPI bus, the application calls the following APIs:

Example Usage

Include the below file to access the APIs

#include <stdio.h>
#include <string.h>
#include <kernel/dpl/MutexArmP.h>
#include <kernel/nortos/dpl/r5/HwiP_armv7r_vim.h>

Instance Open Example

int32_t status = QSPI_SYSTEM_SUCCESS;
gQspiHandle = &gQspiObject[CONFIG_QSPI0];
status = QSPI_lld_init(gQspiHandle);

Instance Close Example

int32_t status = QSPI_SYSTEM_SUCCESS;
status = QSPI_lld_deInit(gQspiHandle);

Blocking Read Example

void writeRead_blocking(void)
{
int32_t status = SystemP_SUCCESS;
msg.cmd = QSPI_NOR_PAGE_PROG;
msg.cmdAddr = APP_QSPI_FLASH_OFFSET;
msg.dataLen = APP_QSPI_DATA_SIZE;
msg.numAddrBytes = QSPI_ADDR_BYTES;
msg.dataBuf = (void *)gQspiTxBuf;
status = QSPI_lld_writeCmd(gQspiHandle, &msg);
status = QSPI_lld_read(gQspiHandle,APP_QSPI_DATA_SIZE,gQspiRxBuf,APP_QSPI_FLASH_OFFSET,SystemP_WAIT_FOREVER);
if(status == SystemP_SUCCESS)
{
DebugP_log("QSPI Read Success");
}
else
{
DebugP_log("QSPI Read Fail");
}
}

Non-Blocking Example ISR Register

static __attribute__((__section__(".text.hwi"), noinline, naked, target("arm"), aligned(4))) void App_QSPI_ISR(void)
{
ISR_CALL_LEVEL_NONFLOAT_REENTRANT(QSPI_lld_isr, \
gQspiHandle, \
intrNum, \
gQSPIVimStsAddr, \
gQSPIVimStsClrMask,
intcBaseAddr);
}

Non-Blocking Transfer Example

void transfer_nonblocking(void)
{
int32_t status = SystemP_SUCCESS;
uint32_t itr = 0U;
/* Interrupt configuration and registration*/
gQspiHandle->interruptCallback = isrCallback;
intrNum = gQspiHandle->hQspiInit->intrNum;
intcBaseAddr = gHwiConfig.intcBaseAddr;
gQSPIVimStsAddr = intcBaseAddr + (0x404u + (((intrNum)>> 5) & 0xFu) * 0x20u);
gQSPIVimStsClrMask = 0x1u << ((intrNum) & 0x1Fu);
/* Register Interrupt */
HwiP_setPri(intrNum, 4U);
HwiP_setVecAddr(intrNum, (uintptr_t)&App_QSPI_ISR);
HwiP_enableInt(intrNum);
/* Populating the command and Tx buffer*/
msg.dataLen = APP_QSPI_DATA_SIZE;
msg.dataBuf = gQspiTxBuf;
msg.cmdAddr = APP_QSPI_FLASH_OFFSET;
msg.cmd = QSPI_NOR_PAGE_PROG;
msg.numAddrBytes = QSPI_ADDR_BYTES;
status = QSPI_lld_writeCmdIntr(gQspiHandle,&msg);
if (status == SystemP_SUCCESS )
{
while(try_lock_mutex(&transferMutex) == MUTEX_ARM_LOCKED);
}
else
{
DebugP_log("QSPI Write Fail");
}
/* Mutex Lock */
transferMutex = MUTEX_ARM_LOCKED;
msg.dataBuf = gQspiRxBuf;
msg.cmd = QSPI_NOR_CMD_SINGLE_READ;
msg.numAddrBytes = QSPI_ADDR_BYTES;
QSPI_lld_readCmdIntr(gQspiHandle,&msg);
if (status == SystemP_SUCCESS )
{
while(try_lock_mutex(&transferMutex) == MUTEX_ARM_LOCKED);
}
else
{
DebugP_log("QSPI Write Fail");
}
for(itr = 0U; itr < APP_QSPI_DATA_SIZE; itr++)
{
if(gQspiTxBuf[itr] != gQspiRxBuf[itr])
{
status = SystemP_FAILURE;
DebugP_logError("QSPI read data mismatch %d !!!\r\n",itr);
break;
}
}
if (status == SystemP_SUCCESS)
{
DebugP_log("QSPI Write and Read PASS");
}
/* De-Register Interrupt */
HwiP_setVecAddr(intrNum, 0);
HwiP_disableInt(intrNum);
}

Non-Blocking Example ISR callback

void isrCallback(void *args)
{
unlock_mutex(&transferMutex);
}

API

APIs for QSPI LLD

QSPILLD_WriteCmdParams::dataBuf
void * dataBuf
Definition: qspi_lld.h:368
args
void * args
Definition: hsmclient_msg.h:4
HwiP_disableInt
uint32_t HwiP_disableInt(uint32_t intNum)
Disable a specific interrupt.
QSPI_lld_read
int32_t QSPI_lld_read(QSPILLD_Handle hQspi, uint32_t count, void *rxBuf, uint32_t addrOffset, uint32_t timeout)
Function to perform reads from the flash in memory map mode.
SystemP_WAIT_FOREVER
#define SystemP_WAIT_FOREVER
Value to use when needing a timeout of infinity or wait forver until resource is available.
Definition: SystemP.h:83
QSPILLD_WriteCmdParams::dataLen
uint32_t dataLen
Definition: qspi_lld.h:370
QSPI_lld_isr
void QSPI_lld_isr(void *args)
QSPI ISR for Read and Write Functionality.
QSPI_SYSTEM_SUCCESS
#define QSPI_SYSTEM_SUCCESS
Return status when the API execution was successful.
Definition: qspi_lld.h:197
QSPILLD_WriteCmdParams::cmdAddr
uint32_t cmdAddr
Definition: qspi_lld.h:363
DebugP_log
#define DebugP_log(format,...)
Function to log a string to the enabled console.
Definition: DebugP.h:225
QSPI_lld_readCmdIntr
int32_t QSPI_lld_readCmdIntr(QSPILLD_Handle hQspi, const QSPILLD_WriteCmdParams *msg)
Function to send specific commands and receive related data from flash in interrupt mode.
QSPILLD_WriteCmdParams::cmd
uint8_t cmd
Definition: qspi_lld.h:361
HwiP_enableInt
void HwiP_enableInt(uint32_t intNum)
Enable a specific interrupt.
DebugP_logError
#define DebugP_logError(format,...)
Function to log a string to the enabled console, for error zone.
Definition: DebugP.h:234
QSPI_lld_writeCmd
int32_t QSPI_lld_writeCmd(QSPILLD_Handle hQspi, QSPILLD_WriteCmdParams *writeMsg)
Function to send specific commands and write data into flash in configuration mode.
SystemP_SUCCESS
#define SystemP_SUCCESS
Return status when the API execution was successful.
Definition: SystemP.h:56
QSPILLD_WriteCmdParams::numAddrBytes
uint8_t numAddrBytes
Definition: qspi_lld.h:366
SystemP_FAILURE
#define SystemP_FAILURE
Return status when the API execution was not successful due to a failure.
Definition: SystemP.h:61
QSPILLD_WriteCmdParams
QSPI Transaction Info.
Definition: qspi_lld.h:360
qspi_lld.h
QSPI LLD Driver API/interface file.
DebugP.h
QSPI_lld_deInit
int32_t QSPI_lld_deInit(QSPILLD_Handle hQspi)
This function de-initializes the QSPI module.
DebugP_assert
#define DebugP_assert(expression)
Function to call for assert check.
Definition: DebugP.h:177
__attribute__
struct sockaddr __attribute__
HSM client / server message format struct.
QSPI_lld_init
int32_t QSPI_lld_init(QSPILLD_Handle hQspi)
This function initializes the QSPI module.
QSPI_lld_writeCmdIntr
int32_t QSPI_lld_writeCmdIntr(QSPILLD_Handle hQspi, const QSPILLD_WriteCmdParams *msg)
Function to send specific commands and write data into flash in interrupt mode.