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
|
||||
int "DAC1 timer frequency"
|
||||
default 0
|
||||
default 100
|
||||
---help---
|
||||
DAC1 output frequency. Default: 100Hz
|
||||
|
||||
endif
|
||||
|
||||
@ -3272,7 +3274,9 @@ config STM32L4_DAC2_TIMER
|
||||
|
||||
config STM32L4_DAC2_TIMER_FREQUENCY
|
||||
int "DAC2 timer frequency"
|
||||
default 0
|
||||
default 100
|
||||
---help---
|
||||
DAC2 output frequency. Default: 100Hz
|
||||
|
||||
endif
|
||||
|
||||
|
@ -177,7 +177,7 @@
|
||||
#elif defined(CONFIG_STM32L4_TIM15_ADC1)
|
||||
# define ADC1_HAVE_TIMER 1
|
||||
# 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
|
||||
# undef ADC1_HAVE_TIMER
|
||||
#endif
|
||||
@ -219,7 +219,7 @@
|
||||
#elif defined(CONFIG_STM32L4_TIM15_ADC2)
|
||||
# define ADC2_HAVE_TIMER 1
|
||||
# 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
|
||||
# undef ADC2_HAVE_TIMER
|
||||
#endif
|
||||
@ -261,7 +261,7 @@
|
||||
#elif defined(CONFIG_STM32L4_TIM15_ADC3)
|
||||
# define ADC3_HAVE_TIMER 1
|
||||
# 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
|
||||
# undef ADC3_HAVE_TIMER
|
||||
#endif
|
||||
|
@ -103,11 +103,12 @@
|
||||
|
||||
#ifdef CONFIG_STM32L4_DAC1_DMA
|
||||
# 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_TIMER_FREQUENCY
|
||||
# elif !defined(CONFIG_STM32L4_DAC1_TIMER_FREQUENCY)
|
||||
# warning "A timer frequency must be specificed in CONFIG_STM32L4_DAC1_TIMER_FREQUENCY"
|
||||
# elif !defined(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_TIMER
|
||||
# endif
|
||||
@ -115,11 +116,12 @@
|
||||
|
||||
#ifdef CONFIG_STM32L4_DAC2_DMA
|
||||
# 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_TIMER_FREQUENCY
|
||||
# elif !defined(CONFIG_STM32L4_DAC2_TIMER_FREQUENCY)
|
||||
# warning "A timer frequency must be specificed in CONFIG_STM32L4_DAC2_TIMER_FREQUENCY"
|
||||
# elif !defined(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_TIMER
|
||||
# endif
|
||||
@ -269,7 +271,7 @@
|
||||
#endif
|
||||
|
||||
/* Calculate timer divider values based upon DACn_TIMER_PCLK_FREQUENCY and
|
||||
* CONFIG_STM32_DACn_TIMER_FREQUENCY.
|
||||
* CONFIG_STM32L4_DACn_TIMER_FREQUENCY.
|
||||
*/
|
||||
|
||||
#warning "Missing Logic"
|
||||
@ -312,6 +314,7 @@ struct stm32_chan_s
|
||||
DMA_HANDLE dma; /* Allocated DMA channel */
|
||||
uint32_t tbase; /* Timer base address */
|
||||
uint32_t tfrequency; /* Timer frequency */
|
||||
int result; /* DMA result */
|
||||
uint16_t dmabuffer[CONFIG_STM32L4_DAC_DMA_BUFFER_SIZE]; /* DMA transfer buffer */
|
||||
#endif
|
||||
};
|
||||
@ -323,9 +326,10 @@ struct stm32_chan_s
|
||||
/* DAC Register access */
|
||||
|
||||
#ifdef HAVE_DMA
|
||||
static uint32_t tim_getreg(FAR struct stm32_chan_s *chan, int offset);
|
||||
static void tim_putreg(FAR struct stm32_chan_s *chan, int offset,
|
||||
uint32_t value);
|
||||
static inline void tim_putreg(FAR struct stm32_chan_s *chan, int offset,
|
||||
uint32_t value);
|
||||
static inline void tim_modifyreg(FAR struct stm32_chan_s *chan, int offset,
|
||||
uint32_t clearbits, uint32_t setbits);
|
||||
#endif
|
||||
|
||||
/* DAC methods */
|
||||
@ -457,7 +461,7 @@ static struct stm32_dac_s g_dacblock;
|
||||
* Modify the contents of the DAC control register.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - Driver state instance
|
||||
* chan - A reference to the DAC channel state data
|
||||
* clearbits - Bits in the control register to be cleared
|
||||
* 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);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* 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
|
||||
*
|
||||
@ -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.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Returned Value:
|
||||
@ -522,8 +504,8 @@ static uint32_t tim_getreg(FAR struct stm32_chan_s *chan, int offset)
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef HAVE_DMA
|
||||
static void tim_putreg(FAR struct stm32_chan_s *chan, int offset,
|
||||
uint32_t value)
|
||||
static inline void tim_putreg(FAR struct stm32_chan_s *chan, int offset,
|
||||
uint32_t value)
|
||||
{
|
||||
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.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - Driver state instance
|
||||
* chan - A reference to the DAC channel state data
|
||||
* offset - The timer register offset
|
||||
* clearbits - Bits in the control register to be cleared
|
||||
* 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
|
||||
static void tim_modifyreg(FAR struct stm32_chan_s *chan, int offset,
|
||||
uint32_t clearbits, uint32_t setbits)
|
||||
static inline void tim_modifyreg(FAR struct stm32_chan_s *chan, int offset,
|
||||
uint32_t clearbits, uint32_t 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
|
||||
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
|
||||
|
||||
@ -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,
|
||||
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);
|
||||
|
||||
/* Enable DMA for DAC Channel */
|
||||
@ -777,7 +802,7 @@ static int dac_timinit(FAR struct stm32_chan_s *chan)
|
||||
* 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
|
||||
*/
|
||||
|
||||
@ -1004,6 +1029,7 @@ static int dac_chaninit(FAR struct stm32_chan_s *chan)
|
||||
if (ret < 0)
|
||||
{
|
||||
aerr("ERROR: Failed to initialize the DMA timer: %d\n", ret);
|
||||
stm32l4_dmafree(chan->dma);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -548,7 +548,7 @@ static struct stm32l4_pwmtimer_s g_pwm15dev =
|
||||
.irq = STM32L4_IRQ_TIM15,
|
||||
#endif
|
||||
.base = STM32L4_TIM15_BASE,
|
||||
.pclk = STM32L4_APB1_TIM15_CLKIN,
|
||||
.pclk = STM32L4_APB2_TIM15_CLKIN,
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -574,7 +574,7 @@ static struct stm32l4_pwmtimer_s g_pwm16dev =
|
||||
.irq = STM32L4_IRQ_TIM16,
|
||||
#endif
|
||||
.base = STM32L4_TIM16_BASE,
|
||||
.pclk = STM32L4_APB1_TIM16_CLKIN,
|
||||
.pclk = STM32L4_APB2_TIM16_CLKIN,
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -600,7 +600,7 @@ static struct stm32l4_pwmtimer_s g_pwm17dev =
|
||||
.irq = STM32L4_IRQ_TIM17,
|
||||
#endif
|
||||
.base = STM32L4_TIM17_BASE,
|
||||
.pclk = STM32L4_APB1_TIM17_CLKIN,
|
||||
.pclk = STM32L4_APB2_TIM17_CLKIN,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -435,8 +435,10 @@ static inline void rcc_enableapb2(void)
|
||||
|
||||
regval = getreg32(STM32L4_RCC_APB2ENR);
|
||||
|
||||
#ifdef CONFIG_STM32L4_SYSCFG
|
||||
/* System configuration controller clock enable */
|
||||
#if defined(CONFIG_STM32L4_SYSCFG) || defined(CONFIG_STM32L4_COMP)
|
||||
/* System configuration controller, comparators, and voltage reference buffer
|
||||
* clock enable
|
||||
*/
|
||||
|
||||
regval |= RCC_APB2ENR_SYSCFGEN;
|
||||
#endif
|
||||
|
@ -446,8 +446,10 @@ static inline void rcc_enableapb2(void)
|
||||
|
||||
regval = getreg32(STM32L4_RCC_APB2ENR);
|
||||
|
||||
#ifdef CONFIG_STM32L4_SYSCFG
|
||||
/* System configuration controller clock enable */
|
||||
#if defined(CONFIG_STM32L4_SYSCFG) || defined(CONFIG_STM32L4_COMP)
|
||||
/* System configuration controller, comparators, and voltage reference buffer
|
||||
* clock enable
|
||||
*/
|
||||
|
||||
regval |= RCC_APB2ENR_SYSCFGEN;
|
||||
#endif
|
||||
|
@ -491,8 +491,10 @@ static inline void rcc_enableapb2(void)
|
||||
|
||||
regval = getreg32(STM32L4_RCC_APB2ENR);
|
||||
|
||||
#ifdef CONFIG_STM32L4_SYSCFG
|
||||
/* System configuration controller clock enable */
|
||||
#if defined(CONFIG_STM32L4_SYSCFG) || defined(CONFIG_STM32L4_COMP)
|
||||
/* System configuration controller, comparators, and voltage reference buffer
|
||||
* clock enable
|
||||
*/
|
||||
|
||||
regval |= RCC_APB2ENR_SYSCFGEN;
|
||||
#endif
|
||||
|
@ -16,6 +16,9 @@ config HOST_X86_64
|
||||
config HOST_X86
|
||||
bool "x86"
|
||||
|
||||
config HOST_ARM
|
||||
bool "arm"
|
||||
|
||||
endchoice # Host CPU Type
|
||||
|
||||
config SIM_M32
|
||||
|
@ -57,10 +57,12 @@
|
||||
/* Storage order: %rbx, %rsp, %rbp, %r12, %r13, %r14, %r15, %rip */
|
||||
|
||||
# define XCPTCONTEXT_REGS 8
|
||||
#else
|
||||
#elif defined(CONFIG_HOST_X86) || defined(CONFIG_SIM_M32)
|
||||
/* Storage order: %ebx, %esi, %edi, %ebp, sp, and return PC */
|
||||
|
||||
# define XCPTCONTEXT_REGS 6
|
||||
#elif defined(CONFIG_HOST_ARM)
|
||||
# define XCPTCONTEXT_REGS 16
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -47,10 +47,16 @@ ifeq ($(CONFIG_SIM_M32),y)
|
||||
else
|
||||
ASRCS += up_setjmp64.S
|
||||
endif
|
||||
else
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_HOST_X86_64),y)
|
||||
ASRCS += up_setjmp32.S
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_HOST_ARM),y)
|
||||
ASRCS += up_setjmp_arm.S
|
||||
endif
|
||||
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
|
||||
CSRCS = up_initialize.c up_idle.c up_interruptcontext.c up_initialstate.c
|
||||
|
@ -132,7 +132,7 @@
|
||||
# define JB_SP JB_RSP
|
||||
# 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 */
|
||||
|
||||
# ifdef __ASSEMBLY__
|
||||
@ -152,7 +152,10 @@
|
||||
# define JB_PC (5)
|
||||
|
||||
# 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 **********************************************/
|
||||
/* 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
|
||||
Arduino DUE board featuring the Atmel ATSAM3X8E MCU running at 84
|
||||
MHz.
|
||||
Arduino DUE board featuring the Atmel ATSAM3X8E MCU running at 84 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
|
||||
-----------------
|
||||
|
@ -58,7 +58,7 @@
|
||||
/* After power-on reset, the SAM3X device is running on a 4MHz internal RC. These
|
||||
* definitions will configure clocking
|
||||
*
|
||||
* MAINOSC: Frequency = 12MHz (crysta)
|
||||
* MAINOSC: Frequency = 12MHz (crystal)
|
||||
* PLLA: PLL Divider = 1, Multiplier = 14 to generate PLLACK = 168MHz
|
||||
* Master Clock (MCK): Source = PLLACK, Prescalar = 1 to generate MCK = 84MHz
|
||||
* CPU clock: 84MHz
|
||||
|
@ -610,7 +610,17 @@ Configuration sub-directories
|
||||
unnecessarily busy. There is some prototype code to do just this
|
||||
in the driver, but does not seem to work.
|
||||
|
||||
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
|
||||
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
|
||||
to the hub. However, they are not being forwarded to the other
|
||||
endpoint.
|
||||
|
||||
2017-06-30: The failure to forward is understood: When the star
|
||||
endpoint sent the IPv6 destination address, the HC06 compression
|
||||
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
|
||||
compressed IPv6 addresses, then all tests are working as expected:
|
||||
TCP, UDP, Telnet.
|
||||
|
||||
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
|
||||
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
|
||||
incoming streams.
|
||||
incoming streams. The design was extended to support multiple
|
||||
reassembly buffers but have not yet been verified on this platform.
|
||||
|
||||
nsh:
|
||||
|
||||
|
@ -203,7 +203,8 @@
|
||||
*/
|
||||
|
||||
/* 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)
|
||||
|
||||
@ -292,11 +293,12 @@
|
||||
/* REVISIT : this can be configured */
|
||||
|
||||
#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
|
||||
* 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 */
|
||||
|
||||
@ -379,7 +381,8 @@
|
||||
#define STM32L4_PCLK2_FREQUENCY (STM32L4_HCLK_FREQUENCY/1)
|
||||
|
||||
#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)
|
||||
|
||||
@ -459,13 +462,14 @@
|
||||
#define STM32L4_PCLK2_FREQUENCY (STM32L4_HCLK_FREQUENCY/1)
|
||||
|
||||
#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
|
||||
|
||||
/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
|
||||
* 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
|
||||
@ -475,10 +479,8 @@
|
||||
#define BOARD_TIM5_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
||||
#define BOARD_TIM6_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_TIM16_FREQUENCY STM32L4_HCLK_FREQUENCY
|
||||
#define BOARD_TIM17_FREQUENCY STM32L4_HCLK_FREQUENCY
|
||||
#define BOARD_LPTIM1_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
||||
#define BOARD_LPTIM2_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
||||
|
||||
|
@ -292,11 +292,12 @@
|
||||
/* REVISIT : this can be configured */
|
||||
|
||||
#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
|
||||
* 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 */
|
||||
|
||||
@ -379,7 +380,8 @@
|
||||
#define STM32L4_PCLK2_FREQUENCY (STM32L4_HCLK_FREQUENCY/1)
|
||||
|
||||
#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)
|
||||
|
||||
@ -459,13 +461,14 @@
|
||||
#define STM32L4_PCLK2_FREQUENCY (STM32L4_HCLK_FREQUENCY/1)
|
||||
|
||||
#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
|
||||
|
||||
/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
|
||||
* 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
|
||||
@ -475,10 +478,8 @@
|
||||
#define BOARD_TIM5_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
||||
#define BOARD_TIM6_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_TIM16_FREQUENCY STM32L4_HCLK_FREQUENCY
|
||||
#define BOARD_TIM17_FREQUENCY STM32L4_HCLK_FREQUENCY
|
||||
#define BOARD_LPTIM1_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
||||
#define BOARD_LPTIM2_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
||||
|
||||
|
@ -49,7 +49,7 @@
|
||||
#include "nucleo-l452re.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Defintiionis
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#undef HAVE_I2C_DRIVER
|
||||
|
@ -293,10 +293,13 @@
|
||||
|
||||
#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)
|
||||
#define STM32L4_APB2_TIM17_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||
|
||||
/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
|
||||
* 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 */
|
||||
|
||||
@ -380,6 +383,9 @@
|
||||
|
||||
#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)
|
||||
#define STM32L4_APB2_TIM17_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||
|
||||
#elif defined(MSI_CLOCK_CONFIG)
|
||||
|
||||
@ -460,6 +466,9 @@
|
||||
|
||||
#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)
|
||||
#define STM32L4_APB2_TIM17_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -178,10 +178,13 @@
|
||||
|
||||
#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)
|
||||
#define STM32L4_APB2_TIM17_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||
|
||||
/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
|
||||
* 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 */
|
||||
|
||||
@ -361,9 +364,9 @@
|
||||
/* DMA channels *************************************************************/
|
||||
/* ADC */
|
||||
|
||||
#define ADC1_DMA_CHAN DMAMAP_ADC1_1
|
||||
#define ADC2_DMA_CHAN DMAMAP_ADC2_1
|
||||
#define ADC3_DMA_CHAN DMAMAP_ADC3_1
|
||||
#define ADC1_DMA_CHAN DMACHAN_ADC1_1
|
||||
#define ADC2_DMA_CHAN DMACHAN_ADC2_1
|
||||
#define ADC3_DMA_CHAN DMACHAN_ADC3_1
|
||||
|
||||
/* SPI
|
||||
*
|
||||
|
@ -997,7 +997,7 @@ Tickless OS
|
||||
will have an error of 0.6% and will have inaccuracies that will
|
||||
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,
|
||||
|
||||
nsh> sleep 10
|
||||
@ -1318,7 +1318,7 @@ Configuration sub-directories
|
||||
|
||||
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
|
||||
the clicker2-stm32 configurations. Essentially, the SAME70 Xplained
|
||||
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.
|
||||
|
||||
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
|
||||
incoming streams.
|
||||
incoming streams. The design was extended to support multiple
|
||||
reassembly buffers but have not yet been verified on this platform.
|
||||
|
||||
netnsh:
|
||||
|
||||
|
@ -1956,10 +1956,11 @@ Configuration sub-directories
|
||||
The SPI signals look clean on the board and the MRF24J40 seems
|
||||
fully functional.
|
||||
|
||||
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
|
||||
incoming streams.
|
||||
incoming streams. The design was extended to support multiple
|
||||
reassembly buffers but additional testing is needed.
|
||||
|
||||
mxtxplnd:
|
||||
|
||||
|
@ -292,6 +292,25 @@ config BQ2425X
|
||||
---help---
|
||||
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
|
||||
bool "Battery Fuel Gauge support"
|
||||
default n
|
||||
@ -312,6 +331,10 @@ config I2C_BQ2425X
|
||||
bool
|
||||
default y if BQ2425X
|
||||
|
||||
config I2C_BQ2429X
|
||||
bool
|
||||
default y if BQ2429X
|
||||
|
||||
config I2C_MAX1704X
|
||||
bool
|
||||
default y if MAX1704X
|
||||
|
@ -80,6 +80,12 @@ ifeq ($(CONFIG_I2C_BQ2425X),y)
|
||||
CSRCS += bq2425x.c
|
||||
endif
|
||||
|
||||
# Add the BQ2429x I2C-based battery charger driver
|
||||
|
||||
ifeq ($(CONFIG_I2C_BQ2429X),y)
|
||||
CSRCS += bq2429x.c
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
# 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;
|
||||
int ret;
|
||||
|
||||
/* Inforce mutually exclusive access to the battery driver */
|
||||
/* Enforce mutually exclusive access to the battery driver */
|
||||
|
||||
ret = sem_wait(&dev->batsem);
|
||||
if (ret < 0)
|
||||
@ -168,7 +168,7 @@ static int bat_charger_ioctl(FAR struct file *filep, int cmd,
|
||||
return -errno; /* Probably EINTR */
|
||||
}
|
||||
|
||||
/* Procss the IOCTL command */
|
||||
/* Process the IOCTL command */
|
||||
|
||||
ret = -EINVAL; /* Assume a bad argument */
|
||||
switch (cmd)
|
||||
@ -239,6 +239,16 @@ static int bat_charger_ioctl(FAR struct file *filep, int cmd,
|
||||
}
|
||||
break;
|
||||
|
||||
case BATIOC_OPERATE:
|
||||
{
|
||||
FAR int *ptr = (FAR int *)((uintptr_t)arg);
|
||||
if (ptr)
|
||||
{
|
||||
ret = dev->ops->operate(dev, (uintptr_t)arg);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
_err("ERROR: Unrecognized cmd: %d\n", cmd);
|
||||
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_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
|
||||
@ -146,7 +147,8 @@ static const struct battery_charger_operations_s g_bq2425xops =
|
||||
bq2425x_online,
|
||||
bq2425x_voltage,
|
||||
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;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* 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
|
||||
****************************************************************************/
|
||||
|
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/net/netdev.h>
|
||||
#include <nuttx/net/radiodev.h>
|
||||
#include <nuttx/net/sixlowpan.h>
|
||||
|
||||
#include <nuttx/wireless/spirit.h>
|
||||
#include <nuttx/wireless/pktradio.h>
|
||||
@ -363,6 +364,12 @@ int spirit_hw_initialize(FAR struct spirit_driver_s *dev,
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN
|
||||
/* One single packet buffer */
|
||||
|
||||
static struct sixlowpan_reassbuf_s g_iobuffer;
|
||||
#endif
|
||||
|
||||
/* Spirit radio initialization */
|
||||
|
||||
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;
|
||||
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 */
|
||||
|
||||
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
|
||||
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)
|
||||
{
|
||||
@ -1281,7 +1293,12 @@ static void spirit_interrupt_work(FAR void *arg)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1320,7 +1337,7 @@ static void spirit_interrupt_work(FAR void *arg)
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
@ -1473,7 +1490,7 @@ static void spirit_interrupt_work(FAR void *arg)
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
@ -1571,7 +1588,7 @@ static void spirit_interrupt_work(FAR void *arg)
|
||||
*/
|
||||
|
||||
#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)
|
||||
{
|
||||
@ -1752,6 +1769,12 @@ static void spirit_txpoll_work(FAR void *arg)
|
||||
|
||||
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 */
|
||||
|
||||
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 radio_driver_s *radio;
|
||||
FAR struct net_driver_s *dev;
|
||||
FAR uint8_t *pktbuf;
|
||||
int ret;
|
||||
|
||||
/* Allocate a driver state structure instance */
|
||||
@ -2764,16 +2786,6 @@ int spirit_netdev_initialize(FAR struct spi_dev_s *spi,
|
||||
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 */
|
||||
|
||||
priv->lower = lower;
|
||||
@ -2798,7 +2810,6 @@ int spirit_netdev_initialize(FAR struct spi_dev_s *spi,
|
||||
/* Initialize the common network device fields */
|
||||
|
||||
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_ifdown = spirit_ifdown; /* I/F down 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)
|
||||
{
|
||||
wlerr("ERROR: Failed to attach interrupt: %d\n", ret);
|
||||
goto errout_with_pktbuf;
|
||||
goto errout_with_alloc;
|
||||
}
|
||||
|
||||
/* Enable Radio IRQ */
|
||||
@ -2850,11 +2861,6 @@ int spirit_netdev_initialize(FAR struct spi_dev_s *spi,
|
||||
errout_with_attach:
|
||||
(void)lower->attach(lower, NULL, NULL);
|
||||
|
||||
errout_with_pktbuf:
|
||||
#if 0
|
||||
kmm_free(pktbuf);
|
||||
#endif
|
||||
|
||||
errout_with_alloc:
|
||||
kmm_free(priv);
|
||||
return ret;
|
||||
|
@ -13,6 +13,7 @@ config FS_AUTOMOUNTER
|
||||
bool "Auto-mounter"
|
||||
default n
|
||||
depends on !DISABLE_MOUNTPOINT
|
||||
select SCHED_LPWORK
|
||||
---help---
|
||||
The automounter provides an OS-internal mechanism for automatically
|
||||
mounting and unmounting removable media as the media is inserted and
|
||||
|
@ -42,8 +42,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <nuttx/clock.h>
|
||||
#include <nuttx/mm/iob.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
|
||||
#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.
|
||||
* 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
|
||||
* send more data. The length of the frame is provided in the io_len
|
||||
* field of the IOB.
|
||||
*
|
||||
* In this case, the d_buf is not used at all and, if fact, may be
|
||||
* NULL.
|
||||
* Outgoing frames are generated when the radio network driver calls
|
||||
* 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
|
||||
* via an IOB parameter in the sixlowpan_input() pr ieee802154_input()
|
||||
* interface. The length of the frame is io_len.
|
||||
*
|
||||
* - 6LoWPAN frames and will be uncompressed and possibly reassembled in
|
||||
* the d_buf; d_len will hold the size of the reassembled packet.
|
||||
* Again, the radio network driver must provide an instance of struct
|
||||
* 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'
|
||||
* 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:
|
||||
*
|
||||
* 1. On a TX poll, the radio network driver should provide its driver
|
||||
* structure. During the course of the poll, the networking layer may
|
||||
* generate outgoing frames. These frames will by provided to the MAC
|
||||
* structure along is (single) reassemby buffer provided at d_buf.
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
* obtained using the iob_alloc() function.
|
||||
*
|
||||
* For 6LoWPAN, the larger dev.d_buf must have a size of at least the
|
||||
* advertised MTU of the protocol, CONFIG_NET_6LOWPAN_MTU, plus
|
||||
* CONFIG_NET_GUARDSIZE. If fragmentation is enabled, then the logical
|
||||
* packet size may be significantly larger than the size of the frame
|
||||
* buffer. The dev.d_buf is used for de-compressing each frame and
|
||||
* reassembling any fragmented packets to create the full input packet
|
||||
* that is provided to the application.
|
||||
* For 6LoWPAN, fragmented packets will be reassembled using allocated
|
||||
* reassembly buffers that are managed by the 6LoWPAN layer. The radio
|
||||
* driver must still provide its (single) reassembly buffer in d_buf;
|
||||
* that buffer is still used for the case where the packet is not
|
||||
* fragmented into many frames. In either case, the packet buffer will
|
||||
* have a size of advertised MTU of the protocol, CONFIG_NET_6LOWPAN_MTU,
|
||||
* 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
|
||||
* frame by calling sixlowpan_input() or ieee802154_input(). That
|
||||
* The radio network driver should then inform the network of the recipt
|
||||
* of a frame by calling sixlowpan_input() or ieee802154_input(). That
|
||||
* single frame (or, perhaps, list of frames) should be provided as
|
||||
* second argument of that call.
|
||||
*
|
||||
@ -167,65 +182,6 @@ struct radio_driver_s
|
||||
uint8_t r_msdu_handle;
|
||||
#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 **********************************/
|
||||
/**************************************************************************
|
||||
* Name: r_get_mhrlen
|
||||
|
@ -53,6 +53,10 @@
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <nuttx/clock.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN
|
||||
|
||||
@ -337,6 +341,99 @@
|
||||
(a)[4] == 0 && (a)[5] == 0 && (a)[6] == 0 && \
|
||||
(((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
|
||||
****************************************************************************/
|
||||
|
@ -60,6 +60,7 @@
|
||||
*
|
||||
* CONFIG_I2C - I2C support *may* be needed
|
||||
* CONFIG_I2C_BQ2425X - The BQ2425x driver must be explicitly selected.
|
||||
* CONFIG_I2C_BQ2429X - The BQ2429x driver must be explicitly selected.
|
||||
*/
|
||||
|
||||
/* IOCTL Commands ***********************************************************/
|
||||
@ -84,6 +85,8 @@
|
||||
* Input value: An int defining the current value.
|
||||
* BATIOC_INPUT_CURRENT - Define the input current limit of power supply.
|
||||
* 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
|
||||
@ -151,6 +154,10 @@ struct battery_charger_operations_s
|
||||
/* Set the input current limit of power supply */
|
||||
|
||||
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 */
|
||||
@ -207,11 +214,11 @@ int battery_charger_register(FAR const char *devpath,
|
||||
*
|
||||
* Description:
|
||||
* 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:
|
||||
*
|
||||
* 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_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);
|
||||
#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
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* include/nuttx/power/battery_ioctl.h
|
||||
* 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>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -60,5 +60,35 @@
|
||||
#define BATIOC_CURRENT _BATIOC(0x0005)
|
||||
#define BATIOC_INPUT_CURRENT _BATIOC(0x0006)
|
||||
#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 */
|
||||
|
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)
|
||||
*/
|
||||
|
||||
ninfo("Call event=%p with flags=%04x\n", list->event, 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)
|
||||
*/
|
||||
|
||||
ninfo("Call event=%p with flags=%04x\n", cb->event, 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)
|
||||
{
|
||||
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);
|
||||
dev->d_sndlen = len;
|
||||
|
@ -51,6 +51,7 @@
|
||||
|
||||
#include <nuttx/clock.h>
|
||||
#include <nuttx/semaphore.h>
|
||||
#include <nuttx/mm/iob.h>
|
||||
#include <nuttx/net/net.h>
|
||||
#include <nuttx/net/radiodev.h>
|
||||
#include <netpacket/ieee802154.h>
|
||||
|
@ -64,7 +64,7 @@
|
||||
#endif
|
||||
|
||||
#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)
|
||||
# define L3_MAXHDRLEN UDP_HDRLEN
|
||||
#elif defined(CONFIG_NET_ICMPv6)
|
||||
|
@ -12,6 +12,40 @@ config NET_6LOWPAN_FRAG
|
||||
CONFIG_NET_6LOWPAN_FRAG specifies if 6lowpan fragmentation should be
|
||||
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
|
||||
int "Max Radio Frame Size"
|
||||
default 127
|
||||
|
@ -68,6 +68,10 @@ ifeq ($(CONFIG_NET_6LOWPAN_COMPRESSION_HC06),y)
|
||||
NET_CSRCS += sixlowpan_hc06.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_NET_6LOWPAN_FRAG),y)
|
||||
NET_CSRCS += sixlowpan_reassbuf.c
|
||||
endif
|
||||
|
||||
# Include the sixlowpan directory in the build
|
||||
|
||||
DEPPATH += --dep-path sixlowpan
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/mm/iob.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
#include <nuttx/net/radiodev.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;
|
||||
int framer_hdrlen;
|
||||
struct netdev_varaddr_s bcastmac;
|
||||
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
||||
uint16_t pktlen;
|
||||
uint16_t paysize;
|
||||
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
||||
uint16_t outlen = 0;
|
||||
#endif
|
||||
uint8_t protosize;
|
||||
@ -505,12 +506,18 @@ int sixlowpan_queue_frames(FAR struct radio_driver_s *radio,
|
||||
* added at qtail.
|
||||
*/
|
||||
|
||||
FAR struct sixlowpan_reassbuf_s *reass;
|
||||
FAR struct iob_s *qhead;
|
||||
FAR struct iob_s *qtail;
|
||||
FAR uint8_t *frame1;
|
||||
FAR uint8_t *fragptr;
|
||||
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
|
||||
* packet, so we fragment it into multiple packets and send them.
|
||||
* 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;
|
||||
PUTHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE,
|
||||
((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;
|
||||
|
||||
@ -575,7 +582,7 @@ int sixlowpan_queue_frames(FAR struct radio_driver_s *radio,
|
||||
outlen = paysize;
|
||||
|
||||
ninfo("First fragment: length %d, tag %d\n",
|
||||
paysize, radio->r_dgramtag);
|
||||
paysize, reass->rb_dgramtag);
|
||||
sixlowpan_dumpbuffer("Outgoing frame",
|
||||
(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,
|
||||
((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;
|
||||
|
||||
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;
|
||||
outlen += paysize;
|
||||
|
||||
ninfo("Fragment offset=%d, paysize=%d, r_dgramtag=%d\n",
|
||||
outlen >> 3, paysize, radio->r_dgramtag);
|
||||
ninfo("Fragment offset=%d, paysize=%d, rb_dgramtag=%d\n",
|
||||
outlen >> 3, paysize, reass->rb_dgramtag);
|
||||
sixlowpan_dumpbuffer("Outgoing frame",
|
||||
(FAR const uint8_t *)iob->io_data,
|
||||
iob->io_len);
|
||||
@ -697,7 +704,7 @@ int sixlowpan_queue_frames(FAR struct radio_driver_s *radio,
|
||||
|
||||
/* Update the datagram TAG value */
|
||||
|
||||
radio->r_dgramtag++;
|
||||
reass->rb_dgramtag++;
|
||||
#else
|
||||
nerr("ERROR: Packet too large: %d\n", buflen);
|
||||
nerr(" Cannot to be sent without fragmentation support\n");
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include <string.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/mm/iob.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
#include <nuttx/net/radiodev.h>
|
||||
#include <nuttx/net/ip.h>
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/mm/iob.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
#include <nuttx/net/radiodev.h>
|
||||
#include "sixlowpan/sixlowpan_internal.h"
|
||||
|
@ -69,6 +69,12 @@
|
||||
|
||||
void sixlowpan_initialize(void)
|
||||
{
|
||||
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
||||
/* Initialize the reassembly buffer allocator */
|
||||
|
||||
sixlowpan_reass_initialize();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
|
||||
/* Initialize HC06 data data structures */
|
||||
|
||||
|
@ -54,10 +54,7 @@
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
||||
# include "nuttx/clock.h"
|
||||
#endif
|
||||
|
||||
#include "nuttx/mm/iob.h"
|
||||
#include "nuttx/net/netdev.h"
|
||||
#include "nuttx/net/radiodev.h"
|
||||
#include "nuttx/net/ip.h"
|
||||
@ -82,10 +79,6 @@
|
||||
#define INPUT_PARTIAL 0 /* Frame processed successful, packet incomplete */
|
||||
#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
|
||||
* HC06 or HC1 headers.
|
||||
*/
|
||||
@ -132,50 +125,6 @@ static uint8_t g_bitbucket[UNCOMP_MAXHDR];
|
||||
* 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
|
||||
*
|
||||
@ -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 */
|
||||
int reqsize; /* Required buffer size */
|
||||
int hdrsize; /* Size of the IEEE802.15.4 header */
|
||||
int ret;
|
||||
|
||||
#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 */
|
||||
bool isfrag = false;
|
||||
bool isfirstfrag = false;
|
||||
uint16_t fragtag = 0; /* Tag of the fragment */
|
||||
systime_t elapsed; /* Elapsed time */
|
||||
int ret;
|
||||
#endif /* CONFIG_NET_6LOWPAN_FRAG */
|
||||
|
||||
/* 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",
|
||||
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 */
|
||||
|
||||
isfirstfrag = true;
|
||||
isfrag = true;
|
||||
bptr = reass->rb_buf;
|
||||
isfirstfrag = true;
|
||||
isfrag = true;
|
||||
}
|
||||
break;
|
||||
|
||||
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];
|
||||
fragtag = GETUINT16(fragptr, SIXLOWPAN_FRAG_TAG);
|
||||
fragsize = GETUINT16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE) & 0x07ff;
|
||||
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",
|
||||
fragsize, fragtag, fragoffset);
|
||||
ninfo("FRAGN: r_accumlen=%d paysize=%u fragsize=%u\n",
|
||||
radio->r_accumlen, iob->io_len - g_frame_hdrlen, fragsize);
|
||||
ninfo("FRAGN: rb_accumlen=%d paysize=%u fragsize=%u\n",
|
||||
reass->rb_accumlen, iob->io_len - g_frame_hdrlen, fragsize);
|
||||
|
||||
/* Indicate that this frame is a another fragment for reassembly */
|
||||
|
||||
isfrag = true;
|
||||
bptr = g_bitbucket;
|
||||
isfrag = true;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Not a fragment */
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* Check if we are currently reassembling a packet */
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
#else
|
||||
bptr = radio->r_dev.d_buf;
|
||||
#endif /* CONFIG_NET_6LOWPAN_FRAG */
|
||||
|
||||
/* Process next dispatch and headers */
|
||||
@ -553,7 +456,8 @@ static int sixlowpan_frame_process(FAR struct radio_driver_s *radio,
|
||||
/* Unknown or unsupported header */
|
||||
|
||||
nwarn("WARNING: Unknown dispatch: %u\n", hc1[SIXLOWPAN_HC1_DISPATCH]);
|
||||
return -ENOSYS;
|
||||
ret = -ENOSYS;
|
||||
goto errout_with_reass;
|
||||
}
|
||||
|
||||
#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.
|
||||
*/
|
||||
|
||||
radio->r_boffset = g_uncomp_hdrlen;
|
||||
reass->rb_boffset = g_uncomp_hdrlen;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
g_uncomp_hdrlen = radio->r_boffset;
|
||||
g_uncomp_hdrlen = reass->rb_boffset;
|
||||
}
|
||||
#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",
|
||||
paysize, CONFIG_NET_6LOWPAN_MTU);
|
||||
return -ENOSPC;
|
||||
ret = -ENOSPC;
|
||||
goto errout_with_reass;
|
||||
}
|
||||
|
||||
/* 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",
|
||||
g_uncomp_hdrlen, (fragoffset << 3), paysize,
|
||||
reqsize, CONFIG_NET_6LOWPAN_MTU);
|
||||
return -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
goto errout_with_reass;
|
||||
}
|
||||
|
||||
memcpy(radio->r_dev.d_buf + g_uncomp_hdrlen + (fragoffset << 3),
|
||||
fptr + g_frame_hdrlen, paysize);
|
||||
|
||||
#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.
|
||||
*/
|
||||
|
||||
@ -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.
|
||||
*/
|
||||
|
||||
radio->r_accumlen = g_uncomp_hdrlen + (fragoffset << 3) + paysize;
|
||||
reass->rb_accumlen = g_uncomp_hdrlen + (fragoffset << 3) + paysize;
|
||||
}
|
||||
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
|
||||
* the IP stack
|
||||
*/
|
||||
|
||||
ninfo("r_accumlen=%d r_pktlen=%d paysize=%d\n",
|
||||
radio->r_accumlen, radio->r_pktlen, paysize);
|
||||
ninfo("rb_accumlen=%d rb_pktlen=%d paysize=%d\n",
|
||||
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_pktlen = 0;
|
||||
radio->r_accumlen = 0;
|
||||
radio->r_dev.d_buf = reass->rb_buf;
|
||||
radio->r_dev.d_len = reass->rb_pktlen;
|
||||
reass->rb_active = false;
|
||||
reass->rb_pktlen = 0;
|
||||
reass->rb_accumlen = 0;
|
||||
return INPUT_COMPLETE;
|
||||
}
|
||||
|
||||
radio->r_dev.d_buf = NULL;
|
||||
radio->r_dev.d_len = 0;
|
||||
return INPUT_PARTIAL;
|
||||
|
||||
errout_with_reass:
|
||||
sixlowpan_reass_free(reass);
|
||||
return ret;
|
||||
|
||||
#else
|
||||
/* Deliver the packet to the IP stack */
|
||||
|
||||
radio->r_dev.d_len = paysize + g_uncomp_hdrlen;
|
||||
return INPUT_COMPLETE;
|
||||
|
||||
errout_with_reass:
|
||||
return ret;
|
||||
|
||||
#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)
|
||||
{
|
||||
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
||||
FAR struct sixlowpan_reassbuf_s *reass;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
sixlowpan_dumpbuffer("Incoming packet",
|
||||
(FAR const uint8_t *)IPv6BUF(&radio->r_dev),
|
||||
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.
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
#define COMPRESS_HDR_INLINE 0 /* L2 header not compressed */
|
||||
#define COMPRESS_HDR_ELIDED 1 /* L2 header compressed */
|
||||
#define COMPRESS_HDR_INLINE 0 /* L2 header not compressed */
|
||||
#define COMPRESS_HDR_ELIDED 1 /* L2 header compressed */
|
||||
|
||||
/* Memory Pools *************************************************************/
|
||||
|
||||
#define REASS_POOL_PREALLOCATED 0
|
||||
#define REASS_POOL_DYNAMIC 1
|
||||
|
||||
/* Debug ********************************************************************/
|
||||
|
||||
@ -657,5 +662,107 @@ int sixlowpan_extract_destaddr(FAR struct radio_driver_s *radio,
|
||||
FAR const void *metadata,
|
||||
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 /* _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 <string.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/net/netconfig.h>
|
||||
@ -342,9 +343,12 @@ found:
|
||||
#endif
|
||||
|
||||
/* 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);
|
||||
}
|
||||
else
|
||||
|
@ -51,6 +51,7 @@
|
||||
|
||||
#include <nuttx/wdog.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/mm/iob.h>
|
||||
#include <nuttx/net/net.h>
|
||||
#include <nuttx/net/ip.h>
|
||||
#include <nuttx/net/radiodev.h>
|
||||
@ -137,7 +138,7 @@ struct lo_driver_s
|
||||
|
||||
static struct lo_driver_s g_loopback;
|
||||
#ifdef CONFIG_NET_6LOWPAN
|
||||
static uint8_t g_iobuffer[CONFIG_NET_6LOWPAN_MTU + CONFIG_NET_GUARDSIZE];
|
||||
static struct sixlowpan_reassbuf_s g_iobuffer;
|
||||
#endif
|
||||
|
||||
static uint8_t g_eaddr[IEEE802154_EADDRSIZE] =
|
||||
@ -388,6 +389,12 @@ static int lo_loopback(FAR struct net_driver_s *dev)
|
||||
#endif
|
||||
#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);
|
||||
}
|
||||
#endif
|
||||
@ -459,6 +466,15 @@ static void lo_poll_work(FAR void *arg)
|
||||
/* Perform the poll */
|
||||
|
||||
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);
|
||||
|
||||
/* 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 */
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
@ -1063,9 +1085,6 @@ int ieee8021514_loopback(void)
|
||||
#endif
|
||||
#ifdef CONFIG_NETDEV_IOCTL
|
||||
dev->d_ioctl = lo_ioctl; /* Handle network IOCTL commands */
|
||||
#endif
|
||||
#ifdef CONFIG_NET_6LOWPAN
|
||||
dev->d_buf = g_iobuffer; /* Attach the IO buffer */
|
||||
#endif
|
||||
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,
|
||||
FAR struct radiodev_properties_s *properties);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN
|
||||
static struct sixlowpan_reassbuf_s g_iobuffer;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
@ -470,6 +478,12 @@ static int macnet_rxframe(FAR struct mac802154_maccb_s *maccb,
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -568,7 +582,13 @@ static void macnet_txpoll_work(FAR void *arg)
|
||||
|
||||
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);
|
||||
|
||||
@ -836,9 +856,13 @@ static void macnet_txavail_work(FAR void *arg)
|
||||
|
||||
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);
|
||||
}
|
||||
@ -1206,9 +1230,6 @@ int mac802154netdev_register(MACHANDLE mac)
|
||||
FAR struct radio_driver_s *radio;
|
||||
FAR struct net_driver_s *dev;
|
||||
FAR struct mac802154_maccb_s *maccb;
|
||||
#ifdef CONFIG_NET_6LOWPAN
|
||||
FAR uint8_t *pktbuf;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(mac != NULL);
|
||||
@ -1224,27 +1245,10 @@ int mac802154netdev_register(MACHANDLE mac)
|
||||
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 */
|
||||
|
||||
radio = &priv->md_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_ifdown = macnet_ifdown; /* I/F down 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 */
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN
|
||||
kmm_free(pktbuf);
|
||||
#endif
|
||||
kmm_free(priv);
|
||||
return ret;
|
||||
}
|
||||
|
@ -51,6 +51,7 @@
|
||||
|
||||
#include <nuttx/wdog.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/mm/iob.h>
|
||||
#include <nuttx/net/net.h>
|
||||
#include <nuttx/net/ip.h>
|
||||
#include <nuttx/net/radiodev.h>
|
||||
@ -130,7 +131,9 @@ struct lo_driver_s
|
||||
****************************************************************************/
|
||||
|
||||
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] =
|
||||
{
|
||||
@ -346,6 +349,10 @@ static int lo_loopback(FAR struct net_driver_s *dev)
|
||||
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 */
|
||||
|
||||
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 */
|
||||
|
||||
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);
|
||||
|
||||
/* Setup the watchdog poll timer again */
|
||||
@ -576,6 +592,13 @@ static void lo_txavail_work(FAR void *arg)
|
||||
if (priv->lo_bifup)
|
||||
{
|
||||
/* 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);
|
||||
}
|
||||
@ -1009,7 +1032,6 @@ int pktradio_loopback(void)
|
||||
#ifdef CONFIG_NETDEV_IOCTL
|
||||
dev->d_ioctl = lo_ioctl; /* Handle network IOCTL commands */
|
||||
#endif
|
||||
dev->d_buf = g_iobuffer; /* Attach the IO buffer */
|
||||
dev->d_private = (FAR void *)priv; /* Used to recover private state from dev */
|
||||
|
||||
/* Set the network mask and advertise our MAC-based IP address */
|
||||
|
Loading…
Reference in New Issue
Block a user