Merged nuttx/arch into master

This commit is contained in:
Lok Tep 2015-09-29 17:26:13 +02:00
commit bf9fdfa447
7 changed files with 455 additions and 275 deletions

View File

@ -428,14 +428,14 @@ static inline void lpc43_m4clkselect(uint32_t clksel)
void lpc43_pll0usbconfig(void) void lpc43_pll0usbconfig(void)
{ {
//power down, no bypass, direct i-o, /* 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((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_MDIV, LPC43_PLL0USB_MDIV);
putreg32(BOARD_USB0_NP_DIV, LPC43_PLL0USB_NP_DIV); putreg32(BOARD_USB0_NP_DIV, LPC43_PLL0USB_NP_DIV);
} }
/**************************************************************************** /****************************************************************************
* Name: lpc43_pll0usbenable * Name: lpc43_pll0usbenable
* *
@ -467,7 +467,6 @@ void lpc43_pll0usbenable(void)
while ((getreg32(LPC43_PLL0USB_STAT) & PLL0USB_STAT_LOCK) == 0); while ((getreg32(LPC43_PLL0USB_STAT) & PLL0USB_STAT_LOCK) == 0);
} }
/**************************************************************************** /****************************************************************************
* Name: lpc43_pll0usbdisable * Name: lpc43_pll0usbdisable
* *
@ -494,12 +493,12 @@ void lpc43_idiva(void)
{ {
uint32_t regval; uint32_t regval;
//set clock source, divider /* Set clock source, divider */
regval = getreg32(LPC43_IDIVA_CTRL); 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); regval |= BOARD_IDIVA_CLKSRC | IDIVA_CTRL_AUTOBLOCK | IDIVA_CTRL_IDIV(BOARD_IDIVA_DIVIDER);
putreg32(regval, LPC43_IDIVA_CTRL); putreg32(regval, LPC43_IDIVA_CTRL);
} }
#endif #endif
@ -508,12 +507,12 @@ void lpc43_idivb(void)
{ {
uint32_t regval; uint32_t regval;
//set clock source, divider /* Set clock source, divider */
regval = getreg32(LPC43_IDIVB_CTRL); 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); regval |= BOARD_IDIVB_CLKSRC | IDIVBCD_CTRL_AUTOBLOCK | IDIVBCD_CTRL_IDIV(BOARD_IDIVB_DIVIDER);
putreg32(regval, LPC43_IDIVB_CTRL); putreg32(regval, LPC43_IDIVB_CTRL);
} }
#endif #endif
@ -522,12 +521,12 @@ void lpc43_idivc(void)
{ {
uint32_t regval; uint32_t regval;
//set clock source, divider /* Set clock source, divider */
regval = getreg32(LPC43_IDIVC_CTRL); 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); regval |= BOARD_IDIVC_CLKSRC | IDIVBCD_CTRL_AUTOBLOCK | IDIVBCD_CTRL_IDIV(BOARD_IDIVC_DIVIDER);
putreg32(regval, LPC43_IDIVC_CTRL); putreg32(regval, LPC43_IDIVC_CTRL);
} }
#endif #endif
@ -536,12 +535,12 @@ void lpc43_idivd(void)
{ {
uint32_t regval; uint32_t regval;
//set clock source, divider /* Set clock source, divider */
regval = getreg32(LPC43_IDIVD_CTRL); 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); regval |= BOARD_IDIVD_CLKSRC | IDIVBCD_CTRL_AUTOBLOCK | IDIVBCD_CTRL_IDIV(BOARD_IDIVD_DIVIDER);
putreg32(regval, LPC43_IDIVD_CTRL); putreg32(regval, LPC43_IDIVD_CTRL);
} }
#endif #endif
@ -550,27 +549,26 @@ void lpc43_idive(void)
{ {
uint32_t regval; uint32_t regval;
//set clock source, divider /* Set clock source, divider */
regval = getreg32(LPC43_IDIVE_CTRL); 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); regval |= BOARD_IDIVE_CLKSRC | IDIVE_CTRL_AUTOBLOCK | IDIVE_CTRL_IDIV(BOARD_IDIVE_DIVIDER);
putreg32(regval, LPC43_IDIVE_CTRL); putreg32(regval, LPC43_IDIVE_CTRL);
} }
#endif #endif
#if defined(BOARD_ABP1_CLKSRC) #if defined(BOARD_ABP1_CLKSRC)
void lpc43_abp1(void) void lpc43_abp1(void)
{ {
uint32_t regval; uint32_t regval;
//set clock source /* Set clock source */
regval = getreg32(LPC43_BASE_APB1_CLK); regval = getreg32(LPC43_BASE_APB1_CLK);
regval &= ~BASE_APB1_CLK_CLKSEL_MASK; regval &= ~BASE_APB1_CLK_CLKSEL_MASK;
regval |= BOARD_ABP1_CLKSRC | BASE_APB1_CLK_AUTOBLOCK; regval |= BOARD_ABP1_CLKSRC | BASE_APB1_CLK_AUTOBLOCK;
putreg32(regval, LPC43_BASE_APB1_CLK); putreg32(regval, LPC43_BASE_APB1_CLK);
} }
#endif #endif
@ -579,12 +577,12 @@ void lpc43_abp3(void)
{ {
uint32_t regval; uint32_t regval;
//set clock source /* Set clock source */
regval = getreg32(LPC43_BASE_APB3_CLK); regval = getreg32(LPC43_BASE_APB3_CLK);
regval &= ~BASE_APB3_CLK_CLKSEL_MASK; regval &= ~BASE_APB3_CLK_CLKSEL_MASK;
regval |= BOARD_ABP3_CLKSRC | BASE_APB3_CLK_AUTOBLOCK; regval |= BOARD_ABP3_CLKSRC | BASE_APB3_CLK_AUTOBLOCK;
putreg32(regval, LPC43_BASE_APB3_CLK); putreg32(regval, LPC43_BASE_APB3_CLK);
} }
#endif #endif
@ -652,7 +650,7 @@ void lpc43_clockconfig(void)
lpc43_pll1config(PLL_CONTROLS); lpc43_pll1config(PLL_CONTROLS);
#endif #endif
//configure idivs /* Configure idivs */
#if defined(BOARD_IDIVA_DIVIDER) && defined(BOARD_IDIVA_CLKSRC) #if defined(BOARD_IDIVA_DIVIDER) && defined(BOARD_IDIVA_CLKSRC)
lpc43_idiva(); lpc43_idiva();
@ -674,7 +672,7 @@ void lpc43_clockconfig(void)
lpc43_idive(); lpc43_idive();
#endif #endif
//configure abpXs /* Configure abpXs */
#if defined(BOARD_ABP1_CLKSRC) #if defined(BOARD_ABP1_CLKSRC)
lpc43_abp1(); lpc43_abp1();
@ -683,6 +681,4 @@ void lpc43_clockconfig(void)
#if defined(BOARD_ABP3_CLKSRC) #if defined(BOARD_ABP3_CLKSRC)
lpc43_abp3(); lpc43_abp3();
#endif #endif
} }

View File

