Skip to content

Commit

Permalink
Merge pull request #1 from bosmoment/work/pinetime
Browse files Browse the repository at this point in the history
Pull bosmoment/RIOT
  • Loading branch information
j-devel authored Oct 7, 2020
2 parents 5d940af + bfe228c commit 0361105
Show file tree
Hide file tree
Showing 49 changed files with 1,862 additions and 62 deletions.
4 changes: 4 additions & 0 deletions boards/pinetime/Makefile.dep
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
DEFAULT_MODULE += stdio_rtt

ifneq (,$(filter mtd,$(USEMODULE)))
USEMODULE += mtd_spi_nor
endif

# include common nrf52 dependencies
include $(RIOTBOARD)/common/nrf52/nrf52832/Makefile.dep
include $(RIOTBOARD)/common/nrf52/Makefile.dep
23 changes: 23 additions & 0 deletions boards/pinetime/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,30 @@

#include "cpu.h"
#include "board.h"
#include "mtd.h"
#include "mtd_spi_nor.h"
#include "periph/gpio.h"
#include "periph/spi.h"

#ifdef MODULE_MTD
static mtd_spi_nor_t pinetime_nor_dev = {
.base = {
.driver = &mtd_spi_nor_driver,
.page_size = PINETIME_NOR_PAGE_SIZE,
.pages_per_sector = PINETIME_NOR_PAGES_PER_SECTOR,
.sector_count = PINETIME_NOR_SECTOR_COUNT,
},
.flag = PINETIME_NOR_FLAGS,
.opcode = &mtd_spi_nor_opcode_default,
.spi = PINETIME_NOR_SPI_DEV,
.cs = PINETIME_NOR_SPI_CS,
.addr_width = 3,
.mode = PINETIME_NOR_SPI_MODE,
.clk = PINETIME_NOR_SPI_CLK,
};

mtd_dev_t *mtd0 = (mtd_dev_t *)&pinetime_nor_dev;
#endif /* MODULE_MTD */

void board_init(void)
{
Expand Down
23 changes: 23 additions & 0 deletions boards/pinetime/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include "cpu.h"
#include "board_common.h"
#include "mtd.h"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -66,6 +67,28 @@ extern "C" {
#define ILI9341_PARAM_NUM_LINES 240U
/** @} */

/**
* @name PineTime NOR flash hardware configuration
* @{
*/
#define PINETIME_NOR_PAGE_SIZE (256)
#define PINETIME_NOR_PAGES_PER_SECTOR (16)
#define PINETIME_NOR_SECTOR_COUNT (2048)
#define PINETIME_NOR_FLAGS (SPI_NOR_F_SECT_4K | SPI_NOR_F_SECT_32K)
#define PINETIME_NOR_SPI_DEV SPI_DEV(0)
#define PINETIME_NOR_SPI_CLK SPI_CLK_10MHZ
#define PINETIME_NOR_SPI_CS GPIO_PIN(0, 5)
#define PINETIME_NOR_SPI_MODE SPI_MODE_3
/** @} */

/**
* @name MTD configuration
*/
/** @{ */
extern mtd_dev_t *mtd0;
#define MTD_0 mtd0
/** @} */

#ifdef __cplusplus
}
#endif
Expand Down
136 changes: 134 additions & 2 deletions cpu/nrf5x_common/periph/spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,40 @@
*
* @}
*/
#include <stdio.h>
#include <string.h>

#include "cpu.h"
#include "mutex.h"
#include "assert.h"
#include "periph/spi.h"
#include "periph/gpio.h"

#define SPI_CPU_FLASH_END (CPU_FLASH_BASE + FLASHPAGE_NUMOF * FLASHPAGE_SIZE)

#define THREAD_FLAG_SPI_BUS (1<<10)

/**
* @brief array holding one pre-initialized mutex for each SPI device
*/
static mutex_t locks[SPI_NUMOF];
static kernel_pid_t pid[SPI_NUMOF];

static uint8_t _mbuf[SPI_NUMOF][UINT8_MAX];

static void _setup_workaround_for_ftpan_58(spi_t bus);

#ifdef CFU_FAM_NRF51
static inline NRF_SPI_Type *dev(spi_t bus)
{
return spi_config[bus].dev;
}
#else
static inline NRF_SPIM_Type *dev(spi_t bus)
{
return (NRF_SPIM_Type *)spi_config[bus].dev;
}
#endif

