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();
|
(void)syslog_flush();
|
||||||
|
|
||||||
#ifdef CONFIG_BOARD_CRASHDUMP
|
#ifdef CONFIG_BOARD_CRASHDUMP
|
||||||
board_crashdump(up_getsp(), running_task(), filename, lineno);
|
board_crashdump(Z80_getsp(), running_task(), filename, lineno);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_up_assert(EXIT_FAILURE);
|
_up_assert(EXIT_FAILURE);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* arch/z80/src/common/up_stackdump.c
|
* 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>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -49,29 +49,24 @@
|
|||||||
#ifdef CONFIG_ARCH_STACKDUMP
|
#ifdef CONFIG_ARCH_STACKDUMP
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: up_getsp
|
|
||||||
****************************************************************************/
|
|
||||||
#warning TO BE PROVIDED
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: up_stackdump
|
* Name: up_stackdump
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void up_stackdump(void)
|
void up_stackdump(void)
|
||||||
{
|
{
|
||||||
struct tcb_s *rtcb = this_task();
|
FAR struct tcb_s *rtcb = this_task();
|
||||||
uint16_t sp = up_getsp();
|
uintptr_t sp = z80_getsp();
|
||||||
uint16_t stack_base = (uint16_t)rtcb->adj_stack_ptr;
|
uintptr_t stack_base = (uintptr_t)rtcb->adj_stack_ptr;
|
||||||
uint16_t stack_size = (uint16_t)rtcb->adj_stack_size;
|
uintptr_t stack_size = (uintptr_t)rtcb->adj_stack_size;
|
||||||
uint16_t stack;
|
uintptr_t stack;
|
||||||
|
|
||||||
_alert("stack_base: %04x\n", stack_base);
|
_alert("stack_base: %06x\n", stack_base);
|
||||||
_alert("stack_size: %04x\n", stack_size);
|
_alert("stack_size: %06x\n", stack_size);
|
||||||
_alert("sp: %04x\n", sp);
|
_alert("sp: %06x\n", sp);
|
||||||
|
|
||||||
if (sp >= stack_base || sp < stack_base - stack_size)
|
if (sp >= stack_base || sp < stack_base - stack_size)
|
||||||
{
|
{
|
||||||
@ -83,12 +78,17 @@ static void up_stackdump(void)
|
|||||||
stack = sp;
|
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;
|
FAR uint8_t *ptr = (FAR uint8_t*)stack;
|
||||||
_alert("%04x: %04x %04x %04x %04x %04x %04x %04x %04x\n",
|
|
||||||
stack, ptr[0], ptr[1], ptr[2], ptr[3],
|
_alert("%06x: %02x %02x %02x %02x %02x %02x %02x %02x ",
|
||||||
ptr[4], ptr[5], ptr[6], ptr[7]);
|
"%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) */
|
/* 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 */
|
/* 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_mdelay.c up_stackframe.c up_udelay.c up_usestack.c
|
||||||
CMN_CSRCS += up_puts.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_startup.asm ez80_io.asm ez80_irqsave.asm
|
||||||
CHIP_ASRCS += ez80_saveusercontext.asm ez80_restorecontext.asm
|
CHIP_ASRCS += ez80_saveusercontext.asm ez80_restorecontext.asm
|
||||||
|
|
||||||
ifeq ($(CONFIG_ARCH_CHIP_EZ80F91),y)
|
ifeq ($(CONFIG_ARCH_CHIP_EZ80F91),y)
|
||||||
CHIP_ASRCS += ez80f91_init.asm
|
CHIP_ASRCS += ez80f91_init.asm
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_ARCH_STACKDUMP),y)
|
||||||
|
CHIP_ASRCS += ez80_getsp.asm
|
||||||
|
endif
|
||||||
|
|
||||||
CHIP_SSRCS =
|
CHIP_SSRCS =
|
||||||
CHIP_CSRCS = ez80_clock.c ez80_initialstate.c ez80_irq.c ez80_copystate.c
|
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_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)
|
ifeq ($(CONFIG_EZ80_I2C),y)
|
||||||
CHIP_CSRCS += ez80_i2c.c
|
CHIP_CSRCS += ez80_i2c.c
|
||||||
@ -65,6 +78,9 @@ endif
|
|||||||
|
|
||||||
ifeq ($(CONFIG_EZ80_RTC),y)
|
ifeq ($(CONFIG_EZ80_RTC),y)
|
||||||
CHIP_CSRCS += ez80_rtc.c
|
CHIP_CSRCS += ez80_rtc.c
|
||||||
|
ifeq ($(CONFIG_RTC_DRIVER),y)
|
||||||
|
CHIP_CSRCS += ez80_rtc_lowerhalf.c
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_ARCH_CHIP_EZ80F91),y)
|
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
|
* 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>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -49,10 +49,6 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_ARCH_STACKDUMP
|
#ifdef CONFIG_ARCH_STACKDUMP
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Pre-processor Definitions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -60,14 +56,14 @@
|
|||||||
static chipreg_t s_last_regs[XCPTCONTEXT_REGS];
|
static chipreg_t s_last_regs[XCPTCONTEXT_REGS];
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: z80_registerdump
|
* Name: z80_registerdump
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void ez80_registerdump(void)
|
void ez80_registerdump(void)
|
||||||
{
|
{
|
||||||
volatile chipreg_t *regs = g_current_regs;
|
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]);
|
regs[XCPT_BC], regs[XCPT_DE], regs[XCPT_HL]);
|
||||||
_alert("IX: %06x IY: %06x\n",
|
_alert("IX: %06x IY: %06x\n",
|
||||||
regs[XCPT_IX], regs[XCPT_IY]);
|
regs[XCPT_IX], regs[XCPT_IY]);
|
||||||
_alert("SP: %06x PC: %06x\n"
|
_alert("SP: %06x PC: %06x\n",
|
||||||
regs[XCPT_SP], regs[XCPT_PC]);
|
regs[XCPT_SP], regs[XCPT_PC]);
|
||||||
#endif
|
#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
|
* 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);
|
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
|
* Name: ez80_serialout
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static inline void ez80_serialout(struct ez80_dev_s *priv, uint8_t offset,
|
static void ez80_serialout(FAR struct ez80_dev_s *priv, uint8_t offset,
|
||||||
uint8_t value)
|
uint8_t value)
|
||||||
{
|
{
|
||||||
outp(priv->uartbase + offset, 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
|
* 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);
|
uint8_t ier = ez80_serialin(priv, EZ80_UART_IER);
|
||||||
ier &= ~EZ80_UARTEIR_INTMASK;
|
ier &= ~EZ80_UARTEIR_INTMASK;
|
||||||
@ -283,7 +283,7 @@ static inline void ez80_disableuartint(struct ez80_dev_s *priv)
|
|||||||
* Name: ez80_restoreuartint
|
* 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);
|
uint8_t ier = ez80_serialin(priv, EZ80_UART_IER);
|
||||||
ier |= bits & (EZ80_UARTEIR_TIE|EZ80_UARTEIR_RIE);
|
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
|
* 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;
|
int tmp;
|
||||||
|
|
||||||
@ -311,7 +311,7 @@ static inline void ez80_waittxready(struct ez80_dev_s *priv)
|
|||||||
* Name: ez80_setbaud
|
* 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;
|
uint32_t brg_divisor;
|
||||||
uint8_t lctl;
|
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
|
#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 reg;
|
||||||
uint8_t cval;
|
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);
|
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 */
|
/* 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);
|
ez80_disableuartint(priv);
|
||||||
irq_detach(priv->irq);
|
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;
|
struct ez80_dev_s *priv;
|
||||||
volatile uint32_t cause;
|
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;
|
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 rbr = ez80_serialin(priv, EZ80_UART_RBR);
|
||||||
uint8_t lsr = ez80_serialin(priv, EZ80_UART_LSR);
|
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);
|
uint8_t ier = ez80_serialin(priv, EZ80_UART_IER);
|
||||||
|
|
||||||
if (enable)
|
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;
|
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);
|
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);
|
uint8_t ier = ez80_serialin(priv, EZ80_UART_IER);
|
||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
@ -623,13 +623,13 @@ static void ez80_txint(struct uart_dev_s *dev, bool enable)
|
|||||||
* Name: ez80_txready
|
* Name: ez80_txready
|
||||||
*
|
*
|
||||||
* Description:
|
* 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;
|
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;
|
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)
|
int up_putc(int ch)
|
||||||
{
|
{
|
||||||
#ifdef CONSOLE_DEV
|
#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);
|
uint8_t ier = ez80_serialin(priv, EZ80_UART_IER);
|
||||||
|
|
||||||
ez80_disableuartint(priv);
|
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_txready() ((ez80_inp(EZ80_UART_LSR) & EZ80_UARTLSR_THRE) != 0)
|
||||||
#define ez80_send(ch) ez80_outp(EZ80_UART_THR, ch)
|
#define ez80_send(ch) ez80_outp(EZ80_UART_THR, ch)
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Function Prototypes
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
#include <arch/board/board.h>
|
#include <arch/board/board.h>
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
@ -62,11 +63,19 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_CHIP_EZ80F91
|
#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
|
#else
|
||||||
# error "Check GPIO initialization for this chip"
|
# error "Check GPIO initialization for this chip"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define SPIF_RETRIES 1000
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Function Prototypes
|
* Private Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -178,7 +187,7 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
|||||||
* was awakened by a signal.
|
* was awakened by a signal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DEBUGASSERT(ret == OK || ret == -EINTR);
|
DEBUGASSERT(ret == OK || ret == -EINTR || ret == -ECANCELED);
|
||||||
}
|
}
|
||||||
while (ret == -EINTR);
|
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,
|
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev,
|
||||||
uint32_t frequency)
|
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
|
/* We want select divisor to provide the highest frequency (SPIR) that does
|
||||||
* NOT exceed the requested frequency.:
|
* 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)
|
* 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
|
/* "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
|
* 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)
|
else if (brg > 0xffff)
|
||||||
{
|
{
|
||||||
brg = 0xfff;
|
brg = 0xffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
outp(EZ80_SPI_BRG_L, brg & 0xff);
|
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;
|
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 modebits;
|
||||||
uint8_t regval;
|
uint8_t regval;
|
||||||
|
|
||||||
|
spiinfo("mode: %d\n", (int)mode);
|
||||||
|
|
||||||
/* Select the CTL register bits based on the selected mode */
|
/* Select the CTL register bits based on the selected mode */
|
||||||
|
|
||||||
switch (mode)
|
switch (mode)
|
||||||
@ -304,25 +319,34 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
|||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* 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;
|
uint8_t status;
|
||||||
|
int retries;
|
||||||
|
|
||||||
/* Wait for the device to be ready to accept another byte (or for an error
|
/* 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
|
* Send one byte on SPI, return the response
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* 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:
|
* Returned Value:
|
||||||
* response
|
* 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 */
|
/* Send the byte, repeating if some error occurs */
|
||||||
|
|
||||||
for (; ; )
|
for (; ; )
|
||||||
{
|
{
|
||||||
outp(EZ80_SPI_TSR, ch);
|
outp(EZ80_SPI_TSR, chout);
|
||||||
|
|
||||||
/* Wait for the device to be ready to accept another byte */
|
/* Wait for the device to be ready to accept another byte */
|
||||||
|
|
||||||
status = spi_waitspif();
|
ret = spi_waitspif();
|
||||||
if ((status & SPI_SR_SPIF) != 0)
|
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)
|
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 const uint8_t *inptr = (FAR const uint8_t *)txbuffer;
|
||||||
FAR uint8_t *outptr = (FAR const uint8_t *)rxbuffer;
|
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 */
|
/* Loop while there are bytes remaining to be sent */
|
||||||
|
|
||||||
while (nwords-- > 0)
|
while (nwords-- > 0)
|
||||||
{
|
{
|
||||||
|
uint8_t outword;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* Send 0xff if there is no outgoing TX stream */
|
/* 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)
|
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)
|
size_t buflen)
|
||||||
{
|
{
|
||||||
FAR const uint8_t *ptr = (FAR const uint8_t *)buffer;
|
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 */
|
/* Loop while there are bytes remaining to be sent */
|
||||||
|
|
||||||
while (buflen-- > 0)
|
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
|
#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;
|
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)
|
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
|
#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,
|
* 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
|
* 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.
|
* specific logic.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* Port number (for hardware that has mutiple SPI interfaces)
|
* Port number (for hardware that has multiple SPI interfaces)
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* 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
|
* GPIO ALT MASTER SLAVE COMMENT
|
||||||
* ---- ----- ------- ------- ---------------------------------
|
* ---- ----- ------- ------- ---------------------------------
|
||||||
* PB2 SS INPUT INPUT Managed by board specific logic
|
* PB2 SS INPUT INPUT Managed by board specific logic
|
||||||
* PB3 SCLK OUTPUT INPUT
|
* PB3 SCLK OUTPUT INPUT
|
||||||
* PB4 MISO INPUT OUTPUT
|
* PB6 MISO INPUT OUTPUT
|
||||||
* PB5 MOSI OUTPUT INPUT
|
* 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
|
#ifdef CONFIG_ARCH_CHIP_EZ80F91
|
||||||
@ -579,7 +653,7 @@ FAR struct spi_dev_s *ez80_spibus_initialize(int port)
|
|||||||
|
|
||||||
/* Enable the SPI.
|
/* Enable the SPI.
|
||||||
* NOTE 1: Interrupts are not used in this driver version.
|
* 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);
|
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.
|
placed in the card slot before the system is started.
|
||||||
|
|
||||||
STATUS:
|
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
|
using only the CPU and I/O expansion card. Console is provided over
|
||||||
USB.
|
USB.
|
||||||
|
|
||||||
Added support for SPI-based SD cards, the RTC and procFS. There are
|
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
|
still a few issues at the end-of-the-day: (1) the SD card initialization
|
||||||
is not being registered, and (2) RTC does not preserve time across a
|
hangs and prevents booting, and (2) RTC does not preserve time across a
|
||||||
power cycle.
|
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_STACKCREATED 0
|
||||||
#define LED_IDLE 0
|
#define LED_IDLE 0
|
||||||
#define LED_INIRQ 0
|
#define LED_INIRQ 0
|
||||||
#define LED_ASSERTION 1
|
#define LED_ASSERTION 0
|
||||||
#define LED_SIGNAL 0
|
#define LED_SIGNAL 0
|
||||||
#define LED_PANIC 1
|
#define LED_PANIC 1
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ CONFIG_ARCH_BOARD="makerlisp"
|
|||||||
CONFIG_ARCH_BOARD_MAKERLISP=y
|
CONFIG_ARCH_BOARD_MAKERLISP=y
|
||||||
CONFIG_ARCH_CHIP_EZ80=y
|
CONFIG_ARCH_CHIP_EZ80=y
|
||||||
CONFIG_ARCH_CHIP_EZ80F91=y
|
CONFIG_ARCH_CHIP_EZ80F91=y
|
||||||
|
CONFIG_ARCH_STACKDUMP=y
|
||||||
CONFIG_ARCH_Z80=y
|
CONFIG_ARCH_Z80=y
|
||||||
CONFIG_BOARD_LOOPSPERMSEC=1250
|
CONFIG_BOARD_LOOPSPERMSEC=1250
|
||||||
CONFIG_DISABLE_MQUEUE=y
|
CONFIG_DISABLE_MQUEUE=y
|
||||||
|
@ -43,6 +43,8 @@
|
|||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
|
|
||||||
|
#include "makerlisp.h"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -78,7 +80,7 @@ int ez80_bringup(void)
|
|||||||
#ifdef HAVE_MMCSD
|
#ifdef HAVE_MMCSD
|
||||||
/* Initialize SPI-based SD card slot */
|
/* Initialize SPI-based SD card slot */
|
||||||
|
|
||||||
ret = ez80_mmcsd_initialize(void);
|
ret = ez80_mmcsd_initialize();
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "ERROR: Failed to initialize SD card: %d\n", ret);
|
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;
|
uint8_t status = 0;
|
||||||
|
|
||||||
#ifdef HAVE_MMCSD_SPI
|
#ifdef HAVE_MMCSD
|
||||||
if (devid == SPIDEV_MMCSD(0))
|
if (devid == SPIDEV_MMCSD(0))
|
||||||
{
|
{
|
||||||
/* No card detect pin.. Always claim that the card is present in
|
/* No card detect pin.. Always claim that the card is present in
|
||||||
|
Loading…
Reference in New Issue
Block a user