Skip to content

Commit

Permalink
Added nRF5340 QSPI support. Various other fixes for SPI/UART.
Browse files Browse the repository at this point in the history
  • Loading branch information
dgarske committed Aug 27, 2024
1 parent 3232664 commit 0ca4823
Show file tree
Hide file tree
Showing 7 changed files with 273 additions and 138 deletions.
42 changes: 30 additions & 12 deletions hal/nrf5340.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@
#ifdef TARGET_nrf5340

#include <stdint.h>
#include "image.h"

#include "image.h"
#include "string.h"
#include "nrf5340.h"

#ifdef DEBUG_UART
Expand All @@ -34,31 +35,46 @@

void uart_init(void)
{
/* nRF5340-DK UART0=P1.01, UART1=P0.20 */
#if UART_SEL == 0
UART_PSEL_TXD(UART_SEL) = (PSEL_PORT(1) | 1);
#else
UART_PSEL_TXD(UART_SEL) = (PSEL_PORT(0) | 20);
#endif
UART_BAUDRATE(UART_SEL) = BAUD_115200;
UART_ENABLE(UART_SEL) = 1;
}

static void uart_write_char(char c)
void uart_write_sz(const char* c, unsigned int sz)
{
UART_EVENT_ENDTX(UART_SEL) = 0;

UART_TXD_PTR(UART_SEL) = (uint32_t)(&c);
UART_TXD_MAXCOUNT(UART_SEL) = 1;
UART_TXD_PTR(UART_SEL) = (uint32_t)c;
UART_TXD_MAXCOUNT(UART_SEL) = sz;
UART_TASK_STARTTX(UART_SEL) = 1;
while(UART_EVENT_ENDTX(UART_SEL) == 0)
;
}

