RTno is communicating library and framework which allows you to make your embedded device capable of communicating with RT-middleware world. RT-middleware is a platform software to realize Robotic system. In RTM, robots are developed by constructing robotics technologies\' elements (components) named RT-component. Therefore, the RTno helps you to create your own RT-component with your mbed and arduino. To know how to use your RTno device, visit here: http://ysuga.net/robot_e/rtm_e/rtc_e/1065?lang=en To know about RT-middleware and RT-component, visit http://www.openrtm.org

Dependencies:   EthernetNetIf

Dependents:   RTnoV3_LED RTnoV3_Template RTnoV3_ADC RTnoV3_Timer ... more

EtherTcp.cpp

Committer:
ysuga
Date:
2012-02-09
Revision:
0:9fac71a0bff3

File content as of revision 0:9fac71a0bff3:

#include "mbed.h"
#include "EtherTcp.h"
#include "EthernetNetIf.h"
#include "TCPSocket.h"

#include "ip_addr.h"
/**
#include <../SPI/SPI.h>
#include <../Ethernet/Ethernet.h>

static EthernetServer *m_pServer;
static EthernetClient *m_pClient;
*/
static EthernetNetIf* m_pInterface;
static TCPSocket* m_pServerSocket;
static TCPSocket* m_pClientSocket;


#define ETCP_RX_BUFFER_SIZE 128
unsigned char etcp_rx_buffer[ETCP_RX_BUFFER_SIZE];
int etcp_rx_buffer_pointer_head = 0;
int etcp_rx_buffer_pointer_tail = 0;
Host m_Client;

Serial *pSerial;

/**
 * Push data to ring buffer.
 */
int etcp_rx_buffer_push(unsigned char c) {
    etcp_rx_buffer[etcp_rx_buffer_pointer_tail] = c;
    etcp_rx_buffer_pointer_tail++;
    if(etcp_rx_buffer_pointer_tail >= ETCP_RX_BUFFER_SIZE) {
        etcp_rx_buffer_pointer_tail = 0;
    }
    return 0;
}

/**
 * Pop data fron ring buffer
 */
int etcp_rx_buffer_pop(unsigned char *c) {
    *c = etcp_rx_buffer[etcp_rx_buffer_pointer_head];
    etcp_rx_buffer_pointer_head++;
    if(etcp_rx_buffer_pointer_head >= ETCP_RX_BUFFER_SIZE) {
        etcp_rx_buffer_pointer_head = 0;
    }
    return 0;
}

int etcp_rx_buffer_get_size() {
    int size = etcp_rx_buffer_pointer_tail - etcp_rx_buffer_pointer_head;
    if(size < 0) {
        size += ETCP_RX_BUFFER_SIZE;
    }
    return size;
}

static void EtherTcp_onClientEvent(TCPSocketEvent e) {
  switch (e) {
  // If the socket is readable, do stuff
  case TCPSOCKET_READABLE:
    while(1) {
      char buf;
      int ret = m_pClientSocket->recv(&buf, 1);
      if (ret == 0) break;
      etcp_rx_buffer_push(buf);
    }
    
    break;
  case TCPSOCKET_CONTIMEOUT:
  case TCPSOCKET_CONRST:
  case TCPSOCKET_CONABRT:
  case TCPSOCKET_ERROR:
  case TCPSOCKET_DISCONNECTED:
    delete m_pClientSocket;
    m_pClientSocket = NULL;
    break;
  }
}

static void EtherTcp_onServerEvent(TCPSocketEvent e) {
  if(e == TCPSOCKET_ACCEPT ) {
    if ( m_pServerSocket->accept(&m_Client, &m_pClientSocket) ) {
      return; //Error in accept, discard connection
    }
    
    m_pClientSocket->setOnEvent(EtherTcp_onClientEvent);
  }
}

void EtherTcp_init(uint8_t* mac, uint8_t* ip, 
           uint8_t* gateway, uint8_t* subnet,
           uint16_t port) 

{
  pSerial = new Serial(USBTX, USBRX);
  m_pInterface = new EthernetNetIf(
       IpAddr(ip[0], ip[1], ip[2], ip[3]), 
       IpAddr(subnet[0], subnet[1], subnet[2], subnet[3]),
       IpAddr(gateway[0], gateway[1], gateway[2], gateway[3]),
       IpAddr(gateway[0], gateway[1], gateway[2], gateway[3]));    
  printf("Hello %d %d %d %d\r\n", ip[0], ip[1], ip[2], ip[3]);
  EthernetErr ethErr = m_pInterface->setup();
  if (ethErr) {
    return;
  }  
  
  m_pServerSocket = new TCPSocket();
  m_pServerSocket->setOnEvent(EtherTcp_onServerEvent);
  m_pServerSocket->bind(Host(IP_ADDR_ANY, port));
  m_pServerSocket->listen();
  SerialDevice_available = EtherTcp_available;
  SerialDevice_getc = EtherTcp_getc;
  SerialDevice_putc = EtherTcp_putc;
}

uint8_t EtherTcp_available()
{
  Net::poll();
  return etcp_rx_buffer_get_size();
}


void EtherTcp_putc(const char c) {
  if(m_pClientSocket != NULL) {
    m_pClientSocket->send(&c, 1);
  }
}

char EtherTcp_getc()
{
  char c;
  etcp_rx_buffer_pop((unsigned char*)&c);
  return c;
}