Moin Moin,
ich möchte gerne mein XMC4500 relax kit per Ethernet mit einem
Messinstrument verbinden. klappt soweit auch ganz gut.. Das Problem ist
nur, wenn ich die Verbindung aufbaue und der laser bestätigt mit dem
ersten ack, macht das Board danach nichts mehr. Quellcode befindet sich
unten und die wireshark datei im Anhang..
Vielen dank für mögliche Lösungsansätze
#include <DAVE3.h> //Declarations from DAVE3 Code Generation
(includes SFR declaration)
#include <string.h>
/*Test LED */
#define LED1 IO004_Handle0
void delay(long unsigned int i)
{
while(i--)
{
__NOP();
}
}
enum {
LASER_STATUS_UNKNOWN = 0,
LASER_STATUS_CONNECTING,
LASER_STATUS_CONNECTED,
LASER_STATUS_VV_SENT,
LASER_STATUS_VV_RECEIVED,
LASER_STATUS_DISTANCE_QUERY_SENT,
LASER_STATUS_DISTANCE_QUERY_RECEIVED,
LASER_STATUS_CONNECTION_CLOSED
};
int laser_status = LASER_STATUS_UNKNOWN;
// zentrale stelle un state-changes im programm-fluss zu kontrollieren
u. evtl. zu dokumentieren
void setLaserStatus(int new_state)
{
int old_state = new_state;
if (old_state != new_state)
{
// toggle LED ?
// printf ("Laser state change %d -> %d\n", old_state,
new_state);
laser_status = new_state;
}
}
// send query-string to TCP connection
err_t sendLaserQuery(struct tcp_pcb * tpcb, char * laserQuery)
{
err_t error;
struct pbuf *pb;
int queryLen;
int bufspace = tcp_sndbuf(tpcb);
if (bufspace < strlen(laserQuery))
{
// printf ("TCP sndbuf insufficient space (%d)\n", bufspace);
tcp_close(tpcb);
return ERR_MEM;
}
queryLen = strlen(laserQuery);
pb = pbuf_alloc(PBUF_TRANSPORT, queryLen, PBUF_REF);
memcpy(pb->payload, laserQuery, queryLen);
pb->len = pb->tot_len = queryLen;
// write data to TCP socket
error = tcp_write(tpcb, pb->payload, pb->len, queryLen);
if (error != ERR_OK) {
return error;
}
// force data to be sent out
error = tcp_output(tpcb);
if (error != ERR_OK) {
return error;
}
return ERR_OK;
}
// called by lwip to inidicate TCP connection is established (3way
handshake is SYN, SYN-ACK, ACK, ...)
err_t laserConnect(void * arg, struct tcp_pcb * tpcb, err_t err)
{
err_t error;
setLaserStatus(LASER_STATUS_CONNECTED);
error = sendLaserQuery(tpcb, "VV\r\n");
if (error == ERR_OK) {
setLaserStatus(LASER_STATUS_VV_SENT);
}
return error;
}
// called by lwip to inidicate incoming laser data
err_t laserReceive(void * arg, struct tcp_pcb * tpcb, struct pbuf * p,
err_t err)
{
err_t error = ERR_OK;
switch (laser_status) {
case LASER_STATUS_VV_SENT:
// @TODO parse/analyse/display VV info (p->payload / p->len)
// send distance query
error = sendLaserQuery(tpcb, "WTF-DD-ETC-PP\r\n");
if (error == ERR_OK) {
setLaserStatus(LASER_STATUS_DISTANCE_QUERY_SENT);
}
break;
case LASER_STATUS_DISTANCE_QUERY_SENT:
// @TODO parse/analyse/display/store Distance info
(p->payload / p->len)
// @TODO set timer to send text query, or close connection
/*
error = sendLaserQuery(tpcb, "WTF-DD-ETC-PP\r\n");
if (error == ERR_OK) {
setlaserStatus(LASER_STATUS_DISTANCE_QUERY_SEND);
}
*/
break;
}
// mark data as process aka disposable by lwip
tcp_recved(tpcb, p->tot_len);
return error;
}
// callback to poll laser tcp connection
err_t laserPoll(void * arg, struct tcp_pcb * tpcb)
{
// @TODO close connection on idle connection
// z.B: wenn der Laser einfach nicht mehr antwortet, etc...
return ERR_OK;
}
// callback on tcp error
void laserError(void * arg, err_t err)
{
// @TODO handle error? wtf!
}
// close tcp connection
void closeLaserConnection(struct tcp_pcb *tpcb)
{
tcp_arg(tpcb, NULL);
tcp_sent(tpcb, NULL);
tcp_recv(tpcb, NULL);
tcp_close(tpcb);
setLaserStatus(LASER_STATUS_CONNECTION_CLOSED);
}
/*
* - establish TCP connection
* - register receive/poll/error callbacks
*/
struct tcp_pcb * laserInitTCP(struct ip_addr * laserIp, uint16_t
laserPort)
{
err_t error;
struct tcp_pcb * pcb = NULL;
setLaserStatus(LASER_STATUS_CONNECTING);
pcb = tcp_new();
error = tcp_bind(pcb, IP_ADDR_ANY, 55555);
error = tcp_connect(pcb, laserIp, laserPort, laserConnect);
tcp_recv(pcb, laserReceive);
tcp_poll(pcb, laserPoll, 1);
tcp_err(pcb, laserError);
return pcb;
}
int main(void)
{
struct ip_addr laserIp;
struct tcp_pcb * laser_pcb = NULL;
// do it! ;)
DAVE_Init();
lwIPStack_init();
// establish TCP connetion
IP4_ADDR(&laserIp, 192,168,0,10);
laser_pcb = laserInitTCP(&laserIp, 10940);
while (laser_status != LASER_STATUS_CONNECTION_CLOSED)
{
// app still running, do idle in main task
}
return 0;
}