Skip to content

Commit

Permalink
Add code to wake spinor.
Browse files Browse the repository at this point in the history
Many PineTime payloads (currently including mcuboot) are broken if booted
with the spinor in deep powerdown. Let's wake the spinor during reloading
to avoid bugs when switching from a firmware with power down support to
one without.

The changes here are suprisingly large because we have to refactor the
existing spi code to untangle it from the st7789 driver.

Signed-off-by: Daniel Thompson <[email protected]>
  • Loading branch information
daniel-thompson committed Nov 7, 2020
1 parent 819713d commit cdd5e76
Show file tree
Hide file tree
Showing 10 changed files with 167 additions and 58 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.*.swp
build-*/
src/boards/*/bootloader.h
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ LDFLAGS += $(CFLAGS) -Wl,-Map=$(OBJDIR)/reloader.map -Lsrc -Llib/nrfx/mdk -T$(LD
APP = $(OBJDIR)/reloader.zip
OBJS = main.o \
flash.o \
spi.o \
spinor.o \
st7789.o \
wdt.o \
nrfx_nvmc.o \
Expand Down
3 changes: 3 additions & 0 deletions src/boards/pinetime/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@
#define CONFIG_WDT_BUTTON_PULL (0) // no pull up/down
#define CONFIG_WDT_BUTTON_ENABLE (15)

#define CONFIG_HAVE_SPINOR (1)
#define CONFIG_SPINOR_CS (5)

#endif /* RELOADER_BOARD_PINETIME_H__ */
15 changes: 14 additions & 1 deletion src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#include "board.h"
#include "flash.h"
#include "spi.h"
#include "spinor.h"
#include "st7789.h"
#include "util.h"
#include "wdt.h"
Expand Down Expand Up @@ -44,10 +46,21 @@ int main()
wdt_init();

#ifdef CONFIG_ST7789
st7789_init();
st7789_preinit();
#else
nrf_gpio_cfg_output(CONFIG_USR_LED);
#endif
#ifdef CONFIG_HAVE_SPINOR
spinor_preinit();
#endif

spi_init();
#ifdef CONFIG_ST7789
st7789_init();
#endif
#ifdef CONFIG_HAVE_SPINOR
spinor_init();
#endif

flash_all();
reboot();
Expand Down
64 changes: 64 additions & 0 deletions src/spi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* SPDX-License-Identifier: LGPL-3.0-or-later
* Copyright (C) 2020 Daniel Thompson
*/

#include "spi.h"

#include <nrf_gpio.h>
#include <nrf_spi.h>

#define SPIx NRF_SPI0
#define SPI_MODE NRF_SPI_MODE_3
#define SPI_SCK 2
#define SPI_MOSI 3

void spi_init(void)
{
nrf_gpio_pin_write(SPI_SCK, SPI_MODE >= 2);
nrf_gpio_cfg(SPI_SCK, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_CONNECT,
NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_S0S1, NRF_GPIO_PIN_NOSENSE);
nrf_gpio_pin_clear(SPI_MOSI);
nrf_gpio_cfg_output(SPI_MOSI);


nrf_spi_pins_set(SPIx, SPI_SCK, SPI_MOSI, NRF_SPI_PIN_NOT_CONNECTED);
nrf_spi_frequency_set(SPIx, NRF_SPI_FREQ_8M);
nrf_spi_configure(SPIx, SPI_MODE, NRF_SPI_BIT_ORDER_MSB_FIRST);

nrf_spi_enable(SPIx);
}

void spi_teardown(void)
{
/* no need to tear down SCK and MOSI - output pins can be left alone */
nrf_spi_event_clear(SPIx, NRF_SPI_EVENT_READY);
nrf_spi_disable(SPIx);
nrf_gpio_cfg_default(SPI_MOSI);
nrf_gpio_cfg_default(SPI_SCK);
}

void spi_write(const uint8_t *data, unsigned len)
{
const uint8_t *endp = data + len;

/* paranoid... but worthwhile due to the havoc this could cause */
nrf_spi_event_clear(SPIx, NRF_SPI_EVENT_READY);

/* send first character */
nrf_spi_txd_set(SPIx, *data++);

/* TXD is double buffers so we can xmit and then poll for the event */
while (data < endp) {
nrf_spi_txd_set(SPIx, *data++);

while (!nrf_spi_event_check(SPIx, NRF_SPI_EVENT_READY)) {}
nrf_spi_event_clear(SPIx, NRF_SPI_EVENT_READY);
(void) nrf_spi_rxd_get(SPIx);
}

/* wait for the final character */
while (!nrf_spi_event_check(SPIx, NRF_SPI_EVENT_READY)) {}
nrf_spi_event_clear(SPIx, NRF_SPI_EVENT_READY);
(void) nrf_spi_rxd_get(SPIx);
}
15 changes: 15 additions & 0 deletions src/spi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* SPDX-License-Identifier: LGPL-3.0-or-later
* Copyright (C) 2020 Daniel Thompson
*/

#ifndef RELOADER_SPI_H__
#define RELOADER_SPI_H__

#include <stdint.h>

void spi_init(void);
void spi_teardown(void);
void spi_write(const uint8_t *data, unsigned len);

