Merged nuttx/arch into master
This commit is contained in:
commit
bf9fdfa447
@ -565,9 +565,9 @@
|
||||
|
||||
#define USBHOST_USBMODE_CM_SHIFT (0) /* Bits 0-1: Controller mode */
|
||||
#define USBHOST_USBMODE_CM_MASK (3 << USBHOST_USBMODE_CM_SHIFT)
|
||||
#define USBHOST_USBMODE_CM_IDLE (0 << USBHOST_USBMODE_CM_SHIFT) /* Idle */
|
||||
#define USBHOST_USBMODE_CM_DEVICE (2 << USBHOST_USBMODE_CM_SHIFT) /* Device controller */
|
||||
#define USBHOST_USBMODE_CM_HOST (3 << USBHOST_USBMODE_CM_SHIFT) /* Host controller */
|
||||
# define USBHOST_USBMODE_CM_IDLE (0 << USBHOST_USBMODE_CM_SHIFT) /* Idle */
|
||||
# define USBHOST_USBMODE_CM_DEVICE (2 << USBHOST_USBMODE_CM_SHIFT) /* Device controller */
|
||||
# define USBHOST_USBMODE_CM_HOST (3 << USBHOST_USBMODE_CM_SHIFT) /* Host controller */
|
||||
#define USBHOST_USBMODE_ES (1 << 2) /* Bit 2: Endian select */
|
||||
/* Bit 3: Not used in host mode */
|
||||
#define USBHOST_USBMODE_SDIS (1 << 4) /* Bit 4: Stream disable mode */
|
||||
|
@ -428,14 +428,14 @@ static inline void lpc43_m4clkselect(uint32_t clksel)
|
||||
|
||||
void lpc43_pll0usbconfig(void)
|
||||
{
|
||||
//power down, no bypass, direct i-o,
|
||||
putreg32( (PLL0USB_CTRL_PD | PLL0USB_CTRL_DIRECTI | PLL0USB_CTRL_DIRECTO | PLL0USB_CTRL_CLKEN | PLL0USB_CTRL_AUTOBLOCK | BOARD_USB0_CLKSRC), LPC43_PLL0USB_CTRL);
|
||||
/* Power down, no bypass, direct i-o, */
|
||||
|
||||
putreg32((PLL0USB_CTRL_PD | PLL0USB_CTRL_DIRECTI | PLL0USB_CTRL_DIRECTO | PLL0USB_CTRL_CLKEN | PLL0USB_CTRL_AUTOBLOCK | BOARD_USB0_CLKSRC), LPC43_PLL0USB_CTRL);
|
||||
|
||||
putreg32(BOARD_USB0_MDIV, LPC43_PLL0USB_MDIV);
|
||||
putreg32(BOARD_USB0_NP_DIV, LPC43_PLL0USB_NP_DIV);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc43_pll0usbenable
|
||||
*
|
||||
@ -467,7 +467,6 @@ void lpc43_pll0usbenable(void)
|
||||
while ((getreg32(LPC43_PLL0USB_STAT) & PLL0USB_STAT_LOCK) == 0);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc43_pll0usbdisable
|
||||
*
|
||||
@ -489,17 +488,17 @@ void lpc43_pll0usbdisable(void)
|
||||
putreg32(regval, LPC43_PLL0USB_CTRL);
|
||||
}
|
||||
|
||||
#if defined(BOARD_IDIVA_DIVIDER) && defined(BOARD_IDIVA_CLKSRC )
|
||||
#if defined(BOARD_IDIVA_DIVIDER) && defined(BOARD_IDIVA_CLKSRC)
|
||||
void lpc43_idiva(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
//set clock source, divider
|
||||
/* Set clock source, divider */
|
||||
|
||||
regval = getreg32(LPC43_IDIVA_CTRL);
|
||||
regval &= ~( IDIVA_CTRL_CLKSEL_MASK | IDIVA_CTRL_IDIV_MASK );
|
||||
regval &= ~(IDIVA_CTRL_CLKSEL_MASK | IDIVA_CTRL_IDIV_MASK);
|
||||
regval |= BOARD_IDIVA_CLKSRC | IDIVA_CTRL_AUTOBLOCK | IDIVA_CTRL_IDIV(BOARD_IDIVA_DIVIDER);
|
||||
putreg32(regval, LPC43_IDIVA_CTRL);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -508,12 +507,12 @@ void lpc43_idivb(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
//set clock source, divider
|
||||
/* Set clock source, divider */
|
||||
|
||||
regval = getreg32(LPC43_IDIVB_CTRL);
|
||||
regval &= ~( IDIVBCD_CTRL_CLKSEL_MASK | IDIVBCD_CTRL_IDIV_MASK );
|
||||
regval &= ~(IDIVBCD_CTRL_CLKSEL_MASK | IDIVBCD_CTRL_IDIV_MASK);
|
||||
regval |= BOARD_IDIVB_CLKSRC | IDIVBCD_CTRL_AUTOBLOCK | IDIVBCD_CTRL_IDIV(BOARD_IDIVB_DIVIDER);
|
||||
putreg32(regval, LPC43_IDIVB_CTRL);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -522,12 +521,12 @@ void lpc43_idivc(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
//set clock source, divider
|
||||
/* Set clock source, divider */
|
||||
|
||||
regval = getreg32(LPC43_IDIVC_CTRL);
|
||||
regval &= ~( IDIVBCD_CTRL_CLKSEL_MASK | IDIVBCD_CTRL_IDIV_MASK );
|
||||
regval &= ~(IDIVBCD_CTRL_CLKSEL_MASK | IDIVBCD_CTRL_IDIV_MASK);
|
||||
regval |= BOARD_IDIVC_CLKSRC | IDIVBCD_CTRL_AUTOBLOCK | IDIVBCD_CTRL_IDIV(BOARD_IDIVC_DIVIDER);
|
||||
putreg32(regval, LPC43_IDIVC_CTRL);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -536,12 +535,12 @@ void lpc43_idivd(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
//set clock source, divider
|
||||
/* Set clock source, divider */
|
||||
|
||||
regval = getreg32(LPC43_IDIVD_CTRL);
|
||||
regval &= ~( IDIVBCD_CTRL_CLKSEL_MASK | IDIVBCD_CTRL_IDIV_MASK );
|
||||
regval &= ~(IDIVBCD_CTRL_CLKSEL_MASK | IDIVBCD_CTRL_IDIV_MASK);
|
||||
regval |= BOARD_IDIVD_CLKSRC | IDIVBCD_CTRL_AUTOBLOCK | IDIVBCD_CTRL_IDIV(BOARD_IDIVD_DIVIDER);
|
||||
putreg32(regval, LPC43_IDIVD_CTRL);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -550,27 +549,26 @@ void lpc43_idive(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
//set clock source, divider
|
||||
/* Set clock source, divider */
|
||||
|
||||
regval = getreg32(LPC43_IDIVE_CTRL);
|
||||
regval &= ~( IDIVE_CTRL_CLKSEL_MASK | IDIVE_CTRL_IDIV_MASK );
|
||||
regval &= ~(IDIVE_CTRL_CLKSEL_MASK | IDIVE_CTRL_IDIV_MASK);
|
||||
regval |= BOARD_IDIVE_CLKSRC | IDIVE_CTRL_AUTOBLOCK | IDIVE_CTRL_IDIV(BOARD_IDIVE_DIVIDER);
|
||||
putreg32(regval, LPC43_IDIVE_CTRL);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(BOARD_ABP1_CLKSRC)
|
||||
void lpc43_abp1(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
//set clock source
|
||||
/* Set clock source */
|
||||
|
||||
regval = getreg32(LPC43_BASE_APB1_CLK);
|
||||
regval &= ~BASE_APB1_CLK_CLKSEL_MASK;
|
||||
regval |= BOARD_ABP1_CLKSRC | BASE_APB1_CLK_AUTOBLOCK;
|
||||
putreg32(regval, LPC43_BASE_APB1_CLK);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -579,12 +577,12 @@ void lpc43_abp3(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
//set clock source
|
||||
/* Set clock source */
|
||||
|
||||
regval = getreg32(LPC43_BASE_APB3_CLK);
|
||||
regval &= ~BASE_APB3_CLK_CLKSEL_MASK;
|
||||
regval |= BOARD_ABP3_CLKSRC | BASE_APB3_CLK_AUTOBLOCK;
|
||||
putreg32(regval, LPC43_BASE_APB3_CLK);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -652,7 +650,7 @@ void lpc43_clockconfig(void)
|
||||
lpc43_pll1config(PLL_CONTROLS);
|
||||
#endif
|
||||
|
||||
//configure idivs
|
||||
/* Configure idivs */
|
||||
|
||||
#if defined(BOARD_IDIVA_DIVIDER) && defined(BOARD_IDIVA_CLKSRC)
|
||||
lpc43_idiva();
|
||||
@ -674,7 +672,7 @@ void lpc43_clockconfig(void)
|
||||
lpc43_idive();
|
||||
#endif
|
||||
|
||||
//configure abpXs
|
||||
/* Configure abpXs */
|
||||
|
||||
#if defined(BOARD_ABP1_CLKSRC)
|
||||
lpc43_abp1();
|
||||
@ -683,6 +681,4 @@ void lpc43_clockconfig(void)
|
||||
#if defined(BOARD_ABP3_CLKSRC)
|
||||
lpc43_abp3();
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
@ -94,15 +94,15 @@ struct lpc43_i2cdev_s
|
||||
struct i2c_msg_s msg; /* a single message for legacy read/write */
|
||||
unsigned int base; /* Base address of registers */
|
||||
uint16_t irqid; /* IRQ for this device */
|
||||
uint32_t baseFreq; /* branch frequency */
|
||||
uint32_t baseFreq; /* branch frequency */
|
||||
|
||||
sem_t mutex; /* Only one thread can access at a time */
|
||||
sem_t wait; /* Place to wait for state machine completion */
|
||||
volatile uint8_t state; /* State of state machine */
|
||||
WDOG_ID timeout; /* watchdog to timeout when bus hung */
|
||||
|
||||
struct i2c_msg_s *msgs; /* remaining transfers - first one is in progress */
|
||||
unsigned int nmsg; /* number of transfer remaining */
|
||||
struct i2c_msg_s *msgs; /* remaining transfers - first one is in progress */
|
||||
unsigned int nmsg; /* number of transfer remaining */
|
||||
|
||||
uint16_t wrcnt; /* number of bytes sent to tx fifo */
|
||||
uint16_t rdcnt; /* number of bytes read from rx fifo */
|
||||
@ -152,8 +152,6 @@ struct i2c_ops_s lpc43_i2c_ops =
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: lpc43_i2c_setfrequency
|
||||
*
|
||||
@ -166,23 +164,23 @@ static uint32_t i2c_setfrequency(FAR struct i2c_dev_s *dev, uint32_t frequency)
|
||||
struct lpc43_i2cdev_s *priv = (struct lpc43_i2cdev_s *) dev;
|
||||
|
||||
if (frequency > 100000)
|
||||
{
|
||||
/* asymetric per 400Khz I2C spec */
|
||||
{
|
||||
/* asymetric per 400Khz I2C spec */
|
||||
|
||||
putreg32(priv->baseFreq / (83 + 47) * 47 / frequency, priv->base + LPC43_I2C_SCLH_OFFSET);
|
||||
putreg32(priv->baseFreq / (83 + 47) * 83 / frequency, priv->base + LPC43_I2C_SCLL_OFFSET);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 50/50 mark space ratio */
|
||||
putreg32(priv->baseFreq / (83 + 47) * 47 / frequency, priv->base + LPC43_I2C_SCLH_OFFSET);
|
||||
putreg32(priv->baseFreq / (83 + 47) * 83 / frequency, priv->base + LPC43_I2C_SCLL_OFFSET);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 50/50 mark space ratio */
|
||||
|
||||
putreg32(priv->baseFreq / 100 * 50 / frequency, priv->base + LPC43_I2C_SCLH_OFFSET);
|
||||
putreg32(priv->baseFreq / 100 * 50 / frequency, priv->base + LPC43_I2C_SCLL_OFFSET);
|
||||
}
|
||||
putreg32(priv->baseFreq / 100 * 50 / frequency, priv->base + LPC43_I2C_SCLH_OFFSET);
|
||||
putreg32(priv->baseFreq / 100 * 50 / frequency, priv->base + LPC43_I2C_SCLL_OFFSET);
|
||||
}
|
||||
|
||||
/* FIXME: This function should return the actual selected frequency */
|
||||
|
||||
return (frequency);
|
||||
return frequency;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -232,9 +230,10 @@ static int i2c_write(FAR struct i2c_dev_s *dev, const uint8_t *buffer,
|
||||
priv->nmsg = 1;
|
||||
priv->msgs = &(priv->msg);
|
||||
|
||||
if ( buflen>0 ) {
|
||||
ret = i2c_start(priv);
|
||||
}
|
||||
if (buflen > 0)
|
||||
{
|
||||
ret = i2c_start(priv);
|
||||
}
|
||||
|
||||
return (ret == 0 ? 0 : -ETIMEDOUT);
|
||||
}
|
||||
@ -255,8 +254,8 @@ static int i2c_read(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen)
|
||||
|
||||
DEBUGASSERT(dev != NULL);
|
||||
|
||||
priv->wrcnt=0;
|
||||
priv->rdcnt=0;
|
||||
priv->wrcnt = 0;
|
||||
priv->rdcnt = 0;
|
||||
priv->msg.addr |= 0x01;
|
||||
priv->msg.buffer = buffer;
|
||||
priv->msg.length = buflen;
|
||||
@ -264,9 +263,10 @@ static int i2c_read(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen)
|
||||
priv->nmsg = 1;
|
||||
priv->msgs = &(priv->msg);
|
||||
|
||||
if ( buflen>0 ) {
|
||||
ret = i2c_start(priv);
|
||||
}
|
||||
if (buflen > 0)
|
||||
{
|
||||
ret = i2c_start(priv);
|
||||
}
|
||||
|
||||
return (ret == 0 ? 0 : -ETIMEDOUT);
|
||||
}
|
||||
@ -297,7 +297,7 @@ static int i2c_start(struct lpc43_i2cdev_s *priv)
|
||||
|
||||
sem_post(&priv->mutex);
|
||||
|
||||
return (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -358,19 +358,22 @@ static int i2c_transfer(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *msgs, i
|
||||
|
||||
ret = count - i2c_start(priv);
|
||||
|
||||
|
||||
return (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void startStopNextMessage(struct lpc43_i2cdev_s *priv) {
|
||||
priv->nmsg--;
|
||||
void startStopNextMessage(struct lpc43_i2cdev_s *priv)
|
||||
{
|
||||
priv->nmsg--;
|
||||
|
||||
if( priv->nmsg > 0 ) {
|
||||
priv->msgs++;
|
||||
putreg32(I2C_CONSET_STA,priv->base+LPC43_I2C_CONSET_OFFSET);
|
||||
} else {
|
||||
i2c_stop(priv);
|
||||
}
|
||||
if(priv->nmsg > 0)
|
||||
{
|
||||
priv->msgs++;
|
||||
putreg32(I2C_CONSET_STA,priv->base+LPC43_I2C_CONSET_OFFSET);
|
||||
}
|
||||
else
|
||||
{
|
||||
i2c_stop(priv);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -406,57 +409,60 @@ static int i2c_interrupt(int irq, FAR void *context)
|
||||
}
|
||||
|
||||
/* Reference UM10360 19.10.5 */
|
||||
|
||||
state = getreg32(priv->base+LPC43_I2C_STAT_OFFSET);
|
||||
msg = priv->msgs;
|
||||
|
||||
priv->state = state;
|
||||
state &= 0xf8; //state mask, only 0xX8 is possible
|
||||
state &= 0xf8; /* state mask, only 0xX8 is possible */
|
||||
switch (state)
|
||||
{
|
||||
|
||||
case 0x08: /* A START condition has been transmitted. */
|
||||
case 0x10: /* A Repeated START condition has been transmitted. */
|
||||
putreg32(msg->addr, priv->base + LPC43_I2C_DAT_OFFSET); //set address
|
||||
putreg32(I2C_CONCLR_STAC, priv->base + LPC43_I2C_CONCLR_OFFSET); //clear start bit
|
||||
putreg32(msg->addr, priv->base + LPC43_I2C_DAT_OFFSET); /* set address */
|
||||
putreg32(I2C_CONCLR_STAC, priv->base + LPC43_I2C_CONCLR_OFFSET); /* clear start bit */
|
||||
break;
|
||||
|
||||
//write cases
|
||||
case 0x18: //SLA+W has been transmitted; ACK has been received
|
||||
/* Write cases */
|
||||
|
||||
case 0x18: /* SLA+W has been transmitted; ACK has been received */
|
||||
priv->wrcnt=0;
|
||||
putreg32(msg->buffer[0], priv->base + LPC43_I2C_DAT_OFFSET); //put first byte
|
||||
putreg32(msg->buffer[0], priv->base + LPC43_I2C_DAT_OFFSET); /* put first byte */
|
||||
break;
|
||||
|
||||
case 0x28: //Data byte in DAT has been transmitted; ACK has been received.
|
||||
case 0x28: /* Data byte in DAT has been transmitted; ACK has been received. */
|
||||
priv->wrcnt++;
|
||||
|
||||
if (priv->wrcnt < msg->length) {
|
||||
putreg32(msg->buffer[priv->wrcnt],priv->base+LPC43_I2C_DAT_OFFSET); //put next byte
|
||||
putreg32(msg->buffer[priv->wrcnt],priv->base+LPC43_I2C_DAT_OFFSET); /* Put next byte */
|
||||
} else {
|
||||
startStopNextMessage(priv);
|
||||
startStopNextMessage(priv);
|
||||
}
|
||||
break;
|
||||
|
||||
//read cases
|
||||
case 0x40: //SLA+R has been transmitted; ACK has been received
|
||||
/* Read cases */
|
||||
|
||||
case 0x40: /* SLA+R has been transmitted; ACK has been received */
|
||||
priv->rdcnt = 0;
|
||||
if ( msg->length > 1 ) {
|
||||
putreg32(I2C_CONSET_AA, priv->base + LPC43_I2C_CONSET_OFFSET); // set ACK next read
|
||||
if (msg->length > 1) {
|
||||
putreg32(I2C_CONSET_AA, priv->base + LPC43_I2C_CONSET_OFFSET); /* Set ACK next read */
|
||||
} else {
|
||||
putreg32(I2C_CONCLR_AAC,priv->base + LPC43_I2C_CONCLR_OFFSET); // do not ACK because only one byte
|
||||
putreg32(I2C_CONCLR_AAC,priv->base + LPC43_I2C_CONCLR_OFFSET); /* Do not ACK because only one byte */
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x50: //Data byte has been received; ACK has been returned.
|
||||
case 0x50: /* Data byte has been received; ACK has been returned. */
|
||||
priv->rdcnt++;
|
||||
msg->buffer[priv->rdcnt-1 ] = getreg32(priv->base+LPC43_I2C_BUFR_OFFSET);
|
||||
|
||||
if ( priv->rdcnt >= (msg->length - 1) ) {
|
||||
putreg32(I2C_CONCLR_AAC,priv->base+LPC43_I2C_CONCLR_OFFSET); // do not ACK any more
|
||||
if (priv->rdcnt >= (msg->length - 1)) {
|
||||
putreg32(I2C_CONCLR_AAC,priv->base+LPC43_I2C_CONCLR_OFFSET); /* Do not ACK any more */
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x58: //Data byte has been received; NACK has been returned.
|
||||
case 0x58: /* Data byte has been received; NACK has been returned. */
|
||||
msg->buffer[priv->rdcnt ] = getreg32(priv->base+LPC43_I2C_BUFR_OFFSET);
|
||||
startStopNextMessage(priv);
|
||||
break;
|
||||
@ -466,13 +472,11 @@ static int i2c_interrupt(int irq, FAR void *context)
|
||||
break;
|
||||
}
|
||||
|
||||
putreg32(I2C_CONCLR_SIC, priv->base + LPC43_I2C_CONCLR_OFFSET); //clear interrupt
|
||||
putreg32(I2C_CONCLR_SIC, priv->base + LPC43_I2C_CONCLR_OFFSET); /* clear interrupt */
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -489,7 +493,7 @@ struct i2c_dev_s *up_i2cinitialize(int port)
|
||||
{
|
||||
struct lpc43_i2cdev_s *priv;
|
||||
|
||||
if (port>1)
|
||||
if (port > 1)
|
||||
{
|
||||
dbg("lpc I2C Only support 0,1\n");
|
||||
return NULL;
|
||||
@ -503,27 +507,33 @@ struct i2c_dev_s *up_i2cinitialize(int port)
|
||||
#ifdef CONFIG_LPC43_I2C0
|
||||
if (port == 0)
|
||||
{
|
||||
priv = &g_i2c0dev;
|
||||
priv->base = LPC43_I2C0_BASE;
|
||||
priv->irqid = LPC43M0_IRQ_I2C0;
|
||||
priv = &g_i2c0dev;
|
||||
priv->base = LPC43_I2C0_BASE;
|
||||
priv->irqid = LPC43M0_IRQ_I2C0;
|
||||
priv->baseFreq = BOARD_ABP1_FREQUENCY;
|
||||
|
||||
//enable, set mode
|
||||
regval = getreg32(LPC43_SCU_SFSI2C0 );
|
||||
/* Enable, set mode */
|
||||
|
||||
regval = getreg32(LPC43_SCU_SFSI2C0);
|
||||
regval |= SCU_SFSI2C0_SCL_EZI | SCU_SFSI2C0_SDA_EZI;
|
||||
if ( CONFIG_I2C0_FREQ == 1000000 ) { //super fast mode
|
||||
regval |= SCU_SFSI2C0_SCL_EHD | SCU_SFSI2C0_SDA_EHD;
|
||||
}
|
||||
if (CONFIG_I2C0_FREQ == 1000000)
|
||||
{
|
||||
/* Super fast mode */
|
||||
|
||||
regval |= SCU_SFSI2C0_SCL_EHD | SCU_SFSI2C0_SDA_EHD;
|
||||
}
|
||||
|
||||
putreg32(regval, LPC43_SCU_SFSI2C0);
|
||||
|
||||
//enable clock
|
||||
/* Enable clock */
|
||||
|
||||
regval = getreg32(LPC43_CCU1_APB1_I2C0_CFG);
|
||||
regval |= CCU_CLK_CFG_RUN;
|
||||
putreg32(regval, LPC43_CCU1_APB1_I2C0_CFG);
|
||||
|
||||
i2c_setfrequency( (struct i2c_dev_s *)priv,CONFIG_I2C0_FREQ);
|
||||
i2c_setfrequency((struct i2c_dev_s *)priv,CONFIG_I2C0_FREQ);
|
||||
|
||||
//no pins configuration needed
|
||||
/* No pin configuration needed */
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@ -535,14 +545,16 @@ struct i2c_dev_s *up_i2cinitialize(int port)
|
||||
priv->irqid = LPC43M0_IRQ_I2C1;
|
||||
priv->baseFreq = BOARD_ABP3_FREQUENCY;
|
||||
|
||||
//no need to enable
|
||||
/* No need to enable */
|
||||
|
||||
/* Enable clock */
|
||||
|
||||
//enable clock
|
||||
regval = getreg32(LPC43_CCU1_APB3_I2C1_CFG);
|
||||
regval |= CCU_CLK_CFG_RUN;
|
||||
putreg32(regval, LPC43_CCU1_APB3_I2C1_CFG);
|
||||
|
||||
//pins configuration
|
||||
/* Pin configuration */
|
||||
|
||||
lpc43_pin_config(PINCONF_I2C1_SCL);
|
||||
lpc43_pin_config(PINCONF_I2C1_SDA);
|
||||
|
||||
@ -578,7 +590,7 @@ struct i2c_dev_s *up_i2cinitialize(int port)
|
||||
/* Install our operations */
|
||||
|
||||
priv->dev.ops = &lpc43_i2c_ops;
|
||||
return (&priv->dev);
|
||||
return &priv->dev;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -599,5 +611,4 @@ int up_i2cuninitialize(FAR struct i2c_dev_s * dev)
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
#endif /* CONFIG_LPC43_I2C0 || CONFIG_LPC43_I2C1 */
|
||||
|
@ -175,7 +175,7 @@ static struct lpc43_sspdev_s g_ssp0dev =
|
||||
{
|
||||
.spidev = { &g_spi0ops },
|
||||
.sspbase = LPC43_SSP0_BASE,
|
||||
.sspbasefreq = BOARD_SSP0_BASEFREQ
|
||||
.sspbasefreq = BOARD_SSP0_BASEFREQ
|
||||
#ifdef CONFIG_LPC43_SSP_INTERRUPTS
|
||||
.sspirq = LPC43_IRQ_SSP0,
|
||||
#endif
|
||||
@ -210,7 +210,7 @@ static struct lpc43_sspdev_s g_ssp1dev =
|
||||
{
|
||||
.spidev = { &g_spi1ops },
|
||||
.sspbase = LPC43_SSP1_BASE,
|
||||
.sspbasefreq = BOARD_SSP1_BASEFREQ
|
||||
.sspbasefreq = BOARD_SSP1_BASEFREQ
|
||||
#ifdef CONFIG_LPC43_SSP_INTERRUPTS
|
||||
.sspirq = LPC43_IRQ_SSP1,
|
||||
#endif
|
||||
@ -309,6 +309,7 @@ static int ssp_lock(FAR struct spi_dev_s *dev, bool lock)
|
||||
{
|
||||
(void)sem_post(&priv->exclsem);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
@ -708,22 +709,26 @@ static inline FAR struct lpc43_sspdev_s *lpc43_ssp0initialize(void)
|
||||
flags = irqsave();
|
||||
|
||||
/* Configure clocking */
|
||||
|
||||
regval = getreg32(LPC43_BASE_SSP0_CLK);
|
||||
regval &= ~BASE_SSP0_CLK_CLKSEL_MASK;
|
||||
regval |= (BOARD_SSP0_CLKSRC | BASE_SSP0_CLK_AUTOBLOCK);
|
||||
putreg32(regval, LPC43_BASE_SSP0_CLK);
|
||||
|
||||
//clock register
|
||||
/* Clock register */
|
||||
|
||||
regval = getreg32(LPC43_CCU1_M4_SSP0_CFG);
|
||||
regval |= CCU_CLK_CFG_RUN;
|
||||
putreg32(regval, LPC43_CCU1_M4_SSP0_CFG);
|
||||
|
||||
//clock peripheral
|
||||
/* Clock peripheral */
|
||||
|
||||
regval = getreg32(LPC43_CCU2_APB0_SSP0_CFG);
|
||||
regval |= CCU_CLK_CFG_RUN;
|
||||
putreg32(regval, LPC43_CCU2_APB0_SSP0_CFG);
|
||||
|
||||
//pins configuration
|
||||
/* Pin configuration */
|
||||
|
||||
lpc43_pin_config(PINCONF_SSP0_SCK);
|
||||
lpc43_pin_config(PINCONF_SSP0_SSEL);
|
||||
lpc43_pin_config(PINCONF_SSP0_MISO);
|
||||
@ -758,22 +763,26 @@ static inline FAR struct lpc43_sspdev_s *lpc43_ssp1initialize(void)
|
||||
flags = irqsave();
|
||||
|
||||
/* Configure clocking */
|
||||
|
||||
regval = getreg32(LPC43_BASE_SSP1_CLK);
|
||||
regval &= ~BASE_SSP1_CLK_CLKSEL_MASK;
|
||||
regval |= (BOARD_SSP1_CLKSRC | BASE_SSP1_CLK_AUTOBLOCK);
|
||||
putreg32(regval, LPC43_BASE_SSP1_CLK);
|
||||
|
||||
//clock register
|
||||
/* Clock register */
|
||||
|
||||
regval = getreg32(LPC43_CCU1_M4_SSP1_CFG);
|
||||
regval |= CCU_CLK_CFG_RUN;
|
||||
putreg32(regval, LPC43_CCU1_M4_SSP1_CFG);
|
||||
|
||||
//clock peripheral
|
||||
/* Clock peripheral */
|
||||
|
||||
regval = getreg32(LPC43_CCU2_APB2_SSP1_CFG);
|
||||
regval |= CCU_CLK_CFG_RUN;
|
||||
putreg32(regval, LPC43_CCU2_APB2_SSP1_CFG);
|
||||
|
||||
//pins configuration
|
||||
/* Pins configuration */
|
||||
|
||||
lpc43_pin_config(PINCONF_SSP1_SCK);
|
||||
lpc43_pin_config(PINCONF_SSP1_SSEL);
|
||||
lpc43_pin_config(PINCONF_SSP1_MISO);
|
||||
@ -818,11 +827,13 @@ FAR struct spi_dev_s *lpc43_sspinitialize(int port)
|
||||
priv = lpc43_ssp0initialize();
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LPC43_SSP1
|
||||
case 1:
|
||||
priv = lpc43_ssp1initialize();
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@ -908,4 +919,3 @@ void ssp_flush(FAR struct spi_dev_s *dev)
|
||||
}
|
||||
|
||||
#endif /* CONFIG_LPC43_SSP0/1 */
|
||||
|
||||
|
@ -334,12 +334,14 @@ void lpc43_usart0_setup(void)
|
||||
regval |= (BOARD_USART0_CLKSRC | BASE_USART0_CLK_AUTOBLOCK);
|
||||
putreg32(regval, LPC43_BASE_USART0_CLK);
|
||||
|
||||
//clock register
|
||||
/* Clock register */
|
||||
|
||||
regval = getreg32(LPC43_CCU1_M4_USART0_CFG);
|
||||
regval |= CCU_CLK_CFG_RUN;
|
||||
putreg32(regval, LPC43_CCU1_M4_USART0_CFG);
|
||||
|
||||
//clock peripheral
|
||||
/* Clock peripheral */
|
||||
|
||||
regval = getreg32(LPC43_CCU2_APB0_USART0_CFG);
|
||||
regval |= CCU_CLK_CFG_RUN;
|
||||
putreg32(regval, LPC43_CCU2_APB0_USART0_CFG);
|
||||
@ -381,12 +383,14 @@ void lpc43_uart1_setup(void)
|
||||
regval |= (BOARD_UART1_CLKSRC | BASE_UART1_CLK_AUTOBLOCK);
|
||||
putreg32(regval, LPC43_BASE_UART1_CLK);
|
||||
|
||||
//clock register
|
||||
/* Clock register */
|
||||
|
||||
regval = getreg32(LPC43_CCU1_M4_UART1_CFG);
|
||||
regval |= CCU_CLK_CFG_RUN;
|
||||
putreg32(regval, LPC43_CCU1_M4_UART1_CFG);
|
||||
|
||||
//clock peripheral
|
||||
/* Clock peripheral */
|
||||
|
||||
regval = getreg32(LPC43_CCU2_APB0_UART1_CFG);
|
||||
regval |= CCU_CLK_CFG_RUN;
|
||||
putreg32(regval, LPC43_CCU2_APB0_UART1_CFG);
|
||||
@ -428,12 +432,14 @@ void lpc43_usart2_setup(void)
|
||||
regval |= (BOARD_USART2_CLKSRC | BASE_USART2_CLK_AUTOBLOCK);
|
||||
putreg32(regval, LPC43_BASE_USART2_CLK);
|
||||
|
||||
//clock register
|
||||
/* Clock register */
|
||||
|
||||
regval = getreg32(LPC43_CCU1_M4_USART2_CFG);
|
||||
regval |= CCU_CLK_CFG_RUN;
|
||||
putreg32(regval, LPC43_CCU1_M4_USART2_CFG);
|
||||
|
||||
//clock peripheral
|
||||
/* Clock peripheral */
|
||||
|
||||
regval = getreg32(LPC43_CCU2_APB2_USART2_CFG);
|
||||
regval |= CCU_CLK_CFG_RUN;
|
||||
putreg32(regval, LPC43_CCU2_APB2_USART2_CFG);
|
||||
@ -476,12 +482,14 @@ void lpc43_usart3_setup(void)
|
||||
regval |= (BOARD_USART3_CLKSRC | BASE_USART3_CLK_AUTOBLOCK);
|
||||
putreg32(regval, LPC43_BASE_USART3_CLK);
|
||||
|
||||
//clock register
|
||||
/* Clock register */
|
||||
|
||||
regval = getreg32(LPC43_CCU1_M4_USART3_CFG);
|
||||
regval |= CCU_CLK_CFG_RUN;
|
||||
putreg32(regval, LPC43_CCU1_M4_USART3_CFG);
|
||||
|
||||
//clock peripheral
|
||||
/* Clock peripheral */
|
||||
|
||||
regval = getreg32(LPC43_CCU2_APB2_USART3_CFG);
|
||||
regval |= CCU_CLK_CFG_RUN;
|
||||
putreg32(regval, LPC43_CCU2_APB2_USART3_CFG);
|
||||
@ -561,7 +569,7 @@ void lpc43_setbaud(uintptr_t uartbase, uint32_t basefreq, uint32_t baud)
|
||||
/* Candidate:
|
||||
* dl = ((Fbase * mul) >> 4) / ((mul + cdivadd) * Fbaud)
|
||||
* (dl << 32) = (Fbase << 28) * cmul / ((mul + cdivadd) * Fbaud)
|
||||
*/
|
||||
*/
|
||||
|
||||
uint64_t dl64 = ((uint64_t)basefreq << 28) * cmul /
|
||||
((cmul + cdivadd) * baud);
|
||||
|
@ -174,7 +174,10 @@
|
||||
|
||||
/* Hardware interface **********************************************************/
|
||||
|
||||
/* This represents a Endpoint Transfer Descriptor - note these must be 32 byte aligned */
|
||||
/* This represents a Endpoint Transfer Descriptor - note these must be 32 byte
|
||||
* aligned.
|
||||
*/
|
||||
|
||||
struct lpc43_dtd_s
|
||||
{
|
||||
volatile uint32_t nextdesc; /* Address of the next DMA descripto in RAM */
|
||||
@ -187,10 +190,12 @@ struct lpc43_dtd_s
|
||||
uint32_t xfer_len; /* Software only - transfer len that was queued */
|
||||
};
|
||||
|
||||
/* DTD nextdesc field*/
|
||||
/* DTD nextdesc field */
|
||||
|
||||
#define DTD_NEXTDESC_INVALID (1 << 0) /* Bit 0 : Next Descriptor Invalid */
|
||||
|
||||
/* DTD config field */
|
||||
|
||||
#define DTD_CONFIG_LENGTH(n) ((n) << 16) /* Bits 16-31 : Total bytes to transfer */
|
||||
#define DTD_CONFIG_IOC (1 << 15) /* Bit 15 : Interrupt on Completion */
|
||||
#define DTD_CONFIG_MULT_VARIABLE (0 << 10) /* Bits 10-11 : Number of packets executed per transacation descriptor (override) */
|
||||
@ -201,6 +206,7 @@ struct lpc43_dtd_s
|
||||
#define DTD_CONFIG_TRANSACTION_ERROR (1 << 3) /* Bit 3 : Status Transaction Error */
|
||||
|
||||
/* This represents a queue head - not these must be aligned to a 2048 byte boundary */
|
||||
|
||||
struct lpc43_dqh_s
|
||||
{
|
||||
uint32_t capability; /* Endpoint capability */
|
||||
@ -211,6 +217,7 @@ struct lpc43_dqh_s
|
||||
};
|
||||
|
||||
/* DQH capability field */
|
||||
|
||||
#define DQH_CAPABILITY_MULT_VARIABLE (0 << 30) /* Bits 30-31 : Number of packets executed per transaction descriptor */
|
||||
#define DQH_CAPABILITY_MULT_NUM(n) ((n) << 30)
|
||||
#define DQH_CAPABILITY_ZLT (1 << 29) /* Bit 29 : Zero Length Termination Select */
|
||||
@ -220,10 +227,12 @@ struct lpc43_dqh_s
|
||||
/* Endpoints ******************************************************************/
|
||||
|
||||
/* Number of endpoints */
|
||||
|
||||
#define LPC43_NLOGENDPOINTS (4) /* ep0-3 */
|
||||
#define LPC43_NPHYSENDPOINTS (8) /* x2 for IN and OUT */
|
||||
|
||||
/* Odd physical endpoint numbers are IN; even are OUT */
|
||||
|
||||
#define LPC43_EPPHYIN(epphy) (((epphy)&1)!=0)
|
||||
#define LPC43_EPPHYOUT(epphy) (((epphy)&1)==0)
|
||||
|
||||
@ -231,10 +240,12 @@ struct lpc43_dqh_s
|
||||
#define LPC43_EPPHYOUT2LOG(epphy) (((uint8_t)(epphy)>>1)|USB_DIR_OUT)
|
||||
|
||||
/* Endpoint 0 is special... */
|
||||
|
||||
#define LPC43_EP0_OUT (0)
|
||||
#define LPC43_EP0_IN (1)
|
||||
|
||||
/* Each endpoint has somewhat different characteristics */
|
||||
|
||||
#define LPC43_EPALLSET (0xff) /* All endpoints */
|
||||
#define LPC43_EPOUTSET (0x55) /* Even phy endpoint numbers are OUT EPs */
|
||||
#define LPC43_EPINSET (0xaa) /* Odd endpoint numbers are IN EPs */
|
||||
@ -244,12 +255,14 @@ struct lpc43_dqh_s
|
||||
#define LPC43_EPISOCSET (0xfc) /* Isochronous endpoints */
|
||||
|
||||
/* Maximum packet sizes for endpoints */
|
||||
|
||||
#define LPC43_EP0MAXPACKET (64) /* EP0 max packet size (1-64) */
|
||||
#define LPC43_BULKMAXPACKET (512) /* Bulk endpoint max packet (8/16/32/64/512) */
|
||||
#define LPC43_INTRMAXPACKET (1024) /* Interrupt endpoint max packet (1 to 1024) */
|
||||
#define LPC43_ISOCMAXPACKET (512) /* Acutally 1..1023 */
|
||||
|
||||
/* Endpoint bit position in SETUPSTAT, PRIME, FLUSH, STAT, COMPLETE registers */
|
||||
|
||||
#define LPC43_ENDPTSHIFT(epphy) (LPC43_EPPHYIN(epphy) ? (16 + ((epphy) >> 1)) : ((epphy) >> 1))
|
||||
#define LPC43_ENDPTMASK(epphy) (1 << LPC43_ENDPTSHIFT(epphy))
|
||||
#define LPC43_ENDPTMASK_ALL 0x000f000f
|
||||
@ -323,6 +336,7 @@ struct lpc43_usbdev_s
|
||||
#endif
|
||||
|
||||
/* The endpoint list */
|
||||
|
||||
struct lpc43_ep_s eplist[LPC43_NPHYSENDPOINTS];
|
||||
};
|
||||
|
||||
@ -382,6 +396,7 @@ static void lpc43_reqcomplete(struct lpc43_ep_s *privep,
|
||||
static void lpc43_cancelrequests(struct lpc43_ep_s *privep, int16_t status);
|
||||
|
||||
/* Interrupt handling **********************************************************/
|
||||
|
||||
static struct lpc43_ep_s *lpc43_epfindbyaddr(struct lpc43_usbdev_s *priv,
|
||||
uint16_t eplog);
|
||||
static void lpc43_dispatchrequest(struct lpc43_usbdev_s *priv,
|
||||
@ -651,6 +666,7 @@ static bool lpc43_rqenqueue(FAR struct lpc43_ep_s *privep,
|
||||
privep->tail->flink = req;
|
||||
privep->tail = req;
|
||||
}
|
||||
|
||||
return is_empty;
|
||||
}
|
||||
|
||||
@ -724,24 +740,31 @@ static inline void lpc43_ep0xfer(uint8_t epphy, uint8_t *buf, uint32_t nbytes)
|
||||
*******************************************************************************/
|
||||
static void lpc43_readsetup(uint8_t epphy, struct usb_ctrlreq_s *ctrl)
|
||||
{
|
||||
struct lpc43_dqh_s *dqh = &g_qh[epphy];
|
||||
int i;
|
||||
struct lpc43_dqh_s *dqh = &g_qh[epphy];
|
||||
int i;
|
||||
|
||||
do {
|
||||
/* Set the trip wire */
|
||||
lpc43_setbits(USBDEV_USBCMD_SUTW, LPC43_USBDEV_USBCMD);
|
||||
do
|
||||
{
|
||||
/* Set the trip wire */
|
||||
|
||||
/* copy the request... */
|
||||
for (i = 0; i < 8; i++)
|
||||
((uint8_t *) ctrl)[i] = ((uint8_t *) dqh->setup)[i];
|
||||
lpc43_setbits(USBDEV_USBCMD_SUTW, LPC43_USBDEV_USBCMD);
|
||||
|
||||
} while (!(lpc43_getreg(LPC43_USBDEV_USBCMD) & USBDEV_USBCMD_SUTW));
|
||||
/* Copy the request... */
|
||||
|
||||
/* Clear the trip wire */
|
||||
lpc43_clrbits(USBDEV_USBCMD_SUTW, LPC43_USBDEV_USBCMD);
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
((uint8_t *) ctrl)[i] = ((uint8_t *) dqh->setup)[i];
|
||||
}
|
||||
}
|
||||
while (!(lpc43_getreg(LPC43_USBDEV_USBCMD) & USBDEV_USBCMD_SUTW));
|
||||
|
||||
/* Clear the Setup Interrupt */
|
||||
lpc43_putreg (LPC43_ENDPTMASK(LPC43_EP0_OUT), LPC43_USBDEV_ENDPTSETUPSTAT);
|
||||
/* Clear the trip wire */
|
||||
|
||||
lpc43_clrbits(USBDEV_USBCMD_SUTW, LPC43_USBDEV_USBCMD);
|
||||
|
||||
/* Clear the Setup Interrupt */
|
||||
|
||||
lpc43_putreg (LPC43_ENDPTMASK(LPC43_EP0_OUT), LPC43_USBDEV_ENDPTSETUPSTAT);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -808,40 +831,56 @@ static int lpc43_progressep(struct lpc43_ep_s *privep)
|
||||
|
||||
if (privreq->req.len == 0)
|
||||
{
|
||||
/* If the class driver is responding to a setup packet, then wait for the
|
||||
* host to illicit thr response */
|
||||
/* If the class driver is responding to a setup packet, then wait for
|
||||
* the host to illicit thr response
|
||||
*/
|
||||
|
||||
if (privep->epphy == LPC43_EP0_IN && privep->dev->ep0state == EP0STATE_SETUP_OUT)
|
||||
lpc43_ep0state (privep->dev, EP0STATE_WAIT_NAK_IN);
|
||||
else
|
||||
{
|
||||
if (LPC43_EPPHYIN(privep->epphy))
|
||||
usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_EPINNULLPACKET), 0);
|
||||
else
|
||||
usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_EPOUTNULLPACKET), 0);
|
||||
}
|
||||
if (privep->epphy == LPC43_EP0_IN && privep->dev->ep0state == EP0STATE_SETUP_OUT)
|
||||
{
|
||||
lpc43_ep0state (privep->dev, EP0STATE_WAIT_NAK_IN);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LPC43_EPPHYIN(privep->epphy))
|
||||
{
|
||||
usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_EPINNULLPACKET), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_EPOUTNULLPACKET), 0);
|
||||
}
|
||||
}
|
||||
|
||||
lpc43_reqcomplete(privep, lpc43_rqdequeue(privep), OK);
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (privep->epphy == LPC43_EP0_IN)
|
||||
lpc43_ep0state (privep->dev, EP0STATE_DATA_IN);
|
||||
{
|
||||
lpc43_ep0state (privep->dev, EP0STATE_DATA_IN);
|
||||
}
|
||||
else if (privep->epphy == LPC43_EP0_OUT)
|
||||
lpc43_ep0state (privep->dev, EP0STATE_DATA_OUT);
|
||||
{
|
||||
lpc43_ep0state (privep->dev, EP0STATE_DATA_OUT);
|
||||
}
|
||||
|
||||
int bytesleft = privreq->req.len - privreq->req.xfrd;
|
||||
|
||||
if (LPC43_EPPHYIN(privep->epphy))
|
||||
usbtrace(TRACE_WRITE(privep->epphy), privreq->req.xfrd);
|
||||
{
|
||||
usbtrace(TRACE_WRITE(privep->epphy), privreq->req.xfrd);
|
||||
}
|
||||
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 */
|
||||
|
||||
lpc43_writedtd (dtd, privreq->req.buf + privreq->req.xfrd, bytesleft);
|
||||
|
||||
/* then queue onto the DQH */
|
||||
/* Then queue onto the DQH */
|
||||
|
||||
lpc43_queuedtd(privep->epphy, dtd);
|
||||
|
||||
return OK;
|
||||
@ -1010,6 +1049,7 @@ static void lpc43_dispatchrequest(struct lpc43_usbdev_s *priv,
|
||||
static void lpc43_ep0configure(struct lpc43_usbdev_s *priv)
|
||||
{
|
||||
/* Enable ep0 IN and ep0 OUT */
|
||||
|
||||
g_qh[LPC43_EP0_OUT].capability = (DQH_CAPABILITY_MAX_PACKET(CONFIG_USBDEV_EP0_MAXSIZE) |
|
||||
DQH_CAPABILITY_IOS |
|
||||
DQH_CAPABILITY_ZLT);
|
||||
@ -1022,6 +1062,7 @@ static void lpc43_ep0configure(struct lpc43_usbdev_s *priv)
|
||||
g_qh[LPC43_EP0_IN ].currdesc = DTD_NEXTDESC_INVALID;
|
||||
|
||||
/* Enable EP0 */
|
||||
|
||||
lpc43_setbits (USBDEV_ENDPTCTRL0_RXE | USBDEV_ENDPTCTRL0_TXE, LPC43_USBDEV_ENDPTCTRL0);
|
||||
}
|
||||
|
||||
@ -1051,6 +1092,7 @@ static void lpc43_usbreset(struct lpc43_usbdev_s *priv)
|
||||
lpc43_putreg (lpc43_getreg(LPC43_USBDEV_ENDPTCOMPLETE), LPC43_USBDEV_ENDPTCOMPLETE);
|
||||
|
||||
/* Wait for all prime operations to have completed and then flush all DTDs */
|
||||
|
||||
while (lpc43_getreg (LPC43_USBDEV_ENDPTPRIME) != 0)
|
||||
;
|
||||
lpc43_putreg (LPC43_ENDPTMASK_ALL, LPC43_USBDEV_ENDPTFLUSH);
|
||||
@ -1058,6 +1100,7 @@ static void lpc43_usbreset(struct lpc43_usbdev_s *priv)
|
||||
;
|
||||
|
||||
/* Reset endpoints */
|
||||
|
||||
for (epphy = 0; epphy < LPC43_NPHYSENDPOINTS; epphy++)
|
||||
{
|
||||
struct lpc43_ep_s *privep = &priv->eplist[epphy];
|
||||
@ -1065,6 +1108,7 @@ static void lpc43_usbreset(struct lpc43_usbdev_s *priv)
|
||||
lpc43_cancelrequests (privep, -ESHUTDOWN);
|
||||
|
||||
/* Reset endpoint status */
|
||||
|
||||
privep->stalled = false;
|
||||
}
|
||||
|
||||
@ -1072,25 +1116,33 @@ static void lpc43_usbreset(struct lpc43_usbdev_s *priv)
|
||||
* driver should then accept any new configurations. */
|
||||
|
||||
if (priv->driver)
|
||||
{
|
||||
CLASS_DISCONNECT(priv->driver, &priv->usbdev);
|
||||
}
|
||||
|
||||
/* Set the interrupt Threshold control interval to 0 */
|
||||
|
||||
lpc43_chgbits(USBDEV_USBCMD_ITC_MASK, USBDEV_USBCMD_ITCIMME, LPC43_USBDEV_USBCMD);
|
||||
|
||||
/* Zero out the Endpoint queue heads */
|
||||
|
||||
memset ((void *) g_qh, 0, sizeof (g_qh));
|
||||
memset ((void *) g_td, 0, sizeof (g_td));
|
||||
|
||||
/* Set USB address to 0 */
|
||||
|
||||
lpc43_set_address (priv, 0);
|
||||
|
||||
/* Initialise the Enpoint List Address */
|
||||
|
||||
lpc43_putreg ((uint32_t)g_qh, LPC43_USBDEV_ENDPOINTLIST);
|
||||
|
||||
/* EndPoint 0 initialization */
|
||||
|
||||
lpc43_ep0configure(priv);
|
||||
|
||||
/* Enable Device interrupts */
|
||||
|
||||
lpc43_putreg(USB_FRAME_INT | USB_ERROR_INT |
|
||||
USBDEV_USBINTR_NAKE | USBDEV_USBINTR_SLE | USBDEV_USBINTR_URE | USBDEV_USBINTR_PCE | USBDEV_USBINTR_UE,
|
||||
LPC43_USBDEV_USBINTR);
|
||||
@ -1113,9 +1165,11 @@ static inline void lpc43_ep0state(struct lpc43_usbdev_s *priv, uint16_t state)
|
||||
case EP0STATE_WAIT_NAK_IN:
|
||||
lpc43_putreg (LPC43_ENDPTMASK(LPC43_EP0_IN), LPC43_USBDEV_ENDPTNAKEN);
|
||||
break;
|
||||
|
||||
case EP0STATE_WAIT_NAK_OUT:
|
||||
lpc43_putreg (LPC43_ENDPTMASK(LPC43_EP0_OUT), LPC43_USBDEV_ENDPTNAKEN);
|
||||
break;
|
||||
|
||||
default:
|
||||
lpc43_putreg(0, LPC43_USBDEV_ENDPTNAKEN);
|
||||
break;
|
||||
@ -1140,7 +1194,8 @@ static inline void lpc43_ep0setup(struct lpc43_usbdev_s *priv)
|
||||
uint16_t len;
|
||||
|
||||
/* Terminate any pending requests - since all DTDs will have been retired
|
||||
* because of the setup packet */
|
||||
* because of the setup packet.
|
||||
*/
|
||||
|
||||
lpc43_cancelrequests(&priv->eplist[LPC43_EP0_OUT], -EPROTO);
|
||||
lpc43_cancelrequests(&priv->eplist[LPC43_EP0_IN], -EPROTO);
|
||||
@ -1152,12 +1207,15 @@ static inline void lpc43_ep0setup(struct lpc43_usbdev_s *priv)
|
||||
priv->stalled = false;
|
||||
|
||||
/* Read EP0 setup data */
|
||||
|
||||
lpc43_readsetup(LPC43_EP0_OUT, &ctrl);
|
||||
|
||||
/* Starting a control request - update state */
|
||||
|
||||
lpc43_ep0state (priv, (ctrl.type & USB_REQ_DIR_IN) ? EP0STATE_SETUP_IN : EP0STATE_SETUP_OUT);
|
||||
|
||||
/* And extract the little-endian 16-bit values to host order */
|
||||
|
||||
value = GETUINT16(ctrl.value);
|
||||
index = GETUINT16(ctrl.index);
|
||||
len = GETUINT16(ctrl.len);
|
||||
@ -1166,95 +1224,105 @@ static inline void lpc43_ep0setup(struct lpc43_usbdev_s *priv)
|
||||
ctrl.type, ctrl.req, value, index, len);
|
||||
|
||||
/* Dispatch any non-standard requests */
|
||||
|
||||
if ((ctrl.type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD)
|
||||
lpc43_dispatchrequest(priv, &ctrl);
|
||||
{
|
||||
lpc43_dispatchrequest(priv, &ctrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Handle standard request. Pick off the things of interest to the USB
|
||||
* device controller driver; pass what is left to the class driver */
|
||||
switch (ctrl.req)
|
||||
{
|
||||
case USB_REQ_GETSTATUS:
|
||||
/* Handle standard request. Pick off the things of interest to the USB
|
||||
* device controller driver; pass what is left to the class driver.
|
||||
*/
|
||||
|
||||
switch (ctrl.req)
|
||||
{
|
||||
/* type: device-to-host; recipient = device, interface, endpoint
|
||||
* value: 0
|
||||
* index: zero interface endpoint
|
||||
* len: 2; data = status
|
||||
*/
|
||||
case USB_REQ_GETSTATUS:
|
||||
{
|
||||
/* type: device-to-host; recipient = device, interface, endpoint
|
||||
* value: 0
|
||||
* index: zero interface endpoint
|
||||
* len: 2; data = status
|
||||
*/
|
||||
|
||||
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_GETSTATUS), 0);
|
||||
if (!priv->paddrset || len != 2 ||
|
||||
(ctrl.type & USB_REQ_DIR_IN) == 0 || value != 0)
|
||||
{
|
||||
priv->stalled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (ctrl.type & USB_REQ_RECIPIENT_MASK)
|
||||
{
|
||||
case USB_REQ_RECIPIENT_ENDPOINT:
|
||||
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_GETSTATUS), 0);
|
||||
if (!priv->paddrset || len != 2 ||
|
||||
(ctrl.type & USB_REQ_DIR_IN) == 0 || value != 0)
|
||||
{
|
||||
priv->stalled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (ctrl.type & USB_REQ_RECIPIENT_MASK)
|
||||
{
|
||||
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EPGETSTATUS), 0);
|
||||
privep = lpc43_epfindbyaddr(priv, index);
|
||||
if (!privep)
|
||||
{
|
||||
usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADEPGETSTATUS), 0);
|
||||
priv->stalled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (privep->stalled)
|
||||
priv->ep0buf[0] = 1; /* Stalled */
|
||||
else
|
||||
priv->ep0buf[0] = 0; /* Not stalled */
|
||||
priv->ep0buf[1] = 0;
|
||||
case USB_REQ_RECIPIENT_ENDPOINT:
|
||||
{
|
||||
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EPGETSTATUS), 0);
|
||||
privep = lpc43_epfindbyaddr(priv, index);
|
||||
if (!privep)
|
||||
{
|
||||
usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADEPGETSTATUS), 0);
|
||||
priv->stalled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (privep->stalled)
|
||||
{
|
||||
priv->ep0buf[0] = 1; /* Stalled */
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->ep0buf[0] = 0; /* Not stalled */
|
||||
}
|
||||
|
||||
lpc43_ep0xfer (LPC43_EP0_IN, priv->ep0buf, 2);
|
||||
lpc43_ep0state (priv, EP0STATE_SHORTWRITE);
|
||||
}
|
||||
priv->ep0buf[1] = 0;
|
||||
|
||||
lpc43_ep0xfer (LPC43_EP0_IN, priv->ep0buf, 2);
|
||||
lpc43_ep0state (priv, EP0STATE_SHORTWRITE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case USB_REQ_RECIPIENT_DEVICE:
|
||||
{
|
||||
if (index == 0)
|
||||
{
|
||||
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_DEVGETSTATUS), 0);
|
||||
case USB_REQ_RECIPIENT_DEVICE:
|
||||
{
|
||||
if (index == 0)
|
||||
{
|
||||
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_DEVGETSTATUS), 0);
|
||||
|
||||
/* Features: Remote Wakeup=YES; selfpowered=? */
|
||||
/* Features: Remote Wakeup=YES; selfpowered=? */
|
||||
|
||||
priv->ep0buf[0] = (priv->selfpowered << USB_FEATURE_SELFPOWERED) |
|
||||
(1 << USB_FEATURE_REMOTEWAKEUP);
|
||||
priv->ep0buf[1] = 0;
|
||||
priv->ep0buf[0] = (priv->selfpowered << USB_FEATURE_SELFPOWERED) |
|
||||
(1 << USB_FEATURE_REMOTEWAKEUP);
|
||||
priv->ep0buf[1] = 0;
|
||||
|
||||
lpc43_ep0xfer(LPC43_EP0_IN, priv->ep0buf, 2);
|
||||
lpc43_ep0state (priv, EP0STATE_SHORTWRITE);
|
||||
}
|
||||
else
|
||||
{
|
||||
usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADDEVGETSTATUS), 0);
|
||||
priv->stalled = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
lpc43_ep0xfer(LPC43_EP0_IN, priv->ep0buf, 2);
|
||||
lpc43_ep0state (priv, EP0STATE_SHORTWRITE);
|
||||
}
|
||||
else
|
||||
{
|
||||
usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADDEVGETSTATUS), 0);
|
||||
priv->stalled = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_RECIPIENT_INTERFACE:
|
||||
{
|
||||
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_IFGETSTATUS), 0);
|
||||
priv->ep0buf[0] = 0;
|
||||
priv->ep0buf[1] = 0;
|
||||
case USB_REQ_RECIPIENT_INTERFACE:
|
||||
{
|
||||
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_IFGETSTATUS), 0);
|
||||
priv->ep0buf[0] = 0;
|
||||
priv->ep0buf[1] = 0;
|
||||
|
||||
lpc43_ep0xfer(LPC43_EP0_IN, priv->ep0buf, 2);
|
||||
lpc43_ep0state (priv, EP0STATE_SHORTWRITE);
|
||||
}
|
||||
break;
|
||||
lpc43_ep0xfer(LPC43_EP0_IN, priv->ep0buf, 2);
|
||||
lpc43_ep0state (priv, EP0STATE_SHORTWRITE);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADGETSTATUS), 0);
|
||||
priv->stalled = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADGETSTATUS), 0);
|
||||
priv->stalled = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1326,6 +1394,7 @@ static inline void lpc43_ep0setup(struct lpc43_usbdev_s *priv)
|
||||
* index: 0
|
||||
* len: 0; data = none
|
||||
*/
|
||||
|
||||
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EP0SETUPSETADDRESS), value);
|
||||
if ((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE &&
|
||||
index == 0 && len == 0 && value < 128)
|
||||
@ -1477,18 +1546,26 @@ static void lpc43_ep0complete(struct lpc43_usbdev_s *priv, uint8_t epphy)
|
||||
{
|
||||
case EP0STATE_DATA_IN:
|
||||
if (lpc43_rqempty(privep))
|
||||
return;
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (lpc43_epcomplete (priv, epphy))
|
||||
lpc43_ep0state (priv, EP0STATE_WAIT_NAK_OUT);
|
||||
{
|
||||
lpc43_ep0state (priv, EP0STATE_WAIT_NAK_OUT);
|
||||
}
|
||||
break;
|
||||
|
||||
case EP0STATE_DATA_OUT:
|
||||
if (lpc43_rqempty(privep))
|
||||
return;
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (lpc43_epcomplete (priv, epphy))
|
||||
lpc43_ep0state (priv, EP0STATE_WAIT_NAK_IN);
|
||||
{
|
||||
lpc43_ep0state (priv, EP0STATE_WAIT_NAK_IN);
|
||||
}
|
||||
break;
|
||||
|
||||
case EP0STATE_SHORTWRITE:
|
||||
@ -1499,12 +1576,15 @@ static void lpc43_ep0complete(struct lpc43_usbdev_s *priv, uint8_t epphy)
|
||||
lpc43_ep0state (priv, EP0STATE_IDLE);
|
||||
|
||||
/* If we've received a SETADDRESS packet, then we set the address
|
||||
* now that the status phase has completed */
|
||||
* now that the status phase has completed
|
||||
*/
|
||||
|
||||
if (! priv->paddrset && priv->paddr != 0)
|
||||
{
|
||||
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EP0INSETADDRESS), (uint16_t)priv->paddr);
|
||||
lpc43_set_address (priv, priv->paddr);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case EP0STATE_WAIT_STATUS_OUT:
|
||||
@ -1549,14 +1629,16 @@ static void lpc43_ep0nak(struct lpc43_usbdev_s *priv, uint8_t epphy)
|
||||
lpc43_ep0xfer (LPC43_EP0_IN, NULL, 0);
|
||||
lpc43_ep0state (priv, EP0STATE_WAIT_STATUS_IN);
|
||||
break;
|
||||
|
||||
case EP0STATE_WAIT_NAK_OUT:
|
||||
lpc43_ep0xfer (LPC43_EP0_OUT, NULL, 0);
|
||||
lpc43_ep0state (priv, EP0STATE_WAIT_STATUS_OUT);
|
||||
break;
|
||||
|
||||
default:
|
||||
#ifdef CONFIG_DEBUG
|
||||
DEBUGASSERT(priv->ep0state != EP0STATE_WAIT_NAK_IN &&
|
||||
priv->ep0state != EP0STATE_WAIT_NAK_OUT);
|
||||
priv->ep0state != EP0STATE_WAIT_NAK_OUT);
|
||||
#endif
|
||||
priv->stalled = true;
|
||||
break;
|
||||
@ -1586,13 +1668,18 @@ bool lpc43_epcomplete(struct lpc43_usbdev_s *priv, uint8_t epphy)
|
||||
struct lpc43_dtd_s *dtd = &g_td[epphy];
|
||||
|
||||
if (privreq == NULL) /* This shouldn't really happen */
|
||||
{
|
||||
if (LPC43_EPPHYOUT(privep->epphy))
|
||||
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EPINQEMPTY), 0);
|
||||
else
|
||||
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EPOUTQEMPTY), 0);
|
||||
return true;
|
||||
}
|
||||
{
|
||||
if (LPC43_EPPHYOUT(privep->epphy))
|
||||
{
|
||||
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EPINQEMPTY), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EPOUTQEMPTY), 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int xfrd = dtd->xfer_len - (dtd->config >> 16);
|
||||
|
||||
@ -1656,6 +1743,7 @@ static int lpc43_usbinterrupt(int irq, FAR void *context)
|
||||
usbtrace(TRACE_INTENTRY(LPC43_TRACEINTID_USB), 0);
|
||||
|
||||
/* Read the interrupts and then clear them */
|
||||
|
||||
disr = lpc43_getreg(LPC43_USBDEV_USBSTS);
|
||||
lpc43_putreg(disr, LPC43_USBDEV_USBSTS);
|
||||
|
||||
@ -1746,33 +1834,47 @@ static int lpc43_usbinterrupt(int irq, FAR void *context)
|
||||
if (disr & USBDEV_USBSTS_UI)
|
||||
{
|
||||
/* Handle completion interrupts */
|
||||
|
||||
uint32_t mask = lpc43_getreg (LPC43_USBDEV_ENDPTCOMPLETE);
|
||||
|
||||
if (mask)
|
||||
{
|
||||
/* Clear any NAK interrupt and completion interrupts */
|
||||
|
||||
lpc43_putreg (mask, LPC43_USBDEV_ENDPTNAK);
|
||||
lpc43_putreg (mask, LPC43_USBDEV_ENDPTCOMPLETE);
|
||||
|
||||
if (mask & LPC43_ENDPTMASK(0))
|
||||
lpc43_ep0complete(priv, 0);
|
||||
{
|
||||
lpc43_ep0complete(priv, 0);
|
||||
}
|
||||
|
||||
if (mask & LPC43_ENDPTMASK(1))
|
||||
lpc43_ep0complete(priv, 1);
|
||||
{
|
||||
lpc43_ep0complete(priv, 1);
|
||||
}
|
||||
|
||||
for (n = 1; n < LPC43_NLOGENDPOINTS; n++)
|
||||
{
|
||||
if (mask & LPC43_ENDPTMASK((n<<1)))
|
||||
lpc43_epcomplete (priv, (n<<1));
|
||||
if (mask & LPC43_ENDPTMASK((n<<1)+1))
|
||||
lpc43_epcomplete(priv, (n<<1)+1);
|
||||
if (mask & LPC43_ENDPTMASK((n << 1)))
|
||||
{
|
||||
lpc43_epcomplete (priv, (n << 1));
|
||||
}
|
||||
|
||||
if (mask & LPC43_ENDPTMASK((n << 1)+1))
|
||||
{
|
||||
lpc43_epcomplete(priv, (n << 1)+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle setup interrupts */
|
||||
|
||||
uint32_t setupstat = lpc43_getreg(LPC43_USBDEV_ENDPTSETUPSTAT);
|
||||
if (setupstat)
|
||||
{
|
||||
/* Clear the endpoint complete CTRL OUT and IN when a Setup is received */
|
||||
|
||||
lpc43_putreg(LPC43_ENDPTMASK(LPC43_EP0_IN) | LPC43_ENDPTMASK(LPC43_EP0_OUT),
|
||||
LPC43_USBDEV_ENDPTCOMPLETE);
|
||||
|
||||
@ -1790,13 +1892,20 @@ static int lpc43_usbinterrupt(int irq, FAR void *context)
|
||||
if (pending)
|
||||
{
|
||||
/* We shouldn't see NAK interrupts except on Endpoint 0 */
|
||||
|
||||
if (pending & LPC43_ENDPTMASK(0))
|
||||
{
|
||||
lpc43_ep0nak(priv, 0);
|
||||
}
|
||||
|
||||
if (pending & LPC43_ENDPTMASK(1))
|
||||
{
|
||||
lpc43_ep0nak(priv, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear the interrupts */
|
||||
|
||||
lpc43_putreg(pending, LPC43_USBDEV_ENDPTNAK);
|
||||
}
|
||||
|
||||
@ -1852,9 +1961,11 @@ static int lpc43_epconfigure(FAR struct usbdev_ep_s *ep,
|
||||
if (LPC43_EPPHYIN(privep->epphy))
|
||||
{
|
||||
/* Reset the data toggles */
|
||||
|
||||
uint32_t cfg = USBDEV_ENDPTCTRL_TXR;
|
||||
|
||||
/* Set the endpoint type */
|
||||
|
||||
switch (desc->attr & USB_EP_ATTR_XFERTYPE_MASK)
|
||||
{
|
||||
case USB_EP_ATTR_XFER_CONTROL: cfg |= USBDEV_ENDPTCTRL_TXT_CTRL; break;
|
||||
@ -1862,31 +1973,41 @@ static int lpc43_epconfigure(FAR struct usbdev_ep_s *ep,
|
||||
case USB_EP_ATTR_XFER_BULK: cfg |= USBDEV_ENDPTCTRL_TXT_BULK; break;
|
||||
case USB_EP_ATTR_XFER_INT: cfg |= USBDEV_ENDPTCTRL_TXT_INTR; break;
|
||||
}
|
||||
|
||||
lpc43_chgbits (0xFFFF0000, cfg, LPC43_USBDEV_ENDPTCTRL(privep->epphy));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset the data toggles */
|
||||
|
||||
uint32_t cfg = USBDEV_ENDPTCTRL_RXR;
|
||||
|
||||
/* Set the endpoint type */
|
||||
|
||||
switch (desc->attr & USB_EP_ATTR_XFERTYPE_MASK)
|
||||
{
|
||||
case USB_EP_ATTR_XFER_CONTROL: cfg |= USBDEV_ENDPTCTRL_RXT_CTRL; break;
|
||||
case USB_EP_ATTR_XFER_ISOC: cfg |= USBDEV_ENDPTCTRL_RXT_ISOC; break;
|
||||
case USB_EP_ATTR_XFER_BULK: cfg |= USBDEV_ENDPTCTRL_RXT_BULK; break;
|
||||
}
|
||||
|
||||
lpc43_chgbits (0x0000FFFF, cfg, LPC43_USBDEV_ENDPTCTRL(privep->epphy));
|
||||
}
|
||||
|
||||
/* Reset endpoint status */
|
||||
|
||||
privep->stalled = false;
|
||||
|
||||
/* Enable the endpoint */
|
||||
|
||||
if (LPC43_EPPHYIN(privep->epphy))
|
||||
lpc43_setbits (USBDEV_ENDPTCTRL_TXE, LPC43_USBDEV_ENDPTCTRL(privep->epphy));
|
||||
{
|
||||
lpc43_setbits (USBDEV_ENDPTCTRL_TXE, LPC43_USBDEV_ENDPTCTRL(privep->epphy));
|
||||
}
|
||||
else
|
||||
lpc43_setbits (USBDEV_ENDPTCTRL_RXE, LPC43_USBDEV_ENDPTCTRL(privep->epphy));
|
||||
{
|
||||
lpc43_setbits (USBDEV_ENDPTCTRL_RXE, LPC43_USBDEV_ENDPTCTRL(privep->epphy));
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
@ -1916,14 +2037,20 @@ static int lpc43_epdisable(FAR struct usbdev_ep_s *ep)
|
||||
flags = irqsave();
|
||||
|
||||
/* Disable Endpoint */
|
||||
|
||||
if (LPC43_EPPHYIN(privep->epphy))
|
||||
lpc43_clrbits (USBDEV_ENDPTCTRL_TXE, LPC43_USBDEV_ENDPTCTRL(privep->epphy));
|
||||
{
|
||||
lpc43_clrbits (USBDEV_ENDPTCTRL_TXE, LPC43_USBDEV_ENDPTCTRL(privep->epphy));
|
||||
}
|
||||
else
|
||||
lpc43_clrbits (USBDEV_ENDPTCTRL_RXE, LPC43_USBDEV_ENDPTCTRL(privep->epphy));
|
||||
{
|
||||
lpc43_clrbits (USBDEV_ENDPTCTRL_RXE, LPC43_USBDEV_ENDPTCTRL(privep->epphy));
|
||||
}
|
||||
|
||||
privep->stalled = true;
|
||||
|
||||
/* Cancel any ongoing activity */
|
||||
|
||||
lpc43_cancelrequests(privep, -ESHUTDOWN);
|
||||
|
||||
irqrestore(flags);
|
||||
@ -2082,9 +2209,13 @@ static int lpc43_epsubmit(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *r
|
||||
/* Add the new request to the request queue for the endpoint */
|
||||
|
||||
if (LPC43_EPPHYIN(privep->epphy))
|
||||
usbtrace(TRACE_INREQQUEUED(privep->epphy), privreq->req.len);
|
||||
{
|
||||
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 (lpc43_rqenqueue(privep, privreq))
|
||||
{
|
||||
@ -2194,7 +2325,7 @@ static int lpc43_epstall(FAR struct usbdev_ep_s *ep, bool resume)
|
||||
*******************************************************************************/
|
||||
|
||||
static FAR struct usbdev_ep_s *lpc43_allocep(FAR struct usbdev_s *dev, uint8_t eplog,
|
||||
bool in, uint8_t eptype)
|
||||
bool in, uint8_t eptype)
|
||||
{
|
||||
FAR struct lpc43_usbdev_s *priv = (FAR struct lpc43_usbdev_s *)dev;
|
||||
uint32_t epset = LPC43_EPALLSET & ~LPC43_EPCTRLSET;
|
||||
@ -2292,8 +2423,11 @@ static FAR struct usbdev_ep_s *lpc43_allocep(FAR struct usbdev_s *dev, uint8_t e
|
||||
return &priv->eplist[epndx].ep;
|
||||
}
|
||||
}
|
||||
|
||||
/* Shouldn't get here */
|
||||
|
||||
}
|
||||
|
||||
irqrestore(flags);
|
||||
}
|
||||
|
||||
@ -2350,6 +2484,7 @@ static int lpc43_getframe(struct usbdev_s *dev)
|
||||
usbtrace(TRACE_DEVGETFRAME, 0);
|
||||
|
||||
/* FIXME: this actually returns the micro frame number! */
|
||||
|
||||
return (int)lpc43_getreg(LPC43_USBDEV_FRINDEX_OFFSET);
|
||||
#endif
|
||||
}
|
||||
@ -2414,9 +2549,14 @@ static int lpc43_pullup(struct usbdev_s *dev, bool enable)
|
||||
|
||||
irqstate_t flags = irqsave();
|
||||
if (enable)
|
||||
lpc43_setbits (USBDEV_USBCMD_RS, LPC43_USBDEV_USBCMD);
|
||||
{
|
||||
lpc43_setbits (USBDEV_USBCMD_RS, LPC43_USBDEV_USBCMD);
|
||||
}
|
||||
else
|
||||
lpc43_clrbits (USBDEV_USBCMD_RS, LPC43_USBDEV_USBCMD);
|
||||
{
|
||||
lpc43_clrbits (USBDEV_USBCMD_RS, LPC43_USBDEV_USBCMD);
|
||||
}
|
||||
|
||||
irqrestore(flags);
|
||||
return OK;
|
||||
}
|
||||
@ -2468,6 +2608,7 @@ void up_usbinitialize(void)
|
||||
* the physical endpoint number (which is just the index to the
|
||||
* endpoint).
|
||||
*/
|
||||
|
||||
priv->eplist[i].ep.ops = &g_epops;
|
||||
priv->eplist[i].dev = priv;
|
||||
|
||||
@ -2506,33 +2647,38 @@ void up_usbinitialize(void)
|
||||
}
|
||||
|
||||
|
||||
//clock
|
||||
/* Clock */
|
||||
|
||||
regval = getreg32(LPC43_BASE_USB0_CLK);
|
||||
regval &= ~BASE_USB0_CLK_CLKSEL_MASK;
|
||||
regval |= (BASE_USB0_CLKSEL_PLL0USB | BASE_USB0_CLK_AUTOBLOCK);
|
||||
putreg32(regval, LPC43_BASE_USB0_CLK);
|
||||
|
||||
//clock run
|
||||
/* Clock run */
|
||||
|
||||
regval = getreg32(LPC43_CCU1_M4_USB0_CFG);
|
||||
regval |= CCU_CLK_CFG_RUN;
|
||||
putreg32(regval, LPC43_CCU1_M4_USB0_CFG);
|
||||
|
||||
/* Enable PLL0 clock*/
|
||||
|
||||
lpc43_pll0usbconfig();
|
||||
lpc43_pll0usbenable();
|
||||
|
||||
|
||||
/* Reset USB block */
|
||||
|
||||
regval = lpc43_getreg(LPC43_RGU_CTRL0);
|
||||
regval |= RGU_CTRL0_USB0_RST;
|
||||
regval |= RGU_CTRL0_USB0_RST;
|
||||
lpc43_putreg(regval, LPC43_RGU_CTRL0);
|
||||
|
||||
/* Reset the controller */
|
||||
|
||||
lpc43_putreg (USBDEV_USBCMD_RST, LPC43_USBDEV_USBCMD);
|
||||
while (lpc43_getreg (LPC43_USBDEV_USBCMD) & USBDEV_USBCMD_RST)
|
||||
;
|
||||
|
||||
//power PHY
|
||||
/* Power PHY */
|
||||
|
||||
regval = getreg32(LPC43_CREG0);
|
||||
regval &= ~CREG0_USB0PHY;
|
||||
putreg32(regval, LPC43_CREG0);
|
||||
@ -2665,6 +2811,7 @@ int usbdev_register(struct usbdevclass_driver_s *driver)
|
||||
|
||||
lpc43_pullup(&g_usbdev.usbdev, true);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
@ -1149,23 +1150,30 @@ struct spi_sctrlr_s *sam_spi_slave_initialize(int port)
|
||||
DEBUGASSERT(spino == 1);
|
||||
#endif
|
||||
|
||||
/* Allocate a new state structure for this chip select. NOTE that there
|
||||
* is no protection if the same chip select is used in two different
|
||||
* chip select structures.
|
||||
*/
|
||||
|
||||
priv = (struct sam_spidev_s *)zalloc(sizeof(struct sam_spidev_s));
|
||||
if (!priv)
|
||||
#if defined(CONFIG_SAMV7_SPI0_SLAVE) && defined(CONFIG_SAMV7_SPI1_SLAVE)
|
||||
if (spino == 0)
|
||||
{
|
||||
spidbg("ERROR: Failed to allocate a chip select structure\n");
|
||||
return NULL;
|
||||
priv = &g_spi0_sctrlr;
|
||||
}
|
||||
else
|
||||
{
|
||||
priv = &g_spi1_sctrlr;
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_SAMV7_SPI0_SLAVE)
|
||||
priv = &g_spi0_sctrlr;
|
||||
|
||||
#elif defined(CONFIG_SAMV7_SPI1_SLAVE)
|
||||
priv = &g_spi1_sctrlr;
|
||||
#endif
|
||||
|
||||
/* Set up the initial state for this chip select structure. Other fields
|
||||
* were zeroed by zalloc().
|
||||
* are zeroed.
|
||||
*/
|
||||
|
||||
/* Initialize the SPI operations */
|
||||
memset(priv, 0, sizeof(struct sam_spidev_s));
|
||||
|
||||
/* Initialize the SPI operations */
|
||||
|
||||
priv->sctrlr.ops = &g_sctrlr_ops;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user