void uart_write(const char* buf, unsigned int sz)
{
uint32_t pos = 0;
while (sz-- > 0) {
char c = buf[pos++];
if (c == '\n') { /* handle CRLF */
uart_write_char('\r');
const char* line;
unsigned int lineSz;
do {
/* find `\n` */
line = memchr(buf, sz, '\n');
if (line == NULL) {
uart_write_sz(buf, sz);
break;
}
uart_write_char(c);
}
lineSz = line - buf;

uart_write_sz(line, lineSz);
uart_write_sz("\r", 1); /* handle CRLF */

buf = line;
sz -= lineSz;
} while ((int)sz > 0);
}
#endif /* DEBUG_UART */

Expand All @@ -74,7 +90,8 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
uint32_t *src, *dst;

while (i < len) {
if ((len - i > 3) && ((((address + i) & 0x03) == 0) && ((((uint32_t)data) + i) & 0x03) == 0)) {
if ((len - i > 3) && ((((address + i) & 0x03) == 0) &&
((((uint32_t)data) + i) & 0x03) == 0)) {
src = (uint32_t *)data;
dst = (uint32_t *)address;
NVMC_CONFIG = NVMC_CONFIG_WEN;
Expand Down Expand Up @@ -129,6 +146,7 @@ void hal_init(void)
uart_write("wolfBoot HAL Init\n", 18);
#endif

/* wait for high frequency clock startup */
TASKS_HFCLKSTART = 1;
while(EVENTS_HFCLKSTARTED == 0)
;
Expand Down
103 changes: 89 additions & 14 deletions hal/nrf5340.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
#define DMB() __asm__ volatile ("dmb")
#define NOP() __asm__ volatile ("nop")

/* PSEL Port (bit 5) - Used for various PSEL (UART,SPI,QSPI,I2C,NFC) */
#define PSEL_PORT(n) (((n) & 0x1) << 5)

/* Non-volatile memory controller */
#ifdef TZEN
#define NVMC_BASE (0x50039000)
Expand All @@ -49,26 +52,34 @@
#define APP_CLOCK_BASE (0x40005000)
#endif
#define NET_CLOCK_BASE (0x41005000)
#define TASKS_HFCLKSTART *((volatile uint32_t *)(APP_CLOCK_BASE + 0x000))
#define TASKS_HFCLKSTOP *((volatile uint32_t *)(APP_CLOCK_BASE + 0x004))
#define EVENTS_HFCLKSTARTED *((volatile uint32_t *)(APP_CLOCK_BASE + 0x100))
#define TASKS_HFCLKSTART *((volatile uint32_t *)(APP_CLOCK_BASE + 0x000))
#define TASKS_HFCLKSTOP *((volatile uint32_t *)(APP_CLOCK_BASE + 0x004))
#define EVENTS_HFCLKSTARTED *((volatile uint32_t *)(APP_CLOCK_BASE + 0x100))

/* GPIO Port 0 or Port 1 */
/* GPIO Port (0-1) */
#ifdef TZEN
#define GPIO_BASE(n) (0x50842500 + (((n) & 0x1) * 0x300))
#else
#define GPIO_BASE(n) (0x40842500 + (((n) & 0x1) * 0x300))
#endif
#define GPIO_OUT(n) *((volatile uint32_t *)(GPIO_BASE(n) + 0x004))
#define GPIO_OUTSET(n) *((volatile uint32_t *)(GPIO_BASE(n) + 0x008))
#define GPIO_OUTCLR(n) *((volatile uint32_t *)(GPIO_BASE(n) + 0x00C))
#define GPIO_DIRSET(n) *((volatile uint32_t *)(GPIO_BASE(n) + 0x018))
#define GPIO_PIN_CNF(n,p) *((volatile uint32_t *)(GPIO_BASE(n) + 0x200 + (p)))
#define GPIO_OUT(n) *((volatile uint32_t *)(GPIO_BASE(n) + 0x004))
#define GPIO_OUTSET(n) *((volatile uint32_t *)(GPIO_BASE(n) + 0x008))
#define GPIO_OUTCLR(n) *((volatile uint32_t *)(GPIO_BASE(n) + 0x00C))
#define GPIO_IN(n) *((volatile uint32_t *)(GPIO_BASE(n) + 0x010))
#define GPIO_DIRSET(n) *((volatile uint32_t *)(GPIO_BASE(n) + 0x018))
#define GPIO_PIN_CNF(n,p) *((volatile uint32_t *)(GPIO_BASE(n) + 0x200 + (p)))

#define GPIO_CNF_IN 0
#define GPIO_CNF_OUT 3
#define GPIO_CNF_IN 0
#define GPIO_CNF_OUT 3
#define GPIO_CNF_PULL_DIS 0
#define GPIO_CNF_PULL_UP (3UL << 2)
#define GPIO_CNF_PULL_DOWN (1UL << 2)
#define GPIO_CNF_STD_DRIVE 0
#define GPIO_CNF_HIGH_DRIVE (3UL << 8)
#define GPIO_CNF_SENSE_NONE 0
#define GPIO_CNF_MCUSEL(n) (((n) & 0x7) << 28)

/* UART 0 or 1 */
/* UART (0-1) */
#ifdef TZEN
#define UART_BASE(n) (0x50008000 + (((n) & 0x1) * 0x1000))
#else
Expand All @@ -78,13 +89,17 @@
#define UART_TASK_STOPTX(n) *((volatile uint32_t *)(UART_BASE(n) + 0x00C))
#define UART_EVENT_ENDTX(n) *((volatile uint32_t *)(UART_BASE(n) + 0x120))
#define UART_ENABLE(n) *((volatile uint32_t *)(UART_BASE(n) + 0x500))
#define UART_PSEL_TXD(n) *((volatile uint32_t *)(UART_BASE(n) + 0x50C))
#define UART_PSEL_RXD(n) *((volatile uint32_t *)(UART_BASE(n) + 0x514))
#define UART_BAUDRATE(n) *((volatile uint32_t *)(UART_BASE(n) + 0x524))
#define UART_TXD_PTR(n) *((volatile uint32_t *)(UART_BASE(n) + 0x544))
#define UART_TXD_MAXCOUNT(n) *((volatile uint32_t *)(UART_BASE(n) + 0x548))
#define UART_BAUDRATE(n) *((volatile uint32_t *)(UART_BASE(n) + 0x524))

#define BAUD_115200 0x01D60000

/* SPI */
void uart_write_sz(const char* c, unsigned int sz);

/* SPI (0-2) */
#ifdef TZEN
#define SPI_BASE(n) (0x50008000 + (((n) & 0x3) * 0x1000))
#else
Expand Down Expand Up @@ -118,10 +133,70 @@
#define SPI_FREQ_M32 0x14000000

/* QSPI */
#define QSPI_CLK 96000000
#ifdef TZEN
#define QSPI_BASE (0x5002B000)
#else
#define QSPI_BASE (0x4002B000)
#endif
#define QSPI_TASKS_ACTIVATE *((volatile uint32_t *)(QSPI_BASE + 0x000))
#define QSPI_TASKS_READSTART *((volatile uint32_t *)(QSPI_BASE + 0x004))
#define QSPI_TASKS_WRITESTART *((volatile uint32_t *)(QSPI_BASE + 0x008))
#define QSPI_TASKS_ERASESTART *((volatile uint32_t *)(QSPI_BASE + 0x00C))
#define QSPI_TASKS_DEACTIVATE *((volatile uint32_t *)(QSPI_BASE + 0x010))
#define QSPI_EVENTS_READY *((volatile uint32_t *)(QSPI_BASE + 0x100))
#define QSPI_ENABLE *((volatile uint32_t *)(QSPI_BASE + 0x500))

#define QSPI_READ_SRC *((volatile uint32_t *)(QSPI_BASE + 0x504))
#define QSPI_READ_DST *((volatile uint32_t *)(QSPI_BASE + 0x508))
#define QSPI_READ_CNT *((volatile uint32_t *)(QSPI_BASE + 0x50C))
#define QSPI_WRITE_DST *((volatile uint32_t *)(QSPI_BASE + 0x510))
#define QSPI_WRITE_SRC *((volatile uint32_t *)(QSPI_BASE + 0x514))
#define QSPI_WRITE_CNT *((volatile uint32_t *)(QSPI_BASE + 0x518))
#define QSPI_ERASE_PTR *((volatile uint32_t *)(QSPI_BASE + 0x51C))
#define QSPI_ERASE_LEN *((volatile uint32_t *)(QSPI_BASE + 0x520))

#define QSPI_PSEL_SCK *((volatile uint32_t *)(QSPI_BASE + 0x524))
#define QSPI_PSEL_CSN *((volatile uint32_t *)(QSPI_BASE + 0x528))
#define QSPI_PSEL_IO0 *((volatile uint32_t *)(QSPI_BASE + 0x530))
#define QSPI_PSEL_IO1 *((volatile uint32_t *)(QSPI_BASE + 0x534))
#define QSPI_PSEL_IO2 *((volatile uint32_t *)(QSPI_BASE + 0x538))
#define QSPI_PSEL_IO3 *((volatile uint32_t *)(QSPI_BASE + 0x53C))

#define QSPI_IFCONFIG0 *((volatile uint32_t *)(QSPI_BASE + 0x544))
#define QSPI_IFCONFIG1 *((volatile uint32_t *)(QSPI_BASE + 0x600))

#define QSPI_STATUS *((volatile uint32_t *)(QSPI_BASE + 0x604))
#define QSPI_ADDRCONF *((volatile uint32_t *)(QSPI_BASE + 0x624))
#define QSPI_CINSTRCONF *((volatile uint32_t *)(QSPI_BASE + 0x634))
#define QSPI_CINSTRDAT0 *((volatile uint32_t *)(QSPI_BASE + 0x638))
#define QSPI_CINSTRDAT1 *((volatile uint32_t *)(QSPI_BASE + 0x63C))
#define QSPI_IFTIMING *((volatile uint32_t *)(QSPI_BASE + 0x640))

#define QSPI_IFCONFIG0_READOC_FASTREAD (0) /* opcode 0x0B */
#define QSPI_IFCONFIG0_READOC_READ2O (1) /* opcode 0x3B */
#define QSPI_IFCONFIG0_READOC_READ2IO (2) /* opcode 0xBB */
#define QSPI_IFCONFIG0_READOC_READ4O (3) /* opcode 0x6B */
#define QSPI_IFCONFIG0_READOC_READ4IO (4) /* opcode 0xEB */
#define QSPI_IFCONFIG0_WRITEOC_PP ((0) << 3) /* opcode 0x02 */
#define QSPI_IFCONFIG0_WRITEOC_PP2O ((1) << 3) /* opcode 0xA2 */
#define QSPI_IFCONFIG0_WRITEOC_PP4O ((2) << 3) /* opcode 0x32 */
#define QSPI_IFCONFIG0_WRITEOC_PP4IO ((3) << 3) /* opcode 0x38 */
#define QSPI_IFCONFIG0_ADDRMODE_24BIT ((0) << 6)
#define QSPI_IFCONFIG0_ADDRMODE_32BIT ((1) << 6)
#define QSPI_IFCONFIG0_DPMENABLE ((1) << 7)
#define QSPI_IFCONFIG0_PPSIZE_256 ((0) << 12)
#define QSPI_IFCONFIG0_PPSIZE_512 ((1) << 12)

#define QSPI_IFCONFIG1_SCKDEKLAY(n) ((n) & 0xFF)
#define QSPI_IFCONFIG1_SPIMODE0 0
#define QSPI_IFCONFIG1_SPIMODE3 (1UL << 25)
#define QSPI_IFCONFIG1_SCKFREQ(n) (((n) & 0xF) << 28)

#define QSPI_CINSTRCONF_OPCODE(n) ((n) & 0xFF)
#define QSPI_CINSTRCONF_LENGTH(n) (((n) & 0xF) << 8)
#define QSPI_CINSTRCONF_WREN (1 << 15) /* send WREN opcode 0x6 before */



#endif /* !_HAL_NRF5340_H_ */
Loading

0 comments on commit 0ca4823

Please sign in to comment.