Merged nuttx/nuttx into master
This commit is contained in:
commit
0d123014e4
@ -212,6 +212,7 @@ struct stm32_chan_s
|
|||||||
uint8_t eptype; /* See OTGFS_EPTYPE_* definitions */
|
uint8_t eptype; /* See OTGFS_EPTYPE_* definitions */
|
||||||
uint8_t funcaddr; /* Device function address */
|
uint8_t funcaddr; /* Device function address */
|
||||||
uint8_t speed; /* Device speed */
|
uint8_t speed; /* Device speed */
|
||||||
|
uint8_t interval; /* Interrupt/isochronous EP polling interval */
|
||||||
uint8_t pid; /* Data PID */
|
uint8_t pid; /* Data PID */
|
||||||
uint8_t npackets; /* Number of packets (for data toggle) */
|
uint8_t npackets; /* Number of packets (for data toggle) */
|
||||||
bool inuse; /* True: This channel is "in use" */
|
bool inuse; /* True: This channel is "in use" */
|
||||||
@ -1210,6 +1211,7 @@ static int stm32_ctrlchan_alloc(FAR struct stm32_usbhost_s *priv,
|
|||||||
chan->eptype = OTGFS_EPTYPE_CTRL;
|
chan->eptype = OTGFS_EPTYPE_CTRL;
|
||||||
chan->funcaddr = funcaddr;
|
chan->funcaddr = funcaddr;
|
||||||
chan->speed = speed;
|
chan->speed = speed;
|
||||||
|
chan->interval = 0;
|
||||||
chan->maxpacket = STM32_EP0_DEF_PACKET_SIZE;
|
chan->maxpacket = STM32_EP0_DEF_PACKET_SIZE;
|
||||||
chan->indata1 = false;
|
chan->indata1 = false;
|
||||||
chan->outdata1 = false;
|
chan->outdata1 = false;
|
||||||
@ -1234,6 +1236,7 @@ static int stm32_ctrlchan_alloc(FAR struct stm32_usbhost_s *priv,
|
|||||||
chan->eptype = OTGFS_EPTYPE_CTRL;
|
chan->eptype = OTGFS_EPTYPE_CTRL;
|
||||||
chan->funcaddr = funcaddr;
|
chan->funcaddr = funcaddr;
|
||||||
chan->speed = speed;
|
chan->speed = speed;
|
||||||
|
chan->interval = 0;
|
||||||
chan->maxpacket = STM32_EP0_DEF_PACKET_SIZE;
|
chan->maxpacket = STM32_EP0_DEF_PACKET_SIZE;
|
||||||
chan->indata1 = false;
|
chan->indata1 = false;
|
||||||
chan->outdata1 = false;
|
chan->outdata1 = false;
|
||||||
@ -1363,6 +1366,7 @@ static int stm32_xfrep_alloc(FAR struct stm32_usbhost_s *priv,
|
|||||||
chan->eptype = epdesc->xfrtype;
|
chan->eptype = epdesc->xfrtype;
|
||||||
chan->funcaddr = hport->funcaddr;
|
chan->funcaddr = hport->funcaddr;
|
||||||
chan->speed = hport->speed;
|
chan->speed = hport->speed;
|
||||||
|
chan->interval = epdesc->interval;
|
||||||
chan->maxpacket = epdesc->mxpacketsize;
|
chan->maxpacket = epdesc->mxpacketsize;
|
||||||
chan->indata1 = false;
|
chan->indata1 = false;
|
||||||
chan->outdata1 = false;
|
chan->outdata1 = false;
|
||||||
@ -1893,6 +1897,8 @@ static ssize_t stm32_in_transfer(FAR struct stm32_usbhost_s *priv, int chidx,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
useconds_t delay;
|
||||||
|
|
||||||
/* Get the elapsed time. Has the timeout elapsed?
|
/* Get the elapsed time. Has the timeout elapsed?
|
||||||
* if not then try again.
|
* if not then try again.
|
||||||
*/
|
*/
|
||||||
@ -1907,13 +1913,46 @@ static ssize_t stm32_in_transfer(FAR struct stm32_usbhost_s *priv, int chidx,
|
|||||||
return (ssize_t)ret;
|
return (ssize_t)ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait a bit before retrying after a NAK.
|
/* Wait a bit before retrying after a NAK. */
|
||||||
*
|
|
||||||
* REVISIT: This is intended to give the CPU a break from
|
|
||||||
* the tight polling loop. But are there performance issues?
|
|
||||||
*/
|
|
||||||
|
|
||||||
usleep(1000);
|
if (chan->eptype == OTGFS_HCCHAR_EPTYP_INTR)
|
||||||
|
{
|
||||||
|
/* For interrupt (and isochronous) endpoints, the
|
||||||
|
* polling rate is determined by the bInterval field
|
||||||
|
* of the endpoint descriptor (in units of frames
|
||||||
|
* which we treat as milliseconds here).
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (chan->interval > 0)
|
||||||
|
{
|
||||||
|
/* Convert the delay to units of microseconds */
|
||||||
|
|
||||||
|
delay = (useconds_t)chan->interval * 1000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Out of range! For interrupt endpoints, the valid
|
||||||
|
* range is 1-255 frames. Assume one frame.
|
||||||
|
*/
|
||||||
|
|
||||||
|
delay = 1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* For Isochronous endpoints, bInterval must be 1. Bulk
|
||||||
|
* endpoints do not have a polling interval. Rather,
|
||||||
|
* the should wait until data is received.
|
||||||
|
*
|
||||||
|
* REVISIT: For bulk endpoints this 1 msec delay is only
|
||||||
|
* intended to give the CPU a break from the bulk EP tight
|
||||||
|
* polling loop. But are there performance issues?
|
||||||
|
*/
|
||||||
|
|
||||||
|
delay = 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
usleep(delay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -5319,6 +5319,7 @@ static void stm32_hwinitialize(FAR struct stm32_usbdev_s *priv)
|
|||||||
|
|
||||||
stm32_putreg(0xbfffffff, STM32_OTGHS_GINTSTS);
|
stm32_putreg(0xbfffffff, STM32_OTGHS_GINTSTS);
|
||||||
|
|
||||||
|
#ifndef BOARD_ENABLE_USBOTG_HSULPI
|
||||||
/* Disable the ULPI Clock enable in RCC AHB1 Register. This must
|
/* Disable the ULPI Clock enable in RCC AHB1 Register. This must
|
||||||
* be done because if both the ULPI and the FS PHY clock enable bits
|
* be done because if both the ULPI and the FS PHY clock enable bits
|
||||||
* are set at the same time, the ARM never awakens from WFI due to
|
* are set at the same time, the ARM never awakens from WFI due to
|
||||||
@ -5328,6 +5329,7 @@ static void stm32_hwinitialize(FAR struct stm32_usbdev_s *priv)
|
|||||||
regval = stm32_getreg(STM32_RCC_AHB1LPENR);
|
regval = stm32_getreg(STM32_RCC_AHB1LPENR);
|
||||||
regval &= ~RCC_AHB1ENR_OTGHSULPIEN;
|
regval &= ~RCC_AHB1ENR_OTGHSULPIEN;
|
||||||
stm32_putreg(regval, STM32_RCC_AHB1LPENR);
|
stm32_putreg(regval, STM32_RCC_AHB1LPENR);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Enable the interrupts in the INTMSK */
|
/* Enable the interrupts in the INTMSK */
|
||||||
|
|
||||||
|
@ -217,6 +217,7 @@ struct stm32_chan_s
|
|||||||
uint8_t eptype; /* See OTGHS_EPTYPE_* definitions */
|
uint8_t eptype; /* See OTGHS_EPTYPE_* definitions */
|
||||||
uint8_t funcaddr; /* Device function address */
|
uint8_t funcaddr; /* Device function address */
|
||||||
uint8_t speed; /* Device speed */
|
uint8_t speed; /* Device speed */
|
||||||
|
uint8_t interval; /* Interrupt/isochronous EP polling interval */
|
||||||
uint8_t pid; /* Data PID */
|
uint8_t pid; /* Data PID */
|
||||||
uint8_t npackets; /* Number of packets (for data toggle) */
|
uint8_t npackets; /* Number of packets (for data toggle) */
|
||||||
bool inuse; /* True: This channel is "in use" */
|
bool inuse; /* True: This channel is "in use" */
|
||||||
@ -1215,6 +1216,7 @@ static int stm32_ctrlchan_alloc(FAR struct stm32_usbhost_s *priv,
|
|||||||
chan->eptype = OTGHS_EPTYPE_CTRL;
|
chan->eptype = OTGHS_EPTYPE_CTRL;
|
||||||
chan->funcaddr = funcaddr;
|
chan->funcaddr = funcaddr;
|
||||||
chan->speed = speed;
|
chan->speed = speed;
|
||||||
|
chan->interval = 0;
|
||||||
chan->maxpacket = STM32_EP0_DEF_PACKET_SIZE;
|
chan->maxpacket = STM32_EP0_DEF_PACKET_SIZE;
|
||||||
chan->indata1 = false;
|
chan->indata1 = false;
|
||||||
chan->outdata1 = false;
|
chan->outdata1 = false;
|
||||||
@ -1239,6 +1241,7 @@ static int stm32_ctrlchan_alloc(FAR struct stm32_usbhost_s *priv,
|
|||||||
chan->eptype = OTGHS_EPTYPE_CTRL;
|
chan->eptype = OTGHS_EPTYPE_CTRL;
|
||||||
chan->funcaddr = funcaddr;
|
chan->funcaddr = funcaddr;
|
||||||
chan->speed = speed;
|
chan->speed = speed;
|
||||||
|
chan->interval = 0;
|
||||||
chan->maxpacket = STM32_EP0_DEF_PACKET_SIZE;
|
chan->maxpacket = STM32_EP0_DEF_PACKET_SIZE;
|
||||||
chan->indata1 = false;
|
chan->indata1 = false;
|
||||||
chan->outdata1 = false;
|
chan->outdata1 = false;
|
||||||
@ -1368,6 +1371,7 @@ static int stm32_xfrep_alloc(FAR struct stm32_usbhost_s *priv,
|
|||||||
chan->eptype = epdesc->xfrtype;
|
chan->eptype = epdesc->xfrtype;
|
||||||
chan->funcaddr = hport->funcaddr;
|
chan->funcaddr = hport->funcaddr;
|
||||||
chan->speed = hport->speed;
|
chan->speed = hport->speed;
|
||||||
|
chan->interval = epdesc->interval;
|
||||||
chan->maxpacket = epdesc->mxpacketsize;
|
chan->maxpacket = epdesc->mxpacketsize;
|
||||||
chan->indata1 = false;
|
chan->indata1 = false;
|
||||||
chan->outdata1 = false;
|
chan->outdata1 = false;
|
||||||
@ -1898,6 +1902,8 @@ static ssize_t stm32_in_transfer(FAR struct stm32_usbhost_s *priv, int chidx,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
useconds_t delay;
|
||||||
|
|
||||||
/* Get the elapsed time. Has the timeout elapsed?
|
/* Get the elapsed time. Has the timeout elapsed?
|
||||||
* if not then try again.
|
* if not then try again.
|
||||||
*/
|
*/
|
||||||
@ -1912,13 +1918,46 @@ static ssize_t stm32_in_transfer(FAR struct stm32_usbhost_s *priv, int chidx,
|
|||||||
return (ssize_t)ret;
|
return (ssize_t)ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait a bit before retrying after a NAK.
|
/* Wait a bit before retrying after a NAK. */
|
||||||
*
|
|
||||||
* REVISIT: This is intended to give the CPU a break from
|
|
||||||
* the tight polling loop. But are there performance issues?
|
|
||||||
*/
|
|
||||||
|
|
||||||
usleep(1000);
|
if (chan->eptype == OTGFS_HCCHAR_EPTYP_INTR)
|
||||||
|
{
|
||||||
|
/* For interrupt (and isochronous) endpoints, the
|
||||||
|
* polling rate is determined by the bInterval field
|
||||||
|
* of the endpoint descriptor (in units of frames
|
||||||
|
* which we treat as milliseconds here).
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (chan->interval > 0)
|
||||||
|
{
|
||||||
|
/* Convert the delay to units of microseconds */
|
||||||
|
|
||||||
|
delay = (useconds_t)chan->interval * 1000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Out of range! For interrupt endpoints, the valid
|
||||||
|
* range is 1-255 frames. Assume one frame.
|
||||||
|
*/
|
||||||
|
|
||||||
|
delay = 1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* For Isochronous endpoints, bInterval must be 1. Bulk
|
||||||
|
* endpoints do not have a polling interval. Rather,
|
||||||
|
* the should wait until data is received.
|
||||||
|
*
|
||||||
|
* REVISIT: For bulk endpoints this 1 msec delay is only
|
||||||
|
* intended to give the CPU a break from the bulk EP tight
|
||||||
|
* polling loop. But are there performance issues?
|
||||||
|
*/
|
||||||
|
|
||||||
|
delay = 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
usleep(delay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -5446,7 +5446,7 @@ static void stm32_hwinitialize(FAR struct stm32_usbdev_s *priv)
|
|||||||
regval &= OTG_GINT_RESERVED;
|
regval &= OTG_GINT_RESERVED;
|
||||||
stm32_putreg(regval | OTG_GINT_RC_W1, STM32_OTG_GINTSTS);
|
stm32_putreg(regval | OTG_GINT_RC_W1, STM32_OTG_GINTSTS);
|
||||||
|
|
||||||
#if defined(CONFIG_STM32F7_OTGHS)
|
#if defined(CONFIG_STM32F7_OTGHS) && !defined(BOARD_ENABLE_USBOTG_HSULPI)
|
||||||
/* Disable the ULPI Clock enable in RCC AHB1 Register. This must
|
/* Disable the ULPI Clock enable in RCC AHB1 Register. This must
|
||||||
* be done because if both the ULPI and the FS PHY clock enable bits
|
* be done because if both the ULPI and the FS PHY clock enable bits
|
||||||
* are set at the same time, the ARM never awakens from WFI due to
|
* are set at the same time, the ARM never awakens from WFI due to
|
||||||
|
@ -214,6 +214,7 @@ struct stm32_chan_s
|
|||||||
uint8_t eptype; /* See OTG_EPTYPE_* definitions */
|
uint8_t eptype; /* See OTG_EPTYPE_* definitions */
|
||||||
uint8_t funcaddr; /* Device function address */
|
uint8_t funcaddr; /* Device function address */
|
||||||
uint8_t speed; /* Device speed */
|
uint8_t speed; /* Device speed */
|
||||||
|
uint8_t interval; /* Interrupt/isochronous EP polling interval */
|
||||||
uint8_t pid; /* Data PID */
|
uint8_t pid; /* Data PID */
|
||||||
uint8_t npackets; /* Number of packets (for data toggle) */
|
uint8_t npackets; /* Number of packets (for data toggle) */
|
||||||
bool inuse; /* True: This channel is "in use" */
|
bool inuse; /* True: This channel is "in use" */
|
||||||
@ -1209,6 +1210,7 @@ static int stm32_ctrlchan_alloc(FAR struct stm32_usbhost_s *priv,
|
|||||||
chan->eptype = OTG_EPTYPE_CTRL;
|
chan->eptype = OTG_EPTYPE_CTRL;
|
||||||
chan->funcaddr = funcaddr;
|
chan->funcaddr = funcaddr;
|
||||||
chan->speed = speed;
|
chan->speed = speed;
|
||||||
|
chan->interval = 0;
|
||||||
chan->maxpacket = STM32_EP0_DEF_PACKET_SIZE;
|
chan->maxpacket = STM32_EP0_DEF_PACKET_SIZE;
|
||||||
chan->indata1 = false;
|
chan->indata1 = false;
|
||||||
chan->outdata1 = false;
|
chan->outdata1 = false;
|
||||||
@ -1233,6 +1235,7 @@ static int stm32_ctrlchan_alloc(FAR struct stm32_usbhost_s *priv,
|
|||||||
chan->eptype = OTG_EPTYPE_CTRL;
|
chan->eptype = OTG_EPTYPE_CTRL;
|
||||||
chan->funcaddr = funcaddr;
|
chan->funcaddr = funcaddr;
|
||||||
chan->speed = speed;
|
chan->speed = speed;
|
||||||
|
chan->interval = 0;
|
||||||
chan->maxpacket = STM32_EP0_DEF_PACKET_SIZE;
|
chan->maxpacket = STM32_EP0_DEF_PACKET_SIZE;
|
||||||
chan->indata1 = false;
|
chan->indata1 = false;
|
||||||
chan->outdata1 = false;
|
chan->outdata1 = false;
|
||||||
@ -1362,6 +1365,7 @@ static int stm32_xfrep_alloc(FAR struct stm32_usbhost_s *priv,
|
|||||||
chan->eptype = epdesc->xfrtype;
|
chan->eptype = epdesc->xfrtype;
|
||||||
chan->funcaddr = hport->funcaddr;
|
chan->funcaddr = hport->funcaddr;
|
||||||
chan->speed = hport->speed;
|
chan->speed = hport->speed;
|
||||||
|
chan->interval = epdesc->interval;
|
||||||
chan->maxpacket = epdesc->mxpacketsize;
|
chan->maxpacket = epdesc->mxpacketsize;
|
||||||
chan->indata1 = false;
|
chan->indata1 = false;
|
||||||
chan->outdata1 = false;
|
chan->outdata1 = false;
|
||||||
@ -1892,6 +1896,8 @@ static ssize_t stm32_in_transfer(FAR struct stm32_usbhost_s *priv, int chidx,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
useconds_t delay;
|
||||||
|
|
||||||
/* Get the elapsed time. Has the timeout elapsed?
|
/* Get the elapsed time. Has the timeout elapsed?
|
||||||
* if not then try again.
|
* if not then try again.
|
||||||
*/
|
*/
|
||||||
@ -1906,13 +1912,46 @@ static ssize_t stm32_in_transfer(FAR struct stm32_usbhost_s *priv, int chidx,
|
|||||||
return (ssize_t)ret;
|
return (ssize_t)ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait a bit before retrying after a NAK.
|
/* Wait a bit before retrying after a NAK. */
|
||||||
*
|
|
||||||
* REVISIT: This is intended to give the CPU a break from
|
|
||||||
* the tight polling loop. But are there performance issues?
|
|
||||||
*/
|
|
||||||
|
|
||||||
usleep(1000);
|
if (chan->eptype == OTGFS_HCCHAR_EPTYP_INTR)
|
||||||
|
{
|
||||||
|
/* For interrupt (and isochronous) endpoints, the
|
||||||
|
* polling rate is determined by the bInterval field
|
||||||
|
* of the endpoint descriptor (in units of frames
|
||||||
|
* which we treat as milliseconds here).
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (chan->interval > 0)
|
||||||
|
{
|
||||||
|
/* Convert the delay to units of microseconds */
|
||||||
|
|
||||||
|
delay = (useconds_t)chan->interval * 1000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Out of range! For interrupt endpoints, the valid
|
||||||
|
* range is 1-255 frames. Assume one frame.
|
||||||
|
*/
|
||||||
|
|
||||||
|
delay = 1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* For Isochronous endpoints, bInterval must be 1. Bulk
|
||||||
|
* endpoints do not have a polling interval. Rather,
|
||||||
|
* the should wait until data is received.
|
||||||
|
*
|
||||||
|
* REVISIT: For bulk endpoints this 1 msec delay is only
|
||||||
|
* intended to give the CPU a break from the bulk EP tight
|
||||||
|
* polling loop. But are there performance issues?
|
||||||
|
*/
|
||||||
|
|
||||||
|
delay = 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
usleep(delay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -213,6 +213,7 @@ struct stm32l4_chan_s
|
|||||||
uint8_t eptype; /* See OTGFS_EPTYPE_* definitions */
|
uint8_t eptype; /* See OTGFS_EPTYPE_* definitions */
|
||||||
uint8_t funcaddr; /* Device function address */
|
uint8_t funcaddr; /* Device function address */
|
||||||
uint8_t speed; /* Device speed */
|
uint8_t speed; /* Device speed */
|
||||||
|
uint8_t interval; /* Interrupt/isochronous EP polling interval */
|
||||||
uint8_t pid; /* Data PID */
|
uint8_t pid; /* Data PID */
|
||||||
uint8_t npackets; /* Number of packets (for data toggle) */
|
uint8_t npackets; /* Number of packets (for data toggle) */
|
||||||
bool inuse; /* True: This channel is "in use" */
|
bool inuse; /* True: This channel is "in use" */
|
||||||
@ -1212,6 +1213,7 @@ static int stm32l4_ctrlchan_alloc(FAR struct stm32l4_usbhost_s *priv,
|
|||||||
chan->eptype = OTGFS_EPTYPE_CTRL;
|
chan->eptype = OTGFS_EPTYPE_CTRL;
|
||||||
chan->funcaddr = funcaddr;
|
chan->funcaddr = funcaddr;
|
||||||
chan->speed = speed;
|
chan->speed = speed;
|
||||||
|
chan->interval = 0;
|
||||||
chan->maxpacket = STM32L4_EP0_DEF_PACKET_SIZE;
|
chan->maxpacket = STM32L4_EP0_DEF_PACKET_SIZE;
|
||||||
chan->indata1 = false;
|
chan->indata1 = false;
|
||||||
chan->outdata1 = false;
|
chan->outdata1 = false;
|
||||||
@ -1236,6 +1238,7 @@ static int stm32l4_ctrlchan_alloc(FAR struct stm32l4_usbhost_s *priv,
|
|||||||
chan->eptype = OTGFS_EPTYPE_CTRL;
|
chan->eptype = OTGFS_EPTYPE_CTRL;
|
||||||
chan->funcaddr = funcaddr;
|
chan->funcaddr = funcaddr;
|
||||||
chan->speed = speed;
|
chan->speed = speed;
|
||||||
|
chan->interval = 0;
|
||||||
chan->maxpacket = STM32L4_EP0_DEF_PACKET_SIZE;
|
chan->maxpacket = STM32L4_EP0_DEF_PACKET_SIZE;
|
||||||
chan->indata1 = false;
|
chan->indata1 = false;
|
||||||
chan->outdata1 = false;
|
chan->outdata1 = false;
|
||||||
@ -1365,6 +1368,7 @@ static int stm32l4_xfrep_alloc(FAR struct stm32l4_usbhost_s *priv,
|
|||||||
chan->eptype = epdesc->xfrtype;
|
chan->eptype = epdesc->xfrtype;
|
||||||
chan->funcaddr = hport->funcaddr;
|
chan->funcaddr = hport->funcaddr;
|
||||||
chan->speed = hport->speed;
|
chan->speed = hport->speed;
|
||||||
|
chan->interval = epdesc->interval;
|
||||||
chan->maxpacket = epdesc->mxpacketsize;
|
chan->maxpacket = epdesc->mxpacketsize;
|
||||||
chan->indata1 = false;
|
chan->indata1 = false;
|
||||||
chan->outdata1 = false;
|
chan->outdata1 = false;
|
||||||
@ -1897,6 +1901,8 @@ static ssize_t stm32l4_in_transfer(FAR struct stm32l4_usbhost_s *priv,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
useconds_t delay;
|
||||||
|
|
||||||
/* Get the elapsed time. Has the timeout elapsed?
|
/* Get the elapsed time. Has the timeout elapsed?
|
||||||
* if not then try again.
|
* if not then try again.
|
||||||
*/
|
*/
|
||||||
@ -1911,13 +1917,46 @@ static ssize_t stm32l4_in_transfer(FAR struct stm32l4_usbhost_s *priv,
|
|||||||
return (ssize_t)ret;
|
return (ssize_t)ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait a bit before retrying after a NAK.
|
/* Wait a bit before retrying after a NAK. */
|
||||||
*
|
|
||||||
* REVISIT: This is intended to give the CPU a break from
|
|
||||||
* the tight polling loop. But are there performance issues?
|
|
||||||
*/
|
|
||||||
|
|
||||||
usleep(1000);
|
if (chan->eptype == OTGFS_HCCHAR_EPTYP_INTR)
|
||||||
|
{
|
||||||
|
/* For interrupt (and isochronous) endpoints, the
|
||||||
|
* polling rate is determined by the bInterval field
|
||||||
|
* of the endpoint descriptor (in units of frames
|
||||||
|
* which we treat as milliseconds here).
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (chan->interval > 0)
|
||||||
|
{
|
||||||
|
/* Convert the delay to units of microseconds */
|
||||||
|
|
||||||
|
delay = (useconds_t)chan->interval * 1000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Out of range! For interrupt endpoints, the valid
|
||||||
|
* range is 1-255 frames. Assume one frame.
|
||||||
|
*/
|
||||||
|
|
||||||
|
delay = 1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* For Isochronous endpoints, bInterval must be 1. Bulk
|
||||||
|
* endpoints do not have a polling interval. Rather,
|
||||||
|
* the should wait until data is received.
|
||||||
|
*
|
||||||
|
* REVISIT: For bulk endpoints this 1 msec delay is only
|
||||||
|
* intended to give the CPU a break from the bulk EP tight
|
||||||
|
* polling loop. But are there performance issues?
|
||||||
|
*/
|
||||||
|
|
||||||
|
delay = 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
usleep(delay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -51,4 +51,8 @@ config PHOTON_WDG_THREAD_STACKSIZE
|
|||||||
endif # PHOTON_WDG_THREAD
|
endif # PHOTON_WDG_THREAD
|
||||||
endif # PHOTON_WDG
|
endif # PHOTON_WDG
|
||||||
|
|
||||||
|
config PHOTON_WLAN
|
||||||
|
bool "Enable WLAN chip support"
|
||||||
|
depends on IEEE80211_BROADCOM_FULLMAC_SDIO
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
# include <stdint.h>
|
# include <stdbool.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "stm32_rcc.h"
|
#include "stm32_rcc.h"
|
||||||
@ -171,6 +171,39 @@
|
|||||||
# define GPIO_USART1_TX GPIO_USART1_TX_1
|
# define GPIO_USART1_TX GPIO_USART1_TX_1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* SDIO definitions *****************************************************************/
|
||||||
|
|
||||||
|
/* Note that slower clocking is required when DMA is disabled in order
|
||||||
|
* to avoid RX overrun/TX underrun errors due to delayed responses
|
||||||
|
* to service FIFOs in interrupt driven mode.
|
||||||
|
*
|
||||||
|
* These values have not been tuned!!!
|
||||||
|
*
|
||||||
|
* SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(118+2)=400 KHz
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SDIO_INIT_CLKDIV (118 << SDIO_CLKCR_CLKDIV_SHIFT)
|
||||||
|
|
||||||
|
/* DMA ON: SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(1+2)=16 MHz
|
||||||
|
* DMA OFF: SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(2+2)=12 MHz
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_SDIO_DMA
|
||||||
|
# define SDIO_MMCXFR_CLKDIV (1 << SDIO_CLKCR_CLKDIV_SHIFT)
|
||||||
|
#else
|
||||||
|
# define SDIO_MMCXFR_CLKDIV (2 << SDIO_CLKCR_CLKDIV_SHIFT)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* DMA ON: SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(1+2)=16 MHz
|
||||||
|
* DMA OFF: SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(2+2)=12 MHz
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_SDIO_DMA
|
||||||
|
# define SDIO_SDXFR_CLKDIV (1 << SDIO_CLKCR_CLKDIV_SHIFT)
|
||||||
|
#else
|
||||||
|
# define SDIO_SDXFR_CLKDIV (2 << SDIO_CLKCR_CLKDIV_SHIFT)
|
||||||
|
#endif
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Public Data
|
* Public Data
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
@ -53,6 +53,10 @@ ifeq ($(CONFIG_PHOTON_WDG),y)
|
|||||||
CSRCS += stm32_wdt.c
|
CSRCS += stm32_wdt.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_PHOTON_WLAN),y)
|
||||||
|
CSRCS += stm32_wlan.c
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_STM32_OTGHS),y)
|
ifeq ($(CONFIG_STM32_OTGHS),y)
|
||||||
CSRCS += stm32_usb.c
|
CSRCS += stm32_usb.c
|
||||||
endif
|
endif
|
||||||
|
@ -61,6 +61,20 @@
|
|||||||
|
|
||||||
#define GPIO_BUTTON1 (GPIO_INPUT|GPIO_PULLUP|GPIO_EXTI|GPIO_PORTC|GPIO_PIN7)
|
#define GPIO_BUTTON1 (GPIO_INPUT|GPIO_PULLUP|GPIO_EXTI|GPIO_PORTC|GPIO_PIN7)
|
||||||
|
|
||||||
|
/* WLAN chip */
|
||||||
|
|
||||||
|
#define SDIO_WLAN0_SLOTNO 0 /* Photon board has only one sdio device */
|
||||||
|
#define SDIO_WLAN0_MINOR 0 /* Register "wlan0" device */
|
||||||
|
|
||||||
|
#define GPIO_WLAN0_RESET (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\
|
||||||
|
GPIO_OUTPUT_CLEAR|GPIO_PORTC|GPIO_PIN1)
|
||||||
|
|
||||||
|
#define GPIO_WLAN0_32K_CLK (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\
|
||||||
|
GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN1)
|
||||||
|
|
||||||
|
#define GPIO_WLAN0_OOB_INT (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|\
|
||||||
|
GPIO_PORTB|GPIO_PIN0)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Types
|
* Public Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -93,6 +107,24 @@
|
|||||||
int photon_watchdog_initialize(void);
|
int photon_watchdog_initialize(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: photon_wlan_initialize
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initialize wlan hardware and driver for Photon board.
|
||||||
|
*
|
||||||
|
* Input parameters:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero on success; a negated errno value on failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_PHOTON_WLAN
|
||||||
|
int photon_wlan_initialize(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: stm32_usbinitialize
|
* Name: stm32_usbinitialize
|
||||||
*
|
*
|
||||||
|
@ -135,5 +135,17 @@ int board_app_initialize(uintptr_t arg)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_PHOTON_WLAN
|
||||||
|
|
||||||
|
/* Initialize wlan driver and hardware */
|
||||||
|
|
||||||
|
ret = photon_wlan_initialize();
|
||||||
|
if (ret != OK)
|
||||||
|
{
|
||||||
|
syslog(LOG_ERR, "Failed to initialize wlan: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
129
configs/photon/src/stm32_wlan.c
Normal file
129
configs/photon/src/stm32_wlan.c
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* configs/photon/src/stm32_wlan.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Simon Piriou <spiriou31@gmail.com>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <arch/board/board.h>
|
||||||
|
#include <nuttx/wireless/ieee80211/bcmf_sdio.h>
|
||||||
|
#include <nuttx/wireless/ieee80211/bcmf_board.h>
|
||||||
|
#include "photon.h"
|
||||||
|
|
||||||
|
#include "stm32_gpio.h"
|
||||||
|
#include "stm32_sdio.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: bcmf_board_reset
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void bcmf_board_reset(int minor, bool reset)
|
||||||
|
{
|
||||||
|
if (minor != SDIO_WLAN0_MINOR)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
stm32_gpiowrite(GPIO_WLAN0_RESET, !reset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: bcmf_board_power
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void bcmf_board_power(int minor, bool power)
|
||||||
|
{
|
||||||
|
/* Power signal is not used on Photon board */
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: bcmf_board_initialize
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void bcmf_board_initialize(int minor)
|
||||||
|
{
|
||||||
|
if (minor != SDIO_WLAN0_MINOR)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure reset pin */
|
||||||
|
|
||||||
|
stm32_configgpio(GPIO_WLAN0_RESET);
|
||||||
|
|
||||||
|
/* Put wlan chip in reset state */
|
||||||
|
|
||||||
|
bcmf_board_reset(minor, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: photon_wlan_initialize
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int photon_wlan_initialize()
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct sdio_dev_s *sdio_dev;
|
||||||
|
|
||||||
|
/* Initialize sdio interface */
|
||||||
|
_info("Initializing SDIO slot %d\n", SDIO_WLAN0_SLOTNO);
|
||||||
|
|
||||||
|
sdio_dev = sdio_initialize(SDIO_WLAN0_SLOTNO);
|
||||||
|
|
||||||
|
if (!sdio_dev)
|
||||||
|
{
|
||||||
|
_err("ERROR: Failed to initialize SDIO with slot %d\n",
|
||||||
|
SDIO_WLAN0_SLOTNO);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bind the SDIO interface to the bcmf driver */
|
||||||
|
ret = bcmf_sdio_initialize(SDIO_WLAN0_MINOR, sdio_dev);
|
||||||
|
|
||||||
|
if (ret != OK)
|
||||||
|
{
|
||||||
|
_err("ERROR: Failed to bind SDIO to bcmf driver\n");
|
||||||
|
/* FIXME deinitialize sdio device */
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
return OK;
|
||||||
|
}
|
@ -26,6 +26,15 @@ menuconfig DRIVERS_IEEE802154
|
|||||||
|
|
||||||
source drivers/wireless/ieee802154/Kconfig
|
source drivers/wireless/ieee802154/Kconfig
|
||||||
|
|
||||||
|
menuconfig DRIVERS_IEEE80211
|
||||||
|
bool "IEEE 802.11 Device Support"
|
||||||
|
default n
|
||||||
|
depends on EXPERIMENTAL
|
||||||
|
---help---
|
||||||
|
This directory holds implementations of IEEE802.11 device drivers.
|
||||||
|
|
||||||
|
source drivers/wireless/ieee80211/Kconfig
|
||||||
|
|
||||||
config WL_NRF24L01
|
config WL_NRF24L01
|
||||||
bool "nRF24l01+ transceiver support"
|
bool "nRF24l01+ transceiver support"
|
||||||
default n
|
default n
|
||||||
|
@ -41,6 +41,12 @@ ifeq ($(CONFIG_DRIVERS_IEEE802154),y)
|
|||||||
include wireless$(DELIM)ieee802154$(DELIM)Make.defs
|
include wireless$(DELIM)ieee802154$(DELIM)Make.defs
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Include IEEE 802.11 support
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_DRIVERS_IEEE80211),y)
|
||||||
|
include wireless$(DELIM)ieee80211$(DELIM)Make.defs
|
||||||
|
endif
|
||||||
|
|
||||||
# Include wireless drivers
|
# Include wireless drivers
|
||||||
|
|
||||||
ifeq ($(CONFIG_WL_CC1101),y)
|
ifeq ($(CONFIG_WL_CC1101),y)
|
||||||
|
20
drivers/wireless/ieee80211/Kconfig
Normal file
20
drivers/wireless/ieee80211/Kconfig
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#
|
||||||
|
# For a description of the syntax of this configuration file,
|
||||||
|
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||||
|
#
|
||||||
|
|
||||||
|
if DRIVERS_IEEE80211
|
||||||
|
|
||||||
|
config IEEE80211_BROADCOM_FULLMAC
|
||||||
|
bool
|
||||||
|
|
||||||
|
config IEEE80211_BROADCOM_FULLMAC_SDIO
|
||||||
|
bool "Broadcom FullMAC driver on SDIO bus"
|
||||||
|
depends on ARCH_HAVE_SDIO
|
||||||
|
select IEEE80211_BROADCOM_FULLMAC
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
This selection enables support for broadcom
|
||||||
|
FullMAC-compliant devices using SDIO bus.
|
||||||
|
|
||||||
|
endif # DRIVERS_IEEE80211
|
53
drivers/wireless/ieee80211/Make.defs
Normal file
53
drivers/wireless/ieee80211/Make.defs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
############################################################################
|
||||||
|
# drivers/wireless/ieee80211/Make.defs
|
||||||
|
#
|
||||||
|
# Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions
|
||||||
|
# are met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in
|
||||||
|
# the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
# 3. Neither the name NuttX nor the names of its contributors may be
|
||||||
|
# used to endorse or promote products derived from this software
|
||||||
|
# without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
# Include nothing if IEEE 802.11 is disabled
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_DRIVERS_IEEE80211),y)
|
||||||
|
|
||||||
|
# Include common IEEE 802.11 files into the build
|
||||||
|
|
||||||
|
# Include IEEE 802.11 drivers into the build
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_IEEE80211_BROADCOM_FULLMAC_SDIO),y)
|
||||||
|
CSRCS += bcmf_sdio.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Include IEEE 802.11 build support
|
||||||
|
|
||||||
|
DEPPATH += --dep-path wireless$(DELIM)ieee80211
|
||||||
|
VPATH += :wireless$(DELIM)ieee80211
|
||||||
|
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)wireless$(DELIM)ieee80211}
|
||||||
|
|
||||||
|
endif # CONFIG_DRIVERS_IEEE80211
|
271
drivers/wireless/ieee80211/bcmf_sdio.c
Normal file
271
drivers/wireless/ieee80211/bcmf_sdio.c
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* drivers/wireless/ieee80211/bcmf_sdio.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Simon Piriou <spiriou31@gmail.com>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include <nuttx/compiler.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <debug.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <nuttx/kmalloc.h>
|
||||||
|
#include <nuttx/sdio.h>
|
||||||
|
#include <nuttx/arch.h>
|
||||||
|
|
||||||
|
#include <nuttx/wireless/ieee80211/bcmf_sdio.h>
|
||||||
|
#include <nuttx/wireless/ieee80211/bcmf_board.h>
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define BCMF_DEVICE_RESET_DELAY_MS 10
|
||||||
|
#define BCMF_DEVICE_START_DELAY_MS 10
|
||||||
|
#define BCMF_DEVICE_IDLE_DELAY_MS 50
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* This structure is contains the unique state of the Broadcom FullMAC driver */
|
||||||
|
|
||||||
|
struct bcmf_dev_s
|
||||||
|
{
|
||||||
|
FAR struct sdio_dev_s *sdio_dev; /* The SDIO device bound to this instance */
|
||||||
|
int minor; /* Device minor number */
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int bcmf_sendcmdpoll(FAR struct bcmf_dev_s *priv,
|
||||||
|
uint32_t cmd, uint32_t arg);
|
||||||
|
|
||||||
|
static int bcmf_probe(FAR struct bcmf_dev_s *priv);
|
||||||
|
static int bcmf_hwinitialize(FAR struct bcmf_dev_s *priv);
|
||||||
|
static void bcmf_hwuninitialize(FAR struct bcmf_dev_s *priv);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: bcmf_sendcmdpoll
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int bcmf_sendcmdpoll(FAR struct bcmf_dev_s *priv, uint32_t cmd, uint32_t arg)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Send the command */
|
||||||
|
|
||||||
|
ret = SDIO_SENDCMD(priv->sdio_dev, cmd, arg);
|
||||||
|
if (ret == OK)
|
||||||
|
{
|
||||||
|
/* Then poll-wait until the response is available */
|
||||||
|
|
||||||
|
ret = SDIO_WAITRESPONSE(priv->sdio_dev, cmd);
|
||||||
|
if (ret != OK)
|
||||||
|
{
|
||||||
|
_err("ERROR: Wait for response to cmd: %08x failed: %d\n",
|
||||||
|
cmd, ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: bcmf_probe
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int bcmf_probe(FAR struct bcmf_dev_s *priv)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
uint32_t data = 0;
|
||||||
|
|
||||||
|
/* Set device state from reset to idle */
|
||||||
|
|
||||||
|
bcmf_sendcmdpoll(priv, MMCSD_CMD0, 0);
|
||||||
|
up_mdelay(BCMF_DEVICE_START_DELAY_MS);
|
||||||
|
|
||||||
|
/* Send IO_SEND_OP_COND command */
|
||||||
|
|
||||||
|
ret = bcmf_sendcmdpoll(priv, SDIO_CMD5, 0);
|
||||||
|
|
||||||
|
if (ret != OK)
|
||||||
|
{
|
||||||
|
goto exit_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Receive R4 response */
|
||||||
|
|
||||||
|
ret = SDIO_RECVR4(priv->sdio_dev, SDIO_CMD5, &data);
|
||||||
|
|
||||||
|
if (ret != OK)
|
||||||
|
{
|
||||||
|
goto exit_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Broadcom chips have 2 additional functions and wide voltage range */
|
||||||
|
|
||||||
|
if ((((data >> 28) & 7) != 2) ||
|
||||||
|
(((data >> 8) & 0xff80) != 0xff80))
|
||||||
|
{
|
||||||
|
goto exit_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
exit_error:
|
||||||
|
|
||||||
|
_err("ERROR: failed to probe device %d\n", priv->minor);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: bcmf_hwinitialize
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int bcmf_hwinitialize(FAR struct bcmf_dev_s *priv)
|
||||||
|
{
|
||||||
|
/* Attach and prepare SDIO interrupts */
|
||||||
|
|
||||||
|
SDIO_ATTACH(priv->sdio_dev);
|
||||||
|
|
||||||
|
/* Set ID mode clocking (<400KHz) */
|
||||||
|
|
||||||
|
SDIO_CLOCK(priv->sdio_dev, CLOCK_IDMODE);
|
||||||
|
|
||||||
|
/* Configure hardware */
|
||||||
|
|
||||||
|
bcmf_board_initialize(priv->minor);
|
||||||
|
|
||||||
|
/* Reset and power device */
|
||||||
|
|
||||||
|
bcmf_board_reset(priv->minor, true);
|
||||||
|
bcmf_board_power(priv->minor, true);
|
||||||
|
up_mdelay(BCMF_DEVICE_RESET_DELAY_MS);
|
||||||
|
bcmf_board_reset(priv->minor, false);
|
||||||
|
|
||||||
|
/* Wait for device to start */
|
||||||
|
|
||||||
|
up_mdelay(BCMF_DEVICE_START_DELAY_MS);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: bcmf_hwuninitialize
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void bcmf_hwuninitialize(FAR struct bcmf_dev_s *priv)
|
||||||
|
{
|
||||||
|
/* Shutdown device */
|
||||||
|
|
||||||
|
bcmf_board_power(priv->minor, false);
|
||||||
|
bcmf_board_reset(priv->minor, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: bcmf_sdio_initialize
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int bcmf_sdio_initialize(int minor, FAR struct sdio_dev_s *dev)
|
||||||
|
{
|
||||||
|
FAR struct bcmf_dev_s *priv;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
_info("minor: %d\n", minor);
|
||||||
|
|
||||||
|
/* Allocate a bcmf device structure */
|
||||||
|
|
||||||
|
priv = (FAR struct bcmf_dev_s *)kmm_malloc(sizeof(*priv));
|
||||||
|
|
||||||
|
if (!priv)
|
||||||
|
{
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize bcmf device structure */
|
||||||
|
|
||||||
|
memset(priv, 0, sizeof(*priv));
|
||||||
|
priv->sdio_dev = dev;
|
||||||
|
priv->minor = minor;
|
||||||
|
|
||||||
|
/* Initialize device hardware */
|
||||||
|
|
||||||
|
ret = bcmf_hwinitialize(priv);
|
||||||
|
|
||||||
|
if (ret != OK)
|
||||||
|
{
|
||||||
|
goto exit_free_priv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Probe device */
|
||||||
|
|
||||||
|
ret = bcmf_probe(priv);
|
||||||
|
|
||||||
|
if (ret != OK)
|
||||||
|
{
|
||||||
|
goto exit_uninit_hw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO Create a wlan device name and register network driver here */
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
exit_uninit_hw:
|
||||||
|
bcmf_hwuninitialize(priv);
|
||||||
|
|
||||||
|
exit_free_priv:
|
||||||
|
kmm_free(priv);
|
||||||
|
return ret;
|
||||||
|
}
|
110
include/nuttx/wireless/ieee80211/bcmf_board.h
Normal file
110
include/nuttx/wireless/ieee80211/bcmf_board.h
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* include/nuttx/wireless/ieee80211/bcmf_board.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Simon Piriou <spiriou31@gmail.com>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __INCLUDE_NUTTX_WIRELESS_IEEE80211_BCMF_BOARD_H
|
||||||
|
#define __INCLUDE_NUTTX_WIRELESS_IEEE80211_BCMF_BOARD_H
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define EXTERN extern "C"
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#else
|
||||||
|
#define EXTERN extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/************************************************************************************
|
||||||
|
* Function: bcmf_board_initialize
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Board specific function called from Broadcom FullMAC driver
|
||||||
|
* that must be implemented to configure WLAN chip GPIOs
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* minor - zero based minor device number which is unique
|
||||||
|
* for each wlan device.
|
||||||
|
************************************************************************************/
|
||||||
|
|
||||||
|
void bcmf_board_initialize(int minor);
|
||||||
|
|
||||||
|
/************************************************************************************
|
||||||
|
* Function: bcmf_board_power
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Board specific function called from Broadcom FullMAC driver
|
||||||
|
* that must be implemented to power WLAN chip
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* minor - zero based minor device number which is unique
|
||||||
|
* for each wlan device.
|
||||||
|
* power - true to power WLAN chip else false
|
||||||
|
************************************************************************************/
|
||||||
|
|
||||||
|
void bcmf_board_power(int minor, bool power);
|
||||||
|
|
||||||
|
/************************************************************************************
|
||||||
|
* Function: bcmf_board_reset
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Board specific function called from Broadcom FullMAC driver
|
||||||
|
* that must be implemented to reset WLAN chip
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* minor - zero based minor device number which is unique
|
||||||
|
* for each wlan device.
|
||||||
|
* reset - true to set WLAN chip in reset state else false
|
||||||
|
************************************************************************************/
|
||||||
|
|
||||||
|
void bcmf_board_reset(int minor, bool reset);
|
||||||
|
|
||||||
|
#undef EXTERN
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __INCLUDE_NUTTX_WIRELESS_IEEE80211_BCMF_BOARD_H */
|
86
include/nuttx/wireless/ieee80211/bcmf_sdio.h
Normal file
86
include/nuttx/wireless/ieee80211/bcmf_sdio.h
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* include/nuttx/wireless/ieee80211/bcmf_sdio.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Simon Piriou <spiriou31@gmail.com>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __INCLUDE_NUTTX_WIRELESS_IEEE80211_BCMF_SDIO_H
|
||||||
|
#define __INCLUDE_NUTTX_WIRELESS_IEEE80211_BCMF_SDIO_H
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/mmcsd.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define EXTERN extern "C"
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#else
|
||||||
|
#define EXTERN extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: bcmf_sdio_initialize
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initialize Broadcom FullMAC driver.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* minor - zero based minor device number which is unique
|
||||||
|
* for each wlan device.
|
||||||
|
* dev - SDIO device used to communicate with the wlan chip
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* OK on success; Negated errno on failure.
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int bcmf_sdio_initialize(int minor, FAR struct sdio_dev_s *dev);
|
||||||
|
|
||||||
|
#undef EXTERN
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __INCLUDE_NUTTX_WIRELESS_IEEE80211_BCMF_SDIO_H */
|
Loading…
Reference in New Issue
Block a user