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

@ -565,9 +565,9 @@
#define USBHOST_USBMODE_CM_SHIFT (0) /* Bits 0-1: Controller mode */ #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_MASK (3 << USBHOST_USBMODE_CM_SHIFT)
#define USBHOST_USBMODE_CM_IDLE (0 << USBHOST_USBMODE_CM_SHIFT) /* Idle */ # 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_DEVICE (2 << USBHOST_USBMODE_CM_SHIFT) /* Device controller */
#define USBHOST_USBMODE_CM_HOST (3 << USBHOST_USBMODE_CM_SHIFT) /* Host controller */ # define USBHOST_USBMODE_CM_HOST (3 << USBHOST_USBMODE_CM_SHIFT) /* Host controller */
#define USBHOST_USBMODE_ES (1 << 2) /* Bit 2: Endian select */ #define USBHOST_USBMODE_ES (1 << 2) /* Bit 2: Endian select */
/* Bit 3: Not used in host mode */ /* Bit 3: Not used in host mode */
#define USBHOST_USBMODE_SDIS (1 << 4) /* Bit 4: Stream disable mode */ #define USBHOST_USBMODE_SDIS (1 << 4) /* Bit 4: Stream disable mode */

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
* *
@ -489,17 +488,17 @@ void lpc43_pll0usbdisable(void)
putreg32(regval, LPC43_PLL0USB_CTRL); 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) 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

