mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-31 05:41:42 +08:00
Fix ENC28J60 Tx transmit (still a receive problem); Add HTTP 408 logic from Kate
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5158 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
+4
-3
@@ -332,6 +332,7 @@
|
|||||||
* apps/netutils/uip_listenon.c: Logic in uip_server.c that creates
|
* apps/netutils/uip_listenon.c: Logic in uip_server.c that creates
|
||||||
the listening socket was moved to this new file to support re-use.
|
the listening socket was moved to this new file to support re-use.
|
||||||
Contributed by Kate.
|
Contributed by Kate.
|
||||||
* apps/netutils/webserver/httpd.c: The option CONFIG_NETUTILS_HTTPD_SINGLETHREAD
|
* apps/netutils/webserver/httpd.c: The option CONFIG_NETUTILS_HTTPD_SINGLECONNECT
|
||||||
can now be used to limit the server to a single thread. From Kate.
|
can now be used to limit the server to a single thread. Option
|
||||||
|
CONFIG_NETUTILS_HTTPD_TIMEOUT can be used to generate HTTP 408 errors.
|
||||||
|
Both from Kate.
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ config NETUTILS_WEBSERVER
|
|||||||
|
|
||||||
if NETUTILS_WEBSERVER
|
if NETUTILS_WEBSERVER
|
||||||
|
|
||||||
config NETUTILS_HTTPD_SINGLETHREAD
|
config NETUTILS_HTTPD_SINGLECONNECT
|
||||||
bool "Single Threded"
|
bool "Single Connection"
|
||||||
default n if !DISABLE_PTHREAD
|
default n if !DISABLE_PTHREAD
|
||||||
default y if DISABLE_PTHREAD
|
default y if DISABLE_PTHREAD
|
||||||
---help---
|
---help---
|
||||||
@@ -22,8 +22,8 @@ config NETUTILS_HTTPD_SINGLETHREAD
|
|||||||
for each connection. This can, however, use a lot of stack space
|
for each connection. This can, however, use a lot of stack space
|
||||||
if there are many connections and that can be a problem is RAM is
|
if there are many connections and that can be a problem is RAM is
|
||||||
limited. If this option is selected, then a single thread will
|
limited. If this option is selected, then a single thread will
|
||||||
service all HTTP requests. TCP_BACKLOG would be a good idea
|
service all HTTP requests and, in this case, only a single connection
|
||||||
in this case.
|
at a time is supported at a time.
|
||||||
|
|
||||||
config NETUTILS_HTTPD_SCRIPT_DISABLE
|
config NETUTILS_HTTPD_SCRIPT_DISABLE
|
||||||
bool "Disable %! scripting"
|
bool "Disable %! scripting"
|
||||||
@@ -65,6 +65,14 @@ config NETUTILS_HTTPD_SERVERHEADER_DISABLE
|
|||||||
---help---
|
---help---
|
||||||
This option, if selected, will elide the Server\: header
|
This option, if selected, will elide the Server\: header
|
||||||
|
|
||||||
|
config NETUTILS_HTTPD_TIMEOUT
|
||||||
|
int "Receive Timeout (sec)"
|
||||||
|
default 0
|
||||||
|
---help---
|
||||||
|
Receive timeout setting (in seconds). A timeout value of zero
|
||||||
|
disables the timeout. An HTTP 408 error is generated if the timeout
|
||||||
|
expires.
|
||||||
|
|
||||||
choice
|
choice
|
||||||
prompt "File Transfer Method"
|
prompt "File Transfer Method"
|
||||||
default NETUTILS_HTTPD_CLASSIC
|
default NETUTILS_HTTPD_CLASSIC
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
#ifndef CONFIG_NETUTILS_HTTPD_SINGLETHREAD
|
#ifndef CONFIG_NETUTILS_HTTPD_SINGLECONNECT
|
||||||
# include <pthread.h>
|
# include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -92,6 +92,14 @@
|
|||||||
# define CONFIG_NETUTILS_HTTPD_PATH "/mnt"
|
# define CONFIG_NETUTILS_HTTPD_PATH "/mnt"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* The correct way to disable receive timeout errors is by setting the
|
||||||
|
* timeout to zero.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONFIG_NETUTILS_HTTPD_TIMEOUT
|
||||||
|
# define CONFIG_NETUTILS_HTTPD_TIMEOUT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -116,6 +124,9 @@ static const char g_httpextensionjpg[] = ".jpg";
|
|||||||
static const char g_httpextensionjs[] = ".js";
|
static const char g_httpextensionjs[] = ".js";
|
||||||
|
|
||||||
static const char g_http404path[] = "/404.html";
|
static const char g_http404path[] = "/404.html";
|
||||||
|
#if CONFIG_NETUTILS_HTTPD_TIMEOUT > 0
|
||||||
|
static const char g_http408path[] = "/408.html";
|
||||||
|
#endif
|
||||||
#ifndef CONFIG_NETUTILS_HTTPD_SCRIPT_DISABLE
|
#ifndef CONFIG_NETUTILS_HTTPD_SCRIPT_DISABLE
|
||||||
static const char g_httpindexpath[] = "/index.shtml";
|
static const char g_httpindexpath[] = "/index.shtml";
|
||||||
#else
|
#else
|
||||||
@@ -138,6 +149,15 @@ static const char g_httpheader404[] =
|
|||||||
#endif
|
#endif
|
||||||
"Connection: close\r\n";
|
"Connection: close\r\n";
|
||||||
|
|
||||||
|
#if CONFIG_NETUTILS_HTTPD_TIMEOUT > 0
|
||||||
|
static const char g_httpheader408[] =
|
||||||
|
"HTTP/1.0 408 Request timed out\r\n"
|
||||||
|
#ifndef CONFIG_NETUTILS_HTTPD_SERVERHEADER_DISABLE
|
||||||
|
"Server: uIP/1.0 http://www.sics.se/~adam/uip/\r\n"
|
||||||
|
#endif
|
||||||
|
"Connection: close\r\n";
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -507,6 +527,28 @@ static inline int httpd_cmd(struct httpd_state *pstate)
|
|||||||
/* Get the next HTTP command. We will handle only GET */
|
/* Get the next HTTP command. We will handle only GET */
|
||||||
|
|
||||||
recvlen = recv(pstate->ht_sockfd, pstate->ht_buffer, HTTPD_IOBUFFER_SIZE, 0);
|
recvlen = recv(pstate->ht_sockfd, pstate->ht_buffer, HTTPD_IOBUFFER_SIZE, 0);
|
||||||
|
#if CONFIG_NETUTILS_HTTPD_TIMEOUT > 0
|
||||||
|
if (recvlen < 0 && errno == EWOULDBLOCK)
|
||||||
|
{
|
||||||
|
ndbg("[%d] recv timeout\n");
|
||||||
|
strncpy(pstate->ht_filename, g_httpindexpath, strlen(g_httpindexpath));
|
||||||
|
|
||||||
|
memcpy(pstate->ht_filename, g_http408path, strlen(g_http408path));
|
||||||
|
if (httpd_open(g_http408path, &pstate->ht_file) != OK)
|
||||||
|
{
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (send_headers(pstate, g_httpheader408, strlen(g_httpheader408)) == OK)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_NETUTILS_HTTPD_SENDFILE
|
||||||
|
return httpd_sendfile_send(pstate->ht_sockfd, &pstate->ht_file);
|
||||||
|
#else
|
||||||
|
return httpd_addchunk(pstate, pstate->ht_file.data, pstate->ht_file.len);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (recvlen < 0)
|
if (recvlen < 0)
|
||||||
{
|
{
|
||||||
ndbg("[%d] recv failed: %d\n", pstate->ht_sockfd, errno);
|
ndbg("[%d] recv failed: %d\n", pstate->ht_sockfd, errno);
|
||||||
@@ -598,7 +640,7 @@ static void *httpd_handler(void *arg)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_NETUTILS_HTTPD_SINGLETHREAD
|
#ifdef CONFIG_NETUTILS_HTTPD_SINGLECONNECT
|
||||||
static void single_server(uint16_t portno, pthread_startroutine_t handler, int stacksize)
|
static void single_server(uint16_t portno, pthread_startroutine_t handler, int stacksize)
|
||||||
{
|
{
|
||||||
struct sockaddr_in myaddr;
|
struct sockaddr_in myaddr;
|
||||||
@@ -608,11 +650,14 @@ static void single_server(uint16_t portno, pthread_startroutine_t handler, int s
|
|||||||
#ifdef CONFIG_NET_HAVE_SOLINGER
|
#ifdef CONFIG_NET_HAVE_SOLINGER
|
||||||
struct linger ling;
|
struct linger ling;
|
||||||
#endif
|
#endif
|
||||||
|
#if CONFIG_NETUTILS_HTTPD_TIMEOUT > 0
|
||||||
|
struct timeval tv;
|
||||||
|
#endif
|
||||||
|
|
||||||
listensd = uip_listenon(portno);
|
listensd = uip_listenon(portno);
|
||||||
if (listensd < 0)
|
if (listensd < 0)
|
||||||
{
|
{
|
||||||
return ERROR;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Begin serving connections */
|
/* Begin serving connections */
|
||||||
@@ -643,12 +688,25 @@ static void single_server(uint16_t portno, pthread_startroutine_t handler, int s
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_NETUTILS_HTTPD_TIMEOUT > 0
|
||||||
|
/* Set up a receive timeout */
|
||||||
|
|
||||||
|
tv.tv_sec = CONFIG_NETUTILS_HTTPD_TIMEOUT;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
if (setsockopt(acceptsd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval)) < 0)
|
||||||
|
{
|
||||||
|
close(acceptsd);
|
||||||
|
ndbg("setsockopt SO_RCVTIMEO failure: %d\n", errno);
|
||||||
|
break;;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Handle the request. This blocks until complete. */
|
/* Handle the request. This blocks until complete. */
|
||||||
|
|
||||||
(void) httpd_handler((void*)acceptsd);
|
(void) httpd_handler((void*)acceptsd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -668,7 +726,7 @@ int httpd_listen(void)
|
|||||||
{
|
{
|
||||||
/* Execute httpd_handler on each connection to port 80 */
|
/* Execute httpd_handler on each connection to port 80 */
|
||||||
|
|
||||||
#ifdef CONFIG_NETUTILS_HTTPD_SINGLETHREAD
|
#ifdef CONFIG_NETUTILS_HTTPD_SINGLECONNECT
|
||||||
single_server(HTONS(80), httpd_handler, CONFIG_NETUTILS_HTTPDSTACKSIZE);
|
single_server(HTONS(80), httpd_handler, CONFIG_NETUTILS_HTTPDSTACKSIZE);
|
||||||
#else
|
#else
|
||||||
uip_server(HTONS(80), httpd_handler, CONFIG_NETUTILS_HTTPDSTACKSIZE);
|
uip_server(HTONS(80), httpd_handler, CONFIG_NETUTILS_HTTPDSTACKSIZE);
|
||||||
|
|||||||
@@ -116,8 +116,10 @@
|
|||||||
|
|
||||||
/* Interrupt wait time timeout in system timer ticks */
|
/* Interrupt wait time timeout in system timer ticks */
|
||||||
|
|
||||||
#define CONFIG_STM32_I2CTIMEOTICKS \
|
#ifndef CONFIG_STM32_I2CTIMEOTICKS
|
||||||
(SEC2TICK(CONFIG_STM32_I2CTIMEOSEC) + MSEC2TICK(CONFIG_STM32_I2CTIMEOMS))
|
# define CONFIG_STM32_I2CTIMEOTICKS \
|
||||||
|
(SEC2TICK(CONFIG_STM32_I2CTIMEOSEC) + MSEC2TICK(CONFIG_STM32_I2CTIMEOMS))
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_STM32_I2C_DYNTIMEO_STARTSTOP
|
#ifndef CONFIG_STM32_I2C_DYNTIMEO_STARTSTOP
|
||||||
# define CONFIG_STM32_I2C_DYNTIMEO_STARTSTOP TICK2USEC(CONFIG_STM32_I2CTIMEOTICKS)
|
# define CONFIG_STM32_I2C_DYNTIMEO_STARTSTOP TICK2USEC(CONFIG_STM32_I2CTIMEOTICKS)
|
||||||
|
|||||||
@@ -70,6 +70,13 @@ config ENC28J60_DUMPPACKET
|
|||||||
If selected, the ENC28J60 driver will dump the contents of each
|
If selected, the ENC28J60 driver will dump the contents of each
|
||||||
packet to the console.
|
packet to the console.
|
||||||
|
|
||||||
|
config ENC28J60_REGDEBUG
|
||||||
|
bool "Register-Level Debug"
|
||||||
|
default n
|
||||||
|
depends on DEBUG && DEBUG_NET
|
||||||
|
---help---
|
||||||
|
Enable very low-level register access debug. Depends on DEBUG and DEBUG_NET.
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
config NET_E1000
|
config NET_E1000
|
||||||
|
|||||||
@@ -128,6 +128,12 @@
|
|||||||
# warrning "CONFIG_NET_NOINTS should be set"
|
# warrning "CONFIG_NET_NOINTS should be set"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Low-level register debug */
|
||||||
|
|
||||||
|
#if !defined(CONFIG_DEBUG) || !defined(CONFIG_DEBUG_NET)
|
||||||
|
# undef CONFIG_ENC28J60_REGDEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Timing *******************************************************************/
|
/* Timing *******************************************************************/
|
||||||
|
|
||||||
/* TX poll deley = 1 seconds. CLK_TCK is the number of clock ticks per second */
|
/* TX poll deley = 1 seconds. CLK_TCK is the number of clock ticks per second */
|
||||||
@@ -169,6 +175,20 @@
|
|||||||
|
|
||||||
#define BUF ((struct uip_eth_hdr *)priv->dev.d_buf)
|
#define BUF ((struct uip_eth_hdr *)priv->dev.d_buf)
|
||||||
|
|
||||||
|
/* Debug ********************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_ENC28J60_REGDEBUG
|
||||||
|
# define enc_wrdump(a,v) lib_lowprintf("ENC28J60: %02x<-%02x\n", a, v);
|
||||||
|
# define enc_rddump(a,v) lib_lowprintf("ENC28J60: %02x->%02x\n", a, v);
|
||||||
|
# define enc_cmddump(c) lib_lowprintf("ENC28J60: CMD: %02x\n", c);
|
||||||
|
# define enc_bmdump(c,b,s) lib_lowprintf("ENC28J60: CMD: %02x buffer: %p length: %d\n", c,b,s);
|
||||||
|
#else
|
||||||
|
# define enc_wrdump(a,v)
|
||||||
|
# define enc_rddump(a,v)
|
||||||
|
# define enc_cmddump(c)
|
||||||
|
# define enc_bmdump(c,b,s)
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -264,7 +284,7 @@ static int enc_waitbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg,
|
|||||||
|
|
||||||
static void enc_rdbuffer(FAR struct enc_driver_s *priv, FAR uint8_t *buffer,
|
static void enc_rdbuffer(FAR struct enc_driver_s *priv, FAR uint8_t *buffer,
|
||||||
size_t buflen);
|
size_t buflen);
|
||||||
static void enc_wrbuffer(FAR struct enc_driver_s *priv,
|
static inline void enc_wrbuffer(FAR struct enc_driver_s *priv,
|
||||||
FAR const uint8_t *buffer, size_t buflen);
|
FAR const uint8_t *buffer, size_t buflen);
|
||||||
|
|
||||||
/* PHY register access */
|
/* PHY register access */
|
||||||
@@ -498,6 +518,8 @@ static uint8_t enc_rdgreg2(FAR struct enc_driver_s *priv, uint8_t cmd)
|
|||||||
/* De-select ENC28J60 chip */
|
/* De-select ENC28J60 chip */
|
||||||
|
|
||||||
enc_deselect(priv);
|
enc_deselect(priv);
|
||||||
|
|
||||||
|
enc_rddump(cmd, rddata);
|
||||||
return rddata;
|
return rddata;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -539,6 +561,7 @@ static void enc_wrgreg2(FAR struct enc_driver_s *priv, uint8_t cmd,
|
|||||||
/* De-select ENC28J60 chip. */
|
/* De-select ENC28J60 chip. */
|
||||||
|
|
||||||
enc_deselect(priv);
|
enc_deselect(priv);
|
||||||
|
enc_wrdump(cmd, wrdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -592,6 +615,7 @@ static inline void enc_src(FAR struct enc_driver_s *priv)
|
|||||||
/* De-select ENC28J60 chip. */
|
/* De-select ENC28J60 chip. */
|
||||||
|
|
||||||
enc_deselect(priv);
|
enc_deselect(priv);
|
||||||
|
enc_cmddump(ENC_SRC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -688,6 +712,7 @@ static uint8_t enc_rdbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg)
|
|||||||
/* De-select ENC28J60 chip */
|
/* De-select ENC28J60 chip */
|
||||||
|
|
||||||
enc_deselect(priv);
|
enc_deselect(priv);
|
||||||
|
enc_rddump(ENC_RCR | GETADDR(ctrlreg), rddata);
|
||||||
return rddata;
|
return rddata;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -734,6 +759,7 @@ static void enc_wrbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg,
|
|||||||
/* De-select ENC28J60 chip. */
|
/* De-select ENC28J60 chip. */
|
||||||
|
|
||||||
enc_deselect(priv);
|
enc_deselect(priv);
|
||||||
|
enc_wrdump(ENC_WCR | GETADDR(ctrlreg), wrdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -816,6 +842,7 @@ static void enc_rdbuffer(FAR struct enc_driver_s *priv, FAR uint8_t *buffer,
|
|||||||
/* De-select ENC28J60 chip. */
|
/* De-select ENC28J60 chip. */
|
||||||
|
|
||||||
enc_deselect(priv);
|
enc_deselect(priv);
|
||||||
|
enc_bmdump(ENC_WBM, buffer, buflen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -837,26 +864,68 @@ static void enc_rdbuffer(FAR struct enc_driver_s *priv, FAR uint8_t *buffer,
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void enc_wrbuffer(FAR struct enc_driver_s *priv,
|
static inline void enc_wrbuffer(FAR struct enc_driver_s *priv,
|
||||||
FAR const uint8_t *buffer, size_t buflen)
|
FAR const uint8_t *buffer, size_t buflen)
|
||||||
{
|
{
|
||||||
DEBUGASSERT(priv && priv->spi);
|
DEBUGASSERT(priv && priv->spi);
|
||||||
|
|
||||||
/* Select ENC28J60 chip */
|
/* Select ENC28J60 chip
|
||||||
|
*
|
||||||
|
* "The WBM command is started by lowering the CS pin. ..."
|
||||||
|
*/
|
||||||
|
|
||||||
enc_select(priv);
|
enc_select(priv);
|
||||||
|
|
||||||
/* Send the write buffer memory command (ignoring the response) */
|
/* Send the write buffer memory command (ignoring the response)
|
||||||
|
*
|
||||||
|
* "...The [3-bit]WBM opcode should then be sent to the ENC28J60,
|
||||||
|
* followed by the 5-bit constant, 1Ah."
|
||||||
|
*/
|
||||||
|
|
||||||
(void)SPI_SEND(priv->spi, ENC_WBM);
|
(void)SPI_SEND(priv->spi, ENC_WBM);
|
||||||
|
|
||||||
/* Then send the buffer */
|
/* "...the ENC28J60 requires a single per packet control byte to
|
||||||
|
* precede the packet for transmission."
|
||||||
|
*
|
||||||
|
* POVERRIDE: Per Packet Override bit (Not set):
|
||||||
|
* 1 = The values of PCRCEN, PPADEN and PHUGEEN will override the
|
||||||
|
* configuration defined by MACON3.
|
||||||
|
* 0 = The values in MACON3 will be used to determine how the packet
|
||||||
|
* will be transmitted
|
||||||
|
* PCRCEN: Per Packet CRC Enable bit (Set, but won't be used because
|
||||||
|
* POVERRIDE is zero).
|
||||||
|
* PPADEN: Per Packet Padding Enable bit (Set, but won't be used because
|
||||||
|
* POVERRIDE is zero).
|
||||||
|
* PHUGEEN: Per Packet Huge Frame Enable bit (Set, but won't be used
|
||||||
|
* because POVERRIDE is zero).
|
||||||
|
*/
|
||||||
|
|
||||||
|
(void)SPI_SEND(priv->spi,
|
||||||
|
(PKTCTRL_PCRCEN | PKTCTRL_PPADEN | PKTCTRL_PHUGEEN));
|
||||||
|
|
||||||
|
/* Then send the buffer
|
||||||
|
*
|
||||||
|
* "... After the WBM command and constant are sent, the data to
|
||||||
|
* be stored in the memory pointed to by EWRPT should be shifted
|
||||||
|
* out MSb first to the ENC28J60. After 8 data bits are received,
|
||||||
|
* the Write Pointer will automatically increment if AUTOINC is
|
||||||
|
* set. The host controller can continue to provide clocks on the
|
||||||
|
* SCK pin and send data on the SI pin, without raising CS, to
|
||||||
|
* keep writing to the memory. In this manner, with AUTOINC
|
||||||
|
* enabled, it is possible to continuously write sequential bytes
|
||||||
|
* to the buffer memory without any extra SPI command
|
||||||
|
* overhead.
|
||||||
|
*/
|
||||||
|
|
||||||
SPI_SNDBLOCK(priv->spi, buffer, buflen);
|
SPI_SNDBLOCK(priv->spi, buffer, buflen);
|
||||||
|
|
||||||
/* De-select ENC28J60 chip. */
|
/* De-select ENC28J60 chip
|
||||||
|
*
|
||||||
|
* "The WBM command is terminated by bringing up the CS pin. ..."
|
||||||
|
*/
|
||||||
|
|
||||||
enc_deselect(priv);
|
enc_deselect(priv);
|
||||||
|
enc_bmdump(ENC_WBM, buffer, buflen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -984,6 +1053,11 @@ static int enc_transmit(FAR struct enc_driver_s *priv)
|
|||||||
|
|
||||||
enc_dumppacket("Transmit Packet", priv->dev.d_buf, priv->dev.d_len);
|
enc_dumppacket("Transmit Packet", priv->dev.d_buf, priv->dev.d_len);
|
||||||
|
|
||||||
|
/* Set transmit buffer start (is this necessary?). */
|
||||||
|
|
||||||
|
enc_wrbreg(priv, ENC_ETXSTL, PKTMEM_TX_START & 0xff);
|
||||||
|
enc_wrbreg(priv, ENC_ETXSTH, PKTMEM_TX_START >> 8);
|
||||||
|
|
||||||
/* Reset the write pointer to start of transmit buffer */
|
/* Reset the write pointer to start of transmit buffer */
|
||||||
|
|
||||||
enc_wrbreg(priv, ENC_EWRPTL, PKTMEM_TX_START & 0xff);
|
enc_wrbreg(priv, ENC_EWRPTL, PKTMEM_TX_START & 0xff);
|
||||||
@@ -995,11 +1069,9 @@ static int enc_transmit(FAR struct enc_driver_s *priv)
|
|||||||
enc_wrbreg(priv, ENC_ETXNDL, txend & 0xff);
|
enc_wrbreg(priv, ENC_ETXNDL, txend & 0xff);
|
||||||
enc_wrbreg(priv, ENC_ETXNDH, txend >> 8);
|
enc_wrbreg(priv, ENC_ETXNDH, txend >> 8);
|
||||||
|
|
||||||
/* Write the per-packet control byte into the transmit buffer */
|
/* Send the WBM command and copy the packet itself into the transmit
|
||||||
|
* buffer at the position of the EWRPT register.
|
||||||
enc_wrgreg(priv, ENC_WBM, 0x00);
|
*/
|
||||||
|
|
||||||
/* Copy the packet itself into the transmit buffer */
|
|
||||||
|
|
||||||
enc_wrbuffer(priv, priv->dev.d_buf, priv->dev.d_len);
|
enc_wrbuffer(priv, priv->dev.d_buf, priv->dev.d_len);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user