mirror of
https://github.com/apache/nuttx.git
synced 2026-05-30 05:16:47 +08:00
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:
@@ -1129,3 +1129,16 @@
|
|||||||
* drivers/lcd/p14201.c - Driver for RiT P14201 series 128x96 4-bit OLED.
|
* drivers/lcd/p14201.c - Driver for RiT P14201 series 128x96 4-bit OLED.
|
||||||
* configs/lm3s6965-ek/nx - NX graphics configuration for the LM3S6965
|
* configs/lm3s6965-ek/nx - NX graphics configuration for the LM3S6965
|
||||||
Ethernet Evaluation Kit.
|
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.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<tr align="center" bgcolor="#e4e4e4">
|
<tr align="center" bgcolor="#e4e4e4">
|
||||||
<td>
|
<td>
|
||||||
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
|
<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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -1752,6 +1752,19 @@ nuttx-5.6 2010-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
|||||||
* drivers/lcd/p14201.c - Driver for RiT P14201 series 128x96 4-bit OLED.
|
* drivers/lcd/p14201.c - Driver for RiT P14201 series 128x96 4-bit OLED.
|
||||||
* configs/lm3s6965-ek/nx - NX graphics configuration for the LM3S6965
|
* configs/lm3s6965-ek/nx - NX graphics configuration for the LM3S6965
|
||||||
Ethernet Evaluation Kit.
|
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 <spudmonkey@racsa.co.cr>
|
pascal-2.1 2010-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
NuttX TODO List (Last updated May 16, 2010)
|
NuttX TODO List (Last updated May 19, 2010)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
(5) Task/Scheduler (sched/)
|
(5) Task/Scheduler (sched/)
|
||||||
@@ -12,7 +12,7 @@ NuttX TODO List (Last updated May 16, 2010)
|
|||||||
(1) USB (drivers/usbdev)
|
(1) USB (drivers/usbdev)
|
||||||
(5) Libraries (lib/)
|
(5) Libraries (lib/)
|
||||||
(12) File system/Generic drivers (fs/, drivers/)
|
(12) File system/Generic drivers (fs/, drivers/)
|
||||||
(2) Graphics subystem (graphics/)
|
(3) Graphics subystem (graphics/)
|
||||||
(1) Pascal add-on (pcode/)
|
(1) Pascal add-on (pcode/)
|
||||||
(1) Documentation (Documentation/)
|
(1) Documentation (Documentation/)
|
||||||
(6) Build system / Toolchains
|
(6) Build system / Toolchains
|
||||||
@@ -430,6 +430,15 @@ o Graphics subystem (graphics/)
|
|||||||
Status: Open
|
Status: Open
|
||||||
Priority: Medium
|
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/)
|
o Pascal Add-On (pcode/)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|||||||
@@ -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 \
|
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_dataabort.c up_mdelay.c up_udelay.c up_exit.c up_idle.c \
|
||||||
up_initialize.c up_initialstate.c up_interruptcontext.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_prefetchabort.c up_releasepending.c up_releasestack.c \
|
||||||
up_reprioritizertr.c up_schedulesigaction.c \
|
up_reprioritizertr.c up_schedulesigaction.c \
|
||||||
up_sigdeliver.c up_syscall.c up_unblocktask.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_ASRCS = $(CGU_ASRCS)
|
||||||
CHIP_CSRCS = lpc313x_allocateheap.c lpc313x_boot.c lpc313x_decodeirq.c \
|
CHIP_CSRCS = lpc313x_allocateheap.c lpc313x_boot.c lpc313x_decodeirq.c \
|
||||||
lpc313x_irq.c lpc313x_lowputc.c lpc313x_serial.c \
|
lpc313x_irq.c lpc313x_lowputc.c lpc313x_serial.c lpc313x_i2c.c \
|
||||||
lpc313x_timerisr.c lpc313x_usbdev.c $(CGU_CSRCS)
|
lpc313x_spi.c lpc313x_timerisr.c $(CGU_CSRCS)
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_USBDEV),y)
|
||||||
|
CHIP_CSRCS += lpc313x_usbdev.c
|
||||||
|
endif
|
||||||
|
|||||||
@@ -85,7 +85,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define ADC_RX_SHIFT (0) /* Bits 0-9: Digital conversion data */
|
#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 */
|
/* ADC_CON, address 0x13002020 */
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,7 @@
|
|||||||
#define LPC313X_EVNTRTR_CGUWKUPMASK_OFFSET(b) (0x1400+_OB(4,b)) /* cgu_wakeup mask */
|
#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_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_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 */
|
#define LPC313X_EVNTRTR_CGUWKUPMASKSET_OFFSET(b) (0x1c00+_OB(4,b)) /* cgu_wakeup mask set */
|
||||||
|
|
||||||
/* EVNTRTR register (virtual) addresses *********************************************************************/
|
/* EVNTRTR register (virtual) addresses *********************************************************************/
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
#define LPC313X_EVNTRTR_INTSET(b) (LPC313X_EVNTRTR_VBASE+LPC313X_EVNTRTR_INTSET_OFFSET(b))
|
#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_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_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_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_ATR(b) (LPC313X_EVNTRTR_VBASE+LPC313X_EVNTRTR_ATR_OFFSET(b))
|
||||||
#define LPC313X_EVNTRTR_RSR(b) (LPC313X_EVNTRTR_VBASE+LPC313X_EVNTRTR_RSR_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_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_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_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_INTOUTMASKSET(o,b) (LPC313X_EVNTRTR_VBASE+LPC313X_EVNTRTR_INTOUTMASKSET_OFFSET(o,b))
|
||||||
#define LPC313X_EVNTRTR_CGUWKUPMASKSET(b) (LPC313X_EVNTRTR_VBASE+LPC313X_EVNTRTR_INTOUTPMASKSET_OFFSET(b)
|
#define LPC313X_EVNTRTR_CGUWKUPMASKSET(b) (LPC313X_EVNTRTR_VBASE+LPC313X_EVNTRTR_CGUWKUPMASKSET_OFFSET(b)
|
||||||
|
|
||||||
/* EVNTRTR event definitions ********************************************************************************/
|
/* EVNTRTR event definitions ********************************************************************************/
|
||||||
/* Bank 0 */
|
/* Bank 0 */
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -76,9 +76,9 @@
|
|||||||
#define LPC313X_IOCONFIG_MODE0SET_OFFSET 0x014 /* WR:Set Bits RD:Read Mode 0 */
|
#define LPC313X_IOCONFIG_MODE0SET_OFFSET 0x014 /* WR:Set Bits RD:Read Mode 0 */
|
||||||
#define LPC313X_IOCONFIG_MODE0RESET_OFFSET 0x018 /* WR:Reset Bits RD: */
|
#define LPC313X_IOCONFIG_MODE0RESET_OFFSET 0x018 /* WR:Reset Bits RD: */
|
||||||
/* 0x01c: Reserved */
|
/* 0x01c: Reserved */
|
||||||
#define LPC313X_IOCONFIG_MODE1_OFFSET 0x010 /* WR:Load RD: */
|
#define LPC313X_IOCONFIG_MODE1_OFFSET 0x020 /* WR:Load RD: */
|
||||||
#define LPC313X_IOCONFIG_MODE1SET_OFFSET 0x014 /* WR:Set Bits RD:Read Mode 1 */
|
#define LPC313X_IOCONFIG_MODE1SET_OFFSET 0x024 /* WR:Set Bits RD:Read Mode 1 */
|
||||||
#define LPC313X_IOCONFIG_MODE1RESET_OFFSET 0x018 /* WR:Reset Bits RD: */
|
#define LPC313X_IOCONFIG_MODE1RESET_OFFSET 0x028 /* WR:Reset Bits RD: */
|
||||||
/* 0x02c-0x3c: Reserved */
|
/* 0x02c-0x3c: Reserved */
|
||||||
|
|
||||||
/* IOCONFIG function block (virtual) base addresses *********************************************/
|
/* IOCONFIG function block (virtual) base addresses *********************************************/
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -143,7 +143,7 @@
|
|||||||
# define SPI_SLVENABLE2_DISABLED (0 << SPI_SLVENABLE2_SHIFT) /* Disabled */
|
# define SPI_SLVENABLE2_DISABLED (0 << SPI_SLVENABLE2_SHIFT) /* Disabled */
|
||||||
# define SPI_SLVENABLE2_ENABLED (1 << SPI_SLVENABLE2_SHIFT) /* Enabled */
|
# define SPI_SLVENABLE2_ENABLED (1 << SPI_SLVENABLE2_SHIFT) /* Enabled */
|
||||||
# define SPI_SLVENABLE2_SUSPENDED (3 << SPI_SLVENABLE2_SHIFT) /* Suspended */
|
# 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_MASK (3 << SPI_SLVENABLE1_SHIFT)
|
||||||
# define SPI_SLVENABLE1_DISABLED (0 << SPI_SLVENABLE1_SHIFT) /* Disabled */
|
# define SPI_SLVENABLE1_DISABLED (0 << SPI_SLVENABLE1_SHIFT) /* Disabled */
|
||||||
# define SPI_SLVENABLE1_ENABLED (1 << SPI_SLVENABLE1_SHIFT) /* Enabled */
|
# define SPI_SLVENABLE1_ENABLED (1 << SPI_SLVENABLE1_SHIFT) /* Enabled */
|
||||||
|
|||||||
@@ -282,7 +282,6 @@ struct lpc313x_ep_s
|
|||||||
struct lpc313x_req_s *tail;
|
struct lpc313x_req_s *tail;
|
||||||
uint8_t epphy; /* Physical EP address */
|
uint8_t epphy; /* Physical EP address */
|
||||||
uint8_t stalled:1; /* 1: Endpoint is stalled */
|
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 */
|
/* 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 inline void lpc313x_set_address(struct lpc313x_usbdev_s *priv, uint16_t address);
|
||||||
|
|
||||||
static void lpc313x_flushep(struct lpc313x_ep_s *privep);
|
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 int lpc313x_progressep(struct lpc313x_ep_s *privep);
|
||||||
static inline void lpc313x_abortrequest(struct lpc313x_ep_s *privep,
|
static inline void lpc313x_abortrequest(struct lpc313x_ep_s *privep,
|
||||||
struct lpc313x_req_s *privreq, int16_t result);
|
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);
|
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
|
* Name: lpc313x_progressep
|
||||||
*
|
*
|
||||||
@@ -825,7 +805,7 @@ static int lpc313x_progressep(struct lpc313x_ep_s *privep)
|
|||||||
usbtrace(TRACE_DEVERROR(LPC313X_TRACEERR_EPOUTNULLPACKET), 0);
|
usbtrace(TRACE_DEVERROR(LPC313X_TRACEERR_EPOUTNULLPACKET), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
lpc313x_reqcomplete(privep, OK);
|
lpc313x_reqcomplete(privep, lpc313x_rqdequeue(privep), OK);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -836,15 +816,13 @@ static int lpc313x_progressep(struct lpc313x_ep_s *privep)
|
|||||||
|
|
||||||
int bytesleft = privreq->req.len - privreq->req.xfrd;
|
int bytesleft = privreq->req.len - privreq->req.xfrd;
|
||||||
|
|
||||||
if (bytesleft > privep->ep.maxpacket)
|
|
||||||
bytesleft = privep->ep.maxpacket;
|
|
||||||
|
|
||||||
if (LPC313X_EPPHYIN(privep->epphy))
|
if (LPC313X_EPPHYIN(privep->epphy))
|
||||||
usbtrace(TRACE_WRITE(privep->epphy), privreq->req.xfrd);
|
usbtrace(TRACE_WRITE(privep->epphy), privreq->req.xfrd);
|
||||||
else
|
else
|
||||||
usbtrace(TRACE_READ(privep->epphy), privreq->req.xfrd);
|
usbtrace(TRACE_READ(privep->epphy), privreq->req.xfrd);
|
||||||
|
|
||||||
/* Initialise the DTD to transfer the next chunk */
|
/* Initialise the DTD to transfer the next chunk */
|
||||||
|
|
||||||
lpc313x_writedtd (dtd, privreq->req.buf + privreq->req.xfrd, bytesleft);
|
lpc313x_writedtd (dtd, privreq->req.buf + privreq->req.xfrd, bytesleft);
|
||||||
|
|
||||||
/* then queue onto the DQH */
|
/* 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;
|
/* If endpoint 0, temporarily reflect the state of protocol stalled
|
||||||
irqstate_t flags;
|
* 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();
|
/* Save the result in the request structure */
|
||||||
privreq = lpc313x_rqdequeue(privep);
|
|
||||||
irqrestore(flags);
|
|
||||||
|
|
||||||
if (privreq)
|
privreq->req.result = result;
|
||||||
{
|
|
||||||
/* If endpoint 0, temporarily reflect the state of protocol stalled
|
|
||||||
* in the callback.
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool stalled = privep->stalled;
|
/* Callback to the request completion handler */
|
||||||
if (privep->epphy == LPC313X_EP0_IN)
|
|
||||||
privep->stalled = privep->dev->stalled;
|
|
||||||
|
|
||||||
/* 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 */
|
privep->stalled = stalled;
|
||||||
|
|
||||||
privreq->req.callback(&privep->ep, &privreq->req);
|
|
||||||
|
|
||||||
/* Restore the stalled indication */
|
|
||||||
|
|
||||||
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
|
// FIXME: only report the error status if the transfer hasn't completed
|
||||||
usbtrace(TRACE_COMPLETE(privep->epphy),
|
usbtrace(TRACE_COMPLETE(privep->epphy),
|
||||||
(lpc313x_rqpeek(privep))->req.xfrd);
|
(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 */
|
/* Reset endpoint status */
|
||||||
privep->stalled = false;
|
privep->stalled = false;
|
||||||
privep->halted = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tell the class driver that we are disconnected. The class
|
/* 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
|
else
|
||||||
{
|
{
|
||||||
if (lpc313x_epstalled(privep))
|
if (privep->stalled)
|
||||||
priv->ep0buf[0] = 1; /* Stalled */
|
priv->ep0buf[0] = 1; /* Stalled */
|
||||||
else
|
else
|
||||||
priv->ep0buf[0] = 0; /* Not stalled */
|
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 &&
|
else if (priv->paddrset != 0 && value == USB_FEATURE_ENDPOINTHALT && len == 0 &&
|
||||||
(privep = lpc313x_epfindbyaddr(priv, index)) != NULL)
|
(privep = lpc313x_epfindbyaddr(priv, index)) != NULL)
|
||||||
{
|
{
|
||||||
privep->halted = 0;
|
|
||||||
|
|
||||||
lpc313x_epstall(&privep->ep, true);
|
lpc313x_epstall(&privep->ep, true);
|
||||||
|
|
||||||
lpc313x_ep0state (priv, EP0STATE_WAIT_NAK_IN);
|
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 &&
|
else if (priv->paddrset != 0 && value == USB_FEATURE_ENDPOINTHALT && len == 0 &&
|
||||||
(privep = lpc313x_epfindbyaddr(priv, index)) != NULL)
|
(privep = lpc313x_epfindbyaddr(priv, index)) != NULL)
|
||||||
{
|
{
|
||||||
privep->halted = 1;
|
|
||||||
|
|
||||||
lpc313x_epstall(&privep->ep, false);
|
lpc313x_epstall(&privep->ep, false);
|
||||||
|
|
||||||
lpc313x_ep0state (priv, EP0STATE_WAIT_NAK_IN);
|
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;
|
privreq->req.xfrd += xfrd;
|
||||||
|
|
||||||
bool complete;
|
bool complete = true;
|
||||||
if (LPC313X_EPPHYOUT(privep->epphy))
|
if (LPC313X_EPPHYOUT(privep->epphy))
|
||||||
{
|
{
|
||||||
/* read(OUT) completes when request filled, or a short transfer is received */
|
/* 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);
|
usbtrace(TRACE_INTDECODE(LPC313X_TRACEINTID_EPIN), complete);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1643,15 +1602,25 @@ lpc313x_epcomplete(struct lpc313x_usbdev_s *priv, uint8_t epphy)
|
|||||||
usbtrace(TRACE_INTDECODE(LPC313X_TRACEINTID_EPOUT), complete);
|
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)
|
if (complete)
|
||||||
{
|
{
|
||||||
usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd);
|
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;
|
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));
|
lpc313x_chgbits (0x0000FFFF, cfg, LPC313X_USBDEV_ENDPTCTRL(privep->epphy));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reset endpoint status */
|
||||||
|
privep->stalled = false;
|
||||||
|
|
||||||
/* Enable the endpoint */
|
/* Enable the endpoint */
|
||||||
if (LPC313X_EPPHYIN(privep->epphy))
|
if (LPC313X_EPPHYIN(privep->epphy))
|
||||||
lpc313x_setbits (USBDEV_ENDPTCTRL_TXE, LPC313X_USBDEV_ENDPTCTRL(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
|
else
|
||||||
lpc313x_clrbits (USBDEV_ENDPTCTRL_RXE, LPC313X_USBDEV_ENDPTCTRL(privep->epphy));
|
lpc313x_clrbits (USBDEV_ENDPTCTRL_RXE, LPC313X_USBDEV_ENDPTCTRL(privep->epphy));
|
||||||
|
|
||||||
|
privep->stalled = true;
|
||||||
|
|
||||||
/* Cancel any ongoing activity */
|
/* Cancel any ongoing activity */
|
||||||
lpc313x_cancelrequests(privep, -ESHUTDOWN);
|
lpc313x_cancelrequests(privep, -ESHUTDOWN);
|
||||||
|
|
||||||
privep->halted = 1;
|
|
||||||
|
|
||||||
irqrestore(flags);
|
irqrestore(flags);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@@ -2048,12 +2020,8 @@ static int lpc313x_epsubmit(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s
|
|||||||
|
|
||||||
if (privep->stalled)
|
if (privep->stalled)
|
||||||
{
|
{
|
||||||
lpc313x_abortrequest(privep, privreq, -EBUSY);
|
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle IN (device-to-host) requests */
|
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Add the new request to the request queue for the endpoint */
|
/* 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))
|
if (LPC313X_EPPHYIN(privep->epphy))
|
||||||
usbtrace(TRACE_INREQQUEUED(privep->epphy), privreq->req.len);
|
usbtrace(TRACE_INREQQUEUED(privep->epphy), privreq->req.len);
|
||||||
else
|
else
|
||||||
usbtrace(TRACE_OUTREQQUEUED(privep->epphy), privreq->req.len);
|
usbtrace(TRACE_OUTREQQUEUED(privep->epphy), privreq->req.len);
|
||||||
|
|
||||||
if (lpc313x_rqenqueue(privep, privreq))
|
if (lpc313x_rqenqueue(privep, privreq))
|
||||||
|
{
|
||||||
lpc313x_progressep(privep);
|
lpc313x_progressep(privep);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
irqrestore(flags);
|
irqrestore(flags);
|
||||||
@@ -2676,3 +2646,4 @@ int usbdev_unregister(struct usbdevclass_driver_s *driver)
|
|||||||
g_usbdev.driver = NULL;
|
g_usbdev.driver = NULL;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user