diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-07-12 16:36:45 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-07-12 16:36:45 +0000 |
commit | ec5c538c2d9b423c79387a09c60457e918e22703 (patch) | |
tree | 986a5643cf00efbea8f795c17cc3466982031247 | |
parent | e6f4d56ce41c0e258632e9525b2e62dd17fe8273 (diff) | |
download | nuttx-ec5c538c2d9b423c79387a09c60457e918e22703.tar.gz nuttx-ec5c538c2d9b423c79387a09c60457e918e22703.tar.bz2 nuttx-ec5c538c2d9b423c79387a09c60457e918e22703.zip |
Add wchar_t type; Add LPC17xx CAN driver from Lzyy; Fix serial bug reported by Lzyy
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3775 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r-- | nuttx/ChangeLog | 4 | ||||
-rw-r--r-- | nuttx/arch/arm/src/common/up_internal.h | 5 | ||||
-rwxr-xr-x | nuttx/arch/arm/src/lpc17xx/Make.defs | 4 | ||||
-rwxr-xr-x | nuttx/arch/arm/src/lpc17xx/lpc17_can.c | 301 | ||||
-rw-r--r-- | nuttx/drivers/serial/serial.c | 8 | ||||
-rw-r--r-- | nuttx/fs/fat/fs_fat32.h | 13 | ||||
-rw-r--r-- | nuttx/include/inttypes.h | 4 | ||||
-rw-r--r-- | nuttx/include/sys/types.h | 11 |
8 files changed, 341 insertions, 9 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 8522f814b..5f1e723c5 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -1907,4 +1907,6 @@ serial RX buffer becomes full. Data is now discarded in that case; before, leaving data in the hardware would cause infinite interrupts one most MCUs since you must read the data in order to clear the - interrupt.
\ No newline at end of file + interrupt. + * arch/arm/src/lpc17xx/lpc17_can.c: Added a CAN driver contributed by Lzyy. + * include/stddefs.h and sys/types: Added type wchar_t.
\ No newline at end of file diff --git a/nuttx/arch/arm/src/common/up_internal.h b/nuttx/arch/arm/src/common/up_internal.h index ac6c0d3ea..2992812c3 100644 --- a/nuttx/arch/arm/src/common/up_internal.h +++ b/nuttx/arch/arm/src/common/up_internal.h @@ -293,6 +293,11 @@ extern void up_usbuninitialize(void); # define up_usbuninitialize() #endif +/* CAN **********************************************************************/ + +struct can_dev_s; /* Forward reference */ +extern FAR struct can_dev_s *up_caninitialize(int port); + /**************************************************************************** * Name: up_check_stack * diff --git a/nuttx/arch/arm/src/lpc17xx/Make.defs b/nuttx/arch/arm/src/lpc17xx/Make.defs index 32bc8b47f..09875a979 100755 --- a/nuttx/arch/arm/src/lpc17xx/Make.defs +++ b/nuttx/arch/arm/src/lpc17xx/Make.defs @@ -57,8 +57,8 @@ endif # Required LPC17xx files CHIP_ASRCS = -CHIP_CSRCS = lpc17_allocateheap.c lpc17_clockconfig.c lpc17_clrpend.c \ - lpc17_gpio.c lpc17_idle.c lpc17_irq.c lpc17_lowputc.c \ +CHIP_CSRCS = lpc17_allocateheap.c lpc17_can.c lpc17_clockconfig.c \ + lpc17_clrpend.c lpc17_gpio.c lpc17_idle.c lpc17_irq.c lpc17_lowputc.c \ lpc17_serial.c lpc17_spi.c lpc17_ssp.c lpc17_start.c lpc17_timerisr.c # Configuration-dependent LPC17xx files diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_can.c b/nuttx/arch/arm/src/lpc17xx/lpc17_can.c new file mode 100755 index 000000000..06e607069 --- /dev/null +++ b/nuttx/arch/arm/src/lpc17xx/lpc17_can.c @@ -0,0 +1,301 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_can.c + * + * Copyright (C) 2011 Li Zhuoyi. All rights reserved. + * Author: Li Zhuoyi <lzyy.cn@gmail.com> + * + * This file is a part of NuttX: + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#include <nuttx/config.h> + +#include <stdio.h> +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> +#include <semaphore.h> +#include <errno.h> +#include <debug.h> + +#include <arch/board/board.h> +#include <nuttx/arch.h> +#include <nuttx/can.h> + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "lpc17_internal.h" +#include "lpc17_syscon.h" +#include "lpc17_pinconn.h" +#include "lpc17_can.h" + +#if HAVE_CAN + +#define CAN2_RATE 500000 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* CAN methods */ + +static void can_reset(FAR struct can_dev_s *dev); +static int can_setup(FAR struct can_dev_s *dev); +static void can_shutdown(FAR struct can_dev_s *dev); +static void can_rxint(FAR struct can_dev_s *dev, bool enable); +static void can_txint(FAR struct can_dev_s *dev, bool enable); +static int can_ioctl(FAR struct can_dev_s *dev, int cmd, unsigned long arg); +static int can_remoterequest(FAR struct can_dev_s *dev, uint16_t id); +static int can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg); +static bool can_txempty(FAR struct can_dev_s *dev); +static int can_interrupt(int irq, void *context); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct can_ops_s g_canops = +{ + .co_reset =can_reset, + .co_setup = can_setup, + .co_shutdown = can_shutdown, + .co_rxint = can_rxint, + .co_txint = can_txint, + .co_ioctl = can_ioctl, + .co_remoterequest = can_remoterequest, + .co_send = can_send, + .co_txempty = can_txempty, +}; + +static struct can_dev_s g_candev = +{ + .cd_ops = &g_canops, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/* Reset the CAN device. Called early to initialize the hardware. This +* is called, before co_setup() and on error conditions. +*/ +static void can_reset(FAR struct can_dev_s *dev) +{ + irqstate_t flags; + uint32_t regval; + + flags = irqsave(); + putreg32(0x01,LPC17_CAN2_MOD); + putreg32(0x00,LPC17_CAN2_IER); + putreg32(0x00,LPC17_CAN2_GSR); + putreg32(0x02,LPC17_CAN2_CMR); + putreg32(0x25c003,LPC17_CAN2_BTR); + putreg32(0x00,LPC17_CAN2_MOD); + putreg32(0x01,LPC17_CAN2_IER); + putreg32(0x02,LPC17_CANAF_AFMR); + + irqrestore(flags); + + regval = getreg32(LPC17_CAN2_BTR); + //dbg("BTR=%x\n",regval); +} + +/* Configure the CAN. This method is called the first time that the CAN +* device is opened. This will occur when the port is first opened. +* This setup includes configuring and attaching CAN interrupts. Interrupts +* are all disabled upon return. +*/ +static int can_setup(FAR struct can_dev_s *dev) +{ + int ret=0; + ret = irq_attach(LPC17_IRQ_CAN, can_interrupt); + if (ret == OK) + { + up_enable_irq(LPC17_IRQ_CAN); + } + return ret; +} + +/* Disable the CAN. This method is called when the CAN device is closed. +* This method reverses the operation the setup method. +*/ +static void can_shutdown(FAR struct can_dev_s *dev) +{ + up_disable_irq(LPC17_IRQ_CAN); + irq_detach(LPC17_IRQ_CAN); +} + +/* Call to enable or disable RX interrupts */ +static void can_rxint(FAR struct can_dev_s *dev, bool enable) +{ + uint32_t regval; + regval = getreg32(LPC17_CAN2_IER); + if(enable) + regval |= CAN_IER_RIE; + else + regval &= ~CAN_IER_RIE; + putreg32(regval, LPC17_CAN2_IER); +} + +/* Call to enable or disable TX interrupts */ +static void can_txint(FAR struct can_dev_s *dev, bool enable) +{ + uint32_t regval; + regval = getreg32(LPC17_CAN2_IER); + if(enable) + regval |= CAN_IER_TIE1; + else + regval &= ~CAN_IER_TIE1; + putreg32(regval, LPC17_CAN2_IER); +} + +/* All ioctl calls will be routed through this method */ +static int can_ioctl(FAR struct can_dev_s *dev, int cmd, unsigned long arg) +{ + dbg("Fix me:Not Implemented\n"); + return 0; +} + +/* Send a remote request */ +static int can_remoterequest(FAR struct can_dev_s *dev, uint16_t id) +{ + dbg("Fix me:Not Implemented\n"); + return 0; +} + +static int can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg) +{ + uint32_t tid=CAN_ID(msg->cm_hdr); + uint32_t tfi=CAN_DLC(msg->cm_hdr)<<16; + if(CAN_RTR(msg->cm_hdr)) + tfi|=CAN_TFI_RTR; + //dbg("header=%04x\n",msg->cm_hdr); + putreg32(tfi,LPC17_CAN2_TFI1); + putreg32(tid,LPC17_CAN2_TID1); + putreg32(*(uint32_t *)&msg->cm_data[0],LPC17_CAN2_TDA1); + putreg32(*(uint32_t *)&msg->cm_data[4],LPC17_CAN2_TDB1); + putreg32(0x21,LPC17_CAN2_CMR); + return 0; +} + +static bool can_txempty(FAR struct can_dev_s *dev) +{ + uint32_t regval; + regval = getreg32(LPC17_CAN2_GSR); + if( regval & CAN_GSR_TBS) + return true; + else + return false; +} + +static int can_interrupt(int irq, void *context) +{ + uint32_t regval; + regval=getreg32(LPC17_CAN2_ICR); + if (regval & CAN_ICR_RI ) //Receive interrupt + { + uint16_t hdr; + uint32_t data[2]; + uint32_t rfs=getreg32(LPC17_CAN2_RFS); + uint32_t rid=getreg32(LPC17_CAN2_RID); + data[0]=getreg32(LPC17_CAN2_RDA); + data[1]=getreg32(LPC17_CAN2_RDB); + putreg32(0x04,LPC17_CAN2_CMR); //release recieve buffer + hdr=((rid<<5)&~0x1f)|((rfs>>16)&0x0f); + if(rfs&CAN_RFS_RTR) + hdr|=0x10; + can_receive(&g_candev,hdr,data); + } + if ( regval & CAN_ICR_TI1) //Transmit interrupt 1 + can_txdone(&g_candev); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_caninitialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct can_dev_s *up_caninitialize(int port) +{ + uint32_t regval; + irqstate_t flags; + flags = irqsave(); + + /* Step 1: Enable power on */ + regval = getreg32(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCCAN2; + putreg32(regval, LPC17_SYSCON_PCONP); + + /* Step 2: Enable clocking */ + regval = getreg32(LPC17_SYSCON_PCLKSEL0); + regval &= ~SYSCON_PCLKSEL0_CAN2_MASK; + regval |= (SYSCON_PCLKSEL_CCLK4 << SYSCON_PCLKSEL0_CAN2_SHIFT); + putreg32(regval, LPC17_SYSCON_PCLKSEL0); + + /* Step 3: Configure I/O pins */ + lpc17_configgpio(GPIO_CAN2_RD_2); + lpc17_configgpio(GPIO_CAN2_TD_2); + + /* Step 4: Setup */ + putreg32(0x01,LPC17_CAN2_MOD); + putreg32(0x00,LPC17_CAN2_IER); + putreg32(0x00,LPC17_CAN2_GSR); + putreg32(0x02,LPC17_CAN2_CMR); + putreg32(0x49c009,LPC17_CAN2_BTR); + putreg32(0x00,LPC17_CAN2_MOD); + putreg32(0x01,LPC17_CAN2_IER); + putreg32(0x02,LPC17_CANAF_AFMR); + + irqrestore(flags); + return &g_candev; +} +#endif + diff --git a/nuttx/drivers/serial/serial.c b/nuttx/drivers/serial/serial.c index 3df4a4e18..983d4ae16 100644 --- a/nuttx/drivers/serial/serial.c +++ b/nuttx/drivers/serial/serial.c @@ -296,6 +296,7 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen { FAR struct inode *inode = filep->f_inode; FAR uart_dev_t *dev = inode->i_private; + irqstate_t flags; ssize_t recvd = 0; /* Only one user can be accessing dev->recv.tail at once */ @@ -372,14 +373,17 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen else { - /* Wait for some characters to be sent from the buffer - * with the TX interrupt re-enabled. + /* Wait for some characters to be sent from the buffer with the RX interrupt + * re-enabled. Interrupts are disabled briefly to assure that the following + * operations are atomic. */ + flags = irqsave(); dev->recvwaiting = true; uart_enablerxint(dev); uart_takesem(&dev->recvsem); uart_disablerxint(dev); + irqrestore(flags); } } diff --git a/nuttx/fs/fat/fs_fat32.h b/nuttx/fs/fat/fs_fat32.h index ca5915098..15bb18283 100644 --- a/nuttx/fs/fat/fs_fat32.h +++ b/nuttx/fs/fat/fs_fat32.h @@ -148,8 +148,8 @@ #define PART_SIZE 12 /* 4@12: Partition size (in sectors) */ /**************************************************************************** - * Each FAT directory entry is 32-bytes long. The following define offsets - * relative to the beginning of a directory entry. + * Each FAT "short" 8.3 file name directory entry is 32-bytes long. The + * following define offsets relative to the beginning of a directory entry. */ #define DIR_NAME 0 /* 11@ 0: NAME: 8 bytes + 3 byte extension */ @@ -193,6 +193,15 @@ #define CLUS_NDXMASK(f) ((f)->fs_fatsecperclus - 1) /**************************************************************************** +/* The FAT "long" file name directory entry */ + +/* Sizes and limits */ + +#define LDIR_MAXCHARS 255 /* Max unicode characters */ +#define LDIR_MAXLFNCHARS 13 /* Max unicode characters in one LFN */ +#define LDIR_MAXLFNS 20 /* Max number of LFNs */ + +/**************************************************************************** * File system types */ #define FSTYPE_FAT12 0 diff --git a/nuttx/include/inttypes.h b/nuttx/include/inttypes.h index 77dfaa4e6..f305d187d 100644 --- a/nuttx/include/inttypes.h +++ b/nuttx/include/inttypes.h @@ -40,6 +40,8 @@ * Included Files ****************************************************************************/ +#include <stddef.h> /* for wchar_t */ + /* Notes from www.opengroup.org: * * "The <inttypes.h> header shall include the <stdint.h> header." @@ -177,10 +179,8 @@ EXTERN imaxdiv_t imaxdiv(intmax_t, intmax_t); EXTERN intmax_t strtoimax(const char *, char **, int); EXTERN uintmax_t strtoumax(const char *, char **, int); -#if 0 /* No wchar_t */ EXTERN intmax_t wcstoimax(const wchar_t *, wchar_t **, int); EXTERN uintmax_t wcstoumax(const wchar_t *, wchar_t **, int); -#endif #undef EXTERN #ifdef __cplusplus diff --git a/nuttx/include/sys/types.h b/nuttx/include/sys/types.h index 521598278..f505c6afa 100644 --- a/nuttx/include/sys/types.h +++ b/nuttx/include/sys/types.h @@ -103,6 +103,9 @@ ****************************************************************************/ #ifndef __ASSEMBLY__ + +/* Floating point types */ + typedef float float32; #ifndef CONFIG_HAVE_DOUBLE typedef float double_t; @@ -158,6 +161,14 @@ typedef int pid_t; typedef unsigned int id_t; +/* Signed integral type of the result of subtracting two pointers */ + +typedef intptr_t ptrdiff_t; + +/* Wide, 16-bit character types */ + +typedef uint16_t wchar_t; + /* blkcnt_t and off_t are signed integer types. * * blkcnt_t is used for file block counts. |