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

View File

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

View File

@ -94,15 +94,15 @@ struct lpc43_i2cdev_s
struct i2c_msg_s msg; /* a single message for legacy read/write */
unsigned int base; /* Base address of registers */
uint16_t irqid; /* IRQ for this device */
uint32_t baseFreq; /* branch frequency */
uint32_t baseFreq; /* branch frequency */
sem_t mutex; /* Only one thread can access at a time */
sem_t wait; /* Place to wait for state machine completion */
volatile uint8_t state; /* State of state machine */
WDOG_ID timeout; /* watchdog to timeout when bus hung */
struct i2c_msg_s *msgs; /* remaining transfers - first one is in progress */
unsigned int nmsg; /* number of transfer remaining */
struct i2c_msg_s *msgs; /* remaining transfers - first one is in progress */
unsigned int nmsg; /* number of transfer remaining */
uint16_t wrcnt; /* number of bytes sent to tx fifo */
uint16_t rdcnt; /* number of bytes read from rx fifo */
@ -152,8 +152,6 @@ struct i2c_ops_s lpc43_i2c_ops =
#endif
};
/*******************************************************************************
* Name: lpc43_i2c_setfrequency
*
@ -166,23 +164,23 @@ static uint32_t i2c_setfrequency(FAR struct i2c_dev_s *dev, uint32_t frequency)
struct lpc43_i2cdev_s *priv = (struct lpc43_i2cdev_s *) dev;
if (frequency > 100000)
{
/* asymetric per 400Khz I2C spec */
{
/* asymetric per 400Khz I2C spec */
putreg32(priv->baseFreq / (83 + 47) * 47 / frequency, priv->base + LPC43_I2C_SCLH_OFFSET);
putreg32(priv->baseFreq / (83 + 47) * 83 / frequency, priv->base + LPC43_I2C_SCLL_OFFSET);
}
else
{
/* 50/50 mark space ratio */
putreg32(priv->baseFreq / (83 + 47) * 47 / frequency, priv->base + LPC43_I2C_SCLH_OFFSET);
putreg32(priv->baseFreq / (83 + 47) * 83 / frequency, priv->base + LPC43_I2C_SCLL_OFFSET);
}
else
{
/* 50/50 mark space ratio */
putreg32(priv->baseFreq / 100 * 50 / frequency, priv->base + LPC43_I2C_SCLH_OFFSET);
putreg32(priv->baseFreq / 100 * 50 / frequency, priv->base + LPC43_I2C_SCLL_OFFSET);
}
putreg32(priv->baseFreq / 100 * 50 / frequency, priv->base + LPC43_I2C_SCLH_OFFSET);
putreg32(priv->baseFreq / 100 * 50 / frequency, priv->base + LPC43_I2C_SCLL_OFFSET);
}
/* FIXME: This function should return the actual selected frequency */
return (frequency);
return frequency;
}
/*******************************************************************************
@ -232,9 +230,10 @@ static int i2c_write(FAR struct i2c_dev_s *dev, const uint8_t *buffer,
priv->nmsg = 1;
priv->msgs = &(priv->msg);
if ( buflen>0 ) {
ret = i2c_start(priv);
}
if (buflen > 0)
{
ret = i2c_start(priv);
}
return (ret == 0 ? 0 : -ETIMEDOUT);
}
@ -255,8 +254,8 @@ static int i2c_read(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen)
DEBUGASSERT(dev != NULL);
priv->wrcnt=0;
priv->rdcnt=0;
priv->wrcnt = 0;
priv->rdcnt = 0;
priv->msg.addr |= 0x01;
priv->msg.buffer = buffer;
priv->msg.length = buflen;
@ -264,9 +263,10 @@ static int i2c_read(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen)
priv->nmsg = 1;
priv->msgs = &(priv->msg);
if ( buflen>0 ) {
ret = i2c_start(priv);
}
if (buflen > 0)
{
ret = i2c_start(priv);
}
return (ret == 0 ? 0 : -ETIMEDOUT);
}
@ -297,7 +297,7 @@ static int i2c_start(struct lpc43_i2cdev_s *priv)
sem_post(&priv->mutex);
return (ret);
return ret;
}
/*******************************************************************************
@ -358,19 +358,22 @@ static int i2c_transfer(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *msgs, i
ret = count - i2c_start(priv);
return (ret);
return ret;
}
void startStopNextMessage(struct lpc43_i2cdev_s *priv) {
priv->nmsg--;
void startStopNextMessage(struct lpc43_i2cdev_s *priv)
{
priv->nmsg--;
if( priv->nmsg > 0 ) {
priv->msgs++;
putreg32(I2C_CONSET_STA,priv->base+LPC43_I2C_CONSET_OFFSET);
} else {
i2c_stop(priv);
}
if(priv->nmsg > 0)
{
priv->msgs++;
putreg32(I2C_CONSET_STA,priv->base+LPC43_I2C_CONSET_OFFSET);
}
else
{
i2c_stop(priv);
}
}
/*******************************************************************************
@ -406,57 +409,60 @@ static int i2c_interrupt(int irq, FAR void *context)
}
/* Reference UM10360 19.10.5 */
state = getreg32(priv->base+LPC43_I2C_STAT_OFFSET);
msg = priv->msgs;
priv->state = state;
state &= 0xf8; //state mask, only 0xX8 is possible
state &= 0xf8; /* state mask, only 0xX8 is possible */
switch (state)
{
case 0x08: /* A START condition has been transmitted. */
case 0x10: /* A Repeated START condition has been transmitted. */
putreg32(msg->addr, priv->base + LPC43_I2C_DAT_OFFSET); //set address
putreg32(I2C_CONCLR_STAC, priv->base + LPC43_I2C_CONCLR_OFFSET); //clear start bit
putreg32(msg->addr, priv->base + LPC43_I2C_DAT_OFFSET); /* set address */
putreg32(I2C_CONCLR_STAC, priv->base + LPC43_I2C_CONCLR_OFFSET); /* clear start bit */
break;
//write cases
case 0x18: //SLA+W has been transmitted; ACK has been received
/* Write cases */
case 0x18: /* SLA+W has been transmitted; ACK has been received */
priv->wrcnt=0;
putreg32(msg->buffer[0], priv->base + LPC43_I2C_DAT_OFFSET); //put first byte
putreg32(msg->buffer[0], priv->base + LPC43_I2C_DAT_OFFSET); /* put first byte */
break;
case 0x28: //Data byte in DAT has been transmitted; ACK has been received.
case 0x28: /* Data byte in DAT has been transmitted; ACK has been received. */
priv->wrcnt++;
if (priv->wrcnt < msg->length) {
putreg32(msg->buffer[priv->wrcnt],priv->base+LPC43_I2C_DAT_OFFSET); //put next byte
putreg32(msg->buffer[priv->wrcnt],priv->base+LPC43_I2C_DAT_OFFSET); /* Put next byte */
} else {
startStopNextMessage(priv);
startStopNextMessage(priv);
}
break;
//read cases
case 0x40: //SLA+R has been transmitted; ACK has been received
/* Read cases */
case 0x40: /* SLA+R has been transmitted; ACK has been received */
priv->rdcnt = 0;
if ( msg->length > 1 ) {
putreg32(I2C_CONSET_AA, priv->base + LPC43_I2C_CONSET_OFFSET); // set ACK next read
if (msg->length > 1) {
putreg32(I2C_CONSET_AA, priv->base + LPC43_I2C_CONSET_OFFSET); /* Set ACK next read */
} else {
putreg32(I2C_CONCLR_AAC,priv->base + LPC43_I2C_CONCLR_OFFSET); // do not ACK because only one byte
putreg32(I2C_CONCLR_AAC,priv->base + LPC43_I2C_CONCLR_OFFSET); /* Do not ACK because only one byte */
}
break;
case 0x50: //Data byte has been received; ACK has been returned.
case 0x50: /* Data byte has been received; ACK has been returned. */
priv->rdcnt++;
msg->buffer[priv->rdcnt-1 ] = getreg32(priv->base+LPC43_I2C_BUFR_OFFSET);
if ( priv->rdcnt >= (msg->length - 1) ) {
putreg32(I2C_CONCLR_AAC,priv->base+LPC43_I2C_CONCLR_OFFSET); // do not ACK any more
if (priv->rdcnt >= (msg->length - 1)) {
putreg32(I2C_CONCLR_AAC,priv->base+LPC43_I2C_CONCLR_OFFSET); /* Do not ACK any more */
}
break;
case 0x58: //Data byte has been received; NACK has been returned.
case 0x58: /* Data byte has been received; NACK has been returned. */
msg->buffer[priv->rdcnt ] = getreg32(priv->base+LPC43_I2C_BUFR_OFFSET);
startStopNextMessage(priv);
break;
@ -466,13 +472,11 @@ static int i2c_interrupt(int irq, FAR void *context)
break;
}
putreg32(I2C_CONCLR_SIC, priv->base + LPC43_I2C_CONCLR_OFFSET); //clear interrupt
putreg32(I2C_CONCLR_SIC, priv->base + LPC43_I2C_CONCLR_OFFSET); /* clear interrupt */
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -489,7 +493,7 @@ struct i2c_dev_s *up_i2cinitialize(int port)
{
struct lpc43_i2cdev_s *priv;
if (port>1)
if (port > 1)
{
dbg("lpc I2C Only support 0,1\n");
return NULL;
@ -503,27 +507,33 @@ struct i2c_dev_s *up_i2cinitialize(int port)
#ifdef CONFIG_LPC43_I2C0
if (port == 0)
{
priv = &g_i2c0dev;
priv->base = LPC43_I2C0_BASE;
priv->irqid = LPC43M0_IRQ_I2C0;
priv = &g_i2c0dev;
priv->base = LPC43_I2C0_BASE;
priv->irqid = LPC43M0_IRQ_I2C0;
priv->baseFreq = BOARD_ABP1_FREQUENCY;
//enable, set mode
regval = getreg32(LPC43_SCU_SFSI2C0 );
/* Enable, set mode */
regval = getreg32(LPC43_SCU_SFSI2C0);
regval |= SCU_SFSI2C0_SCL_EZI | SCU_SFSI2C0_SDA_EZI;
if ( CONFIG_I2C0_FREQ == 1000000 ) { //super fast mode
regval |= SCU_SFSI2C0_SCL_EHD | SCU_SFSI2C0_SDA_EHD;
}
if (CONFIG_I2C0_FREQ == 1000000)
{
/* Super fast mode */
regval |= SCU_SFSI2C0_SCL_EHD | SCU_SFSI2C0_SDA_EHD;
}
putreg32(regval, LPC43_SCU_SFSI2C0);
//enable clock
/* Enable clock */
regval = getreg32(LPC43_CCU1_APB1_I2C0_CFG);
regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU1_APB1_I2C0_CFG);
i2c_setfrequency( (struct i2c_dev_s *)priv,CONFIG_I2C0_FREQ);
i2c_setfrequency((struct i2c_dev_s *)priv,CONFIG_I2C0_FREQ);
//no pins configuration needed
/* No pin configuration needed */
}
else
#endif
@ -535,14 +545,16 @@ struct i2c_dev_s *up_i2cinitialize(int port)
priv->irqid = LPC43M0_IRQ_I2C1;
priv->baseFreq = BOARD_ABP3_FREQUENCY;
//no need to enable
/* No need to enable */
/* Enable clock */
//enable clock
regval = getreg32(LPC43_CCU1_APB3_I2C1_CFG);
regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU1_APB3_I2C1_CFG);
//pins configuration
/* Pin configuration */
lpc43_pin_config(PINCONF_I2C1_SCL);
lpc43_pin_config(PINCONF_I2C1_SDA);
@ -578,7 +590,7 @@ struct i2c_dev_s *up_i2cinitialize(int port)
/* Install our operations */
priv->dev.ops = &lpc43_i2c_ops;
return (&priv->dev);
return &priv->dev;
}
/*******************************************************************************
@ -599,5 +611,4 @@ int up_i2cuninitialize(FAR struct i2c_dev_s * dev)
return OK;
}
#endif
#endif /* CONFIG_LPC43_I2C0 || CONFIG_LPC43_I2C1 */

View File

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

View File

@ -334,12 +334,14 @@ void lpc43_usart0_setup(void)
regval |= (BOARD_USART0_CLKSRC | BASE_USART0_CLK_AUTOBLOCK);
putreg32(regval, LPC43_BASE_USART0_CLK);
//clock register
/* Clock register */
regval = getreg32(LPC43_CCU1_M4_USART0_CFG);
regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU1_M4_USART0_CFG);
//clock peripheral
/* Clock peripheral */
regval = getreg32(LPC43_CCU2_APB0_USART0_CFG);
regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU2_APB0_USART0_CFG);
@ -381,12 +383,14 @@ void lpc43_uart1_setup(void)
regval |= (BOARD_UART1_CLKSRC | BASE_UART1_CLK_AUTOBLOCK);
putreg32(regval, LPC43_BASE_UART1_CLK);
//clock register
/* Clock register */
regval = getreg32(LPC43_CCU1_M4_UART1_CFG);
regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU1_M4_UART1_CFG);
//clock peripheral
/* Clock peripheral */
regval = getreg32(LPC43_CCU2_APB0_UART1_CFG);
regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU2_APB0_UART1_CFG);
@ -428,12 +432,14 @@ void lpc43_usart2_setup(void)
regval |= (BOARD_USART2_CLKSRC | BASE_USART2_CLK_AUTOBLOCK);
putreg32(regval, LPC43_BASE_USART2_CLK);
//clock register
/* Clock register */
regval = getreg32(LPC43_CCU1_M4_USART2_CFG);
regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU1_M4_USART2_CFG);
//clock peripheral
/* Clock peripheral */
regval = getreg32(LPC43_CCU2_APB2_USART2_CFG);
regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU2_APB2_USART2_CFG);
@ -476,12 +482,14 @@ void lpc43_usart3_setup(void)
regval |= (BOARD_USART3_CLKSRC | BASE_USART3_CLK_AUTOBLOCK);
putreg32(regval, LPC43_BASE_USART3_CLK);
//clock register
/* Clock register */
regval = getreg32(LPC43_CCU1_M4_USART3_CFG);
regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU1_M4_USART3_CFG);
//clock peripheral
/* Clock peripheral */
regval = getreg32(LPC43_CCU2_APB2_USART3_CFG);
regval |= CCU_CLK_CFG_RUN;
putreg32(regval, LPC43_CCU2_APB2_USART3_CFG);
@ -561,7 +569,7 @@ void lpc43_setbaud(uintptr_t uartbase, uint32_t basefreq, uint32_t baud)
/* Candidate:
* dl = ((Fbase * mul) >> 4) / ((mul + cdivadd) * Fbaud)
* (dl << 32) = (Fbase << 28) * cmul / ((mul + cdivadd) * Fbaud)
*/
*/
uint64_t dl64 = ((uint64_t)basefreq << 28) * cmul /
((cmul + cdivadd) * baud);

View File

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

View File

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