Merged nuttx/arch into master

This commit is contained in:
Lok Tep 2015-11-11 16:56:19 +01:00
commit 4eed3afc79
4 changed files with 435 additions and 400 deletions

View File

@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* arch/arm/src/lpc43xx/lpc43_i2c.c * arch/arm/src/lpc43xx/lpc43_i2c.c
* *
* Copyright (C) 2012, 2014 Gregory Nutt. All rights reserved. * Copyright (C) 2012, 2014-2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Ported from from the LPC17 version: * Ported from from the LPC17 version:
@ -427,8 +427,15 @@ static int i2c_interrupt(int irq, FAR void *context)
case 0x08: /* A START condition has been transmitted. */ case 0x08: /* A START condition has been transmitted. */
case 0x10: /* A Repeated START condition has been transmitted. */ case 0x10: /* A Repeated START condition has been transmitted. */
putreg32(((I2C_M_READ & msg->flags) == I2C_M_READ)?I2C_READADDR8(msg->addr):I2C_WRITEADDR8(msg->addr), priv->base + LPC43_I2C_DAT_OFFSET); /* set address */ /* Set address */
putreg32(I2C_CONCLR_STAC, priv->base + LPC43_I2C_CONCLR_OFFSET); /* clear start bit */
putreg32(((I2C_M_READ & msg->flags) == I2C_M_READ) ?
I2C_READADDR8(msg->addr) :
I2C_WRITEADDR8(msg->addr), priv->base + LPC43_I2C_DAT_OFFSET);
/* Clear start bit */
putreg32(I2C_CONCLR_STAC, priv->base + LPC43_I2C_CONCLR_OFFSET);
break; break;
/* Write cases */ /* Write cases */

View File

@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* arch/arm/src/lpc43xx/lpc43_spi.c * arch/arm/src/lpc43xx/lpc43_spi.c
* *
* Copyright (C) 2012 Gregory Nutt. All rights reserved. * Copyright (C) 2015 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
@ -603,13 +603,16 @@ FAR struct spi_dev_s *lpc43_spiinitialize(int port)
FAR struct spi_dev_s *up_spiinitialize(int port) FAR struct spi_dev_s *up_spiinitialize(int port)
{ {
if (port) { if (port)
#if ( defined(CONFIG_LPC43_SSP0) || defined(CONFIG_LPC43_SSP1) ) {
return lpc43_sspinitialize(port-1); #if defined(CONFIG_LPC43_SSP0) || defined(CONFIG_LPC43_SSP1)
return lpc43_sspinitialize(port - 1);
#else #else
return NULL; return NULL;
#endif #endif
} else { }
else
{
#if defined(CONFIG_LPC43_SPI) #if defined(CONFIG_LPC43_SPI)
return lpc43_spiinitialize(port); return lpc43_spiinitialize(port);
#else #else
@ -617,6 +620,3 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
#endif #endif
} }
} }

View File

