From 4e920054f9a32ad1843fb6adc48a6a94ef4fb8ff Mon Sep 17 00:00:00 2001 From: Myles Watson Date: Thu, 26 Feb 2015 15:48:38 -0800 Subject: nrf51: Add PPI wrappers Programmable Peripheral Interconnect is a shared resource. This CL adds code for allocating PPIs to devices. BUG=None BRANCH=None TEST=Modify the I2C code to use this PPI allocation code and test I2C communication (using experimental MXT touch controller code) Change-Id: I8ec27867d041982ef18e8515d6434c5de2c189c5 Signed-off-by: Myles Watson Reviewed-on: https://chromium-review.googlesource.com/361405 Commit-Ready: Myles Watson Tested-by: Myles Watson Reviewed-by: Aseda Aboagye Reviewed-by: Levi Oliver --- chip/nrf51/build.mk | 2 +- chip/nrf51/ppi.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ chip/nrf51/ppi.h | 42 ++++++++++++++++++++++++++++++ chip/nrf51/registers.h | 20 +++++++++++++++ 4 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 chip/nrf51/ppi.c create mode 100644 chip/nrf51/ppi.h (limited to 'chip') diff --git a/chip/nrf51/build.mk b/chip/nrf51/build.mk index ddfa46b078..db64c6f618 100644 --- a/chip/nrf51/build.mk +++ b/chip/nrf51/build.mk @@ -11,7 +11,7 @@ CORE:=cortex-m0 CFLAGS_CPU+=-march=armv6-m -mcpu=cortex-m0 chip-y+=gpio.o system.o uart.o -chip-y+=jtag.o watchdog.o +chip-y+=jtag.o watchdog.o ppi.o chip-$(CONFIG_COMMON_TIMER)+=hwtimer.o clock.o chip-$(CONFIG_I2C)+=i2c.o diff --git a/chip/nrf51/ppi.c b/chip/nrf51/ppi.c new file mode 100644 index 0000000000..d0be87f2ba --- /dev/null +++ b/chip/nrf51/ppi.c @@ -0,0 +1,69 @@ +/* Copyright 2016 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "ppi.h" +#include "registers.h" +#include "util.h" + +#define NRF51_PPI_FIRST_PP_CH NRF51_PPI_CH_TIMER0_CC0__RADIO_TXEN +#define NRF51_PPI_LAST_PP_CH NRF51_PPI_CH_RTC0_COMPARE0__TIMER0_START + +static uint32_t channels_in_use; +static uint32_t channel_groups_in_use; + +int ppi_request_pre_programmed_channel(int ppi_chan) +{ + ASSERT(ppi_chan >= NRF51_PPI_FIRST_PP_CH && + ppi_chan <= NRF51_PPI_LAST_PP_CH); + + if (channels_in_use & (1 << ppi_chan)) + return EC_ERROR_BUSY; + + channels_in_use |= (1 << ppi_chan); + + return EC_SUCCESS; +} + +int ppi_request_channel(int *ppi_chan) +{ + int chan; + + for (chan = 0; chan < NRF51_PPI_NUM_PROGRAMMABLE_CHANNELS; chan++) + if ((channels_in_use & (1 << chan)) == 0) + break; + + if (chan == NRF51_PPI_NUM_PROGRAMMABLE_CHANNELS) + return EC_ERROR_BUSY; + + channels_in_use |= (1 << chan); + *ppi_chan = chan; + return EC_SUCCESS; +} + +void ppi_release_channel(int ppi_chan) +{ + channels_in_use &= ~(1 << ppi_chan); +} + +void ppi_release_group(int ppi_group) +{ + channel_groups_in_use &= ~(1 << ppi_group); +} + +int ppi_request_group(int *ppi_group) +{ + int group; + + for (group = 0; group < NRF51_PPI_NUM_GROUPS; group++) + if ((channel_groups_in_use & (1 << group)) == 0) + break; + + if (group == NRF51_PPI_NUM_GROUPS) + return EC_ERROR_BUSY; + + channel_groups_in_use |= (1 << group); + *ppi_group = group; + return EC_SUCCESS; +} diff --git a/chip/nrf51/ppi.h b/chip/nrf51/ppi.h new file mode 100644 index 0000000000..bbb74a2cf0 --- /dev/null +++ b/chip/nrf51/ppi.h @@ -0,0 +1,42 @@ +/* Copyright 2016 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* + * PPI channels are a way to connect NRF51 EVENTs to TASKs without software + * involvement. They are like SHORTs, except between peripherals. + * + * PPI groups are user-defined sets of channels that can be enabled and disabled + * together. + */ + +/* + * Reserve a pre-programmed PPI channel. + * + * Return EC_SUCCESS if ppi_chan is a pre-programmed channel that was not in + * use, otherwise returns EC_ERROR_BUSY. + */ +int ppi_request_pre_programmed_channel(int ppi_chan); + +/* + * Reserve an available PPI channel. + * + * Return EC_SUCCESS and set the value of ppi_chan to an available PPI + * channel. If no channel is available, return EC_ERROR_BUSY. + */ +int ppi_request_channel(int *ppi_chan); + +/* Release a PPI channel which was reserved with ppi_request_*_channel. */ +void ppi_release_channel(int ppi_chan); + +/* + * Reserve a PPI group. + * + * Return EC_SUCCESS and set the value of ppi_group to an available PPI + * group. If no group is available, return EC_ERROR_BUSY. + */ +int ppi_request_group(int *ppi_group); + +/* Release a PPI channel which was reserved with ppi_request_*_channel. */ +void ppi_release_group(int ppi_group); diff --git a/chip/nrf51/registers.h b/chip/nrf51/registers.h index dab3a05fd1..2a010e2556 100644 --- a/chip/nrf51/registers.h +++ b/chip/nrf51/registers.h @@ -646,6 +646,26 @@ #define NRF51_PPI_TEP(channel) REG32(NRF51_PPI_BASE + 0x514 + channel*8) #define NRF51_PPI_CHG(group) REG32(NRF51_PPI_BASE + 0x800 + group*4) +#define NRF51_PPI_NUM_PROGRAMMABLE_CHANNELS 16 +#define NRF51_PPI_NUM_GROUPS 4 + +#define NRF51_PPI_CH_TIMER0_CC0__RADIO_TXEN 20 +#define NRF51_PPI_CH_TIMER0_CC0__RADIO_RXEN 21 +#define NRF51_PPI_CH_TIMER0_CC1__RADIO_DISABLE 22 +#define NRF51_PPI_CH_RADIO_BCMATCH__AAR_START 23 +#define NRF51_PPI_CH_RADIO_READY__CCM_KSGEN 24 +#define NRF51_PPI_CH_RADIO_ADDR__CCM_CRYPT 25 +#define NRF51_PPI_CH_RADIO_ADDR__TIMER0CC1 26 +#define NRF51_PPI_CH_RADIO_END_TIMER0CC2 27 +#define NRF51_PPI_CH_RTC0_COMPARE0__RADIO_TXEN 28 +#define NRF51_PPI_CH_RTC0_COMPARE0__RADIO_RXEN 29 +#define NRF51_PPI_CH_RTC0_COMPARE0__TIMER0_CLEAR 30 +#define NRF51_PPI_CH_RTC0_COMPARE0__TIMER0_START 31 + +#define NRF51_PPI_CH_FIRST NRF51_PPI_CH_TIMER0_CC0__RADIO_TXEN +#define NRF51_PPI_CH_LAST NRF51_PPI_CH_RTC0_COMPARE0__TIMER0_START + + /* These will be defined in their respective functions if/when they are used. */ #define NRF51_SPI0_BASE 0x40003000 #define NRF51_SPI0_PSELSCK REG32(NRF51_SPI0_BASE + 0x508) -- cgit v1.2.1