arch/arm/src/lpc54xx: Add support for a random number generator.

This commit is contained in:
Gregory Nutt 2017-12-26 10:20:41 -06:00
parent 0b91074850
commit edef041f93
7 changed files with 325 additions and 3 deletions

View File

@ -406,8 +406,13 @@ config LPC54_LCD
default n
depends on ARCH_LPC54_HAVE_LCD
config LPC54_RNG
bool "Random Number Generator (RNG)"
default n
select ARCH_HAVE_RNG
config LPC54_RTC
bool "RTC"
bool "Real Time Clock (RTC)"
default n
select RTC

View File

@ -116,6 +116,10 @@ ifeq ($(CONFIG_LPC54_WWDT),y)
CHIP_CSRCS += lpc54_wwdt.c
endif
ifeq ($(CONFIG_LPC54_RNG),y)
CHIP_CSRCS += lpc54_rng.c
endif
ifeq ($(CONFIG_LPC54_HAVE_USART),y)
CHIP_CSRCS += lpc54_serial.c
endif

View File

@ -70,6 +70,10 @@
#define LPC54_DRAMCS3_BASE 0xb8000000 /* Dynamic memory chip select 3 (<=256MB) */
#define LPC54_CORTEXM4_BASE 0xe0000000 /* Cortex-M4 Private Peripheral Bus */
/* ROM Driver Table */
#define LPC54_ROM_DRIVERTAB 0x03000200 /* Beginning of the ROM driver table */
/* AHB Peripherals */
#define LPC54_SPIFI_BASE 0x40080000 /* SPIFI registers */

View File

@ -0,0 +1,113 @@
/********************************************************************************************
* arch/arm/src/lpc54xx/lpc54_rom.h
*
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
********************************************************************************************/
#ifndef __ARCH_ARM_SRC_LPC54XX_CHIP_LPC54_ROM_H
#define __ARCH_ARM_SRC_LPC54XX_CHIP_LPC54_ROM_H
/********************************************************************************************
* Included Files
********************************************************************************************/
#include <nuttx/config.h>
#include "chip/lpc54_memorymap.h"
/********************************************************************************************
* Pre-processor Definitions
********************************************************************************************/
/* Table offsets ****************************************************************************/
/* First level table offsets */
#define LPC54_USB_API_OFFSET 0x0000
#define LPC54_OTP_API_OFFSET 0x0038
/* USB API table offsets (to be provided) */
/* OTP API driver table offsets */
#define LPC54_OTP_API_INIT_OFFSET 0x0000
#define LPC54_OTP_API_ENABLEBANKWRITEMASK_OFFSET 0x0004
#define LPC54_OTP_API_DISABLEBANKWRITEMASK_OFFSET 0x0008
#define LPC54_OTP_API_ENABLEBANKWRITELOCK_OFFSET 0x000c
#define LPC54_OTP_API_ENABLEBANKREADLOCK_OFFSET 0x0010
#define LPC54_OTP_API_PROGRAMREG_OFFSET 0x0014
#define LPC54_OTP_API_RNGREAD_OFFSET 0x002c
#define LPC54_OTP_API_GETDRIVERVERSION_OFFSET 0x0030
/********************************************************************************************
* Public Data
********************************************************************************************/
/* Dereference the LPC54_ROM_DRIVERTAB address to get the address of the ROM driver table.
* Not often that I get to use a pointer-to-a-pointer-to-a-pointer. The result of de-
* referencing the LPC54_ROM_DRIVERTAB is a pointer to an array of type uinptr_t *.
*/
#define lpc54_driver_vtable (*(uintptr_t ***)LPC54_ROM_DRIVERTAB)
/* Index the ROM driver table to get the specific driver table. Perhaps in the future these
* uintptr_t * arrays would be replaced with proper vtable structures.
*/
#define lpc54_usb_vtable lpc54_driver_vtable[LPC54_USB_API_OFFSET >> 2]
#define lpc54_otg_vtable lpc54_driver_vtable[LPC54_OTP_API_OFFSET >> 2]
/* Then, finally, index the specific driver table to get the API entry point */
/********************************************************************************************
* Public Types/Functions
********************************************************************************************/
/********************************************************************************************
* Name: lpc54_rng_read
*
* Description:
* Returns a 32 bit random number from hardware. The Random Number Generator is accessed
* through an API call located in the ROM.
*
* Input Parameters:
* None
*
* Returned Value:
* Unsigned random number
*
********************************************************************************************/
typedef CODE unsigned int (*rng_read_t)(void);
#define LPC54_RNG_READ ((rng_read_t)(lpc54_otg_vtable[LPC54_OTP_API_RNGREAD_OFFSET >> 2]))
#endif /* __ARCH_ARM_SRC_LPC54XX_CHIP_LPC54_ROM_H */