@ -152,8 +152,6 @@ struct i2c_ops_s lpc43_i2c_ops =
#endif #endif
}; };
/******************************************************************************* /*******************************************************************************
* Name: lpc43_i2c_setfrequency * Name: lpc43_i2c_setfrequency
* *
@ -182,7 +180,7 @@ static uint32_t i2c_setfrequency(FAR struct i2c_dev_s *dev, uint32_t frequency)
/* FIXME: This function should return the actual selected frequency */ /* FIXME: This function should return the actual selected frequency */
return (frequency); return frequency;
} }
/******************************************************************************* /*******************************************************************************
@ -232,7 +230,8 @@ static int i2c_write(FAR struct i2c_dev_s *dev, const uint8_t *buffer,
priv->nmsg = 1; priv->nmsg = 1;
priv->msgs = &(priv->msg); priv->msgs = &(priv->msg);
if ( buflen>0 ) { if (buflen > 0)
{
ret = i2c_start(priv); ret = i2c_start(priv);
} }
@ -264,7 +263,8 @@ static int i2c_read(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen)
priv->nmsg = 1; priv->nmsg = 1;
priv->msgs = &(priv->msg); priv->msgs = &(priv->msg);
if ( buflen>0 ) { if (buflen > 0)
{
ret = i2c_start(priv); ret = i2c_start(priv);
} }
@ -297,7 +297,7 @@ static int i2c_start(struct lpc43_i2cdev_s *priv)
sem_post(&priv->mutex); sem_post(&priv->mutex);
return (ret); return ret;
} }
/******************************************************************************* /*******************************************************************************
@ -358,17 +358,20 @@ static int i2c_transfer(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *msgs, i
ret = count - i2c_start(priv); ret = count - i2c_start(priv);
return ret;
return (ret);
} }
void startStopNextMessage(struct lpc43_i2cdev_s *priv) { void startStopNextMessage(struct lpc43_i2cdev_s *priv)
{
priv->nmsg--; priv->nmsg--;
if( priv->nmsg > 0 ) { if(priv->nmsg > 0)
{
priv->msgs++; priv->msgs++;
putreg32(I2C_CONSET_STA,priv->base+LPC43_I2C_CONSET_OFFSET); putreg32(I2C_CONSET_STA,priv->base+LPC43_I2C_CONSET_OFFSET);
} else { }
else
{
i2c_stop(priv); i2c_stop(priv);
} }
} }
@ -406,57 +409,60 @@ static int i2c_interrupt(int irq, FAR void *context)
} }
/* Reference UM10360 19.10.5 */ /* Reference UM10360 19.10.5 */
state = getreg32(priv->base+LPC43_I2C_STAT_OFFSET); state = getreg32(priv->base+LPC43_I2C_STAT_OFFSET);
msg = priv->msgs; msg = priv->msgs;
priv->state = state; priv->state = state;
state &= 0xf8; //state mask, only 0xX8 is possible state &= 0xf8; /* state mask, only 0xX8 is possible */
switch (state) switch (state)
{ {
case 0x08: /* A START condition has been transmitted. */ case 0x08: /* A START condition has been transmitted. */
case 0x10: /* A Repeated 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(msg->addr, priv->base + LPC43_I2C_DAT_OFFSET); /* set address */
putreg32(I2C_CONCLR_STAC, priv->base + LPC43_I2C_CONCLR_OFFSET); //clear start bit putreg32(I2C_CONCLR_STAC, priv->base + LPC43_I2C_CONCLR_OFFSET); /* clear start bit */
break; break;
//write cases /* Write cases */
case 0x18: //SLA+W has been transmitted; ACK has been received
case 0x18: /* SLA+W has been transmitted; ACK has been received */
priv->wrcnt=0; 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; 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++; priv->wrcnt++;
if (priv->wrcnt < msg->length) { 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 { } else {
startStopNextMessage(priv); startStopNextMessage(priv);
} }
break; break;
//read cases /* Read cases */
case 0x40: //SLA+R has been transmitted; ACK has been received
case 0x40: /* SLA+R has been transmitted; ACK has been received */
priv->rdcnt = 0; priv->rdcnt = 0;
if (msg->length > 1) { if (msg->length > 1) {
putreg32(I2C_CONSET_AA, priv->base + LPC43_I2C_CONSET_OFFSET); // set ACK next read putreg32(I2C_CONSET_AA, priv->base + LPC43_I2C_CONSET_OFFSET); /* Set ACK next read */
} else { } 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; 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++; priv->rdcnt++;
msg->buffer[priv->rdcnt-1 ] = getreg32(priv->base+LPC43_I2C_BUFR_OFFSET); msg->buffer[priv->rdcnt-1 ] = getreg32(priv->base+LPC43_I2C_BUFR_OFFSET);
if (priv->rdcnt >= (msg->length - 1)) { if (priv->rdcnt >= (msg->length - 1)) {
putreg32(I2C_CONCLR_AAC,priv->base+LPC43_I2C_CONCLR_OFFSET); // do not ACK any more putreg32(I2C_CONCLR_AAC,priv->base+LPC43_I2C_CONCLR_OFFSET); /* Do not ACK any more */
} }
break; 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); msg->buffer[priv->rdcnt ] = getreg32(priv->base+LPC43_I2C_BUFR_OFFSET);
startStopNextMessage(priv); startStopNextMessage(priv);
break; break;
@ -466,13 +472,11 @@ static int i2c_interrupt(int irq, FAR void *context)
break; 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; return OK;
} }
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
@ -508,22 +512,28 @@ struct i2c_dev_s *up_i2cinitialize(int port)
priv->irqid = LPC43M0_IRQ_I2C0; priv->irqid = LPC43M0_IRQ_I2C0;
priv->baseFreq = BOARD_ABP1_FREQUENCY; priv->baseFreq = BOARD_ABP1_FREQUENCY;
//enable, set mode /* Enable, set mode */
regval = getreg32(LPC43_SCU_SFSI2C0); regval = getreg32(LPC43_SCU_SFSI2C0);
regval |= SCU_SFSI2C0_SCL_EZI | SCU_SFSI2C0_SDA_EZI; regval |= SCU_SFSI2C0_SCL_EZI | SCU_SFSI2C0_SDA_EZI;
if ( CONFIG_I2C0_FREQ == 1000000 ) { //super fast mode if (CONFIG_I2C0_FREQ == 1000000)
{
/* Super fast mode */
regval |= SCU_SFSI2C0_SCL_EHD | SCU_SFSI2C0_SDA_EHD; regval |= SCU_SFSI2C0_SCL_EHD | SCU_SFSI2C0_SDA_EHD;
} }
putreg32(regval, LPC43_SCU_SFSI2C0); putreg32(regval, LPC43_SCU_SFSI2C0);
//enable clock /* Enable clock */
regval = getreg32(LPC43_CCU1_APB1_I2C0_CFG); regval = getreg32(LPC43_CCU1_APB1_I2C0_CFG);
regval |= CCU_CLK_CFG_RUN; regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU1_APB1_I2C0_CFG); 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 else
#endif #endif
@ -535,14 +545,16 @@ struct i2c_dev_s *up_i2cinitialize(int port)
priv->irqid = LPC43M0_IRQ_I2C1; priv->irqid = LPC43M0_IRQ_I2C1;
priv->baseFreq = BOARD_ABP3_FREQUENCY; 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 = getreg32(LPC43_CCU1_APB3_I2C1_CFG);
regval |= CCU_CLK_CFG_RUN; regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU1_APB3_I2C1_CFG); putreg32(regval, LPC43_CCU1_APB3_I2C1_CFG);
//pins configuration /* Pin configuration */
lpc43_pin_config(PINCONF_I2C1_SCL); lpc43_pin_config(PINCONF_I2C1_SCL);
lpc43_pin_config(PINCONF_I2C1_SDA); lpc43_pin_config(PINCONF_I2C1_SDA);
@ -578,7 +590,7 @@ struct i2c_dev_s *up_i2cinitialize(int port)
/* Install our operations */ /* Install our operations */
priv->dev.ops = &lpc43_i2c_ops; 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; return OK;
} }
#endif /* CONFIG_LPC43_I2C0 || CONFIG_LPC43_I2C1 */
#endif