#endif /* RELOADER_SPI_H__ */
43 changes: 43 additions & 0 deletions src/spinor.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* SPDX-License-Identifier: LGPL-3.0-or-later
* Copyright (C) 2020 Daniel Thompson
*/

#include "spinor.h"

#include <nrf_gpio.h>

#include "board.h"
#include "spi.h"

#ifdef CONFIG_HAVE_SPINOR

uint32_t spinor_page_size_get(void)
{
return 0;
}

int spinor_page_erase(uint32_t addr)
{
return -1;
}

void spinor_word_write(uint32_t addr, uint32_t value)
{
}

void spinor_preinit(void)
{
nrf_gpio_pin_set(CONFIG_SPINOR_CS);
nrf_gpio_cfg_output(CONFIG_SPINOR_CS);
}

void spinor_init(void)
{
/* release deep power-down (RDP) */
nrf_gpio_pin_clear(CONFIG_SPINOR_CS);
spi_write((const uint8_t*) "\xab", 1);
nrf_gpio_pin_set(CONFIG_SPINOR_CS);
}

#endif /* CONFIG_HAVE_SPINOR */
17 changes: 17 additions & 0 deletions src/spinor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* SPDX-License-Identifier: LGPL-3.0-or-later
* Copyright (C) 2020 Daniel Thompson
*/

#ifndef RELOADER_SPINOR_H__
#define RELOADER_SPINOR_H__

#include <stdint.h>

uint32_t spinor_page_size_get(void);
int spinor_page_erase(uint32_t addr);
void spinor_word_write(uint32_t addr, uint32_t value);
void spinor_preinit(void);
void spinor_init(void);

#endif /* RELOADER_SPINOR_H__ */
64 changes: 7 additions & 57 deletions src/st7789.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,77 +3,25 @@
* Copyright (C) 2020 Daniel Thompson
*/

#include "st7789.h"

#include <string.h>

#include <nrf_gpio.h>
#include <nrf_spi.h>

#include "board.h"
#include "st7789.h"
#include "spi.h"

#ifndef CONFIG_ST7789_BACKLIGHT
#define CONFIG_ST7789_BACKLIGHT 14
#endif

#define SPIx NRF_SPI0
#define SPI_MODE NRF_SPI_MODE_3
#define SPI_SCK 2
#define SPI_MOSI 3
#define DISP_SS 25
#define DISP_DC 18
#define DISP_RESET 26
#define BACKLIGHT CONFIG_ST7789_BACKLIGHT /* lowest level */

static void spi_init(void)
{
nrf_gpio_pin_write(SPI_SCK, SPI_MODE >= 2);
nrf_gpio_cfg(SPI_SCK, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_CONNECT,
NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_S0S1, NRF_GPIO_PIN_NOSENSE);
nrf_gpio_pin_clear(SPI_MOSI);
nrf_gpio_cfg_output(SPI_MOSI);


nrf_spi_pins_set(SPIx, SPI_SCK, SPI_MOSI, NRF_SPI_PIN_NOT_CONNECTED);
nrf_spi_frequency_set(SPIx, NRF_SPI_FREQ_8M);
nrf_spi_configure(SPIx, SPI_MODE, NRF_SPI_BIT_ORDER_MSB_FIRST);

nrf_spi_enable(SPIx);
}

static void spi_teardown(void)
{
/* no need to tear down SCK and MOSI - output pins can be left alone */
nrf_spi_event_clear(SPIx, NRF_SPI_EVENT_READY);
nrf_spi_disable(SPIx);
nrf_gpio_cfg_default(SPI_MOSI);
nrf_gpio_cfg_default(SPI_SCK);
}

static void spi_write(const uint8_t *data, unsigned len)
{
const uint8_t *endp = data + len;

/* paranoid... but worthwhile due to the havoc this could cause */
nrf_spi_event_clear(SPIx, NRF_SPI_EVENT_READY);

/* send first character */
nrf_spi_txd_set(SPIx, *data++);

/* TXD is double buffers so we can xmit and then poll for the event */
while (data < endp) {
nrf_spi_txd_set(SPIx, *data++);

while (!nrf_spi_event_check(SPIx, NRF_SPI_EVENT_READY)) {}
nrf_spi_event_clear(SPIx, NRF_SPI_EVENT_READY);
(void) nrf_spi_rxd_get(SPIx);
}

/* wait for the final character */
while (!nrf_spi_event_check(SPIx, NRF_SPI_EVENT_READY)) {}
nrf_spi_event_clear(SPIx, NRF_SPI_EVENT_READY);
(void) nrf_spi_rxd_get(SPIx);
}

#define NOP 0x00
#define SWRESET 0x01
#define SLPOUT 0x11
Expand Down Expand Up @@ -276,12 +224,14 @@ void st7789_state(int percent_complete)
}
}

void st7789_init(void)
void st7789_preinit(void)
{
nrf_gpio_pin_set(DISP_SS);
nrf_gpio_cfg_output(DISP_SS);
spi_init();
}

void st7789_init(void)
{
nrf_gpio_cfg_output(DISP_DC);

/* deliver a reset */
Expand Down
1 change: 1 addition & 0 deletions src/st7789.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ enum {
};

void st7789_state(int state);
void st7789_preinit(void);
void st7789_init(void);
void st7789_teardown(void);

Expand Down

0 comments on commit cdd5e76

Please sign in to comment.