mirror of
https://github.com/apache/nuttx.git
synced 2026-06-01 07:45:16 +08:00
arch/mips/src/pic32mz: Add support for the PIC32MZ timers (driver, lowerhalf, freerun and oneshot)
This commit is contained in:
committed by
Gregory Nutt
parent
d8943be51c
commit
06e27e5547
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
############################################################################
|
||||
# arch/mips/src/pic32mz/Make.defs
|
||||
#
|
||||
# Copyright (C) 2015, 2018 Gregory Nutt. All rights reserved.
|
||||
# Copyright (C) 2015, 2018, 2019 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -90,6 +90,24 @@ ifeq ($(CONFIG_PIC32MZ_I2C),y)
|
||||
CHIP_CSRCS += pic32mz-i2c.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PIC32MZ_TIMER),y)
|
||||
CHIP_CSRCS += pic32mz-timer.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_TIMER),y)
|
||||
CHIP_CSRCS += pic32mz-timer-lowerhalf.c
|
||||
else ifeq ($(CONFIG_PIC32MZ_ONESHOT),y)
|
||||
CHIP_CSRCS += pic32mz-timer-lowerhalf.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PIC32MZ_FREERUN),y)
|
||||
CHIP_CSRCS += pic32mz-freerun.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PIC32MZ_ONESHOT),y)
|
||||
CHIP_CSRCS += pic32mz-oneshot.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PIC32MZ_ETHERNET),y)
|
||||
CHIP_CSRCS += pic32mz-ethernet.c
|
||||
endif
|
||||
|
||||
@@ -33,8 +33,8 @@
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifndef __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_TIMER_H
|
||||
#define __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_TIMER_H
|
||||
#ifndef __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_TIMER_H
|
||||
#define __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_TIMER_H
|
||||
|
||||
/************************************************************************************
|
||||
* Included Files
|
||||
@@ -308,4 +308,4 @@ extern "C"
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* CHIP_NTIMERS > 0 */
|
||||
#endif /* __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_TIMER_H */
|
||||
#endif /* __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_TIMER_H */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/********************************************************************************************
|
||||
* arch/mips/src/pic32mz/pic32mzec-pps.h
|
||||
*
|
||||
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2015, 2019 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -45,6 +45,7 @@
|
||||
/********************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
********************************************************************************************/
|
||||
|
||||
/* PPS Register Offsets *********************************************************************/
|
||||
|
||||
/* Peripheral pin select input register map */
|
||||
|
||||
@@ -55,14 +55,14 @@
|
||||
# define PIC32MZ_INT3R_OFFSET 0x140c
|
||||
# define PIC32MZ_INT4R_OFFSET 0x1410
|
||||
#define PIC32MZ_TnCKR_OFFSET(n) (0x1410 + ((n << 2)) /* n=2..9 */
|
||||
# define PIC32MZ_I2TKR_OFFSET 0x1418
|
||||
# define PIC32MZ_I3TKR_OFFSET 0x141c
|
||||
# define PIC32MZ_I4TKR_OFFSET 0x1420
|
||||
# define PIC32MZ_I5TKR_OFFSET 0x1424
|
||||
# define PIC32MZ_I6TKR_OFFSET 0x1428
|
||||
# define PIC32MZ_I7TKR_OFFSET 0x142c
|
||||
# define PIC32MZ_I8TKR_OFFSET 0x1430
|
||||
# define PIC32MZ_I9TKR_OFFSET 0x1434
|
||||
# define PIC32MZ_T2CKR_OFFSET 0x1418
|
||||
# define PIC32MZ_T3CKR_OFFSET 0x141c
|
||||
# define PIC32MZ_T4CKR_OFFSET 0x1420
|
||||
# define PIC32MZ_T5CKR_OFFSET 0x1424
|
||||
# define PIC32MZ_T6CKR_OFFSET 0x1428
|
||||
# define PIC32MZ_T7CKR_OFFSET 0x142c
|
||||
# define PIC32MZ_T8CKR_OFFSET 0x1430
|
||||
# define PIC32MZ_T9CKR_OFFSET 0x1434
|
||||
#define PIC32MZ_ICnR_OFFSET(n) (0x1434 + ((n << 2)) /* n=1..9 */
|
||||
# define PIC32MZ_IC1R_OFFSET 0x1438
|
||||
# define PIC32MZ_IC2R_OFFSET 0x143c
|
||||
@@ -189,14 +189,14 @@
|
||||
# define PIC32MZ_INT3R (PIC32MZ_SFR_K1BASE+PIC32MZ_INT3R_OFFSET)
|
||||
# define PIC32MZ_INT4R (PIC32MZ_SFR_K1BASE+PIC32MZ_INT4R_OFFSET)
|
||||
#define PIC32MZ_TnCKR(n) (PIC32MZ_SFR_K1BASE+PIC32MZ_TnCKR_OFFSET(n))
|
||||
# define PIC32MZ_I2TKR (PIC32MZ_SFR_K1BASE+PIC32MZ_I2TKR_OFFSET)
|
||||
# define PIC32MZ_I3TKR (PIC32MZ_SFR_K1BASE+PIC32MZ_I3TKR_OFFSET)
|
||||
# define PIC32MZ_I4TKR (PIC32MZ_SFR_K1BASE+PIC32MZ_I4TKR_OFFSET)
|
||||
# define PIC32MZ_I5TKR (PIC32MZ_SFR_K1BASE+PIC32MZ_I5TKR_OFFSET)
|
||||
# define PIC32MZ_I6TKR (PIC32MZ_SFR_K1BASE+PIC32MZ_I6TKR_OFFSET)
|
||||
# define PIC32MZ_I7TKR (PIC32MZ_SFR_K1BASE+PIC32MZ_I7TKR_OFFSET)
|
||||
# define PIC32MZ_I8TKR (PIC32MZ_SFR_K1BASE+PIC32MZ_I8TKR_OFFSET)
|
||||
# define PIC32MZ_I9TKR (PIC32MZ_SFR_K1BASE+PIC32MZ_I9TKR_OFFSET)
|
||||
# define PIC32MZ_T2CKR (PIC32MZ_SFR_K1BASE+PIC32MZ_T2CKR_OFFSET)
|
||||
# define PIC32MZ_T3CKR (PIC32MZ_SFR_K1BASE+PIC32MZ_T3CKR_OFFSET)
|
||||
# define PIC32MZ_T4CKR (PIC32MZ_SFR_K1BASE+PIC32MZ_T4CKR_OFFSET)
|
||||
# define PIC32MZ_T5CKR (PIC32MZ_SFR_K1BASE+PIC32MZ_T5CKR_OFFSET)
|
||||
# define PIC32MZ_T6CKR (PIC32MZ_SFR_K1BASE+PIC32MZ_T6CKR_OFFSET)
|
||||
# define PIC32MZ_T7CKR (PIC32MZ_SFR_K1BASE+PIC32MZ_T7CKR_OFFSET)
|
||||
# define PIC32MZ_T8CKR (PIC32MZ_SFR_K1BASE+PIC32MZ_T8CKR_OFFSET)
|
||||
# define PIC32MZ_T9CKR (PIC32MZ_SFR_K1BASE+PIC32MZ_T9CKR_OFFSET)
|
||||
#define PIC32MZ_ICnR(n) (PIC32MZ_SFR_K1BASE+PIC32MZ_ICnR_OFFSET(n))
|
||||
# define PIC32MZ_IC1R (PIC32MZ_SFR_K1BASE+PIC32MZ_IC1R_OFFSET)
|
||||
# define PIC32MZ_IC2R (PIC32MZ_SFR_K1BASE+PIC32MZ_IC2R_OFFSET)
|
||||
|
||||
@@ -0,0 +1,335 @@
|
||||
/****************************************************************************
|
||||
* arch/mips/src/pic32mz/chip/pic32mz-freerun.c
|
||||
*
|
||||
* Copyright (C) 2019 Abdelatif Guettouche. All rights reserved.
|
||||
* Author: Abdelatif Guettouche <abdelatif.guettouche@gmail.com>
|
||||
*
|
||||
* This file is a part of NuttX:
|
||||
*
|
||||
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
|
||||
*
|
||||
* 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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/clock.h>
|
||||
|
||||
#include "pic32mz-freerun.h"
|
||||
|
||||
#ifdef CONFIG_PIC32MZ_FREERUN
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_CLOCK_TIMEKEEPING
|
||||
static int pic32mz_freerun_handler(int irq, void *context, void *arg);
|
||||
#endif /* CONFIG_CLOCK_TIMEKEEPING */
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_freerun_handler
|
||||
*
|
||||
* Description:
|
||||
* Timer interrupt callback. When the freerun timer counter overflows,
|
||||
* this interrupt will occur. We will just increment an overflow count.
|
||||
*
|
||||
* Input Parameters:
|
||||
* irq Number of the IRQ that generated the interrupt
|
||||
* context Interrupt register state save info (architecture-specific)
|
||||
* arg An opaque argument provided when the interrupt was registered
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_CLOCK_TIMEKEEPING
|
||||
static int pic32mz_freerun_handler(int irq, void *context, void *arg)
|
||||
{
|
||||
struct pic32mz_freerun_s *freerun = (struct pic32mz_freerun_s *) arg;
|
||||
|
||||
DEBUGASSERT(freerun != NULL && freerun->overflow < UINT32_MAX);
|
||||
freerun->overflow++;
|
||||
|
||||
PIC32MZ_TIMER_ACKINT(freerun->timer);
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif /* CONFIG_CLOCK_TIMEKEEPING */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_freerun_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the freerun timer wrapper
|
||||
*
|
||||
* Input Parameters:
|
||||
* freerun Caller allocated instance of the freerun state structure
|
||||
* chan Timer counter channel to be used.
|
||||
* resolution The required resolution of the timer in units of
|
||||
* microseconds. NOTE that the range is restricted to the
|
||||
* range of uint16_t (excluding zero).
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int pic32mz_freerun_initialize(struct pic32mz_freerun_s *freerun, int chan,
|
||||
uint16_t resolution)
|
||||
{
|
||||
uint32_t freq;
|
||||
|
||||
tmrinfo("chan=%d resolution=%d usec\n", chan, resolution);
|
||||
DEBUGASSERT(freerun != NULL && resolution > 0);
|
||||
|
||||
freerun->timer = pic32mz_timer_init(chan);
|
||||
if (!freerun->timer)
|
||||
{
|
||||
tmrerr("ERROR: Failed to allocate timer%d\n", chan);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* Get the timer's frequency that corresponds to the requested resolution */
|
||||
|
||||
freq = USEC_PER_SEC / (uint32_t)resolution;
|
||||
|
||||
tmrinfo("Setting frequency=%luHz\n", freq);
|
||||
|
||||
if (!PIC32MZ_TIMER_SETFREQ(freerun->timer, freq))
|
||||
{
|
||||
tmrerr("Cannot set frequency=%luHz\n", freq);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* Initialize the remaining fields in the state structure.
|
||||
*
|
||||
* The timer's frequency might not be the same as requested,
|
||||
* due to the lack of prescale values. Get it from the driver.
|
||||
*/
|
||||
|
||||
freerun->freq = PIC32MZ_TIMER_GETFREQ(freerun->timer);
|
||||
freerun->width = PIC32MZ_TIMER_GETWIDTH(freerun->timer);
|
||||
freerun->chan = chan;
|
||||
freerun->running = false;
|
||||
|
||||
#ifdef CONFIG_CLOCK_TIMEKEEPING
|
||||
if (freerun->width == 32)
|
||||
{
|
||||
freerun->counter_mask = 0xffffffffull;
|
||||
}
|
||||
else
|
||||
{
|
||||
freerun->counter_mask = 0x0000ffffull;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_CLOCK_TIMEKEEPING
|
||||
freerun->overflow = 0;
|
||||
|
||||
/* Set up to receive the callback when the counter overflow occurs */
|
||||
|
||||
PIC32MZ_TIMER_ACKINT(freerun->timer);
|
||||
PIC32MZ_TIMER_SETISR(freerun->timer, pic32mz_freerun_handler, freerun);
|
||||
#endif
|
||||
|
||||
/* Set the period */
|
||||
|
||||
PIC32MZ_TIMER_SETPERIOD(freerun->timer,
|
||||
(uint32_t)((1ull << freerun->width) - 1ul));
|
||||
|
||||
/* Start the timer */
|
||||
|
||||
PIC32MZ_TIMER_START(freerun->timer);
|
||||
freerun->running = true;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_freerun_counter
|
||||
*
|
||||
* Description:
|
||||
* Read the counter register of the free-running timer.
|
||||
*
|
||||
* Input Parameters:
|
||||
* freerun Caller allocated instance of the freerun state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* pic32mz_freerun_initialize();
|
||||
* ts The location in which to return the time from the free-running
|
||||
* timer.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_CLOCK_TIMEKEEPING
|
||||
|
||||
int pic32mz_freerun_counter(struct pic32mz_freerun_s *freerun,
|
||||
struct timespec *ts)
|
||||
{
|
||||
uint64_t usec;
|
||||
uint32_t counter;
|
||||
uint32_t verify;
|
||||
uint32_t overflow;
|
||||
uint32_t sec;
|
||||
bool pending;
|
||||
irqstate_t flags;
|
||||
|
||||
DEBUGASSERT(freerun && freerun->timer && ts);
|
||||
|
||||
/* Temporarily disable the overflow counter. */
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
overflow = freerun->overflow;
|
||||
counter = PIC32MZ_TIMER_GETCOUNTER(freerun->timer);
|
||||
pending = PIC32MZ_TIMER_CHECKINT(freerun->timer);
|
||||
verify = PIC32MZ_TIMER_GETCOUNTER(freerun->timer);
|
||||
|
||||
/* If an interrupt was pending before we re-enabled interrupts,
|
||||
* then the overflow needs to be incremented.
|
||||
*/
|
||||
|
||||
if (pending)
|
||||
{
|
||||
PIC32MZ_TIMER_ACKINT(freerun->timer);
|
||||
|
||||
/* Increment the overflow count and use the value of the
|
||||
* guaranteed to be AFTER the overflow occurred.
|
||||
*/
|
||||
|
||||
overflow++;
|
||||
counter = verify;
|
||||
|
||||
/* Update freerun overflow counter. */
|
||||
|
||||
freerun->overflow = overflow;
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
|
||||
tmrinfo("counter=%lu (%lu) overflow=%lu, pending=%i\n",
|
||||
(unsigned long)counter, (unsigned long)verify,
|
||||
(unsigned long)overflow, pending);
|
||||
tmrinfo("frequency=%u\n", freerun->freq);
|
||||
|
||||
/* Convert the whole thing to units of microseconds.
|
||||
*
|
||||
* frequency = ticks / second
|
||||
* seconds = ticks * frequency
|
||||
* usecs = (ticks * USEC_PER_SEC) / frequency;
|
||||
*/
|
||||
|
||||
usec = ((((uint64_t)overflow << freerun->width) +
|
||||
(uint64_t)counter) * USEC_PER_SEC) / freerun->freq;
|
||||
|
||||
/* And return the value of the timer */
|
||||
|
||||
sec = (uint32_t)(usec / USEC_PER_SEC);
|
||||
ts->tv_sec = sec;
|
||||
ts->tv_nsec = (usec - (sec * USEC_PER_SEC)) * NSEC_PER_USEC;
|
||||
|
||||
tmrinfo("usec=%llu ts=(%u, %lu)\n",
|
||||
usec, (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
#else /* CONFIG_CLOCK_TIMEKEEPING */
|
||||
|
||||
int pic32mz_freerun_counter(struct pic32mz_freerun_s *freerun,
|
||||
uint64_t *counter)
|
||||
{
|
||||
*counter = (uint64_t)PIC32MZ_TIMER_GETCOUNTER(freerun->timer) &
|
||||
freerun->counter_mask;
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_CLOCK_TIMEKEEPING */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_freerun_uninitialize
|
||||
*
|
||||
* Description:
|
||||
* Stop the free-running timer and release all resources that it uses.
|
||||
*
|
||||
* Input Parameters:
|
||||
* freerun Caller allocated instance of the freerun state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* pic32mz_freerun_initialize();
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int pic32mz_freerun_uninitialize(struct pic32mz_freerun_s *freerun)
|
||||
{
|
||||
DEBUGASSERT(freerun && freerun->timer);
|
||||
|
||||
/* Now we can disable the timer interrupt */
|
||||
|
||||
PIC32MZ_TIMER_SETISR(freerun->timer, NULL, NULL);
|
||||
|
||||
/* Free the timer, this will stop the timer as well */
|
||||
|
||||
pic32mz_timer_deinit(freerun->timer);
|
||||
|
||||
freerun->running = false;
|
||||
freerun->timer = NULL;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PIC32MZ_FREERUN */
|
||||
@@ -0,0 +1,179 @@
|
||||
/****************************************************************************
|
||||
* arch/mips/src/pic32mz/chip/pic32mz-freerun.h
|
||||
*
|
||||
* Copyright (C) 2019 Abdelatif Guettouche. All rights reserved.
|
||||
* Author: Abdelatif Guettouche <abdelatif.guettouche@gmail.com>
|
||||
*
|
||||
* This file is a part of NuttX:
|
||||
*
|
||||
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_FREERUN_H
|
||||
#define __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_FREERUN_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "pic32mz-timer.h"
|
||||
|
||||
#ifdef CONFIG_PIC32MZ_FREERUN
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* The freerun client must allocate an instance of this structure and call
|
||||
* pic32mz_freerun_initialize() before using the freerun facilities.
|
||||
* The client should not access the contents of this structure directly
|
||||
* since the contents are subject to change.
|
||||
*/
|
||||
|
||||
struct pic32mz_freerun_s
|
||||
{
|
||||
uint8_t chan; /* The timer in use */
|
||||
uint8_t width; /* Width of timer (16- or 32) */
|
||||
bool running; /* True: the timer is running */
|
||||
FAR struct pic32mz_timer_dev_s *timer; /* PIC32MZ timer driver */
|
||||
uint32_t freq; /* Timer's frequency (Hz) */
|
||||
|
||||
#ifndef CONFIG_CLOCK_TIMEKEEPING
|
||||
uint32_t overflow; /* Timer's counter overflow */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CLOCK_TIMEKEEPING
|
||||
uint64_t counter_mask; /* Timer's count register mask */
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_freerun_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the freerun timer wrapper
|
||||
*
|
||||
* Input Parameters:
|
||||
* freerun Caller allocated instance of the freerun state structure
|
||||
* chan Timer channel to be used.
|
||||
* resolution The required resolution of the timer in units of
|
||||
* microseconds. NOTE that the range is restricted to the
|
||||
* range of uint16_t (excluding zero).
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int pic32mz_freerun_initialize(struct pic32mz_freerun_s *freerun, int chan,
|
||||
uint16_t resolution);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_freerun_counter
|
||||
*
|
||||
* Description:
|
||||
* Read the counter register of the free-running timer.
|
||||
*
|
||||
* Input Parameters:
|
||||
* freerun Caller allocated instance of the freerun state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* pic32mz_freerun_initialize();
|
||||
* ts The location in which to return the time remaining on the
|
||||
* oneshot timer.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_CLOCK_TIMEKEEPING
|
||||
|
||||
int pic32mz_freerun_counter(struct pic32mz_freerun_s *freerun,
|
||||
struct timespec *ts);
|
||||
|
||||
#else /* CONFIG_CLOCK_TIMEKEEPING */
|
||||
|
||||
int pic32mz_freerun_counter(struct pic32mz_freerun_s *freerun,
|
||||
uint64_t *counter);
|
||||
|
||||
#endif /* CONFIG_CLOCK_TIMEKEEPING */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_freerun_uninitialize
|
||||
*
|
||||
* Description:
|
||||
* Stop the free-running timer and release all resources that it uses.
|
||||
*
|
||||
* Input Parameters:
|
||||
* freerun Caller allocated instance of the freerun state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* pic32mz_freerun_initialize();
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int pic32mz_freerun_uninitialize(struct pic32mz_freerun_s *freerun);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_PIC32MZ_FREERUN */
|
||||
#endif /* __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_FREERUN_H */
|
||||
@@ -0,0 +1,353 @@
|
||||
/****************************************************************************
|
||||
* arch/mips/src/pic32mz/chip/pic32mz-oneshot-lowerhalf.c
|
||||
*
|
||||
* Copyright (C) 2019 Abdelatif Guettouche. All rights reserved.
|
||||
* Author: Abdelatif Guettouche <abdelatif.guettouche@gmail.com>
|
||||
*
|
||||
* This file is a part of NuttX:
|
||||
*
|
||||
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/timers/oneshot.h>
|
||||
|
||||
#include "pic32mz-oneshot.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* This structure describes the state of the oneshot lower-half driver */
|
||||
|
||||
struct pic32mz_oneshot_lowerhalf_s
|
||||
{
|
||||
/* This is the part of the lower half driver that is visible to the upper-
|
||||
* half client of the driver. This must be the first thing in this
|
||||
* structure so that pointers to struct oneshot_lowerhalf_s are cast
|
||||
* compatible to struct pic32mz_oneshot_lowerhalf_s and vice versa.
|
||||
*/
|
||||
|
||||
struct oneshot_lowerhalf_s lh; /* Common lower-half driver fields */
|
||||
|
||||
/* Private lower half data follows */
|
||||
|
||||
struct pic32mz_oneshot_s oneshot; /* PIC32MZ-specific oneshot state */
|
||||
oneshot_callback_t callback; /* Handler that receives callback */
|
||||
FAR void *arg; /* Argument passed to the handler */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static void pic32mz_oneshot_handler(void *arg);
|
||||
|
||||
static int pic32mz_max_delay(FAR struct oneshot_lowerhalf_s *lower,
|
||||
FAR struct timespec *ts);
|
||||
static int pic32mz_start(FAR struct oneshot_lowerhalf_s *lower,
|
||||
oneshot_callback_t callback, FAR void *arg,
|
||||
FAR const struct timespec *ts);
|
||||
static int pic32mz_cancel(FAR struct oneshot_lowerhalf_s *lower,
|
||||
FAR struct timespec *ts);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Lower half operations */
|
||||
|
||||
static const struct oneshot_operations_s g_oneshot_ops =
|
||||
{
|
||||
.max_delay = pic32mz_max_delay,
|
||||
.start = pic32mz_start,
|
||||
.cancel = pic32mz_cancel,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_oneshot_handler
|
||||
*
|
||||
* Description:
|
||||
* Timer expiration handler
|
||||
*
|
||||
* Input Parameters:
|
||||
* arg Should be the same argument provided when pic32mz_oneshot_start()
|
||||
* was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void pic32mz_oneshot_handler(void *arg)
|
||||
{
|
||||
FAR struct pic32mz_oneshot_lowerhalf_s *priv =
|
||||
(FAR struct pic32mz_oneshot_lowerhalf_s *)arg;
|
||||
oneshot_callback_t callback;
|
||||
FAR void *cbarg;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
/* Perhaps the callback was nullified in a race condition with
|
||||
* pic32mz_cancel?
|
||||
*/
|
||||
|
||||
if (priv->callback)
|
||||
{
|
||||
/* Sample and nullify BEFORE executing callback (in case the callback
|
||||
* restarts the oneshot).
|
||||
*/
|
||||
|
||||
callback = priv->callback;
|
||||
cbarg = priv->arg;
|
||||
priv->callback = NULL;
|
||||
priv->arg = NULL;
|
||||
|
||||
/* Then perform the callback */
|
||||
|
||||
callback(&priv->lh, cbarg);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_max_delay
|
||||
*
|
||||
* Description:
|
||||
* Determine the maximum delay of the one-shot timer (in microseconds)
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower An instance of the lower-half oneshot state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* oneshot_initialize();
|
||||
* ts The location in which to return the maxumum delay.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int pic32mz_max_delay(FAR struct oneshot_lowerhalf_s *lower,
|
||||
FAR struct timespec *ts)
|
||||
{
|
||||
FAR struct pic32mz_oneshot_lowerhalf_s *priv =
|
||||
(FAR struct pic32mz_oneshot_lowerhalf_s *)lower;
|
||||
uint64_t usecs;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(priv != NULL && ts != NULL);
|
||||
|
||||
ret = pic32mz_oneshot_max_delay(&priv->oneshot, &usecs);
|
||||
tmrinfo("max delay %lu\n", usecs);
|
||||
|
||||
if (ret >= 0)
|
||||
{
|
||||
uint64_t sec = usecs / 1000000;
|
||||
usecs -= 1000000 * sec;
|
||||
|
||||
ts->tv_sec = (time_t)sec;
|
||||
ts->tv_nsec = (long)(usecs * 1000);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_start
|
||||
*
|
||||
* Description:
|
||||
* Start the oneshot timer
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower An instance of the lower-half oneshot state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* oneshot_initialize();
|
||||
* handler The function to call when when the oneshot timer expires.
|
||||
* arg An opaque argument that will accompany the callback.
|
||||
* ts Provides the duration of the one shot timer.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int pic32mz_start(FAR struct oneshot_lowerhalf_s *lower,
|
||||
oneshot_callback_t callback, FAR void *arg,
|
||||
FAR const struct timespec *ts)
|
||||
{
|
||||
FAR struct pic32mz_oneshot_lowerhalf_s *priv =
|
||||
(FAR struct pic32mz_oneshot_lowerhalf_s *)lower;
|
||||
irqstate_t flags;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(priv != NULL && callback != NULL && ts != NULL);
|
||||
|
||||
/* Save the callback information and start the timer */
|
||||
|
||||
flags = enter_critical_section();
|
||||
priv->callback = callback;
|
||||
priv->arg = arg;
|
||||
ret = pic32mz_oneshot_start(&priv->oneshot,
|
||||
pic32mz_oneshot_handler,
|
||||
priv, ts);
|
||||
leave_critical_section(flags);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
tmrerr("ERROR: pic32mz_oneshot_start failed: %d\n", flags);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_cancel
|
||||
*
|
||||
* Description:
|
||||
* Cancel the oneshot timer and return the time remaining on the timer.
|
||||
*
|
||||
* NOTE: This function may execute at a high rate with no timer running (as
|
||||
* when pre-emption is enabled and disabled).
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower Caller allocated instance of the oneshot state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* oneshot_initialize();
|
||||
* ts The location in which to return the time remaining on the
|
||||
* oneshot timer. A time of zero is returned if the timer is
|
||||
* not running.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success. A call to up_timer_cancel() when
|
||||
* the timer is not active should also return success; a negated errno
|
||||
* value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int pic32mz_cancel(FAR struct oneshot_lowerhalf_s *lower,
|
||||
FAR struct timespec *ts)
|
||||
{
|
||||
FAR struct pic32mz_oneshot_lowerhalf_s *priv =
|
||||
(FAR struct pic32mz_oneshot_lowerhalf_s *)lower;
|
||||
irqstate_t flags;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
/* Cancel the timer */
|
||||
|
||||
flags = enter_critical_section();
|
||||
ret = pic32mz_oneshot_cancel(&priv->oneshot, ts);
|
||||
priv->callback = NULL;
|
||||
priv->arg = NULL;
|
||||
leave_critical_section(flags);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
tmrerr("ERROR: pic32mz_oneshot_cancel failed: %d\n", flags);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: oneshot_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the oneshot timer and return a oneshot lower half driver
|
||||
* instance.
|
||||
*
|
||||
* Input Parameters:
|
||||
* chan Timer counter channel to be used.
|
||||
* resolution The required resolution of the timer in units of
|
||||
* microseconds. NOTE that the range is restricted to the
|
||||
* range of uint16_t (excluding zero).
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, a non-NULL instance of the oneshot lower-half driver is
|
||||
* returned. NULL is return on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct oneshot_lowerhalf_s *oneshot_initialize(int chan,
|
||||
uint16_t resolution)
|
||||
{
|
||||
FAR struct pic32mz_oneshot_lowerhalf_s *priv;
|
||||
int ret;
|
||||
|
||||
/* Allocate an instance of the lower half driver */
|
||||
|
||||
priv = (FAR struct pic32mz_oneshot_lowerhalf_s *)
|
||||
kmm_zalloc(sizeof(struct pic32mz_oneshot_lowerhalf_s));
|
||||
|
||||
if (priv == NULL)
|
||||
{
|
||||
tmrerr("ERROR: Failed to initialized state structure\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize the lower-half driver structure */
|
||||
|
||||
priv->lh.ops = &g_oneshot_ops;
|
||||
|
||||
/* Initialize the contained PIC32MZ oneshot timer */
|
||||
|
||||
ret = pic32mz_oneshot_initialize(&priv->oneshot, chan, resolution);
|
||||
if (ret < 0)
|
||||
{
|
||||
tmrerr("ERROR: pic32mz_oneshot_initialize failed: %d\n", ret);
|
||||
kmm_free(priv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &priv->lh;
|
||||
}
|
||||
@@ -0,0 +1,464 @@
|
||||
/****************************************************************************
|
||||
* arch/mips/src/pic32mz/chip/pic32mz-oneshot.c
|
||||
*
|
||||
* Copyright (C) 2019 Abdelatif Guettouche. All rights reserved.
|
||||
* Author: Abdelatif Guettouche <abdelatif.guettouche@gmail.com>
|
||||
*
|
||||
* This file is a part of NuttX:
|
||||
*
|
||||
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
|
||||
*
|
||||
* 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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <sched.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/clock.h>
|
||||
|
||||
#include "pic32mz-oneshot.h"
|
||||
|
||||
#ifdef CONFIG_PIC32MZ_ONESHOT
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static int pic32mz_oneshot_handler(int irg_num, void * context, void *arg);
|
||||
static inline int pic32mz_allocate_handler(struct pic32mz_oneshot_s *oneshot);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct pic32mz_oneshot_s *g_oneshot[CONFIG_PIC32MZ_ONESHOT_MAXTIMERS];
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_oneshot_handler
|
||||
*
|
||||
* Description:
|
||||
* Common timer interrupt callback. When any oneshot timer interrupt
|
||||
* expires, this function will be called. It will forward the call to
|
||||
* the next level up.
|
||||
*
|
||||
* Input Parameters:
|
||||
* oneshot The state associated with the expired timer
|
||||
*
|
||||
* Returned Value:
|
||||
* Always returns OK
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int pic32mz_oneshot_handler(int irg_num, void * context, void *arg)
|
||||
{
|
||||
struct pic32mz_oneshot_s * oneshot = (struct pic32mz_oneshot_s *) arg;
|
||||
oneshot_handler_t oneshot_handler;
|
||||
void *oneshot_arg;
|
||||
|
||||
tmrinfo("Expired...\n");
|
||||
DEBUGASSERT(oneshot != NULL && oneshot->handler);
|
||||
|
||||
/* Stop the timer and disable any further interrupts */
|
||||
|
||||
PIC32MZ_TIMER_ACKINT(oneshot->timer);
|
||||
PIC32MZ_TIMER_SETISR(oneshot->timer, NULL, NULL);
|
||||
PIC32MZ_TIMER_STOP(oneshot->timer);
|
||||
|
||||
/* The timer is no longer running */
|
||||
|
||||
oneshot->running = false;
|
||||
|
||||
/* Forward the event, clearing out any vestiges */
|
||||
|
||||
oneshot_handler = (oneshot_handler_t)oneshot->handler;
|
||||
oneshot->handler = NULL;
|
||||
oneshot_arg = (void *)oneshot->arg;
|
||||
oneshot->arg = NULL;
|
||||
|
||||
oneshot_handler(oneshot_arg);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_allocate_handler
|
||||
*
|
||||
* Description:
|
||||
* Allocate a timer callback handler for the oneshot instance.
|
||||
*
|
||||
* Input Parameters:
|
||||
* oneshot The state instance the new oneshot timer
|
||||
*
|
||||
* Returned Value:
|
||||
* Returns zero (OK) on success. This can only fail if the number of
|
||||
* timers exceeds CONFIG_PIC32MZ_ONESHOT_MAXTIMERS.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline int pic32mz_allocate_handler(struct pic32mz_oneshot_s *oneshot)
|
||||
{
|
||||
#if CONFIG_PIC32MZ_ONESHOT_MAXTIMERS > 1
|
||||
int ret = -EBUSY;
|
||||
int i;
|
||||
|
||||
/* Search for an unused handler */
|
||||
|
||||
sched_lock();
|
||||
for (i = 0; i < CONFIG_PIC32MZ_ONESHOT_MAXTIMERS; i++)
|
||||
{
|
||||
/* Is this handler available? */
|
||||
|
||||
if (g_oneshot[i] == NULL)
|
||||
{
|
||||
/* Yes... assign it to this oneshot */
|
||||
|
||||
g_oneshot[i] = oneshot;
|
||||
oneshot->cbndx = i;
|
||||
ret = OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
return ret;
|
||||
|
||||
#else
|
||||
if (g_oneshot[0] == NULL)
|
||||
{
|
||||
g_oneshot[0] = oneshot;
|
||||
return OK;
|
||||
}
|
||||
|
||||
return -EBUSY;
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_oneshot_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the oneshot timer wrapper
|
||||
*
|
||||
* Input Parameters:
|
||||
* oneshot Caller allocated instance of the oneshot state structure
|
||||
* chan Timer counter channel to be used.
|
||||
* resolution The required resolution of the timer in units of
|
||||
* microseconds. NOTE that the range is restricted to the
|
||||
* range of uint16_t (excluding zero).
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int pic32mz_oneshot_initialize(struct pic32mz_oneshot_s *oneshot, int chan,
|
||||
uint16_t resolution)
|
||||
{
|
||||
uint32_t freq;
|
||||
|
||||
tmrinfo("chan=%d resolution=%d usec\n", chan, resolution);
|
||||
DEBUGASSERT(oneshot && resolution > 0);
|
||||
|
||||
oneshot->timer = pic32mz_timer_init(chan);
|
||||
if (!oneshot->timer)
|
||||
{
|
||||
tmrerr("ERROR: Failed to allocate timer%d\n", chan);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* Get the timer's frequency that corresponds to the requested resolution */
|
||||
|
||||
freq = USEC_PER_SEC / (uint32_t)resolution;
|
||||
tmrinfo("Setting frequency=%luHz\n", freq);
|
||||
|
||||
if (!PIC32MZ_TIMER_SETFREQ(oneshot->timer, freq))
|
||||
{
|
||||
tmrerr("Cannot set frequency=%luHz\n", freq);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* Initialize the remaining fields in the state structure.
|
||||
*
|
||||
* The timer's frequency might not be the same as requested,
|
||||
* due to the lack of prescale values. Get it from the driver.
|
||||
*/
|
||||
|
||||
oneshot->freq = PIC32MZ_TIMER_GETFREQ(oneshot->timer);
|
||||
oneshot->width = PIC32MZ_TIMER_GETWIDTH(oneshot->timer);
|
||||
oneshot->chan = chan;
|
||||
oneshot->running = false;
|
||||
oneshot->handler = NULL;
|
||||
oneshot->arg = NULL;
|
||||
|
||||
/* Assign a callback handler to the oneshot */
|
||||
|
||||
return pic32mz_allocate_handler(oneshot);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_oneshot_max_delay
|
||||
*
|
||||
* Description:
|
||||
* Determine the maximum delay of the one-shot timer (in microseconds)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int pic32mz_oneshot_max_delay(struct pic32mz_oneshot_s *oneshot,
|
||||
uint64_t *usec)
|
||||
{
|
||||
uint32_t maxticks;
|
||||
|
||||
maxticks = (1ull << oneshot->width) - 1ul;
|
||||
|
||||
DEBUGASSERT(oneshot != NULL && usec != NULL);
|
||||
tmrinfo("width=%u freq=%lu max ticks=%lu\n",
|
||||
oneshot->width, oneshot->freq, maxticks);
|
||||
|
||||
*usec = (maxticks / oneshot->freq) * USEC_PER_SEC;
|
||||
|
||||
tmrinfo("max delay %lu\n", *usec);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_oneshot_start
|
||||
*
|
||||
* Description:
|
||||
* Start the oneshot timer
|
||||
*
|
||||
* Input Parameters:
|
||||
* oneshot Caller allocated instance of the oneshot state structure.
|
||||
* This structure must have been previously initialized via
|
||||
* a call to pic32mz_oneshot_initialize();
|
||||
* handler The function to call when when the oneshot timer expires.
|
||||
* arg An opaque argument that will accompany the callback.
|
||||
* ts Provides the duration of the one shot timer.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int pic32mz_oneshot_start(struct pic32mz_oneshot_s *oneshot,
|
||||
oneshot_handler_t handler, void *arg,
|
||||
const struct timespec *ts)
|
||||
{
|
||||
uint64_t usec;
|
||||
uint64_t period;
|
||||
irqstate_t flags;
|
||||
|
||||
tmrinfo("handler=%p arg=%p, ts=(%lu, %lu)\n",
|
||||
handler, arg, (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec);
|
||||
DEBUGASSERT(oneshot && handler && ts);
|
||||
DEBUGASSERT(oneshot->timer);
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Was the oneshot already running? */
|
||||
|
||||
if (oneshot->running)
|
||||
{
|
||||
/* Yes.. then cancel it */
|
||||
|
||||
tmrinfo("Already running... cancelling\n");
|
||||
(void)pic32mz_oneshot_cancel(oneshot, NULL);
|
||||
}
|
||||
|
||||
/* Save the new handler and its argument */
|
||||
|
||||
oneshot->handler = handler;
|
||||
oneshot->arg = arg;
|
||||
|
||||
/* Express the delay in microseconds */
|
||||
|
||||
usec = (uint64_t)ts->tv_sec * USEC_PER_SEC +
|
||||
(uint64_t)(ts->tv_nsec / NSEC_PER_USEC);
|
||||
|
||||
period = (usec * (uint64_t)oneshot->freq) / USEC_PER_SEC;
|
||||
|
||||
tmrinfo("usec=%llu period=%08llx\n", usec, period);
|
||||
DEBUGASSERT(period <= ((1ull << oneshot->width) - 1ul));
|
||||
|
||||
/* Set timer period */
|
||||
|
||||
oneshot->period = (uint32_t)period;
|
||||
PIC32MZ_TIMER_SETPERIOD(oneshot->timer, (uint32_t)period);
|
||||
|
||||
/* Set up to receive the callback and start the timer */
|
||||
|
||||
PIC32MZ_TIMER_ACKINT(oneshot->timer);
|
||||
PIC32MZ_TIMER_SETISR(oneshot->timer, pic32mz_oneshot_handler, oneshot);
|
||||
PIC32MZ_TIMER_START(oneshot->timer);
|
||||
|
||||
oneshot->running = true;
|
||||
leave_critical_section(flags);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_oneshot_cancel
|
||||
*
|
||||
* Description:
|
||||
* Cancel the oneshot timer and return the time remaining on the timer.
|
||||
*
|
||||
* NOTE: This function may execute at a high rate with no timer running (as
|
||||
* when pre-emption is enabled and disabled).
|
||||
*
|
||||
* Input Parameters:
|
||||
* oneshot Caller allocated instance of the oneshot state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* pic32mz_oneshot_initialize();
|
||||
* ts The location in which to return the time remaining on the
|
||||
* oneshot timer. A time of zero is returned if the timer is
|
||||
* not running. ts may be zero in which case the time remaining
|
||||
* is not returned.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success. A call to up_timer_cancel() when
|
||||
* the timer is not active should also return success; a negated errno
|
||||
* value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int pic32mz_oneshot_cancel(struct pic32mz_oneshot_s *oneshot,
|
||||
struct timespec *ts)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint64_t usec;
|
||||
uint64_t sec;
|
||||
uint64_t nsec;
|
||||
uint32_t count;
|
||||
uint32_t period;
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Was the timer running? */
|
||||
|
||||
if (!oneshot->running)
|
||||
{
|
||||
/* No.. Just return zero timer remaining and successful cancellation.
|
||||
* This function may execute at a high rate with no timer running
|
||||
* (as when pre-emption is enabled and disabled).
|
||||
*/
|
||||
|
||||
ts->tv_sec = 0;
|
||||
ts->tv_nsec = 0;
|
||||
leave_critical_section(flags);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Yes.. Get the timer counter and period registers and stop the counter. */
|
||||
|
||||
tmrinfo("Cancelling...\n");
|
||||
|
||||
count = PIC32MZ_TIMER_GETCOUNTER(oneshot->timer);
|
||||
period = oneshot->period;
|
||||
|
||||
PIC32MZ_TIMER_SETISR(oneshot->timer, NULL, NULL);
|
||||
PIC32MZ_TIMER_STOP(oneshot->timer);
|
||||
|
||||
oneshot->running = false;
|
||||
oneshot->handler = NULL;
|
||||
oneshot->arg = NULL;
|
||||
leave_critical_section(flags);
|
||||
|
||||
/* Did the caller provide us with a location to return the time
|
||||
* remaining?
|
||||
*/
|
||||
|
||||
if (ts)
|
||||
{
|
||||
/* Yes.. then calculate and return the time remaining on the
|
||||
* oneshot timer.
|
||||
*/
|
||||
|
||||
tmrinfo("period=%lu count=%lu\n",
|
||||
(unsigned long)period, (unsigned long)count);
|
||||
|
||||
if (count >= period)
|
||||
{
|
||||
/* No time remaining (?) */
|
||||
|
||||
ts->tv_sec = 0;
|
||||
ts->tv_nsec = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The total time remaining is the difference. Convert the that
|
||||
* to units of microseconds.
|
||||
*
|
||||
* frequency = ticks / second
|
||||
* seconds = ticks * frequency
|
||||
* usecs = (ticks * USEC_PER_SEC) / frequency;
|
||||
*/
|
||||
|
||||
usec = (((uint64_t)(period - count)) * USEC_PER_SEC) /
|
||||
oneshot->freq;
|
||||
|
||||
/* Return the time remaining in the correct form */
|
||||
|
||||
sec = usec / USEC_PER_SEC;
|
||||
nsec = ((usec) - (sec * USEC_PER_SEC)) * NSEC_PER_USEC;
|
||||
|
||||
ts->tv_sec = (time_t)sec;
|
||||
ts->tv_nsec = (unsigned long)nsec;
|
||||
}
|
||||
|
||||
tmrinfo("remaining (%lu, %lu)\n",
|
||||
(unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PIC32MZ_ONESHOT */
|
||||
@@ -0,0 +1,208 @@
|
||||
/****************************************************************************
|
||||
* arch/mips/src/pic32mz/chip/pic32mz-oneshort.h
|
||||
*
|
||||
* Copyright (C) 2019 Abdelatif Guettouche. All rights reserved.
|
||||
* Author: Abdelatif Guettouche <abdelatif.guettouche@gmail.com>
|
||||
*
|
||||
* This file is a part of NuttX:
|
||||
*
|
||||
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_ONESHOT_H
|
||||
#define __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_ONESHOT_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
|
||||
#include "pic32mz-timer.h"
|
||||
|
||||
#ifdef CONFIG_PIC32MZ_ONESHOT
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_PIC32MZ_ONESHOT_MAXTIMERS) || \
|
||||
CONFIG_PIC32MZ_ONESHOT_MAXTIMERS < 1
|
||||
# undef CONFIG_PIC32MZ_ONESHOT_MAXTIMERS
|
||||
# define CONFIG_PIC32MZ_ONESHOT_MAXTIMERS 1
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* This describes the callback function that will be invoked when the oneshot
|
||||
* timer expires. When the oneshot fires, the client will receive:
|
||||
*
|
||||
* arg - The opaque argument provided when the interrupt was registered
|
||||
*/
|
||||
|
||||
typedef void (*oneshot_handler_t)(void *arg);
|
||||
|
||||
/* The oneshot client must allocate an instance of this structure and called
|
||||
* pic32mz_oneshot_initialize() before using the oneshot facilities.
|
||||
* The client should not access the contents of this structure directly
|
||||
* since the contents are subject to change.
|
||||
*/
|
||||
|
||||
struct pic32mz_oneshot_s
|
||||
{
|
||||
uint8_t chan; /* The timer/counter in use */
|
||||
#if CONFIG_PIC32MZ_ONESHOT_MAXTIMERS > 1
|
||||
uint8_t cbndx; /* Timer callback handler index */
|
||||
#endif
|
||||
volatile bool running; /* True: the timer is running */
|
||||
FAR struct pic32mz_timer_dev_s *timer; /* PIC32MZ timer driver */
|
||||
volatile oneshot_handler_t handler; /* Oneshot expiration callback */
|
||||
volatile void *arg; /* Callback's argument */
|
||||
uint32_t freq; /* Timer's frequency */
|
||||
uint32_t period; /* Timer's period */
|
||||
uint8_t width; /* Timer's width */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_oneshot_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the oneshot timer wrapper
|
||||
*
|
||||
* Input Parameters:
|
||||
* oneshot Caller allocated instance of the oneshot state structure
|
||||
* chan Timer counter channel to be used.
|
||||
* resolution The required resolution of the timer in units of
|
||||
* microseconds. NOTE that the range is restricted to the
|
||||
* range of uint16_t (excluding zero).
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int pic32mz_oneshot_initialize(struct pic32mz_oneshot_s *oneshot, int chan,
|
||||
uint16_t resolution);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_oneshot_max_delay
|
||||
*
|
||||
* Description:
|
||||
* Determine the maximum delay of the one-shot timer (in microseconds)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int pic32mz_oneshot_max_delay(struct pic32mz_oneshot_s *oneshot,
|
||||
uint64_t *usec);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_oneshot_start
|
||||
*
|
||||
* Description:
|
||||
* Start the oneshot timer
|
||||
*
|
||||
* Input Parameters:
|
||||
* oneshot Caller allocated instance of the oneshot state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* pic32mz_oneshot_initialize();
|
||||
* handler The function to call when when the oneshot timer expires.
|
||||
* arg An opaque argument that will accompany the callback.
|
||||
* ts Provides the duration of the one shot timer.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int pic32mz_oneshot_start(struct pic32mz_oneshot_s *oneshot,
|
||||
oneshot_handler_t handler, void *arg,
|
||||
const struct timespec *ts);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_oneshot_cancel
|
||||
*
|
||||
* Description:
|
||||
* Cancel the oneshot timer and return the time remaining on the timer.
|
||||
*
|
||||
* NOTE: This function may execute at a high rate with no timer running (as
|
||||
* when pre-emption is enabled and disabled).
|
||||
*
|
||||
* Input Parameters:
|
||||
* oneshot Caller allocated instance of the oneshot state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* pic32mz_oneshot_initialize();
|
||||
* ts The location in which to return the time remaining on the
|
||||
* oneshot timer. A time of zero is returned if the timer is
|
||||
* not running.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success. A call to up_timer_cancel() when
|
||||
* the timer is not active should also return success; a negated errno
|
||||
* value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int pic32mz_oneshot_cancel(struct pic32mz_oneshot_s *oneshot,
|
||||
struct timespec *ts);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_PIC32MZ_ONESHOT */
|
||||
#endif /* __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_ONESHOT_H */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,167 @@
|
||||
/****************************************************************************
|
||||
* arch/mips/src/pic32mz/chip/pic32mz-timer.h
|
||||
*
|
||||
* Copyright (C) 2019 Abdelatif Guettouche. All rights reserved.
|
||||
* Author: Abdelatif Guettouche <abdelatif.guettouche@gmail.com>
|
||||
*
|
||||
* This file is a part of NuttX:
|
||||
*
|
||||
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_TIMER_H
|
||||
#define __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_TIMER_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/compiler.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Helpers ******************************************************************/
|
||||
|
||||
#define PIC32MZ_TIMER_START(d) ((d)->ops->start(d))
|
||||
#define PIC32MZ_TIMER_STOP(d) ((d)->ops->stop(d))
|
||||
#define PIC32MZ_TIMER_SETPERIOD(d,p) ((d)->ops->setperiod(d,p))
|
||||
#define PIC32MZ_TIMER_GETCOUNTER(d) ((d)->ops->getcounter(d))
|
||||
#define PIC32MZ_TIMER_SETCOUNTER(d,c) ((d)->ops->setcounter(d,c))
|
||||
#define PIC32MZ_TIMER_GETFREQ(d) ((d)->ops->getfreq(d))
|
||||
#define PIC32MZ_TIMER_SETFREQ(d,f) ((d)->ops->setfreq(d,f))
|
||||
#define PIC32MZ_TIMER_GETWIDTH(d) ((d)->ops->getwidth(d))
|
||||
|
||||
#define PIC32MZ_TIMER_SETISR(d,hnd,arg) ((d)->ops->setisr(d,hnd,arg))
|
||||
#define PIC32MZ_TIMER_ACKINT(d) ((d)->ops->ackint(d))
|
||||
#define PIC32MZ_TIMER_CHECKINT(d) ((d)->ops->checkint(d))
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/* Timer's Operations */
|
||||
|
||||
struct pic32mz_timer_dev_s; /* Forward reference */
|
||||
struct pic32mz_timer_ops_s
|
||||
{
|
||||
/* Timer's methods */
|
||||
|
||||
void (*start)(FAR struct pic32mz_timer_dev_s *dev);
|
||||
void (*stop)(FAR struct pic32mz_timer_dev_s *dev);
|
||||
void (*setperiod)(FAR struct pic32mz_timer_dev_s *dev, uint32_t p);
|
||||
uint32_t (*getcounter)(FAR struct pic32mz_timer_dev_s *dev);
|
||||
void (*setcounter)(FAR struct pic32mz_timer_dev_s *dev, uint32_t c);
|
||||
uint32_t (*getfreq)(FAR struct pic32mz_timer_dev_s *dev);
|
||||
bool (*setfreq)(FAR struct pic32mz_timer_dev_s *dev, uint32_t freq);
|
||||
uint8_t (*getwidth)(FAR struct pic32mz_timer_dev_s *dev);
|
||||
|
||||
/* Timer's interrupts */
|
||||
|
||||
int (*setisr)(FAR struct pic32mz_timer_dev_s *dev, xcpt_t handler,
|
||||
void * arg);
|
||||
void (*ackint)(FAR struct pic32mz_timer_dev_s *dev);
|
||||
bool (*checkint)(FAR struct pic32mz_timer_dev_s *dev);
|
||||
};
|
||||
|
||||
/* Timer's Device Structure */
|
||||
|
||||
struct pic32mz_timer_dev_s
|
||||
{
|
||||
FAR struct pic32mz_timer_ops_s *ops;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_timer_init
|
||||
*
|
||||
* Description:
|
||||
* Power-up the timer and get its structure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct pic32mz_timer_dev_s *pic32mz_timer_init(int timer);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_timer_deinit
|
||||
*
|
||||
* Description:
|
||||
* Power-down the timer and mark it as unused.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int pic32mz_timer_deinit(FAR struct pic32mz_timer_dev_s *dev);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_timer_initialize
|
||||
*
|
||||
* Description:
|
||||
* Bind the configuration timer to a timer lower half instance and
|
||||
* register the timer drivers at 'devpath'
|
||||
*
|
||||
* Input Parameters:
|
||||
* devpath The full path to the timer device.
|
||||
* This should be of the form /dev/timer0
|
||||
* timer The timer's number.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; A negated errno value is returned
|
||||
* to indicate the nature of any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_TIMER
|
||||
int pic32mz_timer_initialize(FAR const char *devpath, int timer);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_TIMER_H */
|
||||
Reference in New Issue
Block a user