void spi_init(spi_t bus)
{
Expand All @@ -45,6 +63,7 @@ void spi_init(spi_t bus)
mutex_init(&locks[bus]);
/* initialize pins */
spi_init_pins(bus);
NVIC_EnableIRQ(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQn);
}

void spi_init_pins(spi_t bus)
Expand All @@ -54,9 +73,17 @@ void spi_init_pins(spi_t bus)
gpio_init(spi_config[bus].mosi, GPIO_OUT);
gpio_init(spi_config[bus].miso, GPIO_IN);
/* select pins for the SPI device */
#ifdef CPU_FAM_NRF51
SPI_SCKSEL = spi_config[bus].sclk;
SPI_MOSISEL = spi_config[bus].mosi;
SPI_MISOSEL = spi_config[bus].miso;
#else
dev(bus)->PSEL.SCK = spi_config[bus].sclk;
dev(bus)->PSEL.MOSI = spi_config[bus].mosi;
dev(bus)->PSEL.MISO = spi_config[bus].miso;

_setup_workaround_for_ftpan_58(bus);
#endif
}

int spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk)
Expand All @@ -72,8 +99,11 @@ int spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk)
dev(bus)->CONFIG = mode;
dev(bus)->FREQUENCY = clk;
/* enable the bus */
#ifdef CPU_FAM_NRF51
dev(bus)->ENABLE = 1;

#else
dev(bus)->ENABLE = SPIM_ENABLE_ENABLE_Enabled;
#endif
return SPI_OK;
}

Expand All @@ -87,6 +117,72 @@ void spi_release(spi_t bus)
mutex_unlock(&locks[bus]);
}

#ifndef CPU_FAM_NRF51
/**
* @brief Work-around for transmitting 1 byte with SPIM.
*
* @param spim: The SPIM instance that is in use.
* @param ppi_channel: An unused PPI channel that will be used by the workaround.
* @param gpiote_channel: An unused GPIOTE channel that will be used by the workaround.
*
* @warning Must not be used when transmitting multiple bytes.
* @warning After this workaround is used, the user must reset the PPI channel and the GPIOTE channel before attempting to transmit multiple bytes.
*/
static void _setup_workaround_for_ftpan_58(spi_t bus)
{
// Create an event when SCK toggles.
NRF_GPIOTE->CONFIG[bus + 7] = (
GPIOTE_CONFIG_MODE_Event <<
GPIOTE_CONFIG_MODE_Pos
) | (
spi_config[bus].sclk <<
GPIOTE_CONFIG_PSEL_Pos
) | (
GPIOTE_CONFIG_POLARITY_Toggle <<
GPIOTE_CONFIG_POLARITY_Pos
);

// Stop the spim instance when SCK toggles.
NRF_PPI->CH[bus].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[bus + 7];
NRF_PPI->CH[bus].TEP = (uint32_t)&dev(bus)->TASKS_STOP;
}

static void _enable_workaround(spi_t bus)
{
NRF_PPI->CHENSET = 1U << bus;
// The spim instance cannot be stopped mid-byte, so it will finish
// transmitting the first byte and then stop. Effectively ensuring
// that only 1 byte is transmitted.
}

static void _clear_workaround(spi_t bus)
{
NRF_PPI->CHENCLR = 1U << bus;
}

static void _transfer(spi_t bus, const uint8_t *out_buf, uint8_t *in_buf, uint8_t transfer_len)
{
uint8_t out_len = (out_buf) ? transfer_len : 0;
uint8_t in_len = (in_buf) ? transfer_len : 0;
const uint8_t *out_mbuf = out_buf;
if ((out_buf < (uint8_t*)SPI_CPU_FLASH_END) && (out_len)) {
memcpy(_mbuf[bus], out_buf, out_len);
out_mbuf = _mbuf[bus];
}
dev(bus)->TXD.PTR = (uint32_t)out_mbuf;
dev(bus)->RXD.PTR = (uint32_t)in_buf;

dev(bus)->TXD.MAXCNT = out_len;
dev(bus)->RXD.MAXCNT = in_len;

dev(bus)->EVENTS_END = 0;

dev(bus)->TASKS_START = 1;
}
#endif



