API  2.3.0
TSmarT Software Library
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
wiznet_dhcp_dns.c

This is an example about how to use the wiznet device.

/* @file main.c
* @author TST
* @version 0.1
* @date 22/10/2014
* @brief This is an example of how to create a TCP client and TCP server using the
* wiznet device. And how to use DHCP and DNS
*
* The Wiznet chip is a Hardwired TCP/IP embedded Ethernet controller that
* enables easier internet connection using SPI (Serial Peripheral
* Interface).
*
* This example show the user how to create and manage a TCP client working
* in a Ethernet network. It downloads a header form "google" website. This
* application uses a HTTP protocol(HEAD method) to do it.
*
* @note To run this application it's necessary to set the following parameters:
* - MAC address.
* - IP device.
* - Subnet mask.
* - IP gateway.
* - DNS address.
*
* Users shall change the specific defines located below: MACx, IP_ADDRx, NET_MASK_x, IPGWx
* and DNSx.
*
* @note This application uses the debug UART to display debug information.
* To use the debug UART, users should set the next configuration in their
* serial communication program:
* - Baud rate -----> 115200
* - Word length ---> 8 bits
* - Parity --------> none
* - Stop bit ------> 1
* - Flow control --> none
*
*/
/* Platform headers */
#include "tsmart.h"
#include "wiznet\W5200\include\w5200.h"
#include "wiznet\W5200\include\socket.h"
#include "wiznet\W5200\include\spi.h"
#include "wiznet\W5200\include\config.h"
#include "wiznet\W5200\include\dhcp.h"
#include "wiznet\W5200\include\dns.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define WIZNET_INIT 0
#define WIZNET_CONNECT 1
#define WIZNET_SEND 2
#define WIZNET_RECEIVE 3
#define WIZNET_CLOSE 4
#define ON 1
#define OFF 0
#define DHCP_SOCKET 0
#define DNS_SOCKET 1
#define TCP_C_SOCKET 4
#define TCP_S_SOCKET 5
#define MAX_BUF_SIZE (2*1024)
/* If defined SERVER NAME Always try to connect using it, but it fails try with SERVER IP */
#define SERVER_NAME "www.google.es"
#define GOOGLE_IP0 173
#define GOOGLE_IP1 194
#define GOOGLE_IP2 41
#define GOOGLE_IP3 208
#define GOOGLE_PORT 80
#define MAX_RETRIES_TO_CONNECT 3
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
//Configuration Network Information of W5200
uint8 Enable_DHCP = ON; //ON;OFF;
uint8 Mac[6] = {0x00, 0x08, 0xDC, 0x11, 0x22, 0x33}; //MAC Address
uint8 IP[4] = {192, 168, 1, 99}; //IP Address
uint8 Gateway[4] = {192, 168, 1, 1}; //Gateway Address
uint8 Subnet[4] = {255, 255, 255, 0}; //SubnetMask Address
uint8 DNSServerIP[4] = {8,8,8,8}; //DNS Server Address
xSemaphoreHandle wiznet_mutex;
void WIZ_Config(void)
{
uint8 i;
int8_t ret;
wiz_NetInfo netinfo;
/* HW Reset */
/* Initialize Wiznet */
/* Enable IRQ socket to work in IRQ mode */
if(Enable_DHCP == OFF){
for(i=0; i<4; i++){
netinfo.Mac[i] = Mac[i];
netinfo.IP[i] = IP[i];
netinfo.Subnet[i] = Subnet[i];
netinfo.Gateway[i] = Gateway[i];
netinfo.DNSServerIP[i] = DNSServerIP[i];
}
netinfo.Mac[i] = Mac[i];
i++;
netinfo.Mac[i] = Mac[i];
} else{
for(i=0; i<6; i++){
SRC_MAC_ADDR[i] = Mac[i];
}
ts_printf("Delay for 2 Seconds..\r\n");
Delay_ms(2000);
// Set DHCP
init_dhcp_client(DHCP_SOCKET, wizSWReset, wizSWReset);
ret = getIP_DHCPS();
if(ret == 1){
for(i=0; i<4; i++){
netinfo.Mac[i] = SRC_MAC_ADDR[i];
netinfo.IP[i] = GET_SIP[i];
netinfo.Subnet[i] = GET_SN_MASK[i];
netinfo.Gateway[i] = GET_GW_IP[i];
netinfo.DNSServerIP[i] = GET_DNS_IP[i];
}
netinfo.Mac[i] = SRC_MAC_ADDR[i];
i++;
netinfo.Mac[i] = SRC_MAC_ADDR[i];
}else{
/* Static IP */
for(i=0; i<4; i++){
netinfo.Mac[i] = Mac[i];
netinfo.IP[i] = IP[i];
netinfo.Subnet[i] = Subnet[i];
netinfo.Gateway[i] = Gateway[i];
netinfo.DNSServerIP[i] = DNSServerIP[i];
}
netinfo.Mac[i] = Mac[i];
i++;
netinfo.Mac[i] = Mac[i];
}
SetNetInfo(&netinfo);
ts_printf("\r\n--------------------------------------- \r\n");
ts_printf("W5200E01-M3 \r\n");
ts_printf("Network Configuration Information \r\n");
ts_printf("--------------------------------------- ");
GetNetInfo(&netinfo);
ts_printf("\r\nMAC : %02X.%02X.%02X.%02X.%02X.%02X", netinfo.Mac[0],netinfo.Mac[1],netinfo.Mac[2],netinfo.Mac[3],netinfo.Mac[4],netinfo.Mac[5]);
ts_printf("\r\nIP : %d.%d.%d.%d", netinfo.IP[0],netinfo.IP[1],netinfo.IP[2],netinfo.IP[3]);
ts_printf("\r\nSN : %d.%d.%d.%d", netinfo.Subnet[0],netinfo.Subnet[1],netinfo.Subnet[2],netinfo.Subnet[3]);
ts_printf("\r\nGW : %d.%d.%d.%d", netinfo.Gateway[0],netinfo.Gateway[1],netinfo.Gateway[2],netinfo.Gateway[3]);
ts_printf("\r\nDNS server : %d.%d.%d.%d", netinfo.DNSServerIP[0],netinfo.DNSServerIP[1],netinfo.DNSServerIP[2],netinfo.DNSServerIP[3]);
}
xQueueReset(socket_queue[DHCP_SOCKET]);
xQueueReset(socket_queue[DNS_SOCKET]);
xQueueReset(socket_queue[TCP_C_SOCKET]);
xQueueReset(socket_queue[TCP_S_SOCKET]);
}
/* @brief vW_TCP_Client task
*
* This task turns on the wiznet device and it sets the network parameters.
* After that it create a TCP client. Then it uses a HTTP protocol to request
* the header of the google website using a HEAD method.
*
* @param pvParameters
*/
void vW_TCP_Client(void *pvParameters) {
/* Variables */
uint8 HTTPs_IP[4]= {GOOGLE_IP0, GOOGLE_IP1, GOOGLE_IP2, GOOGLE_IP3}; /* Google address */
uint16_t port = GOOGLE_PORT; /* Google port */
uint16_t local_port = 5000; /* Local port */
int16_t data_len; /* Data length received */
tsmart_w5200_socket_events_t event; /* Event */
static uint8_t http_head[]="HEAD / HTTP/1.0\r\nHost:www.google.es\r\n\r\n\r\n\0"; /* HTTP method: HEAD */
static uint8_t data[MAX_BUF_SIZE]; /* Data buffer */
uint8_t retries = 0; /* Connection retries */
int ret;
uint8_t state = WIZNET_CONNECT;
vTaskDelay(10000/portTICK_RATE_MS);
/* Debug message */
ts_printf("\r\n ---> WIZNET: TCP CLIENT <---\r\n");
do{
switch(state){
case WIZNET_INIT:
/* Configure network */
ts_printf("< Initializing... ");
WIZ_Config();
/* Time to stabilize */
vTaskDelay(1000/portTICK_RATE_MS);
ts_printf(" OK >\r\n");
state = WIZNET_CONNECT;
/* Give mutex */
xSemaphoreGive(wiznet_mutex);
break;
case WIZNET_CONNECT:
/* Take it to synchronize */
xSemaphoreTake(wiznet_mutex, portMAX_DELAY);
ts_printf("< Resolving: %s ... \r\n",SERVER_NAME);
ret = dns_query(DNS_SOCKET, SERVER_NAME, HTTPs_IP);
if (ret <= 0){
ts_printf(" FAIL -USING Static IP->\r\n");
HTTPs_IP[3] = GOOGLE_IP3;
HTTPs_IP[2] = GOOGLE_IP2;
HTTPs_IP[1] = GOOGLE_IP1;
HTTPs_IP[0] = GOOGLE_IP0;
}
/* Open TCP client */
ts_printf("< Connecting... ");
if( TCPClientOpen(TCP_C_SOCKET, local_port++, (uint8*)HTTPs_IP, port) == 1){
/* Wait for being connected */
if (xQueueReceive(socket_queue[TCP_C_SOCKET], &event, 60000/portTICK_RATE_MS) == pdPASS){
if (event == TSMART_W5200_CONNECT){
/* Correct event */
ts_printf(" OK >\r\n");
state = WIZNET_SEND;
break;
}else{
ts_printf(" FAIL (event received: %d) >\r\n", event);
/* Connect FAIL */
state = WIZNET_CLOSE;
break;
}
}else{
ts_printf(" FAIL -NO MSG->\r\n");
state = WIZNET_CLOSE;
break;
}
}else{
ts_printf(" FAIL >\r\n");
state = WIZNET_INIT;
break;
}
case WIZNET_SEND:
/* Request HTTP: HEAD */
ts_printf("< Sending...... ");
TCPSend(TCP_C_SOCKET, http_head, strlen((char *)http_head));
/* Wait for SEND OK */
if (xQueueReceive(socket_queue[TCP_C_SOCKET], &event, 1000/portTICK_RATE_MS) != pdPASS){
ts_printf(" FAIL -NO MSG- >\r\n");
state = WIZNET_CLOSE;
break;
}
if (event != TSMART_W5200_SEND_OK){
ts_printf(" FAIL (event received: %d) >\r\n", event);
state = WIZNET_CLOSE;
break;
}
ts_printf(" OK >\r\n");
state = WIZNET_RECEIVE;
break;
case WIZNET_RECEIVE:
/* Wait for DATA */
ts_printf("< Receiving.... ");
if (xQueueReceive(socket_queue[TCP_C_SOCKET], &event, 1000/portTICK_RATE_MS) != pdPASS){
ts_printf(" FAIL -NO MSG- >\r\n");
state = WIZNET_CLOSE;
break;
}
if (event != TSMART_W5200_RECEIVE){
ts_printf(" FAIL (event received: %d) >\r\n", event);
state = WIZNET_CLOSE;
break;
}
/* Get bytes received */
data_len = TCPRecv(TCP_C_SOCKET, data, 800);
if (data_len > 0){
ts_printf(" OK -> Receive(%d byes)--->\r\n\r\n %s \r\n >\r\n", data_len, data);
}else{
ts_printf(" FAIL -NO DATA- >\r\n");
}
state = WIZNET_CLOSE;
break;
case WIZNET_CLOSE:
/* Close socket */
ts_printf("< Closing...... ");
TCPClose(TCP_C_SOCKET);
/* Wait for DISCONNECT */
if ((xQueueReceive(socket_queue[TCP_C_SOCKET], &event, 5000/portTICK_RATE_MS) == pdPASS) && (event == TSMART_W5200_DISCONNECT) ){
/* Close OK */
ts_printf(" Disconnected > \r\n");
}else{
/* Fail Closing TCP Client */
ts_printf(" FAIL (event received: %d) >\r\n", event);
state = WIZNET_INIT;
vTaskDelay(10000/portTICK_RATE_MS);
break;
}
/* Give mutex */
xSemaphoreGive(wiznet_mutex);
vTaskDelay(10000/portTICK_RATE_MS);
/* Clean QUEUE */
xQueueReset(socket_queue[TCP_C_SOCKET]);
state = WIZNET_CONNECT;
break;
}
}while(1);
}
/* @brief vW_TCP_Server task
*
* This task turns on the wiznet device and it sets the network parameters.
* After that, it creates a TCP server and waits for new TCP data form a
* remote TCP client.
*
* @param pvParameters
*/
void vW_TCP_Server(void *pvParameters) {
/* Variables */
uint16_t local_port = 1236; /* Local port */
int16_t data_len; /* Data length received */
tsmart_w5200_socket_events_t event; /* Event */
static uint8_t data[MAX_BUF_SIZE]; /* Data buffer */
uint8_t connected = 0;
/* Debug message */
ts_printf("\r\n---> WIZNET: TCP SERVER <---\r\n");
/* Configure network */
WIZ_Config();
/* Time to stabilize */
vTaskDelay(1000/portTICK_RATE_MS);
/* Open server */
do{
if (TCPServerOpen(TCP_S_SOCKET, local_port) != 1){
vTaskDelay(10000/portTICK_RATE_MS);
}else{
break;
}
}while(1);
ts_printf("\r\n *** Waiting for connections *** \r\n");
while(1){
/* Give mutex */
xSemaphoreGive(wiznet_mutex);
xQueueReceive(socket_queue[TCP_S_SOCKET], &event, 10000/portTICK_RATE_MS);
/* Take it to synchronize */
xSemaphoreTake(wiznet_mutex, portMAX_DELAY);
/* Check Socket Status */
if( GetTCPSocketStatus(TCP_S_SOCKET) == -1){
event = TSMART_W5200_DISCONNECT; /* To Re-Start the Server */
}
switch(event){
if (connected == 1){
/* Max time Inactive */
/* Disconnection request */
TCPSend(TCP_S_SOCKET, (u_char *)"WIZNET disconnected. Max time Inactive\r\n", strlen("WWIZNET disconnected. Max time Inactive\r\n"));
ts_printf("<*** Disconnection: Max Time Inactive, closing connection... >\r\n");
TCPClose(TCP_S_SOCKET);
connected = 0;
}else{
/* Nothing to do */
}
break;
/* Connected */
ts_printf("<*** NEW Remote TCP client connected >\r\n");
connected = 1;
TCPSend(TCP_S_SOCKET, (u_char *)"WIZNET OK, press '*' to disconnect\r\n", strlen("WIZNET OK, press '*' to disconnect\r\n"));
break;
/* Data received */
/* Reset data buffer */
memset(data, 0x00, sizeof(data));
/* Receive TCP data */
data_len = TCPRecv(TCP_S_SOCKET, (u_char*)data, sizeof(data));
if(data[0] == '*'){
/* Disconnection request */
ts_printf("<*** Disconnection request: closing connection... >\r\n");
TCPClose(TCP_S_SOCKET);
connected = 0;
}else if (data_len > 0){
ts_printf("<*** Data Received from Server Client: %s >\r\n", data);
}
break;
/* Disconnected */
connected = 0;
/* Open server */
do{
if (TCPServerOpen(TCP_S_SOCKET, local_port) != 1){
vTaskDelay(10000/portTICK_RATE_MS);
}else{
break;
}
}while(1);
ts_printf("< *** Waiting for a new connection *** >\r\n");
break;
/* Timeout */
ts_printf("<*** Timeout >\r\n\r\n");
break;
/* Sending ACK */
ts_printf("<*** Sending Message to Client OK >\r\n");
break;
default:
/* Unknow state */
break;
}
}
/* End task */
vTaskDelay(portMAX_DELAY);
}
/* @brief "Init()" function.
*
* This is the first thing that the user must do for using TSmarT.
* It initializes specific hardware resources (GPRS, GPS, AI, DIO, MODBUS, MSA...)
* and software resources (queues, mutex, tasks...) for the user application.
*
* The way to fill in this function properly is to initialize first
* hardware resources and after that software resources.
*
* This function must return: TSMART_PASS when every thing is OK or
* TSMART_FAIL when a failure happened.
*
* @return
* @arg TSMART_PASS
* @arg TSMART_FAIL
*/
int32_t init() {
/* Variables */
tsmart_uart_config_t uart_config;
uint8_t uart_buf[1];
/* ************************************************************************* */
/* Debug Mode */
/* ************************************************************************* */
/* ************************************************************************* */
/* Initialize resources */
/* ************************************************************************* */
/* Create mutex */
wiznet_mutex = xSemaphoreCreateMutex();
if(wiznet_mutex == NULL){
return TSMART_FAIL;
}
/* Take it to synchronize */
xSemaphoreTake(wiznet_mutex, portMAX_DELAY);
/* The specific hardware for this application: Wiznet and UART
*/
/* Initialize wiznet */
/* UART configuration */
uart_config.baud_rate = 115200;
uart_config.flow_control = TSMART_UART_FC_NONE;
uart_config.parity_bit = TSMART_UART_PARITY_NONE;
uart_config.word_length = TSMART_UART_WORDLENGTH_8B;
uart_config.stop_bit = TSMART_UART_STOPBITS_1;
uart_config.rx_buf_sz = 1;
uart_config.rx_buf = uart_buf;
uart_config.use_dma = TSMART_UART_DMA_RX_TX;
uart_config.use_tim = TSMART_UART_TIM_SW;
/* Initialize UART */
TSMART_UART_Init(&tsmart_uart1, &uart_config);
/* Use ts_printf for debugging. This utility is vinculated to an UART. To use it,
* it is necessary to initilialize an UART */
ts_printf_init(&tsmart_uart1);
/* ************************************************************************* */
/* Application task */
/* ************************************************************************* */
/* This examples will need one task:
*
* - W_TCP_Client task: This task turns on the wiznet, configures the device
* and download the header of "google" website using
* HTTP protocol.
*/
/* Create W_TCP_Client Task */
if (xTaskCreate(vW_TCP_Client, "W_TCP_Client", 512, NULL, 7, NULL) != pdPASS) {
return TSMART_FAIL;
}
/* Create W_TCP_Server Task */
if (xTaskCreate(vW_TCP_Server, "W_TCP_Server", 512, NULL, 9, NULL) != pdPASS) {
return TSMART_FAIL;
}
/* Everything OK */
return TSMART_PASS;
}