Add LPC313x I2C+SPI drivers and fixes for USB driver

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2702 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo
2010-05-26 13:02:39 +00:00
parent 34e5fb7d6b
commit a6004aa2bb
11 changed files with 1483 additions and 86 deletions
+13
View File
@@ -1129,3 +1129,16 @@
* drivers/lcd/p14201.c - Driver for RiT P14201 series 128x96 4-bit OLED.
* configs/lm3s6965-ek/nx - NX graphics configuration for the LM3S6965
Ethernet Evaluation Kit.
* graphics/ - Numerous fixes to get the P14201 4-bpp greyscale display
working (there may still be some minor issues .. see the TODO list).
* arch/arm/include/lpc17xx and arch/arm/src/lpc17xxx - Began port for
NXP LPC1768
* drivers/mtd/m25px.c - Add support for M25P1 flash part (See NOTE)
* include/nuttx/i2c.h - Extended I2C interface definition to handle
multiple transfers (See NOTE).
* include/nuttx/usbdev.h - Corrected an important macro definition
needed to correctly handle USB null packet transfers (See NOTE).
* arch/arm/src/lpc313x - New drivers: I2C and SPI. Plus several
important LPC313x USB bug fixes (See NOTE).
NOTE: Contributed by David Hewson.
+14 -1
View File
@@ -8,7 +8,7 @@
<tr align="center" bgcolor="#e4e4e4">
<td>
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
<p>Last Updated: May 12, 2010</p>
<p>Last Updated: May 26, 2010</p>
</td>
</tr>
</table>
@@ -1752,6 +1752,19 @@ nuttx-5.6 2010-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;
* drivers/lcd/p14201.c - Driver for RiT P14201 series 128x96 4-bit OLED.
* configs/lm3s6965-ek/nx - NX graphics configuration for the LM3S6965
Ethernet Evaluation Kit.
* graphics/ - Numerous fixes to get the P14201 4-bpp greyscale display
working (there may still be some minor issues .. see the TODO list).
* arch/arm/include/lpc17xx and arch/arm/src/lpc17xxx - Began port for
NXP LPC1768
* drivers/mtd/m25px.c - Add support for M25P1 flash part (See NOTE)
* include/nuttx/i2c.h - Extended I2C interface definition to handle
multiple transfers (See NOTE).
* include/nuttx/usbdev.h - Corrected an important macro definition
needed to correctly handle USB null packet transfers (See NOTE).
* arch/arm/src/lpc313x - New drivers: I2C and SPI. Plus several
important LPC313x USB bug fixes (See NOTE).
NOTE: Contributed by David Hewson.
pascal-2.1 2010-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;
+11 -2
View File
@@ -1,4 +1,4 @@
NuttX TODO List (Last updated May 16, 2010)
NuttX TODO List (Last updated May 19, 2010)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(5) Task/Scheduler (sched/)
@@ -12,7 +12,7 @@ NuttX TODO List (Last updated May 16, 2010)
(1) USB (drivers/usbdev)
(5) Libraries (lib/)
(12) File system/Generic drivers (fs/, drivers/)
(2) Graphics subystem (graphics/)
(3) Graphics subystem (graphics/)
(1) Pascal add-on (pcode/)
(1) Documentation (Documentation/)
(6) Build system / Toolchains
@@ -430,6 +430,15 @@ o Graphics subystem (graphics/)
Status: Open
Priority: Medium
Description: The examples/nx test using lcd/p14201.c and the configs/lm3s6965-ek
configuration shows two single pixel-wide anomalies. One along
column zero is clearly caused by the NX windowing logic. It is
not certain if these are consequences of the 4bpp logic or if these
are anomalies that have always been in NX, but are only visible
now at the low resolution of the p14201 LCD (128x96).
Status: Open
Priority: Low (unless you need the p13201 then it is certainly higher).
o Pascal Add-On (pcode/)
^^^^^^^^^^^^^^^^^^^^^^
+7 -2
View File
@@ -40,6 +40,7 @@ CMN_ASRCS = up_cache.S up_fullcontextrestore.S up_saveusercontext.S \
CMN_CSRCS = up_assert.c up_blocktask.c up_copystate.c up_createstack.c \
up_dataabort.c up_mdelay.c up_udelay.c up_exit.c up_idle.c \
up_initialize.c up_initialstate.c up_interruptcontext.c \
up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c \
up_prefetchabort.c up_releasepending.c up_releasestack.c \
up_reprioritizertr.c up_schedulesigaction.c \
up_sigdeliver.c up_syscall.c up_unblocktask.c \
@@ -54,5 +55,9 @@ CGU_CSRCS = lpc313x_bcrndx.c lpc313x_clkdomain.c lpc313x_clkexten.c \
CHIP_ASRCS = $(CGU_ASRCS)
CHIP_CSRCS = lpc313x_allocateheap.c lpc313x_boot.c lpc313x_decodeirq.c \
lpc313x_irq.c lpc313x_lowputc.c lpc313x_serial.c \
lpc313x_timerisr.c lpc313x_usbdev.c $(CGU_CSRCS)
lpc313x_irq.c lpc313x_lowputc.c lpc313x_serial.c lpc313x_i2c.c \
lpc313x_spi.c lpc313x_timerisr.c $(CGU_CSRCS)
ifeq ($(CONFIG_USBDEV),y)
CHIP_CSRCS += lpc313x_usbdev.c
endif
+1 -1
View File
@@ -85,7 +85,7 @@
*/
#define ADC_RX_SHIFT (0) /* Bits 0-9: Digital conversion data */
#define ADC_RX_MASK (0x3ff << LPC313X_ADC_RX_SHIFT)
#define ADC_RX_MASK (0x3ff << ADC_RX_SHIFT)
/* ADC_CON, address 0x13002020 */
+4 -4
View File
@@ -86,7 +86,7 @@
#define LPC313X_EVNTRTR_CGUWKUPMASK_OFFSET(b) (0x1400+_OB(4,b)) /* cgu_wakeup mask */
#define LPC313X_EVNTRTR_INTOUTMASKCLR_OFFSET(o,b) (0x1800+_OB(o,b)) /* Interrupt output 'o' mask clear */
#define LPC313X_EVNTRTR_CGUWKUPMASKCLR_OFFSET(b) (0x1800+_OB(4,b)) /* cgu_wakeup mask clear */
#define LPC313X_EVNTRTR_INTOUTPMASKSET_OFFSET(o,b) (0x1c00+_OB(o,b)) /* Interrupt output 'o' mask set */
#define LPC313X_EVNTRTR_INTOUTMASKSET_OFFSET(o,b) (0x1c00+_OB(o,b)) /* Interrupt output 'o' mask set */
#define LPC313X_EVNTRTR_CGUWKUPMASKSET_OFFSET(b) (0x1c00+_OB(4,b)) /* cgu_wakeup mask set */
/* EVNTRTR register (virtual) addresses *********************************************************************/
@@ -96,7 +96,7 @@
#define LPC313X_EVNTRTR_INTSET(b) (LPC313X_EVNTRTR_VBASE+LPC313X_EVNTRTR_INTSET_OFFSET(b))
#define LPC313X_EVNTRTR_MASK(b) (LPC313X_EVNTRTR_VBASE+LPC313X_EVNTRTR_MASK_OFFSET(b))
#define LPC313X_EVNTRTR_MASKCLR(b) (LPC313X_EVNTRTR_VBASE+LPC313X_EVNTRTR_MASKCLR_OFFSET(b))
#define LPC313X_EVNTRTR_PEND(b) (LPC313X_EVNTRTR_VBASE+LPC313X_EVNTRTR_PEND_OFFSET(b))
#define LPC313X_EVNTRTR_MASKSET(b) (LPC313X_EVNTRTR_VBASE+LPC313X_EVNTRTR_MASKSET_OFFSET(b))
#define LPC313X_EVNTRTR_APR(b) (LPC313X_EVNTRTR_VBASE+LPC313X_EVNTRTR_APR_OFFSET(b))
#define LPC313X_EVNTRTR_ATR(b) (LPC313X_EVNTRTR_VBASE+LPC313X_EVNTRTR_ATR_OFFSET(b))
#define LPC313X_EVNTRTR_RSR(b) (LPC313X_EVNTRTR_VBASE+LPC313X_EVNTRTR_RSR_OFFSET(b))
@@ -107,8 +107,8 @@
#define LPC313X_EVNTRTR_CGUWKUPMASK(b) (LPC313X_EVNTRTR_VBASE+LPC313X_EVNTRTR_CGUWKUPMASK_OFFSET(b))
#define LPC313X_EVNTRTR_INTOUTMASKCLR(o,b) (LPC313X_EVNTRTR_VBASE+LPC313X_EVNTRTR_INTOUTMASKCLR_OFFSET(o,b))
#define LPC313X_EVNTRTR_CGUWKUPMASKCLR(b) (LPC313X_EVNTRTR_VBASE+LPC313X_EVNTRTR_CGUWKUPMASKCLR_OFFSET(b))
#define LPC313X_EVNTRTR_INTOUTPMASKSET(o,b) (LPC313X_EVNTRTR_VBASE+LPC313X_EVNTRTR_INTOUTPMASKSET_OFFSET(o,b))
#define LPC313X_EVNTRTR_CGUWKUPMASKSET(b) (LPC313X_EVNTRTR_VBASE+LPC313X_EVNTRTR_INTOUTPMASKSET_OFFSET(b)
#define LPC313X_EVNTRTR_INTOUTMASKSET(o,b) (LPC313X_EVNTRTR_VBASE+LPC313X_EVNTRTR_INTOUTMASKSET_OFFSET(o,b))
#define LPC313X_EVNTRTR_CGUWKUPMASKSET(b) (LPC313X_EVNTRTR_VBASE+LPC313X_EVNTRTR_CGUWKUPMASKSET_OFFSET(b)
/* EVNTRTR event definitions ********************************************************************************/
/* Bank 0 */
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -76,9 +76,9 @@
#define LPC313X_IOCONFIG_MODE0SET_OFFSET 0x014 /* WR:Set Bits RD:Read Mode 0 */
#define LPC313X_IOCONFIG_MODE0RESET_OFFSET 0x018 /* WR:Reset Bits RD: */
/* 0x01c: Reserved */
#define LPC313X_IOCONFIG_MODE1_OFFSET 0x010 /* WR:Load RD: */
#define LPC313X_IOCONFIG_MODE1SET_OFFSET 0x014 /* WR:Set Bits RD:Read Mode 1 */
#define LPC313X_IOCONFIG_MODE1RESET_OFFSET 0x018 /* WR:Reset Bits RD: */
#define LPC313X_IOCONFIG_MODE1_OFFSET 0x020 /* WR:Load RD: */
#define LPC313X_IOCONFIG_MODE1SET_OFFSET 0x024 /* WR:Set Bits RD:Read Mode 1 */
#define LPC313X_IOCONFIG_MODE1RESET_OFFSET 0x028 /* WR:Reset Bits RD: */
/* 0x02c-0x3c: Reserved */
/* IOCONFIG function block (virtual) base addresses *********************************************/
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -143,7 +143,7 @@
# define SPI_SLVENABLE2_DISABLED (0 << SPI_SLVENABLE2_SHIFT) /* Disabled */
# define SPI_SLVENABLE2_ENABLED (1 << SPI_SLVENABLE2_SHIFT) /* Enabled */
# define SPI_SLVENABLE2_SUSPENDED (3 << SPI_SLVENABLE2_SHIFT) /* Suspended */
#define SPI_SLVENABLE1_SHIFT (0) /* Bits 0-1: Slave 3 enable bits */
#define SPI_SLVENABLE1_SHIFT (0) /* Bits 0-1: Slave 1 enable bits */
#define SPI_SLVENABLE1_MASK (3 << SPI_SLVENABLE1_SHIFT)
# define SPI_SLVENABLE1_DISABLED (0 << SPI_SLVENABLE1_SHIFT) /* Disabled */
# define SPI_SLVENABLE1_ENABLED (1 << SPI_SLVENABLE1_SHIFT) /* Enabled */
+43 -72
View File
@@ -282,7 +282,6 @@ struct lpc313x_ep_s
struct lpc313x_req_s *tail;
uint8_t epphy; /* Physical EP address */
uint8_t stalled:1; /* 1: Endpoint is stalled */
uint8_t halted:1; /* 1: Endpoint feature halted */
};
/* This structure retains the state of the USB device controller */
@@ -364,12 +363,11 @@ static void lpc313x_readsetup(uint8_t epphy, struct usb_ctrlreq_s *ctrl);
static inline void lpc313x_set_address(struct lpc313x_usbdev_s *priv, uint16_t address);
static void lpc313x_flushep(struct lpc313x_ep_s *privep);
static inline bool lpc313x_epstalled(struct lpc313x_ep_s *privep);
static int lpc313x_progressep(struct lpc313x_ep_s *privep);
static inline void lpc313x_abortrequest(struct lpc313x_ep_s *privep,
struct lpc313x_req_s *privreq, int16_t result);
static void lpc313x_reqcomplete(struct lpc313x_ep_s *privep, int16_t result);
static void lpc313x_reqcomplete(struct lpc313x_ep_s *privep, struct lpc313x_req_s *privreq, int16_t result);
static void lpc313x_cancelrequests(struct lpc313x_ep_s *privep, int16_t status);
@@ -768,24 +766,6 @@ static void lpc313x_flushep(struct lpc313x_ep_s *privep)
}
/*******************************************************************************
* Name: lpc313x_epstalled
*
* Description:
* Return whether the endpoint is stalled or not
*
*******************************************************************************/
static inline bool lpc313x_epstalled(struct lpc313x_ep_s *privep)
{
uint32_t ctrl = lpc313x_getreg (LPC313X_USBDEV_ENDPTCTRL(privep->epphy));
if (LPC313X_EPPHYIN(privep->epphy))
return (ctrl & USBDEV_ENDPTCTRL_TXS);
else
return (ctrl & USBDEV_ENDPTCTRL_RXS);
}
/*******************************************************************************
* Name: lpc313x_progressep
*
@@ -825,7 +805,7 @@ static int lpc313x_progressep(struct lpc313x_ep_s *privep)
usbtrace(TRACE_DEVERROR(LPC313X_TRACEERR_EPOUTNULLPACKET), 0);
}
lpc313x_reqcomplete(privep, OK);
lpc313x_reqcomplete(privep, lpc313x_rqdequeue(privep), OK);
return OK;
}
@@ -836,15 +816,13 @@ static int lpc313x_progressep(struct lpc313x_ep_s *privep)
int bytesleft = privreq->req.len - privreq->req.xfrd;
if (bytesleft > privep->ep.maxpacket)
bytesleft = privep->ep.maxpacket;
if (LPC313X_EPPHYIN(privep->epphy))
usbtrace(TRACE_WRITE(privep->epphy), privreq->req.xfrd);
else
usbtrace(TRACE_READ(privep->epphy), privreq->req.xfrd);
/* Initialise the DTD to transfer the next chunk */
lpc313x_writedtd (dtd, privreq->req.buf + privreq->req.xfrd, bytesleft);
/* then queue onto the DQH */
@@ -884,39 +862,27 @@ static inline void lpc313x_abortrequest(struct lpc313x_ep_s *privep,
*
*******************************************************************************/
static void lpc313x_reqcomplete(struct lpc313x_ep_s *privep, int16_t result)
static void lpc313x_reqcomplete(struct lpc313x_ep_s *privep, struct lpc313x_req_s *privreq, int16_t result)
{
struct lpc313x_req_s *privreq;
irqstate_t flags;
/* If endpoint 0, temporarily reflect the state of protocol stalled
* in the callback.
*/
/* Remove the completed request at the head of the endpoint request list */
bool stalled = privep->stalled;
if (privep->epphy == LPC313X_EP0_IN)
privep->stalled = privep->dev->stalled;
flags = irqsave();
privreq = lpc313x_rqdequeue(privep);
irqrestore(flags);
/* Save the result in the request structure */
if (privreq)
{
/* If endpoint 0, temporarily reflect the state of protocol stalled
* in the callback.
*/
privreq->req.result = result;
bool stalled = privep->stalled;
if (privep->epphy == LPC313X_EP0_IN)
privep->stalled = privep->dev->stalled;
/* Callback to the request completion handler */
/* Save the result in the request structure */
privreq->req.callback(&privep->ep, &privreq->req);
privreq->req.result = result;
/* Restore the stalled indication */
/* Callback to the request completion handler */
privreq->req.callback(&privep->ep, &privreq->req);
/* Restore the stalled indication */
privep->stalled = stalled;
}
privep->stalled = stalled;
}
/*******************************************************************************
@@ -938,7 +904,7 @@ static void lpc313x_cancelrequests(struct lpc313x_ep_s *privep, int16_t status)
// FIXME: only report the error status if the transfer hasn't completed
usbtrace(TRACE_COMPLETE(privep->epphy),
(lpc313x_rqpeek(privep))->req.xfrd);
lpc313x_reqcomplete(privep, status);
lpc313x_reqcomplete(privep, lpc313x_rqdequeue(privep), status);
}
}
@@ -1083,7 +1049,6 @@ static void lpc313x_usbreset(struct lpc313x_usbdev_s *priv)
/* Reset endpoint status */
privep->stalled = false;
privep->halted = false;
}
/* Tell the class driver that we are disconnected. The class
@@ -1221,7 +1186,7 @@ static inline void lpc313x_ep0setup(struct lpc313x_usbdev_s *priv)
}
else
{
if (lpc313x_epstalled(privep))
if (privep->stalled)
priv->ep0buf[0] = 1; /* Stalled */
else
priv->ep0buf[0] = 0; /* Not stalled */
@@ -1294,8 +1259,6 @@ static inline void lpc313x_ep0setup(struct lpc313x_usbdev_s *priv)
else if (priv->paddrset != 0 && value == USB_FEATURE_ENDPOINTHALT && len == 0 &&
(privep = lpc313x_epfindbyaddr(priv, index)) != NULL)
{
privep->halted = 0;
lpc313x_epstall(&privep->ep, true);
lpc313x_ep0state (priv, EP0STATE_WAIT_NAK_IN);
@@ -1329,8 +1292,6 @@ static inline void lpc313x_ep0setup(struct lpc313x_usbdev_s *priv)
else if (priv->paddrset != 0 && value == USB_FEATURE_ENDPOINTHALT && len == 0 &&
(privep = lpc313x_epfindbyaddr(priv, index)) != NULL)
{
privep->halted = 1;
lpc313x_epstall(&privep->ep, false);
lpc313x_ep0state (priv, EP0STATE_WAIT_NAK_IN);
@@ -1623,13 +1584,11 @@ lpc313x_epcomplete(struct lpc313x_usbdev_s *priv, uint8_t epphy)
privreq->req.xfrd += xfrd;
bool complete;
bool complete = true;
if (LPC313X_EPPHYOUT(privep->epphy))
{
/* read(OUT) completes when request filled, or a short transfer is received */
complete = (privreq->req.xfrd >= privreq->req.len || xfrd < privep->ep.maxpacket);
usbtrace(TRACE_INTDECODE(LPC313X_TRACEINTID_EPIN), complete);
}
else
@@ -1643,15 +1602,25 @@ lpc313x_epcomplete(struct lpc313x_usbdev_s *priv, uint8_t epphy)
usbtrace(TRACE_INTDECODE(LPC313X_TRACEINTID_EPOUT), complete);
}
/* If the transfer is complete, then dequeue and progress any further queued requests */
if (complete)
{
privreq = lpc313x_rqdequeue (privep);
}
if (!lpc313x_rqempty(privep))
{
lpc313x_progressep(privep);
}
/* Now it's safe to call the completion callback as it may well submit a new request */
if (complete)
{
usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd);
lpc313x_reqcomplete(privep, OK);
lpc313x_reqcomplete(privep, privreq, OK);
}
/* If there's more requests, then progress them */
if (!lpc313x_rqempty(privep))
lpc313x_progressep(privep);
return complete;
}
@@ -1863,6 +1832,9 @@ static int lpc313x_epconfigure(FAR struct usbdev_ep_s *ep,
lpc313x_chgbits (0x0000FFFF, cfg, LPC313X_USBDEV_ENDPTCTRL(privep->epphy));
}
/* Reset endpoint status */
privep->stalled = false;
/* Enable the endpoint */
if (LPC313X_EPPHYIN(privep->epphy))
lpc313x_setbits (USBDEV_ENDPTCTRL_TXE, LPC313X_USBDEV_ENDPTCTRL(privep->epphy));
@@ -1902,11 +1874,11 @@ static int lpc313x_epdisable(FAR struct usbdev_ep_s *ep)
else
lpc313x_clrbits (USBDEV_ENDPTCTRL_RXE, LPC313X_USBDEV_ENDPTCTRL(privep->epphy));
privep->stalled = true;
/* Cancel any ongoing activity */
lpc313x_cancelrequests(privep, -ESHUTDOWN);
privep->halted = 1;
irqrestore(flags);
return OK;
}
@@ -2048,12 +2020,8 @@ static int lpc313x_epsubmit(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s
if (privep->stalled)
{
lpc313x_abortrequest(privep, privreq, -EBUSY);
ret = -EBUSY;
}
/* Handle IN (device-to-host) requests */
else
{
/* Add the new request to the request queue for the endpoint */
@@ -2061,10 +2029,12 @@ static int lpc313x_epsubmit(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s
if (LPC313X_EPPHYIN(privep->epphy))
usbtrace(TRACE_INREQQUEUED(privep->epphy), privreq->req.len);
else
usbtrace(TRACE_OUTREQQUEUED(privep->epphy), privreq->req.len);
usbtrace(TRACE_OUTREQQUEUED(privep->epphy), privreq->req.len);
if (lpc313x_rqenqueue(privep, privreq))
{
lpc313x_progressep(privep);
}
}
irqrestore(flags);
@@ -2676,3 +2646,4 @@ int usbdev_unregister(struct usbdevclass_driver_s *driver)
g_usbdev.driver = NULL;
return OK;
}