Merge remote-tracking branch 'nuttx_bitbucket/master'
This commit is contained in:
commit
cd946c5712
@ -3249,7 +3249,9 @@ config STM32L4_DAC1_TIMER
|
|||||||
|
|
||||||
config STM32L4_DAC1_TIMER_FREQUENCY
|
config STM32L4_DAC1_TIMER_FREQUENCY
|
||||||
int "DAC1 timer frequency"
|
int "DAC1 timer frequency"
|
||||||
default 0
|
default 100
|
||||||
|
---help---
|
||||||
|
DAC1 output frequency. Default: 100Hz
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -3272,7 +3274,9 @@ config STM32L4_DAC2_TIMER
|
|||||||
|
|
||||||
config STM32L4_DAC2_TIMER_FREQUENCY
|
config STM32L4_DAC2_TIMER_FREQUENCY
|
||||||
int "DAC2 timer frequency"
|
int "DAC2 timer frequency"
|
||||||
default 0
|
default 100
|
||||||
|
---help---
|
||||||
|
DAC2 output frequency. Default: 100Hz
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@
|
|||||||
#elif defined(CONFIG_STM32L4_TIM15_ADC1)
|
#elif defined(CONFIG_STM32L4_TIM15_ADC1)
|
||||||
# define ADC1_HAVE_TIMER 1
|
# define ADC1_HAVE_TIMER 1
|
||||||
# define ADC1_TIMER_BASE STM32L4_TIM15_BASE
|
# define ADC1_TIMER_BASE STM32L4_TIM15_BASE
|
||||||
# define ADC1_TIMER_PCLK_FREQUENCY STM32L4_APB1_TIM15_CLKIN
|
# define ADC1_TIMER_PCLK_FREQUENCY STM32L4_APB2_TIM15_CLKIN
|
||||||
#else
|
#else
|
||||||
# undef ADC1_HAVE_TIMER
|
# undef ADC1_HAVE_TIMER
|
||||||
#endif
|
#endif
|
||||||
@ -219,7 +219,7 @@
|
|||||||
#elif defined(CONFIG_STM32L4_TIM15_ADC2)
|
#elif defined(CONFIG_STM32L4_TIM15_ADC2)
|
||||||
# define ADC2_HAVE_TIMER 1
|
# define ADC2_HAVE_TIMER 1
|
||||||
# define ADC2_TIMER_BASE STM32L4_TIM15_BASE
|
# define ADC2_TIMER_BASE STM32L4_TIM15_BASE
|
||||||
# define ADC2_TIMER_PCLK_FREQUENCY STM32L4_APB1_TIM15_CLKIN
|
# define ADC2_TIMER_PCLK_FREQUENCY STM32L4_APB2_TIM15_CLKIN
|
||||||
#else
|
#else
|
||||||
# undef ADC2_HAVE_TIMER
|
# undef ADC2_HAVE_TIMER
|
||||||
#endif
|
#endif
|
||||||
@ -261,7 +261,7 @@
|
|||||||
#elif defined(CONFIG_STM32L4_TIM15_ADC3)
|
#elif defined(CONFIG_STM32L4_TIM15_ADC3)
|
||||||
# define ADC3_HAVE_TIMER 1
|
# define ADC3_HAVE_TIMER 1
|
||||||
# define ADC3_TIMER_BASE STM32L4_TIM15_BASE
|
# define ADC3_TIMER_BASE STM32L4_TIM15_BASE
|
||||||
# define ADC3_TIMER_PCLK_FREQUENCY STM32L4_APB1_TIM15_CLKIN
|
# define ADC3_TIMER_PCLK_FREQUENCY STM32L4_APB2_TIM15_CLKIN
|
||||||
#else
|
#else
|
||||||
# undef ADC3_HAVE_TIMER
|
# undef ADC3_HAVE_TIMER
|
||||||
#endif
|
#endif
|
||||||
|
@ -103,11 +103,12 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_STM32L4_DAC1_DMA
|
#ifdef CONFIG_STM32L4_DAC1_DMA
|
||||||
# if !defined(CONFIG_STM32L4_DAC1_TIMER)
|
# if !defined(CONFIG_STM32L4_DAC1_TIMER)
|
||||||
# warning "A timer number must be specificed in CONFIG_STM32L4_DAC1_TIMER"
|
# warning "A timer number must be specified in CONFIG_STM32L4_DAC1_TIMER"
|
||||||
# undef CONFIG_STM32L4_DAC1_DMA
|
# undef CONFIG_STM32L4_DAC1_DMA
|
||||||
# undef CONFIG_STM32L4_DAC1_TIMER_FREQUENCY
|
# undef CONFIG_STM32L4_DAC1_TIMER_FREQUENCY
|
||||||
# elif !defined(CONFIG_STM32L4_DAC1_TIMER_FREQUENCY)
|
# elif !defined(CONFIG_STM32L4_DAC1_TIMER_FREQUENCY) || \
|
||||||
# warning "A timer frequency must be specificed in CONFIG_STM32L4_DAC1_TIMER_FREQUENCY"
|
(CONFIG_STM32L4_DAC1_TIMER_FREQUENCY < 1)
|
||||||
|
# warning "A timer frequency (>0) must be specified in CONFIG_STM32L4_DAC1_TIMER_FREQUENCY"
|
||||||
# undef CONFIG_STM32L4_DAC1_DMA
|
# undef CONFIG_STM32L4_DAC1_DMA
|
||||||
# undef CONFIG_STM32L4_DAC1_TIMER
|
# undef CONFIG_STM32L4_DAC1_TIMER
|
||||||
# endif
|
# endif
|
||||||
@ -115,11 +116,12 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_STM32L4_DAC2_DMA
|
#ifdef CONFIG_STM32L4_DAC2_DMA
|
||||||
# if !defined(CONFIG_STM32L4_DAC2_TIMER)
|
# if !defined(CONFIG_STM32L4_DAC2_TIMER)
|
||||||
# warning "A timer number must be specificed in CONFIG_STM32L4_DAC2_TIMER"
|
# warning "A timer number must be specified in CONFIG_STM32L4_DAC2_TIMER"
|
||||||
# undef CONFIG_STM32L4_DAC2_DMA
|
# undef CONFIG_STM32L4_DAC2_DMA
|
||||||
# undef CONFIG_STM32L4_DAC2_TIMER_FREQUENCY
|
# undef CONFIG_STM32L4_DAC2_TIMER_FREQUENCY
|
||||||
# elif !defined(CONFIG_STM32L4_DAC2_TIMER_FREQUENCY)
|
# elif !defined(CONFIG_STM32L4_DAC2_TIMER_FREQUENCY) || \
|
||||||
# warning "A timer frequency must be specificed in CONFIG_STM32L4_DAC2_TIMER_FREQUENCY"
|
(CONFIG_STM32L4_DAC2_TIMER_FREQUENCY < 1)
|
||||||
|
# warning "A timer frequency (>0) must be specified in CONFIG_STM32L4_DAC2_TIMER_FREQUENCY"
|
||||||
# undef CONFIG_STM32L4_DAC2_DMA
|
# undef CONFIG_STM32L4_DAC2_DMA
|
||||||
# undef CONFIG_STM32L4_DAC2_TIMER
|
# undef CONFIG_STM32L4_DAC2_TIMER
|
||||||
# endif
|
# endif
|
||||||
@ -269,7 +271,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Calculate timer divider values based upon DACn_TIMER_PCLK_FREQUENCY and
|
/* Calculate timer divider values based upon DACn_TIMER_PCLK_FREQUENCY and
|
||||||
* CONFIG_STM32_DACn_TIMER_FREQUENCY.
|
* CONFIG_STM32L4_DACn_TIMER_FREQUENCY.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#warning "Missing Logic"
|
#warning "Missing Logic"
|
||||||
@ -312,6 +314,7 @@ struct stm32_chan_s
|
|||||||
DMA_HANDLE dma; /* Allocated DMA channel */
|
DMA_HANDLE dma; /* Allocated DMA channel */
|
||||||
uint32_t tbase; /* Timer base address */
|
uint32_t tbase; /* Timer base address */
|
||||||
uint32_t tfrequency; /* Timer frequency */
|
uint32_t tfrequency; /* Timer frequency */
|
||||||
|
int result; /* DMA result */
|
||||||
uint16_t dmabuffer[CONFIG_STM32L4_DAC_DMA_BUFFER_SIZE]; /* DMA transfer buffer */
|
uint16_t dmabuffer[CONFIG_STM32L4_DAC_DMA_BUFFER_SIZE]; /* DMA transfer buffer */
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@ -323,9 +326,10 @@ struct stm32_chan_s
|
|||||||
/* DAC Register access */
|
/* DAC Register access */
|
||||||
|
|
||||||
#ifdef HAVE_DMA
|
#ifdef HAVE_DMA
|
||||||
static uint32_t tim_getreg(FAR struct stm32_chan_s *chan, int offset);
|
static inline void tim_putreg(FAR struct stm32_chan_s *chan, int offset,
|
||||||
static void tim_putreg(FAR struct stm32_chan_s *chan, int offset,
|
uint32_t value);
|
||||||
uint32_t value);
|
static inline void tim_modifyreg(FAR struct stm32_chan_s *chan, int offset,
|
||||||
|
uint32_t clearbits, uint32_t setbits);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* DAC methods */
|
/* DAC methods */
|
||||||
@ -457,7 +461,7 @@ static struct stm32_dac_s g_dacblock;
|
|||||||
* Modify the contents of the DAC control register.
|
* Modify the contents of the DAC control register.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* priv - Driver state instance
|
* chan - A reference to the DAC channel state data
|
||||||
* clearbits - Bits in the control register to be cleared
|
* clearbits - Bits in the control register to be cleared
|
||||||
* setbits - Bits in the control register to be set
|
* setbits - Bits in the control register to be set
|
||||||
*
|
*
|
||||||
@ -484,28 +488,6 @@ static inline void stm32l4_dac_modify_cr(FAR struct stm32_chan_s *chan,
|
|||||||
modifyreg32(chan->cr, clearbits << shift, setbits << shift);
|
modifyreg32(chan->cr, clearbits << shift, setbits << shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: tim_getreg
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Read the value of an DMA timer register.
|
|
||||||
*
|
|
||||||
* Input Parameters:
|
|
||||||
* chan - A reference to the DAC block status
|
|
||||||
* offset - The offset to the register to read
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* The current contents of the specified register
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifdef HAVE_DMA
|
|
||||||
static uint32_t tim_getreg(FAR struct stm32_chan_s *chan, int offset)
|
|
||||||
{
|
|
||||||
return getreg32(chan->tbase + offset);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: tim_putreg
|
* Name: tim_putreg
|
||||||
*
|
*
|
||||||
@ -513,7 +495,7 @@ static uint32_t tim_getreg(FAR struct stm32_chan_s *chan, int offset)
|
|||||||
* Read the value of an DMA timer register.
|
* Read the value of an DMA timer register.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* chan - A reference to the DAC block status
|
* chan - A reference to the DAC channel state data
|
||||||
* offset - The offset to the register to read
|
* offset - The offset to the register to read
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
@ -522,8 +504,8 @@ static uint32_t tim_getreg(FAR struct stm32_chan_s *chan, int offset)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef HAVE_DMA
|
#ifdef HAVE_DMA
|
||||||
static void tim_putreg(FAR struct stm32_chan_s *chan, int offset,
|
static inline void tim_putreg(FAR struct stm32_chan_s *chan, int offset,
|
||||||
uint32_t value)
|
uint32_t value)
|
||||||
{
|
{
|
||||||
putreg32(value, chan->tbase + offset);
|
putreg32(value, chan->tbase + offset);
|
||||||
}
|
}
|
||||||
@ -536,7 +518,7 @@ static void tim_putreg(FAR struct stm32_chan_s *chan, int offset,
|
|||||||
* Modify the value of an DMA timer register.
|
* Modify the value of an DMA timer register.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* priv - Driver state instance
|
* chan - A reference to the DAC channel state data
|
||||||
* offset - The timer register offset
|
* offset - The timer register offset
|
||||||
* clearbits - Bits in the control register to be cleared
|
* clearbits - Bits in the control register to be cleared
|
||||||
* setbits - Bits in the control register to be set
|
* setbits - Bits in the control register to be set
|
||||||
@ -547,8 +529,8 @@ static void tim_putreg(FAR struct stm32_chan_s *chan, int offset,
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef HAVE_DMA
|
#ifdef HAVE_DMA
|
||||||
static void tim_modifyreg(FAR struct stm32_chan_s *chan, int offset,
|
static inline void tim_modifyreg(FAR struct stm32_chan_s *chan, int offset,
|
||||||
uint32_t clearbits, uint32_t setbits)
|
uint32_t clearbits, uint32_t setbits)
|
||||||
{
|
{
|
||||||
modifyreg32(chan->tbase + offset, clearbits, setbits);
|
modifyreg32(chan->tbase + offset, clearbits, setbits);
|
||||||
}
|
}
|
||||||
@ -659,6 +641,48 @@ static void dac_txint(FAR struct dac_dev_s *dev, bool enable)
|
|||||||
#ifdef HAVE_DMA
|
#ifdef HAVE_DMA
|
||||||
static void dac_dmatxcallback(DMA_HANDLE handle, uint8_t isr, FAR void *arg)
|
static void dac_dmatxcallback(DMA_HANDLE handle, uint8_t isr, FAR void *arg)
|
||||||
{
|
{
|
||||||
|
struct stm32_chan_s *chan = (struct stm32_chan_s *)arg;
|
||||||
|
struct dac_dev_s *dev;
|
||||||
|
|
||||||
|
DEBUGASSERT(chan);
|
||||||
|
|
||||||
|
#ifdef CONFIG_STM32L4_DAC1
|
||||||
|
if (chan->intf == 0)
|
||||||
|
{
|
||||||
|
dev = &g_dac1dev;
|
||||||
|
}
|
||||||
|
#if STM32L4_NDAC > 1
|
||||||
|
else if (chan->intf == 1)
|
||||||
|
{
|
||||||
|
dev = &g_dac2dev;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
#endif /* CONFIG_STM32L4_DAC1 */
|
||||||
|
#ifdef CONFIG_STM32L4_DAC2
|
||||||
|
if (chan->intf == 2)
|
||||||
|
{
|
||||||
|
dev = &g_dac3dev;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
DEBUGPANIC();
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGASSERT(dev->ad_priv == chan);
|
||||||
|
|
||||||
|
/* Report the result of the transfer only if the TX callback has not already
|
||||||
|
* reported an error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (chan->result == -EBUSY)
|
||||||
|
{
|
||||||
|
/* Save the result of the transfer if no error was previously reported. */
|
||||||
|
|
||||||
|
chan->result = (isr & DMA_CHAN_TEIF_BIT) ? -EIO : OK;
|
||||||
|
dac_txdone(dev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -705,8 +729,9 @@ static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg)
|
|||||||
stm32l4_dmasetup(chan->dma, chan->dro, (uint32_t)chan->dmabuffer,
|
stm32l4_dmasetup(chan->dma, chan->dro, (uint32_t)chan->dmabuffer,
|
||||||
CONFIG_STM32L4_DAC_DMA_BUFFER_SIZE, DAC_DMA_CONTROL_WORD);
|
CONFIG_STM32L4_DAC_DMA_BUFFER_SIZE, DAC_DMA_CONTROL_WORD);
|
||||||
|
|
||||||
/* Enable DMA */
|
/* Start the DMA */
|
||||||
|
|
||||||
|
chan->result = -EBUSY;
|
||||||
stm32l4_dmastart(chan->dma, dac_dmatxcallback, chan, false);
|
stm32l4_dmastart(chan->dma, dac_dmatxcallback, chan, false);
|
||||||
|
|
||||||
/* Enable DMA for DAC Channel */
|
/* Enable DMA for DAC Channel */
|
||||||
@ -777,7 +802,7 @@ static int dac_timinit(FAR struct stm32_chan_s *chan)
|
|||||||
* counter mode (up).
|
* counter mode (up).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Enable the timer. At most, two of the following cases (pluse the
|
/* Enable the timer. At most, two of the following cases (plus the
|
||||||
* default) will be enabled
|
* default) will be enabled
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1004,6 +1029,7 @@ static int dac_chaninit(FAR struct stm32_chan_s *chan)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
aerr("ERROR: Failed to initialize the DMA timer: %d\n", ret);
|
aerr("ERROR: Failed to initialize the DMA timer: %d\n", ret);
|
||||||
|
stm32l4_dmafree(chan->dma);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -548,7 +548,7 @@ static struct stm32l4_pwmtimer_s g_pwm15dev =
|
|||||||
.irq = STM32L4_IRQ_TIM15,
|
.irq = STM32L4_IRQ_TIM15,
|
||||||
#endif
|
#endif
|
||||||
.base = STM32L4_TIM15_BASE,
|
.base = STM32L4_TIM15_BASE,
|
||||||
.pclk = STM32L4_APB1_TIM15_CLKIN,
|
.pclk = STM32L4_APB2_TIM15_CLKIN,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -574,7 +574,7 @@ static struct stm32l4_pwmtimer_s g_pwm16dev =
|
|||||||
.irq = STM32L4_IRQ_TIM16,
|
.irq = STM32L4_IRQ_TIM16,
|
||||||
#endif
|
#endif
|
||||||
.base = STM32L4_TIM16_BASE,
|
.base = STM32L4_TIM16_BASE,
|
||||||
.pclk = STM32L4_APB1_TIM16_CLKIN,
|
.pclk = STM32L4_APB2_TIM16_CLKIN,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -600,7 +600,7 @@ static struct stm32l4_pwmtimer_s g_pwm17dev =
|
|||||||
.irq = STM32L4_IRQ_TIM17,
|
.irq = STM32L4_IRQ_TIM17,
|
||||||
#endif
|
#endif
|
||||||
.base = STM32L4_TIM17_BASE,
|
.base = STM32L4_TIM17_BASE,
|
||||||
.pclk = STM32L4_APB1_TIM17_CLKIN,
|
.pclk = STM32L4_APB2_TIM17_CLKIN,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -435,8 +435,10 @@ static inline void rcc_enableapb2(void)
|
|||||||
|
|
||||||
regval = getreg32(STM32L4_RCC_APB2ENR);
|
regval = getreg32(STM32L4_RCC_APB2ENR);
|
||||||
|
|
||||||
#ifdef CONFIG_STM32L4_SYSCFG
|
#if defined(CONFIG_STM32L4_SYSCFG) || defined(CONFIG_STM32L4_COMP)
|
||||||
/* System configuration controller clock enable */
|
/* System configuration controller, comparators, and voltage reference buffer
|
||||||
|
* clock enable
|
||||||
|
*/
|
||||||
|
|
||||||
regval |= RCC_APB2ENR_SYSCFGEN;
|
regval |= RCC_APB2ENR_SYSCFGEN;
|
||||||
#endif
|
#endif
|
||||||
|
@ -446,8 +446,10 @@ static inline void rcc_enableapb2(void)
|
|||||||
|
|
||||||
regval = getreg32(STM32L4_RCC_APB2ENR);
|
regval = getreg32(STM32L4_RCC_APB2ENR);
|
||||||
|
|
||||||
#ifdef CONFIG_STM32L4_SYSCFG
|
#if defined(CONFIG_STM32L4_SYSCFG) || defined(CONFIG_STM32L4_COMP)
|
||||||
/* System configuration controller clock enable */
|
/* System configuration controller, comparators, and voltage reference buffer
|
||||||
|
* clock enable
|
||||||
|
*/
|
||||||
|
|
||||||
regval |= RCC_APB2ENR_SYSCFGEN;
|
regval |= RCC_APB2ENR_SYSCFGEN;
|
||||||
#endif
|
#endif
|
||||||
|
@ -491,8 +491,10 @@ static inline void rcc_enableapb2(void)
|
|||||||
|
|
||||||
regval = getreg32(STM32L4_RCC_APB2ENR);
|
regval = getreg32(STM32L4_RCC_APB2ENR);
|
||||||
|
|
||||||
#ifdef CONFIG_STM32L4_SYSCFG
|
#if defined(CONFIG_STM32L4_SYSCFG) || defined(CONFIG_STM32L4_COMP)
|
||||||
/* System configuration controller clock enable */
|
/* System configuration controller, comparators, and voltage reference buffer
|
||||||
|
* clock enable
|
||||||
|
*/
|
||||||
|
|
||||||
regval |= RCC_APB2ENR_SYSCFGEN;
|
regval |= RCC_APB2ENR_SYSCFGEN;
|
||||||
#endif
|
#endif
|
||||||
|
@ -16,6 +16,9 @@ config HOST_X86_64
|
|||||||
config HOST_X86
|
config HOST_X86
|
||||||
bool "x86"
|
bool "x86"
|
||||||
|
|
||||||
|
config HOST_ARM
|
||||||
|
bool "arm"
|
||||||
|
|
||||||
endchoice # Host CPU Type
|
endchoice # Host CPU Type
|
||||||
|
|
||||||
config SIM_M32
|
config SIM_M32
|
||||||
|
@ -57,10 +57,12 @@
|
|||||||
/* Storage order: %rbx, %rsp, %rbp, %r12, %r13, %r14, %r15, %rip */
|
/* Storage order: %rbx, %rsp, %rbp, %r12, %r13, %r14, %r15, %rip */
|
||||||
|
|
||||||
# define XCPTCONTEXT_REGS 8
|
# define XCPTCONTEXT_REGS 8
|
||||||
#else
|
#elif defined(CONFIG_HOST_X86) || defined(CONFIG_SIM_M32)
|
||||||
/* Storage order: %ebx, %esi, %edi, %ebp, sp, and return PC */
|
/* Storage order: %ebx, %esi, %edi, %ebp, sp, and return PC */
|
||||||
|
|
||||||
# define XCPTCONTEXT_REGS 6
|
# define XCPTCONTEXT_REGS 6
|
||||||
|
#elif defined(CONFIG_HOST_ARM)
|
||||||
|
# define XCPTCONTEXT_REGS 16
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -47,10 +47,16 @@ ifeq ($(CONFIG_SIM_M32),y)
|
|||||||
else
|
else
|
||||||
ASRCS += up_setjmp64.S
|
ASRCS += up_setjmp64.S
|
||||||
endif
|
endif
|
||||||
else
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_HOST_X86_64),y)
|
||||||
ASRCS += up_setjmp32.S
|
ASRCS += up_setjmp32.S
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_HOST_ARM),y)
|
||||||
|
ASRCS += up_setjmp_arm.S
|
||||||
|
endif
|
||||||
|
|
||||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||||
|
|
||||||
CSRCS = up_initialize.c up_idle.c up_interruptcontext.c up_initialstate.c
|
CSRCS = up_initialize.c up_idle.c up_interruptcontext.c up_initialstate.c
|
||||||
|
@ -132,7 +132,7 @@
|
|||||||
# define JB_SP JB_RSP
|
# define JB_SP JB_RSP
|
||||||
# define JB_PC JB_RSI
|
# define JB_PC JB_RSI
|
||||||
|
|
||||||
#else
|
#elif defined(CONFIG_HOST_X86) || defined(CONFIG_SIM_M32)
|
||||||
/* Storage order: %ebx, $esi, %edi, %ebp, sp, and return PC */
|
/* Storage order: %ebx, $esi, %edi, %ebp, sp, and return PC */
|
||||||
|
|
||||||
# ifdef __ASSEMBLY__
|
# ifdef __ASSEMBLY__
|
||||||
@ -152,7 +152,10 @@
|
|||||||
# define JB_PC (5)
|
# define JB_PC (5)
|
||||||
|
|
||||||
# endif /* __ASSEMBLY__ */
|
# endif /* __ASSEMBLY__ */
|
||||||
#endif /* CONFIG_HOST_X86_64 && !CONFIG_SIM_M32 */
|
#elif defined(CONFIG_HOST_ARM)
|
||||||
|
# define JB_SP 8
|
||||||
|
# define JB_PC 9
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Simulated Heap Definitions **********************************************/
|
/* Simulated Heap Definitions **********************************************/
|
||||||
/* Size of the simulated heap */
|
/* Size of the simulated heap */
|
||||||
|
103
arch/sim/src/up_setjmp_arm.S
Normal file
103
arch/sim/src/up_setjmp_arm.S
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* arch/sim/src/up_setjmp_arm.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Nickolay Semyonov (RPI) <snob@wolpike.com>
|
||||||
|
*
|
||||||
|
* Extracted from the MUSL C-library. The MUSL C library has a compatible
|
||||||
|
* MIT license and is released here under the NuttX 3-clause BSD license:
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
.syntax unified
|
||||||
|
.global up_setjmp
|
||||||
|
.type up_setjmp,%function
|
||||||
|
up_setjmp:
|
||||||
|
mov ip,r0
|
||||||
|
stmia ip!,{v1,v2,v3,v4,v5,v6,sl,fp}
|
||||||
|
mov r2,sp
|
||||||
|
stmia ip!,{r2,lr}
|
||||||
|
mov r0,#0
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
adr r1,1f
|
||||||
|
ldr r2,1f
|
||||||
|
ldr r1,[r1,r2]
|
||||||
|
|
||||||
|
tst r1,#0x260
|
||||||
|
beq 3f
|
||||||
|
tst r1,#0x20
|
||||||
|
beq 2f
|
||||||
|
stc p2, cr4, [ip], #48
|
||||||
|
2: tst r1,#0x40
|
||||||
|
beq 2f
|
||||||
|
.fpu vfp
|
||||||
|
vstmia ip!, {d8-d15}
|
||||||
|
.fpu softvfp
|
||||||
|
.eabi_attribute 10, 0
|
||||||
|
.eabi_attribute 27, 0
|
||||||
|
2: tst r1,#0x200
|
||||||
|
beq 3f
|
||||||
|
stcl p1, cr10, [ip], #8
|
||||||
|
stcl p1, cr11, [ip], #8
|
||||||
|
stcl p1, cr12, [ip], #8
|
||||||
|
stcl p1, cr13, [ip], #8
|
||||||
|
stcl p1, cr14, [ip], #8
|
||||||
|
stcl p1, cr15, [ip], #8
|
||||||
|
#endif
|
||||||
|
3: bx lr
|
||||||
|
|
||||||
|
.syntax unified
|
||||||
|
.global up_longjmp
|
||||||
|
.type up_longjmp,%function
|
||||||
|
up_longjmp:
|
||||||
|
mov ip,r0
|
||||||
|
movs r0,r1
|
||||||
|
moveq r0,#1
|
||||||
|
ldmia ip!, {v1,v2,v3,v4,v5,v6,sl,fp}
|
||||||
|
ldmia ip!, {r2,lr}
|
||||||
|
mov sp,r2
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
.fpu vfp
|
||||||
|
vldmia ip!, {d8-d15}
|
||||||
|
.fpu softvfp
|
||||||
|
.eabi_attribute 10, 0
|
||||||
|
.eabi_attribute 27, 0
|
||||||
|
2: tst r1,#0x200
|
||||||
|
beq 3f
|
||||||
|
ldcl p1, cr10, [ip], #8
|
||||||
|
ldcl p1, cr11, [ip], #8
|
||||||
|
ldcl p1, cr12, [ip], #8
|
||||||
|
ldcl p1, cr13, [ip], #8
|
||||||
|
ldcl p1, cr14, [ip], #8
|
||||||
|
ldcl p1, cr15, [ip], #8
|
||||||
|
#endif
|
||||||
|
3: bx lr
|
@ -2,8 +2,15 @@ README
|
|||||||
^^^^^^
|
^^^^^^
|
||||||
|
|
||||||
This README discusses issues unique to NuttX configurations for the
|
This README discusses issues unique to NuttX configurations for the
|
||||||
Arduino DUE board featuring the Atmel ATSAM3X8E MCU running at 84
|
Arduino DUE board featuring the Atmel ATSAM3X8E MCU running at 84 MHz.
|
||||||
MHz.
|
|
||||||
|
NOTE: If found that newer Arduino Due board differ from the older boards
|
||||||
|
mine: Mine has the 32.768 slow clock crystal and associated caps installed.
|
||||||
|
the newer boards do not. This can cause a hang in the SAM startup code
|
||||||
|
where it waits for the slow crystal input to lock on.
|
||||||
|
|
||||||
|
Options: (1) Solder a 32.768 KHz crystal and associated caps on board or,
|
||||||
|
(2) disable the function sam_setupsupc() in sam_clockconfig.c
|
||||||
|
|
||||||
Supported Shields
|
Supported Shields
|
||||||
-----------------
|
-----------------
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
/* After power-on reset, the SAM3X device is running on a 4MHz internal RC. These
|
/* After power-on reset, the SAM3X device is running on a 4MHz internal RC. These
|
||||||
* definitions will configure clocking
|
* definitions will configure clocking
|
||||||
*
|
*
|
||||||
* MAINOSC: Frequency = 12MHz (crysta)
|
* MAINOSC: Frequency = 12MHz (crystal)
|
||||||
* PLLA: PLL Divider = 1, Multiplier = 14 to generate PLLACK = 168MHz
|
* PLLA: PLL Divider = 1, Multiplier = 14 to generate PLLACK = 168MHz
|
||||||
* Master Clock (MCK): Source = PLLACK, Prescalar = 1 to generate MCK = 84MHz
|
* Master Clock (MCK): Source = PLLACK, Prescalar = 1 to generate MCK = 84MHz
|
||||||
* CPU clock: 84MHz
|
* CPU clock: 84MHz
|
||||||
|
@ -610,7 +610,17 @@ Configuration sub-directories
|
|||||||
unnecessarily busy. There is some prototype code to do just this
|
unnecessarily busy. There is some prototype code to do just this
|
||||||
in the driver, but does not seem to work.
|
in the driver, but does not seem to work.
|
||||||
|
|
||||||
2017-08-24: There is only a single buffer for reassemblying larger
|
2017-08-26: There was only a single buffer for reassemblying larger
|
||||||
packets. This could be an important issue for the hub configuration
|
packets. This could be a problem issue for the hub configuration
|
||||||
which really needs the capability concurrently reassemble multiple
|
which really needs the capability concurrently reassemble multiple
|
||||||
incoming streams.
|
incoming streams. The design was extended to support multiple
|
||||||
|
reassembly buffers.
|
||||||
|
|
||||||
|
Initial testing shows the same basic behavior as noted before:
|
||||||
|
The UDP test works and TCP test (usually) works. There are,
|
||||||
|
however, are errors in reported by the hub in the TCP test.
|
||||||
|
Occassionally the test will hang when ther server echoes the data
|
||||||
|
back to the client. These errors are presumably the result of ACKs
|
||||||
|
from the receiver colliding with frames from the sender.
|
||||||
|
|
||||||
|
Needs more investigation.
|
||||||
|
@ -671,6 +671,7 @@ Configurations
|
|||||||
two star endpoints via the hub, the frames are correctly directed
|
two star endpoints via the hub, the frames are correctly directed
|
||||||
to the hub. However, they are not being forwarded to the other
|
to the hub. However, they are not being forwarded to the other
|
||||||
endpoint.
|
endpoint.
|
||||||
|
|
||||||
2017-06-30: The failure to forward is understood: When the star
|
2017-06-30: The failure to forward is understood: When the star
|
||||||
endpoint sent the IPv6 destination address, the HC06 compression
|
endpoint sent the IPv6 destination address, the HC06 compression
|
||||||
logic elided the address -- meaning that it could be reconstructed
|
logic elided the address -- meaning that it could be reconstructed
|
||||||
@ -686,13 +687,16 @@ Configurations
|
|||||||
some additional fixes for byte ordering in 16-bit and 64-bit
|
some additional fixes for byte ordering in 16-bit and 64-bit
|
||||||
compressed IPv6 addresses, then all tests are working as expected:
|
compressed IPv6 addresses, then all tests are working as expected:
|
||||||
TCP, UDP, Telnet.
|
TCP, UDP, Telnet.
|
||||||
|
|
||||||
2017-08-05: It looks like I have lost one of my Clicker2-STM32 boards.
|
2017-08-05: It looks like I have lost one of my Clicker2-STM32 boards.
|
||||||
This means that I will not be able to do any regression testing as
|
This means that I will not be able to do any regression testing as
|
||||||
changes are made to the radio interfaces and 6LoWPAN :(
|
changes are made to the radio interfaces and 6LoWPAN :(
|
||||||
2017-08-24: There is only a single buffer for reassemblying larger
|
|
||||||
packets. This could be an important issue for the hub configuration
|
2017-08-26: There was only a single buffer for reassemblying larger
|
||||||
|
packets. This could be a problem issue for the hub configuration
|
||||||
which really needs the capability concurrently reassemble multiple
|
which really needs the capability concurrently reassemble multiple
|
||||||
incoming streams.
|
incoming streams. The design was extended to support multiple
|
||||||
|
reassembly buffers but have not yet been verified on this platform.
|
||||||
|
|
||||||
nsh:
|
nsh:
|
||||||
|
|
||||||
|
@ -203,7 +203,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* prescaler common to all PLL inputs; will be 1 (XXX source is implicitly
|
/* prescaler common to all PLL inputs; will be 1 (XXX source is implicitly
|
||||||
as per comment above HSI) */
|
* as per comment above HSI)
|
||||||
|
*/
|
||||||
|
|
||||||
#define STM32L4_PLLCFG_PLLM RCC_PLLCFG_PLLM(1)
|
#define STM32L4_PLLCFG_PLLM RCC_PLLCFG_PLLM(1)
|
||||||
|
|
||||||
@ -292,11 +293,12 @@
|
|||||||
/* REVISIT : this can be configured */
|
/* REVISIT : this can be configured */
|
||||||
|
|
||||||
#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
#define STM32L4_APB2_TIM8_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
#define STM32L4_APB2_TIM15_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
#define STM32L4_APB2_TIM16_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
|
||||||
/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
|
/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
|
||||||
* otherwise frequency is 2xAPBx.
|
* otherwise frequency is 2xAPBx.
|
||||||
* Note: TIM1,8 are on APB2, others on APB1
|
* Note: TIM1,15,16 are on APB2, others on APB1
|
||||||
*/
|
*/
|
||||||
/* REVISIT : this can be configured */
|
/* REVISIT : this can be configured */
|
||||||
|
|
||||||
@ -379,7 +381,8 @@
|
|||||||
#define STM32L4_PCLK2_FREQUENCY (STM32L4_HCLK_FREQUENCY/1)
|
#define STM32L4_PCLK2_FREQUENCY (STM32L4_HCLK_FREQUENCY/1)
|
||||||
|
|
||||||
#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
#define STM32L4_APB2_TIM8_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
#define STM32L4_APB2_TIM15_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
#define STM32L4_APB2_TIM16_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
|
||||||
#elif defined(MSI_CLOCK_CONFIG)
|
#elif defined(MSI_CLOCK_CONFIG)
|
||||||
|
|
||||||
@ -459,13 +462,14 @@
|
|||||||
#define STM32L4_PCLK2_FREQUENCY (STM32L4_HCLK_FREQUENCY/1)
|
#define STM32L4_PCLK2_FREQUENCY (STM32L4_HCLK_FREQUENCY/1)
|
||||||
|
|
||||||
#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
#define STM32L4_APB2_TIM8_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
#define STM32L4_APB2_TIM15_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
#define STM32L4_APB2_TIM16_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
|
/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
|
||||||
* otherwise frequency is 2xAPBx.
|
* otherwise frequency is 2xAPBx.
|
||||||
* Note: TIM1,8,15,16,17 are on APB2, others on APB1
|
* Note: TIM1,15,16 are on APB2, others on APB1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define BOARD_TIM1_FREQUENCY STM32L4_HCLK_FREQUENCY
|
#define BOARD_TIM1_FREQUENCY STM32L4_HCLK_FREQUENCY
|
||||||
@ -475,10 +479,8 @@
|
|||||||
#define BOARD_TIM5_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
#define BOARD_TIM5_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
||||||
#define BOARD_TIM6_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
#define BOARD_TIM6_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
||||||
#define BOARD_TIM7_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
#define BOARD_TIM7_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
||||||
#define BOARD_TIM8_FREQUENCY STM32L4_HCLK_FREQUENCY
|
|
||||||
#define BOARD_TIM15_FREQUENCY STM32L4_HCLK_FREQUENCY
|
#define BOARD_TIM15_FREQUENCY STM32L4_HCLK_FREQUENCY
|
||||||
#define BOARD_TIM16_FREQUENCY STM32L4_HCLK_FREQUENCY
|
#define BOARD_TIM16_FREQUENCY STM32L4_HCLK_FREQUENCY
|
||||||
#define BOARD_TIM17_FREQUENCY STM32L4_HCLK_FREQUENCY
|
|
||||||
#define BOARD_LPTIM1_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
#define BOARD_LPTIM1_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
||||||
#define BOARD_LPTIM2_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
#define BOARD_LPTIM2_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
||||||
|
|
||||||
|
@ -292,11 +292,12 @@
|
|||||||
/* REVISIT : this can be configured */
|
/* REVISIT : this can be configured */
|
||||||
|
|
||||||
#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
#define STM32L4_APB2_TIM8_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
#define STM32L4_APB2_TIM15_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
#define STM32L4_APB2_TIM16_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
|
||||||
/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
|
/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
|
||||||
* otherwise frequency is 2xAPBx.
|
* otherwise frequency is 2xAPBx.
|
||||||
* Note: TIM1,8 are on APB2, others on APB1
|
* Note: TIM1,15,16 are on APB2, others on APB1
|
||||||
*/
|
*/
|
||||||
/* REVISIT : this can be configured */
|
/* REVISIT : this can be configured */
|
||||||
|
|
||||||
@ -379,7 +380,8 @@
|
|||||||
#define STM32L4_PCLK2_FREQUENCY (STM32L4_HCLK_FREQUENCY/1)
|
#define STM32L4_PCLK2_FREQUENCY (STM32L4_HCLK_FREQUENCY/1)
|
||||||
|
|
||||||
#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
#define STM32L4_APB2_TIM8_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
#define STM32L4_APB2_TIM15_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
#define STM32L4_APB2_TIM16_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
|
||||||
#elif defined(MSI_CLOCK_CONFIG)
|
#elif defined(MSI_CLOCK_CONFIG)
|
||||||
|
|
||||||
@ -459,13 +461,14 @@
|
|||||||
#define STM32L4_PCLK2_FREQUENCY (STM32L4_HCLK_FREQUENCY/1)
|
#define STM32L4_PCLK2_FREQUENCY (STM32L4_HCLK_FREQUENCY/1)
|
||||||
|
|
||||||
#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
#define STM32L4_APB2_TIM8_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
#define STM32L4_APB2_TIM15_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
#define STM32L4_APB2_TIM16_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
|
/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
|
||||||
* otherwise frequency is 2xAPBx.
|
* otherwise frequency is 2xAPBx.
|
||||||
* Note: TIM1,8,15,16,17 are on APB2, others on APB1
|
* Note: TIM1,15,16 are on APB2, others on APB1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define BOARD_TIM1_FREQUENCY STM32L4_HCLK_FREQUENCY
|
#define BOARD_TIM1_FREQUENCY STM32L4_HCLK_FREQUENCY
|
||||||
@ -475,10 +478,8 @@
|
|||||||
#define BOARD_TIM5_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
#define BOARD_TIM5_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
||||||
#define BOARD_TIM6_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
#define BOARD_TIM6_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
||||||
#define BOARD_TIM7_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
#define BOARD_TIM7_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
||||||
#define BOARD_TIM8_FREQUENCY STM32L4_HCLK_FREQUENCY
|
|
||||||
#define BOARD_TIM15_FREQUENCY STM32L4_HCLK_FREQUENCY
|
#define BOARD_TIM15_FREQUENCY STM32L4_HCLK_FREQUENCY
|
||||||
#define BOARD_TIM16_FREQUENCY STM32L4_HCLK_FREQUENCY
|
#define BOARD_TIM16_FREQUENCY STM32L4_HCLK_FREQUENCY
|
||||||
#define BOARD_TIM17_FREQUENCY STM32L4_HCLK_FREQUENCY
|
|
||||||
#define BOARD_LPTIM1_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
#define BOARD_LPTIM1_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
||||||
#define BOARD_LPTIM2_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
#define BOARD_LPTIM2_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
#include "nucleo-l452re.h"
|
#include "nucleo-l452re.h"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Defintiionis
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#undef HAVE_I2C_DRIVER
|
#undef HAVE_I2C_DRIVER
|
||||||
|
@ -293,10 +293,13 @@
|
|||||||
|
|
||||||
#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
#define STM32L4_APB2_TIM8_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
#define STM32L4_APB2_TIM8_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
#define STM32L4_APB2_TIM15_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
#define STM32L4_APB2_TIM16_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
#define STM32L4_APB2_TIM17_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
|
||||||
/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
|
/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
|
||||||
* otherwise frequency is 2xAPBx.
|
* otherwise frequency is 2xAPBx.
|
||||||
* Note: TIM1,8 are on APB2, others on APB1
|
* Note: TIM1,8,15,16,17 are on APB2, others on APB1
|
||||||
*/
|
*/
|
||||||
/* REVISIT : this can be configured */
|
/* REVISIT : this can be configured */
|
||||||
|
|
||||||
@ -380,6 +383,9 @@
|
|||||||
|
|
||||||
#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
#define STM32L4_APB2_TIM8_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
#define STM32L4_APB2_TIM8_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
#define STM32L4_APB2_TIM15_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
#define STM32L4_APB2_TIM16_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
#define STM32L4_APB2_TIM17_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
|
||||||
#elif defined(MSI_CLOCK_CONFIG)
|
#elif defined(MSI_CLOCK_CONFIG)
|
||||||
|
|
||||||
@ -460,6 +466,9 @@
|
|||||||
|
|
||||||
#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
#define STM32L4_APB2_TIM8_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
#define STM32L4_APB2_TIM8_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
#define STM32L4_APB2_TIM15_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
#define STM32L4_APB2_TIM16_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
#define STM32L4_APB2_TIM17_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -178,10 +178,13 @@
|
|||||||
|
|
||||||
#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
#define STM32L4_APB2_TIM8_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
#define STM32L4_APB2_TIM8_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
#define STM32L4_APB2_TIM15_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
#define STM32L4_APB2_TIM16_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
#define STM32L4_APB2_TIM17_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
|
|
||||||
/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
|
/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
|
||||||
* otherwise frequency is 2xAPBx.
|
* otherwise frequency is 2xAPBx.
|
||||||
* Note: TIM1,8 are on APB2, others on APB1
|
* Note: TIM1,8,15,16,17 are on APB2, others on APB1
|
||||||
*/
|
*/
|
||||||
/* REVISIT : this can be configured */
|
/* REVISIT : this can be configured */
|
||||||
|
|
||||||
@ -361,9 +364,9 @@
|
|||||||
/* DMA channels *************************************************************/
|
/* DMA channels *************************************************************/
|
||||||
/* ADC */
|
/* ADC */
|
||||||
|
|
||||||
#define ADC1_DMA_CHAN DMAMAP_ADC1_1
|
#define ADC1_DMA_CHAN DMACHAN_ADC1_1
|
||||||
#define ADC2_DMA_CHAN DMAMAP_ADC2_1
|
#define ADC2_DMA_CHAN DMACHAN_ADC2_1
|
||||||
#define ADC3_DMA_CHAN DMAMAP_ADC3_1
|
#define ADC3_DMA_CHAN DMACHAN_ADC3_1
|
||||||
|
|
||||||
/* SPI
|
/* SPI
|
||||||
*
|
*
|
||||||
|
@ -997,7 +997,7 @@ Tickless OS
|
|||||||
will have an error of 0.6% and will have inaccuracies that will
|
will have an error of 0.6% and will have inaccuracies that will
|
||||||
effect the time due to long term error build-up.
|
effect the time due to long term error build-up.
|
||||||
|
|
||||||
Using the slow clock clock input, the Tickless support is functional,
|
Using the slow clock input, the Tickless support is functional,
|
||||||
however, there are inaccuracies in delays. For example,
|
however, there are inaccuracies in delays. For example,
|
||||||
|
|
||||||
nsh> sleep 10
|
nsh> sleep 10
|
||||||
@ -1318,7 +1318,7 @@ Configuration sub-directories
|
|||||||
|
|
||||||
mrf24j40-starhub
|
mrf24j40-starhub
|
||||||
|
|
||||||
This configuration implement a hub node in a 6LoWPAN start network.
|
This configuration implements a hub node in a 6LoWPAN start network.
|
||||||
It is intended for the us the mrf24j40-starpoint configuration with
|
It is intended for the us the mrf24j40-starpoint configuration with
|
||||||
the clicker2-stm32 configurations. Essentially, the SAME70 Xplained
|
the clicker2-stm32 configurations. Essentially, the SAME70 Xplained
|
||||||
plays the roll of the hub in the configuration and the clicker2-stm32
|
plays the roll of the hub in the configuration and the clicker2-stm32
|
||||||
@ -1383,10 +1383,11 @@ Configuration sub-directories
|
|||||||
|
|
||||||
No significant functional testing has yet been performed.
|
No significant functional testing has yet been performed.
|
||||||
|
|
||||||
2017-08-24: There is only a single buffer for reassemblying larger
|
2017-08-26: There was only a single buffer for reassemblying larger
|
||||||
packets. This could be an important issue for the hub configuration
|
packets. This could be a problem issue for the hub configuration
|
||||||
which really needs the capability concurrently reassemble multiple
|
which really needs the capability concurrently reassemble multiple
|
||||||
incoming streams.
|
incoming streams. The design was extended to support multiple
|
||||||
|
reassembly buffers but have not yet been verified on this platform.
|
||||||
|
|
||||||
netnsh:
|
netnsh:
|
||||||
|
|
||||||
|
@ -1956,10 +1956,11 @@ Configuration sub-directories
|
|||||||
The SPI signals look clean on the board and the MRF24J40 seems
|
The SPI signals look clean on the board and the MRF24J40 seems
|
||||||
fully functional.
|
fully functional.
|
||||||
|
|
||||||
2017-08-24: There is only a single buffer for reassemblying larger
|
2017-08-26: There was only a single buffer for reassemblying larger
|
||||||
packets. This could be an important issue for the hub configuration
|
packets. This could be a problem issue for the hub configuration
|
||||||
which really needs the capability concurrently reassemble multiple
|
which really needs the capability concurrently reassemble multiple
|
||||||
incoming streams.
|
incoming streams. The design was extended to support multiple
|
||||||
|
reassembly buffers but additional testing is needed.
|
||||||
|
|
||||||
mxtxplnd:
|
mxtxplnd:
|
||||||
|
|
||||||
|
@ -292,6 +292,25 @@ config BQ2425X
|
|||||||
---help---
|
---help---
|
||||||
The BQ24250/BQ24251 are battery charger for lithium-ion batteries.
|
The BQ24250/BQ24251 are battery charger for lithium-ion batteries.
|
||||||
|
|
||||||
|
config BQ2429X
|
||||||
|
bool "BQ2429X Battery charger support"
|
||||||
|
default n
|
||||||
|
select I2C
|
||||||
|
select I2C_BQ2429X
|
||||||
|
depends on BATTERY_CHARGER
|
||||||
|
---help---
|
||||||
|
The BQ24296/BQ24297/BQ24296M are battery charger for lithium-ion batteries.
|
||||||
|
|
||||||
|
if BQ2429X
|
||||||
|
|
||||||
|
config DEBUG_BQ2429X
|
||||||
|
bool "BQ2429X Debug Features"
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
Enable BQ2429X battery management debug features.
|
||||||
|
|
||||||
|
endif # BQ2429X
|
||||||
|
|
||||||
config BATTERY_GAUGE
|
config BATTERY_GAUGE
|
||||||
bool "Battery Fuel Gauge support"
|
bool "Battery Fuel Gauge support"
|
||||||
default n
|
default n
|
||||||
@ -312,6 +331,10 @@ config I2C_BQ2425X
|
|||||||
bool
|
bool
|
||||||
default y if BQ2425X
|
default y if BQ2425X
|
||||||
|
|
||||||
|
config I2C_BQ2429X
|
||||||
|
bool
|
||||||
|
default y if BQ2429X
|
||||||
|
|
||||||
config I2C_MAX1704X
|
config I2C_MAX1704X
|
||||||
bool
|
bool
|
||||||
default y if MAX1704X
|
default y if MAX1704X
|
||||||
|
@ -80,6 +80,12 @@ ifeq ($(CONFIG_I2C_BQ2425X),y)
|
|||||||
CSRCS += bq2425x.c
|
CSRCS += bq2425x.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Add the BQ2429x I2C-based battery charger driver
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_I2C_BQ2429X),y)
|
||||||
|
CSRCS += bq2429x.c
|
||||||
|
endif
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Include power support in the build
|
# Include power support in the build
|
||||||
|
@ -160,7 +160,7 @@ static int bat_charger_ioctl(FAR struct file *filep, int cmd,
|
|||||||
FAR struct battery_charger_dev_s *dev = inode->i_private;
|
FAR struct battery_charger_dev_s *dev = inode->i_private;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Inforce mutually exclusive access to the battery driver */
|
/* Enforce mutually exclusive access to the battery driver */
|
||||||
|
|
||||||
ret = sem_wait(&dev->batsem);
|
ret = sem_wait(&dev->batsem);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -168,7 +168,7 @@ static int bat_charger_ioctl(FAR struct file *filep, int cmd,
|
|||||||
return -errno; /* Probably EINTR */
|
return -errno; /* Probably EINTR */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Procss the IOCTL command */
|
/* Process the IOCTL command */
|
||||||
|
|
||||||
ret = -EINVAL; /* Assume a bad argument */
|
ret = -EINVAL; /* Assume a bad argument */
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
@ -239,6 +239,16 @@ static int bat_charger_ioctl(FAR struct file *filep, int cmd,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BATIOC_OPERATE:
|
||||||
|
{
|
||||||
|
FAR int *ptr = (FAR int *)((uintptr_t)arg);
|
||||||
|
if (ptr)
|
||||||
|
{
|
||||||
|
ret = dev->ops->operate(dev, (uintptr_t)arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
_err("ERROR: Unrecognized cmd: %d\n", cmd);
|
_err("ERROR: Unrecognized cmd: %d\n", cmd);
|
||||||
ret = -ENOTTY;
|
ret = -ENOTTY;
|
||||||
|
@ -134,6 +134,7 @@ static int bq2425x_online(struct battery_charger_dev_s *dev, bool *status);
|
|||||||
static int bq2425x_voltage(struct battery_charger_dev_s *dev, int value);
|
static int bq2425x_voltage(struct battery_charger_dev_s *dev, int value);
|
||||||
static int bq2425x_current(struct battery_charger_dev_s *dev, int value);
|
static int bq2425x_current(struct battery_charger_dev_s *dev, int value);
|
||||||
static int bq2425x_input_current(struct battery_charger_dev_s *dev, int value);
|
static int bq2425x_input_current(struct battery_charger_dev_s *dev, int value);
|
||||||
|
static int bq2425x_operate(struct battery_charger_dev_s *dev, uintptr_t param);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
@ -146,7 +147,8 @@ static const struct battery_charger_operations_s g_bq2425xops =
|
|||||||
bq2425x_online,
|
bq2425x_online,
|
||||||
bq2425x_voltage,
|
bq2425x_voltage,
|
||||||
bq2425x_current,
|
bq2425x_current,
|
||||||
bq2425x_input_current
|
bq2425x_input_current,
|
||||||
|
bq2425x_operate
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -728,6 +730,19 @@ static int bq2425x_input_current(struct battery_charger_dev_s *dev, int value)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: bq2425x_operate
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Do miscellaneous battery ioctl()
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int bq2425x_operate(struct battery_charger_dev_s *dev, uintptr_t param)
|
||||||
|
{
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
1262
drivers/power/bq2429x.c
Normal file
1262
drivers/power/bq2429x.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -127,6 +127,7 @@
|
|||||||
#include <nuttx/spi/spi.h>
|
#include <nuttx/spi/spi.h>
|
||||||
#include <nuttx/net/netdev.h>
|
#include <nuttx/net/netdev.h>
|
||||||
#include <nuttx/net/radiodev.h>
|
#include <nuttx/net/radiodev.h>
|
||||||
|
#include <nuttx/net/sixlowpan.h>
|
||||||
|
|
||||||
#include <nuttx/wireless/spirit.h>
|
#include <nuttx/wireless/spirit.h>
|
||||||
#include <nuttx/wireless/pktradio.h>
|
#include <nuttx/wireless/pktradio.h>
|
||||||
@ -363,6 +364,12 @@ int spirit_hw_initialize(FAR struct spirit_driver_s *dev,
|
|||||||
* Private Data
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_6LOWPAN
|
||||||
|
/* One single packet buffer */
|
||||||
|
|
||||||
|
static struct sixlowpan_reassbuf_s g_iobuffer;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Spirit radio initialization */
|
/* Spirit radio initialization */
|
||||||
|
|
||||||
static const struct radio_init_s g_radio_init =
|
static const struct radio_init_s g_radio_init =
|
||||||
@ -1043,6 +1050,11 @@ static void spirit_receive_work(FAR void *arg)
|
|||||||
iob = pktmeta->pm_iob;
|
iob = pktmeta->pm_iob;
|
||||||
pktmeta->pm_iob = NULL;
|
pktmeta->pm_iob = NULL;
|
||||||
|
|
||||||
|
/* Make sure the our single packet buffer is attached */
|
||||||
|
|
||||||
|
priv->radio.r_dev.d_buf = g_iobuffer.rb_buf;
|
||||||
|
priv->radio.r_dev.d_len = 0;
|
||||||
|
|
||||||
/* Send the next frame to the network */
|
/* Send the next frame to the network */
|
||||||
|
|
||||||
wlinfo("Send frame %p to the network: Offset=%u Length=%u\n",
|
wlinfo("Send frame %p to the network: Offset=%u Length=%u\n",
|
||||||
@ -1137,7 +1149,7 @@ static void spirit_interrupt_work(FAR void *arg)
|
|||||||
#ifdef CONFIG_SPIRIT_FIFOS
|
#ifdef CONFIG_SPIRIT_FIFOS
|
||||||
irqstatus.IRQ_RX_FIFO_ALMOST_FULL = 0;
|
irqstatus.IRQ_RX_FIFO_ALMOST_FULL = 0;
|
||||||
|
|
||||||
/* Discard any RX buffer that might have been allocated */
|
/* Discard any packet buffer that might have been allocated */
|
||||||
|
|
||||||
if (priv->rxbuffer != NULL)
|
if (priv->rxbuffer != NULL)
|
||||||
{
|
{
|
||||||
@ -1281,7 +1293,12 @@ static void spirit_interrupt_work(FAR void *arg)
|
|||||||
|
|
||||||
if (priv->state != DRIVER_STATE_RECEIVING)
|
if (priv->state != DRIVER_STATE_RECEIVING)
|
||||||
{
|
{
|
||||||
DEBUGASSERT(priv->state == DRIVER_STATE_IDLE);
|
/* As a race condition, the TX state, but overriden by concurrent
|
||||||
|
* RX activity? This assertion here *does* fire:
|
||||||
|
*
|
||||||
|
* DEBUGASSERT(priv->state == DRIVER_STATE_IDLE);
|
||||||
|
*/
|
||||||
|
|
||||||
priv->state = DRIVER_STATE_RECEIVING;
|
priv->state = DRIVER_STATE_RECEIVING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1320,7 +1337,7 @@ static void spirit_interrupt_work(FAR void *arg)
|
|||||||
|
|
||||||
irqstatus.IRQ_RX_FIFO_ALMOST_FULL = 0;
|
irqstatus.IRQ_RX_FIFO_ALMOST_FULL = 0;
|
||||||
|
|
||||||
/* There should be a RX buffer that was allocated when the data sync
|
/* There should be a packet buffer that was allocated when the data sync
|
||||||
* interrupt was processed.
|
* interrupt was processed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1473,7 +1490,7 @@ static void spirit_interrupt_work(FAR void *arg)
|
|||||||
|
|
||||||
wlinfo("RX FIFO almost full\n");
|
wlinfo("RX FIFO almost full\n");
|
||||||
|
|
||||||
/* There should be a RX buffer that was allocated when the data sync
|
/* There should be a packet buffer that was allocated when the data sync
|
||||||
* interrupt was processed.
|
* interrupt was processed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1571,7 +1588,7 @@ static void spirit_interrupt_work(FAR void *arg)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_SPIRIT_FIFOS
|
#ifdef CONFIG_SPIRIT_FIFOS
|
||||||
/* Discard any RX buffer that might have been allocated */
|
/* Discard any packet buffer that might have been allocated */
|
||||||
|
|
||||||
if (priv->rxbuffer != NULL)
|
if (priv->rxbuffer != NULL)
|
||||||
{
|
{
|
||||||
@ -1752,6 +1769,12 @@ static void spirit_txpoll_work(FAR void *arg)
|
|||||||
|
|
||||||
net_lock();
|
net_lock();
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_6LOWPAN
|
||||||
|
/* Make sure the our single packet buffer is attached */
|
||||||
|
|
||||||
|
priv->radio.r_dev.d_buf = g_iobuffer.rb_buf;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Do nothing if the network is not yet UP */
|
/* Do nothing if the network is not yet UP */
|
||||||
|
|
||||||
if (!priv->ifup)
|
if (!priv->ifup)
|
||||||
@ -2752,7 +2775,6 @@ int spirit_netdev_initialize(FAR struct spi_dev_s *spi,
|
|||||||
FAR struct spirit_driver_s *priv;
|
FAR struct spirit_driver_s *priv;
|
||||||
FAR struct radio_driver_s *radio;
|
FAR struct radio_driver_s *radio;
|
||||||
FAR struct net_driver_s *dev;
|
FAR struct net_driver_s *dev;
|
||||||
FAR uint8_t *pktbuf;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Allocate a driver state structure instance */
|
/* Allocate a driver state structure instance */
|
||||||
@ -2764,16 +2786,6 @@ int spirit_netdev_initialize(FAR struct spi_dev_s *spi,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate a packet buffer */
|
|
||||||
|
|
||||||
pktbuf = (uint8_t *)kmm_zalloc(CONFIG_NET_6LOWPAN_MTU + CONFIG_NET_GUARDSIZE);
|
|
||||||
if (priv == NULL)
|
|
||||||
{
|
|
||||||
wlerr("ERROR: Failed to allocate a packet buffer\n");
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto errout_with_alloc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Attach the interface, lower driver, and devops */
|
/* Attach the interface, lower driver, and devops */
|
||||||
|
|
||||||
priv->lower = lower;
|
priv->lower = lower;
|
||||||
@ -2798,7 +2810,6 @@ int spirit_netdev_initialize(FAR struct spi_dev_s *spi,
|
|||||||
/* Initialize the common network device fields */
|
/* Initialize the common network device fields */
|
||||||
|
|
||||||
dev = &radio->r_dev;
|
dev = &radio->r_dev;
|
||||||
dev->d_buf = pktbuf; /* Single packet buffer */
|
|
||||||
dev->d_ifup = spirit_ifup; /* I/F up (new IP address) callback */
|
dev->d_ifup = spirit_ifup; /* I/F up (new IP address) callback */
|
||||||
dev->d_ifdown = spirit_ifdown; /* I/F down callback */
|
dev->d_ifdown = spirit_ifdown; /* I/F down callback */
|
||||||
dev->d_txavail = spirit_txavail; /* New TX data callback */
|
dev->d_txavail = spirit_txavail; /* New TX data callback */
|
||||||
@ -2839,7 +2850,7 @@ int spirit_netdev_initialize(FAR struct spi_dev_s *spi,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
wlerr("ERROR: Failed to attach interrupt: %d\n", ret);
|
wlerr("ERROR: Failed to attach interrupt: %d\n", ret);
|
||||||
goto errout_with_pktbuf;
|
goto errout_with_alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable Radio IRQ */
|
/* Enable Radio IRQ */
|
||||||
@ -2850,11 +2861,6 @@ int spirit_netdev_initialize(FAR struct spi_dev_s *spi,
|
|||||||
errout_with_attach:
|
errout_with_attach:
|
||||||
(void)lower->attach(lower, NULL, NULL);
|
(void)lower->attach(lower, NULL, NULL);
|
||||||
|
|
||||||
errout_with_pktbuf:
|
|
||||||
#if 0
|
|
||||||
kmm_free(pktbuf);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
errout_with_alloc:
|
errout_with_alloc:
|
||||||
kmm_free(priv);
|
kmm_free(priv);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -13,6 +13,7 @@ config FS_AUTOMOUNTER
|
|||||||
bool "Auto-mounter"
|
bool "Auto-mounter"
|
||||||
default n
|
default n
|
||||||
depends on !DISABLE_MOUNTPOINT
|
depends on !DISABLE_MOUNTPOINT
|
||||||
|
select SCHED_LPWORK
|
||||||
---help---
|
---help---
|
||||||
The automounter provides an OS-internal mechanism for automatically
|
The automounter provides an OS-internal mechanism for automatically
|
||||||
mounting and unmounting removable media as the media is inserted and
|
mounting and unmounting removable media as the media is inserted and
|
||||||
|
@ -42,8 +42,6 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <nuttx/clock.h>
|
|
||||||
#include <nuttx/mm/iob.h>
|
|
||||||
#include <nuttx/net/netdev.h>
|
#include <nuttx/net/netdev.h>
|
||||||
|
|
||||||
#if defined(CONFIG_NET_6LOWPAN) || defined(CONFIG_NET_IEEE802154)
|
#if defined(CONFIG_NET_6LOWPAN) || defined(CONFIG_NET_IEEE802154)
|
||||||
@ -76,22 +74,37 @@ struct radiodev_properties_s
|
|||||||
* The radio network driver does not use the d_buf packet buffer directly.
|
* The radio network driver does not use the d_buf packet buffer directly.
|
||||||
* Rather, it uses a list smaller frame buffers.
|
* Rather, it uses a list smaller frame buffers.
|
||||||
*
|
*
|
||||||
* - The packet fragment data is provided in an IOB in the via the
|
* - Outgoing frame data is provided in an IOB in the via the
|
||||||
* r_req_data() interface method each time that the radio needs to
|
* r_req_data() interface method each time that the radio needs to
|
||||||
* send more data. The length of the frame is provided in the io_len
|
* send more data. The length of the frame is provided in the io_len
|
||||||
* field of the IOB.
|
* field of the IOB.
|
||||||
*
|
*
|
||||||
* In this case, the d_buf is not used at all and, if fact, may be
|
* Outgoing frames are generated when the radio network driver calls
|
||||||
* NULL.
|
* the devif_poll(), devif_timer(), sixlowpan_input(), or
|
||||||
|
* ieee802154_input() interfaces. In each case, the radio driver must
|
||||||
|
* provide a working buffer in the d_buf pointer. A special form of
|
||||||
|
* the packet buffer must be used, struct sixlowpan_reassbuf_s. This
|
||||||
|
* special for includes appended data for managing reassembly of packets.
|
||||||
*
|
*
|
||||||
* - Received frames are provided by radio network driver to the network
|
* - Received frames are provided by radio network driver to the network
|
||||||
* via an IOB parameter in the sixlowpan_input() pr ieee802154_input()
|
* via an IOB parameter in the sixlowpan_input() pr ieee802154_input()
|
||||||
* interface. The length of the frame is io_len.
|
* interface. The length of the frame is io_len.
|
||||||
*
|
*
|
||||||
* - 6LoWPAN frames and will be uncompressed and possibly reassembled in
|
* Again, the radio network driver must provide an instance of struct
|
||||||
* the d_buf; d_len will hold the size of the reassembled packet.
|
* sixlowpan_reassbuf_s as the packet buffer in the d_buf field. This
|
||||||
|
* driver-provided data will only be used if the the receive frames are
|
||||||
|
* not fragmented.
|
||||||
*
|
*
|
||||||
* In this case, a d_buf of size CONFIG_NET_6LOWPAN_MTU must be provided.
|
* - Received 6LoWPAN frames and will be uncompressed and possibly
|
||||||
|
* reassembled in resassembled the d_buf; d_len will hold the size of
|
||||||
|
* the reassembled packet.
|
||||||
|
*
|
||||||
|
* For fagemented frames, d_buf provided by radio driver will not be
|
||||||
|
* used. 6LoWPAN must handle mutliple reassemblies from different
|
||||||
|
* sources simultaneously. To support this, 6LoWPAN will allocate a
|
||||||
|
* unique reassembly buffer for each active reassembly, based on the
|
||||||
|
* reassembly tag and source radio address. These reassembly buffers
|
||||||
|
* are managed entirely by the 6LoWPAN layer.
|
||||||
*
|
*
|
||||||
* This is accomplished by "inheriting" the standard 'struct net_driver_s'
|
* This is accomplished by "inheriting" the standard 'struct net_driver_s'
|
||||||
* and appending the frame buffer as well as other metadata needed to
|
* and appending the frame buffer as well as other metadata needed to
|
||||||
@ -103,8 +116,9 @@ struct radiodev_properties_s
|
|||||||
* structure. In general, all fields must be set to NULL. In addition:
|
* structure. In general, all fields must be set to NULL. In addition:
|
||||||
*
|
*
|
||||||
* 1. On a TX poll, the radio network driver should provide its driver
|
* 1. On a TX poll, the radio network driver should provide its driver
|
||||||
* structure. During the course of the poll, the networking layer may
|
* structure along is (single) reassemby buffer provided at d_buf.
|
||||||
* generate outgoing frames. These frames will by provided to the MAC
|
* During the course of the poll, the networking layer may generate
|
||||||
|
* outgoing frames. These frames will by provided to the radio network
|
||||||
* driver via the req_data() method.
|
* driver via the req_data() method.
|
||||||
*
|
*
|
||||||
* After sending each frame through the radio, the MAC driver must
|
* After sending each frame through the radio, the MAC driver must
|
||||||
@ -117,16 +131,17 @@ struct radiodev_properties_s
|
|||||||
* payload area of an IOB frame structure. That IOB structure may be
|
* payload area of an IOB frame structure. That IOB structure may be
|
||||||
* obtained using the iob_alloc() function.
|
* obtained using the iob_alloc() function.
|
||||||
*
|
*
|
||||||
* For 6LoWPAN, the larger dev.d_buf must have a size of at least the
|
* For 6LoWPAN, fragmented packets will be reassembled using allocated
|
||||||
* advertised MTU of the protocol, CONFIG_NET_6LOWPAN_MTU, plus
|
* reassembly buffers that are managed by the 6LoWPAN layer. The radio
|
||||||
* CONFIG_NET_GUARDSIZE. If fragmentation is enabled, then the logical
|
* driver must still provide its (single) reassembly buffer in d_buf;
|
||||||
* packet size may be significantly larger than the size of the frame
|
* that buffer is still used for the case where the packet is not
|
||||||
* buffer. The dev.d_buf is used for de-compressing each frame and
|
* fragmented into many frames. In either case, the packet buffer will
|
||||||
* reassembling any fragmented packets to create the full input packet
|
* have a size of advertised MTU of the protocol, CONFIG_NET_6LOWPAN_MTU,
|
||||||
* that is provided to the application.
|
* plus CONFIG_NET_GUARDSIZE and some additional overhead for reassembly
|
||||||
|
* state data.
|
||||||
*
|
*
|
||||||
* The MAC driver should then inform the network of the reciptor of a
|
* The radio network driver should then inform the network of the recipt
|
||||||
* frame by calling sixlowpan_input() or ieee802154_input(). That
|
* of a frame by calling sixlowpan_input() or ieee802154_input(). That
|
||||||
* single frame (or, perhaps, list of frames) should be provided as
|
* single frame (or, perhaps, list of frames) should be provided as
|
||||||
* second argument of that call.
|
* second argument of that call.
|
||||||
*
|
*
|
||||||
@ -167,65 +182,6 @@ struct radio_driver_s
|
|||||||
uint8_t r_msdu_handle;
|
uint8_t r_msdu_handle;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_NET_6LOWPAN_FRAG
|
|
||||||
/* Fragmentation Support *************************************************/
|
|
||||||
/* Fragmentation is handled frame by frame and requires that certain
|
|
||||||
* state information be retained from frame to frame.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* r_dgramtag. Datagram tag to be put in the header of the set of
|
|
||||||
* fragments. It is used by the recipient to match fragments of the
|
|
||||||
* same payload.
|
|
||||||
*
|
|
||||||
* This is the sender's copy of the tag. It is incremented after each
|
|
||||||
* fragmented packet is sent so that it will be unique to that
|
|
||||||
* sequence fragmentation. Its value is then persistent, the values of
|
|
||||||
* other fragmentation variables are valid on during a single
|
|
||||||
* fragmentation sequence (while r_accumlen > 0)
|
|
||||||
*/
|
|
||||||
|
|
||||||
uint16_t r_dgramtag;
|
|
||||||
|
|
||||||
/* r_reasstag. Each frame in the reassembly has a tag. That tag must
|
|
||||||
* match the reassembly tag in the fragments being merged.
|
|
||||||
*
|
|
||||||
* This is the same tag as r_dgramtag but is saved on the receiving
|
|
||||||
* side to match all of the fragments of the packet.
|
|
||||||
*/
|
|
||||||
|
|
||||||
uint16_t r_reasstag;
|
|
||||||
|
|
||||||
/* r_pktlen. The total length of the IPv6 packet to be re-assembled in
|
|
||||||
* d_buf. Used to determine when the re-assembly is complete.
|
|
||||||
*/
|
|
||||||
|
|
||||||
uint16_t r_pktlen;
|
|
||||||
|
|
||||||
/* The current accumulated length of the packet being received in d_buf.
|
|
||||||
* Included IPv6 and protocol headers. Currently used only to determine
|
|
||||||
* there is a fragmentation sequence in progress.
|
|
||||||
*/
|
|
||||||
|
|
||||||
uint16_t r_accumlen;
|
|
||||||
|
|
||||||
/* r_boffset. Offset to the beginning of data in d_buf. As each fragment
|
|
||||||
* is received, data is placed at an appriate offset added to this.
|
|
||||||
*/
|
|
||||||
|
|
||||||
uint16_t r_boffset;
|
|
||||||
|
|
||||||
/* The source MAC address of the fragments being merged */
|
|
||||||
|
|
||||||
struct netdev_varaddr_s r_fragsrc;
|
|
||||||
|
|
||||||
/* That time at which reassembly was started. If the elapsed time
|
|
||||||
* exceeds CONFIG_NET_6LOWPAN_MAXAGE, then the reassembly will
|
|
||||||
* be cancelled.
|
|
||||||
*/
|
|
||||||
|
|
||||||
systime_t r_time;
|
|
||||||
#endif /* CONFIG_NET_6LOWPAN_FRAG */
|
|
||||||
|
|
||||||
/* MAC network driver callback functions **********************************/
|
/* MAC network driver callback functions **********************************/
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* Name: r_get_mhrlen
|
* Name: r_get_mhrlen
|
||||||
|
@ -53,6 +53,10 @@
|
|||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include <nuttx/clock.h>
|
||||||
|
#include <nuttx/net/netdev.h>
|
||||||
|
|
||||||
#ifdef CONFIG_NET_6LOWPAN
|
#ifdef CONFIG_NET_6LOWPAN
|
||||||
|
|
||||||
@ -337,6 +341,99 @@
|
|||||||
(a)[4] == 0 && (a)[5] == 0 && (a)[6] == 0 && \
|
(a)[4] == 0 && (a)[5] == 0 && (a)[6] == 0 && \
|
||||||
(((a)[7] & HTONS(0xff00)) == 0x0000))
|
(((a)[7] & HTONS(0xff00)) == 0x0000))
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Fragmentation Support
|
||||||
|
*
|
||||||
|
* This structure defines the reassembly buffer. NOTE: The packet buffer
|
||||||
|
* is needed even in the case where reassembly is disabled.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct sixlowpan_reassbuf_s
|
||||||
|
{
|
||||||
|
/* This is the externally visible packet buffer. This is assigned
|
||||||
|
* to the driver's d_buf field when the reassembly is complete and
|
||||||
|
* provides the full reassembly packet to the network.
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint8_t rb_buf[CONFIG_NET_6LOWPAN_MTU + CONFIG_NET_GUARDSIZE];
|
||||||
|
|
||||||
|
/* Memory pool used to allocate this reassembly buffer */
|
||||||
|
|
||||||
|
uint8_t rb_pool;
|
||||||
|
|
||||||
|
/* True if the reassemby buffer is active (set to false when reassembly is
|
||||||
|
* complete).
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool rb_active;
|
||||||
|
|
||||||
|
/* Supports a singly linked list */
|
||||||
|
|
||||||
|
FAR struct sixlowpan_reassbuf_s *rb_flink;
|
||||||
|
|
||||||
|
#if CONFIG_NET_6LOWPAN_FRAG
|
||||||
|
/* Fragmentation is handled frame by frame and requires that certain
|
||||||
|
* state information be retained from frame to frame. That additional
|
||||||
|
* information follows the externally visible packet buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* rb_dgramtag. Datagram tag to be put in the header of the set of
|
||||||
|
* fragments. It is used by the recipient to match fragments of the
|
||||||
|
* same payload.
|
||||||
|
*
|
||||||
|
* This is the sender's copy of the tag. It is incremented after each
|
||||||
|
* fragmented packet is sent so that it will be unique to that
|
||||||
|
* sequence fragmentation. Its value is then persistent, the values of
|
||||||
|
* other fragmentation variables are valid on during a single
|
||||||
|
* fragmentation sequence (while rb_accumlen > 0)
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint16_t rb_dgramtag;
|
||||||
|
|
||||||
|
/* rb_reasstag. Each frame in the reassembly has a tag. That tag must
|
||||||
|
* match the reassembly tag in the fragments being merged.
|
||||||
|
*
|
||||||
|
* This is the same tag as rb_dgramtag but is saved on the receiving
|
||||||
|
* side to match all of the fragments of the packet.
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint16_t rb_reasstag;
|
||||||
|
|
||||||
|
/* rb_pktlen. The total length of the IPv6 packet to be re-assembled in
|
||||||
|
* d_buf. Used to determine when the re-assembly is complete.
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint16_t rb_pktlen;
|
||||||
|
|
||||||
|
/* The current accumulated length of the packet being received in d_buf.
|
||||||
|
* Included IPv6 and protocol headers. Currently used only to determine
|
||||||
|
* there is a fragmentation sequence in progress.
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint16_t rb_accumlen;
|
||||||
|
|
||||||
|
/* rb_boffset. Offset to the beginning of data in d_buf. As each fragment
|
||||||
|
* is received, data is placed at an appriate offset added to this.
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint16_t rb_boffset;
|
||||||
|
|
||||||
|
/* The source MAC address of the fragments being merged */
|
||||||
|
|
||||||
|
struct netdev_varaddr_s rb_fragsrc;
|
||||||
|
|
||||||
|
/* That time at which reassembly was started. If the elapsed time
|
||||||
|
* exceeds CONFIG_NET_6LOWPAN_MAXAGE, then the reassembly will
|
||||||
|
* be cancelled.
|
||||||
|
*/
|
||||||
|
|
||||||
|
systime_t rb_time;
|
||||||
|
#endif /* CONFIG_NET_6LOWPAN_FRAG */
|
||||||
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Function Prototypes
|
* Public Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
*
|
*
|
||||||
* CONFIG_I2C - I2C support *may* be needed
|
* CONFIG_I2C - I2C support *may* be needed
|
||||||
* CONFIG_I2C_BQ2425X - The BQ2425x driver must be explicitly selected.
|
* CONFIG_I2C_BQ2425X - The BQ2425x driver must be explicitly selected.
|
||||||
|
* CONFIG_I2C_BQ2429X - The BQ2429x driver must be explicitly selected.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* IOCTL Commands ***********************************************************/
|
/* IOCTL Commands ***********************************************************/
|
||||||
@ -84,6 +85,8 @@
|
|||||||
* Input value: An int defining the current value.
|
* Input value: An int defining the current value.
|
||||||
* BATIOC_INPUT_CURRENT - Define the input current limit of power supply.
|
* BATIOC_INPUT_CURRENT - Define the input current limit of power supply.
|
||||||
* Input value: An int defining the input current limit value.
|
* Input value: An int defining the input current limit value.
|
||||||
|
* BATIOC_OPERATE - Perform miscellaneous, device-specific charger operation.
|
||||||
|
* Input value: An uintptr_t that can hold a pointer to struct batio_operate_msg_s.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Special input values for BATIOC_INPUT_CURRENT that may optionally
|
/* Special input values for BATIOC_INPUT_CURRENT that may optionally
|
||||||
@ -151,6 +154,10 @@ struct battery_charger_operations_s
|
|||||||
/* Set the input current limit of power supply */
|
/* Set the input current limit of power supply */
|
||||||
|
|
||||||
int (*input_current)(struct battery_charger_dev_s *dev, int value);
|
int (*input_current)(struct battery_charger_dev_s *dev, int value);
|
||||||
|
|
||||||
|
/* Do device specific operation */
|
||||||
|
|
||||||
|
int (*operate)(struct battery_charger_dev_s *dev, uintptr_t param);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This structure defines the battery driver state structure */
|
/* This structure defines the battery driver state structure */
|
||||||
@ -207,11 +214,11 @@ int battery_charger_register(FAR const char *devpath,
|
|||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Initialize the BQ2425X battery driver and return an instance of the
|
* Initialize the BQ2425X battery driver and return an instance of the
|
||||||
* lower_half interface that may be used with battery_charger_register();
|
* lower-half interface that may be used with battery_charger_register().
|
||||||
*
|
*
|
||||||
* This driver requires:
|
* This driver requires:
|
||||||
*
|
*
|
||||||
* CONFIG_BATTERY_CHARGER - Upper half battery fuel gauge driver support
|
* CONFIG_BATTERY_CHARGER - Upper half battery charger driver support
|
||||||
* CONFIG_I2C - I2C support
|
* CONFIG_I2C - I2C support
|
||||||
* CONFIG_I2C_BQ2425X - And the driver must be explictly selected.
|
* CONFIG_I2C_BQ2425X - And the driver must be explictly selected.
|
||||||
*
|
*
|
||||||
@ -237,6 +244,55 @@ FAR struct battery_charger_dev_s *bq2425x_initialize(FAR struct i2c_master_s *i2
|
|||||||
int current);
|
int current);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: bq2429x_initialize
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initialize the BQ2429X (BQ24series LiIon Charger with USB OTG boost 5V)
|
||||||
|
* battery driver and return an instance of the lower-half interface that
|
||||||
|
* may be used with battery_charger_register().
|
||||||
|
*
|
||||||
|
* This is for:
|
||||||
|
* BQ24296M VQFN24
|
||||||
|
* BQ24296 VQFN24
|
||||||
|
* BQ24297
|
||||||
|
* BQ24298
|
||||||
|
* Possibly similar:
|
||||||
|
* BQ24262
|
||||||
|
* BQ24259
|
||||||
|
* BQ24292I BQ24295 B
|
||||||
|
* Possibly the following:
|
||||||
|
* BQ24260/1/2 Vin-14V
|
||||||
|
* BQ24190 Vin=17V
|
||||||
|
*
|
||||||
|
* This driver requires:
|
||||||
|
*
|
||||||
|
* CONFIG_BATTERY_CHARGER - Upper half battery charger driver support
|
||||||
|
* CONFIG_I2C - I2C support
|
||||||
|
* CONFIG_I2C_BQ2429X - And the driver must be explictly selected.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* i2c - An instance of the I2C interface to use to communicate with
|
||||||
|
* the BQ2429X
|
||||||
|
* addr - The I2C address of the BQ2429X (Better be 0x6B).
|
||||||
|
* frequency - The I2C frequency
|
||||||
|
* current - The input current our power-supply can offer to charger
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* A pointer to the initialized battery driver instance. A NULL pointer
|
||||||
|
* is returned on a failure to initialize the BQ2429X lower half.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if defined(CONFIG_I2C) && defined(CONFIG_I2C_BQ2429X)
|
||||||
|
|
||||||
|
struct i2c_master_s;
|
||||||
|
FAR struct battery_charger_dev_s *bq2429x_initialize(FAR struct i2c_master_s *i2c,
|
||||||
|
uint8_t addr,
|
||||||
|
uint32_t frequency,
|
||||||
|
int current);
|
||||||
|
#endif
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* include/nuttx/power/battery_ioctl.h
|
* include/nuttx/power/battery_ioctl.h
|
||||||
* NuttX Battery IOCTLs definition
|
* NuttX Battery IOCTLs definition
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2015, 2017 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
|
||||||
@ -60,5 +60,35 @@
|
|||||||
#define BATIOC_CURRENT _BATIOC(0x0005)
|
#define BATIOC_CURRENT _BATIOC(0x0005)
|
||||||
#define BATIOC_INPUT_CURRENT _BATIOC(0x0006)
|
#define BATIOC_INPUT_CURRENT _BATIOC(0x0006)
|
||||||
#define BATIOC_CAPACITY _BATIOC(0x0007)
|
#define BATIOC_CAPACITY _BATIOC(0x0007)
|
||||||
|
#define BATIOC_OPERATE _BATIOC(0x0008)
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
struct batio_operate_msg_s
|
||||||
|
{
|
||||||
|
uint8_t operate_type; /* Really enum batio_operate_e */
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint32_t u32;
|
||||||
|
uint8_t u8[8];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(CONFIG_I2C_BQ2429X)
|
||||||
|
enum batio_operate_e
|
||||||
|
{
|
||||||
|
BATIO_OPRTN_NOP = 0,
|
||||||
|
BATIO_OPRTN_BOOST,
|
||||||
|
BATIO_OPRTN_CHARGE,
|
||||||
|
BATIO_OPRTN_EN_TERM,
|
||||||
|
BATIO_OPRTN_HIZ,
|
||||||
|
BATIO_OPRTN_SYSOFF,
|
||||||
|
BATIO_OPRTN_RESET,
|
||||||
|
BATIO_OPRTN_WDOG,
|
||||||
|
BATIO_OPRTN_END
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __INCLUDE_NUTTX_POWER_BATTERY_IOCTL_H */
|
#endif /* __INCLUDE_NUTTX_POWER_BATTERY_IOCTL_H */
|
||||||
|
244
include/nuttx/power/bq2429x.h
Normal file
244
include/nuttx/power/bq2429x.h
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* drivers/power/bq2429x.h
|
||||||
|
* Lower half driver for BQ2429X battery charger
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Neil Hancock. All rights reserved.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Haltian Ltd. All rights reserved.
|
||||||
|
* Author: Juha Niskanen <juha.niskanen@haltian.com>
|
||||||
|
*
|
||||||
|
* 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 __DRIVERS_POWER_BQ2429X_H
|
||||||
|
#define __DRIVERS_POWER_BQ2429X_H
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Auxiliary Definitions */
|
||||||
|
|
||||||
|
#define BQ2429X_VOLTCHG_MIN 3504
|
||||||
|
#define BQ2429X_VOLTCHG_MAX 4400
|
||||||
|
|
||||||
|
#define BQ2429X_CURRCHG_MIN 512
|
||||||
|
#define BQ2429X_CURRCHG_MAX 3008
|
||||||
|
|
||||||
|
/* BQ2429X Register Definitions ********************************************/
|
||||||
|
#define BQ2429X_REG00 0x00
|
||||||
|
#define BQ2429X_REG01 0x01
|
||||||
|
#define BQ2429X_REG02 0x02
|
||||||
|
#define BQ2429X_REG03 0x03
|
||||||
|
#define BQ2429X_REG04 0x04
|
||||||
|
#define BQ2429X_REG05 0x05
|
||||||
|
#define BQ2429X_REG06 0x06
|
||||||
|
#define BQ2429X_REG07 0x07
|
||||||
|
#define BQ2429X_REG08 0x08
|
||||||
|
#define BQ2429X_REG09 0x09
|
||||||
|
#define BQ2429X_REG0A 0x0a
|
||||||
|
|
||||||
|
/* REG00 Input Source Control Register */
|
||||||
|
|
||||||
|
/* For enabling Device Shutdown for shipping - EN_HIZ=1 until QON pressed*/
|
||||||
|
#define BQ2429XR1_EN_HIZ (1 << 7) /* 0 Disable (default) 1 Enable HighZ on battery, powerdown */
|
||||||
|
|
||||||
|
/* Dynamic Power Management - Indicated in StatusReg DPM_STAT REG08[3]
|
||||||
|
VINDPM - Input Voltage threshold (a drop below 5V) that triggers DPM
|
||||||
|
INLIM - Input current threshold that tiggers DPM */
|
||||||
|
|
||||||
|
#define BQ2429XR0_VINDPM_SHIFT 3 /* VIN DPM Offset 5V? Range*/
|
||||||
|
#define BQ2429XR0_VINDPM_MASK (0xf << BQ2429XR0_VINDPM_SHIFT)
|
||||||
|
# define BQ2429XR0_VINDPM3_080mV (1 << BQ2429XR0_VINDPM_SHIFT)
|
||||||
|
# define BQ2429XR0_VINDPM2_160mV (2 << BQ2429XR0_VINDPM_SHIFT)
|
||||||
|
# define BQ2429XR0_VINDPM1_320mV (4 << BQ2429XR0_VINDPM_SHIFT)
|
||||||
|
# define BQ2429XR0_VINDPM0_640mV (8 << BQ2429XR0_VINDPM_SHIFT)
|
||||||
|
#define BQ2429XR0_INLIM_SHIFT 0 /* Input Current Limit - lower of I2C & ILIM */
|
||||||
|
#define BQ2429XR0_INLIM_MASK (0x7 << BQ2429XR0_INLIM_SHIFT)
|
||||||
|
# define BQ2429XR0_INLIM_0100mA (0x0 << BQ2429XR0_INLIM_SHIFT)
|
||||||
|
# define BQ2429XR0_INLIM_0150mA (0x1 << BQ2429XR0_INLIM_SHIFT)
|
||||||
|
# define BQ2429XR0_INLIM_0500mA (0x2 << BQ2429XR0_INLIM_SHIFT)
|
||||||
|
# define BQ2429XR0_INLIM_0900mA (0x3 << BQ2429XR0_INLIM_SHIFT)
|
||||||
|
# define BQ2429XR0_INLIM_1000mA (0x4 << BQ2429XR0_INLIM_SHIFT)
|
||||||
|
# define BQ2429XR0_INLIM_1500mA (0x5 << BQ2429XR0_INLIM_SHIFT)
|
||||||
|
# define BQ2429XR0_INLIM_2000mA (0x6 << BQ2429XR0_INLIM_SHIFT)
|
||||||
|
# define BQ2429XR0_INLIM_3000mA (0x7 << BQ2429XR0_INLIM_SHIFT)
|
||||||
|
|
||||||
|
/* REG01 Power-On Configuration Register */
|
||||||
|
|
||||||
|
#define BQ2429XR1_REG_RESET (1 << 7) /* Write 1 to Reset all registers to default values */
|
||||||
|
#define BQ2429XR1_DOG_RESET (1 << 6) /* Write 1 for watchdog timer reset */
|
||||||
|
#define BQ2429XR1_OTG_CONFIG (1 << 5) /* =0 Disable (default) =1 Enable See description */
|
||||||
|
#define BQ2429XR1_CHG_CONFIG (1 << 4) /* =0 Disable =1 Enable (default) See description */
|
||||||
|
#define BQ2429XR1_SYS_MINV_SHIFT 1 /* Min Sys Voltage Limit. Offset 3.0V Range 3-3.7V */
|
||||||
|
#define BQ2429XR1_SYS_MINV_MASK (7 << BQ2429XR1_SYS_MINV_SHIFT)
|
||||||
|
#define BQ2429XR1_SYS_MINV0_0_1V (1 << BQ2429XR1_SYS_MINV_SHIFT)
|
||||||
|
#define BQ2429XR1_SYS_MINV0_0_2V (2 << BQ2429XR1_SYS_MINV_SHIFT)
|
||||||
|
#define BQ2429XR1_SYS_MINV0_0_4V (4 << BQ2429XR1_SYS_MINV_SHIFT)
|
||||||
|
|
||||||
|
#define BQ2429XR2_BOOST_LIM (1 << 0) /* 0=1A, 1=1.5A (default) Vout Boost Current Limit */
|
||||||
|
|
||||||
|
/* REG02 Charge Current Control */
|
||||||
|
|
||||||
|
#define BQ2429XR2_ICHG_SHIFT 2
|
||||||
|
#define BQ2429XR2_ICHG_MASK (0x3f << BQ2429XR2_ICHG_SHIFT)
|
||||||
|
|
||||||
|
#define BQ2429XR2_BCOLD (1 << 1) /* Boost Mode temperature threshold config for boost disable 0=76% 1=79% */
|
||||||
|
#define BQ2429XR2_FORCE_20PCT (1 << 0) /* Charge Configuration Threshold 0=Fast 1=less */
|
||||||
|
|
||||||
|
/* REG03 Pre-charge Termination Control Register */
|
||||||
|
|
||||||
|
#define BQ2429XR3_IPRECHG_SHIFT 4 /* Precharge I Limit. Offset 128mA Range 128-2048 mA */
|
||||||
|
#define BQ2429XR3_IPRECHG_MASK (0xf << BQ2429XR3_IPRECHG_SHIFT)
|
||||||
|
#define BQ2429XR3_IPRECHG_0128mA (0x00 << BQ2429XR3_IPRECHG_SHIFT)
|
||||||
|
#define BQ2429XR3_IPRECHG_0128mA (0x01 << BQ2429XR3_IPRECHG_SHIFT)
|
||||||
|
#define BQ2429XR3_IPRECHG_0256mA (0x02 << BQ2429XR3_IPRECHG_SHIFT)
|
||||||
|
#define BQ2429XR3_IPRECHG_0384mA (0x03 << BQ2429XR3_IPRECHG_SHIFT)
|
||||||
|
#define BQ2429XR3_IPRECHG_0512mA (0x04 << BQ2429XR3_IPRECHG_SHIFT)
|
||||||
|
#define BQ2429XR3_IPRECHG_0768mA (0x05 << BQ2429XR3_IPRECHG_SHIFT)
|
||||||
|
#define BQ2429XR3_IPRECHG_0896mA (0x06 << BQ2429XR3_IPRECHG_SHIFT)
|
||||||
|
#define BQ2429XR3_IPRECHG_1024mA (0x07 << BQ2429XR3_IPRECHG_SHIFT)
|
||||||
|
#define BQ2429XR3_IPRECHG_1152mA (0x10 << BQ2429XR3_IPRECHG_SHIFT)
|
||||||
|
#define BQ2429XR3_IPRECHG_1280mA (0x11 << BQ2429XR3_IPRECHG_SHIFT)
|
||||||
|
#define BQ2429XR3_IPRECHG_1408mA (0x12 << BQ2429XR3_IPRECHG_SHIFT)
|
||||||
|
#define BQ2429XR3_IPRECHG_1536mA (0x13 << BQ2429XR3_IPRECHG_SHIFT)
|
||||||
|
#define BQ2429XR3_IPRECHG_1664mA (0x14 << BQ2429XR3_IPRECHG_SHIFT)
|
||||||
|
#define BQ2429XR3_IPRECHG_1792mA (0x15 << BQ2429XR3_IPRECHG_SHIFT)
|
||||||
|
#define BQ2429XR3_IPRECHG_1920mA (0x16 << BQ2429XR3_IPRECHG_SHIFT)
|
||||||
|
#define BQ2429XR3_IPRECHG_2048mA (0x17 << BQ2429XR3_IPRECHG_SHIFT)
|
||||||
|
|
||||||
|
#define BQ2429XR3_ITERM_SHIFT 0 /* Offset 128mA Range 128-2048 mA (128-1024 mA in BQ24296M )*/
|
||||||
|
#define BQ2429XR3_ITERM_MASK (0xf << BQ2429XR3_ITERM_SHIFT)
|
||||||
|
#define BQ2429XR3_ITERM0_128mA (1 << BQ2429XR3_ITERM_SHIFT)
|
||||||
|
#define BQ2429XR3_ITERM0_256mA (2 << BQ2429XR3_ITERM_SHIFT)
|
||||||
|
#define BQ2429XR3_ITERM0_512mA (4 << BQ2429XR3_ITERM_SHIFT)
|
||||||
|
#define BQ2429XR3_ITERM0_1024mA (8 << BQ2429XR3_ITERM_SHIFT) /* Reserved in BQ24296M */
|
||||||
|
|
||||||
|
/* REG04 Charge Voltage Control Register */
|
||||||
|
#define BQ2429XR4_VREG_SHIFT 2 /* Offset 3.504V Range 3.504-4.400V Default 4.208V */
|
||||||
|
#define BQ2429XR4_VREG_MASK (0x3f<< BQ2429XR4_VREG_SHIFT)
|
||||||
|
|
||||||
|
#define BQ2429XR4_BATLOWV (1 << 1) /* 0=2.8V 1=3.0V Pre-charge to fast Charge */
|
||||||
|
#define BQ2429XR4_VRECHG (1 << 0) /* 0=100mV 1=300mV */
|
||||||
|
|
||||||
|
/* REG05 Charge Termination Timer Control Register */
|
||||||
|
|
||||||
|
#define BQ2429XR5_EN_TERM (1 << 7) /* 0=Disable 1=Enable(default) terminate of charge */
|
||||||
|
#define BQ2429XR5_RESERVED6 (1 << 6)
|
||||||
|
#define BQ2429XR5_WATCHDOG_SHIFT 4 /* Watchdog Timer Settings */
|
||||||
|
#define BQ2429XR5_WATCHDOG_MASK (3 << BQ2429XR5_WATCHDOG_SHIFT)
|
||||||
|
# define BQ2429XR5_WATCHDOG_DIS (0 << BQ2429XR5_WATCHDOG_SHIFT)
|
||||||
|
# define BQ2429XR5_WATCHDOG_040Sec (1 << BQ2429XR5_WATCHDOG_SHIFT)
|
||||||
|
# define BQ2429XR5_WATCHDOG_080Sec (2 << BQ2429XR5_WATCHDOG_SHIFT)
|
||||||
|
# define BQ2429XR5_WATCHDOG_160Sec (3 << BQ2429XR5_WATCHDOG_SHIFT)
|
||||||
|
|
||||||
|
#define BQ2429XR5_EN_TIMER (1 << 3) /* 0=Disable 1=Enable(default) */
|
||||||
|
/* Fast Charge Timer Settings */
|
||||||
|
#define BQ2429XR5_CHG_TIMER_SHIFT 1
|
||||||
|
#define BQ2429XR5_CHG_TIMER_MASK (3 << BQ2429XR5_CHG_TIMER_SHIFT)
|
||||||
|
# define BQ2429XR5_CHG_TIMER_05hrs (0 << BQ2429XR5_CHG_TIMER_SHIFT)
|
||||||
|
# define BQ2429XR5_CHG_TIMER_08hrs (1 << BQ2429XR5_CHG_TIMER_SHIFT)
|
||||||
|
# define BQ2429XR5_CHG_TIMER_12hrs (2 << BQ2429XR5_CHG_TIMER_SHIFT)
|
||||||
|
# define BQ2429XR5_CHG_TIMER_20hrs (3 << BQ2429XR5_CHG_TIMER_SHIFT)
|
||||||
|
#define BQ2429XR5_RESERVED0 (1 << 0)
|
||||||
|
|
||||||
|
/* REG06 Boost Voltage/Thermal Regulation Control register */
|
||||||
|
|
||||||
|
#define BQ2429XR6_BOOSTV_SHIFT 4 /* Offset 4.55V Range 4.55-5.51A Dev 4.998V(0111) */
|
||||||
|
#define BQ2429XR6_BOOSTV_MASK (0xf << BQ2429XR6_BOOSTV_SHIFT)
|
||||||
|
# define BQ2429XR6_BOOSTV_064mV (1 << BQ2429XR6_BOOSTV_SHIFT)
|
||||||
|
# define BQ2429XR6_BOOSTV_128mV (2 << BQ2429XR6_BOOSTV_SHIFT)
|
||||||
|
# define BQ2429XR6_BOOSTV_256mV (4 << BQ2429XR6_BOOSTV_SHIFT)
|
||||||
|
# define BQ2429XR6_BOOSTV_512mV (8 << BQ2429XR6_BOOSTV_SHIFT)
|
||||||
|
#define BQ2429XR6_BHOT_SHIFT 2 /* Boost Mode temp threshold */
|
||||||
|
#define BQ2429XR6_BHOT_MASK (3 << BQ2429XR6_BHOT_SHIFT)
|
||||||
|
# define BQ2429XR6_BHOT_55C (0 << BQ2429XR6_BHOT_SHIFT)
|
||||||
|
# define BQ2429XR6_BHOT_60C (1 << BQ2429XR6_BHOT_SHIFT)
|
||||||
|
# define BQ2429XR6_BHOT_65C (2 << BQ2429XR6_BHOT_SHIFT)
|
||||||
|
# define BQ2429XR6_BHOT_DISABLE (3 << BQ2429XR6_BHOT_SHIFT)
|
||||||
|
#define BQ2429XR6_TREG_SHIFT 0 /* Thermal Regulation */
|
||||||
|
#define BQ2429XR6_TREG_MASK (3 << BQ2429XR6_TREG_SHIFT)
|
||||||
|
# define BQ2429XR6_TREG_060C (0 << BQ2429XR6_TREG_SHIFT)
|
||||||
|
# define BQ2429XR6_TREG_080C (1 << BQ2429XR6_TREG_SHIFT)
|
||||||
|
# define BQ2429XR6_TREG_100C (2 << BQ2429XR6_TREG_SHIFT)
|
||||||
|
# define BQ2429XR6_TREG_110C (3 << BQ2429XR6_TREG_SHIFT)
|
||||||
|
|
||||||
|
/* REG07 Misc Operation Control Register */
|
||||||
|
|
||||||
|
#define BQ2429XR7_DPDM_EN (1 << 7) /* 1=Force Detection when VBUS power is present */
|
||||||
|
#define BQ2429XR7_TMR2X_EN (1 << 6) /* 1=Safety Timer slowed by 2X during DPM/Thermal regulation */
|
||||||
|
#define BQ2429XR7_BATFET_DISABLE (1 << 5) /* 1=BATFET (Q4) turn off */
|
||||||
|
#define BQ2429XR7_RESERVED4 (1 << 4)
|
||||||
|
#define BQ2429XR7_RESERVED3 (1 << 3)
|
||||||
|
#define BQ2429XR7_RESERVED2 (1 << 2)
|
||||||
|
#define BQ2429XR7_INT_MASK1 (1 << 1) /* =1 (default) INT on CHRG_FAULT */
|
||||||
|
#define BQ2429XR7_INT_MASK0 (1 << 0) /* =1 (default) INT on BAT_FAULT */
|
||||||
|
|
||||||
|
/* REG08 Systems Status Register */
|
||||||
|
|
||||||
|
#define BQ2429XR8_VBUS_STAT_SHIFT 6 /* VBUS Connection Type */
|
||||||
|
#define BQ2429XR8_VBUS_STAT_MASK (3 << BQ2429XR8_VBUS_STAT_SHIFT)
|
||||||
|
# define BQ2429XR8_VBUS_STAT_UNKNOWN (0 << BQ2429XR8_VBUS_STAT_SHIFT)
|
||||||
|
# define BQ2429XR8_VBUS_STAT_USBH (1 << BQ2429XR8_VBUS_STAT_SHIFT)
|
||||||
|
# define BQ2429XR8_VBUS_STAT_ADAPTER (2 << BQ2429XR8_VBUS_STAT_SHIFT)
|
||||||
|
# define BQ2429XR8_VBUS_STAT_OTG (3 << BQ2429XR8_VBUS_STAT_SHIFT)
|
||||||
|
#define BQ2429XR8_CHRG_STAT_SHIFT 4 /* Charging Status */
|
||||||
|
#define BQ2429XR8_CHRG_STAT_MASK (3 << BQ2429XR8_CHRG_STAT_SHIFT)
|
||||||
|
# define BQ2429XR8_CHRG_STAT_NONE (0 << BQ2429XR8_CHRG_STAT_SHIFT)
|
||||||
|
# define BQ2429XR8_CHRG_STAT_PRECHG (1 << BQ2429XR8_CHRG_STAT_SHIFT)
|
||||||
|
# define BQ2429XR8_CHRG_STAT_FASTCHG (2 << BQ2429XR8_CHRG_STAT_SHIFT)
|
||||||
|
# define BQ2429XR8_CHRG_STAT_DONE (3 << BQ2429XR8_CHRG_STAT_SHIFT)
|
||||||
|
#define BQ2429XR8_DPM_STAT (1 << 3) /* 0= NotDPM 1=VINDPM or INDPM */
|
||||||
|
#define BQ2429XR8_PG_STAT (1 << 2) /* 0= Not 1=Power Good */
|
||||||
|
#define BQ2429XR8_THERM_STAT (1 << 1) /* 0= Normal 1=In Thermal Regulation */
|
||||||
|
#define BQ2429XR8_VSYS_STAT (1 << 0) /* 0= Not 1=In VSYSMIN regulation BAT < VSYSMIN */
|
||||||
|
|
||||||
|
/* REG09 New Fault Register */
|
||||||
|
|
||||||
|
#define BQ2429XR9_WATCHDOG_FAULT (1 << 7) /* 1=Watchdog Timer expired */
|
||||||
|
#define BQ2429XR9_OTG_FAULT (1 << 6) /* 1=Bus overloaded in OTG, or VBUS OVP or battery low */
|
||||||
|
#define BQ2429XR9_CHRG_FAULT_SHIFT 4 /* Charging Status */
|
||||||
|
#define BQ2429XR9_CHRG_FAULT_MASK (3 << BQ2429XR9_CHRG_FAULT_SHIFT)
|
||||||
|
# define BQ2429XR9_CHRG_FAULT_NORMAL (0 << BQ2429XR9_CHRG_FAULT_SHIFT)
|
||||||
|
# define BQ2429XR9_CHRG_FAULT_INPUT (1 << BQ2429XR9_CHRG_FAULT_SHIFT)
|
||||||
|
# define BQ2429XR9_CHRG_FAULT_THERMAL (2 << BQ2429XR9_CHRG_FAULT_SHIFT)
|
||||||
|
# define BQ2429XR9_CHRG_FAULT_TIMER (3 << BQ2429XR9_CHRG_FAULT_SHIFT)
|
||||||
|
#define BQ2429XR9_BAT_FAULT (1 << 3) /* 1=Battery OVP */
|
||||||
|
#define BQ2429XR9_RESERVED2 (1 << 2)
|
||||||
|
|
||||||
|
#define BQ2429XR9_NTC_FAULT1_COLD (1 << 1) /* Cold temperature */
|
||||||
|
#define BQ2429XR9_NTC_FAULT2_HOT (1 << 0) /* Hot temperature */
|
||||||
|
|
||||||
|
/* REG0A Vendor Part Revision Info */
|
||||||
|
|
||||||
|
#define BQ24296_VENDOR_ID 0x20 /* BQ24296 */
|
||||||
|
#define BQ24296M_VENDOR_ID 0x20 /* BQ24296M */
|
||||||
|
#define BQ24297_VENDOR_ID 0x60 /* BQ24297 */
|
||||||
|
|
||||||
|
#endif /* __DRIVERS_POWER_BQ2429X_H */
|
@ -447,7 +447,6 @@ uint16_t devif_conn_event(FAR struct net_driver_s *dev, void *pvconn,
|
|||||||
* beginning of the list (which will be ignored on this pass)
|
* beginning of the list (which will be ignored on this pass)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ninfo("Call event=%p with flags=%04x\n", list->event, flags);
|
|
||||||
flags = list->event(dev, pvconn, list->priv, flags);
|
flags = list->event(dev, pvconn, list->priv, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -511,7 +510,6 @@ uint16_t devif_dev_event(FAR struct net_driver_s *dev, void *pvconn,
|
|||||||
* beginning of the list (which will be ignored on this pass)
|
* beginning of the list (which will be ignored on this pass)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ninfo("Call event=%p with flags=%04x\n", cb->event, flags);
|
|
||||||
flags = cb->event(dev, pvconn, cb->priv, flags);
|
flags = cb->event(dev, pvconn, cb->priv, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@
|
|||||||
|
|
||||||
void devif_send(struct net_driver_s *dev, const void *buf, int len)
|
void devif_send(struct net_driver_s *dev, const void *buf, int len)
|
||||||
{
|
{
|
||||||
DEBUGASSERT(dev && len > 0 && len < NET_DEV_MTU(dev));
|
DEBUGASSERT(dev != NULL && len > 0 && len < NET_DEV_MTU(dev));
|
||||||
|
|
||||||
memcpy(dev->d_appdata, buf, len);
|
memcpy(dev->d_appdata, buf, len);
|
||||||
dev->d_sndlen = len;
|
dev->d_sndlen = len;
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
|
|
||||||
#include <nuttx/clock.h>
|
#include <nuttx/clock.h>
|
||||||
#include <nuttx/semaphore.h>
|
#include <nuttx/semaphore.h>
|
||||||
|
#include <nuttx/mm/iob.h>
|
||||||
#include <nuttx/net/net.h>
|
#include <nuttx/net/net.h>
|
||||||
#include <nuttx/net/radiodev.h>
|
#include <nuttx/net/radiodev.h>
|
||||||
#include <netpacket/ieee802154.h>
|
#include <netpacket/ieee802154.h>
|
||||||
|
@ -64,7 +64,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_NET_TCP)
|
#if defined(CONFIG_NET_TCP)
|
||||||
# define L3_MAXHDRLEN TCP_MAX_HDRLEN
|
# define L3_MAXHDRLEN TCP_HDRLEN /* Could be up to TCP_MAX_HDRLEN */
|
||||||
#elif defined(CONFIG_NET_UDP)
|
#elif defined(CONFIG_NET_UDP)
|
||||||
# define L3_MAXHDRLEN UDP_HDRLEN
|
# define L3_MAXHDRLEN UDP_HDRLEN
|
||||||
#elif defined(CONFIG_NET_ICMPv6)
|
#elif defined(CONFIG_NET_ICMPv6)
|
||||||
|
@ -12,6 +12,40 @@ config NET_6LOWPAN_FRAG
|
|||||||
CONFIG_NET_6LOWPAN_FRAG specifies if 6lowpan fragmentation should be
|
CONFIG_NET_6LOWPAN_FRAG specifies if 6lowpan fragmentation should be
|
||||||
used or not. Fragmentation is on by default.
|
used or not. Fragmentation is on by default.
|
||||||
|
|
||||||
|
config NET_6LOWPAN_NREASSBUF
|
||||||
|
int "Number of preallocated reassembly buffers"
|
||||||
|
default 2
|
||||||
|
depends on NET_6LOWPAN_FRAG
|
||||||
|
---help---
|
||||||
|
Large IPv6 packets will be fragmented by 6LoWPAN into multiple
|
||||||
|
frames and reconstitued into a reassembly buffer on the receiving
|
||||||
|
side. Each concurrent reassembly requires one buffer. Reassembly
|
||||||
|
buffers are large: The size of the 6LoWPAN MTU plus some overhead
|
||||||
|
for the reassembly state.
|
||||||
|
|
||||||
|
Some reassembly buffers may be preallocated; some may be allocated
|
||||||
|
dynamically from the stack. The former require more static memory
|
||||||
|
usage; the later require additional CPU cycles to perform the
|
||||||
|
allocation and may effect deterministic behavior. So this is a
|
||||||
|
trade-off between resources and performance. If the number of pre-
|
||||||
|
allocated reassembly buffers are exhausted, the reassembly will
|
||||||
|
continue with dynamically allocated reassembly buffers.
|
||||||
|
|
||||||
|
This behavior can be changed with CONFIG_NET_6LOWPAN_REASS_STATIC
|
||||||
|
|
||||||
|
config NET_6LOWPAN_REASS_STATIC
|
||||||
|
bool "Static reassembly buffers"
|
||||||
|
default n
|
||||||
|
depends on NET_6LOWPAN_FRAG
|
||||||
|
---help---
|
||||||
|
By default, reassembly buffers may be allocated dynamically from the
|
||||||
|
stack when all of the statically allocation reassembly buffers are
|
||||||
|
in use. This will equire additional CPU cycles to perform the
|
||||||
|
allocation and may effect deterministic behavior. This option may
|
||||||
|
be selected to suppress all dynamica allocation of reassembly
|
||||||
|
buffers. In that case, only static reassembly buffers are available;
|
||||||
|
when those are exhausted, frames that require reassembly will be lost.
|
||||||
|
|
||||||
config NET_6LOWPAN_FRAMELEN
|
config NET_6LOWPAN_FRAMELEN
|
||||||
int "Max Radio Frame Size"
|
int "Max Radio Frame Size"
|
||||||
default 127
|
default 127
|
||||||
|
@ -68,6 +68,10 @@ ifeq ($(CONFIG_NET_6LOWPAN_COMPRESSION_HC06),y)
|
|||||||
NET_CSRCS += sixlowpan_hc06.c
|
NET_CSRCS += sixlowpan_hc06.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_NET_6LOWPAN_FRAG),y)
|
||||||
|
NET_CSRCS += sixlowpan_reassbuf.c
|
||||||
|
endif
|
||||||
|
|
||||||
# Include the sixlowpan directory in the build
|
# Include the sixlowpan directory in the build
|
||||||
|
|
||||||
DEPPATH += --dep-path sixlowpan
|
DEPPATH += --dep-path sixlowpan
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/mm/iob.h>
|
||||||
#include <nuttx/net/netdev.h>
|
#include <nuttx/net/netdev.h>
|
||||||
#include <nuttx/net/radiodev.h>
|
#include <nuttx/net/radiodev.h>
|
||||||
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
|
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
|
||||||
@ -384,9 +385,9 @@ int sixlowpan_queue_frames(FAR struct radio_driver_s *radio,
|
|||||||
FAR uint8_t *fptr;
|
FAR uint8_t *fptr;
|
||||||
int framer_hdrlen;
|
int framer_hdrlen;
|
||||||
struct netdev_varaddr_s bcastmac;
|
struct netdev_varaddr_s bcastmac;
|
||||||
|
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
||||||
uint16_t pktlen;
|
uint16_t pktlen;
|
||||||
uint16_t paysize;
|
uint16_t paysize;
|
||||||
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
|
||||||
uint16_t outlen = 0;
|
uint16_t outlen = 0;
|
||||||
#endif
|
#endif
|
||||||
uint8_t protosize;
|
uint8_t protosize;
|
||||||
@ -505,12 +506,18 @@ int sixlowpan_queue_frames(FAR struct radio_driver_s *radio,
|
|||||||
* added at qtail.
|
* added at qtail.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
FAR struct sixlowpan_reassbuf_s *reass;
|
||||||
FAR struct iob_s *qhead;
|
FAR struct iob_s *qhead;
|
||||||
FAR struct iob_s *qtail;
|
FAR struct iob_s *qtail;
|
||||||
FAR uint8_t *frame1;
|
FAR uint8_t *frame1;
|
||||||
FAR uint8_t *fragptr;
|
FAR uint8_t *fragptr;
|
||||||
uint16_t frag1_hdrlen;
|
uint16_t frag1_hdrlen;
|
||||||
|
|
||||||
|
/* Recover the reassembly buffer from the driver d_buf. */
|
||||||
|
|
||||||
|
reass = (FAR struct sixlowpan_reassbuf_s *)radio->r_dev.d_buf;
|
||||||
|
DEBUGASSERT(reass != NULL);
|
||||||
|
|
||||||
/* The outbound IPv6 packet is too large to fit into a single 15.4
|
/* The outbound IPv6 packet is too large to fit into a single 15.4
|
||||||
* packet, so we fragment it into multiple packets and send them.
|
* packet, so we fragment it into multiple packets and send them.
|
||||||
* The first fragment contains frag1 dispatch, then
|
* The first fragment contains frag1 dispatch, then
|
||||||
@ -548,7 +555,7 @@ int sixlowpan_queue_frames(FAR struct radio_driver_s *radio,
|
|||||||
pktlen = buflen + g_uncomp_hdrlen + protosize;
|
pktlen = buflen + g_uncomp_hdrlen + protosize;
|
||||||
PUTHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE,
|
PUTHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE,
|
||||||
((SIXLOWPAN_DISPATCH_FRAG1 << 8) | pktlen));
|
((SIXLOWPAN_DISPATCH_FRAG1 << 8) | pktlen));
|
||||||
PUTHOST16(fragptr, SIXLOWPAN_FRAG_TAG, radio->r_dgramtag);
|
PUTHOST16(fragptr, SIXLOWPAN_FRAG_TAG, reass->rb_dgramtag);
|
||||||
|
|
||||||
g_frame_hdrlen += SIXLOWPAN_FRAG1_HDR_LEN;
|
g_frame_hdrlen += SIXLOWPAN_FRAG1_HDR_LEN;
|
||||||
|
|
||||||
@ -575,7 +582,7 @@ int sixlowpan_queue_frames(FAR struct radio_driver_s *radio,
|
|||||||
outlen = paysize;
|
outlen = paysize;
|
||||||
|
|
||||||
ninfo("First fragment: length %d, tag %d\n",
|
ninfo("First fragment: length %d, tag %d\n",
|
||||||
paysize, radio->r_dgramtag);
|
paysize, reass->rb_dgramtag);
|
||||||
sixlowpan_dumpbuffer("Outgoing frame",
|
sixlowpan_dumpbuffer("Outgoing frame",
|
||||||
(FAR const uint8_t *)iob->io_data, iob->io_len);
|
(FAR const uint8_t *)iob->io_data, iob->io_len);
|
||||||
|
|
||||||
@ -630,7 +637,7 @@ int sixlowpan_queue_frames(FAR struct radio_driver_s *radio,
|
|||||||
|
|
||||||
PUTHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE,
|
PUTHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE,
|
||||||
((SIXLOWPAN_DISPATCH_FRAGN << 8) | pktlen));
|
((SIXLOWPAN_DISPATCH_FRAGN << 8) | pktlen));
|
||||||
PUTHOST16(fragptr, SIXLOWPAN_FRAG_TAG, radio->r_dgramtag);
|
PUTHOST16(fragptr, SIXLOWPAN_FRAG_TAG, reass->rb_dgramtag);
|
||||||
fragptr[SIXLOWPAN_FRAG_OFFSET] = outlen >> 3;
|
fragptr[SIXLOWPAN_FRAG_OFFSET] = outlen >> 3;
|
||||||
|
|
||||||
fragn_hdrlen += SIXLOWPAN_FRAGN_HDR_LEN;
|
fragn_hdrlen += SIXLOWPAN_FRAGN_HDR_LEN;
|
||||||
@ -654,8 +661,8 @@ int sixlowpan_queue_frames(FAR struct radio_driver_s *radio,
|
|||||||
iob->io_len = paysize + fragn_hdrlen;
|
iob->io_len = paysize + fragn_hdrlen;
|
||||||
outlen += paysize;
|
outlen += paysize;
|
||||||
|
|
||||||
ninfo("Fragment offset=%d, paysize=%d, r_dgramtag=%d\n",
|
ninfo("Fragment offset=%d, paysize=%d, rb_dgramtag=%d\n",
|
||||||
outlen >> 3, paysize, radio->r_dgramtag);
|
outlen >> 3, paysize, reass->rb_dgramtag);
|
||||||
sixlowpan_dumpbuffer("Outgoing frame",
|
sixlowpan_dumpbuffer("Outgoing frame",
|
||||||
(FAR const uint8_t *)iob->io_data,
|
(FAR const uint8_t *)iob->io_data,
|
||||||
iob->io_len);
|
iob->io_len);
|
||||||
@ -697,7 +704,7 @@ int sixlowpan_queue_frames(FAR struct radio_driver_s *radio,
|
|||||||
|
|
||||||
/* Update the datagram TAG value */
|
/* Update the datagram TAG value */
|
||||||
|
|
||||||
radio->r_dgramtag++;
|
reass->rb_dgramtag++;
|
||||||
#else
|
#else
|
||||||
nerr("ERROR: Packet too large: %d\n", buflen);
|
nerr("ERROR: Packet too large: %d\n", buflen);
|
||||||
nerr(" Cannot to be sent without fragmentation support\n");
|
nerr(" Cannot to be sent without fragmentation support\n");
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/mm/iob.h>
|
||||||
#include <nuttx/net/netdev.h>
|
#include <nuttx/net/netdev.h>
|
||||||
#include <nuttx/net/radiodev.h>
|
#include <nuttx/net/radiodev.h>
|
||||||
#include <nuttx/net/ip.h>
|
#include <nuttx/net/ip.h>
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/mm/iob.h>
|
||||||
#include <nuttx/net/netdev.h>
|
#include <nuttx/net/netdev.h>
|
||||||
#include <nuttx/net/radiodev.h>
|
#include <nuttx/net/radiodev.h>
|
||||||
#include "sixlowpan/sixlowpan_internal.h"
|
#include "sixlowpan/sixlowpan_internal.h"
|
||||||
|
@ -69,6 +69,12 @@
|
|||||||
|
|
||||||
void sixlowpan_initialize(void)
|
void sixlowpan_initialize(void)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
||||||
|
/* Initialize the reassembly buffer allocator */
|
||||||
|
|
||||||
|
sixlowpan_reass_initialize();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
|
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
|
||||||
/* Initialize HC06 data data structures */
|
/* Initialize HC06 data data structures */
|
||||||
|
|
||||||
|
@ -54,10 +54,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
#include "nuttx/mm/iob.h"
|
||||||
# include "nuttx/clock.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "nuttx/net/netdev.h"
|
#include "nuttx/net/netdev.h"
|
||||||
#include "nuttx/net/radiodev.h"
|
#include "nuttx/net/radiodev.h"
|
||||||
#include "nuttx/net/ip.h"
|
#include "nuttx/net/ip.h"
|
||||||
@ -82,10 +79,6 @@
|
|||||||
#define INPUT_PARTIAL 0 /* Frame processed successful, packet incomplete */
|
#define INPUT_PARTIAL 0 /* Frame processed successful, packet incomplete */
|
||||||
#define INPUT_COMPLETE 1 /* Frame processed successful, packet complete */
|
#define INPUT_COMPLETE 1 /* Frame processed successful, packet complete */
|
||||||
|
|
||||||
/* Re-assembly timeout in clock ticks */
|
|
||||||
|
|
||||||
#define NET_6LOWPAN_TIMEOUT SEC2TICK(CONFIG_NET_6LOWPAN_MAXAGE)
|
|
||||||
|
|
||||||
/* This is the size of a buffer large enough to hold the largest uncompressed
|
/* This is the size of a buffer large enough to hold the largest uncompressed
|
||||||
* HC06 or HC1 headers.
|
* HC06 or HC1 headers.
|
||||||
*/
|
*/
|
||||||
@ -132,50 +125,6 @@ static uint8_t g_bitbucket[UNCOMP_MAXHDR];
|
|||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: sixlowpan_compare_fragsrc
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Check if the fragment that we just received is from the same source as
|
|
||||||
* the previosly received fragements.
|
|
||||||
*
|
|
||||||
* Input Parameters:
|
|
||||||
* radio - Radio network device driver state instance
|
|
||||||
* metadata - Characteristics of the newly received frame
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* true if the sources are the same.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static bool sixlowpan_compare_fragsrc(FAR struct radio_driver_s *radio,
|
|
||||||
FAR const void *metadata)
|
|
||||||
{
|
|
||||||
struct netdev_varaddr_s fragsrc;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* Extract the source address from the 'metadata' */
|
|
||||||
|
|
||||||
ret = sixlowpan_extract_srcaddr(radio, metadata, &fragsrc);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
nerr("ERROR: sixlowpan_extract_srcaddr failed: %d\n", ret);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The addresses cannot match if they are not the same size */
|
|
||||||
|
|
||||||
if (fragsrc.nv_addrlen == radio->r_fragsrc.nv_addrlen)
|
|
||||||
{
|
|
||||||
/* The are the same sizer, return the address comparisson */
|
|
||||||
|
|
||||||
return (memcmp(fragsrc.nv_addr, radio->r_fragsrc.nv_addr,
|
|
||||||
fragsrc.nv_addrlen) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: sixlowpan_compress_ipv6hdr
|
* Name: sixlowpan_compress_ipv6hdr
|
||||||
*
|
*
|
||||||
@ -311,14 +260,15 @@ static int sixlowpan_frame_process(FAR struct radio_driver_s *radio,
|
|||||||
uint8_t fragoffset = 0; /* Offset of the fragment in the IP packet */
|
uint8_t fragoffset = 0; /* Offset of the fragment in the IP packet */
|
||||||
int reqsize; /* Required buffer size */
|
int reqsize; /* Required buffer size */
|
||||||
int hdrsize; /* Size of the IEEE802.15.4 header */
|
int hdrsize; /* Size of the IEEE802.15.4 header */
|
||||||
|
int ret;
|
||||||
|
|
||||||
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
||||||
|
FAR struct sixlowpan_reassbuf_s *reass;
|
||||||
|
struct netdev_varaddr_s fragsrc;
|
||||||
FAR uint8_t *fragptr; /* Pointer to the fragmentation header */
|
FAR uint8_t *fragptr; /* Pointer to the fragmentation header */
|
||||||
bool isfrag = false;
|
bool isfrag = false;
|
||||||
bool isfirstfrag = false;
|
bool isfirstfrag = false;
|
||||||
uint16_t fragtag = 0; /* Tag of the fragment */
|
uint16_t fragtag = 0; /* Tag of the fragment */
|
||||||
systime_t elapsed; /* Elapsed time */
|
|
||||||
int ret;
|
|
||||||
#endif /* CONFIG_NET_6LOWPAN_FRAG */
|
#endif /* CONFIG_NET_6LOWPAN_FRAG */
|
||||||
|
|
||||||
/* Get a pointer to the payload following the IEEE802.15.4 frame header(s).
|
/* Get a pointer to the payload following the IEEE802.15.4 frame header(s).
|
||||||
@ -359,166 +309,119 @@ static int sixlowpan_frame_process(FAR struct radio_driver_s *radio,
|
|||||||
ninfo("FRAG1: fragsize=%d fragtag=%d fragoffset=%d\n",
|
ninfo("FRAG1: fragsize=%d fragtag=%d fragoffset=%d\n",
|
||||||
fragsize, fragtag, fragoffset);
|
fragsize, fragtag, fragoffset);
|
||||||
|
|
||||||
|
/* Drop any zero length fragments */
|
||||||
|
|
||||||
|
if (fragsize == 0)
|
||||||
|
{
|
||||||
|
nwarn("WARNING: Dropping zero-length 6LoWPAN fragment\n");
|
||||||
|
return INPUT_PARTIAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Drop the packet if it cannot fit into the d_buf */
|
||||||
|
|
||||||
|
if (fragsize > CONFIG_NET_6LOWPAN_MTU)
|
||||||
|
{
|
||||||
|
nwarn("WARNING: Reassembled packet size exeeds CONFIG_NET_6LOWPAN_MTU\n");
|
||||||
|
return -ENOSPC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extract the source address from the 'metadata'. */
|
||||||
|
|
||||||
|
ret = sixlowpan_extract_srcaddr(radio, metadata, &fragsrc);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
nerr("ERROR: sixlowpan_extract_srcaddr failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate a new reassembly buffer */
|
||||||
|
|
||||||
|
reass = sixlowpan_reass_allocate(fragtag, &fragsrc);
|
||||||
|
if (reass == NULL)
|
||||||
|
{
|
||||||
|
nerr("ERROR: Failed to allocate a reassembly buffer\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio->r_dev.d_buf = reass->rb_buf;
|
||||||
|
radio->r_dev.d_len = 0;
|
||||||
|
reass->rb_pktlen = fragsize;
|
||||||
|
|
||||||
/* Indicate the first fragment of the reassembly */
|
/* Indicate the first fragment of the reassembly */
|
||||||
|
|
||||||
isfirstfrag = true;
|
bptr = reass->rb_buf;
|
||||||
isfrag = true;
|
isfirstfrag = true;
|
||||||
|
isfrag = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIXLOWPAN_DISPATCH_FRAGN:
|
case SIXLOWPAN_DISPATCH_FRAGN:
|
||||||
{
|
{
|
||||||
/* Set offset, tag, size. Offset is in units of 8 bytes. */
|
/* Get offset, tag, size. Offset is in units of 8 bytes. */
|
||||||
|
|
||||||
fragoffset = fragptr[SIXLOWPAN_FRAG_OFFSET];
|
fragoffset = fragptr[SIXLOWPAN_FRAG_OFFSET];
|
||||||
fragtag = GETUINT16(fragptr, SIXLOWPAN_FRAG_TAG);
|
fragtag = GETUINT16(fragptr, SIXLOWPAN_FRAG_TAG);
|
||||||
fragsize = GETUINT16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE) & 0x07ff;
|
fragsize = GETUINT16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE) & 0x07ff;
|
||||||
g_frame_hdrlen += SIXLOWPAN_FRAGN_HDR_LEN;
|
g_frame_hdrlen += SIXLOWPAN_FRAGN_HDR_LEN;
|
||||||
|
|
||||||
|
/* Extract the source address from the 'metadata'. */
|
||||||
|
|
||||||
|
ret = sixlowpan_extract_srcaddr(radio, metadata, &fragsrc);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
nerr("ERROR: sixlowpan_extract_srcaddr failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the existing reassembly buffer with the same tag and source address */
|
||||||
|
|
||||||
|
reass = sixlowpan_reass_find(fragtag, &fragsrc);
|
||||||
|
if (reass == NULL)
|
||||||
|
{
|
||||||
|
nerr("ERROR: Failed to find a reassembly buffer for tag=%04x\n",
|
||||||
|
fragtag);
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fragsize != reass->rb_pktlen)
|
||||||
|
{
|
||||||
|
/* The packet is a fragment but its size does not match. */
|
||||||
|
|
||||||
|
nwarn("WARNING: Dropping 6LoWPAN packet. Bad fragsize: %u vs &u\n",
|
||||||
|
fragsize, reass->rb_pktlen);
|
||||||
|
ret = -EPERM;
|
||||||
|
goto errout_with_reass;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio->r_dev.d_buf = reass->rb_buf;
|
||||||
|
radio->r_dev.d_len = 0;
|
||||||
|
|
||||||
ninfo("FRAGN: fragsize=%d fragtag=%d fragoffset=%d\n",
|
ninfo("FRAGN: fragsize=%d fragtag=%d fragoffset=%d\n",
|
||||||
fragsize, fragtag, fragoffset);
|
fragsize, fragtag, fragoffset);
|
||||||
ninfo("FRAGN: r_accumlen=%d paysize=%u fragsize=%u\n",
|
ninfo("FRAGN: rb_accumlen=%d paysize=%u fragsize=%u\n",
|
||||||
radio->r_accumlen, iob->io_len - g_frame_hdrlen, fragsize);
|
reass->rb_accumlen, iob->io_len - g_frame_hdrlen, fragsize);
|
||||||
|
|
||||||
/* Indicate that this frame is a another fragment for reassembly */
|
/* Indicate that this frame is a another fragment for reassembly */
|
||||||
|
|
||||||
isfrag = true;
|
bptr = g_bitbucket;
|
||||||
|
isfrag = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Not a fragment */
|
/* Not a fragment */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
/* We still need a packet buffer. But in this case, the driver should
|
||||||
|
* have provided one.
|
||||||
|
*/
|
||||||
|
|
||||||
|
DEBUGASSERT(radio->r_dev.d_buf != NULL);
|
||||||
|
reass = (FAR struct sixlowpan_reassbuf_s *)radio->r_dev.d_buf;
|
||||||
|
bptr = reass->rb_buf;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
/* Check if we are currently reassembling a packet */
|
bptr = radio->r_dev.d_buf;
|
||||||
|
|
||||||
bptr = radio->r_dev.d_buf;
|
|
||||||
if (radio->r_accumlen > 0)
|
|
||||||
{
|
|
||||||
/* If reassembly timed out, cancel it */
|
|
||||||
|
|
||||||
elapsed = clock_systimer() - radio->r_time;
|
|
||||||
if (elapsed > NET_6LOWPAN_TIMEOUT)
|
|
||||||
{
|
|
||||||
nwarn("WARNING: Reassembly timed out\n");
|
|
||||||
radio->r_pktlen = 0;
|
|
||||||
radio->r_accumlen = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* In this case what we expect is that the next frame will hold the
|
|
||||||
* next FRAGN of the sequence. We have to handle a few exeptional
|
|
||||||
* cases that we need to handle:
|
|
||||||
*
|
|
||||||
* 1. If we are currently reassembling a packet, but have just received
|
|
||||||
* the first fragment of another packet. We can either ignore it and
|
|
||||||
* hope to receive the rest of the under-reassembly packet fragments,
|
|
||||||
* or we can discard the previous packet altogether, and start
|
|
||||||
* reassembling the new packet. Here we discard the previous packet,
|
|
||||||
* and start reassembling the new packet.
|
|
||||||
* 2. The new frame is not a fragment. We should be able to handle this
|
|
||||||
* case, but we cannot because that would require two packet buffers.
|
|
||||||
* It could be handled with a more extensive design.
|
|
||||||
* 3. The fragment came from a different sender. What would this mean?
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
else if (!isfrag)
|
|
||||||
{
|
|
||||||
/* Discard the partially assembled packet */
|
|
||||||
|
|
||||||
nwarn("WARNING: Non-fragment frame received during reassembly\n");
|
|
||||||
radio->r_pktlen = 0;
|
|
||||||
radio->r_accumlen = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* It is a fragment of some kind. Drop any zero length fragments */
|
|
||||||
|
|
||||||
else if (fragsize == 0)
|
|
||||||
{
|
|
||||||
nwarn("WARNING: Dropping zero-length 6LoWPAN fragment\n");
|
|
||||||
return INPUT_PARTIAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* A non-zero, first fragement received while we are in the middle of
|
|
||||||
* rassembly. Discard the partially assembled packet and start over.
|
|
||||||
*/
|
|
||||||
|
|
||||||
else if (isfirstfrag)
|
|
||||||
{
|
|
||||||
nwarn("WARNING: First fragment frame received during reassembly\n");
|
|
||||||
radio->r_pktlen = 0;
|
|
||||||
radio->r_accumlen = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Verify that this fragment is part of that reassembly sequence */
|
|
||||||
|
|
||||||
else if (fragsize != radio->r_pktlen || radio->r_reasstag != fragtag ||
|
|
||||||
!sixlowpan_compare_fragsrc(radio, metadata))
|
|
||||||
{
|
|
||||||
/* The packet is a fragment that does not belong to the packet
|
|
||||||
* being reassembled or the packet is not a fragment.
|
|
||||||
*/
|
|
||||||
|
|
||||||
nwarn("WARNING: Dropping 6LoWPAN packet that is not a fragment of "
|
|
||||||
"the packet currently being reassembled\n");
|
|
||||||
return -EPERM;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Looks good. We are currently processing a reassembling sequence
|
|
||||||
* and we recieved a valid FRAGN fragment. Redirect the header
|
|
||||||
* uncompression to our bitbucket.
|
|
||||||
*/
|
|
||||||
|
|
||||||
bptr = g_bitbucket;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* There is no reassembly in progress. Check if we received a fragment */
|
|
||||||
|
|
||||||
else if (isfrag)
|
|
||||||
{
|
|
||||||
/* Another case that we have to handle is if a FRAGN fragment of a
|
|
||||||
* reassembly is received, but we are not currently reassembling a
|
|
||||||
* packet. I think we have no choice but to drop the packet in this
|
|
||||||
* case.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!isfirstfrag)
|
|
||||||
{
|
|
||||||
nwarn("WARNING: FRAGN 6LoWPAN fragment while not reassembling\n");
|
|
||||||
return -EPERM;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Drop the packet if it cannot fit into the d_buf */
|
|
||||||
|
|
||||||
if (fragsize > CONFIG_NET_6LOWPAN_MTU)
|
|
||||||
{
|
|
||||||
nwarn("WARNING: Reassembled packet size exeeds CONFIG_NET_6LOWPAN_MTU\n");
|
|
||||||
return -ENOSPC;
|
|
||||||
}
|
|
||||||
|
|
||||||
radio->r_pktlen = fragsize;
|
|
||||||
radio->r_reasstag = fragtag;
|
|
||||||
radio->r_time = clock_systimer();
|
|
||||||
|
|
||||||
ninfo("Starting reassembly: r_pktlen %u, r_reasstag %d\n",
|
|
||||||
radio->r_pktlen, radio->r_reasstag);
|
|
||||||
|
|
||||||
/* Extract the source address from the 'metadata'. NOTE that the size
|
|
||||||
* of the source address may be different than our local, destination
|
|
||||||
* address.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ret = sixlowpan_extract_srcaddr(radio, metadata, &radio->r_fragsrc);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
nerr("ERROR: sixlowpan_extract_srcaddr failed: %d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_NET_6LOWPAN_FRAG */
|
#endif /* CONFIG_NET_6LOWPAN_FRAG */
|
||||||
|
|
||||||
/* Process next dispatch and headers */
|
/* Process next dispatch and headers */
|
||||||
@ -553,7 +456,8 @@ static int sixlowpan_frame_process(FAR struct radio_driver_s *radio,
|
|||||||
/* Unknown or unsupported header */
|
/* Unknown or unsupported header */
|
||||||
|
|
||||||
nwarn("WARNING: Unknown dispatch: %u\n", hc1[SIXLOWPAN_HC1_DISPATCH]);
|
nwarn("WARNING: Unknown dispatch: %u\n", hc1[SIXLOWPAN_HC1_DISPATCH]);
|
||||||
return -ENOSYS;
|
ret = -ENOSYS;
|
||||||
|
goto errout_with_reass;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
||||||
@ -565,7 +469,7 @@ static int sixlowpan_frame_process(FAR struct radio_driver_s *radio,
|
|||||||
* begin placing the data payload.
|
* begin placing the data payload.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
radio->r_boffset = g_uncomp_hdrlen;
|
reass->rb_boffset = g_uncomp_hdrlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No.. is this a subsequent fragment in the same sequence? */
|
/* No.. is this a subsequent fragment in the same sequence? */
|
||||||
@ -576,7 +480,7 @@ static int sixlowpan_frame_process(FAR struct radio_driver_s *radio,
|
|||||||
* we began placing payload data.
|
* we began placing payload data.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g_uncomp_hdrlen = radio->r_boffset;
|
g_uncomp_hdrlen = reass->rb_boffset;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_6LOWPAN_FRAG */
|
#endif /* CONFIG_NET_6LOWPAN_FRAG */
|
||||||
|
|
||||||
@ -591,7 +495,8 @@ static int sixlowpan_frame_process(FAR struct radio_driver_s *radio,
|
|||||||
{
|
{
|
||||||
nwarn("WARNING: Packet dropped due to payload (%u) > packet buffer (%u)\n",
|
nwarn("WARNING: Packet dropped due to payload (%u) > packet buffer (%u)\n",
|
||||||
paysize, CONFIG_NET_6LOWPAN_MTU);
|
paysize, CONFIG_NET_6LOWPAN_MTU);
|
||||||
return -ENOSPC;
|
ret = -ENOSPC;
|
||||||
|
goto errout_with_reass;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sanity-check size of incoming packet to avoid buffer overflow */
|
/* Sanity-check size of incoming packet to avoid buffer overflow */
|
||||||
@ -602,14 +507,15 @@ static int sixlowpan_frame_process(FAR struct radio_driver_s *radio,
|
|||||||
nwarn("WARNING: Required buffer size: %u+%u+%u=%u Available=%u\n",
|
nwarn("WARNING: Required buffer size: %u+%u+%u=%u Available=%u\n",
|
||||||
g_uncomp_hdrlen, (fragoffset << 3), paysize,
|
g_uncomp_hdrlen, (fragoffset << 3), paysize,
|
||||||
reqsize, CONFIG_NET_6LOWPAN_MTU);
|
reqsize, CONFIG_NET_6LOWPAN_MTU);
|
||||||
return -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
goto errout_with_reass;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(radio->r_dev.d_buf + g_uncomp_hdrlen + (fragoffset << 3),
|
memcpy(radio->r_dev.d_buf + g_uncomp_hdrlen + (fragoffset << 3),
|
||||||
fptr + g_frame_hdrlen, paysize);
|
fptr + g_frame_hdrlen, paysize);
|
||||||
|
|
||||||
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
||||||
/* Update radio->r_accumlen if the frame is a fragment, radio->r_pktlen
|
/* Update reass->rb_accumlen if the frame is a fragment, reass->rb_pktlen
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -621,36 +527,49 @@ static int sixlowpan_frame_process(FAR struct radio_driver_s *radio,
|
|||||||
* bytes at the end. We must be liberal in what we accept.
|
* bytes at the end. We must be liberal in what we accept.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
radio->r_accumlen = g_uncomp_hdrlen + (fragoffset << 3) + paysize;
|
reass->rb_accumlen = g_uncomp_hdrlen + (fragoffset << 3) + paysize;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
radio->r_pktlen = paysize + g_uncomp_hdrlen;
|
reass->rb_pktlen = paysize + g_uncomp_hdrlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we have a full IP packet in sixlowpan_buf, deliver it to
|
/* If we have a full IP packet in sixlowpan_buf, deliver it to
|
||||||
* the IP stack
|
* the IP stack
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ninfo("r_accumlen=%d r_pktlen=%d paysize=%d\n",
|
ninfo("rb_accumlen=%d rb_pktlen=%d paysize=%d\n",
|
||||||
radio->r_accumlen, radio->r_pktlen, paysize);
|
reass->rb_accumlen, reass->rb_pktlen, paysize);
|
||||||
|
|
||||||
if (radio->r_accumlen == 0 || radio->r_accumlen >= radio->r_pktlen)
|
if (reass->rb_accumlen == 0 || reass->rb_accumlen >= reass->rb_pktlen)
|
||||||
{
|
{
|
||||||
ninfo("IP packet ready (length %d)\n", radio->r_pktlen);
|
ninfo("IP packet ready (length %d)\n", reass->rb_pktlen);
|
||||||
|
|
||||||
radio->r_dev.d_len = radio->r_pktlen;
|
radio->r_dev.d_buf = reass->rb_buf;
|
||||||
radio->r_pktlen = 0;
|
radio->r_dev.d_len = reass->rb_pktlen;
|
||||||
radio->r_accumlen = 0;
|
reass->rb_active = false;
|
||||||
|
reass->rb_pktlen = 0;
|
||||||
|
reass->rb_accumlen = 0;
|
||||||
return INPUT_COMPLETE;
|
return INPUT_COMPLETE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
radio->r_dev.d_buf = NULL;
|
||||||
|
radio->r_dev.d_len = 0;
|
||||||
return INPUT_PARTIAL;
|
return INPUT_PARTIAL;
|
||||||
|
|
||||||
|
errout_with_reass:
|
||||||
|
sixlowpan_reass_free(reass);
|
||||||
|
return ret;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/* Deliver the packet to the IP stack */
|
/* Deliver the packet to the IP stack */
|
||||||
|
|
||||||
radio->r_dev.d_len = paysize + g_uncomp_hdrlen;
|
radio->r_dev.d_len = paysize + g_uncomp_hdrlen;
|
||||||
return INPUT_COMPLETE;
|
return INPUT_COMPLETE;
|
||||||
|
|
||||||
|
errout_with_reass:
|
||||||
|
return ret;
|
||||||
|
|
||||||
#endif /* CONFIG_NET_6LOWPAN_FRAG */
|
#endif /* CONFIG_NET_6LOWPAN_FRAG */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -670,6 +589,11 @@ static int sixlowpan_frame_process(FAR struct radio_driver_s *radio,
|
|||||||
|
|
||||||
static int sixlowpan_dispatch(FAR struct radio_driver_s *radio)
|
static int sixlowpan_dispatch(FAR struct radio_driver_s *radio)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
||||||
|
FAR struct sixlowpan_reassbuf_s *reass;
|
||||||
|
#endif
|
||||||
|
int ret;
|
||||||
|
|
||||||
sixlowpan_dumpbuffer("Incoming packet",
|
sixlowpan_dumpbuffer("Incoming packet",
|
||||||
(FAR const uint8_t *)IPv6BUF(&radio->r_dev),
|
(FAR const uint8_t *)IPv6BUF(&radio->r_dev),
|
||||||
radio->r_dev.d_len);
|
radio->r_dev.d_len);
|
||||||
@ -691,7 +615,17 @@ static int sixlowpan_dispatch(FAR struct radio_driver_s *radio)
|
|||||||
* be set to zero. Oddly, ipv6_input() will return OK in this case.
|
* be set to zero. Oddly, ipv6_input() will return OK in this case.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return ipv6_input(&radio->r_dev);
|
ret = ipv6_input(&radio->r_dev);
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
||||||
|
/* Free the reassemby buffer */
|
||||||
|
|
||||||
|
reass = (FAR struct sixlowpan_reassbuf_s *)radio->r_dev.d_buf;
|
||||||
|
DEBUGASSERT(reass != NULL);
|
||||||
|
sixlowpan_reass_free(reass);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -115,8 +115,13 @@
|
|||||||
|
|
||||||
/* Sucessful return values from header compression logic */
|
/* Sucessful return values from header compression logic */
|
||||||
|
|
||||||
#define COMPRESS_HDR_INLINE 0 /* L2 header not compressed */
|
#define COMPRESS_HDR_INLINE 0 /* L2 header not compressed */
|
||||||
#define COMPRESS_HDR_ELIDED 1 /* L2 header compressed */
|
#define COMPRESS_HDR_ELIDED 1 /* L2 header compressed */
|
||||||
|
|
||||||
|
/* Memory Pools *************************************************************/
|
||||||
|
|
||||||
|
#define REASS_POOL_PREALLOCATED 0
|
||||||
|
#define REASS_POOL_DYNAMIC 1
|
||||||
|
|
||||||
/* Debug ********************************************************************/
|
/* Debug ********************************************************************/
|
||||||
|
|
||||||
@ -657,5 +662,107 @@ int sixlowpan_extract_destaddr(FAR struct radio_driver_s *radio,
|
|||||||
FAR const void *metadata,
|
FAR const void *metadata,
|
||||||
FAR struct netdev_varaddr_s *destaddr);
|
FAR struct netdev_varaddr_s *destaddr);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: sixlowpan_reass_initialize
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function initializes the reassembly buffer allocator. This
|
||||||
|
* function must be called early in the initialization sequence before
|
||||||
|
* any radios begin operation.
|
||||||
|
*
|
||||||
|
* Called only once during network initialization.
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
||||||
|
void sixlowpan_reass_initialize(void);
|
||||||
|
#endif /* CONFIG_NET_6LOWPAN_FRAG */
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: sixlowpan_reass_allocate
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The sixlowpan_reass_allocate function will get a free reassembly buffer
|
||||||
|
* structure for use by 6LoWPAN.
|
||||||
|
*
|
||||||
|
* This function will first attempt to allocate from the g_free_reass
|
||||||
|
* list. If that the list is empty, then the reassembly buffer structure
|
||||||
|
* will be allocated from the dynamic memory pool.
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* reasstag - The reassembly tag for subsequent lookup.
|
||||||
|
* fragsrc - The source address of the fragment.
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* A reference to the allocated reass structure. All fields used by the
|
||||||
|
* reasembly logic have been zeroed. On a failure to allocate, NULL is
|
||||||
|
* returned.
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* The network is locked.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
||||||
|
FAR struct sixlowpan_reassbuf_s *
|
||||||
|
sixlowpan_reass_allocate(uint16_t reasstag,
|
||||||
|
FAR const struct netdev_varaddr_s *fragsrc);
|
||||||
|
#endif /* CONFIG_NET_6LOWPAN_FRAG */
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: sixlowpan_reass_find
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Find a previously allocated, active reassembly buffer with the specified
|
||||||
|
* reassembly tag.
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* reasstag - The reassembly tag to match.
|
||||||
|
* fragsrc - The source address of the fragment.
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* A reference to the matching reass structure.
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* The network is locked.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
||||||
|
FAR struct sixlowpan_reassbuf_s *
|
||||||
|
sixlowpan_reass_find(uint16_t reasstag,
|
||||||
|
FAR const struct netdev_varaddr_s *fragsrc);
|
||||||
|
#endif /* CONFIG_NET_6LOWPAN_FRAG */
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: sixlowpan_reass_free
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The sixlowpan_reass_free function will return a reass structure
|
||||||
|
* to the free list of messages if it was a pre-allocated reass
|
||||||
|
* structure. If the reass structure was allocated dynamically it will
|
||||||
|
* be deallocated.
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* reass - reass structure to free
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* The network is locked.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
||||||
|
void sixlowpan_reass_free(FAR struct sixlowpan_reassbuf_s *reass);
|
||||||
|
#endif /* CONFIG_NET_6LOWPAN_FRAG */
|
||||||
|
|
||||||
#endif /* CONFIG_NET_6LOWPAN */
|
#endif /* CONFIG_NET_6LOWPAN */
|
||||||
#endif /* _NET_SIXLOWPAN_SIXLOWPAN_INTERNAL_H */
|
#endif /* _NET_SIXLOWPAN_SIXLOWPAN_INTERNAL_H */
|
||||||
|
458
net/sixlowpan/sixlowpan_reassbuf.c
Normal file
458
net/sixlowpan/sixlowpan_reassbuf.c
Normal file
@ -0,0 +1,458 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* net/sixlowpan/sixlowpan_reassbuf.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <nuttx/clock.h>
|
||||||
|
#include <nuttx/kmalloc.h>
|
||||||
|
#include <nuttx/mm/iob.h>
|
||||||
|
|
||||||
|
#include "sixlowpan_internal.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Re-assembly timeout in clock ticks */
|
||||||
|
|
||||||
|
#define NET_6LOWPAN_TIMEOUT SEC2TICK(CONFIG_NET_6LOWPAN_MAXAGE)
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* The g_free_reass is a list of reassembly buffer structures that are available for
|
||||||
|
* general use. The number of messages in this list is a system configuration
|
||||||
|
* item. Protected only by the network lock.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static FAR struct sixlowpan_reassbuf_s *g_free_reass;
|
||||||
|
|
||||||
|
/* This is a list of active, allocated reassemby buffers */
|
||||||
|
|
||||||
|
static FAR struct sixlowpan_reassbuf_s *g_active_reass;
|
||||||
|
|
||||||
|
/* Pool of pre-allocated reassembly buffer stuctures */
|
||||||
|
|
||||||
|
static struct sixlowpan_reassbuf_s g_metadata_pool[CONFIG_NET_6LOWPAN_NREASSBUF];
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: sixlowpan_compare_fragsrc
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Check if the fragment that we just received is from the same source as
|
||||||
|
* the previosly received fragements.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* radio - Radio network device driver state instance
|
||||||
|
* fragsrc - The source address of the fragment.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* true if the sources are the same.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static bool sixlowpan_compare_fragsrc(FAR struct sixlowpan_reassbuf_s *reass,
|
||||||
|
FAR const struct netdev_varaddr_s *fragsrc)
|
||||||
|
{
|
||||||
|
/* The addresses cannot match if they are not the same size */
|
||||||
|
|
||||||
|
if (fragsrc->nv_addrlen == reass->rb_fragsrc.nv_addrlen)
|
||||||
|
{
|
||||||
|
/* The are the same size, return the address comparison */
|
||||||
|
|
||||||
|
return (memcmp(fragsrc->nv_addr, reass->rb_fragsrc.nv_addr,
|
||||||
|
fragsrc->nv_addrlen) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: sixlowpan_reass_expire
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Free all expired or inactive reassembly buffers.
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* The network is locked.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void sixlowpan_reass_expire(void)
|
||||||
|
{
|
||||||
|
FAR struct sixlowpan_reassbuf_s *reass;
|
||||||
|
FAR struct sixlowpan_reassbuf_s *next;
|
||||||
|
systime_t elapsed;
|
||||||
|
|
||||||
|
/* If reassembly timed out, cancel it */
|
||||||
|
|
||||||
|
for (reass = g_active_reass; reass != NULL; reass = next)
|
||||||
|
{
|
||||||
|
/* Needed if 'reass' is freed */
|
||||||
|
|
||||||
|
next = reass->rb_flink;
|
||||||
|
|
||||||
|
/* Free any inactive reassembly buffers. This is done because the life
|
||||||
|
* the reassembly buffer is not cerain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!reass->rb_active)
|
||||||
|
{
|
||||||
|
sixlowpan_reass_free(reass);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Get the elpased time of the reassembly */
|
||||||
|
|
||||||
|
elapsed = clock_systimer() - reass->rb_time;
|
||||||
|
|
||||||
|
/* If the reassembly has expired, then free the reassembly buffer */
|
||||||
|
|
||||||
|
if (elapsed > NET_6LOWPAN_TIMEOUT)
|
||||||
|
{
|
||||||
|
nwarn("WARNING: Reassembly timed out\n");
|
||||||
|
sixlowpan_reass_free(reass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: sixlowpan_remove_active
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Remove a reassembly buffer from the active reassembly buffer list.
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* reass - The reassembly buffer to be removed.
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* The network is locked.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void sixlowpan_remove_active(FAR struct sixlowpan_reassbuf_s *reass)
|
||||||
|
{
|
||||||
|
FAR struct sixlowpan_reassbuf_s *curr;
|
||||||
|
FAR struct sixlowpan_reassbuf_s *prev;
|
||||||
|
|
||||||
|
/* Find the reassembly buffer in the list of active reassembly buffers */
|
||||||
|
|
||||||
|
for (prev = NULL, curr = g_active_reass;
|
||||||
|
curr != NULL && curr != reass;
|
||||||
|
prev = curr, curr = curr->rb_flink)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Did we find it? */
|
||||||
|
|
||||||
|
if (curr != NULL)
|
||||||
|
{
|
||||||
|
/* Yes.. remove it from the active reassembly buffer list */
|
||||||
|
|
||||||
|
if (prev == NULL)
|
||||||
|
{
|
||||||
|
g_active_reass = reass->rb_flink;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prev->rb_flink = reass->rb_flink;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reass->rb_flink = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: sixlowpan_reass_initialize
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function initializes the reassembly buffer allocator. This
|
||||||
|
* function must be called early in the initialization sequence before
|
||||||
|
* any radios begin operation.
|
||||||
|
*
|
||||||
|
* Called only once during network initialization.
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void sixlowpan_reass_initialize(void)
|
||||||
|
{
|
||||||
|
FAR struct sixlowpan_reassbuf_s *reass;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Initialize g_free_reass, the list of reassembly buffer structures that are
|
||||||
|
* available for allocation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
g_free_reass = NULL;
|
||||||
|
for (i = 0, reass = g_metadata_pool;
|
||||||
|
i < CONFIG_NET_6LOWPAN_NREASSBUF;
|
||||||
|
i++, reass++)
|
||||||
|
{
|
||||||
|
/* Add the next meta data structure from the pool to the list of
|
||||||
|
* general structures.
|
||||||
|
*/
|
||||||
|
|
||||||
|
reass->rb_flink = g_free_reass;
|
||||||
|
g_free_reass = reass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: sixlowpan_reass_allocate
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The sixlowpan_reass_allocate function will get a free reassembly buffer
|
||||||
|
* structure for use by 6LoWPAN.
|
||||||
|
*
|
||||||
|
* This function will first attempt to allocate from the g_free_reass
|
||||||
|
* list. If that the list is empty, then the reassembly buffer structure
|
||||||
|
* will be allocated from the dynamic memory pool.
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* reasstag - The reassembly tag for subsequent lookup.
|
||||||
|
* fragsrc - The source address of the fragment.
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* A reference to the allocated reass structure. All fields used by the
|
||||||
|
* reasembly logic have been zeroed. On a failure to allocate, NULL is
|
||||||
|
* returned.
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* The network is locked.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
FAR struct sixlowpan_reassbuf_s *
|
||||||
|
sixlowpan_reass_allocate(uint16_t reasstag,
|
||||||
|
FAR const struct netdev_varaddr_s *fragsrc)
|
||||||
|
{
|
||||||
|
FAR struct sixlowpan_reassbuf_s *reass;
|
||||||
|
uint8_t pool;
|
||||||
|
|
||||||
|
/* First, removed any expired or inactive reassembly buffers. This might
|
||||||
|
* free up a pre-allocated buffer for this allocation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sixlowpan_reass_expire();
|
||||||
|
|
||||||
|
/* Now, try the free list first */
|
||||||
|
|
||||||
|
if (g_free_reass != NULL)
|
||||||
|
{
|
||||||
|
reass = g_free_reass;
|
||||||
|
g_free_reass = reass->rb_flink;
|
||||||
|
pool = REASS_POOL_PREALLOCATED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_NET_6LOWPAN_REASS_STATIC
|
||||||
|
reass = NULL;
|
||||||
|
#else
|
||||||
|
/* If we cannot get a reassembly buffer instance from the free list, then we
|
||||||
|
* will have to allocate one from the kernal memory pool.
|
||||||
|
*/
|
||||||
|
|
||||||
|
reass = (FAR struct sixlowpan_reassbuf_s *)
|
||||||
|
kmm_malloc((sizeof (struct sixlowpan_reassbuf_s)));
|
||||||
|
pool = REASS_POOL_DYNAMIC;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We have successfully allocated memory from some source? */
|
||||||
|
|
||||||
|
if (reass != NULL)
|
||||||
|
{
|
||||||
|
/* Zero and tag the allocated reassembly buffer structure. */
|
||||||
|
|
||||||
|
memset(reass, 0, sizeof(struct sixlowpan_reassbuf_s));
|
||||||
|
memcpy(&reass->rb_fragsrc, fragsrc, sizeof(struct netdev_varaddr_s));
|
||||||
|
reass->rb_pool = pool;
|
||||||
|
reass->rb_active = true;
|
||||||
|
reass->rb_reasstag = reasstag;
|
||||||
|
reass->rb_time = clock_systimer();
|
||||||
|
|
||||||
|
/* Add the reassembly buffer to the list of active reassembly buffers */
|
||||||
|
|
||||||
|
reass->rb_flink = g_active_reass;
|
||||||
|
g_active_reass = reass;
|
||||||
|
}
|
||||||
|
|
||||||
|
return reass;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: sixlowpan_reass_find
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Find a previously allocated, active reassembly buffer with the specified
|
||||||
|
* reassembly tag.
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* reasstag - The reassembly tag to match.
|
||||||
|
* fragsrc - The source address of the fragment.
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* A reference to the matching reass structure.
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* The network is locked.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
FAR struct sixlowpan_reassbuf_s *
|
||||||
|
sixlowpan_reass_find(uint16_t reasstag,
|
||||||
|
FAR const struct netdev_varaddr_s *fragsrc)
|
||||||
|
{
|
||||||
|
FAR struct sixlowpan_reassbuf_s *reass;
|
||||||
|
|
||||||
|
/* First, removed any expired or inactive reassembly buffers (we don't want
|
||||||
|
* to return old reassembly buffer with the same tag)
|
||||||
|
*/
|
||||||
|
|
||||||
|
sixlowpan_reass_expire();
|
||||||
|
|
||||||
|
/* Now search for the matching reassembly buffer in the remainng, active
|
||||||
|
* reassembly buffers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (reass = g_active_reass; reass != NULL; reass = reass->rb_flink)
|
||||||
|
{
|
||||||
|
/* In order to be a match, it must have the same reassembly tag as
|
||||||
|
* well as source address (different sources might use the same
|
||||||
|
* reassembly tag).
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (reass->rb_reasstag == reasstag &&
|
||||||
|
sixlowpan_compare_fragsrc(reass, fragsrc))
|
||||||
|
{
|
||||||
|
return reass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Not found */
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: sixlowpan_reass_free
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The sixlowpan_reass_free function will return a reass structure
|
||||||
|
* to the free list of messages if it was a pre-allocated reass
|
||||||
|
* structure. If the reass structure was allocated dynamically it will
|
||||||
|
* be deallocated.
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* reass - reass structure to free
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* The network is locked.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void sixlowpan_reass_free(FAR struct sixlowpan_reassbuf_s *reass)
|
||||||
|
{
|
||||||
|
/* First, remove the reassembly buffer from the list of active reassembly
|
||||||
|
* buffers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sixlowpan_remove_active(reass);
|
||||||
|
|
||||||
|
/* If this is a pre-allocated reassembly buffer structure, then just put it back
|
||||||
|
* in the free list.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (reass->rb_pool == REASS_POOL_PREALLOCATED)
|
||||||
|
{
|
||||||
|
reass->rb_flink = g_free_reass;
|
||||||
|
g_free_reass = reass;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_NET_6LOWPAN_REASS_STATIC
|
||||||
|
DEBUGPANIC();
|
||||||
|
#else
|
||||||
|
DEBUGASSERT(reass->rb_pool == REASS_POOL_DYNAMIC);
|
||||||
|
|
||||||
|
/* Otherwise, deallocate it. */
|
||||||
|
|
||||||
|
sched_kfree(reass);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_NET_6LOWPAN_FRAG */
|
@ -48,6 +48,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
#include <nuttx/net/netconfig.h>
|
#include <nuttx/net/netconfig.h>
|
||||||
@ -342,9 +343,12 @@ found:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* We must free this TCP connection structure; this connection
|
/* We must free this TCP connection structure; this connection
|
||||||
* will never be established.
|
* will never be established. There should only be one reference
|
||||||
|
* on this connection when we allocated for the connection.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
DEBUGASSERT(conn->crefs == 1);
|
||||||
|
conn->crefs = 0;
|
||||||
tcp_free(conn);
|
tcp_free(conn);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
|
|
||||||
#include <nuttx/wdog.h>
|
#include <nuttx/wdog.h>
|
||||||
#include <nuttx/wqueue.h>
|
#include <nuttx/wqueue.h>
|
||||||
|
#include <nuttx/mm/iob.h>
|
||||||
#include <nuttx/net/net.h>
|
#include <nuttx/net/net.h>
|
||||||
#include <nuttx/net/ip.h>
|
#include <nuttx/net/ip.h>
|
||||||
#include <nuttx/net/radiodev.h>
|
#include <nuttx/net/radiodev.h>
|
||||||
@ -137,7 +138,7 @@ struct lo_driver_s
|
|||||||
|
|
||||||
static struct lo_driver_s g_loopback;
|
static struct lo_driver_s g_loopback;
|
||||||
#ifdef CONFIG_NET_6LOWPAN
|
#ifdef CONFIG_NET_6LOWPAN
|
||||||
static uint8_t g_iobuffer[CONFIG_NET_6LOWPAN_MTU + CONFIG_NET_GUARDSIZE];
|
static struct sixlowpan_reassbuf_s g_iobuffer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static uint8_t g_eaddr[IEEE802154_EADDRSIZE] =
|
static uint8_t g_eaddr[IEEE802154_EADDRSIZE] =
|
||||||
@ -388,6 +389,12 @@ static int lo_loopback(FAR struct net_driver_s *dev)
|
|||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_NET_6LOWPAN
|
#ifdef CONFIG_NET_6LOWPAN
|
||||||
{
|
{
|
||||||
|
/* Make sure the our single packet buffer is attached */
|
||||||
|
|
||||||
|
priv->lo_radio.r_dev.d_buf = g_iobuffer.rb_buf;
|
||||||
|
|
||||||
|
/* Then give the frame to 6LoWPAN */
|
||||||
|
|
||||||
ret = sixlowpan_input(&priv->lo_radio, iob, (FAR void *)&ind);
|
ret = sixlowpan_input(&priv->lo_radio, iob, (FAR void *)&ind);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -459,6 +466,15 @@ static void lo_poll_work(FAR void *arg)
|
|||||||
/* Perform the poll */
|
/* Perform the poll */
|
||||||
|
|
||||||
net_lock();
|
net_lock();
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_6LOWPAN
|
||||||
|
/* Make sure the our single packet buffer is attached */
|
||||||
|
|
||||||
|
priv->lo_radio.r_dev.d_buf = g_iobuffer.rb_buf;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Then perform the poll */
|
||||||
|
|
||||||
(void)devif_timer(&priv->lo_radio.r_dev, lo_loopback);
|
(void)devif_timer(&priv->lo_radio.r_dev, lo_loopback);
|
||||||
|
|
||||||
/* Setup the watchdog poll timer again */
|
/* Setup the watchdog poll timer again */
|
||||||
@ -634,6 +650,12 @@ static void lo_txavail_work(FAR void *arg)
|
|||||||
{
|
{
|
||||||
/* If so, then poll the network for new XMIT data */
|
/* If so, then poll the network for new XMIT data */
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_6LOWPAN
|
||||||
|
/* Make sure the our single packet buffer is attached */
|
||||||
|
|
||||||
|
priv->lo_radio.r_dev.d_buf = g_iobuffer.rb_buf;
|
||||||
|
#endif
|
||||||
|
|
||||||
(void)devif_poll(&priv->lo_radio.r_dev, lo_loopback);
|
(void)devif_poll(&priv->lo_radio.r_dev, lo_loopback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1063,9 +1085,6 @@ int ieee8021514_loopback(void)
|
|||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_NETDEV_IOCTL
|
#ifdef CONFIG_NETDEV_IOCTL
|
||||||
dev->d_ioctl = lo_ioctl; /* Handle network IOCTL commands */
|
dev->d_ioctl = lo_ioctl; /* Handle network IOCTL commands */
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_NET_6LOWPAN
|
|
||||||
dev->d_buf = g_iobuffer; /* Attach the IO buffer */
|
|
||||||
#endif
|
#endif
|
||||||
dev->d_private = (FAR void *)priv; /* Used to recover private state from dev */
|
dev->d_private = (FAR void *)priv; /* Used to recover private state from dev */
|
||||||
|
|
||||||
|
@ -224,6 +224,14 @@ static int macnet_req_data(FAR struct radio_driver_s *netdev,
|
|||||||
static int macnet_properties(FAR struct radio_driver_s *netdev,
|
static int macnet_properties(FAR struct radio_driver_s *netdev,
|
||||||
FAR struct radiodev_properties_s *properties);
|
FAR struct radiodev_properties_s *properties);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_6LOWPAN
|
||||||
|
static struct sixlowpan_reassbuf_s g_iobuffer;
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -470,6 +478,12 @@ static int macnet_rxframe(FAR struct mac802154_maccb_s *maccb,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Make sure the our single packet buffer is attached */
|
||||||
|
|
||||||
|
priv->md_dev.r_dev.d_buf = g_iobuffer.rb_buf;
|
||||||
|
|
||||||
|
/* And give the packet to 6LoWPAN */
|
||||||
|
|
||||||
ret = sixlowpan_input(&priv->md_dev, iob, (FAR void *)ind);
|
ret = sixlowpan_input(&priv->md_dev, iob, (FAR void *)ind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -568,7 +582,13 @@ static void macnet_txpoll_work(FAR void *arg)
|
|||||||
|
|
||||||
net_lock();
|
net_lock();
|
||||||
|
|
||||||
/* Perform the poll */
|
#ifdef CONFIG_NET_6LOWPAN
|
||||||
|
/* Make sure the our single packet buffer is attached */
|
||||||
|
|
||||||
|
priv->md_dev.r_dev.d_buf = g_iobuffer.rb_buf;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Then perform the poll */
|
||||||
|
|
||||||
(void)devif_timer(&priv->md_dev.r_dev, macnet_txpoll_callback);
|
(void)devif_timer(&priv->md_dev.r_dev, macnet_txpoll_callback);
|
||||||
|
|
||||||
@ -836,9 +856,13 @@ static void macnet_txavail_work(FAR void *arg)
|
|||||||
|
|
||||||
if (priv->md_bifup)
|
if (priv->md_bifup)
|
||||||
{
|
{
|
||||||
/* Check if there is room in the hardware to hold another outgoing packet. */
|
#ifdef CONFIG_NET_6LOWPAN
|
||||||
|
/* Make sure the our single packet buffer is attached */
|
||||||
|
|
||||||
/* If so, then poll the network for new XMIT data */
|
priv->md_dev.r_dev.d_buf = g_iobuffer.rb_buf;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Then poll the network for new XMIT data */
|
||||||
|
|
||||||
(void)devif_poll(&priv->md_dev.r_dev, macnet_txpoll_callback);
|
(void)devif_poll(&priv->md_dev.r_dev, macnet_txpoll_callback);
|
||||||
}
|
}
|
||||||
@ -1206,9 +1230,6 @@ int mac802154netdev_register(MACHANDLE mac)
|
|||||||
FAR struct radio_driver_s *radio;
|
FAR struct radio_driver_s *radio;
|
||||||
FAR struct net_driver_s *dev;
|
FAR struct net_driver_s *dev;
|
||||||
FAR struct mac802154_maccb_s *maccb;
|
FAR struct mac802154_maccb_s *maccb;
|
||||||
#ifdef CONFIG_NET_6LOWPAN
|
|
||||||
FAR uint8_t *pktbuf;
|
|
||||||
#endif
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
DEBUGASSERT(mac != NULL);
|
DEBUGASSERT(mac != NULL);
|
||||||
@ -1224,27 +1245,10 @@ int mac802154netdev_register(MACHANDLE mac)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_NET_6LOWPAN
|
|
||||||
/* Allocate a packet buffer (not used by this driver, but needed by the
|
|
||||||
* upper networking layer)
|
|
||||||
*/
|
|
||||||
|
|
||||||
pktbuf = (FAR uint8_t *)kmm_malloc(CONFIG_NET_6LOWPAN_MTU + CONFIG_NET_GUARDSIZE);
|
|
||||||
if (pktbuf == NULL)
|
|
||||||
{
|
|
||||||
nerr("ERROR: Failed to allocate the packet buffer\n");
|
|
||||||
kmm_free(priv);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Initialize the driver structure */
|
/* Initialize the driver structure */
|
||||||
|
|
||||||
radio = &priv->md_dev;
|
radio = &priv->md_dev;
|
||||||
dev = &radio->r_dev;
|
dev = &radio->r_dev;
|
||||||
#ifdef CONFIG_NET_6LOWPAN
|
|
||||||
dev->d_buf = pktbuf; /* Single packet buffer */
|
|
||||||
#endif
|
|
||||||
dev->d_ifup = macnet_ifup; /* I/F up (new IP address) callback */
|
dev->d_ifup = macnet_ifup; /* I/F up (new IP address) callback */
|
||||||
dev->d_ifdown = macnet_ifdown; /* I/F down callback */
|
dev->d_ifdown = macnet_ifdown; /* I/F down callback */
|
||||||
dev->d_txavail = macnet_txavail; /* New TX data callback */
|
dev->d_txavail = macnet_txavail; /* New TX data callback */
|
||||||
@ -1297,9 +1301,6 @@ int mac802154netdev_register(MACHANDLE mac)
|
|||||||
|
|
||||||
/* Free memory and return the error */
|
/* Free memory and return the error */
|
||||||
|
|
||||||
#ifdef CONFIG_NET_6LOWPAN
|
|
||||||
kmm_free(pktbuf);
|
|
||||||
#endif
|
|
||||||
kmm_free(priv);
|
kmm_free(priv);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
|
|
||||||
#include <nuttx/wdog.h>
|
#include <nuttx/wdog.h>
|
||||||
#include <nuttx/wqueue.h>
|
#include <nuttx/wqueue.h>
|
||||||
|
#include <nuttx/mm/iob.h>
|
||||||
#include <nuttx/net/net.h>
|
#include <nuttx/net/net.h>
|
||||||
#include <nuttx/net/ip.h>
|
#include <nuttx/net/ip.h>
|
||||||
#include <nuttx/net/radiodev.h>
|
#include <nuttx/net/radiodev.h>
|
||||||
@ -130,7 +131,9 @@ struct lo_driver_s
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static struct lo_driver_s g_loopback;
|
static struct lo_driver_s g_loopback;
|
||||||
static uint8_t g_iobuffer[CONFIG_NET_6LOWPAN_MTU + CONFIG_NET_GUARDSIZE];
|
#ifdef CONFIG_NET_6LOWPAN
|
||||||
|
static struct sixlowpan_reassbuf_s g_iobuffer;
|
||||||
|
#endif
|
||||||
|
|
||||||
static uint8_t g_mac_addr[CONFIG_PKTRADIO_ADDRLEN] =
|
static uint8_t g_mac_addr[CONFIG_PKTRADIO_ADDRLEN] =
|
||||||
{
|
{
|
||||||
@ -346,6 +349,10 @@ static int lo_loopback(FAR struct net_driver_s *dev)
|
|||||||
priv->lo_tail = NULL;
|
priv->lo_tail = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make sure the our single packet buffer is attached */
|
||||||
|
|
||||||
|
priv->lo_radio.r_dev.d_buf = g_iobuffer.rb_buf;
|
||||||
|
|
||||||
/* Return the next frame to the network */
|
/* Return the next frame to the network */
|
||||||
|
|
||||||
ninfo("Send frame %p to the network: Offset=%u Length=%u\n",
|
ninfo("Send frame %p to the network: Offset=%u Length=%u\n",
|
||||||
@ -420,6 +427,15 @@ static void lo_poll_work(FAR void *arg)
|
|||||||
/* Perform the poll */
|
/* Perform the poll */
|
||||||
|
|
||||||
net_lock();
|
net_lock();
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_6LOWPAN
|
||||||
|
/* Make sure the our single packet buffer is attached */
|
||||||
|
|
||||||
|
priv->lo_radio.r_dev.d_buf = g_iobuffer.rb_buf;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* And perform the poll */
|
||||||
|
|
||||||
(void)devif_timer(&priv->lo_radio.r_dev, lo_loopback);
|
(void)devif_timer(&priv->lo_radio.r_dev, lo_loopback);
|
||||||
|
|
||||||
/* Setup the watchdog poll timer again */
|
/* Setup the watchdog poll timer again */
|
||||||
@ -576,6 +592,13 @@ static void lo_txavail_work(FAR void *arg)
|
|||||||
if (priv->lo_bifup)
|
if (priv->lo_bifup)
|
||||||
{
|
{
|
||||||
/* If so, then poll the network for new XMIT data */
|
/* If so, then poll the network for new XMIT data */
|
||||||
|
#ifdef CONFIG_NET_6LOWPAN
|
||||||
|
/* Make sure the our single packet buffer is attached */
|
||||||
|
|
||||||
|
priv->lo_radio.r_dev.d_buf = g_iobuffer.rb_buf;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Then perform the poll */
|
||||||
|
|
||||||
(void)devif_poll(&priv->lo_radio.r_dev, lo_loopback);
|
(void)devif_poll(&priv->lo_radio.r_dev, lo_loopback);
|
||||||
}
|
}
|
||||||
@ -1009,7 +1032,6 @@ int pktradio_loopback(void)
|
|||||||
#ifdef CONFIG_NETDEV_IOCTL
|
#ifdef CONFIG_NETDEV_IOCTL
|
||||||
dev->d_ioctl = lo_ioctl; /* Handle network IOCTL commands */
|
dev->d_ioctl = lo_ioctl; /* Handle network IOCTL commands */
|
||||||
#endif
|
#endif
|
||||||
dev->d_buf = g_iobuffer; /* Attach the IO buffer */
|
|
||||||
dev->d_private = (FAR void *)priv; /* Used to recover private state from dev */
|
dev->d_private = (FAR void *)priv; /* Used to recover private state from dev */
|
||||||
|
|
||||||
/* Set the network mask and advertise our MAC-based IP address */
|
/* Set the network mask and advertise our MAC-based IP address */
|
||||||
|
Loading…
Reference in New Issue
Block a user