View File

@ -309,6 +309,7 @@ static int ssp_lock(FAR struct spi_dev_s *dev, bool lock)
{ {
(void)sem_post(&priv->exclsem); (void)sem_post(&priv->exclsem);
} }
return OK; return OK;
} }
#endif #endif
@ -708,22 +709,26 @@ static inline FAR struct lpc43_sspdev_s *lpc43_ssp0initialize(void)
flags = irqsave(); flags = irqsave();
/* Configure clocking */ /* Configure clocking */
regval = getreg32(LPC43_BASE_SSP0_CLK); regval = getreg32(LPC43_BASE_SSP0_CLK);
regval &= ~BASE_SSP0_CLK_CLKSEL_MASK; regval &= ~BASE_SSP0_CLK_CLKSEL_MASK;
regval |= (BOARD_SSP0_CLKSRC | BASE_SSP0_CLK_AUTOBLOCK); regval |= (BOARD_SSP0_CLKSRC | BASE_SSP0_CLK_AUTOBLOCK);
putreg32(regval, LPC43_BASE_SSP0_CLK); putreg32(regval, LPC43_BASE_SSP0_CLK);
//clock register /* Clock register */
regval = getreg32(LPC43_CCU1_M4_SSP0_CFG); regval = getreg32(LPC43_CCU1_M4_SSP0_CFG);
regval |= CCU_CLK_CFG_RUN; regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU1_M4_SSP0_CFG); putreg32(regval, LPC43_CCU1_M4_SSP0_CFG);
//clock peripheral /* Clock peripheral */
regval = getreg32(LPC43_CCU2_APB0_SSP0_CFG); regval = getreg32(LPC43_CCU2_APB0_SSP0_CFG);
regval |= CCU_CLK_CFG_RUN; regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU2_APB0_SSP0_CFG); putreg32(regval, LPC43_CCU2_APB0_SSP0_CFG);
//pins configuration /* Pin configuration */
lpc43_pin_config(PINCONF_SSP0_SCK); lpc43_pin_config(PINCONF_SSP0_SCK);
lpc43_pin_config(PINCONF_SSP0_SSEL); lpc43_pin_config(PINCONF_SSP0_SSEL);
lpc43_pin_config(PINCONF_SSP0_MISO); lpc43_pin_config(PINCONF_SSP0_MISO);
@ -758,22 +763,26 @@ static inline FAR struct lpc43_sspdev_s *lpc43_ssp1initialize(void)
flags = irqsave(); flags = irqsave();
/* Configure clocking */ /* Configure clocking */
regval = getreg32(LPC43_BASE_SSP1_CLK); regval = getreg32(LPC43_BASE_SSP1_CLK);
regval &= ~BASE_SSP1_CLK_CLKSEL_MASK; regval &= ~BASE_SSP1_CLK_CLKSEL_MASK;
regval |= (BOARD_SSP1_CLKSRC | BASE_SSP1_CLK_AUTOBLOCK); regval |= (BOARD_SSP1_CLKSRC | BASE_SSP1_CLK_AUTOBLOCK);
putreg32(regval, LPC43_BASE_SSP1_CLK); putreg32(regval, LPC43_BASE_SSP1_CLK);
//clock register /* Clock register */
regval = getreg32(LPC43_CCU1_M4_SSP1_CFG); regval = getreg32(LPC43_CCU1_M4_SSP1_CFG);
regval |= CCU_CLK_CFG_RUN; regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU1_M4_SSP1_CFG); putreg32(regval, LPC43_CCU1_M4_SSP1_CFG);
//clock peripheral /* Clock peripheral */
regval = getreg32(LPC43_CCU2_APB2_SSP1_CFG); regval = getreg32(LPC43_CCU2_APB2_SSP1_CFG);
regval |= CCU_CLK_CFG_RUN; regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU2_APB2_SSP1_CFG); putreg32(regval, LPC43_CCU2_APB2_SSP1_CFG);
//pins configuration /* Pins configuration */
lpc43_pin_config(PINCONF_SSP1_SCK); lpc43_pin_config(PINCONF_SSP1_SCK);
lpc43_pin_config(PINCONF_SSP1_SSEL); lpc43_pin_config(PINCONF_SSP1_SSEL);
lpc43_pin_config(PINCONF_SSP1_MISO); lpc43_pin_config(PINCONF_SSP1_MISO);
@ -818,11 +827,13 @@ FAR struct spi_dev_s *lpc43_sspinitialize(int port)
priv = lpc43_ssp0initialize(); priv = lpc43_ssp0initialize();
break; break;
#endif #endif
#ifdef CONFIG_LPC43_SSP1 #ifdef CONFIG_LPC43_SSP1
case 1: case 1:
priv = lpc43_ssp1initialize(); priv = lpc43_ssp1initialize();
break; break;
#endif #endif
default: default:
return NULL; return NULL;
} }
@ -908,4 +919,3 @@ void ssp_flush(FAR struct spi_dev_s *dev)
} }
#endif /* CONFIG_LPC43_SSP0/1 */ #endif /* CONFIG_LPC43_SSP0/1 */

View File

