Merged nuttx/nuttx into master
This commit is contained in:
commit
426dac3747
80
ChangeLog
80
ChangeLog
@ -12295,3 +12295,83 @@
|
||||
Matthias Renner (2016-07-08).
|
||||
* drivers/pipe: Add missing configuration for pipe ring buffer size.
|
||||
From Frank Benkert (2016-07-08).
|
||||
* STM32L4: Fix incorrect clock setup for LPTIM1. From ziggurat29
|
||||
(2016-07-08).
|
||||
* nucleo-l476rg and stm32lf76vg-disco: Define timer clock frequencies on
|
||||
STM32L4-based boards. From ziggurat29 (2016-07-08).
|
||||
* STM32L4: Add support for tickless OS, and incidentally timers, pwm,
|
||||
oneshot, free-running.... From ziggurat29 (2016-07-08).
|
||||
* SAM3/4 I2C: Fix reversed logic in twi_startmessage(). From Wolfgang
|
||||
Reissnegger (2016-07-09).
|
||||
* VFS ioctl(). Per comments from David Sidrane, file_ioctl() should not
|
||||
return succeed if the ioctl method is not supported. It probably
|
||||
should return ENOTTY in that case (2016-07-09).
|
||||
* libm: This change should significantly improve the performance of
|
||||
single precision floating point math library functions. The vast
|
||||
majority of changes have to do with preventing the compiler from
|
||||
needlessly promoting floats to doubles, performing the calculation
|
||||
with doubles, only to demote the result to float. These changes only
|
||||
affect the math lib functions that return float. From David Alessio
|
||||
(2016-07-11).
|
||||
* STM32F4 Discovery: Add FPU support for ostest for the STM32F4Discovery
|
||||
platform. From David Alessio (2016-07-11).
|
||||
* Build system: Remove the includes/apps link to apps/include. It is
|
||||
no longer used. From Sebastien Lorquet (2016-07-11).
|
||||
* printf(): If there are no streams, let printf() fall back to use
|
||||
syslog() for output (2016-07-11).
|
||||
* Qemu-i486: Fix qemu-i486/ostest/Make.defs test for M32. From Heath
|
||||
Petersen (2016-07-12).
|
||||
* UART 16550: Handle when CONFIG_SERIAL_UART_ARCH_IOCTL is not enabled.
|
||||
From Heath Petersen (2016-07-12).
|
||||
* Kinetis Ethernet: Add support for the KSZ8081 PHY (2016-07-12).
|
||||
* SST26 Driver: Before accessing the sst26 flash, the "Global Unlock"
|
||||
command must me executed, which I do in the sst26 driver. BUT re-
|
||||
reading the datasheet, the WREN instruction is required to enable the
|
||||
execution of this command. This was not done. I have no idea how the
|
||||
driver currently works except by chance. The writes should never
|
||||
happen at all, the flash is half-enabled! From Sebastien Lorquet
|
||||
(2016-07-12).
|
||||
* Freedom K64F: Add a networking NSH configuration. (2016-07-12).
|
||||
* N25Qxx Driver: Alter the notion of 'blocksize' to be equivalent to
|
||||
'flash write page size' in order to align with assumptions in the
|
||||
smartfs driver (at least, maybe other things do as well). Correct a
|
||||
bug that was previously masked by having blocksize=eraseblocksize
|
||||
which would cause buffer overflows and delicious hardfaults. Trivial
|
||||
spelling changes in comments, etc. From ziggurat29 (2016-07-12).
|
||||
* STM32L476 Discovery: Update stm32l476 disco to include init code for
|
||||
smartfs and nxffs for cases where those fs are included in build.
|
||||
From ziggurat29 (2016-07-12).
|
||||
* Kinetis Ethernet and Freedom-K64F: Freedcom-K64F PHY address was
|
||||
wrong. Modified Ethernet driver to try all PHY addresses and then
|
||||
only fail if the driver cannot find a usable PHY address. MDIO pin
|
||||
must have an internal pull-up on the Freedom-K64F (2016-07-12).
|
||||
* Kinetis Ethernet: Add support for CONFIG_NET_NOINTS (2016-07-12).
|
||||
* SmartFS: Fix a 32-byte memory leak. From Ken Pettit (2016-07-12).
|
||||
* Freedom-K64F: SDHC is now enabled in the nsh configuration (but does
|
||||
not work)Add hooks for automounter; Change NSH configuration to use
|
||||
Windows (2016-07-13).
|
||||
* SAMV7 USBHS Device: This change solves a problem which causes data
|
||||
loss while sending data via USB. This problem is caused by an incorrect
|
||||
handling of the endpoint state in the USB driver sam_usbdevhs. This
|
||||
leads under some circumstances to situations in which an DMA transfer
|
||||
is setup while a previous DMA transfer is currently active. Amongst
|
||||
other things I introduced the new endpoint state USBHS_EPSTATE_SENDING_DMA
|
||||
for the fix. To reproduce the problem, I used a program which send as
|
||||
many data as possible via a CDC/ACM device and verified the received
|
||||
data on the PC. From Stefan Kolb (2016-07-13).
|
||||
* STM32: Fix bug in oneshot timer. From Max Neklyudov (2016-07-13).
|
||||
* STM32L4: Port foward bugfix from stm32 of oneshot timer. From
|
||||
ziggurat29 (2016-07-13).
|
||||
* STM32 and EFM32: I'm using syslog through ITM. In this case
|
||||
syslog_channel function is call before RAM initialisation in
|
||||
stm32_clockconfig. But syslog channel uses a global variable that is
|
||||
reset to default by the RAM initialization. From Pierre-noel
|
||||
Bouteville (2016-07-14).
|
||||
* LPC43xx SPIFI: If CONFIG_SPIFI_SECTOR512 undefined, lpc43_bwrite
|
||||
doesn't do actual write (probably copy/paste errors). Still not sure
|
||||
about current state of lpc43_spifi implementation, but for me NXFFS
|
||||
works with this patch. From Vytautas Lukenskas (2016-07-14).
|
||||
* SMART MTD layer: Fixes freesector logic error when sectorsPerBlk=256,
|
||||
adds DEBUGASSERT for invalid geometry and additional memory debug
|
||||
logic. Also fixes the dangling pointer on error bug. From Ken
|
||||
Pettit (2016-07-14).
|
||||
|
@ -909,9 +909,6 @@ static inline void efm32_itm_syslog(void)
|
||||
|
||||
efm32_enable_auxhfrco();
|
||||
|
||||
/* Then perform ARMv7-M ITM SYSLOG initialization */
|
||||
|
||||
itm_syslog_initialize();
|
||||
}
|
||||
#else
|
||||
# define efm32_itm_syslog()
|
||||
|
@ -275,6 +275,12 @@ void __start(void)
|
||||
|
||||
showprogress('C');
|
||||
|
||||
#ifdef CONFIG_ARMV7M_ITMSYSLOG
|
||||
/* Perform ARMv7-M ITM SYSLOG initialization */
|
||||
|
||||
itm_syslog_initialize();
|
||||
#endif
|
||||
|
||||
/* Perform early serial initialization */
|
||||
|
||||
up_earlyserialinit();
|
||||
|
@ -615,13 +615,6 @@ config KINETIS_SD4BIT_FREQ
|
||||
Frequency to use for transferring data to/from an SD card using all four data lines.
|
||||
|
||||
endif
|
||||
|
||||
config KINETIS_SDHC_DMAPRIO
|
||||
int "SDHC DMA priority"
|
||||
depends on SDIO_DMA
|
||||
---help---
|
||||
SDHC DMA priority
|
||||
|
||||
endmenu # Kinetis SDHC Configuration
|
||||
|
||||
menu "Kinetis UART Configuration"
|
||||
|
@ -1840,7 +1840,7 @@ static inline int kinetis_initphy(struct kinetis_driver_s *priv)
|
||||
phydata = 0xffff;
|
||||
ret = kinetis_readmii(priv, phyaddr, MII_PHYID1, &phydata);
|
||||
}
|
||||
while (ret >= 0 && phydata == 0xffff && ++retries < 3);
|
||||
while ((ret < 0 || phydata == 0xffff) && ++retries < 3);
|
||||
|
||||
/* If we successfully read anything then break out, using this PHY address */
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/kinetis/kinetis_sdhc.c
|
||||
*
|
||||
* Copyright (C) 2011-2012, 2014 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2011-2012, 2014, 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -85,10 +85,6 @@
|
||||
# define CONFIG_KINETIS_SDHC_PRIO NVIC_SYSH_PRIORITY_DEFAULT
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_KINETIS_SDHC_DMAPRIO
|
||||
# define CONFIG_KINETIS_SDHC_DMAPRIO DMA_CCR_PRIMED
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_DEBUG_MEMCARD_INFO
|
||||
# undef CONFIG_SDIO_XFRDEBUG
|
||||
#endif
|
||||
|
@ -2738,7 +2738,7 @@ static int khci_interrupt(int irq, void *context)
|
||||
#ifdef CONFIG_USBOTG
|
||||
/* Session Request Protocol (SRP) Time Out Check */
|
||||
|
||||
/* if USB OTG SRP is ready */
|
||||
/* Check if USB OTG SRP is ready */
|
||||
# warning "Missing logic"
|
||||
{
|
||||
/* Check if the 1 millisecond timer has expired */
|
||||
@ -2960,6 +2960,8 @@ x
|
||||
}
|
||||
}
|
||||
|
||||
UNUSED(otgir); /* May not be used, depending on above conditional logic */
|
||||
|
||||
/* Clear the pending USB interrupt. Goto is used in the above to assure
|
||||
* that all interrupt exists pass through this logic.
|
||||
*/
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/lpc43/lpc43_spifi.c
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2012, 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -779,12 +779,13 @@ static ssize_t lpc43_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t
|
||||
lpc43_cachewrite(priv, buffer, startblock, nblocks);
|
||||
|
||||
lpc43_dumpbuffer(__func__, buffer, nblocks << SPIFI_512SHIFT)
|
||||
return nblocks;
|
||||
return (ssize_t)nblocks;
|
||||
|
||||
#else
|
||||
|
||||
FAR struct lpc43_dev_s *priv = (FAR struct lpc43_dev_s *)dev;
|
||||
FAR uint8_t *dest;
|
||||
int ret;
|
||||
|
||||
finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
|
||||
|
||||
@ -792,19 +793,17 @@ static ssize_t lpc43_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t
|
||||
|
||||
dest = SPIFI_BASE + (startblock << SPIFI_BLKSHIFT);
|
||||
|
||||
#if defined(CONFIG_SPIFI_SECTOR512)
|
||||
/* Write all of the erase blocks to FLASH */
|
||||
|
||||
ret = lpc43_pagewrite(priv, dest, buffer, nblocks << SPIFI_512SHIFT);
|
||||
ret = lpc43_pagewrite(priv, dest, buffer, nblocks << SPIFI_BLKSHIFT);
|
||||
if (ret < 0)
|
||||
{
|
||||
ferr("ERROR: lpc43_pagewrite failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
lpc43_dumpbuffer(__func__, buffer, nblocks << SPIFI_BLKSHIFT)
|
||||
return nblocks;
|
||||
lpc43_dumpbuffer(__func__, buffer, nblocks << SPIFI_BLKSHIFT);
|
||||
return (ssize_t)nblocks;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* arch/arm/src/sam34/chip/sam_tc.h
|
||||
* Timer Counter (TC) definitions for the SAM3U, SAM4E, and SAM4S
|
||||
*
|
||||
* Copyright (C) 2009, 2013-2014 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2009, 2013-2014, 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -537,16 +537,10 @@
|
||||
# define TC_BMR_TC1XC1S_TIOA2 (3 << TC_BMR_TC1XC1S_SHIFT)
|
||||
#define TC_BMR_TC2XC2S_SHIFT (4) /* Bits 4-5: External Clock Signal 2 Selection */
|
||||
#define TC_BMR_TC2XC2S_MASK (3 << TC_BMR_TC2XC2S_SHIFT)
|
||||
#if defined(CONFIG_ARCH_CHIP_SAM4s) || defined(CONFIG_ARCH_CHIP_SAM4E)
|
||||
# define TC_BMR_TC2XC2S_TCLK2 (0 << TC_BMR_TC2XC2S_SHIFT)
|
||||
# define TC_BMR_TC2XC2S_TIOA1 (2 << TC_BMR_TC2XC2S_SHIFT)
|
||||
# define TC_BMR_TC2XC2S_TIOA2 (3 << TC_BMR_TC2XC2S_SHIFT)
|
||||
#else
|
||||
# define TC_BMR_TC2XC2S_TCLK2 (0 << TC_BMR_TC2XC2S_SHIFT)
|
||||
# define TC_BMR_TC2XC2S_NONE (1 << TC_BMR_TC2XC2S_SHIFT)
|
||||
# define TC_BMR_TC2XC2S_TIOA0 (2 << TC_BMR_TC2XC2S_SHIFT)
|
||||
# define TC_BMR_TC2XC2S_TIOA1 (3 << TC_BMR_TC2XC2S_SHIFT)
|
||||
#endif
|
||||
#define TC_BMR_QDEN (1 << 8) /* Bit 8: Quadrature Decoder Enabled */
|
||||
#define TC_BMR_POSEN (1 << 9) /* Bit 9: Position Enabled */
|
||||
#define TC_BMR_SPEEDEN (1 << 10) /* Bit 10: Speed Enabled */
|
||||
|
@ -301,6 +301,7 @@ enum sam_epstate_e
|
||||
USBHS_EPSTATE_STALLED, /* Endpoint is stalled */
|
||||
USBHS_EPSTATE_IDLE, /* Endpoint is idle (i.e. ready for transmission) */
|
||||
USBHS_EPSTATE_SENDING, /* Endpoint is sending data */
|
||||
USBHS_EPSTATE_SENDING_DMA, /* Endpoint is sending data via DMA */
|
||||
USBHS_EPSTATE_NBUSYBK, /* Endpoint DMA complete, waiting for NBUSYBK==0 */
|
||||
USBHS_EPSTATE_RECEIVING, /* Endpoint is receiving data */
|
||||
/* --- Endpoint 0 Only --- */
|
||||
@ -1006,7 +1007,7 @@ static void sam_dma_wrsetup(struct sam_usbdev_s *priv, struct sam_ep_s *privep,
|
||||
|
||||
/* Switch to the sending state */
|
||||
|
||||
privep->epstate = USBHS_EPSTATE_SENDING;
|
||||
privep->epstate = USBHS_EPSTATE_SENDING_DMA;
|
||||
privreq->inflight = 0;
|
||||
|
||||
/* Get the endpoint number */
|
||||
@ -1211,16 +1212,23 @@ static void sam_req_complete(struct sam_ep_s *privep, int16_t result)
|
||||
|
||||
privreq->req.result = result;
|
||||
|
||||
/* Callback to the request completion handler */
|
||||
|
||||
privreq->flink = NULL;
|
||||
privreq->req.callback(&privep->ep, &privreq->req);
|
||||
|
||||
/* Reset the endpoint state and restore the stalled indication */
|
||||
/* Reset the endpoint state and restore the stalled indication.
|
||||
*
|
||||
* At least the USB class CDC/ACM calls the function sam_ep_submit within
|
||||
* the callback. This function uses sam_req_write or sam_req_read to process
|
||||
* the request, both functions can change the state. Therefore it is verry
|
||||
* important to set the state to USBHS_EPSTATE_IDLE before the callback is
|
||||
* called.
|
||||
*/
|
||||
|
||||
privep->epstate = USBHS_EPSTATE_IDLE;
|
||||
privep->zlpneeded = false;
|
||||
privep->zlpsent = false;
|
||||
|
||||
/* Callback to the request completion handler */
|
||||
|
||||
privreq->flink = NULL;
|
||||
privreq->req.callback(&privep->ep, &privreq->req);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2497,7 +2505,8 @@ static void sam_dma_interrupt(struct sam_usbdev_s *priv, int epno)
|
||||
|
||||
/* Were we sending? Or receiving? */
|
||||
|
||||
if (privep->epstate == USBHS_EPSTATE_SENDING)
|
||||
if (privep->epstate == USBHS_EPSTATE_SENDING ||
|
||||
privep->epstate == USBHS_EPSTATE_SENDING_DMA)
|
||||
{
|
||||
uint32_t nbusybk;
|
||||
uint32_t byct;
|
||||
@ -2923,7 +2932,8 @@ static void sam_ep_interrupt(struct sam_usbdev_s *priv, int epno)
|
||||
*/
|
||||
|
||||
if (privep->epstate == USBHS_EPSTATE_RECEIVING ||
|
||||
privep->epstate == USBHS_EPSTATE_SENDING)
|
||||
privep->epstate == USBHS_EPSTATE_SENDING ||
|
||||
privep->epstate == USBHS_EPSTATE_SENDING_DMA)
|
||||
{
|
||||
sam_req_complete(privep, -EPROTO);
|
||||
}
|
||||
|
@ -95,9 +95,10 @@ static int stm32_oneshot_handler(int irq, void *context)
|
||||
* Disable the TC now and disable any further interrupts.
|
||||
*/
|
||||
|
||||
STM32_TIM_SETISR(oneshot->tch, NULL, 0);
|
||||
STM32_TIM_DISABLEINT(oneshot->tch, 0);
|
||||
STM32_TIM_SETMODE(oneshot->tch, STM32_TIM_MODE_DISABLED);
|
||||
STM32_TIM_ACKINT(oneshot->tch, 0);
|
||||
STM32_TIM_DISABLEINT(oneshot->tch, 0);
|
||||
|
||||
/* The timer is no longer running */
|
||||
|
||||
@ -351,6 +352,7 @@ int stm32_oneshot_cancel(struct stm32_oneshot_s *oneshot,
|
||||
/* Now we can disable the interrupt and stop the timer. */
|
||||
|
||||
STM32_TIM_DISABLEINT(oneshot->tch, 0);
|
||||
STM32_TIM_SETISR(oneshot->tch, NULL, 0);
|
||||
STM32_TIM_SETMODE(oneshot->tch, STM32_TIM_MODE_DISABLED);
|
||||
|
||||
oneshot->running = false;
|
||||
|
@ -282,6 +282,12 @@ void __start(void)
|
||||
|
||||
showprogress('C');
|
||||
|
||||
#ifdef CONFIG_ARMV7M_ITMSYSLOG
|
||||
/* Perform ARMv7-M ITM SYSLOG initialization */
|
||||
|
||||
itm_syslog_initialize();
|
||||
#endif
|
||||
|
||||
/* Perform early serial initialization */
|
||||
|
||||
#ifdef USE_EARLYSERIALINIT
|
||||
|
@ -919,7 +919,6 @@ static inline void rcc_itm_syslog(void)
|
||||
modifyreg32(STM32_DBGMCU_CR, DBGMCU_CR_TRACEMODE_MASK, DBGMCU_CR_ASYNCH |
|
||||
DBGMCU_CR_TRACEIOEN);
|
||||
|
||||
itm_syslog_initialize();
|
||||
}
|
||||
#else
|
||||
# define rcc_itm_syslog()
|
||||
|
@ -96,9 +96,10 @@ static int stm32l4_oneshot_handler(int irq, FAR void *context)
|
||||
* Disable the TC now and disable any further interrupts.
|
||||
*/
|
||||
|
||||
STM32L4_TIM_SETISR(oneshot->tch, NULL, 0);
|
||||
STM32L4_TIM_DISABLEINT(oneshot->tch, 0);
|
||||
STM32L4_TIM_SETMODE(oneshot->tch, STM32L4_TIM_MODE_DISABLED);
|
||||
STM32L4_TIM_ACKINT(oneshot->tch, 0);
|
||||
STM32L4_TIM_DISABLEINT(oneshot->tch, 0);
|
||||
|
||||
/* The timer is no longer running */
|
||||
|
||||
@ -353,6 +354,7 @@ int stm32l4_oneshot_cancel(FAR struct stm32l4_oneshot_s *oneshot,
|
||||
/* Now we can disable the interrupt and stop the timer. */
|
||||
|
||||
STM32L4_TIM_DISABLEINT(oneshot->tch, 0);
|
||||
STM32L4_TIM_SETISR(oneshot->tch, NULL, 0);
|
||||
STM32L4_TIM_SETMODE(oneshot->tch, STM32L4_TIM_MODE_DISABLED);
|
||||
|
||||
oneshot->running = false;
|
||||
|
@ -139,65 +139,27 @@
|
||||
/* DMA priority */
|
||||
|
||||
# ifndef CONFIG_USART_DMAPRIO
|
||||
# if defined(CONFIG_STM32L4_STM32L15XX) || defined(CONFIG_STM32L4_STM32F10XX) || \
|
||||
defined(CONFIG_STM32L4_STM32F30XX) || defined(CONFIG_STM32L4_STM32F37XX)
|
||||
# define CONFIG_USART_DMAPRIO DMA_CCR_PRIMED
|
||||
# elif defined(CONFIG_STM32L4_STM32F20XX) || defined(CONFIG_STM32L4_STM32F40XX)
|
||||
# define CONFIG_USART_DMAPRIO DMA_SCR_PRIMED
|
||||
# else
|
||||
# error "Unknown STM32 DMA"
|
||||
# endif
|
||||
# define CONFIG_USART_DMAPRIO DMA_CCR_PRIMED
|
||||
# endif
|
||||
# if defined(CONFIG_STM32L4_STM32L15XX) || defined(CONFIG_STM32L4_STM32F10XX) || \
|
||||
defined(CONFIG_STM32L4_STM32F30XX) || defined(CONFIG_STM32L4_STM32F37XX)
|
||||
# if (CONFIG_USART_DMAPRIO & ~DMA_CCR_PL_MASK) != 0
|
||||
# error "Illegal value for CONFIG_USART_DMAPRIO"
|
||||
# endif
|
||||
# elif defined(CONFIG_STM32L4_STM32F20XX) || defined(CONFIG_STM32L4_STM32F40XX)
|
||||
# if (CONFIG_USART_DMAPRIO & ~DMA_SCR_PL_MASK) != 0
|
||||
# error "Illegal value for CONFIG_USART_DMAPRIO"
|
||||
# endif
|
||||
# else
|
||||
# error "Unknown STM32 DMA"
|
||||
# if (CONFIG_USART_DMAPRIO & ~DMA_CCR_PL_MASK) != 0
|
||||
# error "Illegal value for CONFIG_USART_DMAPRIO"
|
||||
# endif
|
||||
|
||||
/* DMA control words */
|
||||
|
||||
# if defined(CONFIG_STM32L4_STM32F20XX) || defined(CONFIG_STM32L4_STM32F40XX)
|
||||
# define SERIAL_DMA_CONTROL_WORD \
|
||||
(DMA_SCR_DIR_P2M | \
|
||||
DMA_SCR_CIRC | \
|
||||
DMA_SCR_MINC | \
|
||||
DMA_SCR_PSIZE_8BITS | \
|
||||
DMA_SCR_MSIZE_8BITS | \
|
||||
CONFIG_USART_DMAPRIO | \
|
||||
DMA_SCR_PBURST_SINGLE | \
|
||||
DMA_SCR_MBURST_SINGLE)
|
||||
# ifdef CONFIG_SERIAL_IFLOWCONTROL
|
||||
# define SERIAL_DMA_IFLOW_CONTROL_WORD \
|
||||
(DMA_SCR_DIR_P2M | \
|
||||
DMA_SCR_MINC | \
|
||||
DMA_SCR_PSIZE_8BITS | \
|
||||
DMA_SCR_MSIZE_8BITS | \
|
||||
CONFIG_USART_DMAPRIO | \
|
||||
DMA_SCR_PBURST_SINGLE | \
|
||||
DMA_SCR_MBURST_SINGLE)
|
||||
# endif
|
||||
# else
|
||||
# define SERIAL_DMA_CONTROL_WORD \
|
||||
(DMA_CCR_CIRC | \
|
||||
DMA_CCR_MINC | \
|
||||
DMA_CCR_PSIZE_8BITS | \
|
||||
DMA_CCR_MSIZE_8BITS | \
|
||||
CONFIG_USART_DMAPRIO)
|
||||
# ifdef CONFIG_SERIAL_IFLOWCONTROL
|
||||
# define SERIAL_DMA_IFLOW_CONTROL_WORD \
|
||||
(DMA_CCR_MINC | \
|
||||
DMA_CCR_PSIZE_8BITS | \
|
||||
DMA_CCR_MSIZE_8BITS | \
|
||||
CONFIG_USART_DMAPRIO)
|
||||
# endif
|
||||
# endif
|
||||
# define SERIAL_DMA_CONTROL_WORD \
|
||||
(DMA_CCR_CIRC | \
|
||||
DMA_CCR_MINC | \
|
||||
DMA_CCR_PSIZE_8BITS | \
|
||||
DMA_CCR_MSIZE_8BITS | \
|
||||
CONFIG_USART_DMAPRIO)
|
||||
# ifdef CONFIG_SERIAL_IFLOWCONTROL
|
||||
# define SERIAL_DMA_IFLOW_CONTROL_WORD \
|
||||
(DMA_CCR_MINC | \
|
||||
DMA_CCR_PSIZE_8BITS | \
|
||||
DMA_CCR_MSIZE_8BITS | \
|
||||
CONFIG_USART_DMAPRIO)
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
@ -1590,12 +1552,11 @@ static int up_interrupt_common(FAR struct stm32l4_serial_s *priv)
|
||||
static int stm32l4serial_ioctl(FAR struct file *filep, int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) \
|
||||
|| defined(CONFIG_STM32F7_SERIALBRK_BSDCOMPAT)
|
||||
#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT)
|
||||
FAR struct inode *inode = filep->f_inode;
|
||||
FAR struct uart_dev_s *dev = inode->i_private;
|
||||
#endif
|
||||
#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_STM32F7_SERIALBRK_BSDCOMPAT)
|
||||
#if defined(CONFIG_SERIAL_TERMIOS)
|
||||
FAR struct stm32l4_serial_s *priv = (FAR struct stm32l4_serial_s *)dev->priv;
|
||||
#endif
|
||||
int ret = OK;
|
||||
@ -1619,6 +1580,7 @@ static int stm32l4serial_ioctl(FAR struct file *filep, int cmd,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STM32L4_USART_SINGLEWIRE
|
||||
#warning please review the potential use of ALTERNATE_FUNCTION_OPENDRAIN
|
||||
case TIOCSSINGLEWIRE:
|
||||
{
|
||||
/* Change the TX port to be open-drain/push-pull and enable/disable
|
||||
@ -1627,18 +1589,6 @@ static int stm32l4serial_ioctl(FAR struct file *filep, int cmd,
|
||||
|
||||
uint32_t cr = stm32l4serial_getreg(priv, STM32L4_USART_CR3_OFFSET);
|
||||
|
||||
#if defined(CONFIG_STM32L4_STM32F10XX)
|
||||
if (arg == SER_SINGLEWIRE_ENABLED)
|
||||
{
|
||||
stm32l4_configgpio((priv->tx_gpio & ~(GPIO_CNF_MASK)) | GPIO_CNF_AFOD);
|
||||
cr |= USART_CR3_HDSEL;
|
||||
}
|
||||
else
|
||||
{
|
||||
stm32l4_configgpio((priv->tx_gpio & ~(GPIO_CNF_MASK)) | GPIO_CNF_AFPP);
|
||||
cr &= ~USART_CR3_HDSEL;
|
||||
}
|
||||
#else
|
||||
if (arg == SER_SINGLEWIRE_ENABLED)
|
||||
{
|
||||
stm32l4_configgpio(priv->tx_gpio | GPIO_OPENDRAIN);
|
||||
@ -1649,7 +1599,6 @@ static int stm32l4serial_ioctl(FAR struct file *filep, int cmd,
|
||||
stm32l4_configgpio(priv->tx_gpio | GPIO_PUSHPULL);
|
||||
cr &= ~USART_CR3_HDSEL;
|
||||
}
|
||||
#endif
|
||||
|
||||
stm32l4serial_putreg(priv, STM32L4_USART_CR3_OFFSET, cr);
|
||||
}
|
||||
@ -2484,7 +2433,7 @@ void up_earlyserialinit(void)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void stm32l4serial_getregit(void)
|
||||
void up_serialinit(void)
|
||||
{
|
||||
#ifdef HAVE_UART
|
||||
char devname[16];
|
||||
|
@ -4,4 +4,33 @@
|
||||
#
|
||||
|
||||
if ARCH_BOARD_FREEDOM_K64F
|
||||
endif
|
||||
|
||||
config FRDMK64F_SDHC_AUTOMOUNT
|
||||
bool "SDHC automounter"
|
||||
default n
|
||||
depends on FS_AUTOMOUNTER && KINETIS_SDHC
|
||||
|
||||
if FRDMK64F_SDHC_AUTOMOUNT
|
||||
|
||||
config FRDMK64F_SDHC_AUTOMOUNT_FSTYPE
|
||||
string "SDHC file system type"
|
||||
default "vfat"
|
||||
|
||||
config FRDMK64F_SDHC_AUTOMOUNT_BLKDEV
|
||||
string "SDHC block device"
|
||||
default "/dev/mmcsd0"
|
||||
|
||||
config FRDMK64F_SDHC_AUTOMOUNT_MOUNTPOINT
|
||||
string "SDHC mount point"
|
||||
default "/mnt/sdcard"
|
||||
|
||||
config FRDMK64F_SDHC_AUTOMOUNT_DDELAY
|
||||
int "SDHC debounce delay (milliseconds)"
|
||||
default 1000
|
||||
|
||||
config FRDMK64F_SDHC_AUTOMOUNT_UDELAY
|
||||
int "SDHC unmount retry delay (milliseconds)"
|
||||
default 2000
|
||||
|
||||
endif # FRDMK64F_SDHC_AUTOMOUNT
|
||||
endif # ARCH_BOARD_FREEDOM_K64F
|
||||
|
@ -11,6 +11,8 @@ Contents
|
||||
o Serial Console
|
||||
o LEDs and Buttons
|
||||
o Networking Support
|
||||
o SD Card Support
|
||||
o USB Device Controller Support
|
||||
o Development Environment
|
||||
o GNU Toolchain Options
|
||||
o Freedom K64F Configuration Options
|
||||
@ -409,6 +411,201 @@ f Application Configuration -> Network Utilities
|
||||
CONFIG_NSH_NETINIT_RETRYMSEC=2000 : Configure the network monitor as you like
|
||||
CONFIG_NSH_NETINIT_SIGNO=18
|
||||
|
||||
SD Card Support
|
||||
===============
|
||||
|
||||
Card Slot
|
||||
---------
|
||||
A micro Secure Digital (SD) card slot is available on the FRDM-K64F connected to
|
||||
the SD Host Controller (SDHC) signals of the MCU. This slot will accept micro
|
||||
format SD memory cards. The SD card detect pin (PTE6) is an open switch that
|
||||
shorts with VDD when card is inserted.
|
||||
|
||||
------------ ------------- --------
|
||||
SD Card Slot Board Signal K64F Pin
|
||||
------------ ------------- --------
|
||||
DAT0 SDHC0_D0 PTE0
|
||||
DAT1 SDHC0_D1 PTE1
|
||||
DAT2 SDHC0_D2 PTE5
|
||||
CD/DAT3 SDHC0_D3 PTE4
|
||||
CMD SDHC0_CMD PTE3
|
||||
CLK SDHC0_DCLK PTE2
|
||||
SWITCH D_CARD_DETECT PTE6
|
||||
------------ ------------- --------
|
||||
|
||||
There is no Write Protect pin available to the K64F.
|
||||
|
||||
Configuration Settings
|
||||
----------------------
|
||||
Enabling SDHC support. The Freedom K64F provides one microSD memory card
|
||||
slot. Support for the SD slots can be enabled with the following
|
||||
settings:
|
||||
|
||||
System Type->Kinetic Peripheral Selection
|
||||
CONFIG_KINETIS_SDHC=y : To enable SDHC0 support
|
||||
|
||||
System Type
|
||||
CONFIG_GPIO_IRQ=y : GPIO interrupts needed
|
||||
CONFIG_KINETIS_PORTEINTS=y : Card detect pin is on PTE6
|
||||
|
||||
Device Drivers -> MMC/SD Driver Support
|
||||
CONFIG_MMCSD=y : Enable MMC/SD support
|
||||
CONFIG_MMSCD_NSLOTS=1 : One slot per driver instance
|
||||
CONFIG_MMCSD_MULTIBLOCK_DISABLE=y : (REVISIT)
|
||||
CONFIG_MMCSD_HAVECARDDETECT=y : Supports card-detect PIOs
|
||||
CONFIG_MMCSD_MMCSUPPORT=n : Interferes with some SD cards
|
||||
CONFIG_MMCSD_SPI=n : No SPI-based MMC/SD support
|
||||
CONFIG_MMCSD_SDIO=y : SDIO-based MMC/SD support
|
||||
CONFIG_SDIO_DMA=y : Use SDIO DMA
|
||||
CONFIG_SDIO_BLOCKSETUP=y : Needs to know block sizes
|
||||
|
||||
RTOS Features -> Work Queue Support
|
||||
CONFIG_SCHED_WORKQUEUE=y : Driver needs work queue support
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
|
||||
Application Configuration -> NSH Library
|
||||
CONFIG_NSH_ARCHINIT=y : NSH board-initialization, and
|
||||
CONFIG_LIB_BOARDCTL=y : Or
|
||||
CONFIG_BOARD_INITIALIZE=y
|
||||
|
||||
Using the SD card
|
||||
-----------------
|
||||
|
||||
1. After booting, the SDHC device will appear as /dev/mmcsd0.
|
||||
2. If you try mounting an SD card with nothing in the slot, the mount will
|
||||
fail:
|
||||
|
||||
nsh> mount -t vfat /dev/mmcsd0 /mnt/sd0
|
||||
nsh: mount: mount failed: 19
|
||||
|
||||
NSH can be configured to provide errors as strings instead of
|
||||
numbers. But in this case, only the error number is reported. The
|
||||
error numbers can be found in nuttx/include/errno.h:
|
||||
|
||||
#define ENODEV 19
|
||||
#define ENODEV_STR "No such device"
|
||||
|
||||
So the mount command is saying that there is no device or, more
|
||||
correctly, that there is no card in the SD card slot.
|
||||
|
||||
3. Insert the SD card. Then the mount should succeed.
|
||||
|
||||
nsh> mount -t vfat /dev/mmcsd0 /mnt/sd0
|
||||
nsh> ls /mnt/sd1
|
||||
/mnt/sd1:
|
||||
atest.txt
|
||||
nsh> cat /mnt/sd1/atest.txt
|
||||
This is a test
|
||||
|
||||
NOTE: See the next section entitled "Auto-Mounter" for another way
|
||||
to mount your SD card.
|
||||
|
||||
4. Before removing the card, you must umount the file system. This is
|
||||
equivalent to "ejecting" or "safely removing" the card on Windows: It
|
||||
flushes any cached data to an SD card and makes the SD card unavailable
|
||||
to the applications.
|
||||
|
||||
nsh> umount -t /mnt/sd0
|
||||
|
||||
It is now safe to remove the card. NuttX provides into callbacks
|
||||
that can be used by an application to automatically unmount the
|
||||
volume when it is removed. But those callbacks are not used in
|
||||
these configurations.
|
||||
|
||||
Auto-Mounter
|
||||
------------
|
||||
NuttX implements an auto-mounter than can make working with SD cards
|
||||
easier. With the auto-mounter, the file system will be automatically
|
||||
mounted when the SD card is inserted into the SDHC slot and automatically
|
||||
unmounted when the SD card is removed.
|
||||
|
||||
Here is a sample configuration for the auto-mounter:
|
||||
|
||||
File System Configuration
|
||||
CONFIG_FS_AUTOMOUNTER=y
|
||||
|
||||
Board-Specific Options
|
||||
CONFIG_FRDMK64F_SDHC_AUTOMOUNT=y
|
||||
CONFIG_FRDMK64F_SDHC_AUTOMOUNT_FSTYPE="vfat"
|
||||
CONFIG_FRDMK64F_SDHC_AUTOMOUNT_BLKDEV="/dev/mmcsd0"
|
||||
CONFIG_FRDMK64F_SDHC_AUTOMOUNT_MOUNTPOINT="/mnt/sdcard"
|
||||
CONFIG_FRDMK64F_SDHC_AUTOMOUNT_DDELAY=1000
|
||||
CONFIG_FRDMK64F_SDHC_AUTOMOUNT_UDELAY=2000
|
||||
|
||||
WARNING: SD cards should never be removed without first unmounting
|
||||
them. This is to avoid data and possible corruption of the file
|
||||
system. Certainly this is the case if you are writing to the SD card
|
||||
at the time of the removal. If you use the SD card for read-only access,
|
||||
however, then I cannot think of any reason why removing the card without
|
||||
mounting would be harmful.
|
||||
|
||||
USB Device Controller Support
|
||||
==============================
|
||||
|
||||
USB Device Controller Support
|
||||
-----------------------------
|
||||
The USBHS device controller driver is enabled with he following
|
||||
configurationsettings:
|
||||
|
||||
Device Drivers -> USB Device Driver Support
|
||||
CONFIG_USBDEV=y : Enable USB device support
|
||||
For full-speed/low-power mode:
|
||||
CONFIG_USBDEV_DUALSPEED=n : Disable High speed support
|
||||
For high-speed/normal mode:
|
||||
CONFIG_USBDEV_DUALSPEED=y : Enable High speed support
|
||||
CONFIG_USBDEV_DMA=y : Enable DMA methods
|
||||
CONFIG_USBDEV_MAXPOWER=100 : Maximum power consumption
|
||||
CONFIG_USBDEV_SELFPOWERED=y : Self-powered device
|
||||
|
||||
System Type -> Kinetis Peripheral Selection
|
||||
CONFIG_KINETIS_USBOTG=y
|
||||
|
||||
CDC/ACM Device Class
|
||||
--------------------
|
||||
In order to be usable, you must all enabled some class driver(s) for the
|
||||
USBHS device controller. Here, for example, is how to configure the CDC/ACM
|
||||
serial device class:
|
||||
|
||||
Device Drivers -> USB Device Driver Support
|
||||
CONFIG_CDCACM=y : USB Modem (CDC ACM) support
|
||||
CONFIG_CDCACM_EP0MAXPACKET=64 : Enpoint 0 packet size
|
||||
CONFIG_CDCACM_EPINTIN=1 : Interrupt IN endpoint number
|
||||
CONFIG_CDCACM_EPINTIN_FSSIZE=64 : Full speed packet size
|
||||
CONFIG_CDCACM_EPINTIN_HSSIZE=64 : High speed packet size
|
||||
CONFIG_CDCACM_EPBULKOUT=3 : Bulk OUT endpoint number
|
||||
CONFIG_CDCACM_EPBULKOUT_FSSIZE=64 : Full speed packet size
|
||||
CONFIG_CDCACM_EPBULKOUT_HSSIZE=512 : High speed packet size
|
||||
CONFIG_CDCACM_EPBULKIN=2 : Bulk IN endpoint number
|
||||
CONFIG_CDCACM_EPBULKIN_FSSIZE=64 : Full speed packet size
|
||||
CONFIG_CDCACM_EPBULKIN_HSSIZE=512 : High speed packet size
|
||||
CONFIG_CDCACM_NWRREQS=4 : Number of write requests
|
||||
CONFIG_CDCACM_NRDREQS=8 : Number of read requests
|
||||
CONFIG_CDCACM_BULKIN_REQLEN=96 : Size of write request buffer (for full speed)
|
||||
CONFIG_CDCACM_BULKIN_REQLEN=768 : Size of write request buffer (for high speed)
|
||||
CONFIG_CDCACM_RXBUFSIZE=257 : Serial read buffer size
|
||||
CONFIG_CDCACM_TXBUFSIZE=193 : Serial transmit buffer size (for full speed)
|
||||
CONFIG_CDCACM_TXBUFSIZE=769 : Serial transmit buffer size (for high speed)
|
||||
CONFIG_CDCACM_VENDORID=0x0525 : Vendor ID
|
||||
CONFIG_CDCACM_PRODUCTID=0xa4a7 : Product ID
|
||||
CONFIG_CDCACM_VENDORSTR="NuttX" : Vendor string
|
||||
CONFIG_CDCACM_PRODUCTSTR="CDC/ACM Serial" : Product string
|
||||
|
||||
Device Drivers -> Serial Driver Support
|
||||
CONFIG_SERIAL_REMOVABLE=y : Support for removable serial device
|
||||
|
||||
The CDC/ACM application provides commands to connect and disconnect the
|
||||
CDC/ACM serial device:
|
||||
|
||||
CONFIG_SYSTEM_CDCACM=y : Enable connect/disconnect support
|
||||
CONFIG_SYSTEM_CDCACM_DEVMINOR=0 : Use device /dev/ttyACM0
|
||||
CONFIG_CDCACM_RXBUFSIZE=??? : A large RX may be needed
|
||||
|
||||
If you include this CDC/ACM application, then you can connect the CDC/ACM
|
||||
serial device to the host by entering the command 'sercon' and you detach
|
||||
the serial device with the command 'serdis'. If you do no use this
|
||||
application, they you will have to write logic in your board initialization
|
||||
code to initialize and attach the USB device.
|
||||
|
||||
Development Environment
|
||||
=======================
|
||||
|
||||
@ -636,8 +833,14 @@ Where <subdir> is one of the following:
|
||||
|
||||
NOTES:
|
||||
|
||||
1. Most of the notes associated with the nsh configuration apply here
|
||||
as well (see below).
|
||||
1. This configuration uses the mconf-based configuration tool. To
|
||||
change this configuration using that tool, you should:
|
||||
|
||||
a. Build and install the kconfig-mconf tool. See nuttx/README.txt
|
||||
see additional README.txt files in the NuttX tools repository.
|
||||
|
||||
b. Execute 'make menuconfig' in nuttx/ in order to start the
|
||||
reconfiguration process.
|
||||
|
||||
2. Default platform/toolchain:
|
||||
|
||||
@ -646,13 +849,19 @@ Where <subdir> is one of the following:
|
||||
CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIW=y : ARM/mbed toolcahin (arm-none-elf-gcc)
|
||||
CONFIG_INTELHEX_BINARY=y : Output formats: Intel hex binary
|
||||
|
||||
3. No external pullup is available on MDIO signal when MK64FN1M0VLL12 MCU
|
||||
3. The Serial Console is provided on UART3 with the correct pin
|
||||
configuration for use with an Arduino Serial Shield.
|
||||
|
||||
4. SDHC support is not enabled in this configuration. Refer to the
|
||||
configuration settings listed above under "SD Card Support".
|
||||
|
||||
5. No external pullup is available on MDIO signal when MK64FN1M0VLL12 MCU
|
||||
is requests status of the Ethernet link connection. Internal pullup is
|
||||
required when port configuration for MDIO signal is enabled:
|
||||
|
||||
CONFIG_KINETIS_ENET_MDIOPULLUP=y
|
||||
|
||||
4. Configured to use a fixed IPv4 address:
|
||||
6. Configured to use a fixed IPv4 address:
|
||||
|
||||
CONFIG_NSH_IPADDR=0x0a000002
|
||||
CONFIG_NSH_DRIPADDR=0x0a000001
|
||||
@ -682,50 +891,53 @@ Where <subdir> is one of the following:
|
||||
|
||||
2. Default platform/toolchain:
|
||||
|
||||
CONFIG_HOST_LINUX=y : Linux (Cygwin under Windows okay too).
|
||||
CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT=y : Buildroot (arm-nuttx-elf-gcc)
|
||||
CONFIG_ARMV7M_OABI_TOOLCHAIN=y : The older OABI version
|
||||
CONFIG_HOST_WINDOWS=y : Cygwin under Windows
|
||||
CONFIG_WINDOWS_CYGWIN=y
|
||||
CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIW=y : ARM/mbed toolcahin (arm-none-elf-gcc)
|
||||
CONFIG_INTELHEX_BINARY=y : Output formats: Intel hex binary
|
||||
|
||||
3. The Serial Console is provided on UART3 with the correct pin
|
||||
configuration for use with an Arduino Serial Shield.
|
||||
|
||||
4. An SDHC driver is has not yet been tested but can be enabled in the NSH
|
||||
configuration by setting the following configuration values as follows:
|
||||
|
||||
CONFIG_KINETIS_SDHC=y : Enable the SDHC driver
|
||||
|
||||
CONFIG_MMCSD=y : Enable MMC/SD support
|
||||
CONFIG_MMCSD_SDIO=y : Use the SDIO-based MMC/SD driver
|
||||
CONFIG_MMCSD_NSLOTS=1 : One MMC/SD slot
|
||||
|
||||
CONFIG_FAT=y : Eable FAT file system
|
||||
CONFIG_FAT_LCNAMES=y : FAT lower case name support
|
||||
CONFIG_FAT_LFN=y : FAT long file name support
|
||||
CONFIG_FAT_MAXFNAME=32 : Maximum lenght of a long file name
|
||||
|
||||
CONFIG_GPIO_IRQ=y : Enable GPIO interrupts
|
||||
CONFIG_KINETIS_PORTEINTS=y : Enable PortE GPIO interrupts
|
||||
|
||||
CONFIG_SCHED_WORKQUEUE=y : Enable the NuttX workqueue
|
||||
|
||||
CONFIG_NSH_ARCHINIT=y : Provide NSH initializeation logic
|
||||
4. An SDHC driver is enabled in this configuration but does not yet work.
|
||||
The basic problem seems to be that it does not sense the presence of
|
||||
the SD card on PTE6. No interrupts are generated when the SD card is
|
||||
inserted or removed. You might want to disable SDHC and MMC/SD if
|
||||
you are using this configuration. Refer to the configuration
|
||||
settings listed above under "SD Card Support".
|
||||
|
||||
Status
|
||||
======
|
||||
|
||||
2016-07-11: Received hardware today and the board came up on the very
|
||||
first try. That does not happen often. At this point, the very basic
|
||||
NSH configuration is working and LEDs are working. The only odd
|
||||
behavior that I see is that pressing SW3 causes an unexpected interrupt
|
||||
error.
|
||||
NSH configuration is working and LEDs are working.
|
||||
|
||||
The only odd behavior that I see is that pressing SW3 causes an NMI
|
||||
interrupt (followed by a crash):
|
||||
|
||||
kinetis_nmi: PANIC!!! NMI received
|
||||
|
||||
I don't yet understand why this is.
|
||||
|
||||
2016-07-12: Added support for the KSZ8081 PHY and added the netnsh
|
||||
configuration. The network is basically functional, but a lot more
|
||||
testing is needed to confirm that.
|
||||
|
||||
configuration. The network is basically functional. More testing is
|
||||
needed, but I have not seen any obvious network failures.
|
||||
|
||||
In testing, I notice a strange thing. If I run at full optimization the
|
||||
code runs (albeit with bugs-to-be-solved). But with no optimization or
|
||||
even at -O1, the system fails to boot. This seems to be related to the
|
||||
watchdog timer.
|
||||
|
||||
2016-07-13: Add SD automounter logic; broke out SDHC logic into a separate
|
||||
file. The nsh configuration now has SDHC enabled be default. Does not
|
||||
yet work. The basic problem seems to be that it does not sense the
|
||||
presence of the SD card on PTE6. No interrupts are generated when the
|
||||
SD card is inserted or removed. You might want to disable SDHC and
|
||||
MMC/SD if you are using this configuration.
|
||||
|
||||
The nsh configuration now builds successfully with USB device enabled.
|
||||
USB device, however, has not yet been tested. I have not yet looked
|
||||
into 48MHz clocking requirements.
|
||||
|
||||
|
@ -285,7 +285,7 @@ CONFIG_ARCH_HAVE_RAMVECTORS=y
|
||||
#
|
||||
# Board Settings
|
||||
#
|
||||
CONFIG_BOARD_LOOPSPERMSEC=9535
|
||||
CONFIG_BOARD_LOOPSPERMSEC=10016
|
||||
# CONFIG_ARCH_CALIBRATION is not set
|
||||
|
||||
#
|
||||
|
@ -8,10 +8,14 @@
|
||||
#
|
||||
# CONFIG_EXPERIMENTAL is not set
|
||||
# CONFIG_DEFAULT_SMALL is not set
|
||||
CONFIG_HOST_LINUX=y
|
||||
# CONFIG_HOST_LINUX is not set
|
||||
# CONFIG_HOST_OSX is not set
|
||||
# CONFIG_HOST_WINDOWS is not set
|
||||
CONFIG_HOST_WINDOWS=y
|
||||
# CONFIG_HOST_OTHER is not set
|
||||
# CONFIG_WINDOWS_NATIVE is not set
|
||||
CONFIG_WINDOWS_CYGWIN=y
|
||||
# CONFIG_WINDOWS_MSYS is not set
|
||||
# CONFIG_WINDOWS_OTHER is not set
|
||||
|
||||
#
|
||||
# Build Configuration
|
||||
@ -135,12 +139,15 @@ CONFIG_ARM_HAVE_MPU_UNIFIED=y
|
||||
# CONFIG_ARMV7M_HAVE_DCACHE is not set
|
||||
# CONFIG_ARMV7M_HAVE_ITCM is not set
|
||||
# CONFIG_ARMV7M_HAVE_DTCM is not set
|
||||
# CONFIG_ARMV7M_TOOLCHAIN_IARL is not set
|
||||
CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT=y
|
||||
# CONFIG_ARMV7M_TOOLCHAIN_CODEREDL is not set
|
||||
# CONFIG_ARMV7M_TOOLCHAIN_CODESOURCERYL is not set
|
||||
# CONFIG_ARMV7M_TOOLCHAIN_IARW is not set
|
||||
# CONFIG_ARMV7M_TOOLCHAIN_ATOLLIC is not set
|
||||
# CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT is not set
|
||||
# CONFIG_ARMV7M_TOOLCHAIN_CODEREDW is not set
|
||||
# CONFIG_ARMV7M_TOOLCHAIN_CODESOURCERYW is not set
|
||||
# CONFIG_ARMV7M_TOOLCHAIN_DEVKITARM is not set
|
||||
# CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIL is not set
|
||||
CONFIG_ARMV7M_OABI_TOOLCHAIN=y
|
||||
CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIW=y
|
||||
# CONFIG_ARMV7M_TOOLCHAIN_RAISONANCE is not set
|
||||
# CONFIG_ARMV7M_HAVE_STACKCHECK is not set
|
||||
# CONFIG_ARMV7M_ITMSYSLOG is not set
|
||||
|
||||
@ -208,7 +215,7 @@ CONFIG_KINETIS_UART3=y
|
||||
# CONFIG_KINETIS_ADC1 is not set
|
||||
# CONFIG_KINETIS_CMP is not set
|
||||
# CONFIG_KINETIS_VREF is not set
|
||||
# CONFIG_KINETIS_SDHC is not set
|
||||
CONFIG_KINETIS_SDHC=y
|
||||
# CONFIG_KINETIS_FTM0 is not set
|
||||
# CONFIG_KINETIS_FTM1 is not set
|
||||
# CONFIG_KINETIS_FTM2 is not set
|
||||
@ -229,11 +236,23 @@ CONFIG_KINETIS_UART3=y
|
||||
#
|
||||
# Kinetis GPIO Interrupt Configuration
|
||||
#
|
||||
# CONFIG_GPIO_IRQ is not set
|
||||
CONFIG_GPIO_IRQ=y
|
||||
# CONFIG_KINETIS_PORTAINTS is not set
|
||||
# CONFIG_KINETIS_PORTBINTS is not set
|
||||
# CONFIG_KINETIS_PORTCINTS is not set
|
||||
# CONFIG_KINETIS_PORTDINTS is not set
|
||||
CONFIG_KINETIS_PORTEINTS=y
|
||||
|
||||
#
|
||||
# Kinetis SDHC Configuration
|
||||
#
|
||||
# CONFIG_KINETIS_SDHC_ABSFREQ is not set
|
||||
|
||||
#
|
||||
# Kinetis UART Configuration
|
||||
#
|
||||
CONFIG_SDIO_DMA=y
|
||||
# CONFIG_SDIO_WIDTH_D1_ONLY is not set
|
||||
|
||||
#
|
||||
# Architecture Options
|
||||
@ -267,7 +286,7 @@ CONFIG_ARCH_HAVE_RAMVECTORS=y
|
||||
#
|
||||
# Board Settings
|
||||
#
|
||||
CONFIG_BOARD_LOOPSPERMSEC=9535
|
||||
CONFIG_BOARD_LOOPSPERMSEC=10016
|
||||
# CONFIG_ARCH_CALIBRATION is not set
|
||||
|
||||
#
|
||||
@ -393,6 +412,7 @@ CONFIG_NAME_MAX=32
|
||||
# CONFIG_SCHED_STARTHOOK is not set
|
||||
# CONFIG_SCHED_ATEXIT is not set
|
||||
# CONFIG_SCHED_ONEXIT is not set
|
||||
# CONFIG_SIG_EVTHREAD is not set
|
||||
|
||||
#
|
||||
# Signal Numbers
|
||||
@ -401,6 +421,7 @@ CONFIG_SIG_SIGUSR1=1
|
||||
CONFIG_SIG_SIGUSR2=2
|
||||
CONFIG_SIG_SIGALARM=3
|
||||
CONFIG_SIG_SIGCONDTIMEDOUT=16
|
||||
CONFIG_SIG_SIGWORK=17
|
||||
|
||||
#
|
||||
# POSIX Message Queue Options
|
||||
@ -412,8 +433,11 @@ CONFIG_MQ_MAXMSGSIZE=32
|
||||
#
|
||||
# Work queue support
|
||||
#
|
||||
# CONFIG_SCHED_WORKQUEUE is not set
|
||||
# CONFIG_SCHED_HPWORK is not set
|
||||
CONFIG_SCHED_WORKQUEUE=y
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPRIORITY=224
|
||||
CONFIG_SCHED_HPWORKPERIOD=50000
|
||||
CONFIG_SCHED_HPWORKSTACKSIZE=2048
|
||||
# CONFIG_SCHED_LPWORK is not set
|
||||
|
||||
#
|
||||
@ -479,7 +503,18 @@ CONFIG_DEV_NULL=y
|
||||
# CONFIG_RGBLED is not set
|
||||
# CONFIG_PCA9635PW is not set
|
||||
# CONFIG_NCP5623C is not set
|
||||
# CONFIG_MMCSD is not set
|
||||
CONFIG_MMCSD=y
|
||||
CONFIG_MMCSD_NSLOTS=1
|
||||
# CONFIG_MMCSD_READONLY is not set
|
||||
CONFIG_MMCSD_MULTIBLOCK_DISABLE=y
|
||||
# CONFIG_MMCSD_MMCSUPPORT is not set
|
||||
CONFIG_MMCSD_HAVECARDDETECT=y
|
||||
CONFIG_ARCH_HAVE_SDIO=y
|
||||
# CONFIG_ARCH_HAVE_SDIOWAIT_WRCOMPLETE is not set
|
||||
CONFIG_MMCSD_SDIO=y
|
||||
# CONFIG_SDIO_PREFLIGHT is not set
|
||||
# CONFIG_SDIO_MUXBUS is not set
|
||||
CONFIG_SDIO_BLOCKSETUP=y
|
||||
# CONFIG_MODEM is not set
|
||||
# CONFIG_MTD is not set
|
||||
# CONFIG_EEPROM is not set
|
||||
@ -584,8 +619,9 @@ CONFIG_FS_WRITABLE=y
|
||||
CONFIG_FS_MQUEUE_MPATH="/var/mqueue"
|
||||
# CONFIG_FS_RAMMAP is not set
|
||||
CONFIG_FS_FAT=y
|
||||
# CONFIG_FAT_LCNAMES is not set
|
||||
# CONFIG_FAT_LFN is not set
|
||||
CONFIG_FAT_LCNAMES=y
|
||||
CONFIG_FAT_LFN=y
|
||||
CONFIG_FAT_MAXFNAME=32
|
||||
# CONFIG_FS_FATTIME is not set
|
||||
# CONFIG_FAT_FORCE_INDIRECT is not set
|
||||
# CONFIG_FAT_DMAMEMORY is not set
|
||||
@ -864,6 +900,7 @@ CONFIG_NSH_DISABLE_LOSMART=y
|
||||
# CONFIG_NSH_DISABLE_WGET is not set
|
||||
# CONFIG_NSH_DISABLE_XD is not set
|
||||
CONFIG_NSH_MMCSDMINOR=0
|
||||
CONFIG_NSH_MMCSDSLOTNO=0
|
||||
|
||||
#
|
||||
# Configure Command Options
|
||||
|
@ -61,7 +61,7 @@ fi
|
||||
|
||||
# This is the location where I installed the ARM "GNU Tools for ARM Embedded Processors"
|
||||
# You can this free toolchain here https://launchpad.net/gcc-arm-embedded
|
||||
#export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/GNU Tools ARM Embedded/4.9 2015q2/bin"
|
||||
export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/GNU Tools ARM Embedded/4.9 2015q2/bin"
|
||||
|
||||
# This is the path to the location where I installed the devkitARM toolchain
|
||||
# You can get this free toolchain from http://devkitpro.org/ or http://sourceforge.net/projects/devkitpro/
|
||||
@ -69,7 +69,7 @@ fi
|
||||
|
||||
# This is the Cygwin path to the location where I build the buildroot
|
||||
# toolchain.
|
||||
export TOOLCHAIN_BIN="${WD}/../buildroot/build_arm_nofpu/staging_dir/bin"
|
||||
# export TOOLCHAIN_BIN="${WD}/../buildroot/build_arm_nofpu/staging_dir/bin"
|
||||
|
||||
# Add the path to the toolchain to the PATH varialble
|
||||
export PATH="${TOOLCHAIN_BIN}:/sbin:/usr/sbin:${PATH_ORIG}"
|
||||
|
@ -54,6 +54,13 @@ else ifeq ($(CONFIG_BOARD_INITIALIZE),y)
|
||||
CSRCS += k64_bringup.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KINETIS_SDHC),y)
|
||||
CSRCS += k64_sdhc.c
|
||||
ifeq ($(CONFIG_FS_AUTOMOUNTER),y)
|
||||
CSRCS += k64_automount.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USBDEV),y)
|
||||
CSRCS += k64_usbdev.c
|
||||
endif
|
||||
|
@ -53,9 +53,10 @@
|
||||
|
||||
/* Assume we have everything */
|
||||
|
||||
#define HAVE_PROC 1
|
||||
#define NSH_HAVEUSBDEV 1
|
||||
#define NSH_HAVEMMCSD 1
|
||||
#define HAVE_PROC 1
|
||||
#define HAVE_MMCSD 1
|
||||
#define HAVE_AUTOMOUNTER 1
|
||||
#define HAVE_USBDEV 1
|
||||
|
||||
/* Automount procfs */
|
||||
|
||||
@ -83,12 +84,18 @@
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_DISABLE_MOUNTPOINT) || !defined(CONFIG_KINETIS_SDHC)
|
||||
# undef NSH_HAVEMMCSD
|
||||
# undef HAVE_MMCSD
|
||||
#endif
|
||||
|
||||
#ifdef NSH_HAVEMMCSD
|
||||
#ifdef HAVE_MMCSD
|
||||
# if defined(CONFIG_NSH_MMCSDSLOTNO) && CONFIG_NSH_MMCSDSLOTNO != 0
|
||||
# error "Only one MMC/SD slot, slot 0"
|
||||
# error Only one MMC/SD slot, slot 0
|
||||
# endif
|
||||
|
||||
# ifdef CONFIG_NSH_MMCSDMINOR
|
||||
# define MMSCD_MINOR CONFIG_NSH_MMCSDMINOR
|
||||
# else
|
||||
# define MMSCD_MINOR 0
|
||||
# endif
|
||||
|
||||
/* We expect to receive GPIO interrupts for card insertion events */
|
||||
@ -100,12 +107,49 @@
|
||||
# ifndef CONFIG_KINETIS_PORTEINTS
|
||||
# error "CONFIG_KINETIS_PORTEINTS required for card detect interrupt"
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Automounter */
|
||||
|
||||
#if !defined(CONFIG_FS_AUTOMOUNTER) || !defined(HAVE_MMCSD)
|
||||
# undef HAVE_AUTOMOUNTER
|
||||
# undef CONFIG_FRDMK64F_SDHC_AUTOMOUNT
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_FRDMK64F_SDHC_AUTOMOUNT
|
||||
# undef HAVE_AUTOMOUNTER
|
||||
#endif
|
||||
|
||||
/* Automounter defaults */
|
||||
|
||||
#ifdef HAVE_AUTOMOUNTER
|
||||
|
||||
# ifndef CONFIG_FRDMK64F_SDHC_AUTOMOUNT_FSTYPE
|
||||
# define CONFIG_FRDMK64F_SDHC_AUTOMOUNT_FSTYPE "vfat"
|
||||
# endif
|
||||
|
||||
# ifndef CONFIG_FRDMK64F_SDHC_AUTOMOUNT_BLKDEV
|
||||
# define CONFIG_FRDMK64F_SDHC_AUTOMOUNT_BLKDEV "/dev/mmcds0"
|
||||
# endif
|
||||
|
||||
# ifndef CONFIG_FRDMK64F_SDHC_AUTOMOUNT_MOUNTPOINT
|
||||
# define CONFIG_FRDMK64F_SDHC_AUTOMOUNT_MOUNTPOINT "/mnt/sdcard"
|
||||
# endif
|
||||
|
||||
# ifndef CONFIG_FRDMK64F_SDHC_AUTOMOUNT_DDELAY
|
||||
# define CONFIG_FRDMK64F_SDHC_AUTOMOUNT_DDELAY 1000
|
||||
# endif
|
||||
|
||||
# ifndef CONFIG_FRDMK64F_SDHC_AUTOMOUNT_UDELAY
|
||||
# define CONFIG_FRDMK64F_SDHC_AUTOMOUNT_UDELAY 2000
|
||||
# endif
|
||||
#endif /* HAVE_AUTOMOUNTER */
|
||||
|
||||
/* Can't support USB features if USB is not enabled */
|
||||
|
||||
#ifndef CONFIG_USBDEV
|
||||
# undef NSH_HAVEUSBDEV
|
||||
# undef HAVE_USBDEV
|
||||
#endif
|
||||
|
||||
/* How many SPI modules does this chip support? The LM3S6918 supports 2 SPI
|
||||
@ -126,6 +170,18 @@
|
||||
* format SD memory cards. The SD card detect pin (PTE6) is an open switch that
|
||||
* shorts with VDD when card is inserted.
|
||||
*
|
||||
* ------------ ------------- --------
|
||||
* SD Card Slot Board Signal K64F Pin
|
||||
* ------------ ------------- --------
|
||||
* DAT0 SDHC0_D0 PTE0
|
||||
* DAT1 SDHC0_D1 PTE1
|
||||
* DAT2 SDHC0_D2 PTE5
|
||||
* CD/DAT3 SDHC0_D3 PTE4
|
||||
* CMD SDHC0_CMD PTE3
|
||||
* CLK SDHC0_DCLK PTE2
|
||||
* SWITCH D_CARD_DETECT PTE6
|
||||
* ------------ ------------- --------
|
||||
*
|
||||
* There is no Write Protect pin available to the K64F.
|
||||
*/
|
||||
|
||||
@ -200,5 +256,89 @@ void weak_function k64_usbinitialize(void);
|
||||
int k64_bringup(void);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: k64_sdhc_initialize
|
||||
*
|
||||
* Description:
|
||||
* Inititialize the SDHC SD card slot
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef HAVE_MMCSD
|
||||
int k64_sdhc_initialize(void);
|
||||
#else
|
||||
# define k64_sdhc_initialize() (OK)
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: k64_cardinserted
|
||||
*
|
||||
* Description:
|
||||
* Check if a card is inserted into the SDHC slot
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef HAVE_AUTOMOUNTER
|
||||
bool k64_cardinserted(void);
|
||||
#else
|
||||
# define k64_cardinserted() (false)
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: k64_writeprotected
|
||||
*
|
||||
* Description:
|
||||
* Check if the card in the MMC/SD slot is write protected
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef HAVE_AUTOMOUNTER
|
||||
bool k64_writeprotected(void);
|
||||
#else
|
||||
# define k64_writeprotected() (false)
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: k64_automount_initialize
|
||||
*
|
||||
* Description:
|
||||
* Configure auto-mounter for the configured SDHC slot
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef HAVE_AUTOMOUNTER
|
||||
void k64_automount_initialize(void);
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: k64_automount_event
|
||||
*
|
||||
* Description:
|
||||
* The SDHC card detection logic has detected an insertion or removal event. It
|
||||
* has already scheduled the MMC/SD block driver operations. Now we need to
|
||||
* schedule the auto-mount event which will occur with a substantial delay to make
|
||||
* sure that everything has settle down.
|
||||
*
|
||||
* Input Parameters:
|
||||
* inserted - True if the card is inserted in the slot. False otherwise.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Interrupts are disabled.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef HAVE_AUTOMOUNTER
|
||||
void k64_automount_event(bool inserted);
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __CONFIGS_FREEDOM_K64F_SRC_FREEDOM_K64F_H */
|
||||
|
322
configs/freedom-k64f/src/k64_automount.c
Normal file
322
configs/freedom-k64f/src/k64_automount.c
Normal file
@ -0,0 +1,322 @@
|
||||
/************************************************************************************
|
||||
* configs/freedom-k64f/src/k64_automount.c
|
||||
*
|
||||
* Copyright (C) 2016 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>
|
||||
|
||||
#if defined(CONFIG_FS_AUTOMOUNTER_DEBUG) && !defined(CONFIG_DEBUG_FS)
|
||||
# define CONFIG_DEBUG_FS 1
|
||||
#endif
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/clock.h>
|
||||
#include <nuttx/fs/automount.h>
|
||||
|
||||
#include "freedom-k64f.h"
|
||||
|
||||
#ifdef HAVE_AUTOMOUNTER
|
||||
|
||||
/************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
|
||||
#ifndef NULL
|
||||
# define NULL (FAR void *)0
|
||||
#endif
|
||||
|
||||
#ifndef OK
|
||||
# define OK 0
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Private Types
|
||||
************************************************************************************/
|
||||
/* This structure represents the changeable state of the automounter */
|
||||
|
||||
struct k64_automount_state_s
|
||||
{
|
||||
volatile automount_handler_t handler; /* Upper half handler */
|
||||
FAR void *arg; /* Handler argument */
|
||||
bool enable; /* Fake interrupt enable */
|
||||
bool pending; /* Set if there an event while disabled */
|
||||
};
|
||||
|
||||
/* This structure represents the static configuration of an automounter */
|
||||
|
||||
struct k64_automount_config_s
|
||||
{
|
||||
/* This must be first thing in structure so that we can simply cast from struct
|
||||
* automount_lower_s to struct k64_automount_config_s
|
||||
*/
|
||||
|
||||
struct automount_lower_s lower; /* Publicly visible part */
|
||||
FAR struct k64_automount_state_s *state; /* Changeable state */
|
||||
};
|
||||
|
||||
/************************************************************************************
|
||||
* Private Function Prototypes
|
||||
************************************************************************************/
|
||||
|
||||
static int k64_attach(FAR const struct automount_lower_s *lower,
|
||||
automount_handler_t isr, FAR void *arg);
|
||||
static void k64_enable(FAR const struct automount_lower_s *lower, bool enable);
|
||||
static bool k64_inserted(FAR const struct automount_lower_s *lower);
|
||||
|
||||
/************************************************************************************
|
||||
* Private Data
|
||||
************************************************************************************/
|
||||
|
||||
static struct k64_automount_state_s g_sdhc_state;
|
||||
static const struct k64_automount_config_s g_sdhc_config =
|
||||
{
|
||||
.lower =
|
||||
{
|
||||
.fstype = CONFIG_FRDMK64F_SDHC_AUTOMOUNT_FSTYPE,
|
||||
.blockdev = CONFIG_FRDMK64F_SDHC_AUTOMOUNT_BLKDEV,
|
||||
.mountpoint = CONFIG_FRDMK64F_SDHC_AUTOMOUNT_MOUNTPOINT,
|
||||
.ddelay = MSEC2TICK(CONFIG_FRDMK64F_SDHC_AUTOMOUNT_DDELAY),
|
||||
.udelay = MSEC2TICK(CONFIG_FRDMK64F_SDHC_AUTOMOUNT_UDELAY),
|
||||
.attach = k64_attach,
|
||||
.enable = k64_enable,
|
||||
.inserted = k64_inserted
|
||||
},
|
||||
.state = &g_sdhc_state
|
||||
};
|
||||
|
||||
/************************************************************************************
|
||||
* Private Functions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Name: k64_attach
|
||||
*
|
||||
* Description:
|
||||
* Attach a new SDHC event handler
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower - An instance of the auto-mounter lower half state structure
|
||||
* isr - The new event handler to be attach
|
||||
* arg - Client data to be provided when the event handler is invoked.
|
||||
*
|
||||
* Returned Value:
|
||||
* Always returns OK
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
static int k64_attach(FAR const struct automount_lower_s *lower,
|
||||
automount_handler_t isr, FAR void *arg)
|
||||
{
|
||||
FAR const struct k64_automount_config_s *config;
|
||||
FAR struct k64_automount_state_s *state;
|
||||
|
||||
/* Recover references to our structure */
|
||||
|
||||
config = (FAR struct k64_automount_config_s *)lower;
|
||||
DEBUGASSERT(config != NULL && config->state != NULL);
|
||||
|
||||
state = config->state;
|
||||
|
||||
/* Save the new handler info (clearing the handler first to eliminate race
|
||||
* conditions).
|
||||
*/
|
||||
|
||||
state->handler = NULL;
|
||||
state->pending = false;
|
||||
state->arg = arg;
|
||||
state->handler = isr;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: k64_enable
|
||||
*
|
||||
* Description:
|
||||
* Enable card insertion/removal event detection
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower - An instance of the auto-mounter lower half state structure
|
||||
* enable - True: enable event detection; False: disable
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
static void k64_enable(FAR const struct automount_lower_s *lower, bool enable)
|
||||
{
|
||||
FAR const struct k64_automount_config_s *config;
|
||||
FAR struct k64_automount_state_s *state;
|
||||
irqstate_t flags;
|
||||
|
||||
/* Recover references to our structure */
|
||||
|
||||
config = (FAR struct k64_automount_config_s *)lower;
|
||||
DEBUGASSERT(config != NULL && config->state != NULL);
|
||||
|
||||
state = config->state;
|
||||
|
||||
/* Save the fake enable setting */
|
||||
|
||||
flags = enter_critical_section();
|
||||
state->enable = enable;
|
||||
|
||||
/* Did an interrupt occur while interrupts were disabled? */
|
||||
|
||||
if (enable && state->pending)
|
||||
{
|
||||
/* Yes.. perform the fake interrupt if the interrutp is attached */
|
||||
|
||||
if (state->handler)
|
||||
{
|
||||
bool inserted = k64_cardinserted();
|
||||
(void)state->handler(&config->lower, state->arg, inserted);
|
||||
}
|
||||
|
||||
state->pending = false;
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: k64_inserted
|
||||
*
|
||||
* Description:
|
||||
* Check if a card is inserted into the slot.
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower - An instance of the auto-mounter lower half state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* True if the card is inserted; False otherwise
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
static bool k64_inserted(FAR const struct automount_lower_s *lower)
|
||||
{
|
||||
return k64_cardinserted();
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Name: k64_automount_initialize
|
||||
*
|
||||
* Description:
|
||||
* Configure auto-mounters for each enable and so configured SDHC
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
void k64_automount_initialize(void)
|
||||
{
|
||||
FAR void *handle;
|
||||
|
||||
finfo("Initializing automounter(s)\n");
|
||||
|
||||
/* Initialize the SDHC0 auto-mounter */
|
||||
|
||||
handle = automount_initialize(&g_sdhc_config.lower);
|
||||
if (!handle)
|
||||
{
|
||||
ferr("ERROR: Failed to initialize auto-mounter for SDHC0\n");
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: k64_automount_event
|
||||
*
|
||||
* Description:
|
||||
* The SDHC card detection logic has detected an insertion or removal event. It
|
||||
* has already scheduled the MMC/SD block driver operations. Now we need to
|
||||
* schedule the auto-mount event which will occur with a substantial delay to make
|
||||
* sure that everything has settle down.
|
||||
*
|
||||
* Input Parameters:
|
||||
* slotno - Identifies the SDHC0 slot: SDHC0_SLOTNO or SDHC1_SLOTNO. There is a
|
||||
* terminology problem here: Each SDHC supports two slots, slot A and slot B.
|
||||
* Only slot A is used. So this is not a really a slot, but an HSCMI peripheral
|
||||
* number.
|
||||
* inserted - True if the card is inserted in the slot. False otherwise.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Interrupts are disabled.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
void k64_automount_event(bool inserted)
|
||||
{
|
||||
FAR const struct k64_automount_config_s *config = &g_sdhc_config;
|
||||
FAR struct k64_automount_state_s *state = &g_sdhc_state;
|
||||
|
||||
/* Is the auto-mounter interrupt attached? */
|
||||
|
||||
if (state->handler)
|
||||
{
|
||||
/* Yes.. Have we been asked to hold off interrupts? */
|
||||
|
||||
if (!state->enable)
|
||||
{
|
||||
/* Yes.. just remember the there is a pending interrupt. We will
|
||||
* deliver the interrupt when interrupts are "re-enabled."
|
||||
*/
|
||||
|
||||
state->pending = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No.. forward the event to the handler */
|
||||
|
||||
(void)state->handler(&config->lower, state->arg, inserted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_AUTOMOUNTER */
|
@ -39,112 +39,27 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#ifdef CONFIG_KINETIS_SDHC
|
||||
# include <nuttx/sdio.h>
|
||||
# include <nuttx/mmcsd.h>
|
||||
#endif
|
||||
|
||||
#include "kinetis.h"
|
||||
#include "freedom-k64f.h"
|
||||
|
||||
#if defined(CONFIG_LIB_BOARDCTL) || defined(CONFIG_BOARD_INITIALIZE)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* This structure encapsulates the global variable used in this file and
|
||||
* reduces the probability of name collistions.
|
||||
*/
|
||||
|
||||
#ifdef NSH_HAVEMMCSD
|
||||
struct k64_nsh_s
|
||||
{
|
||||
FAR struct sdio_dev_s *sdhc; /* SDIO driver handle */
|
||||
bool inserted; /* True: card is inserted */
|
||||
};
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef NSH_HAVEMMCSD
|
||||
static struct k64_nsh_s g_nsh;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: k64_mediachange
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef NSH_HAVEMMCSD
|
||||
static void k64_mediachange(void)
|
||||
{
|
||||
bool inserted;
|
||||
|
||||
/* Get the current value of the card detect pin. This pin is pulled up on
|
||||
* board. So low means that a card is present.
|
||||
*/
|
||||
|
||||
inserted = !kinetis_gpioread(GPIO_SD_CARDDETECT);
|
||||
|
||||
/* Has the pin changed state? */
|
||||
|
||||
if (inserted != g_nsh.inserted)
|
||||
{
|
||||
/* Yes.. perform the appropriate action (this might need some debounce). */
|
||||
|
||||
g_nsh.inserted = inserted;
|
||||
sdhc_mediachange(g_nsh.sdhc, inserted);
|
||||
|
||||
/* If the card has been inserted, then check if it is write protected
|
||||
* as well. The pin is pulled up, but apparently logic high means
|
||||
* write protected.
|
||||
*/
|
||||
|
||||
if (inserted)
|
||||
{
|
||||
sdhc_wrprotect(g_nsh.sdhc, kinetis_gpioread(GPIO_SD_WRPROTECT));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: k64_cdinterrupt
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef NSH_HAVEMMCSD
|
||||
static int k64_cdinterrupt(int irq, FAR void *context)
|
||||
{
|
||||
/* All of the work is done by k64_mediachange() */
|
||||
|
||||
k64_mediachange();
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: k64_bringup
|
||||
*
|
||||
* Description:
|
||||
* Bring up board features
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
int k64_bringup(void)
|
||||
{
|
||||
@ -165,52 +80,40 @@ int k64_bringup(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NSH_HAVEMMCSD
|
||||
/* Configure GPIO pins */
|
||||
#ifdef HAVE_MMCSD
|
||||
/* Initialize the SDHC driver */
|
||||
|
||||
/* Attached the card detect interrupt (but don't enable it yet) */
|
||||
|
||||
kinetis_pinconfig(GPIO_SD_CARDDETECT);
|
||||
kinetis_pinirqattach(GPIO_SD_CARDDETECT, k64_cdinterrupt);
|
||||
|
||||
/* Configure the write protect GPIO */
|
||||
|
||||
//kinetis_pinconfig(GPIO_SD_WRPROTECT);
|
||||
|
||||
/* Mount the SDHC-based MMC/SD block driver */
|
||||
/* First, get an instance of the SDHC interface */
|
||||
|
||||
syslog(LOG_INFO, "Initializing SDHC slot %d\n", MMCSD_SLOTNO);
|
||||
|
||||
g_nsh.sdhc = sdhc_initialize(MMCSD_SLOTNO);
|
||||
if (!g_nsh.sdhc)
|
||||
ret = k64_sdhc_initialize();
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: Failed to initialize SDHC slot %d\n",
|
||||
MMCSD_SLOTNO);
|
||||
return -ENODEV;
|
||||
mcerr("ERROR: k64_sdhc_initialize() failed: %d\n", ret);
|
||||
}
|
||||
|
||||
/* Now bind the SDHC interface to the MMC/SD driver */
|
||||
|
||||
syslog(LOG_INFO, "Bind SDHC to the MMC/SD driver, minor=%d\n",
|
||||
CONFIG_NSH_MMCSDMINOR);
|
||||
|
||||
ret = mmcsd_slotinitialize(CONFIG_NSH_MMCSDMINOR, g_nsh.sdhc);
|
||||
if (ret != OK)
|
||||
#ifdef CONFIG_FRDMK64F_SDHC_MOUNT
|
||||
else
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: Failed to bind SDHC to the MMC/SD driver: %d\n", ret);
|
||||
return ret;
|
||||
/* REVISIT: A delay seems to be required here or the mount will fail. */
|
||||
/* Mount the volume on HSMCI0 */
|
||||
|
||||
ret = mount(CONFIG_FRDMK64F_SDHC_MOUNT_BLKDEV,
|
||||
CONFIG_FRDMK64F_SDHC_MOUNT_MOUNTPOINT,
|
||||
CONFIG_FRDMK64F_SDHC_MOUNT_FSTYPE,
|
||||
0, NULL);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
mcerr("ERROR: Failed to mount %s: %d\n",
|
||||
CONFIG_FRDMK64F_SDHC_MOUNT_MOUNTPOINT, errno);
|
||||
}
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "Successfully bound SDHC to the MMC/SD driver\n");
|
||||
#endif /* CONFIG_FRDMK64F_SDHC_MOUNT */
|
||||
#endif /* HAVE_MMCSD */
|
||||
|
||||
/* Handle the initial card state */
|
||||
#ifdef HAVE_AUTOMOUNTER
|
||||
/* Initialize the auto-mounter */
|
||||
|
||||
k64_mediachange();
|
||||
|
||||
/* Enable CD interrupts to handle subsequent media changes */
|
||||
|
||||
kinetis_pinirqenable(GPIO_SD_CARDDETECT);
|
||||
k64_automount_initialize();
|
||||
#endif
|
||||
|
||||
UNUSED(ret);
|
||||
|
251
configs/freedom-k64f/src/k64_sdhc.c
Normal file
251
configs/freedom-k64f/src/k64_sdhc.c
Normal file
@ -0,0 +1,251 @@
|
||||
/****************************************************************************
|
||||
* config/freedom-k64f/src/k64_sdhc.c
|
||||
*
|
||||
* Copyright (C) 2016 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* A micro Secure Digital (SD) card slot is available on the FRDM-K64F connected to
|
||||
* the SD Host Controller (SDHC) signals of the MCU. This slot will accept micro
|
||||
* format SD memory cards. The SD card detect pin (PTE6) is an open switch that
|
||||
* shorts with VDD when card is inserted.
|
||||
*
|
||||
* ------------ ------------- --------
|
||||
* SD Card Slot Board Signal K64F Pin
|
||||
* ------------ ------------- --------
|
||||
* DAT0 SDHC0_D0 PTE0
|
||||
* DAT1 SDHC0_D1 PTE1
|
||||
* DAT2 SDHC0_D2 PTE5
|
||||
* CD/DAT3 SDHC0_D3 PTE4
|
||||
* CMD SDHC0_CMD PTE3
|
||||
* CLK SDHC0_DCLK PTE2
|
||||
* SWITCH D_CARD_DETECT PTE6
|
||||
* ------------ ------------- --------
|
||||
*
|
||||
* There is no Write Protect pin available to the K64F.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/sdio.h>
|
||||
#include <nuttx/mmcsd.h>
|
||||
|
||||
#include "kinetis.h"
|
||||
|
||||
#include "freedom-k64f.h"
|
||||
|
||||
#ifdef HAVE_MMCSD
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
/* This structure holds static information unique to one SDHC peripheral */
|
||||
|
||||
struct k64_sdhc_state_s
|
||||
{
|
||||
struct sdio_dev_s *sdhc; /* R/W device handle */
|
||||
bool inserted; /* TRUE: card is inserted */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* HSCMI device state */
|
||||
|
||||
static struct k64_sdhc_state_s g_sdhc;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: k64_mediachange
|
||||
****************************************************************************/
|
||||
|
||||
static void k64_mediachange(void)
|
||||
{
|
||||
bool inserted;
|
||||
|
||||
/* Get the current value of the card detect pin. This pin is pulled up on
|
||||
* board. So low means that a card is present.
|
||||
*/
|
||||
|
||||
inserted = !kinetis_gpioread(GPIO_SD_CARDDETECT);
|
||||
mcinfo("inserted: %s\n", inserted ? "Yes" : "No");
|
||||
|
||||
/* Has the pin changed state? */
|
||||
|
||||
if (inserted != g_sdhc.inserted)
|
||||
{
|
||||
mcinfo("Media change: %d->%d\n", g_sdhc.inserted, inserted);
|
||||
|
||||
/* Yes.. perform the appropriate action (this might need some debounce). */
|
||||
|
||||
g_sdhc.inserted = inserted;
|
||||
sdhc_mediachange(g_sdhc.sdhc, inserted);
|
||||
|
||||
#ifdef CONFIG_FRDMK64F_SDHC_AUTOMOUNT
|
||||
/* Let the automounter know about the insertion event */
|
||||
|
||||
k64_automount_event(k64_cardinserted());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: k64_cdinterrupt
|
||||
****************************************************************************/
|
||||
|
||||
static int k64_cdinterrupt(int irq, FAR void *context)
|
||||
{
|
||||
/* All of the work is done by k64_mediachange() */
|
||||
|
||||
k64_mediachange();
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: k64_sdhc_initialize
|
||||
*
|
||||
* Description:
|
||||
* Inititialize the SDHC SD card slot
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int k64_sdhc_initialize(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Configure GPIO pins */
|
||||
|
||||
kinetis_pinconfig(GPIO_SD_CARDDETECT);
|
||||
|
||||
/* Attached the card detect interrupt (but don't enable it yet) */
|
||||
|
||||
kinetis_pinirqattach(GPIO_SD_CARDDETECT, k64_cdinterrupt);
|
||||
|
||||
/* Configure the write protect GPIO -- None */
|
||||
|
||||
/* Mount the SDHC-based MMC/SD block driver */
|
||||
/* First, get an instance of the SDHC interface */
|
||||
|
||||
mcinfo("Initializing SDHC slot %d\n", MMCSD_SLOTNO);
|
||||
|
||||
g_sdhc.sdhc = sdhc_initialize(MMCSD_SLOTNO);
|
||||
if (!g_sdhc.sdhc)
|
||||
{
|
||||
mcerr("ERROR: Failed to initialize SDHC slot %d\n", MMCSD_SLOTNO);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Now bind the SDHC interface to the MMC/SD driver */
|
||||
|
||||
mcinfo("Bind SDHC to the MMC/SD driver, minor=%d\n", MMSCD_MINOR);
|
||||
|
||||
ret = mmcsd_slotinitialize(MMSCD_MINOR, g_sdhc.sdhc);
|
||||
if (ret != OK)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: Failed to bind SDHC to the MMC/SD driver: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "Successfully bound SDHC to the MMC/SD driver\n");
|
||||
|
||||
/* Handle the initial card state */
|
||||
|
||||
k64_mediachange();
|
||||
|
||||
/* Enable CD interrupts to handle subsequent media changes */
|
||||
|
||||
kinetis_pinirqenable(GPIO_SD_CARDDETECT);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: k64_cardinserted
|
||||
*
|
||||
* Description:
|
||||
* Check if a card is inserted into the SDHC slot
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef HAVE_AUTOMOUNTER
|
||||
bool k64_cardinserted(void)
|
||||
{
|
||||
bool inserted;
|
||||
|
||||
/* Get the current value of the card detect pin. This pin is pulled up on
|
||||
* board. So low means that a card is present.
|
||||
*/
|
||||
|
||||
inserted = !kinetis_gpioread(GPIO_SD_CARDDETECT);
|
||||
mcinfo("inserted: %s\n", inserted ? "Yes" : "No");
|
||||
return inserted;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: k64_writeprotected
|
||||
*
|
||||
* Description:
|
||||
* Check if a card is inserted into the SDHC slot
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef HAVE_AUTOMOUNTER
|
||||
bool k64_writeprotected(void)
|
||||
{
|
||||
/* There are no write protect pins */
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_MMCSD */
|
@ -129,7 +129,7 @@ bool sam_cardinserted_internal(struct sam_hsmci_state_s *state)
|
||||
/* Get the state of the PIO pin */
|
||||
|
||||
inserted = sam_gpioread(state->cdcfg);
|
||||
finfo("Slot %d inserted: %s\n", state->slotno, inserted ? "NO" : "YES");
|
||||
mcinfo("Slot %d inserted: %s\n", state->slotno, inserted ? "NO" : "YES");
|
||||
return !inserted;
|
||||
}
|
||||
|
||||
@ -221,12 +221,12 @@ int sam_hsmci_initialize(int slotno, int minor)
|
||||
struct sam_hsmci_state_s *state;
|
||||
int ret;
|
||||
|
||||
/* Get the static HSMI description */
|
||||
/* Get the static HSMCI description */
|
||||
|
||||
state = sam_hsmci_state(slotno);
|
||||
if (!state)
|
||||
{
|
||||
ferr("ERROR: No state for slotno %d\n", slotno);
|
||||
mcerr("ERROR: No state for slotno %d\n", slotno);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -247,7 +247,7 @@ int sam_hsmci_initialize(int slotno, int minor)
|
||||
state->hsmci = sdio_initialize(slotno);
|
||||
if (!state->hsmci)
|
||||
{
|
||||
ferr("ERROR: Failed to initialize SDIO slot %d\n", slotno);
|
||||
mcerr("ERROR: Failed to initialize SDIO slot %d\n", slotno);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@ -256,7 +256,7 @@ int sam_hsmci_initialize(int slotno, int minor)
|
||||
ret = mmcsd_slotinitialize(minor, state->hsmci);
|
||||
if (ret != OK)
|
||||
{
|
||||
ferr("ERROR: Failed to bind SDIO to the MMC/SD driver: %d\n", ret);
|
||||
mcerr("ERROR: Failed to bind SDIO to the MMC/SD driver: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -293,7 +293,7 @@ bool sam_cardinserted(int slotno)
|
||||
state = sam_hsmci_state(slotno);
|
||||
if (!state)
|
||||
{
|
||||
ferr("ERROR: No state for slotno %d\n", slotno);
|
||||
mcerr("ERROR: No state for slotno %d\n", slotno);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -171,7 +171,7 @@ static int mmcsd_getSCR(FAR struct mmcsd_state_s *priv, uint32_t scr[2]);
|
||||
|
||||
static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv,
|
||||
uint32_t csd[4]);
|
||||
#if defined(CONFIG_DEBUG_FEATURES) && defined (CONFIG_DEBUG_INFO) && defined(CONFIG_DEBUG_FS)
|
||||
#ifdef CONFIG_DEBUG_FS_INFO
|
||||
static void mmcsd_decodeCID(FAR struct mmcsd_state_s *priv,
|
||||
uint32_t cid[4]);
|
||||
#else
|
||||
@ -558,7 +558,7 @@ static int mmcsd_getSCR(FAR struct mmcsd_state_s *priv, uint32_t scr[2])
|
||||
|
||||
static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
|
||||
{
|
||||
#if defined(CONFIG_DEBUG_FEATURES) && defined (CONFIG_DEBUG_INFO) && defined(CONFIG_DEBUG_FS)
|
||||
#ifdef CONFIG_DEBUG_FS_INFO
|
||||
struct mmcsd_csd_s decoded;
|
||||
#endif
|
||||
unsigned int readbllen;
|
||||
@ -578,7 +578,7 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
|
||||
* TRANSFER_RATE_UNIT 2:0 Rate mantissa
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_DEBUG_FEATURES) && defined (CONFIG_DEBUG_INFO) && defined(CONFIG_DEBUG_FS)
|
||||
#ifdef CONFIG_DEBUG_FS_INFO
|
||||
memset(&decoded, 0, sizeof(struct mmcsd_csd_s));
|
||||
decoded.csdstructure = csd[0] >> 30;
|
||||
decoded.mmcspecvers = (csd[0] >> 26) & 0x0f;
|
||||
@ -606,7 +606,7 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
|
||||
priv->dsrimp = (csd[1] >> 12) & 1;
|
||||
readbllen = (csd[1] >> 16) & 0x0f;
|
||||
|
||||
#if defined(CONFIG_DEBUG_FEATURES) && defined (CONFIG_DEBUG_INFO) && defined(CONFIG_DEBUG_FS)
|
||||
#ifdef CONFIG_DEBUG_FS_INFO
|
||||
decoded.ccc = (csd[1] >> 20) & 0x0fff;
|
||||
decoded.readbllen = (csd[1] >> 16) & 0x0f;
|
||||
decoded.readblpartial = (csd[1] >> 15) & 1;
|
||||
@ -667,7 +667,7 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
|
||||
priv->blocksize = 1 << 9;
|
||||
priv->nblocks = priv->capacity >> 9;
|
||||
|
||||
#if defined(CONFIG_DEBUG_FEATURES) && defined (CONFIG_DEBUG_INFO) && defined(CONFIG_DEBUG_FS)
|
||||
#ifdef CONFIG_DEBUG_FS_INFO
|
||||
decoded.u.sdblock.csize = csize;
|
||||
decoded.u.sdblock.sderblen = (csd[2] >> 14) & 1;
|
||||
decoded.u.sdblock.sdsectorsize = (csd[2] >> 7) & 0x7f;
|
||||
@ -703,7 +703,7 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
|
||||
priv->blockshift = 9;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DEBUG_FEATURES) && defined (CONFIG_DEBUG_INFO) && defined(CONFIG_DEBUG_FS)
|
||||
#ifdef CONFIG_DEBUG_FS_INFO
|
||||
if (IS_SD(priv->type))
|
||||
{
|
||||
decoded.u.sdbyte.csize = csize;
|
||||
@ -753,7 +753,7 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
|
||||
tmpwriteprotect = (csd[3] >> 12) & 1;
|
||||
priv->wrprotect = (permwriteprotect || tmpwriteprotect);
|
||||
|
||||
#if defined(CONFIG_DEBUG_FEATURES) && defined (CONFIG_DEBUG_INFO) && defined(CONFIG_DEBUG_FS)
|
||||
#ifdef CONFIG_DEBUG_FS_INFO
|
||||
decoded.wpgrpen = csd[3] >> 31;
|
||||
decoded.mmcdfltecc = (csd[3] >> 29) & 3;
|
||||
decoded.r2wfactor = (csd[3] >> 26) & 7;
|
||||
@ -844,7 +844,7 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_DEBUG_FEATURES) && defined (CONFIG_DEBUG_INFO) && defined(CONFIG_DEBUG_FS)
|
||||
#ifdef CONFIG_DEBUG_FS_INFO
|
||||
static void mmcsd_decodeCID(FAR struct mmcsd_state_s *priv, uint32_t cid[4])
|
||||
{
|
||||
struct mmcsd_cid_s decoded;
|
||||
@ -910,7 +910,7 @@ static void mmcsd_decodeCID(FAR struct mmcsd_state_s *priv, uint32_t cid[4])
|
||||
|
||||
static void mmcsd_decodeSCR(FAR struct mmcsd_state_s *priv, uint32_t scr[2])
|
||||
{
|
||||
#if defined(CONFIG_DEBUG_FEATURES) && defined (CONFIG_DEBUG_INFO) && defined(CONFIG_DEBUG_FS)
|
||||
#ifdef CONFIG_DEBUG_FS_INFO
|
||||
struct mmcsd_scr_s decoded;
|
||||
#endif
|
||||
|
||||
@ -923,14 +923,14 @@ struct mmcsd_scr_s decoded;
|
||||
* Reserved 47:32 16-bit SD reserved space
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ENDIAN_BIG /* Card transfers SCR in big-endian order */
|
||||
#ifdef CONFIG_ENDIAN_BIG /* Card transfers SCR in big-endian order */
|
||||
priv->buswidth = (scr[0] >> 16) & 15;
|
||||
#else
|
||||
priv->buswidth = (scr[0] >> 8) & 15;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_DEBUG_FEATURES) && defined (CONFIG_DEBUG_INFO) && defined(CONFIG_DEBUG_FS)
|
||||
#ifdef CONFIG_ENDIAN_BIG /* Card SCR is big-endian order / CPU also big-endian
|
||||
#ifdef CONFIG_DEBUG_FS_INFO
|
||||
#ifdef CONFIG_ENDIAN_BIG /* Card SCR is big-endian order / CPU also big-endian
|
||||
* 60 56 52 48 44 40 36 32
|
||||
* VVVV SSSS ESSS BBBB RRRR RRRR RRRR RRRR */
|
||||
decoded.scrversion = scr[0] >> 28;
|
||||
@ -952,7 +952,7 @@ struct mmcsd_scr_s decoded;
|
||||
* Reserved 31:0 32-bits reserved for manufacturing usage.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_DEBUG_FEATURES) && defined (CONFIG_DEBUG_INFO) && defined(CONFIG_DEBUG_FS)
|
||||
#ifdef CONFIG_DEBUG_FS_INFO
|
||||
decoded.mfgdata = scr[1]; /* Might be byte reversed! */
|
||||
|
||||
finfo("SCR:\n");
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Sector Mapped Allocation for Really Tiny (SMART) Flash block driver.
|
||||
*
|
||||
* Copyright (C) 2013-2015 Ken Pettit. All rights reserved.
|
||||
* Copyright (C) 2013-2016 Ken Pettit. All rights reserved.
|
||||
* Author: Ken Pettit <pettitkd@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -73,7 +73,7 @@
|
||||
#define SMART_STATUS_COMMITTED 0x80
|
||||
#define SMART_STATUS_RELEASED 0x40
|
||||
#define SMART_STATUS_CRC 0x20
|
||||
#define SMART_STATUS_SIZEBITS 0x1C
|
||||
#define SMART_STATUS_SIZEBITS 0x1c
|
||||
#define SMART_STATUS_VERBITS 0x03
|
||||
|
||||
#if defined(CONFIG_SMART_CRC_16)
|
||||
@ -87,7 +87,7 @@
|
||||
#define SMART_SECTSIZE_256 0x00
|
||||
#define SMART_SECTSIZE_512 0x04
|
||||
#define SMART_SECTSIZE_1024 0x08
|
||||
#define SMART_SECTSIZE_2048 0x0C
|
||||
#define SMART_SECTSIZE_2048 0x0c
|
||||
#define SMART_SECTSIZE_4096 0x10
|
||||
#define SMART_SECTSIZE_8192 0x14
|
||||
#define SMART_SECTSIZE_16384 0x18
|
||||
@ -134,7 +134,7 @@
|
||||
#define offsetof(type, member) ( (size_t) &( ( (type *) 0)->member))
|
||||
#endif
|
||||
|
||||
#define SMART_MAX_ALLOCS 6
|
||||
#define SMART_MAX_ALLOCS 10
|
||||
//#define CONFIG_MTD_SMART_PACK_COUNTS
|
||||
|
||||
#ifndef CONFIG_MTD_SMART_ALLOC_DEBUG
|
||||
@ -147,7 +147,7 @@
|
||||
#define SMART_WEAR_MIN_LEVEL 5
|
||||
#define SMART_WEAR_FORCE_REORG_THRESHOLD 1
|
||||
#define SMART_WEAR_BIT_DIVIDE 1
|
||||
#define SMART_WEAR_ZERO_MASK 0x0F
|
||||
#define SMART_WEAR_ZERO_MASK 0x0f
|
||||
#define SMART_WEAR_BLOCK_MASK 0x01
|
||||
|
||||
/* Bit mapping for wear level bits */
|
||||
@ -167,10 +167,10 @@
|
||||
|
||||
static const uint8_t gWearLevelToBitMap4[] =
|
||||
{
|
||||
0x0F, 0x0E, 0x0C, 0x08, /* Single bit erased (x3) */
|
||||
0x0f, 0x0e, 0x0c, 0x08, /* Single bit erased (x3) */
|
||||
0x07, 0x06, 0x04, 0x00, /* Single bit erased (x3) */
|
||||
0x0B, 0x0A, 0x02, /* Single bit erased (x2) */
|
||||
0x0D, 0x09, 0x01, /* Single bit erased (x2) */
|
||||
0x0b, 0x0a, 0x02, /* Single bit erased (x2) */
|
||||
0x0d, 0x09, 0x01, /* Single bit erased (x2) */
|
||||
0x03,
|
||||
0x05
|
||||
};
|
||||
@ -473,6 +473,18 @@ FAR static void *smart_malloc(FAR struct smart_struct_s *dev,
|
||||
FAR void *ret = kmm_malloc(bytes);
|
||||
uint8_t x;
|
||||
|
||||
/* Test if we are allocating the dev struct */
|
||||
|
||||
if (dev == NULL)
|
||||
{
|
||||
dev = ret;
|
||||
dev->bytesalloc = 0;
|
||||
for (x = 0; x < SMART_MAX_ALLOCS; x++)
|
||||
{
|
||||
dev->alloc[x].ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Keep track of the total allocation */
|
||||
|
||||
if (ret != NULL)
|
||||
@ -545,11 +557,11 @@ static void smart_set_count(FAR struct smart_struct_s *dev, FAR uint8_t *pCount,
|
||||
|
||||
if (block & 0x01)
|
||||
{
|
||||
pCount[block >> 1] = (pCount[block >> 1] & 0xF0) | (count & 0x0F);
|
||||
pCount[block >> 1] = (pCount[block >> 1] & 0xf0) | (count & 0x0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
pCount[block >> 1] = (pCount[block >> 1] & 0x0F) | ((count & 0x0F) << 4);
|
||||
pCount[block >> 1] = (pCount[block >> 1] & 0x0f) | ((count & 0x0f) << 4);
|
||||
}
|
||||
|
||||
/* If we have 16 sectors per block, then the upper bit (representing 16)
|
||||
@ -595,7 +607,7 @@ static uint8_t smart_get_count(FAR struct smart_struct_s *dev,
|
||||
|
||||
if (block & 0x01)
|
||||
{
|
||||
count = pCount[block >> 1] & 0x0F;
|
||||
count = pCount[block >> 1] & 0x0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -999,6 +1011,9 @@ static int smart_setsectorsize(FAR struct smart_struct_s *dev, uint16_t size)
|
||||
dev->sectorsize = size;
|
||||
dev->mtdBlksPerSector = dev->sectorsize / dev->geo.blocksize;
|
||||
|
||||
DEBUGASSERT(dev->sectorsize >= dev->geo.blocksize);
|
||||
DEBUGASSERT(erasesize / dev->sectorsize <= 256);
|
||||
|
||||
if (erasesize / dev->sectorsize > 256)
|
||||
{
|
||||
/* We can't throw a error message here becasue it is too early.
|
||||
@ -1051,7 +1066,7 @@ static int smart_setsectorsize(FAR struct smart_struct_s *dev, uint16_t size)
|
||||
}
|
||||
|
||||
dev->cache_entries = 0;
|
||||
dev->cache_lastlog = 0xFFFF;
|
||||
dev->cache_lastlog = 0xffff;
|
||||
dev->cache_nextbirth = 0;
|
||||
#endif
|
||||
|
||||
@ -1359,7 +1374,7 @@ static int smart_add_sector_to_cache(FAR struct smart_struct_s *dev,
|
||||
{
|
||||
/* Cache is full. We must find the least accessed entry and replace it */
|
||||
|
||||
oldest = 0xFFFF;
|
||||
oldest = 0xffff;
|
||||
for (x = 0; x < CONFIG_MTD_SMART_SECTOR_CACHE_SIZE; x++)
|
||||
{
|
||||
/* Never replace cache entries for system sectors */
|
||||
@ -1427,7 +1442,7 @@ static uint16_t smart_cache_lookup(FAR struct smart_struct_s *dev, uint16_t logi
|
||||
struct smart_sect_header_s header;
|
||||
size_t readaddress;
|
||||
|
||||
physical = 0xFFFF;
|
||||
physical = 0xffff;
|
||||
|
||||
/* Test if searching for the last sector used */
|
||||
|
||||
@ -1453,7 +1468,7 @@ static uint16_t smart_cache_lookup(FAR struct smart_struct_s *dev, uint16_t logi
|
||||
* for it and add it to the cache.
|
||||
*/
|
||||
|
||||
if (physical == 0xFFFF)
|
||||
if (physical == 0xffff)
|
||||
{
|
||||
/* Now scan the MTD device. Instead of scanning start to end, we
|
||||
* span the erase blocks and read one sector from each at a time.
|
||||
@ -1462,7 +1477,7 @@ static uint16_t smart_cache_lookup(FAR struct smart_struct_s *dev, uint16_t logi
|
||||
* numbers in each erase block first.
|
||||
*/
|
||||
|
||||
for (sector = 0; sector < dev->sectorsPerBlk && physical == 0xFFFF; sector++)
|
||||
for (sector = 0; sector < dev->availSectPerBlk && physical == 0xffff; sector++)
|
||||
{
|
||||
/* Now scan across each erase block */
|
||||
|
||||
@ -1566,7 +1581,7 @@ static void smart_update_cache(FAR struct smart_struct_s *dev, uint16_t
|
||||
* the cache.
|
||||
*/
|
||||
|
||||
if (physical == 0xFFFF)
|
||||
if (physical == 0xffff)
|
||||
{
|
||||
dev->sCache[x].logical = dev->sCache[dev->cache_entries-1].logical;
|
||||
dev->sCache[x].physical = dev->sCache[dev->cache_entries-1].physical;
|
||||
@ -1615,7 +1630,7 @@ static uint8_t smart_get_wear_level(FAR struct smart_struct_s *dev, uint16_t blo
|
||||
{
|
||||
/* Use the lower nibble */
|
||||
|
||||
bits &= 0x0F;
|
||||
bits &= 0x0f;
|
||||
}
|
||||
|
||||
/* Lookup and return the level using the BitToLevel map */
|
||||
@ -1732,14 +1747,14 @@ static int smart_set_wear_level(FAR struct smart_struct_s *dev, uint16_t block,
|
||||
{
|
||||
/* Use the upper nibble */
|
||||
|
||||
dev->wearstatus[block >> SMART_WEAR_BIT_DIVIDE] &= 0x0F;
|
||||
dev->wearstatus[block >> SMART_WEAR_BIT_DIVIDE] &= 0x0f;
|
||||
dev->wearstatus[block >> SMART_WEAR_BIT_DIVIDE] |= bits << 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use the lower nibble */
|
||||
|
||||
dev->wearstatus[block >> SMART_WEAR_BIT_DIVIDE] &= 0xF0;
|
||||
dev->wearstatus[block >> SMART_WEAR_BIT_DIVIDE] &= 0xf0;
|
||||
dev->wearstatus[block >> SMART_WEAR_BIT_DIVIDE] |= bits;
|
||||
}
|
||||
|
||||
@ -1817,10 +1832,10 @@ static int smart_scan(FAR struct smart_struct_s *dev)
|
||||
* a header and not sector data.
|
||||
*/
|
||||
|
||||
sectorsize = 0xFFFF;
|
||||
sectorsize = 0xffff;
|
||||
offset = 16384;
|
||||
|
||||
while (sectorsize == 0xFFFF)
|
||||
while (sectorsize == 0xffff)
|
||||
{
|
||||
readaddress = 0;
|
||||
|
||||
@ -1845,7 +1860,7 @@ static int smart_scan(FAR struct smart_struct_s *dev)
|
||||
}
|
||||
|
||||
offset >>= 1;
|
||||
if (offset < 256 && sectorsize == 0xFFFF)
|
||||
if (offset < 256 && sectorsize == 0xffff)
|
||||
{
|
||||
/* No valid sectors found on device. Default the
|
||||
* sector size to the CONFIG value
|
||||
@ -2074,7 +2089,7 @@ static int smart_scan(FAR struct smart_struct_s *dev)
|
||||
/* Test for duplicate logical sectors on the device */
|
||||
|
||||
#ifndef CONFIG_MTD_SMART_MINIMIZE_RAM
|
||||
if (dev->sMap[logicalsector] != 0xFFFF)
|
||||
if (dev->sMap[logicalsector] != 0xffff)
|
||||
#else
|
||||
if (dev->sBitMap[logicalsector >> 3] & (1 << (logicalsector & 0x07)))
|
||||
#endif
|
||||
@ -2184,7 +2199,7 @@ static int smart_scan(FAR struct smart_struct_s *dev)
|
||||
|
||||
/* Now determine who wins */
|
||||
|
||||
if ((seq1 > 0xFFF0 && seq2 < 10) || seq2 > seq1)
|
||||
if ((seq1 > 0xfff0 && seq2 < 10) || seq2 > seq1)
|
||||
{
|
||||
/* Seq 2 is the winner ... bigger or it wrapped */
|
||||
|
||||
@ -2212,7 +2227,7 @@ static int smart_scan(FAR struct smart_struct_s *dev)
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xFF
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xff
|
||||
header.status &= ~SMART_STATUS_RELEASED;
|
||||
#else
|
||||
header.status |= SMART_STATUS_RELEASED;
|
||||
@ -2248,7 +2263,7 @@ static int smart_scan(FAR struct smart_struct_s *dev)
|
||||
/* We need to check if we are converting an older format with incorrect
|
||||
* wear leveling data in sector zero to the new format. The old format
|
||||
* put all zeros in the wear level bit locations, but the new (better)
|
||||
* way is to leave them 0xFF.
|
||||
* way is to leave them 0xff.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_MTD_SMART_MINIMIZE_RAM
|
||||
@ -2259,7 +2274,7 @@ static int smart_scan(FAR struct smart_struct_s *dev)
|
||||
|
||||
/* Validate the sector is valid ... may be an unformatted device */
|
||||
|
||||
if (sector != 0xFFFF)
|
||||
if (sector != 0xffff)
|
||||
{
|
||||
/* Read the sector data */
|
||||
|
||||
@ -2276,11 +2291,11 @@ static int smart_scan(FAR struct smart_struct_s *dev)
|
||||
if (dev->rwbuffer[SMART_WEAR_LEVEL_FORMAT_SIG] == 0)
|
||||
{
|
||||
/* Old format detected. We must relocate sector zero and fill it
|
||||
* in with 0xFF.
|
||||
* in with 0xff.
|
||||
*/
|
||||
|
||||
uint16_t newsector = smart_findfreephyssector(dev, FALSE);
|
||||
if (newsector == 0xFFFF)
|
||||
if (newsector == 0xffff)
|
||||
{
|
||||
/* Unable to find a free sector!!! */
|
||||
|
||||
@ -2289,7 +2304,7 @@ static int smart_scan(FAR struct smart_struct_s *dev)
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
memset(&dev->rwbuffer[SMART_WEAR_LEVEL_FORMAT_SIG], 0xFF,
|
||||
memset(&dev->rwbuffer[SMART_WEAR_LEVEL_FORMAT_SIG], 0xff,
|
||||
dev->mtdBlksPerSector * dev->geo.blocksize -
|
||||
SMART_WEAR_LEVEL_FORMAT_SIG);
|
||||
|
||||
@ -2677,7 +2692,7 @@ static int smart_relocate_static_data(FAR struct smart_struct_s *dev, uint16_t b
|
||||
/* Get next sector from 'block' */
|
||||
|
||||
newsector = nextsector++;
|
||||
if (newsector == 0xFFFF)
|
||||
if (newsector == 0xffff)
|
||||
{
|
||||
/* Unable to find a free sector!!! */
|
||||
|
||||
@ -2903,7 +2918,7 @@ static inline int smart_llformat(FAR struct smart_struct_s *dev, unsigned long a
|
||||
|
||||
/* Set the sector logical sector to zero and setup the header status */
|
||||
|
||||
#if ( CONFIG_SMARTFS_ERASEDSTATE == 0xFF )
|
||||
#if ( CONFIG_SMARTFS_ERASEDSTATE == 0xff )
|
||||
*((FAR uint16_t *) sectorheader->logicalsector) = 0;
|
||||
sectorheader->status = (uint8_t) ~(SMART_STATUS_COMMITTED | SMART_STATUS_VERBITS |
|
||||
SMART_STATUS_SIZEBITS) | SMART_STATUS_VERSION |
|
||||
@ -2912,14 +2927,14 @@ static inline int smart_llformat(FAR struct smart_struct_s *dev, unsigned long a
|
||||
sectorheader->status &= ~SMART_STATUS_CRC;
|
||||
#endif /* CONFIG_MTD_SMART_ENABLE_CRC */
|
||||
|
||||
#else /* CONFIG_SMARTFS_ERASEDSTATE == 0xFF */
|
||||
*((FAR uint16_t *) sectorheader->logicalsector) = 0xFFFF;
|
||||
#else /* CONFIG_SMARTFS_ERASEDSTATE == 0xff */
|
||||
*((FAR uint16_t *) sectorheader->logicalsector) = 0xffff;
|
||||
sectorheader->status = (uint8_t) (SMART_STATUS_COMMITTED | SMART_STATUS_VERSION |
|
||||
sectsize);
|
||||
#ifdef CONFIG_MTD_SMART_ENABLE_CRC
|
||||
sectorheader->status |= SMART_STATUS_CRC;
|
||||
#endif /* CONFIG_MTD_SMART_ENABLE_CRC */
|
||||
#endif /* CONFIG_SMARTFS_ERASEDSTATE == 0xFF */
|
||||
#endif /* CONFIG_SMARTFS_ERASEDSTATE == 0xff */
|
||||
|
||||
/* Now add the format signature to the sector */
|
||||
|
||||
@ -2933,7 +2948,7 @@ static inline int smart_llformat(FAR struct smart_struct_s *dev, unsigned long a
|
||||
|
||||
/* Record the number of root directory entries we have */
|
||||
|
||||
dev->rwbuffer[SMART_FMT_ROOTDIRS_POS] = (uint8_t) (arg & 0xFF);
|
||||
dev->rwbuffer[SMART_FMT_ROOTDIRS_POS] = (uint8_t) (arg & 0xff);
|
||||
|
||||
#ifdef CONFIG_SMART_CRC_8
|
||||
sectorheader->crc8 = smart_calc_sector_crc(dev);
|
||||
@ -3059,7 +3074,7 @@ static int smart_relocate_sector(FAR struct smart_struct_s *dev,
|
||||
/* Using 8-bit sequence */
|
||||
|
||||
header->seq++;
|
||||
if (header->seq == 0xFF)
|
||||
if (header->seq == 0xff)
|
||||
{
|
||||
header->seq = 1;
|
||||
}
|
||||
@ -3070,7 +3085,7 @@ static int smart_relocate_sector(FAR struct smart_struct_s *dev,
|
||||
/* Using 16-bit sequence and no CRC */
|
||||
|
||||
(*((FAR uint16_t *) &header->seq))++;
|
||||
if (*((FAR uint16_t *) &header->seq) == 0xFFFF)
|
||||
if (*((FAR uint16_t *) &header->seq) == 0xffff)
|
||||
{
|
||||
*((FAR uint16_t *) &header->seq) = 1;
|
||||
}
|
||||
@ -3086,7 +3101,7 @@ static int smart_relocate_sector(FAR struct smart_struct_s *dev,
|
||||
|
||||
/* First pre-commit the sector */
|
||||
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xFF
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xff
|
||||
header->status &= ~(SMART_STATUS_COMMITTED | SMART_STATUS_CRC);
|
||||
#else
|
||||
header->status |= SMART_STATUS_COMMITTED | SMART_STATUS_CRC;
|
||||
@ -3109,7 +3124,7 @@ static int smart_relocate_sector(FAR struct smart_struct_s *dev,
|
||||
|
||||
#else /* CONFIG_MTD_SMART_ENABLE_CRC */
|
||||
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xFF
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xff
|
||||
header->status |= SMART_STATUS_COMMITTED;
|
||||
#else
|
||||
header->status &= ~SMART_STATUS_COMMITTED;
|
||||
@ -3124,7 +3139,7 @@ static int smart_relocate_sector(FAR struct smart_struct_s *dev,
|
||||
|
||||
offset = newsector * dev->mtdBlksPerSector * dev->geo.blocksize +
|
||||
offsetof(struct smart_sect_header_s, status);
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xFF
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xff
|
||||
newstatus = header->status & ~SMART_STATUS_COMMITTED;
|
||||
#else
|
||||
newstatus = header->status | SMART_STATUS_COMMITTED;
|
||||
@ -3139,7 +3154,7 @@ static int smart_relocate_sector(FAR struct smart_struct_s *dev,
|
||||
|
||||
/* Release the old physical sector */
|
||||
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xFF
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xff
|
||||
newstatus = header->status & ~(SMART_STATUS_RELEASED | SMART_STATUS_COMMITTED);
|
||||
#else
|
||||
newstatus = header->status | SMART_STATUS_RELEASED | SMART_STATUS_COMMITTED;
|
||||
@ -3267,7 +3282,7 @@ static int smart_relocate_block(FAR struct smart_struct_s *dev, uint16_t block)
|
||||
if (allocsector)
|
||||
{
|
||||
newsector = smart_findfreephyssector(dev, FALSE);
|
||||
if (newsector == 0xFFFF)
|
||||
if (newsector == 0xffff)
|
||||
{
|
||||
/* Unable to find a free sector!!! */
|
||||
|
||||
@ -3299,7 +3314,7 @@ static int smart_relocate_block(FAR struct smart_struct_s *dev, uint16_t block)
|
||||
/* Find a new sector where it can live, NOT in this erase block */
|
||||
|
||||
newsector = smart_findfreephyssector(dev, FALSE);
|
||||
if (newsector == 0xFFFF)
|
||||
if (newsector == 0xffff)
|
||||
{
|
||||
/* Unable to find a free sector!!! */
|
||||
|
||||
@ -3441,14 +3456,14 @@ static int smart_findfreephyssector(FAR struct smart_struct_s *dev,
|
||||
retry:
|
||||
#endif
|
||||
allocfreecount = 0;
|
||||
allocblock = 0xFFFF;
|
||||
allocblock = 0xffff;
|
||||
#ifdef CONFIG_MTD_SMART_WEAR_LEVEL
|
||||
wornfreecount = 0;
|
||||
wornblock = 0xFFFF;
|
||||
wornblock = 0xffff;
|
||||
wornlevel = 15;
|
||||
maxwearlevel = 0;
|
||||
#endif
|
||||
physicalsector = 0xFFFF;
|
||||
physicalsector = 0xffff;
|
||||
if (++dev->lastallocblock >= dev->neraseblocks)
|
||||
{
|
||||
dev->lastallocblock = 0;
|
||||
@ -3514,7 +3529,7 @@ retry:
|
||||
|
||||
/* Check if we found an allocblock. */
|
||||
|
||||
if (allocblock == 0xFFFF)
|
||||
if (allocblock == 0xffff)
|
||||
{
|
||||
/* No un-worn blocks with free sectors */
|
||||
|
||||
@ -3558,7 +3573,7 @@ retry:
|
||||
|
||||
/* Test if we found a worn block with free sectors */
|
||||
|
||||
if (wornblock != 0xFFFF)
|
||||
if (wornblock != 0xffff)
|
||||
{
|
||||
allocblock = wornblock;
|
||||
}
|
||||
@ -3624,9 +3639,9 @@ retry:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((*((FAR uint16_t *) header.logicalsector) == 0xFFFF) &&
|
||||
if ((*((FAR uint16_t *) header.logicalsector) == 0xffff) &&
|
||||
#if SMART_STATUS_VERSION == 1
|
||||
(*((FAR uint16_t *) &header.seq) == 0xFFFF) &&
|
||||
(*((FAR uint16_t *) &header.seq) == 0xffff) &&
|
||||
#else
|
||||
(header.seq == CONFIG_SMARTFS_ERASEDSTATE) &&
|
||||
#endif
|
||||
@ -3639,7 +3654,7 @@ retry:
|
||||
}
|
||||
}
|
||||
|
||||
if (physicalsector == 0xFFFF)
|
||||
if (physicalsector == 0xffff)
|
||||
{
|
||||
ferr("ERROR: Program bug! Expected a free sector\n");
|
||||
}
|
||||
@ -3700,7 +3715,7 @@ static int smart_garbagecollect(FAR struct smart_struct_s *dev)
|
||||
{
|
||||
/* Find the block with the most released sectors */
|
||||
|
||||
collectblock = 0xFFFF;
|
||||
collectblock = 0xffff;
|
||||
releasemax = 0;
|
||||
for (x = 0; x < dev->neraseblocks; x++)
|
||||
{
|
||||
@ -3731,7 +3746,7 @@ static int smart_garbagecollect(FAR struct smart_struct_s *dev)
|
||||
|
||||
//releasemax = smart_get_count(dev, dev->releasecount, collectblock);
|
||||
|
||||
if (collectblock == 0xFFFF)
|
||||
if (collectblock == 0xffff)
|
||||
{
|
||||
/* Need to collect, but no sectors with released blocks! */
|
||||
|
||||
@ -3801,7 +3816,7 @@ static int smart_write_wearstatus(struct smart_struct_s *dev)
|
||||
|
||||
sector = 0;
|
||||
remaining = dev->geo.neraseblocks >> 1;
|
||||
memset(buffer, 0xFF, sizeof(buffer));
|
||||
memset(buffer, 0xff, sizeof(buffer));
|
||||
|
||||
#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_SMARTFS)
|
||||
if (dev->blockerases > 0)
|
||||
@ -3932,8 +3947,8 @@ static inline int smart_read_wearstatus(FAR struct smart_struct_s *dev)
|
||||
|
||||
/* Check for erased state */
|
||||
|
||||
#if ( CONFIG_SMARTFS_ERASEDSTATE == 0xFF )
|
||||
if (dev->uneven_wearcount == 0xFFFFFFFF)
|
||||
#if ( CONFIG_SMARTFS_ERASEDSTATE == 0xff )
|
||||
if (dev->uneven_wearcount == 0xffffffff)
|
||||
{
|
||||
dev->uneven_wearcount = 0;
|
||||
}
|
||||
@ -3943,8 +3958,8 @@ static inline int smart_read_wearstatus(FAR struct smart_struct_s *dev)
|
||||
/* Get the block erases count */
|
||||
|
||||
dev->blockerases = *((uint32_t *) buffer);
|
||||
#if ( CONFIG_SMARTFS_ERASEDSTATE == 0xFF )
|
||||
if (dev->blockerases == 0xFFFFFFFF)
|
||||
#if ( CONFIG_SMARTFS_ERASEDSTATE == 0xff )
|
||||
if (dev->blockerases == 0xffffffff)
|
||||
{
|
||||
dev->blockerases = 0;
|
||||
}
|
||||
@ -3979,7 +3994,7 @@ static inline int smart_read_wearstatus(FAR struct smart_struct_s *dev)
|
||||
#else
|
||||
physsector = smart_cache_lookup(dev, req.logsector);
|
||||
#endif
|
||||
if ((sector != 0) && (physsector == 0xFFFF))
|
||||
if ((sector != 0) && (physsector == 0xffff))
|
||||
{
|
||||
#ifdef CONFIG_FS_WRITABLE
|
||||
|
||||
@ -4073,7 +4088,7 @@ static int smart_write_alloc_sector(FAR struct smart_struct_s *dev,
|
||||
#endif
|
||||
sectsize = dev->sectorsize >> 7;
|
||||
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xFF
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xff
|
||||
header->status = ~(SMART_STATUS_COMMITTED | SMART_STATUS_SIZEBITS |
|
||||
SMART_STATUS_VERBITS) | SMART_STATUS_VERSION | sectsize;
|
||||
#ifdef CONFIG_MTD_SMART_ENABLE_CRC
|
||||
@ -4238,7 +4253,7 @@ static int smart_writesector(FAR struct smart_struct_s *dev,
|
||||
#else
|
||||
physsector = smart_cache_lookup(dev, req->logsector);
|
||||
#endif
|
||||
if (physsector == 0xFFFF)
|
||||
if (physsector == 0xffff)
|
||||
{
|
||||
ferr("ERROR: Logical sector %d not allocated\n", req->logsector);
|
||||
ret = -EINVAL;
|
||||
@ -4294,7 +4309,7 @@ static int smart_writesector(FAR struct smart_struct_s *dev,
|
||||
/* Test if the next byte can be written to the flash */
|
||||
|
||||
byte = dev->rwbuffer[sizeof(struct smart_sect_header_s) + req->offset + x];
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xFF
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xff
|
||||
if (((byte ^ req->buffer[x]) | byte) != byte)
|
||||
{
|
||||
needsrelocate = TRUE;
|
||||
@ -4322,7 +4337,7 @@ static int smart_writesector(FAR struct smart_struct_s *dev,
|
||||
|
||||
oldphyssector = physsector;
|
||||
physsector = smart_findfreephyssector(dev, FALSE);
|
||||
if (physsector == 0xFFFF)
|
||||
if (physsector == 0xffff)
|
||||
{
|
||||
ferr("ERROR: Error relocating sector %d\n", req->logsector);
|
||||
ret = -EIO;
|
||||
@ -4336,7 +4351,7 @@ static int smart_writesector(FAR struct smart_struct_s *dev,
|
||||
{
|
||||
#endif
|
||||
header->seq++;
|
||||
if (header->seq == 0xFF)
|
||||
if (header->seq == 0xff)
|
||||
{
|
||||
header->seq = 0;
|
||||
}
|
||||
@ -4345,13 +4360,13 @@ static int smart_writesector(FAR struct smart_struct_s *dev,
|
||||
else
|
||||
{
|
||||
(*((FAR uint16_t *) &header->seq))++;
|
||||
if (*((FAR uint16_t *) &header->seq) == 0xFFFF)
|
||||
if (*((FAR uint16_t *) &header->seq) == 0xffff)
|
||||
*((FAR uint16_t *) &header->seq) = 1;
|
||||
}
|
||||
#else
|
||||
header->seq++;
|
||||
#endif
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xFF
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xff
|
||||
header->status |= SMART_STATUS_COMMITTED;
|
||||
#else
|
||||
header->status &= SMART_STATUS_COMMITTED;
|
||||
@ -4409,7 +4424,7 @@ static int smart_writesector(FAR struct smart_struct_s *dev,
|
||||
|
||||
/* Commit the sector ahead of time. The CRC will protect us */
|
||||
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xFF
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xff
|
||||
header->status &= ~(SMART_STATUS_COMMITTED | SMART_STATUS_CRC);
|
||||
#else
|
||||
header->status |= SMART_STATUS_COMMITTED | SMART_STATUS_CRC;
|
||||
@ -4453,7 +4468,7 @@ static int smart_writesector(FAR struct smart_struct_s *dev,
|
||||
|
||||
#ifndef CONFIG_MTD_SMART_ENABLE_CRC
|
||||
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xFF
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xff
|
||||
byte = header->status & ~SMART_STATUS_COMMITTED;
|
||||
#else
|
||||
byte = header->status | SMART_STATUS_COMMITTED;
|
||||
@ -4471,7 +4486,7 @@ static int smart_writesector(FAR struct smart_struct_s *dev,
|
||||
|
||||
/* Release the old physical sector */
|
||||
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xFF
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xff
|
||||
byte = header->status & ~(SMART_STATUS_RELEASED | SMART_STATUS_COMMITTED);
|
||||
#else
|
||||
byte = header->status | SMART_STATUS_RELEASED | SMART_STATUS_COMMITTED;
|
||||
@ -4614,7 +4629,7 @@ static int smart_readsector(FAR struct smart_struct_s *dev,
|
||||
#else
|
||||
physsector = smart_cache_lookup(dev, req->logsector);
|
||||
#endif
|
||||
if (physsector == 0xFFFF)
|
||||
if (physsector == 0xffff)
|
||||
{
|
||||
ferr("ERROR: Logical sector %d not allocated\n", req->logsector);
|
||||
ret = -EINVAL;
|
||||
@ -4729,7 +4744,7 @@ errout:
|
||||
static inline int smart_allocsector(FAR struct smart_struct_s *dev,
|
||||
unsigned long requested)
|
||||
{
|
||||
uint16_t logsector = 0xFFFF; /* Logical sector number selected */
|
||||
uint16_t logsector = 0xffff; /* Logical sector number selected */
|
||||
uint16_t physicalsector; /* The selected physical sector */
|
||||
#ifndef CONFIG_MTD_SMART_ENABLE_CRC
|
||||
int ret;
|
||||
@ -4745,7 +4760,7 @@ static inline int smart_allocsector(FAR struct smart_struct_s *dev,
|
||||
{
|
||||
/* Do a garbage collect and then test freesectors again */
|
||||
|
||||
if (dev->releasesectors + dev->freesectors > dev->availSectPerBlk + 4)
|
||||
if (dev->releasesectors + dev->freesectors > dev->sectorsPerBlk + 4)
|
||||
{
|
||||
|
||||
for (x = 0; x < dev->availSectPerBlk; x++)
|
||||
@ -4814,7 +4829,7 @@ static inline int smart_allocsector(FAR struct smart_struct_s *dev,
|
||||
|
||||
/* Check if we need to scan for an available logical sector */
|
||||
|
||||
if (logsector == 0xFFFF)
|
||||
if (logsector == 0xffff)
|
||||
{
|
||||
/* Loop through all sectors and find one to allocate */
|
||||
|
||||
@ -4865,7 +4880,7 @@ static inline int smart_allocsector(FAR struct smart_struct_s *dev,
|
||||
|
||||
/* Test for an error allocating a sector */
|
||||
|
||||
if (logsector == 0xFFFF)
|
||||
if (logsector == 0xffff)
|
||||
{
|
||||
/* Hmmm. We think we had enough logical sectors, but
|
||||
* something happened and we didn't find any free
|
||||
@ -4896,6 +4911,11 @@ static inline int smart_allocsector(FAR struct smart_struct_s *dev,
|
||||
logsector, physicalsector, physicalsector /
|
||||
dev->sectorsPerBlk, dev->freesectors, dev->releasecount);
|
||||
|
||||
if (physicalsector == 0xffff)
|
||||
{
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MTD_SMART_ENABLE_CRC
|
||||
|
||||
/* When CRC is enabled, we don't write the header to the device until
|
||||
@ -5023,7 +5043,7 @@ static inline int smart_freesector(FAR struct smart_struct_s *dev,
|
||||
|
||||
/* Mark the sector as released */
|
||||
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xFF
|
||||
#if CONFIG_SMARTFS_ERASEDSTATE == 0xff
|
||||
header.status &= ~SMART_STATUS_RELEASED;
|
||||
#else
|
||||
header.status |= SMART_STATUS_RELEASED;
|
||||
@ -5055,7 +5075,7 @@ static inline int smart_freesector(FAR struct smart_struct_s *dev,
|
||||
dev->sMap[logicalsector] = (uint16_t) -1;
|
||||
#else
|
||||
dev->sBitMap[logicalsector >> 3] &= ~(1 << (logicalsector & 0x07));
|
||||
smart_update_cache(dev, logicalsector, 0xFFFF);
|
||||
smart_update_cache(dev, logicalsector, 0xffff);
|
||||
#endif
|
||||
|
||||
/* If this block has only released blocks, then erase it */
|
||||
@ -5291,19 +5311,13 @@ int smart_initialize(int minor, FAR struct mtd_dev_s *mtd, FAR const char *partn
|
||||
|
||||
/* Allocate a SMART device structure */
|
||||
|
||||
dev = (FAR struct smart_struct_s *)kmm_malloc(sizeof(struct smart_struct_s));
|
||||
dev = (FAR struct smart_struct_s *)smart_malloc(NULL, sizeof(struct smart_struct_s),
|
||||
"Dev struct");
|
||||
if (dev)
|
||||
{
|
||||
/* Initialize the SMART device structure */
|
||||
|
||||
dev->mtd = mtd;
|
||||
#ifdef CONFIG_MTD_SMART_ALLOC_DEBUG
|
||||
dev->bytesalloc = 0;
|
||||
for (totalsectors = 0; totalsectors < SMART_MAX_ALLOCS; totalsectors++)
|
||||
{
|
||||
dev->alloc[totalsectors].ptr = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Get the device geometry. (casting to uintptr_t first eliminates
|
||||
* complaints on some architectures where the sizeof long is different
|
||||
@ -5380,6 +5394,15 @@ int smart_initialize(int minor, FAR struct mtd_dev_s *mtd, FAR const char *partn
|
||||
dev->minor = minor;
|
||||
#endif
|
||||
|
||||
/* Do a scan of the device */
|
||||
|
||||
ret = smart_scan(dev);
|
||||
if (ret < 0)
|
||||
{
|
||||
ferr("ERROR: smart_scan failed: %d\n", -ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Create a MTD block device name */
|
||||
|
||||
#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
|
||||
@ -5431,15 +5454,6 @@ int smart_initialize(int minor, FAR struct mtd_dev_s *mtd, FAR const char *partn
|
||||
ferr("ERROR: register_blockdriver failed: %d\n", -ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Do a scan of the device */
|
||||
|
||||
ret = smart_scan(dev);
|
||||
if (ret < 0)
|
||||
{
|
||||
ferr("ERROR: smart_scan failed: %d\n", -ret);
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMART_DEV_LOOP
|
||||
|
330
drivers/serial/ptmx.c
Normal file
330
drivers/serial/ptmx.c
Normal file
@ -0,0 +1,330 @@
|
||||
/****************************************************************************
|
||||
* drivers/serial/ptmx.c
|
||||
*
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_PTY_MAXPTY
|
||||
# define CONFIG_PTY_MAXPTY 32
|
||||
#endif
|
||||
|
||||
#if CONFIG_PTY_MAXPTY > 256
|
||||
# define CONFIG_PTY_MAXPTY 256
|
||||
#endif
|
||||
|
||||
#define PTY_MAX ((CONFIG_PTY_MAXPTY + 31) & ~31)
|
||||
#define INDEX_MAX (PTY_MAX >> 5)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* PTMX device state */
|
||||
|
||||
struct ptmx_dev_s
|
||||
{
|
||||
uint8_t px_next; /* Next minor number to allocate */
|
||||
sem_t px_exclsem; /* Supports mutual exclusion */
|
||||
uint32_t px_alloctab[INDEX_MAX]; /* Set of allocated PTYs */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static int ptmx_open(FAR struct file *filep);
|
||||
static ssize_t ptmx_read(FAR struct file *filep, FAR char *buffer,
|
||||
size_t buflen);
|
||||
static ssize_t ptmx_write(FAR struct file *filep, FAR const char *buffer,
|
||||
size_t buflen);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const struct file_operations g_ptmx_fops =
|
||||
{
|
||||
ptmx_open, /* open */
|
||||
NULL, /* close */
|
||||
ptmx_read, /* read */
|
||||
ptmx_write, /* write */
|
||||
NULL, /* seek */
|
||||
NULL /* ioctl */
|
||||
#ifndef CONFIG_DISABLE_POLL
|
||||
, NULL /* poll */
|
||||
#endif
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
, NULL /* unlink */
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct ptmx_dev_s g_ptmx;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ptmx_semtake and ptmx_semgive
|
||||
*
|
||||
* Description:
|
||||
* This is just a wrapper to handle the annoying behavior of semaphore
|
||||
* waits that return due to the receipt of a signal.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ptmx_semtake(void)
|
||||
{
|
||||
/* Take the semaphore (perhaps waiting) */
|
||||
|
||||
while (sem_wait(&g_ptmx.px_exclsem) != 0)
|
||||
{
|
||||
/* The only case that an error should occur here is if the wait was
|
||||
* awakened by a signal.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(errno == EINTR);
|
||||
}
|
||||
}
|
||||
|
||||
#define ptmx_semgive() sem_post(&g_ptmx.px_exclsem)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ptmx_minor_allocate
|
||||
*
|
||||
* Description:
|
||||
* Allocate a new unique PTY minor number.
|
||||
*
|
||||
* Assumptions:
|
||||
* Caller hold the px_exclsem
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ptmx_minor_allocate(FAR struct ptmx_dev_s *ptmx)
|
||||
{
|
||||
uint8_t startaddr = g_ptmx.px_next;
|
||||
uint8_t minor;
|
||||
int index;
|
||||
int bitno;
|
||||
|
||||
/* Loop until we find a valid device address */
|
||||
|
||||
for (; ; )
|
||||
{
|
||||
/* Try the next device address */
|
||||
|
||||
minor = g_ptmx.px_next;
|
||||
if (g_ptmx.px_next >= PTY_MAX)
|
||||
{
|
||||
g_ptmx.px_next = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_ptmx.px_next++;
|
||||
}
|
||||
|
||||
/* Is this address already allocated? */
|
||||
|
||||
index = minor >> 5;
|
||||
bitno = minor & 31;
|
||||
if ((g_ptmx.px_alloctab[index] & (1 << bitno)) == 0)
|
||||
{
|
||||
/* No... allocate it now */
|
||||
|
||||
g_ptmx.px_alloctab[index] |= (1 << bitno);
|
||||
return (int)minor;
|
||||
}
|
||||
|
||||
/* This address has already been allocated. The following logic will
|
||||
* prevent (unexpected) infinite loops.
|
||||
*/
|
||||
|
||||
if (startaddr == minor)
|
||||
{
|
||||
/* We are back where we started... the are no free device address */
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ptmx_minor_free
|
||||
*
|
||||
* Description:
|
||||
* De-allocate a PTY minor number.
|
||||
*
|
||||
* Assumptions:
|
||||
* Caller hold the px_exclsem
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ptmx_minor_free(uint8_t minor)
|
||||
{
|
||||
int index;
|
||||
int bitno;
|
||||
|
||||
/* Free the address by clearing the associated bit in the px_alloctab[]; */
|
||||
|
||||
index = minor >> 5;
|
||||
bitno = minor & 31;
|
||||
|
||||
DEBUGASSERT((g_ptmx.px_alloctab[index] |= (1 << bitno)) != 0);
|
||||
g_ptmx.px_alloctab[index] &= ~(1 << bitno);
|
||||
|
||||
/* Reset the next pointer if the one just released has a lower value */
|
||||
|
||||
if (minor < g_ptmx.px_next)
|
||||
{
|
||||
g_ptmx.px_next = minor;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ptmx_open
|
||||
****************************************************************************/
|
||||
|
||||
static int ptmx_open(FAR struct file *filep)
|
||||
{
|
||||
char devname[16];
|
||||
int minor;
|
||||
int fd;
|
||||
int ret;
|
||||
|
||||
/* Get exclusive access */
|
||||
|
||||
ptmx_semtake();
|
||||
|
||||
/* Allocate a PTY minor */
|
||||
|
||||
minor = ptmx_minor_allocate();
|
||||
if (minor < 0)
|
||||
{
|
||||
ret = minor;
|
||||
goto errout_with_sem;
|
||||
}
|
||||
|
||||
/* Create the master slave pair */
|
||||
|
||||
ret = pty_register(minor);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_minor;
|
||||
}
|
||||
|
||||
/* Open the master side */
|
||||
|
||||
snprintf(devname, 16, "/dev/ttyp%d", minor);
|
||||
fd = open(devname, O_RDWR);
|
||||
DEBUGASSERT(fd >= 0); /* open() should never fail */
|
||||
|
||||
/* No unlink the master. This will remove it from the VFS namespace,
|
||||
* the the driver will still persist because of the open count on the
|
||||
* driver.
|
||||
*/
|
||||
|
||||
ret = unlink(devname);
|
||||
DEBUGASSERT(ret >= 0); /* unlink() should never fail */
|
||||
UNUSED(ret);
|
||||
|
||||
/* Return the master file descriptor */
|
||||
|
||||
ptmx_semgive();
|
||||
return fd;
|
||||
|
||||
errout_with_minor:
|
||||
ptmx_minor_free(minor);
|
||||
|
||||
errout_with_sem:
|
||||
ptmx_semgive();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ptmx_read
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t ptmx_read(FAR struct file *filep, FAR char *buffer, size_t len)
|
||||
{
|
||||
return 0; /* Return EOF */
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ptmx_write
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t ptmx_write(FAR struct file *filep, FAR const char *buffer, size_t len)
|
||||
{
|
||||
return len; /* Say that everything was written */
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ptmx_register
|
||||
*
|
||||
* Description:
|
||||
* Register /dev/null
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void ptmx_register(void)
|
||||
{
|
||||
FAR struct ptmx_dev_s *ptmx;
|
||||
|
||||
/* Initialize driver state */
|
||||
|
||||
sem_init(&g_ptmx.px_exclsem, 0, 1);
|
||||
|
||||
/* Register the PTMX driver */
|
||||
|
||||
(void)register_driver("/dev/ptmx", &g_ptmx_fops, 0666, NULL);
|
||||
}
|
559
drivers/serial/pty.c
Normal file
559
drivers/serial/pty.c
Normal file
@ -0,0 +1,559 @@
|
||||
/****************************************************************************
|
||||
* drivers/serial/pty.c
|
||||
*
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <semaphore.h>
|
||||
#include <string.h>
|
||||
#include <poll.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static int pty_open(FAR struct file *filep);
|
||||
static int pty_close(FAR struct file *filep);
|
||||
static ssize_t pty_read(FAR struct file *filep, FAR char *buffer,
|
||||
size_t buflen);
|
||||
static ssize_t pty_write(FAR struct file *filep, FAR const char *buffer,
|
||||
size_t buflen);
|
||||
static int pty_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
|
||||
#ifndef CONFIG_DISABLE_POLL
|
||||
static int pty_poll(FAR struct file *filep, FAR struct pollfd *fds,
|
||||
bool setup);
|
||||
#endif
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
static int pty_unlink(FAR struct inode *inode);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* This device structure describes on memory of the PTY device pair */
|
||||
|
||||
struct pty_devpair_s;
|
||||
struct pty_dev_s
|
||||
{
|
||||
FAR struct pty_common_s *pd_devpair;
|
||||
struct file pd_src; /* Provides data to read() method (pipe output) */
|
||||
struct file pd_sink; /* Accepts data from write() method (pipe input) */
|
||||
};
|
||||
|
||||
/* This structure describes the pipe pair */
|
||||
|
||||
struct pty_devpair_s
|
||||
{
|
||||
struct pty_dev_s pp_ptyp; /* /dev/ptypN device */
|
||||
struct pty_dev_s pp_ttyp; /* /dev/ttypN device */
|
||||
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
uint8_t pp_minor; /* Minor device number */
|
||||
uint16_t pp_nopen; /* Open file count */
|
||||
sem_t pp_exclsem; /* Mutual exclusion */
|
||||
bool pp_unlinked; /* File has been unlinked */
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const struct file_operations pty_fops =
|
||||
{
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
pty_open, /* open */
|
||||
pty_close, /* close */
|
||||
#else
|
||||
NULL, /* open */
|
||||
NULL, /* close */
|
||||
#endif
|
||||
pty_read, /* read */
|
||||
pty_write, /* write */
|
||||
NULL, /* seek */
|
||||
pty_ioctl /* ioctl */
|
||||
#ifndef CONFIG_DISABLE_POLL
|
||||
, pty_poll /* poll */
|
||||
#endif
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
, pty_unlink /* unlink */
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pty_semtake
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
static void pty_semtake(FAR struct pty_common_s *devpair)
|
||||
{
|
||||
while (sem_wait(&devpair->pp_exclsem) < 0)
|
||||
{
|
||||
DEBUGASSERT(errno == EINTR);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pty_semgive
|
||||
****************************************************************************/
|
||||
|
||||
#define pty_semgive(c) sem_post(&(c)->pp_exclsem)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pty_destroy
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
static void pty_destroy(FAR struct pty_common_s *devpair)
|
||||
{
|
||||
char devname[16];
|
||||
|
||||
/* Un-register /dev/ptypN */
|
||||
|
||||
snprintf(devname, 16, "/dev/pp_ptyp%d", (int)devpair->pp_minor);
|
||||
(void)unregister_driver(devname);
|
||||
|
||||
/* Un-register /dev/ptypN */
|
||||
|
||||
snprintf(devname, 16, "/dev/ttyp%d", (int)devpair->pp_minor);
|
||||
(void)unregister_driver(devname);
|
||||
|
||||
/* Close the contained file structures */
|
||||
|
||||
(void)file_close_detached(&devpair->pp_ptyp.pd_src);
|
||||
(void)file_close_detached(&devpair->pp_ptyp.pd_sink);
|
||||
(void)file_close_detached(&devpair->pp_ttyp.pd_src);
|
||||
(void)file_close_detached(&devpair->pp_ttyp.pd_sink);
|
||||
|
||||
/* And free the device structure */
|
||||
|
||||
sem_destroy(&devpair->pp_exclsem);
|
||||
kmm_free(upper);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pty_open
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
static int pty_open(FAR struct file *filep)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct pty_dev_s *dev;
|
||||
FAR struct pty_common_s *devpair;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(filep != NULL && file->f_inode != NULL);
|
||||
inode = filep->f_inode;
|
||||
dev = inode->i_private;
|
||||
DEBUGASSERT(dev != NULL && dev->pd_devpair != NULL);
|
||||
devpair = dev->pd_devpair;
|
||||
|
||||
/* Get exclusive access */
|
||||
|
||||
pty_semtake(devpair);
|
||||
|
||||
/* If one side of the driver has been unlinked, then refuse further
|
||||
* opens.
|
||||
*/
|
||||
|
||||
if (cmd->pp_unlinked)
|
||||
{
|
||||
ret = -EIDRAM
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Increment the count of open references on the driver */
|
||||
|
||||
devpair->pp_nopen++;
|
||||
DEBUGASSERT(devpair->pp_nopen > 0);
|
||||
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
pty_semgive(devpair);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pty_open
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
static int pty_close(FAR struct file *filep)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct pty_dev_s *dev;
|
||||
FAR struct pty_common_s *devpair;
|
||||
|
||||
DEBUGASSERT(filep != NULL && file->f_inode != NULL);
|
||||
inode = filep->f_inode;
|
||||
dev = inode->i_private;
|
||||
DEBUGASSERT(dev != NULL && dev->pd_devpair != NULL);
|
||||
devpair = dev->pd_devpair;
|
||||
|
||||
/* Get exclusive access */
|
||||
|
||||
pty_semtake(devpair);
|
||||
|
||||
/* Is this the last open reference? */
|
||||
|
||||
DEBUGASSERT(devpair->pp_nopen > 0);
|
||||
if (devpair->pp_nopen <= 1 && devpair->pp_unlinked)
|
||||
{
|
||||
/* Free the device pair now (without freeing the semaphore) */
|
||||
|
||||
pty_destroy(devpair);
|
||||
return OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise just decrement the open count */
|
||||
|
||||
devpair->pp_nopen--;
|
||||
}
|
||||
|
||||
pty_semgive(devpair);
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pty_read
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t pty_read(FAR struct file *filep, FAR char *buffer, size_t len)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct pty_dev_s *dev;
|
||||
|
||||
DEBUGASSERT(filep != NULL && file->f_inode != NULL);
|
||||
inode = filep->f_inode;
|
||||
dev = inode->i_private;
|
||||
DEBUGASSERT(dev != NULL);
|
||||
|
||||
return file_read(&dev->src, buffer, len);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pty_write
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t pty_write(FAR struct file *filep, FAR const char *buffer, size_t len)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct pty_dev_s *dev;
|
||||
|
||||
DEBUGASSERT(filep != NULL && file->f_inode != NULL);
|
||||
inode = filep->f_inode;
|
||||
dev = inode->i_private;
|
||||
DEBUGASSERT(dev != NULL);
|
||||
|
||||
return file_write(&dev->src, buffer, len);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pty_ioctl
|
||||
*
|
||||
* Description:
|
||||
* The standard ioctl method. This is where ALL of the PWM work is done.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int pty_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct pty_dev_s *dev;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(filep != NULL && file->f_inode != NULL);
|
||||
inode = filep->f_inode;
|
||||
dev = inode->i_private;
|
||||
DEBUGASSERT(dev != NULL);
|
||||
|
||||
/* Handle IOCTL commands */
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
/* PTY IOCTL commands would be handled here */
|
||||
/* There aren't any yet */
|
||||
|
||||
/* Any unrecognized IOCTL commands will be passed to the contained
|
||||
* pipe driver.
|
||||
*/
|
||||
|
||||
default:
|
||||
{
|
||||
ret = file_ioctl(dev->pd_src, cmd, arg);
|
||||
if (ret >= 0 || ret == -ENOTTY)
|
||||
{
|
||||
ret = file_ioctl(dev->pd_sink, cmd, arg);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
sem_post(&upper->exclsem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pty_poll
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_DISABLE_POLL
|
||||
static int pty_poll(FAR struct file *filep, FAR struct pollfd *fds,
|
||||
bool setup)
|
||||
{
|
||||
#warning Missing logic
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pty_unlink
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
static int pty_unlink(FAR struct inode *inode)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct pty_dev_s *dev;
|
||||
FAR struct pty_common_s *devpair;
|
||||
|
||||
DEBUGASSERT(filep != NULL && file->f_inode != NULL);
|
||||
inode = filep->f_inode;
|
||||
dev = inode->i_private;
|
||||
DEBUGASSERT(dev != NULL && dev->pd_devpair != NULL);
|
||||
devpair = dev->pd_devpair;
|
||||
|
||||
/* Get exclusive access */
|
||||
|
||||
pty_semtake(devpair);
|
||||
|
||||
/* Indicate that the driver has been unlinked */
|
||||
|
||||
devpair->pp_unlinked = true;
|
||||
|
||||
/* If there are no further open references to the driver, then commit
|
||||
* Hara-Kiri now.
|
||||
*/
|
||||
|
||||
if (devpair->pp_nopen == 0)
|
||||
{
|
||||
pty_destroy(devpair);
|
||||
return OK;
|
||||
}
|
||||
|
||||
pty_semgive(devpair);
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pty_register
|
||||
*
|
||||
* Input Parameters:
|
||||
*
|
||||
* Description:
|
||||
* Register /dev/ttypN and /dev/ptpN where N=minor number
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int pty_register(int minor)
|
||||
{
|
||||
FAR struct pty_devpair_s *devpair;
|
||||
int pipe_a[2];
|
||||
int pipe_b[2];
|
||||
char devname[16];
|
||||
|
||||
/* Allocate a device instance */
|
||||
|
||||
devpair = kmm_zalloc(sizeof(struct pty_devpair_s));
|
||||
if (devpair == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
sem_init(&devpair->pp_exclsem, 0, 1);
|
||||
devpair->pp_minor = minor;
|
||||
#endif
|
||||
devpair->pp_ptyp.pd_devpair = devpair;
|
||||
devpair->pp_ttyp.pd_devpair = devpair;
|
||||
|
||||
/* Create two pipes */
|
||||
|
||||
ret = pipe(pipe_a);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_devpair;
|
||||
}
|
||||
|
||||
ret = pipe(pipe_b);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_pipea;
|
||||
}
|
||||
|
||||
/* Detach the pipe file descriptors (closing them in the process)
|
||||
*
|
||||
* fd[0] is for reading;
|
||||
* fd[1] is for writing.
|
||||
*/
|
||||
|
||||
ret = file_detach(pipe_a[0], &devpair->pp_ptyp.pd_src);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_pipeb;
|
||||
}
|
||||
|
||||
pipe_a[0] = -1;
|
||||
|
||||
ret = file_detach(pipe_a[1], &devpair->pp_ttyp.pd_sink);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_pipeb;
|
||||
}
|
||||
|
||||
pipe_a[1] = -1;
|
||||
|
||||
ret = file_detach(pipe_b[0], &devpair->pp_ttyp.pd_src);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_pipeb;
|
||||
}
|
||||
|
||||
pipe_b[0] = -1;
|
||||
|
||||
ret = file_detach(pipe_b[1], &devpair->pp_ptyp.pd_sink);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_pipeb;
|
||||
}
|
||||
|
||||
pipe_b[1] = -1;
|
||||
|
||||
/* Register /dev/ptypN */
|
||||
|
||||
snprintf(devname, 16, "/dev/pts/%d", minor);
|
||||
|
||||
ret = register_driver(devname, &pty_fops, 0666, &devpair->pp_ptyp);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_pipeb;
|
||||
}
|
||||
|
||||
/* Register /dev/ptypN */
|
||||
|
||||
snprintf(devname, 16, "/dev/ttyp%d", minor);
|
||||
|
||||
ret = register_driver(devname, &pty_fops, 0666, &devpair->pp_ttyp);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_ptyp;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
errout_with_ptyp:
|
||||
snprintf(devname, 16, "/dev/ptyp%d", minor);
|
||||
(void)unregister_driver(devname)
|
||||
|
||||
errout_with_pipeb:
|
||||
if (pipe_b[0] >= 0)
|
||||
{
|
||||
close(pipe_b[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
(void)file_close_detached(&devpair->pp_ptyp.pd_src);
|
||||
}
|
||||
|
||||
if (pipe_b[1] >= 0)
|
||||
{
|
||||
close(pipe_b[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
(void)file_close_detached(&devpair->pp_ttyp.pd_sink);
|
||||
}
|
||||
|
||||
errout_with_pipea:
|
||||
if (pipe_a[0] >= 0)
|
||||
{
|
||||
close(pipe_a[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
(void)file_close_detached(&devpair->pp_ttyp.pd_src);
|
||||
}
|
||||
|
||||
if (pipe_a[1] >= 0)
|
||||
{
|
||||
close(pipe_a[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
(void)file_close_detached(&devpair->pp_ptyp.pd_sink);
|
||||
}
|
||||
|
||||
errout_with_devpair:
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
sem_destroy(&devpair->pp_exclsem);
|
||||
#endif
|
||||
kmm_free(devpair);
|
||||
return ret;
|
||||
}
|
@ -72,6 +72,12 @@
|
||||
# define CONFIG_ADC_FIFOSIZE 255
|
||||
#endif
|
||||
|
||||
#define ADC_RESET(dev) ((dev)->ad_ops->ao_reset((dev)))
|
||||
#define ADC_SETUP(dev) ((dev)->ad_ops->ao_setup((dev)))
|
||||
#define ADC_SHUTDOWN(dev) ((dev)->ad_ops->ao_shutdown((dev)))
|
||||
#define ADC_RXINT(dev) ((dev)->ad_ops->ao_rxint((dev)))
|
||||
#define ADC_IOCTL(dev,cmd,arg) ((dev)->ad_ops->ao_ioctl((dev),(cmd),(arg)))
|
||||
|
||||
/************************************************************************************
|
||||
* Public Types
|
||||
************************************************************************************/
|
||||
|
@ -67,6 +67,7 @@ double erf(double x)
|
||||
|
||||
sign = (x >= 0 ? 1 : -1);
|
||||
t = 1.0/(1.0 + p*x);
|
||||
return sign * (1.0 - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * expf(-x * x));
|
||||
return sign * (1.0 - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t *
|
||||
(double)expf(-x * x));
|
||||
}
|
||||
#endif
|
||||
|
@ -32,6 +32,8 @@
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
#define FLT_MAX_EXP_X 88.0F
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -50,25 +52,25 @@ float logf(float x)
|
||||
ey = exp(y);
|
||||
y -= (ey - x) / ey;
|
||||
|
||||
if (y > 700.0F)
|
||||
if (y > FLT_MAX_EXP_X)
|
||||
{
|
||||
y = 700.0F;
|
||||
y = FLT_MAX_EXP_X;
|
||||
}
|
||||
|
||||
if (y < -700.0F)
|
||||
if (y < -FLT_MAX_EXP_X)
|
||||
{
|
||||
y = -700.0F;
|
||||
y = -FLT_MAX_EXP_X;
|
||||
}
|
||||
|
||||
epsilon = (fabsf(y) > 1.0F) ? fabsf(y) * FLT_EPSILON : FLT_EPSILON;
|
||||
}
|
||||
|
||||
if (y == 700.0F)
|
||||
if (y == FLT_MAX_EXP_X)
|
||||
{
|
||||
return INFINITY;
|
||||
}
|
||||
|
||||
if (y == -700.0F)
|
||||
if (y == -FLT_MAX_EXP_X)
|
||||
{
|
||||
return INFINITY;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user