View File

@ -0,0 +1,193 @@
/****************************************************************************
* arch/arm/src/lpc54xx/lpc54_rng.c
*
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <nuttx/irq.h>
#include <nuttx/semaphore.h>
#include <nuttx/fs/fs.h>
#include <nuttx/drivers/drivers.h>
#include "chip/lpc54_rom.h"
#if defined(CONFIG_LPC54_RNG)
#if defined(CONFIG_DEV_RANDOM) || defined(CONFIG_DEV_URANDOM_ARCH)
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static ssize_t lpc54_read(struct file *filep, char *buffer, size_t);
/****************************************************************************
* Private Types
****************************************************************************/
struct rng_dev_s
{
sem_t rd_devsem; /* Threads can only exclusively access the RNG */
};
/****************************************************************************
* Private Data
****************************************************************************/
static struct rng_dev_s g_rngdev;
static const struct file_operations g_rngops =
{
NULL, /* open */
NULL, /* close */
lpc54_read, /* read */
NULL, /* write */
NULL, /* seek */
NULL /* ioctl */
#ifndef CONFIG_DISABLE_POLL
, NULL /* poll */
#endif
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
, NULL /* unlink */
#endif
};
/****************************************************************************
* Private functions
****************************************************************************/
/****************************************************************************
* Name: lpc54_read
****************************************************************************/
static ssize_t lpc54_read(struct file *filep, char *buffer, size_t buflen)
{
union
{
uint32_t w;
uint8_t b[4];
} value;
ssize_t remaining;
int ret;
int i;
/* Get exclusive access to ROM random number generator API */
ret = nxsem_wait(&g_rngdev.rd_devsem);
if (ret < 0)
{
return ret;
}
/* Copy the requested number of randome bytes. */
for (remaining = buflen; remaining > 0;)
{
/* Read the next 32-bit random value */
value.w = LPC54_RNG_READ();
/* Return byte at a time to avoid alignment complexities (but
* sacrificing some performance).
*/
for (i = 0; i < sizeof(uint32_t) && remaining > 0; i++, remaining--)
{
*buffer++ = value.b[i];
}
}
nxsem_post(&g_rngdev.rd_devsem);
return buflen;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: devrandom_register
*
* Description:
* Initialize the RNG hardware and register the /dev/random driver.
* Must be called BEFORE devurandom_register.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_DEV_RANDOM
void devrandom_register(void)
{
nxsem_init(&g_rngdev.rd_devsem, 0, 1);
(void)register_driver("/dev/random", &g_rngops, 0444, NULL);
}
#endif
/****************************************************************************
* Name: devurandom_register
*
* Description:
* Register /dev/urandom
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_DEV_URANDOM_ARCH
void devurandom_register(void)
{
#ifndef CONFIG_DEV_RANDOM
nxsem_init(&g_rngdev.rd_devsem, 0, 1);
#endif
(void)register_driver("/dev/urandom", &g_rngops, 0444, NULL);
}
#endif
#endif /* CONFIG_DEV_RANDOM || CONFIG_DEV_URANDOM_ARCH */
#endif /* CONFIG_LPC54_RNG */

View File

@ -147,8 +147,6 @@ static int lpc54_rtc_interrupt(int irq, void *context, FAR void *arg)
int up_rtc_initialize(void)
{
uint32_t regval;
/* Enable the clock to the RTC register interface and peripheral clock. */
lpc54_rtc_enableclk();

View File

@ -75,6 +75,11 @@ STATUS
non-functional without some additional investment.
2017-12-25: Added an RTC driver. It appears to be functional but has not
been well tested.
2017-12-26: Added an RNG driver. The RNG is actually controlled by a ROM
function. This driver seems to work fine when single stepping. However,
if I collect samples indefinitely, I do a reserved interrupt. I suspect
that to use the ROM at high frequencies it may be necessary to modify the
ROM access timing in some way.
There is still no support for the Accelerometer, SPIFI, Ethernet, or USB.
There is a complete, but not-yet-functional SD card drirver. There is a