diff options
author | Myles Watson <mylesgw@chromium.org> | 2015-02-26 15:48:38 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-07-20 22:22:06 -0700 |
commit | 4e920054f9a32ad1843fb6adc48a6a94ef4fb8ff (patch) | |
tree | 87ea77c8836c62685aff660458c96d1911efb7e1 /chip | |
parent | 1e53ce006cf1b58ec3a74af05c975255967de320 (diff) | |
download | chrome-ec-4e920054f9a32ad1843fb6adc48a6a94ef4fb8ff.tar.gz |
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 <mylesgw@google.com>
Reviewed-on: https://chromium-review.googlesource.com/361405
Commit-Ready: Myles Watson <mylesgw@chromium.org>
Tested-by: Myles Watson <mylesgw@chromium.org>
Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
Reviewed-by: Levi Oliver <levio@google.com>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/nrf51/build.mk | 2 | ||||
-rw-r--r-- | chip/nrf51/ppi.c | 69 | ||||
-rw-r--r-- | chip/nrf51/ppi.h | 42 | ||||
-rw-r--r-- | chip/nrf51/registers.h | 20 |
4 files changed, 132 insertions, 1 deletions
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) |