@ -94,15 +94,15 @@ struct lpc43_i2cdev_s
struct i2c_msg_s msg; /* a single message for legacy read/write */ struct i2c_msg_s msg; /* a single message for legacy read/write */
unsigned int base; /* Base address of registers */ unsigned int base; /* Base address of registers */
uint16_t irqid; /* IRQ for this device */ 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 mutex; /* Only one thread can access at a time */
sem_t wait; /* Place to wait for state machine completion */ sem_t wait; /* Place to wait for state machine completion */
volatile uint8_t state; /* State of state machine */ volatile uint8_t state; /* State of state machine */
WDOG_ID timeout; /* watchdog to timeout when bus hung */ WDOG_ID timeout; /* watchdog to timeout when bus hung */
struct i2c_msg_s *msgs; /* remaining transfers - first one is in progress */ struct i2c_msg_s *msgs; /* remaining transfers - first one is in progress */
unsigned int nmsg; /* number of transfer remaining */ unsigned int nmsg; /* number of transfer remaining */
uint16_t wrcnt; /* number of bytes sent to tx fifo */ uint16_t wrcnt; /* number of bytes sent to tx fifo */
uint16_t rdcnt; /* number of bytes read from rx fifo */ uint16_t rdcnt; /* number of bytes read from rx fifo */
@ -152,8 +152,6 @@ struct i2c_ops_s lpc43_i2c_ops =
#endif #endif
}; };
/******************************************************************************* /*******************************************************************************
* Name: lpc43_i2c_setfrequency * 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; struct lpc43_i2cdev_s *priv = (struct lpc43_i2cdev_s *) dev;
if (frequency > 100000) 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) * 47 / frequency, priv->base + LPC43_I2C_SCLH_OFFSET);
putreg32(priv->baseFreq / (83 + 47) * 83 / frequency, priv->base + LPC43_I2C_SCLL_OFFSET); putreg32(priv->baseFreq / (83 + 47) * 83 / frequency, priv->base + LPC43_I2C_SCLL_OFFSET);
} }
else else
{ {
/* 50/50 mark space ratio */ /* 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_SCLH_OFFSET);
putreg32(priv->baseFreq / 100 * 50 / frequency, priv->base + LPC43_I2C_SCLL_OFFSET); putreg32(priv->baseFreq / 100 * 50 / frequency, priv->base + LPC43_I2C_SCLL_OFFSET);
} }
/* FIXME: This function should return the actual selected frequency */ /* 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->nmsg = 1;
priv->msgs = &(priv->msg); priv->msgs = &(priv->msg);
if ( buflen>0 ) { if (buflen > 0)
ret = i2c_start(priv); {
} ret = i2c_start(priv);
}
return (ret == 0 ? 0 : -ETIMEDOUT); 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); DEBUGASSERT(dev != NULL);
priv->wrcnt=0; priv->wrcnt = 0;
priv->rdcnt=0; priv->rdcnt = 0;
priv->msg.addr |= 0x01; priv->msg.addr |= 0x01;
priv->msg.buffer = buffer; priv->msg.buffer = buffer;
priv->msg.length = buflen; 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->nmsg = 1;
priv->msgs = &(priv->msg); priv->msgs = &(priv->msg);
if ( buflen>0 ) { if (buflen > 0)
ret = i2c_start(priv); {
} ret = i2c_start(priv);
}
return (ret == 0 ? 0 : -ETIMEDOUT); return (ret == 0 ? 0 : -ETIMEDOUT);
} }
@ -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,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); 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++; {
putreg32(I2C_CONSET_STA,priv->base+LPC43_I2C_CONSET_OFFSET); priv->msgs++;
} else { putreg32(I2C_CONSET_STA,priv->base+LPC43_I2C_CONSET_OFFSET);
i2c_stop(priv); }
} else
{
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
****************************************************************************/ ****************************************************************************/
@ -489,7 +493,7 @@ struct i2c_dev_s *up_i2cinitialize(int port)
{ {
struct lpc43_i2cdev_s *priv; struct lpc43_i2cdev_s *priv;
if (port>1) if (port > 1)
{ {
dbg("lpc I2C Only support 0,1\n"); dbg("lpc I2C Only support 0,1\n");
return NULL; return NULL;
@ -503,27 +507,33 @@ struct i2c_dev_s *up_i2cinitialize(int port)
#ifdef CONFIG_LPC43_I2C0 #ifdef CONFIG_LPC43_I2C0
if (port == 0) if (port == 0)
{ {
priv = &g_i2c0dev; priv = &g_i2c0dev;
priv->base = LPC43_I2C0_BASE; priv->base = LPC43_I2C0_BASE;
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)
regval |= SCU_SFSI2C0_SCL_EHD | SCU_SFSI2C0_SDA_EHD; {
} /* Super fast mode */
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

@ -175,7 +175,7 @@ static struct lpc43_sspdev_s g_ssp0dev =
{ {
.spidev = { &g_spi0ops }, .spidev = { &g_spi0ops },
.sspbase = LPC43_SSP0_BASE, .sspbase = LPC43_SSP0_BASE,
.sspbasefreq = BOARD_SSP0_BASEFREQ .sspbasefreq = BOARD_SSP0_BASEFREQ
#ifdef CONFIG_LPC43_SSP_INTERRUPTS #ifdef CONFIG_LPC43_SSP_INTERRUPTS
.sspirq = LPC43_IRQ_SSP0, .sspirq = LPC43_IRQ_SSP0,
#endif #endif
@ -210,7 +210,7 @@ static struct lpc43_sspdev_s g_ssp1dev =
{ {
.spidev = { &g_spi1ops }, .spidev = { &g_spi1ops },
.sspbase = LPC43_SSP1_BASE, .sspbase = LPC43_SSP1_BASE,
.sspbasefreq = BOARD_SSP1_BASEFREQ .sspbasefreq = BOARD_SSP1_BASEFREQ
#ifdef CONFIG_LPC43_SSP_INTERRUPTS #ifdef CONFIG_LPC43_SSP_INTERRUPTS
.sspirq = LPC43_IRQ_SSP1, .sspirq = LPC43_IRQ_SSP1,
#endif #endif
@ -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);
@ -561,7 +569,7 @@ void lpc43_setbaud(uintptr_t uartbase, uint32_t basefreq, uint32_t baud)
/* Candidate: /* Candidate:
* dl = ((Fbase * mul) >> 4) / ((mul + cdivadd) * Fbaud) * dl = ((Fbase * mul) >> 4) / ((mul + cdivadd) * Fbaud)
* (dl << 32) = (Fbase << 28) * cmul / ((mul + cdivadd) * Fbaud) * (dl << 32) = (Fbase << 28) * cmul / ((mul + cdivadd) * Fbaud)
*/ */
uint64_t dl64 = ((uint64_t)basefreq << 28) * cmul / uint64_t dl64 = ((uint64_t)basefreq << 28) * cmul /
((cmul + cdivadd) * baud); ((cmul + cdivadd) * baud);

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 */
@ -187,10 +190,12 @@ struct lpc43_dtd_s
uint32_t xfer_len; /* Software only - transfer len that was queued */ 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 */ #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;
} }
@ -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) 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 */ {
lpc43_setbits(USBDEV_USBCMD_SUTW, LPC43_USBDEV_USBCMD); /* Set the trip wire */
/* copy the request... */ lpc43_setbits(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)); /* Copy the request... */
/* Clear the trip wire */ for (i = 0; i < 8; i++)
lpc43_clrbits(USBDEV_USBCMD_SUTW, LPC43_USBDEV_USBCMD); {
((uint8_t *) ctrl)[i] = ((uint8_t *) dqh->setup)[i];
}
}
while (!(lpc43_getreg(LPC43_USBDEV_USBCMD) & USBDEV_USBCMD_SUTW));
/* Clear the Setup Interrupt */ /* Clear the trip wire */
lpc43_putreg (LPC43_ENDPTMASK(LPC43_EP0_OUT), LPC43_USBDEV_ENDPTSETUPSTAT);
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 (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); {
else lpc43_ep0state (privep->dev, EP0STATE_WAIT_NAK_IN);
{ }
if (LPC43_EPPHYIN(privep->epphy)) else
usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_EPINNULLPACKET), 0); {
else if (LPC43_EPPHYIN(privep->epphy))
usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_EPOUTNULLPACKET), 0); {
} usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_EPINNULLPACKET), 0);
}
else
{
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,95 +1224,105 @@ 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) */
{
case USB_REQ_GETSTATUS: switch (ctrl.req)
{ {
/* type: device-to-host; recipient = device, interface, endpoint case USB_REQ_GETSTATUS:
* value: 0 {
* index: zero interface endpoint /* type: device-to-host; recipient = device, interface, endpoint
* len: 2; data = status * value: 0
*/ * index: zero interface endpoint
* len: 2; data = status
*/
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_GETSTATUS), 0); usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_GETSTATUS), 0);
if (!priv->paddrset || len != 2 || if (!priv->paddrset || len != 2 ||
(ctrl.type & USB_REQ_DIR_IN) == 0 || value != 0) (ctrl.type & USB_REQ_DIR_IN) == 0 || value != 0)
{ {
priv->stalled = true; priv->stalled = true;
} }
else else
{ {
switch (ctrl.type & USB_REQ_RECIPIENT_MASK) switch (ctrl.type & USB_REQ_RECIPIENT_MASK)
{
case USB_REQ_RECIPIENT_ENDPOINT:
{ {
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EPGETSTATUS), 0); case USB_REQ_RECIPIENT_ENDPOINT:
privep = lpc43_epfindbyaddr(priv, index); {
if (!privep) usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EPGETSTATUS), 0);
{ privep = lpc43_epfindbyaddr(priv, index);
usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADEPGETSTATUS), 0); if (!privep)
priv->stalled = true; {
} usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADEPGETSTATUS), 0);
else priv->stalled = true;
{ }
if (privep->stalled) else
priv->ep0buf[0] = 1; /* Stalled */ {
else if (privep->stalled)
priv->ep0buf[0] = 0; /* Not stalled */ {
priv->ep0buf[1] = 0; priv->ep0buf[0] = 1; /* Stalled */
}
else
{
priv->ep0buf[0] = 0; /* Not stalled */
}
lpc43_ep0xfer (LPC43_EP0_IN, priv->ep0buf, 2); priv->ep0buf[1] = 0;
lpc43_ep0state (priv, EP0STATE_SHORTWRITE);
} lpc43_ep0xfer (LPC43_EP0_IN, priv->ep0buf, 2);
lpc43_ep0state (priv, EP0STATE_SHORTWRITE);
}
} }
break; break;
case USB_REQ_RECIPIENT_DEVICE: case USB_REQ_RECIPIENT_DEVICE:
{ {
if (index == 0) if (index == 0)
{ {
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_DEVGETSTATUS), 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) | priv->ep0buf[0] = (priv->selfpowered << USB_FEATURE_SELFPOWERED) |
(1 << USB_FEATURE_REMOTEWAKEUP); (1 << USB_FEATURE_REMOTEWAKEUP);
priv->ep0buf[1] = 0; priv->ep0buf[1] = 0;
lpc43_ep0xfer(LPC43_EP0_IN, priv->ep0buf, 2); lpc43_ep0xfer(LPC43_EP0_IN, priv->ep0buf, 2);
lpc43_ep0state (priv, EP0STATE_SHORTWRITE); lpc43_ep0state (priv, EP0STATE_SHORTWRITE);
} }
else else
{ {
usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADDEVGETSTATUS), 0); usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADDEVGETSTATUS), 0);
priv->stalled = true; priv->stalled = true;
} }
} }
break; break;
case USB_REQ_RECIPIENT_INTERFACE: case USB_REQ_RECIPIENT_INTERFACE:
{ {
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_IFGETSTATUS), 0); usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_IFGETSTATUS), 0);
priv->ep0buf[0] = 0; priv->ep0buf[0] = 0;
priv->ep0buf[1] = 0; priv->ep0buf[1] = 0;
lpc43_ep0xfer(LPC43_EP0_IN, priv->ep0buf, 2); lpc43_ep0xfer(LPC43_EP0_IN, priv->ep0buf, 2);
lpc43_ep0state (priv, EP0STATE_SHORTWRITE); lpc43_ep0state (priv, EP0STATE_SHORTWRITE);
} }
break; break;
default: default:
{ {
usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADGETSTATUS), 0); usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADGETSTATUS), 0);
priv->stalled = true; priv->stalled = true;
} }
break; break;
} }
} }
} }
@ -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,14 +1629,16 @@ 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 &&
priv->ep0state != EP0STATE_WAIT_NAK_OUT); priv->ep0state != EP0STATE_WAIT_NAK_OUT);
#endif #endif
priv->stalled = true; priv->stalled = true;
break; break;
@ -1586,13 +1668,18 @@ bool lpc43_epcomplete(struct lpc43_usbdev_s *priv, uint8_t epphy)
struct lpc43_dtd_s *dtd = &g_td[epphy]; struct lpc43_dtd_s *dtd = &g_td[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); {
else usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EPINQEMPTY), 0);
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EPOUTQEMPTY), 0); }
return true; else
} {
usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EPOUTQEMPTY), 0);
}
return true;
}
int xfrd = dtd->xfer_len - (dtd->config >> 16); 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); 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)); {
if (mask & LPC43_ENDPTMASK((n<<1)+1)) lpc43_epcomplete (priv, (n << 1));
lpc43_epcomplete(priv, (n<<1)+1); }
if (mask & LPC43_ENDPTMASK((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))
{ {
@ -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, 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; FAR struct lpc43_usbdev_s *priv = (FAR struct lpc43_usbdev_s *)dev;
uint32_t epset = LPC43_EPALLSET & ~LPC43_EPCTRLSET; 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; 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,23 +1150,30 @@ 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.
*/ */
/* Initialize the SPI operations */ memset(priv, 0, sizeof(struct sam_spidev_s));
/* Initialize the SPI operations */
priv->sctrlr.ops = &g_sctrlr_ops; priv->sctrlr.ops = &g_sctrlr_ops;