-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
udp.c
142 lines (127 loc) · 3.64 KB
/
udp.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
* Copyright (C) 2014 Freek van tienen <freek.v.tienen@gmail.com>
*
* This file is part of paparazzi.
*
* paparazzi is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* paparazzi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
/** \file mcu_periph/udp.c
* \brief arch independent UDP API
*
*/
#include "mcu_periph/udp.h"
/* Print the configurations */
#if USE_UDP0
struct udp_periph udp0;
PRINT_CONFIG_VAR(UDP0_HOST);
PRINT_CONFIG_VAR(UDP0_PORT_OUT);
PRINT_CONFIG_VAR(UDP0_PORT_IN);
PRINT_CONFIG_VAR(UDP0_BROADCAST);
#endif // USE_UDP0
#if USE_UDP1
struct udp_periph udp1;
PRINT_CONFIG_VAR(UDP1_HOST);
PRINT_CONFIG_VAR(UDP1_PORT_OUT);
PRINT_CONFIG_VAR(UDP1_PORT_IN);
PRINT_CONFIG_VAR(UDP1_BROADCAST);
#endif // USE_UDP1
#if USE_UDP2
struct udp_periph udp2;
PRINT_CONFIG_VAR(UDP2_HOST);
PRINT_CONFIG_VAR(UDP2_PORT_OUT);
PRINT_CONFIG_VAR(UDP2_PORT_IN);
PRINT_CONFIG_VAR(UDP2_BROADCAST);
#endif // USE_UDP2
/**
* Initialize the UDP peripheral
*/
void udp_periph_init(struct udp_periph *p, char *host, int port_out, int port_in, bool_t broadcast)
{
p->rx_insert_idx = 0;
p->rx_extract_idx = 0;
p->tx_insert_idx = 0;
p->device.periph = (void *)p;
p->device.check_free_space = (check_free_space_t) udp_check_free_space;
p->device.put_byte = (put_byte_t) udp_transmit;
p->device.send_message = (send_message_t) udp_send_message;
p->device.char_available = (char_available_t) udp_char_available;
p->device.get_byte = (get_byte_t) udp_getch;
// Arch dependent initialization
udp_arch_periph_init(p, host, port_out, port_in, broadcast);
}
/**
* Check if there is enough free space in the transmit buffer.
* @param p pointer to UDP peripheral
* @param len how many bytes of free space to check for
* @return TRUE if enough space for #len bytes
*/
bool_t udp_check_free_space(struct udp_periph *p, uint8_t len)
{
return (UDP_TX_BUFFER_SIZE - p->tx_insert_idx) >= len;
}
/**
* Add one data byte to the tx buffer.
* @param p pointer to UDP peripheral
* @param data byte to add to tx buffer
*/
void udp_transmit(struct udp_periph *p, uint8_t data)
{
if (p->tx_insert_idx >= UDP_TX_BUFFER_SIZE) {
return; // no room
}
p->tx_buf[p->tx_insert_idx] = data;
p->tx_insert_idx++;
}
/**
* Get number of bytes available in receive buffer.
* @param p pointer to UDP peripheral
* @return number of bytes available in receive buffer
*/
uint16_t udp_char_available(struct udp_periph *p)
{
int16_t available = p->rx_insert_idx - p->rx_extract_idx;
if (available < 0) {
available += UDP_RX_BUFFER_SIZE;
}
return (uint16_t)available;
}
/**
* Get the last character from the receive buffer.
* @param p pointer to UDP peripheral
* @return last byte
*/
uint8_t udp_getch(struct udp_periph *p)
{
uint8_t ret = p->rx_buf[p->rx_extract_idx];
p->rx_extract_idx = (p->rx_extract_idx + 1) % UDP_RX_BUFFER_SIZE;
return ret;
}
/**
* Called in the event loop to receive bytes
*/
void udp_event(void)
{
#if USE_UDP0
udp_receive(&udp0);
#endif // USE_UDP0
#if USE_UDP1
udp_receive(&udp1);
#endif // USE_UDP1
#if USE_UDP2
udp_receive(&udp2);
#endif // USE_UDP2
}