@ -137,6 +137,7 @@ static void ssp_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer
static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords); static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords);
static void ssp_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords); static void ssp_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords);
#endif #endif
/* Initialization */ /* Initialization */
#ifdef CONFIG_LPC43_SSP0 #ifdef CONFIG_LPC43_SSP0
@ -537,8 +538,30 @@ static uint16_t ssp_send(FAR struct spi_dev_s *dev, uint16_t wd)
return (uint16_t)regval; return (uint16_t)regval;
} }
/****************************************************************************
* Name: ssp_exchange
*
* Description:
* Exahange a block of data from SPI. Required.
*
* Input Parameters:
* dev - Device-specific state data
* txbuffer - A pointer to the buffer of data to be sent
* rxbuffer - A pointer to the buffer in which to receive data
* nwords - the length of data that to be exchanged in units of words.
* The wordsize is determined by the number of bits-per-word
* selected for the SPI interface. If nbits <= 8, the data is
* packed into uint8_t's; if nbits >8, the data is packed into
* uint16_t's
*
* Returned Value:
* None
*
****************************************************************************/
static void ssp_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, static void ssp_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
FAR void *rxbuffer, size_t nwords) { FAR void *rxbuffer, size_t nwords)
{
FAR struct lpc43_sspdev_s *priv = (FAR struct lpc43_sspdev_s *)dev; FAR struct lpc43_sspdev_s *priv = (FAR struct lpc43_sspdev_s *)dev;
union union
{ {
@ -553,7 +576,7 @@ static void ssp_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
FAR void *pv; FAR void *pv;
} rx; } rx;
uint32_t data; uint32_t data;
uint32_t datadummy = (priv->nbits > 8)?0xffff:0xff; uint32_t datadummy = (priv->nbits > 8) ? 0xffff : 0xff;
uint32_t rxpending = 0; uint32_t rxpending = 0;
/* While there is remaining to be sent (and no synchronization error has occurred) */ /* While there is remaining to be sent (and no synchronization error has occurred) */
@ -602,6 +625,7 @@ static void ssp_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
{ {
*rx.p8++ = (uint8_t)data; *rx.p8++ = (uint8_t)data;
} }
rxpending--; rxpending--;
} }
} }
@ -619,12 +643,14 @@ static void ssp_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
* nwords - the length of data to send from the buffer in number of words. * nwords - the length of data to send from the buffer in number of words.
* The wordsize is determined by the number of bits-per-word * The wordsize is determined by the number of bits-per-word
* selected for the SPI interface. If nbits <= 8, the data is * selected for the SPI interface. If nbits <= 8, the data is
* packed into uint8_t's; if nbits >8, the data is packed into uint16_t's * packed into uint8_t's; if nbits >8, the data is packed into
* uint16_t's
* *
* Returned Value: * Returned Value:
* None * None
* *
****************************************************************************/ ****************************************************************************/
#ifndef CONFIG_SPI_EXCHANGE #ifndef CONFIG_SPI_EXCHANGE
static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords) static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords)
{ {
@ -643,7 +669,8 @@ static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size
* nwords - the length of data that can be received in the buffer in number * nwords - the length of data that can be received in the buffer in number
* of words. The wordsize is determined by the number of bits-per-word * of words. The wordsize is determined by the number of bits-per-word
* selected for the SPI interface. If nbits <= 8, the data is * selected for the SPI interface. If nbits <= 8, the data is
* packed into uint8_t's; if nbits >8, the data is packed into uint16_t's * packed into uint8_t's; if nbits >8, the data is packed into
* uint16_t's
* *
* Returned Value: * Returned Value:
* None * None
@ -654,10 +681,8 @@ static void ssp_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nw
{ {
return ssp_exchange(dev, NULL, buffer, nwords); return ssp_exchange(dev, NULL, buffer, nwords);
} }
#endif /* !CONFIG_SPI_EXCHANGE */
#endif
#ifdef CONFIG_LPC43_SSP0
/**************************************************************************** /****************************************************************************
* Name: lpc43_ssp0initialize * Name: lpc43_ssp0initialize
* *
@ -672,6 +697,7 @@ static void ssp_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nw
* *
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_LPC43_SSP0
static inline FAR struct lpc43_sspdev_s *lpc43_ssp0initialize(void) static inline FAR struct lpc43_sspdev_s *lpc43_ssp0initialize(void)
{ {
irqstate_t flags; irqstate_t flags;

View File

@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* arch/arm/src/lpc43/lpc43_rit.c * arch/arm/src/lpc43/lpc43_rit.c
* *
* Copyright (C) 2012 Gregory Nutt. All rights reserved. * Copyright (C) 2015 Gregory Nutt. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -40,7 +40,6 @@
* *
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Included Files * Included Files
****************************************************************************/ ****************************************************************************/
@ -80,10 +79,10 @@ static uint32_t COMMON_DEV;
static uint32_t MIN_TICKS; static uint32_t MIN_TICKS;
static uint32_t MIN_NSEC; static uint32_t MIN_NSEC;
static uint32_t RESET_TICKS = 1000; /* ticks to add to force a reset */ static uint32_t RESET_TICKS = 1000; /* Ticks to add to force a reset */
static struct timespec base_ts; /* time base */ static struct timespec base_ts; /* Time base */
static uint32_t base_rest; /* rest of ticks that is < MIN_TICKS*/ static uint32_t base_rest; /* Rest of ticks that is < MIN_TICKS*/
static struct timespec alarm_time_ts; /* alarmTime to set on next interrupt, used if not already armed */ static struct timespec alarm_time_ts; /* alarmTime to set on next interrupt, used if not already armed */
@ -91,7 +90,7 @@ static bool alarm_time_set = false; /* true if alarm_time set and need to be pro
static bool call = false; /* true if callback should be called on next interrupt */ static bool call = false; /* true if callback should be called on next interrupt */
static bool forced_int = false; /* true if interrupt was forced with mask, no reset */ static bool forced_int = false; /* true if interrupt was forced with mask, no reset */
static bool armed = false; /* true if alarm is armed for next match */ static bool armed = false; /* true if alarm is armed for next match */
static uint32_t synch = 0; /* synch all calls, recursion is possible */ static uint32_t synch = 0; /* Synch all calls, recursion is possible */
static irqstate_t g_flags; static irqstate_t g_flags;
static uint32_t ctrl_cache; static uint32_t ctrl_cache;
@ -102,56 +101,55 @@ static uint32_t compare_cache;
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
/* some timer HW functions */ /* Some timer HW functions */
static inline void lpc43_tl_set_counter (uint32_t value) static inline void lpc43_tl_set_counter(uint32_t value)
{ {
putreg32(value, LPC43_RIT_COUNTER); putreg32(value, LPC43_RIT_COUNTER);
} }
static inline uint32_t lpc43_tl_get_counter (void) static inline uint32_t lpc43_tl_get_counter(void)
{ {
return getreg32(LPC43_RIT_COUNTER); return getreg32(LPC43_RIT_COUNTER);
} }
static inline void lpc43_tl_set_compare (uint32_t value) static inline void lpc43_tl_set_compare(uint32_t value)
{ {
if ( value != compare_cache) if (value != compare_cache)
{ {
compare_cache = value; compare_cache = value;
putreg32(value, LPC43_RIT_COMPVAL); putreg32(value, LPC43_RIT_COMPVAL);
} }
} }
static inline uint32_t lpc43_tl_get_compare (void) static inline uint32_t lpc43_tl_get_compare(void)
{ {
return compare_cache; return compare_cache;
} }
static inline void lpc43_tl_set_mask (uint32_t value) static inline void lpc43_tl_set_mask(uint32_t value)
{ {
if ( value != mask_cache) if (value != mask_cache)
{ {
mask_cache = value; mask_cache = value;
putreg32(value, LPC43_RIT_MASK); putreg32(value, LPC43_RIT_MASK);
} }
} }
static inline uint32_t lpc43_tl_get_mask (void) static inline uint32_t lpc43_tl_get_mask(void)
{ {
return mask_cache; return mask_cache;
} }
static inline bool lpc43_tl_get_ctrl_bit (uint32_t bit) static inline bool lpc43_tl_get_ctrl_bit(uint32_t bit)
{ {
return ((ctrl_cache & bit)?true:false); return ((ctrl_cache & bit)?true:false);
} }
static inline void lpc43_tl_set_ctrl_bit (uint32_t bit, bool value) static inline void lpc43_tl_set_ctrl_bit(uint32_t bit, bool value)
{ {
if (lpc43_tl_get_ctrl_bit(bit) != value)
if ( lpc43_tl_get_ctrl_bit(bit) != value ) { {
if (value) if (value)
{ {
ctrl_cache |= bit; ctrl_cache |= bit;
@ -165,40 +163,41 @@ static inline bool lpc43_tl_get_ctrl_bit (uint32_t bit)
} }
} }
static inline void lpc43_tl_set_reset_on_match (bool value) static inline void lpc43_tl_set_reset_on_match(bool value)
{ {
lpc43_tl_set_ctrl_bit (RIT_CTRL_ENCLR, value); lpc43_tl_set_ctrl_bit(RIT_CTRL_ENCLR, value);
} }
static inline bool lpc43_tl_get_reset_on_match (void) static inline bool lpc43_tl_get_reset_on_match(void)
{ {
return lpc43_tl_get_ctrl_bit (RIT_CTRL_ENCLR); return lpc43_tl_get_ctrl_bit(RIT_CTRL_ENCLR);
} }
static inline void lpc43_tl_set_enable (bool value) static inline void lpc43_tl_set_enable(bool value)
{ {
lpc43_tl_set_ctrl_bit (RIT_CTRL_EN, value); lpc43_tl_set_ctrl_bit(RIT_CTRL_EN, value);
} }
static inline bool lpc43_tl_get_enable (void) static inline bool lpc43_tl_get_enable(void)
{ {
return lpc43_tl_get_ctrl_bit (RIT_CTRL_EN); return lpc43_tl_get_ctrl_bit(RIT_CTRL_EN);
} }
static inline void lpc43_tl_clear_interrupt (void) static inline void lpc43_tl_clear_interrupt(void)
{ {
putreg32(ctrl_cache | RIT_CTRL_INT, LPC43_RIT_CTRL); putreg32(ctrl_cache | RIT_CTRL_INT, LPC43_RIT_CTRL);
} }
static inline bool lpc43_tl_get_interrupt (void) static inline bool lpc43_tl_get_interrupt(void)
{ {
return (( getreg32(LPC43_RIT_CTRL) & RIT_CTRL_INT )?true:false); return ((getreg32(LPC43_RIT_CTRL) & RIT_CTRL_INT)?true:false);
} }
/* converters */ /* Converters */
static uint32_t commonDev(uint32_t a, uint32_t b) static uint32_t commonDev(uint32_t a, uint32_t b)
{ {
while(b !=0) while (b != 0)
{ {
int h = a%b; int h = a%b;
a = b; a = b;
@ -208,7 +207,7 @@ static uint32_t commonDev(uint32_t a, uint32_t b)
return a; return a;
} }
static void lpc43_tl_add(FAR const struct timespec *ts1, static void lpc43_tl_add(FAR const struct timespec *ts1,
FAR const struct timespec *ts2, FAR const struct timespec *ts2,
FAR struct timespec *ts3) FAR struct timespec *ts3)
{ {
@ -225,7 +224,7 @@ static uint32_t commonDev(uint32_t a, uint32_t b)
ts3->tv_nsec = nsec; ts3->tv_nsec = nsec;
} }
static void lpc43_tl_sub(FAR const struct timespec *ts1, static void lpc43_tl_sub(FAR const struct timespec *ts1,
FAR const struct timespec *ts2, FAR const struct timespec *ts2,
FAR struct timespec *ts3) FAR struct timespec *ts3)
{ {
@ -260,14 +259,14 @@ static uint32_t commonDev(uint32_t a, uint32_t b)
ts3->tv_nsec = nsec; ts3->tv_nsec = nsec;
} }
static inline uint32_t lpc43_tl_ts2tick ( FAR const struct timespec *ts) static inline uint32_t lpc43_tl_ts2tick(FAR const struct timespec *ts)
{ {
return ( ts->tv_sec*LPC43_CCLK + ( ts->tv_nsec/MIN_NSEC*MIN_TICKS ) ); return (ts->tv_sec*LPC43_CCLK + (ts->tv_nsec/MIN_NSEC*MIN_TICKS));
} }
static uint32_t lpc43_tl_tick2ts (uint32_t ticks, FAR struct timespec *ts, bool with_rest)
{
static uint32_t lpc43_tl_tick2ts(uint32_t ticks, FAR struct timespec *ts,
bool with_rest)
{
uint32_t ticks_whole; uint32_t ticks_whole;
uint32_t ticks_rest = 0; uint32_t ticks_rest = 0;
@ -276,7 +275,6 @@ static inline uint32_t lpc43_tl_ts2tick ( FAR const struct timespec *ts)
uint32_t ticks_mult = ticks/MIN_TICKS; uint32_t ticks_mult = ticks/MIN_TICKS;
ticks_whole = ticks_mult*MIN_TICKS; ticks_whole = ticks_mult*MIN_TICKS;
ticks_rest = ticks - ticks_whole; ticks_rest = ticks - ticks_whole;
} }
else else
{ {
@ -287,130 +285,133 @@ static inline uint32_t lpc43_tl_ts2tick ( FAR const struct timespec *ts)
ts->tv_nsec = ((ticks_whole%LPC43_CCLK)/MIN_TICKS)*MIN_NSEC; ts->tv_nsec = ((ticks_whole%LPC43_CCLK)/MIN_TICKS)*MIN_NSEC;
return ticks_rest; return ticks_rest;
} }
/* logic functions */ /* Logic functions */
static inline void lpc43_tl_sync_up (void) { static inline void lpc43_tl_sync_up(void)
{
irqstate_t flags; irqstate_t flags;
flags = irqsave (); flags = irqsave();
if ( synch == 0 ) if (synch == 0)
{ {
g_flags = flags; g_flags = flags;
} }
synch++; synch++;
} }
static inline void lpc43_tl_sync_down (void) { static inline void lpc43_tl_sync_down(void)
{
synch--; synch--;
if ( synch == 0 ) if (synch == 0)
{ {
irqrestore (g_flags); irqrestore(g_flags);
} }
} }
/* assuming safe timer state, force interrupt, no reset possible */ /* Assuming safe timer state, force interrupt, no reset possible */
static inline void lpc43_tl_force_int (void) static inline void lpc43_tl_force_int(void)
{ {
forced_int = true; forced_int = true;
lpc43_tl_set_reset_on_match (false); lpc43_tl_set_reset_on_match(false);
lpc43_tl_set_mask (UINT32_MAX); lpc43_tl_set_mask(UINT32_MAX);
lpc43_tl_set_compare(UINT32_MAX); lpc43_tl_set_compare(UINT32_MAX);
} }
/* init all vars, forced_int should not be cleared */ /* Init all vars, forced_int should not be cleared */
static inline void lpc43_tl_init_timer_vars (void) static inline void lpc43_tl_init_timer_vars(void)
{ {
alarm_time_set = false; alarm_time_set = false;
call = false; call = false;
armed = false; armed = false;
} }
/* calc RESET_TICKS and set compare to TO_RESET */ /* Calc RESET_TICKS and set compare to TO_RESET */
static void lpc43_tl_calibrate_init (void) static void lpc43_tl_calibrate_init(void)
{ {
uint32_t counter = lpc43_tl_get_counter (); uint32_t counter = lpc43_tl_get_counter();
uint32_t counter_after = lpc43_tl_get_counter (); uint32_t counter_after = lpc43_tl_get_counter();
counter_after = TO_RESET + counter; counter_after = TO_RESET + counter;
counter_after = counter_after - counter; counter_after = counter_after - counter;
/*shift to toReset*/ /* Shift to to Reset */
lpc43_tl_set_compare (counter_after); lpc43_tl_set_compare(counter_after);
counter_after = lpc43_tl_get_counter (); counter_after = lpc43_tl_get_counter();
RESET_TICKS = (counter_after - counter) * 2; RESET_TICKS = (counter_after - counter) * 2;
} }
/* process current and set timer in default safe state */ /* Process current and set timer in default safe state */
static void lpc43_tl_save_timer (bool from_isr) static void lpc43_tl_save_timer(bool from_isr)
{ {
if (forced_int) /* special case of forced interrupt by mask*/ if (forced_int) /* special case of forced interrupt by mask*/
{ {
forced_int = false; forced_int = false;
lpc43_tl_set_compare (UINT32_MAX); lpc43_tl_set_compare(UINT32_MAX);
lpc43_tl_set_mask (0); lpc43_tl_set_mask(0);
lpc43_tl_clear_interrupt (); lpc43_tl_clear_interrupt();
} }
else else
{ {
/* Process reset if any */
/*process reset if any*/ uint32_t match = lpc43_tl_get_compare();
uint32_t match = lpc43_tl_get_compare (); /* Move to end, no resets during processing */
/*move to end, no resets during processing*/ lpc43_tl_set_compare(UINT32_MAX);
lpc43_tl_set_mask(0);
lpc43_tl_set_compare (UINT32_MAX); if (from_isr || lpc43_tl_get_interrupt())
lpc43_tl_set_mask (0);
if (from_isr || lpc43_tl_get_interrupt ())
{ {
if (lpc43_tl_get_reset_on_match ()) /*was reset ?*/ if (lpc43_tl_get_reset_on_match()) /*was reset ?*/
{ {
struct timespec match_ts; struct timespec match_ts;
base_rest = lpc43_tl_tick2ts(match + base_rest, &match_ts,true); base_rest = lpc43_tl_tick2ts(match + base_rest,
&match_ts,true);
lpc43_tl_add(&base_ts, &match_ts,&base_ts); lpc43_tl_add(&base_ts, &match_ts,&base_ts);
} }
lpc43_tl_clear_interrupt ();
lpc43_tl_clear_interrupt();
} }
} }
} }
/* assuming safe timer state, true if set, false - time is in the past */ /* Assuming safe timer state, true if set, false - time is in the past */
static bool lpc43_tl_set_safe_compare (uint32_t compare_to_set) static bool lpc43_tl_set_safe_compare(uint32_t compare_to_set)
{ {
if (compare_to_set < TO_RESET) if (compare_to_set < TO_RESET)
{ {
lpc43_tl_set_reset_on_match (false); lpc43_tl_set_reset_on_match(false);
} }
else else
{ {
lpc43_tl_set_reset_on_match (true); lpc43_tl_set_reset_on_match(true);
} }
lpc43_tl_set_compare (compare_to_set); lpc43_tl_set_compare(compare_to_set);
//check if ok /* Check if ok */
bool reset = lpc43_tl_get_interrupt ();
uint32_t counter = lpc43_tl_get_counter (); bool reset = lpc43_tl_get_interrupt();
bool reset_after = lpc43_tl_get_interrupt (); uint32_t counter = lpc43_tl_get_counter();
bool reset_after = lpc43_tl_get_interrupt();
if (reset != reset_after) if (reset != reset_after)
{ {
//was a reset get new counter /* Was a reset get new counter */
counter = lpc43_tl_get_counter ();
counter = lpc43_tl_get_counter();
} }
if (reset_after || (!reset_after && compare_to_set > counter)) if (reset_after || (!reset_after && compare_to_set > counter))
@ -419,31 +420,31 @@ static bool lpc43_tl_set_safe_compare (uint32_t compare_to_set)
} }
else else
{ {
lpc43_tl_set_compare (UINT32_MAX); lpc43_tl_set_compare(UINT32_MAX);
return false; return false;
} }
} }
/* assuming safe timer state, set_safe_compare in loop */ /* Assuming safe timer state, set_safe_compare in loop */
static void lpc43_tl_looped_forced_set_compare (void) static void lpc43_tl_looped_forced_set_compare(void)
{ {
uint32_t i = 1; uint32_t i = 1;
bool result = lpc43_tl_set_safe_compare ( bool result = lpc43_tl_set_safe_compare(
lpc43_tl_get_counter () + RESET_TICKS); /* like in calibrateInit */ lpc43_tl_get_counter() + RESET_TICKS); /* like in calibrateInit */
while (!result) while (!result)
{ {
i++; i++;
result = lpc43_tl_set_safe_compare ( result = lpc43_tl_set_safe_compare(
lpc43_tl_get_counter () + RESET_TICKS * i); lpc43_tl_get_counter() + RESET_TICKS * i);
}; }
} }
/* assuming safe timer state, true if set, false - time is in the past */ /* Assuming safe timer state, true if set, false - time is in the past */
static bool lpc43_tl_set_calc_arm (uint32_t curr, uint32_t to_set, bool arm) static bool lpc43_tl_set_calc_arm(uint32_t curr, uint32_t to_set, bool arm)
{ {
uint32_t calcTime; uint32_t calcTime;
@ -460,12 +461,12 @@ static bool lpc43_tl_set_calc_arm (uint32_t curr, uint32_t to_set, bool arm)
} }
else else
{ {
lpc43_tl_looped_forced_set_compare (); lpc43_tl_looped_forced_set_compare();
return true; return true;
} }
} }
bool set = lpc43_tl_set_safe_compare (calcTime); bool set = lpc43_tl_set_safe_compare(calcTime);
if (arm && set && (calcTime == to_set)) if (arm && set && (calcTime == to_set))
{ {
@ -475,26 +476,27 @@ static bool lpc43_tl_set_calc_arm (uint32_t curr, uint32_t to_set, bool arm)
return set; return set;
} }
/* assuming safe timer state, try to set compare for normal operation */ /* Assuming safe timer state, try to set compare for normal operation */
static void lpc43_tl_set_default_compare (uint32_t curr) static void lpc43_tl_set_default_compare(uint32_t curr)
{ {
bool result = lpc43_tl_set_calc_arm (curr, UINT32_MAX, bool result = lpc43_tl_set_calc_arm(curr, UINT32_MAX, false);
if (!result)
{
result = lpc43_tl_set_calc_arm(lpc43_tl_get_counter(), UINT32_MAX,
false); false);
if (!result) if (!result)
{ {
result = lpc43_tl_set_calc_arm (lpc43_tl_get_counter (), UINT32_MAX, lpc43_tl_looped_forced_set_compare();
false);
if (!result)
{
lpc43_tl_looped_forced_set_compare ();
} }
} }
} }
/* calculates ticks to set from alarm_time_ts and base_ts/base_rest, UINT32_MAX if overflow */ /* Calculates ticks to set from alarm_time_ts and base_ts/base_rest,
static inline uint32_t lpc43_tl_calc_to_set (void) * UINT32_MAX if overflow.
*/
static inline uint32_t lpc43_tl_calc_to_set(void)
{ {
struct timespec diff_ts; struct timespec diff_ts;
struct timespec ovf_ts; struct timespec ovf_ts;
@ -502,42 +504,43 @@ static inline uint32_t lpc43_tl_calc_to_set (void)
lpc43_tl_sub(&alarm_time_ts,&base_ts,&diff_ts); lpc43_tl_sub(&alarm_time_ts,&base_ts,&diff_ts);
lpc43_tl_sub(&diff_ts,&MAX_TS,&ovf_ts); lpc43_tl_sub(&diff_ts,&MAX_TS,&ovf_ts);
if ( ovf_ts.tv_sec == 0 && ovf_ts.tv_nsec == 0 ) /* check overflow */ if (ovf_ts.tv_sec == 0 && ovf_ts.tv_nsec == 0) /* check overflow */
{ {
return ( lpc43_tl_ts2tick(&diff_ts) - base_rest ); return (lpc43_tl_ts2tick(&diff_ts) - base_rest);
} }
else else
{ {
return UINT32_MAX; return UINT32_MAX;
} }
} }
/* assuming safe timer state, used by isr: sets default compare , calls alarm */ /* Assuming safe timer state, used by isr: sets default compare,
static inline void lpc43_tl_alarm (uint32_t curr) * calls alarm.
{ */
lpc43_tl_init_timer_vars ();
lpc43_tl_set_default_compare (curr);
static inline void lpc43_tl_alarm(uint32_t curr)
{
lpc43_tl_init_timer_vars();
lpc43_tl_set_default_compare(curr);
#ifdef CONFIG_SCHED_TICKLESS_ALARM #ifdef CONFIG_SCHED_TICKLESS_ALARM
struct timespec ts; struct timespec ts;
up_timer_gettime(&ts); up_timer_gettime(&ts);
sched_alarm_expiration (&ts); sched_alarm_expiration(&ts);
#else #else
sched_timer_expiration(); sched_timer_expiration();
#endif #endif
} }
/* interrupt handler */ /* Interrupt handler */
static int lpc43_tl_isr (int irq, FAR void *context) static int lpc43_tl_isr(int irq, FAR void *context)
{ {
lpc43_tl_sync_up(); lpc43_tl_sync_up();
lpc43_tl_save_timer(true); lpc43_tl_save_timer(true);
uint32_t curr = lpc43_tl_get_counter (); uint32_t curr = lpc43_tl_get_counter();
if (call) if (call)
{ {
lpc43_tl_alarm(curr); lpc43_tl_alarm(curr);
@ -558,11 +561,11 @@ static int lpc43_tl_isr (int irq, FAR void *context)
{ {
if (toSet > TO_END) if (toSet > TO_END)
{ {
lpc43_tl_set_default_compare (curr); lpc43_tl_set_default_compare(curr);
} }
else else
{ {
bool set = lpc43_tl_set_calc_arm (curr, toSet, true); bool set = lpc43_tl_set_calc_arm(curr, toSet, true);
if (!set) if (!set)
{ {
lpc43_tl_alarm(curr); lpc43_tl_alarm(curr);
@ -576,7 +579,7 @@ static int lpc43_tl_isr (int irq, FAR void *context)
} }
else else
{ {
lpc43_tl_set_default_compare (curr); lpc43_tl_set_default_compare(curr);
} }
} }
} }
@ -584,17 +587,16 @@ static int lpc43_tl_isr (int irq, FAR void *context)
lpc43_tl_sync_down(); lpc43_tl_sync_down();
return OK; return OK;
} }
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
void up_timer_initialize (void) void up_timer_initialize(void)
{ {
irqstate_t flags; irqstate_t flags;
flags = irqsave (); flags = irqsave();
ctrl_cache = getreg32(LPC43_RIT_CTRL); ctrl_cache = getreg32(LPC43_RIT_CTRL);
ctrl_cache &= ~RIT_CTRL_INT; /* set interrupt to 0*/ ctrl_cache &= ~RIT_CTRL_INT; /* set interrupt to 0*/
@ -611,92 +613,96 @@ void up_timer_initialize (void)
lpc43_tl_tick2ts(TO_END,&MAX_TS,false); lpc43_tl_tick2ts(TO_END,&MAX_TS,false);
lpc43_tl_set_enable (false); lpc43_tl_set_enable(false);
lpc43_tl_set_compare (UINT32_MAX); lpc43_tl_set_compare(UINT32_MAX);
lpc43_tl_set_counter (0); lpc43_tl_set_counter(0);
lpc43_tl_set_mask (0); lpc43_tl_set_mask(0);
lpc43_tl_set_reset_on_match (false); lpc43_tl_set_reset_on_match(false);
lpc43_tl_clear_interrupt (); lpc43_tl_clear_interrupt();
irq_attach (LPC43M4_IRQ_RITIMER, lpc43_tl_isr); irq_attach(LPC43M4_IRQ_RITIMER, lpc43_tl_isr);
up_enable_irq (LPC43M4_IRQ_RITIMER); up_enable_irq(LPC43M4_IRQ_RITIMER);
lpc43_tl_init_timer_vars (); lpc43_tl_init_timer_vars();
lpc43_tl_set_enable (true); lpc43_tl_set_enable(true);
lpc43_tl_calibrate_init (); lpc43_tl_calibrate_init();
irqrestore (flags);
irqrestore(flags);
} }
/* No reg changes, only processing */
/* no reg changes, only processing */ int up_timer_gettime(FAR struct timespec *ts)
int up_timer_gettime (FAR struct timespec *ts) {
{
lpc43_tl_sync_up(); lpc43_tl_sync_up();
/* order of calls is important, reset can come during processing */ /* Order of calls is important, reset can come during processing */
bool reset = lpc43_tl_get_interrupt (); bool reset = lpc43_tl_get_interrupt();
uint32_t count = lpc43_tl_get_counter (); uint32_t count = lpc43_tl_get_counter();
/* not processed reset can exist */ /* Not processed reset can exist */
if (lpc43_tl_get_reset_on_match ())
if (lpc43_tl_get_reset_on_match())
{ {
bool resetAfter = lpc43_tl_get_interrupt (); bool resetAfter = lpc43_tl_get_interrupt();
if (reset != resetAfter) /* was a reset during processing? get new counter */ /* Was a reset during processing? get new counter */
if (reset != resetAfter)
{ {
count = lpc43_tl_get_counter (); count = lpc43_tl_get_counter();
} }
if (resetAfter) if (resetAfter)
{ {
count += lpc43_tl_get_compare (); /* count should be smaller then UINT32_MAX-TO_END -> no overflow */ /* Count should be smaller then UINT32_MAX-TO_END -> no overflow */
count += lpc43_tl_get_compare();
} }
} }
struct timespec count_ts; struct timespec count_ts;
lpc43_tl_tick2ts(count + base_rest,&count_ts,false);
lpc43_tl_tick2ts(count + base_rest,&count_ts,false );
lpc43_tl_add(&base_ts,&count_ts,ts); lpc43_tl_add(&base_ts,&count_ts,ts);
lpc43_tl_sync_down(); lpc43_tl_sync_down();
return OK; return OK;
} }
int up_alarm_cancel(FAR struct timespec *ts)
int up_alarm_cancel (FAR struct timespec *ts) {
{
lpc43_tl_sync_up(); lpc43_tl_sync_up();
/*no reg changes, only variables logic*/ /* No reg changes, only variables logic */
if ( ts != NULL ) { if (ts != NULL)
up_timer_gettime (ts); {
up_timer_gettime(ts);
} }
/* let default setup will be done in interrupt handler or up_alarm_start */ /* Let default setup will be done in interrupt handler or up_alarm_start */
lpc43_tl_init_timer_vars ();
lpc43_tl_init_timer_vars();
lpc43_tl_sync_down(); lpc43_tl_sync_down();
return OK; return OK;
} }
int up_alarm_start (FAR const struct timespec *ts) int up_alarm_start(FAR const struct timespec *ts)
{ {
lpc43_tl_sync_up(); lpc43_tl_sync_up();
lpc43_tl_save_timer (false); lpc43_tl_save_timer(false);
lpc43_tl_init_timer_vars (); lpc43_tl_init_timer_vars();
alarm_time_set = true; alarm_time_set = true;
alarm_time_ts.tv_sec = ts->tv_sec; alarm_time_ts.tv_sec = ts->tv_sec;
@ -704,58 +710,55 @@ int up_alarm_start (FAR const struct timespec *ts)
uint32_t toSet = lpc43_tl_calc_to_set(); uint32_t toSet = lpc43_tl_calc_to_set();
uint32_t curr = lpc43_tl_get_counter (); uint32_t curr = lpc43_tl_get_counter();
if (toSet > curr) if (toSet > curr)
{ {
if (toSet > TO_END) /* future set */ if (toSet > TO_END) /* Future set */
{ {
lpc43_tl_set_default_compare (curr); lpc43_tl_set_default_compare(curr);
} }
else else
{ {
bool set = lpc43_tl_set_calc_arm (curr, toSet, true); bool set = lpc43_tl_set_calc_arm(curr, toSet, true);
if (!set) /* signal call, force interrupt handler */ if (!set) /* Signal call, force interrupt handler */
{ {
call = true; call = true;
lpc43_tl_force_int (); lpc43_tl_force_int();
}
} }
} }
else /* signal call, force interrupt handler */ }
else /* Signal call, force interrupt handler */
{ {
call = true; call = true;
lpc43_tl_force_int (); lpc43_tl_force_int();
} }
lpc43_tl_sync_down(); lpc43_tl_sync_down();
return OK; return OK;
} }
#ifndef CONFIG_SCHED_TICKLESS_ALARM #ifndef CONFIG_SCHED_TICKLESS_ALARM
int up_timer_cancel(FAR struct timespec *ts) int up_timer_cancel(FAR struct timespec *ts)
{ {
lpc43_tl_sync_up(); lpc43_tl_sync_up();
if (ts != NULL) if (ts != NULL)
{ {
struct timespec abs_ts; struct timespec abs_ts;
up_timer_gettime(&abs_ts); up_timer_gettime(&abs_ts);
lpc43_tl_sub( &alarm_time_ts,&abs_ts,ts ); lpc43_tl_sub(&alarm_time_ts,&abs_ts,ts);
} }
lpc43_tl_init_timer_vars (); lpc43_tl_init_timer_vars();
lpc43_tl_sync_down(); lpc43_tl_sync_down();
return OK; return OK;
} }
int up_timer_start(FAR const struct timespec *ts) int up_timer_start(FAR const struct timespec *ts)
{ {
lpc43_tl_sync_up(); lpc43_tl_sync_up();
struct timespec abs_ts; struct timespec abs_ts;
@ -766,8 +769,7 @@ int up_timer_start(FAR const struct timespec *ts)
lpc43_tl_sync_down(); lpc43_tl_sync_down();
return OK; return OK;
} }
# endif /* CONFIG_SCHED_TICKLESS_ALARM */
#endif /* CONFIG_SCHED_TICKLESS_ALARM */
#endif /* CONFIG_SCHED_TICKLESS */ #endif /* CONFIG_SCHED_TICKLESS */