@ -334,12 +334,14 @@ void lpc43_usart0_setup(void)
regval |= (BOARD_USART0_CLKSRC | BASE_USART0_CLK_AUTOBLOCK); regval |= (BOARD_USART0_CLKSRC | BASE_USART0_CLK_AUTOBLOCK);
putreg32(regval, LPC43_BASE_USART0_CLK); putreg32(regval, LPC43_BASE_USART0_CLK);
//clock register /* Clock register */
regval = getreg32(LPC43_CCU1_M4_USART0_CFG); regval = getreg32(LPC43_CCU1_M4_USART0_CFG);
regval |= CCU_CLK_CFG_RUN; regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU1_M4_USART0_CFG); putreg32(regval, LPC43_CCU1_M4_USART0_CFG);
//clock peripheral /* Clock peripheral */
regval = getreg32(LPC43_CCU2_APB0_USART0_CFG); regval = getreg32(LPC43_CCU2_APB0_USART0_CFG);
regval |= CCU_CLK_CFG_RUN; regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU2_APB0_USART0_CFG); putreg32(regval, LPC43_CCU2_APB0_USART0_CFG);
@ -381,12 +383,14 @@ void lpc43_uart1_setup(void)
regval |= (BOARD_UART1_CLKSRC | BASE_UART1_CLK_AUTOBLOCK); regval |= (BOARD_UART1_CLKSRC | BASE_UART1_CLK_AUTOBLOCK);
putreg32(regval, LPC43_BASE_UART1_CLK); putreg32(regval, LPC43_BASE_UART1_CLK);
//clock register /* Clock register */
regval = getreg32(LPC43_CCU1_M4_UART1_CFG); regval = getreg32(LPC43_CCU1_M4_UART1_CFG);
regval |= CCU_CLK_CFG_RUN; regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU1_M4_UART1_CFG); putreg32(regval, LPC43_CCU1_M4_UART1_CFG);
//clock peripheral /* Clock peripheral */
regval = getreg32(LPC43_CCU2_APB0_UART1_CFG); regval = getreg32(LPC43_CCU2_APB0_UART1_CFG);
regval |= CCU_CLK_CFG_RUN; regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU2_APB0_UART1_CFG); putreg32(regval, LPC43_CCU2_APB0_UART1_CFG);
@ -428,12 +432,14 @@ void lpc43_usart2_setup(void)
regval |= (BOARD_USART2_CLKSRC | BASE_USART2_CLK_AUTOBLOCK); regval |= (BOARD_USART2_CLKSRC | BASE_USART2_CLK_AUTOBLOCK);
putreg32(regval, LPC43_BASE_USART2_CLK); putreg32(regval, LPC43_BASE_USART2_CLK);
//clock register /* Clock register */
regval = getreg32(LPC43_CCU1_M4_USART2_CFG); regval = getreg32(LPC43_CCU1_M4_USART2_CFG);
regval |= CCU_CLK_CFG_RUN; regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU1_M4_USART2_CFG); putreg32(regval, LPC43_CCU1_M4_USART2_CFG);
//clock peripheral /* Clock peripheral */
regval = getreg32(LPC43_CCU2_APB2_USART2_CFG); regval = getreg32(LPC43_CCU2_APB2_USART2_CFG);
regval |= CCU_CLK_CFG_RUN; regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU2_APB2_USART2_CFG); putreg32(regval, LPC43_CCU2_APB2_USART2_CFG);
@ -476,12 +482,14 @@ void lpc43_usart3_setup(void)
regval |= (BOARD_USART3_CLKSRC | BASE_USART3_CLK_AUTOBLOCK); regval |= (BOARD_USART3_CLKSRC | BASE_USART3_CLK_AUTOBLOCK);
putreg32(regval, LPC43_BASE_USART3_CLK); putreg32(regval, LPC43_BASE_USART3_CLK);
//clock register /* Clock register */
regval = getreg32(LPC43_CCU1_M4_USART3_CFG); regval = getreg32(LPC43_CCU1_M4_USART3_CFG);
regval |= CCU_CLK_CFG_RUN; regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU1_M4_USART3_CFG); putreg32(regval, LPC43_CCU1_M4_USART3_CFG);
//clock peripheral /* Clock peripheral */
regval = getreg32(LPC43_CCU2_APB2_USART3_CFG); regval = getreg32(LPC43_CCU2_APB2_USART3_CFG);
regval |= CCU_CLK_CFG_RUN; regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU2_APB2_USART3_CFG); putreg32(regval, LPC43_CCU2_APB2_USART3_CFG);

View File

