Squashed commit of the following:
commit f5080f53516a853408dd80f09f85e1d1c139133f Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jun 17 12:24:22 2019 -0600 arch/z80/src/ez80/ez80_spi.c: SPI driver still does not work. But the driver now has timeouts so that at least it does not hang the system on startup. commit 5241e9ae643981c43c8c7fa8478a01d0c2e17eb0 Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jun 17 10:45:11 2019 -0600 arch/z80/src/ez80: Fixes to SPI baud rate calculation. commit ce2e9e3703485563a0a5b6a57e4080ad45d91fd7 Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jun 17 09:29:13 2019 -0600 arch/z80/src/ez80: Cosmetic and unnecessary clean-up or serial driver. commit 77287c8508a7e3262068d3e8cf1c5f8e27f3a144 Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jun 17 09:08:56 2019 -0600 arch/z80/src/common and arch/z80/src/ez80: Clean up some assertion-related logic. commit 4d2d3594c22f7240119255825fce2d2437301404 Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jun 17 07:48:21 2019 -0600 configs/makerlisp/nsh/defconfig: Enable STACKDUMP on assertion. commit 76b7a2faa3f213dd26634dd9440d12f746cac097 Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jun 17 07:47:55 2019 -0600 configs/makerlisp/include/board.h: Don't put the board in reset on a simple assertion, onlhy a full panic. commit 0a0dc12edcd39c07696769cb7249d8c39a148ccc Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jun 17 07:46:54 2019 -0600 arch/z80/src/ez80/ez80_rtc_lowerhalf.c: Remove all references to alarm ID. commit 1a4dba1075fcf6466e87520a8ba66bbf91d696d7 Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jun 17 07:33:29 2019 -0600 configs/makerlisp/src/ez80_bringup.c: Fix an error that was causing MMC/SD to fail to initialize. Unfortunately now the system hangs. commit 145a395c7a8e73336fe62caf803d108c59e306a5 Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jun 17 07:32:50 2019 -0600 arch/z80/src/ez80: Add an RTC lower half driver. Initial commit is just the STM32 RTC lower half with name changes.
This commit is contained in:
parent
eacdfa0f73
commit
7aa8039179
@ -190,7 +190,7 @@ void up_assert(void)
|
||||
(void)syslog_flush();
|
||||
|
||||
#ifdef CONFIG_BOARD_CRASHDUMP
|
||||
board_crashdump(up_getsp(), running_task(), filename, lineno);
|
||||
board_crashdump(Z80_getsp(), running_task(), filename, lineno);
|
||||
#endif
|
||||
|
||||
_up_assert(EXIT_FAILURE);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* arch/z80/src/common/up_stackdump.c
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2016 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2016, 2019 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -49,29 +49,24 @@
|
||||
#ifdef CONFIG_ARCH_STACKDUMP
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_getsp
|
||||
****************************************************************************/
|
||||
#warning TO BE PROVIDED
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_stackdump
|
||||
****************************************************************************/
|
||||
|
||||
static void up_stackdump(void)
|
||||
void up_stackdump(void)
|
||||
{
|
||||
struct tcb_s *rtcb = this_task();
|
||||
uint16_t sp = up_getsp();
|
||||
uint16_t stack_base = (uint16_t)rtcb->adj_stack_ptr;
|
||||
uint16_t stack_size = (uint16_t)rtcb->adj_stack_size;
|
||||
uint16_t stack;
|
||||
FAR struct tcb_s *rtcb = this_task();
|
||||
uintptr_t sp = z80_getsp();
|
||||
uintptr_t stack_base = (uintptr_t)rtcb->adj_stack_ptr;
|
||||
uintptr_t stack_size = (uintptr_t)rtcb->adj_stack_size;
|
||||
uintptr_t stack;
|
||||
|
||||
_alert("stack_base: %04x\n", stack_base);
|
||||
_alert("stack_size: %04x\n", stack_size);
|
||||
_alert("sp: %04x\n", sp);
|
||||
_alert("stack_base: %06x\n", stack_base);
|
||||
_alert("stack_size: %06x\n", stack_size);
|
||||
_alert("sp: %06x\n", sp);
|
||||
|
||||
if (sp >= stack_base || sp < stack_base - stack_size)
|
||||
{
|
||||
@ -83,12 +78,17 @@ static void up_stackdump(void)
|
||||
stack = sp;
|
||||
}
|
||||
|
||||
for (stack = stack & ~0x0f; stack < stack_base; stack += 8*sizeof(uint16_t))
|
||||
for (stack = stack & ~0x0f; stack < stack_base; stack += 16)
|
||||
{
|
||||
uint16_t *ptr = (uint16_t*)stack;
|
||||
_alert("%04x: %04x %04x %04x %04x %04x %04x %04x %04x\n",
|
||||
stack, ptr[0], ptr[1], ptr[2], ptr[3],
|
||||
ptr[4], ptr[5], ptr[6], ptr[7]);
|
||||
FAR uint8_t *ptr = (FAR uint8_t*)stack;
|
||||
|
||||
_alert("%06x: %02x %02x %02x %02x %02x %02x %02x %02x ",
|
||||
"%02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
stack,
|
||||
ptr[0], ptr[1], ptr[2], ptr[3],
|
||||
ptr[4], ptr[5], ptr[6], ptr[7],
|
||||
ptr[8], ptr[9], ptr[10], ptr[11],
|
||||
ptr[12], ptr[13], ptr[14], ptr[15]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ int up_multicastfilter(FAR struct net_driver_s *dev, FAR uint8_t *mac, bool enab
|
||||
|
||||
/* Return the current value of the stack pointer (used in stack dump logic) */
|
||||
|
||||
uint16_t up_getsp(void);
|
||||
uintptr_t z80_getsp(void);
|
||||
|
||||
/* Dump stack and registers */
|
||||
|
||||
|
@ -44,16 +44,29 @@ CMN_CSRCS += up_reprioritizertr.c up_idle.c up_assert.c z80_doirq.c
|
||||
CMN_CSRCS += up_mdelay.c up_stackframe.c up_udelay.c up_usestack.c
|
||||
CMN_CSRCS += up_puts.c
|
||||
|
||||
ifeq ($(CONFIG_ARCH_STACKDUMP),y)
|
||||
CMN_CSRCS += up_stackdump.c
|
||||
endif
|
||||
|
||||
CHIP_ASRCS = ez80_startup.asm ez80_io.asm ez80_irqsave.asm
|
||||
CHIP_ASRCS += ez80_saveusercontext.asm ez80_restorecontext.asm
|
||||
|
||||
ifeq ($(CONFIG_ARCH_CHIP_EZ80F91),y)
|
||||
CHIP_ASRCS += ez80f91_init.asm
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_STACKDUMP),y)
|
||||
CHIP_ASRCS += ez80_getsp.asm
|
||||
endif
|
||||
|
||||
CHIP_SSRCS =
|
||||
CHIP_CSRCS = ez80_clock.c ez80_initialstate.c ez80_irq.c ez80_copystate.c
|
||||
CHIP_CSRCS += ez80_schedulesigaction.c ez80_sigdeliver.c ez80_lowuart.c
|
||||
CHIP_CSRCS += ez80_timerisr.c ez80_serial.c ez80_registerdump.c
|
||||
CHIP_CSRCS += ez80_timerisr.c ez80_serial.c
|
||||
|
||||
ifeq ($(CONFIG_ARCH_STACKDUMP),y)
|
||||
CHIP_CSRCS += ez80_registerdump.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_EZ80_I2C),y)
|
||||
CHIP_CSRCS += ez80_i2c.c
|
||||
@ -65,6 +78,9 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_EZ80_RTC),y)
|
||||
CHIP_CSRCS += ez80_rtc.c
|
||||
ifeq ($(CONFIG_RTC_DRIVER),y)
|
||||
CHIP_CSRCS += ez80_rtc_lowerhalf.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_CHIP_EZ80F91),y)
|
||||
|
62
arch/z80/src/ez80/ez80_getsp.asm
Normal file
62
arch/z80/src/ez80/ez80_getsp.asm
Normal file
@ -0,0 +1,62 @@
|
||||
;**************************************************************************
|
||||
; arch/z80/src/ez80/ez80_getsp.asm
|
||||
;
|
||||
; Copyright (C) 2019 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.
|
||||
;
|
||||
;**************************************************************************
|
||||
|
||||
;**************************************************************************
|
||||
; Global Symbols Exported
|
||||
;**************************************************************************
|
||||
|
||||
xdef _z80_getsp
|
||||
|
||||
;**************************************************************************
|
||||
; Code
|
||||
;**************************************************************************
|
||||
|
||||
segment CODE
|
||||
.assume ADL=1
|
||||
|
||||
;**************************************************************************
|
||||
;* Name: _z80_getsp
|
||||
;*
|
||||
;* Description:
|
||||
;* Return the current value of the stack pointer
|
||||
;*
|
||||
;**************************************************************************
|
||||
|
||||
_z80_getsp:
|
||||
ld hl, #0 ; Initialize HL to zero
|
||||
add hl, sp ; Add the stack pointer to HL
|
||||
ret ; Return stack pointer in HL
|
||||
|
||||
end
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* arch/z80/src/ez80/ez80_registerdump.c
|
||||
*
|
||||
* Copyright (C) 2008-2009, 2016 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2008-2009, 2016, 2019 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -49,10 +49,6 @@
|
||||
|
||||
#ifdef CONFIG_ARCH_STACKDUMP
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
@ -60,14 +56,14 @@
|
||||
static chipreg_t s_last_regs[XCPTCONTEXT_REGS];
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: z80_registerdump
|
||||
****************************************************************************/
|
||||
|
||||
static void ez80_registerdump(void)
|
||||
void ez80_registerdump(void)
|
||||
{
|
||||
volatile chipreg_t *regs = g_current_regs;
|
||||
|
||||
@ -93,7 +89,7 @@ static void ez80_registerdump(void)
|
||||
regs[XCPT_BC], regs[XCPT_DE], regs[XCPT_HL]);
|
||||
_alert("IX: %06x IY: %06x\n",
|
||||
regs[XCPT_IX], regs[XCPT_IY]);
|
||||
_alert("SP: %06x PC: %06x\n"
|
||||
_alert("SP: %06x PC: %06x\n",
|
||||
regs[XCPT_SP], regs[XCPT_PC]);
|
||||
#endif
|
||||
}
|
||||
|
604
arch/z80/src/ez80/ez80_rtc_lowerhalf.c
Normal file
604
arch/z80/src/ez80/ez80_rtc_lowerhalf.c
Normal file
@ -0,0 +1,604 @@
|
||||
/****************************************************************************
|
||||
* arch/z80/src/ez80/ez80_rtc_lowerhalf.c
|
||||
*
|
||||
* Copyright (C) 2019 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 <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/timers/rtc.h>
|
||||
|
||||
#include "up_arch.h"
|
||||
|
||||
#include "chip.h"
|
||||
#include "ez80_rtc.h"
|
||||
|
||||
#ifdef CONFIG_RTC_DRIVER
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
struct ez80_cbinfo_s
|
||||
{
|
||||
volatile rtc_alarm_callback_t cb; /* Callback when the alarm expires */
|
||||
volatile FAR void *priv; /* Private argument to accompany callback */
|
||||
};
|
||||
#endif
|
||||
|
||||
/* This is the private type for the RTC state. It must be cast compatible
|
||||
* with struct rtc_lowerhalf_s.
|
||||
*/
|
||||
|
||||
struct ez80_lowerhalf_s
|
||||
{
|
||||
/* This is the contained reference to the read-only, lower-half
|
||||
* operations vtable (which may lie in FLASH or ROM)
|
||||
*/
|
||||
|
||||
FAR const struct rtc_ops_s *ops;
|
||||
|
||||
/* Data following is private to this driver and not visible outside of
|
||||
* this file.
|
||||
*/
|
||||
|
||||
sem_t devsem; /* Threads can only exclusively access the RTC */
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
/* Alarm callback information */
|
||||
|
||||
struct ez80_cbinfo_s cbinfo;
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
/* Prototypes for static methods in struct rtc_ops_s */
|
||||
|
||||
static int ez80_rdtime(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR struct rtc_time *rtctime);
|
||||
static int ez80_settime(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR const struct rtc_time *rtctime);
|
||||
static bool ez80_havesettime(FAR struct rtc_lowerhalf_s *lower);
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
static int ez80_setalarm(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR const struct lower_setalarm_s *alarminfo);
|
||||
static int ez80_setrelative(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR const struct lower_setrelative_s *alarminfo);
|
||||
static int ez80_cancelalarm(FAR struct rtc_lowerhalf_s *lower);
|
||||
static int ez80_rdalarm(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR struct lower_rdalarm_s *alarminfo);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* eZ80 RTC driver operations */
|
||||
|
||||
static const struct rtc_ops_s g_rtc_ops =
|
||||
{
|
||||
.rdtime = ez80_rdtime,
|
||||
.settime = ez80_settime,
|
||||
.havesettime = ez80_havesettime,
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
.setalarm = ez80_setalarm,
|
||||
.setrelative = ez80_setrelative,
|
||||
.cancelalarm = ez80_cancelalarm,
|
||||
.rdalarm = ez80_rdalarm,
|
||||
#endif
|
||||
#ifdef CONFIG_RTC_PERIODIC
|
||||
.setperiodic = NULL,
|
||||
.cancelperiodic = NULL,
|
||||
#endif
|
||||
#ifdef CONFIG_RTC_IOCTL
|
||||
.ioctl = NULL,
|
||||
#endif
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
.destroy = NULL,
|
||||
#endif
|
||||
};
|
||||
|
||||
/* eZ80 RTC device state */
|
||||
|
||||
static struct ez80_lowerhalf_s g_rtc_lowerhalf =
|
||||
{
|
||||
.ops = &g_rtc_ops,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ez80_alarm_callback
|
||||
*
|
||||
* Description:
|
||||
* This is the function that is called from the RTC driver when the alarm
|
||||
* goes off. It just invokes the upper half drivers callback.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
static void ez80_alarm_callback(FAR void *arg)
|
||||
{
|
||||
FAR struct ez80_lowerhalf_s *lower;
|
||||
FAR struct ez80_cbinfo_s *cbinfo;
|
||||
rtc_alarm_callback_t cb;
|
||||
FAR void *priv;
|
||||
|
||||
lower = (struct ez80_lowerhalf_s *)arg;
|
||||
cbinfo = &lower->cbinfo;
|
||||
|
||||
/* Sample and clear the callback information to minimize the window in
|
||||
* time in which race conditions can occur.
|
||||
*/
|
||||
|
||||
cb = (rtc_alarm_callback_t)cbinfo->cb;
|
||||
priv = (FAR void *)cbinfo->priv;
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
cbinfo->cb = NULL;
|
||||
cbinfo->priv = NULL;
|
||||
|
||||
/* Perform the callback */
|
||||
|
||||
if (cb != NULL)
|
||||
{
|
||||
cb(priv);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ez80_rdtime
|
||||
*
|
||||
* Description:
|
||||
* Implements the rdtime() method of the RTC driver interface
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower - A reference to RTC lower half driver state structure
|
||||
* rcttime - The location in which to return the current RTC time.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ez80_rdtime(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR struct rtc_time *rtctime)
|
||||
{
|
||||
#if defined(CONFIG_RTC_DATETIME)
|
||||
/* This operation depends on the fact that struct rtc_time is cast
|
||||
* compatible with struct tm.
|
||||
*/
|
||||
|
||||
return up_rtc_getdatetime((FAR struct tm *)rtctime);
|
||||
|
||||
#elif defined(CONFIG_RTC_HIRES)
|
||||
FAR struct timespec ts;
|
||||
int ret;
|
||||
|
||||
/* Get the higher resolution time */
|
||||
|
||||
ret = up_rtc_gettime(&ts);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_errno;
|
||||
}
|
||||
|
||||
/* Convert the one second epoch time to a struct tm. This operation
|
||||
* depends on the fact that struct rtc_time and struct tm are cast
|
||||
* compatible.
|
||||
*/
|
||||
|
||||
if (!gmtime_r(&ts.tv_sec, (FAR struct tm *)rtctime))
|
||||
{
|
||||
goto errout_with_errno;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
errout_with_errno:
|
||||
ret = get_errno();
|
||||
DEBUGASSERT(ret > 0);
|
||||
return -ret;
|
||||
|
||||
#else
|
||||
time_t timer;
|
||||
|
||||
/* The resolution of time is only 1 second */
|
||||
|
||||
timer = up_rtc_time();
|
||||
|
||||
/* Convert the one second epoch time to a struct tm */
|
||||
|
||||
if (!gmtime_r(&timer, (FAR struct tm *)rtctime))
|
||||
{
|
||||
int errcode = get_errno();
|
||||
DEBUGASSERT(errcode > 0);
|
||||
return -errcode;
|
||||
}
|
||||
|
||||
return OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ez80_settime
|
||||
*
|
||||
* Description:
|
||||
* Implements the settime() method of the RTC driver interface
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower - A reference to RTC lower half driver state structure
|
||||
* rcttime - The new time to set
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ez80_settime(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR const struct rtc_time *rtctime)
|
||||
{
|
||||
#ifdef CONFIG_RTC_DATETIME
|
||||
/* This operation depends on the fact that struct rtc_time is cast
|
||||
* compatible with struct tm.
|
||||
*/
|
||||
|
||||
return ez80_rtc_setdatetime((FAR const struct tm *)rtctime);
|
||||
|
||||
#else
|
||||
struct timespec ts;
|
||||
|
||||
/* Convert the struct rtc_time to a time_t. Here we assume that struct
|
||||
* rtc_time is cast compatible with struct tm.
|
||||
*/
|
||||
|
||||
ts.tv_sec = mktime((FAR struct tm *)rtctime);
|
||||
ts.tv_nsec = 0;
|
||||
|
||||
/* Now set the time (to one second accuracy) */
|
||||
|
||||
return up_rtc_settime(&ts);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ez80_havesettime
|
||||
*
|
||||
* Description:
|
||||
* Implements the havesettime() method of the RTC driver interface
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower - A reference to RTC lower half driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* Returns true if RTC date-time have been previously set.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static bool ez80_havesettime(FAR struct rtc_lowerhalf_s *lower)
|
||||
{
|
||||
return getreg32(RTC_MAGIC_REG) == RTC_MAGIC_TIME_SET;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ez80_setalarm
|
||||
*
|
||||
* Description:
|
||||
* Set a new alarm. This function implements the setalarm() method of the
|
||||
* RTC driver interface
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower - A reference to RTC lower half driver state structure
|
||||
* alarminfo - Provided information needed to set the alarm
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
static int ez80_setalarm(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR const struct lower_setalarm_s *alarminfo)
|
||||
{
|
||||
FAR struct ez80_lowerhalf_s *priv;
|
||||
FAR struct ez80_cbinfo_s *cbinfo;
|
||||
struct alm_setalarm_s lowerinfo;
|
||||
int ret;
|
||||
|
||||
/* ID0-> Alarm A; ID1 -> Alarm B */
|
||||
|
||||
DEBUGASSERT(lower != NULL && alarminfo != NULL);
|
||||
DEBUGASSERT(alarminfo->id == RTC_ALARMA || alarminfo->id == RTC_ALARMB);
|
||||
priv = (FAR struct ez80_lowerhalf_s *)lower;
|
||||
|
||||
ret = nxsem_wait(&priv->devsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Remember the callback information */
|
||||
|
||||
cbinfo = &priv->cbinfo;
|
||||
cbinfo->cb = alarminfo->cb;
|
||||
cbinfo->priv = alarminfo->priv;
|
||||
cbinfo->id = alarminfo->id;
|
||||
|
||||
/* Set the alarm */
|
||||
|
||||
lowerinfo.as_id = alarminfo->id;
|
||||
lowerinfo.as_cb = ez80_alarm_callback;
|
||||
lowerinfo.as_arg = priv;
|
||||
memcpy(&lowerinfo.as_time, &alarminfo->time, sizeof(struct tm));
|
||||
|
||||
/* And set the alarm */
|
||||
|
||||
ret = ez80_rtc_setalarm(&lowerinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
cbinfo->cb = NULL;
|
||||
cbinfo->priv = NULL;
|
||||
}
|
||||
|
||||
nxsem_post(&priv->devsem);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ez80_setrelative
|
||||
*
|
||||
* Description:
|
||||
* Set a new alarm relative to the current time. This function implements
|
||||
* the setrelative() method of the RTC driver interface
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower - A reference to RTC lower half driver state structure
|
||||
* alarminfo - Provided information needed to set the alarm
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
static int ez80_setrelative(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR const struct lower_setrelative_s *alarminfo)
|
||||
{
|
||||
struct lower_setalarm_s setalarm;
|
||||
struct tm time;
|
||||
time_t seconds;
|
||||
int ret = -EINVAL;
|
||||
|
||||
DEBUGASSERT(lower != NULL && alarminfo != NULL);
|
||||
DEBUGASSERT(alarminfo->id == RTC_ALARMA || alarminfo->id == RTC_ALARMB);
|
||||
|
||||
if ((alarminfo->id == RTC_ALARMA || alarminfo->id == RTC_ALARMB) &&
|
||||
alarminfo->reltime > 0)
|
||||
{
|
||||
/* Disable pre-emption while we do this so that we don't have to worry
|
||||
* about being suspended and working on an old time.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
/* Get the current time in broken out format */
|
||||
|
||||
ret = up_rtc_getdatetime(&time);
|
||||
if (ret >= 0)
|
||||
{
|
||||
/* Convert to seconds since the epoch */
|
||||
|
||||
seconds = mktime(&time);
|
||||
|
||||
/* Add the seconds offset. Add one to the number of seconds
|
||||
* because we are unsure of the phase of the timer.
|
||||
*/
|
||||
|
||||
seconds += (alarminfo->reltime + 1);
|
||||
|
||||
/* And convert the time back to broken out format */
|
||||
|
||||
(void)gmtime_r(&seconds, (FAR struct tm *)&setalarm.time);
|
||||
|
||||
/* The set the alarm using this absolute time */
|
||||
|
||||
setalarm.id = alarminfo->id;
|
||||
setalarm.cb = alarminfo->cb;
|
||||
setalarm.priv = alarminfo->priv;
|
||||
|
||||
ret = ez80_setalarm(lower, &setalarm);
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ez80_cancelalarm
|
||||
*
|
||||
* Description:
|
||||
* Cancel the current alarm. This function implements the cancelalarm()
|
||||
* method of the RTC driver interface
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower - A reference to RTC lower half driver state structure
|
||||
* alarminfo - Provided information needed to set the alarm
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
static int ez80_cancelalarm(FAR struct rtc_lowerhalf_s *lower)
|
||||
{
|
||||
FAR struct ez80_lowerhalf_s *priv;
|
||||
FAR struct ez80_cbinfo_s *cbinfo;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(lower != NULL);
|
||||
priv = (FAR struct ez80_lowerhalf_s *)lower;
|
||||
|
||||
ret = nxsem_wait(&priv->devsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Nullify callback information to reduce window for race conditions */
|
||||
|
||||
cbinfo = &priv->cbinfo;
|
||||
cbinfo->cb = NULL;
|
||||
cbinfo->priv = NULL;
|
||||
|
||||
/* Then cancel the alarm */
|
||||
|
||||
ret = ez80_rtc_cancelalarm();
|
||||
nxsem_post(&priv->devsem);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ez80_rdalarm
|
||||
*
|
||||
* Description:
|
||||
* Query the RTC alarm.
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower - A reference to RTC lower half driver state structure
|
||||
* alarminfo - Provided information needed to query the alarm
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
static int ez80_rdalarm(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR struct lower_rdalarm_s *alarminfo)
|
||||
{
|
||||
struct alm_rdalarm_s lowerinfo;
|
||||
int ret = -EINVAL;
|
||||
|
||||
DEBUGASSERT(lower != NULL && alarminfo != NULL && alarminfo->time != NULL);
|
||||
DEBUGASSERT(alarminfo->id == RTC_ALARMA || alarminfo->id == RTC_ALARMB);
|
||||
|
||||
/* Disable pre-emption while we do this so that we don't have to worry
|
||||
* about being suspended and working on an old time.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
lowerinfo.ar_id = alarminfo->id;
|
||||
lowerinfo.ar_time = alarminfo->time;
|
||||
|
||||
ret = ez80_rtc_rdalarm(&lowerinfo);
|
||||
sched_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ez80_rtc_lowerhalf
|
||||
*
|
||||
* Description:
|
||||
* Instantiate the RTC lower half driver for the eZ80. General usage:
|
||||
*
|
||||
* #include <nuttx/timers/rtc.h>
|
||||
* #include "ez80_rtc.h>
|
||||
*
|
||||
* struct rtc_lowerhalf_s *lower;
|
||||
* lower = ez80_rtc_lowerhalf();
|
||||
* rtc_initialize(0, lower);
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, a non-NULL RTC lower interface is returned. NULL is
|
||||
* returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct rtc_lowerhalf_s *ez80_rtc_lowerhalf(void)
|
||||
{
|
||||
nxsem_init(&g_rtc_lowerhalf.devsem, 0, 1);
|
||||
|
||||
return (FAR struct rtc_lowerhalf_s *)&g_rtc_lowerhalf;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_RTC_DRIVER */
|
@ -253,7 +253,7 @@ static uart_dev_t g_uart1port =
|
||||
* Name: ez80_serialin
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint8_t ez80_serialin(struct ez80_dev_s *priv, uint8_t offset)
|
||||
static uint8_t ez80_serialin(FAR struct ez80_dev_s *priv, uint8_t offset)
|
||||
{
|
||||
return inp(priv->uartbase + offset);
|
||||
}
|
||||
@ -262,8 +262,8 @@ static inline uint8_t ez80_serialin(struct ez80_dev_s *priv, uint8_t offset)
|
||||
* Name: ez80_serialout
|
||||
****************************************************************************/
|
||||
|
||||
static inline void ez80_serialout(struct ez80_dev_s *priv, uint8_t offset,
|
||||
uint8_t value)
|
||||
static void ez80_serialout(FAR struct ez80_dev_s *priv, uint8_t offset,
|
||||
uint8_t value)
|
||||
{
|
||||
outp(priv->uartbase + offset, value);
|
||||
}
|
||||
@ -272,7 +272,7 @@ static inline void ez80_serialout(struct ez80_dev_s *priv, uint8_t offset,
|
||||
* Name: ez80_disableuartint
|
||||
****************************************************************************/
|
||||
|
||||
static inline void ez80_disableuartint(struct ez80_dev_s *priv)
|
||||
static void ez80_disableuartint(FAR struct ez80_dev_s *priv)
|
||||
{
|
||||
uint8_t ier = ez80_serialin(priv, EZ80_UART_IER);
|
||||
ier &= ~EZ80_UARTEIR_INTMASK;
|
||||
@ -283,7 +283,7 @@ static inline void ez80_disableuartint(struct ez80_dev_s *priv)
|
||||
* Name: ez80_restoreuartint
|
||||
****************************************************************************/
|
||||
|
||||
static inline void ez80_restoreuartint(struct ez80_dev_s *priv, uint8_t bits)
|
||||
static void ez80_restoreuartint(FAR struct ez80_dev_s *priv, uint8_t bits)
|
||||
{
|
||||
uint8_t ier = ez80_serialin(priv, EZ80_UART_IER);
|
||||
ier |= bits & (EZ80_UARTEIR_TIE|EZ80_UARTEIR_RIE);
|
||||
@ -294,7 +294,7 @@ static inline void ez80_restoreuartint(struct ez80_dev_s *priv, uint8_t bits)
|
||||
* Name: ez80_waittxready
|
||||
****************************************************************************/
|
||||
|
||||
static inline void ez80_waittxready(struct ez80_dev_s *priv)
|
||||
static void ez80_waittxready(FAR struct ez80_dev_s *priv)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
@ -311,7 +311,7 @@ static inline void ez80_waittxready(struct ez80_dev_s *priv)
|
||||
* Name: ez80_setbaud
|
||||
****************************************************************************/
|
||||
|
||||
static inline void ez80_setbaud(struct ez80_dev_s *priv, uint24_t baud)
|
||||
static void ez80_setbaud(FAR struct ez80_dev_s *priv, uint24_t baud)
|
||||
{
|
||||
uint32_t brg_divisor;
|
||||
uint8_t lctl;
|
||||
@ -350,10 +350,10 @@ static inline void ez80_setbaud(struct ez80_dev_s *priv, uint24_t baud)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ez80_setup(struct uart_dev_s *dev)
|
||||
static int ez80_setup(FAR struct uart_dev_s *dev)
|
||||
{
|
||||
#ifndef CONFIG_SUPPRESS_UART_CONFIG
|
||||
struct ez80_dev_s *priv = dev->priv;
|
||||
FAR struct ez80_dev_s *priv = dev->priv;
|
||||
uint8_t reg;
|
||||
uint8_t cval;
|
||||
|
||||
@ -414,9 +414,9 @@ static int ez80_setup(struct uart_dev_s *dev)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ez80_shutdown(struct uart_dev_s *dev)
|
||||
static void ez80_shutdown(FAR struct uart_dev_s *dev)
|
||||
{
|
||||
struct ez80_dev_s *priv = (struct ez80_dev_s*)dev->priv;
|
||||
FAR struct ez80_dev_s *priv = (FAR struct ez80_dev_s*)dev->priv;
|
||||
ez80_disableuartint(priv);
|
||||
}
|
||||
|
||||
@ -435,9 +435,9 @@ static void ez80_shutdown(struct uart_dev_s *dev)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ez80_attach(struct uart_dev_s *dev)
|
||||
static int ez80_attach(FAR struct uart_dev_s *dev)
|
||||
{
|
||||
struct ez80_dev_s *priv = (struct ez80_dev_s*)dev->priv;
|
||||
FAR struct ez80_dev_s *priv = (FAR struct ez80_dev_s*)dev->priv;
|
||||
|
||||
/* Attach the IRQ */
|
||||
|
||||
@ -454,9 +454,9 @@ static int ez80_attach(struct uart_dev_s *dev)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ez80_detach(struct uart_dev_s *dev)
|
||||
static void ez80_detach(FAR struct uart_dev_s *dev)
|
||||
{
|
||||
struct ez80_dev_s *priv = (struct ez80_dev_s*)dev->priv;
|
||||
FAR struct ez80_dev_s *priv = (FAR struct ez80_dev_s*)dev->priv;
|
||||
ez80_disableuartint(priv);
|
||||
irq_detach(priv->irq);
|
||||
}
|
||||
@ -474,9 +474,9 @@ static void ez80_detach(struct uart_dev_s *dev)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ez80_interrupt(int irq, void *context, void *arg)
|
||||
static int ez80_interrupt(int irq, FAR void *context, FAR void *arg)
|
||||
{
|
||||
struct uart_dev_s *dev = (struct uart_dev_s *)arg;
|
||||
FAR struct uart_dev_s *dev = (FAR struct uart_dev_s *)arg;
|
||||
struct ez80_dev_s *priv;
|
||||
volatile uint32_t cause;
|
||||
|
||||
@ -512,7 +512,7 @@ static int ez80_interrupt(int irq, void *context, void *arg)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ez80_ioctl(struct file *filep, int cmd, unsigned long arg)
|
||||
static int ez80_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
{
|
||||
return -ENOTTY;
|
||||
}
|
||||
@ -527,9 +527,9 @@ static int ez80_ioctl(struct file *filep, int cmd, unsigned long arg)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ez80_receive(struct uart_dev_s *dev, unsigned int *status)
|
||||
static int ez80_receive(FAR struct uart_dev_s *dev, FAR unsigned int *status)
|
||||
{
|
||||
struct ez80_dev_s *priv = (struct ez80_dev_s*)dev->priv;
|
||||
FAR struct ez80_dev_s *priv = (FAR struct ez80_dev_s*)dev->priv;
|
||||
uint8_t rbr = ez80_serialin(priv, EZ80_UART_RBR);
|
||||
uint8_t lsr = ez80_serialin(priv, EZ80_UART_LSR);
|
||||
|
||||
@ -545,9 +545,9 @@ static int ez80_receive(struct uart_dev_s *dev, unsigned int *status)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ez80_rxint(struct uart_dev_s *dev, bool enable)
|
||||
static void ez80_rxint(FAR struct uart_dev_s *dev, bool enable)
|
||||
{
|
||||
struct ez80_dev_s *priv = (struct ez80_dev_s*)dev->priv;
|
||||
FAR struct ez80_dev_s *priv = (FAR struct ez80_dev_s*)dev->priv;
|
||||
uint8_t ier = ez80_serialin(priv, EZ80_UART_IER);
|
||||
|
||||
if (enable)
|
||||
@ -572,9 +572,9 @@ static void ez80_rxint(struct uart_dev_s *dev, bool enable)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static bool ez80_rxavailable(struct uart_dev_s *dev)
|
||||
static bool ez80_rxavailable(FAR struct uart_dev_s *dev)
|
||||
{
|
||||
struct ez80_dev_s *priv = (struct ez80_dev_s*)dev->priv;
|
||||
FAR struct ez80_dev_s *priv = (FAR struct ez80_dev_s*)dev->priv;
|
||||
return (ez80_serialin(priv, EZ80_UART_LSR) & EZ80_UARTLSR_DR) != 0;
|
||||
}
|
||||
|
||||
@ -586,9 +586,9 @@ static bool ez80_rxavailable(struct uart_dev_s *dev)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ez80_send(struct uart_dev_s *dev, int ch)
|
||||
static void ez80_send(FAR struct uart_dev_s *dev, int ch)
|
||||
{
|
||||
struct ez80_dev_s *priv = (struct ez80_dev_s*)dev->priv;
|
||||
FAR struct ez80_dev_s *priv = (FAR struct ez80_dev_s*)dev->priv;
|
||||
ez80_serialout(priv, EZ80_UART_THR, (uint8_t)ch);
|
||||
}
|
||||
|
||||
@ -600,9 +600,9 @@ static void ez80_send(struct uart_dev_s *dev, int ch)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ez80_txint(struct uart_dev_s *dev, bool enable)
|
||||
static void ez80_txint(FAR struct uart_dev_s *dev, bool enable)
|
||||
{
|
||||
struct ez80_dev_s *priv = (struct ez80_dev_s*)dev->priv;
|
||||
FAR struct ez80_dev_s *priv = (FAR struct ez80_dev_s*)dev->priv;
|
||||
uint8_t ier = ez80_serialin(priv, EZ80_UART_IER);
|
||||
|
||||
if (enable)
|
||||
@ -623,13 +623,13 @@ static void ez80_txint(struct uart_dev_s *dev, bool enable)
|
||||
* Name: ez80_txready
|
||||
*
|
||||
* Description:
|
||||
* Return true if the tranmsit fifo is not full
|
||||
* Return true if the transmit fifo is not full
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static bool ez80_txready(struct uart_dev_s *dev)
|
||||
static bool ez80_txready(FAR struct uart_dev_s *dev)
|
||||
{
|
||||
struct ez80_dev_s *priv = (struct ez80_dev_s*)dev->priv;
|
||||
FAR struct ez80_dev_s *priv = (FAR struct ez80_dev_s*)dev->priv;
|
||||
return (ez80_serialin(priv, EZ80_UART_LSR) & EZ80_UARTLSR_THRE) != 0;
|
||||
}
|
||||
|
||||
@ -641,9 +641,9 @@ static bool ez80_txready(struct uart_dev_s *dev)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static bool ez80_txempty(struct uart_dev_s *dev)
|
||||
static bool ez80_txempty(FAR struct uart_dev_s *dev)
|
||||
{
|
||||
struct ez80_dev_s *priv = (struct ez80_dev_s*)dev->priv;
|
||||
FAR struct ez80_dev_s *priv = (FAR struct ez80_dev_s*)dev->priv;
|
||||
return (ez80_serialin(priv, EZ80_UART_LSR) & EZ80_UARTLSR_TEMT) != 0;
|
||||
}
|
||||
|
||||
@ -734,7 +734,7 @@ void z80_serial_initialize(void)
|
||||
int up_putc(int ch)
|
||||
{
|
||||
#ifdef CONSOLE_DEV
|
||||
struct ez80_dev_s *priv = (struct ez80_dev_s*)CONSOLE_DEV.priv;
|
||||
FAR struct ez80_dev_s *priv = (FAR struct ez80_dev_s*)CONSOLE_DEV.priv;
|
||||
uint8_t ier = ez80_serialin(priv, EZ80_UART_IER);
|
||||
|
||||
ez80_disableuartint(priv);
|
||||
@ -779,14 +779,6 @@ int up_putc(int ch)
|
||||
#define ez80_txready() ((ez80_inp(EZ80_UART_LSR) & EZ80_UARTLSR_THRE) != 0)
|
||||
#define ez80_send(ch) ez80_outp(EZ80_UART_THR, ch)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include <semaphore.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
#include <nuttx/arch.h>
|
||||
@ -62,11 +63,19 @@
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ARCH_CHIP_EZ80F91
|
||||
# define GPIOB_SPI_PINSET 0x38 /* MISO+MSOI+SCK. Excludes SS */
|
||||
# define GPIOB_SPI_SS (1 << 2) /* Pin 2: /SS (not used by driver) */
|
||||
# define GPIOB_SPI_SCK (1 << 3) /* Pin 3: SCK */
|
||||
# define GPIOB_SPI_MISO (1 << 6) /* Pin 6: MISO */
|
||||
# define GPIOB_SPI_MOSI (1 << 7) /* Pin 7: MOSI */
|
||||
|
||||
# define GPIOB_SPI_PINSET (GPIOB_SPI_SS | GPIOB_SPI_SCK | GPIOB_SPI_MISO | \
|
||||
GPIOB_SPI_MOSI)
|
||||
#else
|
||||
# error "Check GPIO initialization for this chip"
|
||||
#endif
|
||||
|
||||
#define SPIF_RETRIES 1000
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
@ -178,7 +187,7 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
||||
* was awakened by a signal.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(ret == OK || ret == -EINTR);
|
||||
DEBUGASSERT(ret == OK || ret == -EINTR || ret == -ECANCELED);
|
||||
}
|
||||
while (ret == -EINTR);
|
||||
}
|
||||
@ -209,6 +218,10 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev,
|
||||
uint32_t frequency)
|
||||
{
|
||||
uint32_t brg;
|
||||
|
||||
spiinfo("frequency: %lu\n", (unsigned long)frequency);
|
||||
|
||||
/* We want select divisor to provide the highest frequency (SPIR) that does
|
||||
* NOT exceed the requested frequency.:
|
||||
*
|
||||
@ -219,7 +232,7 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev,
|
||||
* BRG >= System Clock Frequency / (2 * SPIR)
|
||||
*/
|
||||
|
||||
uint32_t brg = ((EZ80_SYS_CLK_FREQ + 1) / 2 + frequency - 1) / frequency;
|
||||
brg = ((EZ80_SYS_CLK_FREQ + 1) / 2 + frequency - 1) / frequency;
|
||||
|
||||
/* "When configured as a Master, the 16-bit divisor value must be between
|
||||
* 0003h and FFFFh, inclusive. When configured as a Slave, the 16-bit
|
||||
@ -232,11 +245,11 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev,
|
||||
}
|
||||
else if (brg > 0xffff)
|
||||
{
|
||||
brg = 0xfff;
|
||||
brg = 0xffff;
|
||||
}
|
||||
|
||||
outp(EZ80_SPI_BRG_L, brg & 0xff);
|
||||
outp(EZ80_SPI_BRG_L, (brg >> 8) & 0xff);
|
||||
outp(EZ80_SPI_BRG_H, (brg >> 8) & 0xff);
|
||||
|
||||
return ((EZ80_SYS_CLK_FREQ + 1) / 2 + brg - 1) / brg;
|
||||
}
|
||||
@ -261,6 +274,8 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
||||
uint8_t modebits;
|
||||
uint8_t regval;
|
||||
|
||||
spiinfo("mode: %d\n", (int)mode);
|
||||
|
||||
/* Select the CTL register bits based on the selected mode */
|
||||
|
||||
switch (mode)
|
||||
@ -304,25 +319,34 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* Status register mode bits
|
||||
* OK if the transferred completed without error. Otherwise, a negated
|
||||
* errno value is returned indicating the nature of the error.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint8_t spi_waitspif(void)
|
||||
static int spi_waitspif(void)
|
||||
{
|
||||
uint8_t status;
|
||||
int retries;
|
||||
|
||||
/* Wait for the device to be ready to accept another byte (or for an error
|
||||
* to be reported
|
||||
* to be reported or for a timeout to occur).
|
||||
*/
|
||||
|
||||
do
|
||||
for (retries = 0; retries < SPIF_RETRIES; retries++)
|
||||
{
|
||||
status = inp(EZ80_SPI_SR) & (SPI_SR_SPIF | SPI_SR_WCOL | SPI_SR_MODF);
|
||||
status = inp(EZ80_SPI_SR);
|
||||
if ((status & (SPI_SR_WCOL | SPI_SR_MODF)) != 0)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
else if ((status & SPI_SR_SPIF) != 0)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
while (status == 0);
|
||||
|
||||
return status;
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -332,29 +356,41 @@ static uint8_t spi_waitspif(void)
|
||||
* Send one byte on SPI, return the response
|
||||
*
|
||||
* Input Parameters:
|
||||
* ch - the byte to send
|
||||
* chout - The byte to send
|
||||
* chin - The location to save the returned byte (may be NULL)
|
||||
*
|
||||
* Returned Value:
|
||||
* response
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint8_t spi_transfer(uint8_t ch)
|
||||
static int spi_transfer(uint8_t chout, FAR uint8_t *chin)
|
||||
{
|
||||
uint8_t status;
|
||||
uint8_t response;
|
||||
int ret;
|
||||
|
||||
spiinfo("chout: %02x\n", chout);
|
||||
|
||||
/* Send the byte, repeating if some error occurs */
|
||||
|
||||
for (; ; )
|
||||
{
|
||||
outp(EZ80_SPI_TSR, ch);
|
||||
outp(EZ80_SPI_TSR, chout);
|
||||
|
||||
/* Wait for the device to be ready to accept another byte */
|
||||
|
||||
status = spi_waitspif();
|
||||
if ((status & SPI_SR_SPIF) != 0)
|
||||
ret = spi_waitspif();
|
||||
if (ret < 0)
|
||||
{
|
||||
return inp(EZ80_SPI_RBR);
|
||||
spierr("ERROR: spi_waitspif returned %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
response = inp(EZ80_SPI_RBR);
|
||||
if (chin != NULL)
|
||||
{
|
||||
*chin = response;
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -377,7 +413,19 @@ static uint8_t spi_transfer(uint8_t ch)
|
||||
|
||||
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
||||
{
|
||||
return spi_transfer((uint8_t)wd);
|
||||
uint8_t response;
|
||||
int ret;
|
||||
|
||||
spiinfo("ch: %04x\n", wd);
|
||||
|
||||
ret = spi_transfer((uint8_t)wd, &response);
|
||||
if (ret < 0)
|
||||
{
|
||||
spierr("ERROR: spi_waitspif returned %d\n", ret);
|
||||
return (uint16_t)0xff;
|
||||
}
|
||||
|
||||
return (uint16_t)response;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -409,23 +457,34 @@ static void spi_exchange(FAR struct spi_dev_s *dev,
|
||||
FAR const uint8_t *inptr = (FAR const uint8_t *)txbuffer;
|
||||
FAR uint8_t *outptr = (FAR const uint8_t *)rxbuffer;
|
||||
|
||||
spiinfo("txbuffer: %p rxbuffer: %p nwords: %lu\n",
|
||||
txbuffer, rxbuffer, (unsigned long)nwords);
|
||||
|
||||
/* Loop while there are bytes remaining to be sent */
|
||||
|
||||
while (nwords-- > 0)
|
||||
{
|
||||
uint8_t outword;
|
||||
int ret;
|
||||
|
||||
/* Send 0xff if there is no outgoing TX stream */
|
||||
|
||||
uint8_t outword = (inptr == NULL) ? 0xff : *inptr++;
|
||||
outword = (inptr == NULL) ? 0xff : *inptr++;
|
||||
|
||||
/* Send the outgoing word and obtain the respoonse */
|
||||
/* Send the outgoing word and obtain the response */
|
||||
|
||||
uint8_t inword = spi_transfer(outword);
|
||||
ret = spi_transfer(outword, outptr);
|
||||
if (ret < 0)
|
||||
{
|
||||
spierr("ERROR: spi_waitspif returned %d\n", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Save the response if there is an incoming RX stream */
|
||||
/* Conditionally increment the output buffer pointer. */
|
||||
|
||||
if (outptr != NULL)
|
||||
{
|
||||
*outptr++ = inword;
|
||||
outptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -456,12 +515,20 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
FAR const uint8_t *ptr = (FAR const uint8_t *)buffer;
|
||||
int ret;
|
||||
|
||||
spiinfo("buffer: %p buflen: %lu\n", buffer, (unsigned long)nwords);
|
||||
|
||||
/* Loop while there are bytes remaining to be sent */
|
||||
|
||||
while (buflen-- > 0)
|
||||
{
|
||||
(void)spi_transfer(*ptr++);
|
||||
ret = spi_transfer(*ptr++, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
spierr("ERROR: spi_waitspif returned %d\n", ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -492,11 +559,18 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer,
|
||||
{
|
||||
FAR uint8_t *ptr = (FAR uint8_t *)buffer;
|
||||
|
||||
/* Loop while thre are bytes remaining to be sent */
|
||||
spiinfo("buffer: %p buflen: %lu\n", buffer, (unsigned long)nwords);
|
||||
|
||||
/* Loop while there are bytes remaining to be sent */
|
||||
|
||||
while (buflen-- > 0)
|
||||
{
|
||||
*ptr++ = spi_transfer(0xff);
|
||||
ret = spi_transfer(0xff, ptr++);
|
||||
if (ret < 0)
|
||||
{
|
||||
spierr("ERROR: spi_waitspif returned %d\n", ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -516,14 +590,14 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer,
|
||||
*
|
||||
* One GPIO, SS (PB2 on the eZ8F091) is reserved as a chip select. However,
|
||||
* If multiple devices on on the bus, then multiple chip selects will be
|
||||
* required. Theregore, all GPIO chip management is deferred to board-
|
||||
* required. Therefore, all GPIO chip management is deferred to board-
|
||||
* specific logic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* Port number (for hardware that has mutiple SPI interfaces)
|
||||
* Port number (for hardware that has multiple SPI interfaces)
|
||||
*
|
||||
* Returned Value:
|
||||
* Valid SPI device structre reference on succcess; a NULL on failure
|
||||
* Valid SPI device structure reference on success; a NULL on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
@ -549,12 +623,12 @@ FAR struct spi_dev_s *ez80_spibus_initialize(int port)
|
||||
*
|
||||
* GPIO ALT MASTER SLAVE COMMENT
|
||||
* ---- ----- ------- ------- ---------------------------------
|
||||
* PB2 SS INPUT INPUT Managed by board specific logic
|
||||
* PB3 SCLK OUTPUT INPUT
|
||||
* PB4 MISO INPUT OUTPUT
|
||||
* PB5 MOSI OUTPUT INPUT
|
||||
* PB2 SS INPUT INPUT Managed by board specific logic
|
||||
* PB3 SCLK OUTPUT INPUT
|
||||
* PB6 MISO INPUT OUTPUT
|
||||
* PB7 MOSI OUTPUT INPUT
|
||||
*
|
||||
* Select the alternate function for PB2-5:
|
||||
* Select the alternate function for PB2-3,6-7:
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARCH_CHIP_EZ80F91
|
||||
@ -579,7 +653,7 @@ FAR struct spi_dev_s *ez80_spibus_initialize(int port)
|
||||
|
||||
/* Enable the SPI.
|
||||
* NOTE 1: Interrupts are not used in this driver version.
|
||||
* NOTE 2: Initial mode is mode=0.
|
||||
* NOTE 2: Initial mode is mode=0
|
||||
*/
|
||||
|
||||
outp(EZ80_SPI_CTL, SPI_CTL_SPIEN | SPI_CTL_MASTEREN);
|
||||
|
@ -313,11 +313,19 @@ Configuration Subdirectories
|
||||
placed in the card slot before the system is started.
|
||||
|
||||
STATUS:
|
||||
2109-06-16: The basic NSH configuration appears to be fully functional
|
||||
2019-06-16: The basic NSH configuration appears to be fully functional
|
||||
using only the CPU and I/O expansion card. Console is provided over
|
||||
USB.
|
||||
|
||||
Added support for SPI-based SD cards, the RTC and procFS. There are
|
||||
still a few issues at the end-of-the-day: (1) the SD card block driver
|
||||
is not being registered, and (2) RTC does not preserve time across a
|
||||
still a few issues at the end-of-the-day: (1) the SD card initialization
|
||||
hangs and prevents booting, and (2) RTC does not preserve time across a
|
||||
power cycle.
|
||||
|
||||
2019-06-17: The SD initialization is due to some error in the SPI driver:
|
||||
It waits for a byte transfer to complete but it never receives the
|
||||
indication that the transfer completed. The SPI problem has not been
|
||||
fixed, but timeout logic was added to avoid the hang.
|
||||
|
||||
The MMC/SD start-up failures do effect the boot-up time. You might want
|
||||
to disable SPI to avoid start-up delays.
|
||||
|
@ -76,7 +76,7 @@
|
||||
#define LED_STACKCREATED 0
|
||||
#define LED_IDLE 0
|
||||
#define LED_INIRQ 0
|
||||
#define LED_ASSERTION 1
|
||||
#define LED_ASSERTION 0
|
||||
#define LED_SIGNAL 0
|
||||
#define LED_PANIC 1
|
||||
|
||||
|
@ -14,6 +14,7 @@ CONFIG_ARCH_BOARD="makerlisp"
|
||||
CONFIG_ARCH_BOARD_MAKERLISP=y
|
||||
CONFIG_ARCH_CHIP_EZ80=y
|
||||
CONFIG_ARCH_CHIP_EZ80F91=y
|
||||
CONFIG_ARCH_STACKDUMP=y
|
||||
CONFIG_ARCH_Z80=y
|
||||
CONFIG_BOARD_LOOPSPERMSEC=1250
|
||||
CONFIG_DISABLE_MQUEUE=y
|
||||
|
@ -43,6 +43,8 @@
|
||||
#include <sys/mount.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "makerlisp.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -78,7 +80,7 @@ int ez80_bringup(void)
|
||||
#ifdef HAVE_MMCSD
|
||||
/* Initialize SPI-based SD card slot */
|
||||
|
||||
ret = ez80_mmcsd_initialize(void);
|
||||
ret = ez80_mmcsd_initialize();
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: Failed to initialize SD card: %d\n", ret);
|
||||
|
@ -145,7 +145,7 @@ uint8_t ez80_spistatus(FAR struct spi_dev_s *dev, uint32_t devid)
|
||||
{
|
||||
uint8_t status = 0;
|
||||
|
||||
#ifdef HAVE_MMCSD_SPI
|
||||
#ifdef HAVE_MMCSD
|
||||
if (devid == SPIDEV_MMCSD(0))
|
||||
{
|
||||
/* No card detect pin.. Always claim that the card is present in
|
||||
|
Loading…
Reference in New Issue
Block a user