void spi_transfer_bytes(spi_t bus, spi_cs_t cs, bool cont,
const void *out, void *in, size_t len)
{
Expand All @@ -98,7 +194,7 @@ void spi_transfer_bytes(spi_t bus, spi_cs_t cs, bool cont,
if (cs != SPI_CS_UNDEF) {
gpio_clear((gpio_t)cs);
}

#ifdef CPU_FAM_NRF51
for (int i = 0; i < (int)len; i++) {
uint8_t tmp = (out_buf) ? out_buf[i] : 0;

Expand All @@ -111,8 +207,44 @@ void spi_transfer_bytes(spi_t bus, spi_cs_t cs, bool cont,
in_buf[i] = tmp;
}
}
#else
dev(bus)->RXD.LIST = 0;
dev(bus)->TXD.LIST = 0;

if (len == 1) {
_enable_workaround(bus);
_transfer(bus, out_buf, in_buf, len);
while (dev(bus)->EVENTS_END != 1);
_clear_workaround(bus);
}
else {
// Enable IRQ
dev(bus)->EVENTS_END = 0;
pid[bus] = sched_active_pid;
dev(bus)->INTENSET = SPIM_INTENSET_END_Msk;
do {
size_t transfer_len = len > UINT8_MAX ? UINT8_MAX : len;
_transfer(bus, out_buf, in_buf, transfer_len);
thread_flags_wait_one(THREAD_FLAG_SPI_BUS);
out_buf += out_buf ? transfer_len : 0;
in_buf += in_buf? transfer_len : 0;
len -= transfer_len;
} while (len);
dev(bus)->INTENCLR = SPIM_INTENCLR_END_Msk;
}
#endif

if ((cs != SPI_CS_UNDEF) && (!cont)) {
gpio_set((gpio_t)cs);
}
}

#ifndef CPU_FAM_NRF51
/* TODO: rework to allow arbitrary SPI peripheral order */
void isr_spi0_twi0(void)
{
thread_flags_set((thread_t*)thread_get(pid[0]), THREAD_FLAG_SPI_BUS);
dev(0)->EVENTS_END = 0;
cortexm_isr_end();
}
#endif
18 changes: 18 additions & 0 deletions drivers/Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@ ifneq (,$(filter ccs811,$(USEMODULE)))
USEMODULE += xtimer
endif

ifneq (,$(filter cst816s,$(USEMODULE)))
FEATURES_REQUIRED += periph_gpio_irq
FEATURES_REQUIRED += periph_gpio
FEATURES_REQUIRED += periph_i2c
USEMODULE += xtimer
endif

ifneq (,$(filter dcf77,$(USEMODULE)))
FEATURES_REQUIRED += periph_gpio
FEATURES_REQUIRED += periph_gpio_irq
Expand Down Expand Up @@ -709,10 +716,21 @@ ifneq (,$(filter ws281x,$(USEMODULE)))
USEMODULE += xtimer
endif

ifneq (,$(filter lis3mdl,$(USEMODULE)))
FEATURES_REQUIRED += periph_i2c
USEMODULE += xtimer
endif

ifneq (,$(filter xbee,$(USEMODULE)))
FEATURES_REQUIRED += periph_uart
FEATURES_REQUIRED += periph_gpio
USEMODULE += ieee802154
USEMODULE += xtimer
USEMODULE += netif
endif

ifneq (,$(filter xpt2046,$(USEMODULE)))
FEATURES_REQUIRED += periph_gpio
FEATURES_REQUIRED += periph_gpio_irq
FEATURES_REQUIRED += periph_spi
endif
8 changes: 8 additions & 0 deletions drivers/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ ifneq (,$(filter ccs811,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/ccs811/include
endif

ifneq (,$(filter cst816s,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/cst816s/include
endif

ifneq (,$(filter dcf77,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/dcf77/include
endif
Expand Down Expand Up @@ -363,3 +367,7 @@ endif
ifneq (,$(filter xbee,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/xbee/include
endif

ifneq (,$(filter xpt2046,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/xpt2046/include
endif
1 change: 1 addition & 0 deletions drivers/cst816s/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base
Loading

0 comments on commit 0361105

Please sign in to comment.