@ -174,7 +174,10 @@
/* Hardware interface **********************************************************/ /* 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 struct lpc43_dtd_s
{ {
volatile uint32_t nextdesc; /* Address of the next DMA descripto in RAM */ volatile uint32_t nextdesc; /* Address of the next DMA descripto in RAM */
@ -188,9 +191,11 @@ struct lpc43_dtd_s
}; };
/* DTD nextdesc field */ /* DTD nextdesc field */
#define DTD_NEXTDESC_INVALID (1 << 0) /* Bit 0 : Next Descriptor Invalid */ #define DTD_NEXTDESC_INVALID (1 << 0) /* Bit 0 : Next Descriptor Invalid */
/* DTD config field */ /* DTD config field */
#define DTD_CONFIG_LENGTH(n) ((n) << 16) /* Bits 16-31 : Total bytes to transfer */ #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_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) */ #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 */ #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 */ /* This represents a queue head - not these must be aligned to a 2048 byte boundary */
struct lpc43_dqh_s struct lpc43_dqh_s
{ {
uint32_t capability; /* Endpoint capability */ uint32_t capability; /* Endpoint capability */
@ -211,6 +217,7 @@ struct lpc43_dqh_s
}; };
/* DQH capability field */ /* DQH capability field */
#define DQH_CAPABILITY_MULT_VARIABLE (0 << 30) /* Bits 30-31 : Number of packets executed per transaction descriptor */ #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_MULT_NUM(n) ((n) << 30)
#define DQH_CAPABILITY_ZLT (1 << 29) /* Bit 29 : Zero Length Termination Select */ #define DQH_CAPABILITY_ZLT (1 << 29) /* Bit 29 : Zero Length Termination Select */
@ -220,10 +227,12 @@ struct lpc43_dqh_s
/* Endpoints ******************************************************************/ /* Endpoints ******************************************************************/
/* Number of endpoints */ /* Number of endpoints */
#define LPC43_NLOGENDPOINTS (4) /* ep0-3 */ #define LPC43_NLOGENDPOINTS (4) /* ep0-3 */
#define LPC43_NPHYSENDPOINTS (8) /* x2 for IN and OUT */ #define LPC43_NPHYSENDPOINTS (8) /* x2 for IN and OUT */
/* Odd physical endpoint numbers are IN; even are OUT */ /* Odd physical endpoint numbers are IN; even are OUT */
#define LPC43_EPPHYIN(epphy) (((epphy)&1)!=0) #define LPC43_EPPHYIN(epphy) (((epphy)&1)!=0)
#define LPC43_EPPHYOUT(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) #define LPC43_EPPHYOUT2LOG(epphy) (((uint8_t)(epphy)>>1)|USB_DIR_OUT)
/* Endpoint 0 is special... */ /* Endpoint 0 is special... */
#define LPC43_EP0_OUT (0) #define LPC43_EP0_OUT (0)
#define LPC43_EP0_IN (1) #define LPC43_EP0_IN (1)
/* Each endpoint has somewhat different characteristics */ /* Each endpoint has somewhat different characteristics */
#define LPC43_EPALLSET (0xff) /* All endpoints */ #define LPC43_EPALLSET (0xff) /* All endpoints */
#define LPC43_EPOUTSET (0x55) /* Even phy endpoint numbers are OUT EPs */ #define LPC43_EPOUTSET (0x55) /* Even phy endpoint numbers are OUT EPs */
#define LPC43_EPINSET (0xaa) /* Odd endpoint numbers are IN 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 */ #define LPC43_EPISOCSET (0xfc) /* Isochronous endpoints */
/* Maximum packet sizes for endpoints */ /* Maximum packet sizes for endpoints */
#define LPC43_EP0MAXPACKET (64) /* EP0 max packet size (1-64) */ #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_BULKMAXPACKET (512) /* Bulk endpoint max packet (8/16/32/64/512) */
#define LPC43_INTRMAXPACKET (1024) /* Interrupt endpoint max packet (1 to 1024) */ #define LPC43_INTRMAXPACKET (1024) /* Interrupt endpoint max packet (1 to 1024) */
#define LPC43_ISOCMAXPACKET (512) /* Acutally 1..1023 */ #define LPC43_ISOCMAXPACKET (512) /* Acutally 1..1023 */
/* Endpoint bit position in SETUPSTAT, PRIME, FLUSH, STAT, COMPLETE registers */ /* Endpoint bit position in SETUPSTAT, PRIME, FLUSH, STAT, COMPLETE registers */
#define LPC43_ENDPTSHIFT(epphy) (LPC43_EPPHYIN(epphy) ? (16 + ((epphy) >> 1)) : ((epphy) >> 1)) #define LPC43_ENDPTSHIFT(epphy) (LPC43_EPPHYIN(epphy) ? (16 + ((epphy) >> 1)) : ((epphy) >> 1))
#define LPC43_ENDPTMASK(epphy) (1 << LPC43_ENDPTSHIFT(epphy)) #define LPC43_ENDPTMASK(epphy) (1 << LPC43_ENDPTSHIFT(epphy))
#define LPC43_ENDPTMASK_ALL 0x000f000f #define LPC43_ENDPTMASK_ALL 0x000f000f
@ -323,6 +336,7 @@ struct lpc43_usbdev_s
#endif #endif
/* The endpoint list */ /* The endpoint list */
struct lpc43_ep_s eplist[LPC43_NPHYSENDPOINTS]; 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); static void lpc43_cancelrequests(struct lpc43_ep_s *privep, int16_t status);
/* Interrupt handling **********************************************************/ /* Interrupt handling **********************************************************/
static struct lpc43_ep_s *lpc43_epfindbyaddr(struct lpc43_usbdev_s *priv, static struct lpc43_ep_s *lpc43_epfindbyaddr(struct lpc43_usbdev_s *priv,
uint16_t eplog); uint16_t eplog);
static void lpc43_dispatchrequest(struct lpc43_usbdev_s *priv, 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->flink = req;
privep->tail = req; privep->tail = req;
} }
return is_empty; return is_empty;
} }
@ -727,20 +743,27 @@ static void lpc43_readsetup(uint8_t epphy, struct usb_ctrlreq_s *ctrl)
struct lpc43_dqh_s *dqh = &g_qh[epphy]; struct lpc43_dqh_s *dqh = &g_qh[epphy];
int i; int i;
do { do
{
/* Set the trip wire */ /* Set the trip wire */
lpc43_setbits(USBDEV_USBCMD_SUTW, LPC43_USBDEV_USBCMD); lpc43_setbits(USBDEV_USBCMD_SUTW, LPC43_USBDEV_USBCMD);
/* copy the request... */ /* Copy the request... */
for (i = 0; i < 8; i++)
((uint8_t *) ctrl)[i] = ((uint8_t *) dqh->setup)[i];
} while (!(lpc43_getreg(LPC43_USBDEV_USBCMD) & USBDEV_USBCMD_SUTW)); 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 trip wire */ /* Clear the trip wire */
lpc43_clrbits(USBDEV_USBCMD_SUTW, LPC43_USBDEV_USBCMD); lpc43_clrbits(USBDEV_USBCMD_SUTW, LPC43_USBDEV_USBCMD);
/* Clear the Setup Interrupt */ /* Clear the Setup Interrupt */
lpc43_putreg (LPC43_ENDPTMASK(LPC43_EP0_OUT), LPC43_USBDEV_ENDPTSETUPSTAT); 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 (privreq->req.len == 0)
{ {
/* If the class driver is responding to a setup packet, then wait for the /* If the class driver is responding to a setup packet, then wait for
* host to illicit thr response */ * the host to illicit thr response
*/
if (privep->epphy == LPC43_EP0_IN && privep->dev->ep0state == EP0STATE_SETUP_OUT) if (privep->epphy == LPC43_EP0_IN && privep->dev->ep0state == EP0STATE_SETUP_OUT)
{
lpc43_ep0state (privep->dev, EP0STATE_WAIT_NAK_IN); lpc43_ep0state (privep->dev, EP0STATE_WAIT_NAK_IN);
}
else else
{ {
if (LPC43_EPPHYIN(privep->epphy)) if (LPC43_EPPHYIN(privep->epphy))
{
usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_EPINNULLPACKET), 0); usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_EPINNULLPACKET), 0);
}
else else
{
usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_EPOUTNULLPACKET), 0); usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_EPOUTNULLPACKET), 0);
} }
}
lpc43_reqcomplete(privep, lpc43_rqdequeue(privep), OK); lpc43_reqcomplete(privep, lpc43_rqdequeue(privep), OK);
return OK; return OK;
} }
if (privep->epphy == LPC43_EP0_IN) 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) 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; int bytesleft = privreq->req.len - privreq->req.xfrd;
if (LPC43_EPPHYIN(privep->epphy)) if (LPC43_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 */
lpc43_writedtd (dtd, privreq->req.buf + privreq->req.xfrd, bytesleft); 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); lpc43_queuedtd(privep->epphy, dtd);
return OK; return OK;
@ -1010,6 +1049,7 @@ static void lpc43_dispatchrequest(struct lpc43_usbdev_s *priv,
static void lpc43_ep0configure(struct lpc43_usbdev_s *priv) static void lpc43_ep0configure(struct lpc43_usbdev_s *priv)
{ {
/* Enable ep0 IN and ep0 OUT */ /* Enable ep0 IN and ep0 OUT */
g_qh[LPC43_EP0_OUT].capability = (DQH_CAPABILITY_MAX_PACKET(CONFIG_USBDEV_EP0_MAXSIZE) | g_qh[LPC43_EP0_OUT].capability = (DQH_CAPABILITY_MAX_PACKET(CONFIG_USBDEV_EP0_MAXSIZE) |
DQH_CAPABILITY_IOS | DQH_CAPABILITY_IOS |
DQH_CAPABILITY_ZLT); 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; g_qh[LPC43_EP0_IN ].currdesc = DTD_NEXTDESC_INVALID;
/* Enable EP0 */ /* Enable EP0 */
lpc43_setbits (USBDEV_ENDPTCTRL0_RXE | USBDEV_ENDPTCTRL0_TXE, LPC43_USBDEV_ENDPTCTRL0); 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); lpc43_putreg (lpc43_getreg(LPC43_USBDEV_ENDPTCOMPLETE), LPC43_USBDEV_ENDPTCOMPLETE);
/* Wait for all prime operations to have completed and then flush all DTDs */ /* Wait for all prime operations to have completed and then flush all DTDs */
while (lpc43_getreg (LPC43_USBDEV_ENDPTPRIME) != 0) while (lpc43_getreg (LPC43_USBDEV_ENDPTPRIME) != 0)
; ;
lpc43_putreg (LPC43_ENDPTMASK_ALL, LPC43_USBDEV_ENDPTFLUSH); lpc43_putreg (LPC43_ENDPTMASK_ALL, LPC43_USBDEV_ENDPTFLUSH);
@ -1058,6 +1100,7 @@ static void lpc43_usbreset(struct lpc43_usbdev_s *priv)
; ;
/* Reset endpoints */ /* Reset endpoints */
for (epphy = 0; epphy < LPC43_NPHYSENDPOINTS; epphy++) for (epphy = 0; epphy < LPC43_NPHYSENDPOINTS; epphy++)
{ {
struct lpc43_ep_s *privep = &priv->eplist[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); lpc43_cancelrequests (privep, -ESHUTDOWN);
/* Reset endpoint status */ /* Reset endpoint status */
privep->stalled = false; privep->stalled = false;
} }
@ -1072,25 +1116,33 @@ static void lpc43_usbreset(struct lpc43_usbdev_s *priv)
* driver should then accept any new configurations. */ * driver should then accept any new configurations. */
if (priv->driver) if (priv->driver)
{
CLASS_DISCONNECT(priv->driver, &priv->usbdev); CLASS_DISCONNECT(priv->driver, &priv->usbdev);
}
/* Set the interrupt Threshold control interval to 0 */ /* Set the interrupt Threshold control interval to 0 */
lpc43_chgbits(USBDEV_USBCMD_ITC_MASK, USBDEV_USBCMD_ITCIMME, LPC43_USBDEV_USBCMD); lpc43_chgbits(USBDEV_USBCMD_ITC_MASK, USBDEV_USBCMD_ITCIMME, LPC43_USBDEV_USBCMD);
/* Zero out the Endpoint queue heads */ /* Zero out the Endpoint queue heads */
memset ((void *) g_qh, 0, sizeof (g_qh)); memset ((void *) g_qh, 0, sizeof (g_qh));
memset ((void *) g_td, 0, sizeof (g_td)); memset ((void *) g_td, 0, sizeof (g_td));
/* Set USB address to 0 */ /* Set USB address to 0 */
lpc43_set_address (priv, 0); lpc43_set_address (priv, 0);
/* Initialise the Enpoint List Address */ /* Initialise the Enpoint List Address */
lpc43_putreg ((uint32_t)g_qh, LPC43_USBDEV_ENDPOINTLIST); lpc43_putreg ((uint32_t)g_qh, LPC43_USBDEV_ENDPOINTLIST);
/* EndPoint 0 initialization */ /* EndPoint 0 initialization */
lpc43_ep0configure(priv); lpc43_ep0configure(priv);
/* Enable Device interrupts */ /* Enable Device interrupts */
lpc43_putreg(USB_FRAME_INT | USB_ERROR_INT | lpc43_putreg(USB_FRAME_INT | USB_ERROR_INT |
USBDEV_USBINTR_NAKE | USBDEV_USBINTR_SLE | USBDEV_USBINTR_URE | USBDEV_USBINTR_PCE | USBDEV_USBINTR_UE, USBDEV_USBINTR_NAKE | USBDEV_USBINTR_SLE | USBDEV_USBINTR_URE | USBDEV_USBINTR_PCE | USBDEV_USBINTR_UE,
LPC43_USBDEV_USBINTR); 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: case EP0STATE_WAIT_NAK_IN:
lpc43_putreg (LPC43_ENDPTMASK(LPC43_EP0_IN), LPC43_USBDEV_ENDPTNAKEN); lpc43_putreg (LPC43_ENDPTMASK(LPC43_EP0_IN), LPC43_USBDEV_ENDPTNAKEN);
break; break;
case EP0STATE_WAIT_NAK_OUT: case EP0STATE_WAIT_NAK_OUT:
lpc43_putreg (LPC43_ENDPTMASK(LPC43_EP0_OUT), LPC43_USBDEV_ENDPTNAKEN); lpc43_putreg (LPC43_ENDPTMASK(LPC43_EP0_OUT), LPC43_USBDEV_ENDPTNAKEN);
break; break;
default: default:
lpc43_putreg(0, LPC43_USBDEV_ENDPTNAKEN); lpc43_putreg(0, LPC43_USBDEV_ENDPTNAKEN);
break; break;
@ -1140,7 +1194,8 @@ static inline void lpc43_ep0setup(struct lpc43_usbdev_s *priv)
uint16_t len; uint16_t len;
/* Terminate any pending requests - since all DTDs will have been retired /* 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_OUT], -EPROTO);
lpc43_cancelrequests(&priv->eplist[LPC43_EP0_IN], -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; priv->stalled = false;
/* Read EP0 setup data */ /* Read EP0 setup data */
lpc43_readsetup(LPC43_EP0_OUT, &ctrl); lpc43_readsetup(LPC43_EP0_OUT, &ctrl);
/* Starting a control request - update state */ /* Starting a control request - update state */
lpc43_ep0state (priv, (ctrl.type & USB_REQ_DIR_IN) ? EP0STATE_SETUP_IN : EP0STATE_SETUP_OUT); 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 */ /* And extract the little-endian 16-bit values to host order */
value = GETUINT16(ctrl.value); value = GETUINT16(ctrl.value);
index = GETUINT16(ctrl.index); index = GETUINT16(ctrl.index);
len = GETUINT16(ctrl.len); len = GETUINT16(ctrl.len);
@ -1166,12 +1224,17 @@ static inline void lpc43_ep0setup(struct lpc43_usbdev_s *priv)
ctrl.type, ctrl.req, value, index, len); ctrl.type, ctrl.req, value, index, len);
/* Dispatch any non-standard requests */ /* Dispatch any non-standard requests */
if ((ctrl.type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) if ((ctrl.type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD)
{
lpc43_dispatchrequest(priv, &ctrl); lpc43_dispatchrequest(priv, &ctrl);
}
else else
{ {
/* Handle standard request. Pick off the things of interest to the USB /* Handle standard request. Pick off the things of interest to the USB
* device controller driver; pass what is left to the class driver */ * device controller driver; pass what is left to the class driver.
*/
switch (ctrl.req) switch (ctrl.req)
{ {
case USB_REQ_GETSTATUS: case USB_REQ_GETSTATUS:
@ -1204,9 +1267,14 @@ static inline void lpc43_ep0setup(struct lpc43_usbdev_s *priv)
else else
{ {
if (privep->stalled) 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 */
}
priv->ep0buf[1] = 0; priv->ep0buf[1] = 0;
lpc43_ep0xfer (LPC43_EP0_IN, priv->ep0buf, 2); lpc43_ep0xfer (LPC43_EP0_IN, priv->ep0buf, 2);
@ -1326,6 +1394,7 @@ static inline void lpc43_ep0setup(struct lpc43_usbdev_s *priv)
* index: 0 * index: 0
* len: 0; data = none * len: 0; data = none
*/ */
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EP0SETUPSETADDRESS), value); usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EP0SETUPSETADDRESS), value);
if ((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && if ((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE &&
index == 0 && len == 0 && value < 128) 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: case EP0STATE_DATA_IN:
if (lpc43_rqempty(privep)) if (lpc43_rqempty(privep))
{
return; return;
}
if (lpc43_epcomplete (priv, epphy)) if (lpc43_epcomplete (priv, epphy))
{
lpc43_ep0state (priv, EP0STATE_WAIT_NAK_OUT); lpc43_ep0state (priv, EP0STATE_WAIT_NAK_OUT);
}
break; break;
case EP0STATE_DATA_OUT: case EP0STATE_DATA_OUT:
if (lpc43_rqempty(privep)) if (lpc43_rqempty(privep))
{
return; return;
}
if (lpc43_epcomplete (priv, epphy)) if (lpc43_epcomplete (priv, epphy))
{
lpc43_ep0state (priv, EP0STATE_WAIT_NAK_IN); lpc43_ep0state (priv, EP0STATE_WAIT_NAK_IN);
}
break; break;
case EP0STATE_SHORTWRITE: case EP0STATE_SHORTWRITE:
@ -1499,12 +1576,15 @@ static void lpc43_ep0complete(struct lpc43_usbdev_s *priv, uint8_t epphy)
lpc43_ep0state (priv, EP0STATE_IDLE); lpc43_ep0state (priv, EP0STATE_IDLE);
/* If we've received a SETADDRESS packet, then we set the address /* 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) if (! priv->paddrset && priv->paddr != 0)
{ {
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EP0INSETADDRESS), (uint16_t)priv->paddr); usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EP0INSETADDRESS), (uint16_t)priv->paddr);
lpc43_set_address (priv, priv->paddr); lpc43_set_address (priv, priv->paddr);
} }
break; break;
case EP0STATE_WAIT_STATUS_OUT: case EP0STATE_WAIT_STATUS_OUT:
@ -1549,10 +1629,12 @@ static void lpc43_ep0nak(struct lpc43_usbdev_s *priv, uint8_t epphy)
lpc43_ep0xfer (LPC43_EP0_IN, NULL, 0); lpc43_ep0xfer (LPC43_EP0_IN, NULL, 0);
lpc43_ep0state (priv, EP0STATE_WAIT_STATUS_IN); lpc43_ep0state (priv, EP0STATE_WAIT_STATUS_IN);
break; break;
case EP0STATE_WAIT_NAK_OUT: case EP0STATE_WAIT_NAK_OUT:
lpc43_ep0xfer (LPC43_EP0_OUT, NULL, 0); lpc43_ep0xfer (LPC43_EP0_OUT, NULL, 0);
lpc43_ep0state (priv, EP0STATE_WAIT_STATUS_OUT); lpc43_ep0state (priv, EP0STATE_WAIT_STATUS_OUT);
break; break;
default: default:
#ifdef CONFIG_DEBUG #ifdef CONFIG_DEBUG
DEBUGASSERT(priv->ep0state != EP0STATE_WAIT_NAK_IN && DEBUGASSERT(priv->ep0state != EP0STATE_WAIT_NAK_IN &&
@ -1588,9 +1670,14 @@ bool lpc43_epcomplete(struct lpc43_usbdev_s *priv, uint8_t epphy)
if (privreq == NULL) /* This shouldn't really happen */ if (privreq == NULL) /* This shouldn't really happen */
{ {
if (LPC43_EPPHYOUT(privep->epphy)) if (LPC43_EPPHYOUT(privep->epphy))
{
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EPINQEMPTY), 0); usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EPINQEMPTY), 0);
}
else else
{
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EPOUTQEMPTY), 0); usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EPOUTQEMPTY), 0);
}
return true; return true;
} }
@ -1656,6 +1743,7 @@ static int lpc43_usbinterrupt(int irq, FAR void *context)
usbtrace(TRACE_INTENTRY(LPC43_TRACEINTID_USB), 0); usbtrace(TRACE_INTENTRY(LPC43_TRACEINTID_USB), 0);
/* Read the interrupts and then clear them */ /* Read the interrupts and then clear them */
disr = lpc43_getreg(LPC43_USBDEV_USBSTS); disr = lpc43_getreg(LPC43_USBDEV_USBSTS);
lpc43_putreg(disr, 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) if (disr & USBDEV_USBSTS_UI)
{ {
/* Handle completion interrupts */ /* Handle completion interrupts */
uint32_t mask = lpc43_getreg (LPC43_USBDEV_ENDPTCOMPLETE); uint32_t mask = lpc43_getreg (LPC43_USBDEV_ENDPTCOMPLETE);
if (mask) if (mask)
{ {
/* Clear any NAK interrupt and completion interrupts */ /* Clear any NAK interrupt and completion interrupts */
lpc43_putreg (mask, LPC43_USBDEV_ENDPTNAK); lpc43_putreg (mask, LPC43_USBDEV_ENDPTNAK);
lpc43_putreg (mask, LPC43_USBDEV_ENDPTCOMPLETE); lpc43_putreg (mask, LPC43_USBDEV_ENDPTCOMPLETE);
if (mask & LPC43_ENDPTMASK(0)) if (mask & LPC43_ENDPTMASK(0))
{
lpc43_ep0complete(priv, 0); lpc43_ep0complete(priv, 0);
}
if (mask & LPC43_ENDPTMASK(1)) if (mask & LPC43_ENDPTMASK(1))
{
lpc43_ep0complete(priv, 1); lpc43_ep0complete(priv, 1);
}
for (n = 1; n < LPC43_NLOGENDPOINTS; n++) for (n = 1; n < LPC43_NLOGENDPOINTS; n++)
{ {
if (mask & LPC43_ENDPTMASK((n << 1))) if (mask & LPC43_ENDPTMASK((n << 1)))
{
lpc43_epcomplete (priv, (n << 1)); lpc43_epcomplete (priv, (n << 1));
}
if (mask & LPC43_ENDPTMASK((n << 1)+1)) if (mask & LPC43_ENDPTMASK((n << 1)+1))
{
lpc43_epcomplete(priv, (n << 1)+1); lpc43_epcomplete(priv, (n << 1)+1);
} }
} }
}
/* Handle setup interrupts */ /* Handle setup interrupts */
uint32_t setupstat = lpc43_getreg(LPC43_USBDEV_ENDPTSETUPSTAT); uint32_t setupstat = lpc43_getreg(LPC43_USBDEV_ENDPTSETUPSTAT);
if (setupstat) if (setupstat)
{ {
/* Clear the endpoint complete CTRL OUT and IN when a Setup is received */ /* 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_putreg(LPC43_ENDPTMASK(LPC43_EP0_IN) | LPC43_ENDPTMASK(LPC43_EP0_OUT),
LPC43_USBDEV_ENDPTCOMPLETE); LPC43_USBDEV_ENDPTCOMPLETE);
@ -1790,13 +1892,20 @@ static int lpc43_usbinterrupt(int irq, FAR void *context)
if (pending) if (pending)
{ {
/* We shouldn't see NAK interrupts except on Endpoint 0 */ /* We shouldn't see NAK interrupts except on Endpoint 0 */
if (pending & LPC43_ENDPTMASK(0)) if (pending & LPC43_ENDPTMASK(0))
{
lpc43_ep0nak(priv, 0); lpc43_ep0nak(priv, 0);
}
if (pending & LPC43_ENDPTMASK(1)) if (pending & LPC43_ENDPTMASK(1))
{
lpc43_ep0nak(priv, 1); lpc43_ep0nak(priv, 1);
} }
}
/* Clear the interrupts */ /* Clear the interrupts */
lpc43_putreg(pending, LPC43_USBDEV_ENDPTNAK); 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)) if (LPC43_EPPHYIN(privep->epphy))
{ {
/* Reset the data toggles */ /* Reset the data toggles */
uint32_t cfg = USBDEV_ENDPTCTRL_TXR; uint32_t cfg = USBDEV_ENDPTCTRL_TXR;
/* Set the endpoint type */ /* Set the endpoint type */
switch (desc->attr & USB_EP_ATTR_XFERTYPE_MASK) switch (desc->attr & USB_EP_ATTR_XFERTYPE_MASK)
{ {
case USB_EP_ATTR_XFER_CONTROL: cfg |= USBDEV_ENDPTCTRL_TXT_CTRL; break; 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_BULK: cfg |= USBDEV_ENDPTCTRL_TXT_BULK; break;
case USB_EP_ATTR_XFER_INT: cfg |= USBDEV_ENDPTCTRL_TXT_INTR; break; case USB_EP_ATTR_XFER_INT: cfg |= USBDEV_ENDPTCTRL_TXT_INTR; break;
} }
lpc43_chgbits (0xFFFF0000, cfg, LPC43_USBDEV_ENDPTCTRL(privep->epphy)); lpc43_chgbits (0xFFFF0000, cfg, LPC43_USBDEV_ENDPTCTRL(privep->epphy));
} }
else else
{ {
/* Reset the data toggles */ /* Reset the data toggles */
uint32_t cfg = USBDEV_ENDPTCTRL_RXR; uint32_t cfg = USBDEV_ENDPTCTRL_RXR;
/* Set the endpoint type */ /* Set the endpoint type */
switch (desc->attr & USB_EP_ATTR_XFERTYPE_MASK) 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_CONTROL: cfg |= USBDEV_ENDPTCTRL_RXT_CTRL; break;
case USB_EP_ATTR_XFER_ISOC: cfg |= USBDEV_ENDPTCTRL_RXT_ISOC; 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; case USB_EP_ATTR_XFER_BULK: cfg |= USBDEV_ENDPTCTRL_RXT_BULK; break;
} }
lpc43_chgbits (0x0000FFFF, cfg, LPC43_USBDEV_ENDPTCTRL(privep->epphy)); lpc43_chgbits (0x0000FFFF, cfg, LPC43_USBDEV_ENDPTCTRL(privep->epphy));
} }
/* Reset endpoint status */ /* Reset endpoint status */
privep->stalled = false; privep->stalled = false;
/* Enable the endpoint */ /* Enable the endpoint */
if (LPC43_EPPHYIN(privep->epphy)) 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 else
{
lpc43_setbits (USBDEV_ENDPTCTRL_RXE, LPC43_USBDEV_ENDPTCTRL(privep->epphy)); lpc43_setbits (USBDEV_ENDPTCTRL_RXE, LPC43_USBDEV_ENDPTCTRL(privep->epphy));
}
return OK; return OK;
} }
@ -1916,14 +2037,20 @@ static int lpc43_epdisable(FAR struct usbdev_ep_s *ep)
flags = irqsave(); flags = irqsave();
/* Disable Endpoint */ /* Disable Endpoint */
if (LPC43_EPPHYIN(privep->epphy)) 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 else
{
lpc43_clrbits (USBDEV_ENDPTCTRL_RXE, LPC43_USBDEV_ENDPTCTRL(privep->epphy)); lpc43_clrbits (USBDEV_ENDPTCTRL_RXE, LPC43_USBDEV_ENDPTCTRL(privep->epphy));
}
privep->stalled = true; privep->stalled = true;
/* Cancel any ongoing activity */ /* Cancel any ongoing activity */
lpc43_cancelrequests(privep, -ESHUTDOWN); lpc43_cancelrequests(privep, -ESHUTDOWN);
irqrestore(flags); 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 */ /* Add the new request to the request queue for the endpoint */
if (LPC43_EPPHYIN(privep->epphy)) if (LPC43_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 (lpc43_rqenqueue(privep, privreq)) if (lpc43_rqenqueue(privep, privreq))
{ {
@ -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; return &priv->eplist[epndx].ep;
} }
} }
/* Shouldn't get here */ /* Shouldn't get here */
} }
irqrestore(flags); irqrestore(flags);
} }
@ -2350,6 +2484,7 @@ static int lpc43_getframe(struct usbdev_s *dev)
usbtrace(TRACE_DEVGETFRAME, 0); usbtrace(TRACE_DEVGETFRAME, 0);
/* FIXME: this actually returns the micro frame number! */ /* FIXME: this actually returns the micro frame number! */
return (int)lpc43_getreg(LPC43_USBDEV_FRINDEX_OFFSET); return (int)lpc43_getreg(LPC43_USBDEV_FRINDEX_OFFSET);
#endif #endif
} }
@ -2414,9 +2549,14 @@ static int lpc43_pullup(struct usbdev_s *dev, bool enable)
irqstate_t flags = irqsave(); irqstate_t flags = irqsave();
if (enable) if (enable)
{
lpc43_setbits (USBDEV_USBCMD_RS, LPC43_USBDEV_USBCMD); lpc43_setbits (USBDEV_USBCMD_RS, LPC43_USBDEV_USBCMD);
}
else else
{
lpc43_clrbits (USBDEV_USBCMD_RS, LPC43_USBDEV_USBCMD); lpc43_clrbits (USBDEV_USBCMD_RS, LPC43_USBDEV_USBCMD);
}
irqrestore(flags); irqrestore(flags);
return OK; return OK;
} }
@ -2468,6 +2608,7 @@ void up_usbinitialize(void)
* the physical endpoint number (which is just the index to the * the physical endpoint number (which is just the index to the
* endpoint). * endpoint).
*/ */
priv->eplist[i].ep.ops = &g_epops; priv->eplist[i].ep.ops = &g_epops;
priv->eplist[i].dev = priv; priv->eplist[i].dev = priv;
@ -2506,33 +2647,38 @@ void up_usbinitialize(void)
} }
//clock /* Clock */
regval = getreg32(LPC43_BASE_USB0_CLK); regval = getreg32(LPC43_BASE_USB0_CLK);
regval &= ~BASE_USB0_CLK_CLKSEL_MASK; regval &= ~BASE_USB0_CLK_CLKSEL_MASK;
regval |= (BASE_USB0_CLKSEL_PLL0USB | BASE_USB0_CLK_AUTOBLOCK); regval |= (BASE_USB0_CLKSEL_PLL0USB | BASE_USB0_CLK_AUTOBLOCK);
putreg32(regval, LPC43_BASE_USB0_CLK); putreg32(regval, LPC43_BASE_USB0_CLK);
//clock run /* Clock run */
regval = getreg32(LPC43_CCU1_M4_USB0_CFG); regval = getreg32(LPC43_CCU1_M4_USB0_CFG);
regval |= CCU_CLK_CFG_RUN; regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU1_M4_USB0_CFG); putreg32(regval, LPC43_CCU1_M4_USB0_CFG);
/* Enable PLL0 clock*/ /* Enable PLL0 clock*/
lpc43_pll0usbconfig(); lpc43_pll0usbconfig();
lpc43_pll0usbenable(); lpc43_pll0usbenable();
/* Reset USB block */ /* Reset USB block */
regval = lpc43_getreg(LPC43_RGU_CTRL0); regval = lpc43_getreg(LPC43_RGU_CTRL0);
regval |= RGU_CTRL0_USB0_RST; regval |= RGU_CTRL0_USB0_RST;
lpc43_putreg(regval, LPC43_RGU_CTRL0); lpc43_putreg(regval, LPC43_RGU_CTRL0);
/* Reset the controller */ /* Reset the controller */
lpc43_putreg (USBDEV_USBCMD_RST, LPC43_USBDEV_USBCMD); lpc43_putreg (USBDEV_USBCMD_RST, LPC43_USBDEV_USBCMD);
while (lpc43_getreg (LPC43_USBDEV_USBCMD) & USBDEV_USBCMD_RST) while (lpc43_getreg (LPC43_USBDEV_USBCMD) & USBDEV_USBCMD_RST)
; ;
//power PHY /* Power PHY */
regval = getreg32(LPC43_CREG0); regval = getreg32(LPC43_CREG0);
regval &= ~CREG0_USB0PHY; regval &= ~CREG0_USB0PHY;
putreg32(regval, LPC43_CREG0); putreg32(regval, LPC43_CREG0);
@ -2665,6 +2811,7 @@ int usbdev_register(struct usbdevclass_driver_s *driver)
lpc43_pullup(&g_usbdev.usbdev, true); lpc43_pullup(&g_usbdev.usbdev, true);
} }
return ret; return ret;
} }

View File

@ -41,6 +41,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <string.h>
#include <semaphore.h> #include <semaphore.h>
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
@ -1149,22 +1150,29 @@ struct spi_sctrlr_s *sam_spi_slave_initialize(int port)
DEBUGASSERT(spino == 1); DEBUGASSERT(spino == 1);
#endif #endif
/* Allocate a new state structure for this chip select. NOTE that there #if defined(CONFIG_SAMV7_SPI0_SLAVE) && defined(CONFIG_SAMV7_SPI1_SLAVE)
* is no protection if the same chip select is used in two different if (spino == 0)
* chip select structures.
*/
priv = (struct sam_spidev_s *)zalloc(sizeof(struct sam_spidev_s));
if (!priv)
{ {
spidbg("ERROR: Failed to allocate a chip select structure\n"); priv = &g_spi0_sctrlr;
return NULL; }
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 /* Set up the initial state for this chip select structure. Other fields
* were zeroed by zalloc(). * are zeroed.
*/ */
memset(priv, 0, sizeof(struct sam_spidev_s));
/* Initialize the SPI operations */ /* Initialize the SPI operations */
priv->sctrlr.ops = &g_sctrlr_ops; priv->sctrlr.ops = &g_sctrlr_ops;