Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
w5100.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2012 Gerard Toonstra
3 *
4 * This file is part of paparazzi.
5 *
6 * paparazzi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * paparazzi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with paparazzi; see the file COPYING. If not, write to
18 * the Free Software Foundation, 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 *
21 */
22
28#include "mcu_periph/sys_time.h"
30#include "mcu_periph/spi.h"
31#include "mcu_periph/gpio.h"
32
33#define TXBUF_BASE 0x4000
34#define RXBUF_BASE 0x6000
35#define SOCKETS 4
36
37#define CMD_SOCKET 1
38#define TELEM_SOCKET 0
39
40#define SOCK_OPEN 0x01
41#define SOCK_CLOSE 0x10
42#define SOCK_SEND 0x20
43#define SOCK_RECV 0x40
44#define SNMR_UDP 0x02
45#define SNMR_MULTI 0x80
46#define SNIR_SEND_OK 0x10
47#define SNIR_TIMEOUT 0x08
48#define CH_BASE 0x0400
49#define CH_SIZE 0x0100
50#define SMASK 0x07FF // Tx buffer MASK
51#define RMASK 0x07FF // Tx buffer MASK
52
53#define REG_MR 0x0000
54#define REG_RX_MEM 0x001A
55#define REG_TX_MEM 0x001B
56
57#define REG_GAR 0x0001
58#define REG_SUBR 0x0005
59#define REG_SHAR 0x0009
60#define REG_SIPR 0x000F
61
62#define SOCK_MR 0x0000
63#define SOCK_CR 0x0001
64#define SOCK_IR 0x0002
65#define SOCK_PORT 0x0004
66#define SOCK_DHAR 0x0006
67#define SOCK_DIPR 0x000C
68#define SOCK_DPORT 0x0010
69#define SOCK_TX_WR 0x0024
70#define SOCK_RSR 0x0026
71#define SOCK_RXRD 0x0028
72
73#ifndef W5100_SPI_DEV
74#define W5100_SPI_DEV spi1
75#endif
76
77#ifndef W5100_SLAVE_IDX
78#define W5100_SLAVE_IDX SPI_SLAVE1
79#endif
80
81#ifndef W5100_DRDY_GPIO
82#define W5100_DRDY_GPIO GPIOB
83#endif
84
85#ifndef W5100_DRDY_GPIO_PIN
86#define W5100_DRDY_GPIO_PIN GPIO1
87#endif
88
89struct pprz_w5100_tp;
93
94// the media access control (ethernet hardware) address for the shield.
95static uint8_t mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
96
97//the IP address for the shield:
98static uint8_t ip[] = { W5100_IP };
102
103static const uint8_t RST = 7; // Reset BIT
104
105uint16_t SBASE[SOCKETS]; // Tx buffer base address
106uint16_t RBASE[SOCKETS]; // Rx buffer base address
107static const uint16_t SSIZE = 2048; // Max Tx buffer size
108static const uint16_t RSIZE = 2048; // Max Rx buffer size
109
111
112static void w5100_close_socket(uint8_t _s);
114static void w5100_read_data(uint8_t s, volatile uint8_t *src, volatile uint8_t *dst, uint16_t len);
116
117static inline void w5100_set(uint16_t _reg, uint8_t _val)
118{
119 w5100_spi.output_buf[0] = 0xF0;
120 w5100_spi.output_buf[1] = _reg >> 8;
121 w5100_spi.output_buf[2] = _reg & 0xFF;
123
125
126 // FIXME: no busy waiting! if really needed add a timeout!!!!
128}
129
131{
132 w5100_spi.output_buf[0] = 0x0F;
133 w5100_spi.output_buf[1] = _reg >> 8;
134 w5100_spi.output_buf[2] = _reg & 0xFF;
135
137
138 // FIXME: no busy waiting! if really needed add a timeout!!!!
140
141 return w5100_spi.input_buf[3];
142}
143
144static inline void w5100_set_buffer(uint16_t _reg, volatile uint8_t *_buf, uint16_t _len)
145{
146 for (int i = 0; i < _len; i++) {
147 w5100_set(_reg, _buf[ i ]);
148 _reg++;
149 }
150}
151
156
158{
159 return w5100_get(CH_BASE + _sock * CH_SIZE + _reg);
160}
161
163{
166 res = res << 8;
167 res2 = res2 & 0xFF;
168 res = res | res2;
169 return res;
170}
171
172// Functions for the generic device API
173static int true_function(struct w5100_periph *p __attribute__((unused)), long *fd __attribute__((unused)), uint16_t len __attribute__((unused))) { return true; }
174static void dev_transmit(struct w5100_periph *p __attribute__((unused)), long fd __attribute__((unused)), uint8_t byte) { w5100_transmit(byte); }
175static void dev_transmit_buffer(struct w5100_periph *p __attribute__((unused)), long fd __attribute__((unused)), uint8_t *data, uint16_t len) { w5100_transmit_buffer(data, len); }
176static void dev_send(struct w5100_periph *p __attribute__((unused)), long fd __attribute__((unused))) { w5100_send(); }
177static int dev_char_available(struct w5100_periph *p __attribute__((unused))) { return w5100_ch_available; }
179{
180 uint8_t c = 0;
181 w5100_receive(&c, 1);
182 return c;
183}
184
185void w5100_init(void)
186{
187
188 // configure the SPI bus.
198
200 chip0.curbuf = 0;
203
204 // wait one second for proper initialization (chip getting powered up).
205 sys_time_usleep(1000000);
206
207 // set DRDY pin
210 sys_time_usleep(200);
212
213 // allow some time for the chip to wake up.
214 sys_time_usleep(20000);
215
216 // write reset bit into mode register
217 w5100_set(REG_MR, 1 << RST);
218
219 // allow some time to wake up...
220 sys_time_usleep(20000);
221
222 // receive memory size
223 w5100_set(REG_RX_MEM, 0x55);
224
225 // transmit memory size
226 w5100_set(REG_TX_MEM, 0x55);
227
228 // Setting the required socket base addresses for reads and writes to/from sockets
229 for (int i = 0; i < SOCKETS; i++) {
230 SBASE[i] = TXBUF_BASE + SSIZE * i;
231 RBASE[i] = RXBUF_BASE + RSIZE * i;
232 }
233
234 uint8_t gateway[4];
235 gateway[0] = ip[0];
236 gateway[1] = ip[1];
237 gateway[2] = ip[2];
238 gateway[3] = 1;
239
240 // configure gateway, subnet, mac and ip on "NIC".
245
246 // create a socket to send telemetry through.
248
249 // make dest zero and configure socket to receive data
250 dest[ 0 ] = 0x00;
252
253 // Configure generic device
254 chip0.device.periph = (void *)(&chip0);
255 chip0.device.check_free_space = (check_free_space_t) true_function;
256 chip0.device.put_byte = (put_byte_t) dev_transmit;
258 chip0.device.send_message = (send_message_t) dev_send;
260 chip0.device.get_byte = (get_byte_t) dev_getch;
261
262 // Init PPRZ transport
264}
265
267{
268
270
271 if (temp == chip0.tx_extract_idx[ chip0.curbuf ]) {
272 // no more room in this transaction.
273 return;
274 }
275
276 // check if in process of sending data
279}
280
282{
283 int i;
284 for (i = 0; i < len; i++) {
285 w5100_transmit(data[i]);
286 }
287}
288
290{
291 // Now send off spi transaction.
293 uint8_t curbuf = chip0.curbuf;
294
295 // switch to other buffer to accept more chars.
296 chip0.curbuf++;
298 chip0.curbuf = 0;
299 }
300
304
307
308 if (offset + len > SSIZE) {
309 // Wrap around circular buffer
310 uint16_t size = SSIZE - offset;
311 w5100_set_buffer(dstAddr, &chip0.tx_buf[curbuf][0], size);
312 w5100_set_buffer(SBASE[ TELEM_SOCKET ], &chip0.tx_buf[curbuf][0] + size, len - size);
313 } else {
314 w5100_set_buffer(dstAddr, &chip0.tx_buf[curbuf][0], len);
315 }
316
317 // Reset write pointer
318 ptr += len;
321
322 // send
324
326 while (complete != 0x00) {
328 }
329}
330
332{
333 uint16_t val = 0, val1 = 0;
334
335 do {
337 if (val1 != 0) {
339 }
340 } while (val != val1);
341 return val;
342}
343
345{
346 // send command to close socket
348 // clear interrupt registers
349 w5100_sock_set(_s, SOCK_IR, 0xFF);
350}
351
353{
354 // Configure socket that receives data on 1234
356 // configure type of socket
358 // configure MSB+LSB of local port number
360 w5100_sock_set(_s, SOCK_PORT + 1, _lport & 0xFF);
361 if (_dest[0] != 0x00) {
362 // configure destination to send stuff to.
364 }
365
366 // this mac corresponds to a mac for multicasting....
367 uint8_t mac_multi[] = { 0x01, 0x00, 0x5E, 0x01, 0x01, 0x0B };
369
370 // configure destination port
372 w5100_sock_set(_s, SOCK_DPORT + 1, _dport & 0xFF);
373
374 // send command to open the socket
376}
377
379{
380 if (w5100_rx_size(CMD_SOCKET) > 0) {
381 return true;
382 }
383 return false;
384}
385
387{
388 uint8_t head[8];
389 uint16_t data_len = 0;
390 uint16_t ptr = 0;
391
392 // Get socket read pointer
394 w5100_read_data(CMD_SOCKET, (uint8_t *)ptr, head, 0x08);
395 ptr += 8;
396 data_len = head[6];
397 data_len = (data_len << 8) + head[7];
398
399 // read data from buffer.
400 w5100_read_data(CMD_SOCKET, (uint8_t *)ptr, buf, data_len); // data copy.
401 ptr += data_len;
402
403 // update read pointer
406
407 // finalize read.
409 return data_len;
410}
411
412static void w5100_read_data(uint8_t s __attribute__((unused)), volatile uint8_t *src, volatile uint8_t *dst,
413 uint16_t len)
414{
415 uint16_t size;
418
421
422 if ((src_mask + len) > RSIZE) {
423 size = RSIZE - src_mask;
424 w5100_read(src_ptr, (uint8_t *)dst, size);
425 dst += size;
426 w5100_read(RBASE[CMD_SOCKET], (uint8_t *) dst, len - size);
427 } else {
428 w5100_read(src_ptr, (uint8_t *) dst, len);
429 }
430}
431
433{
434 for (int i = 0; i < _len; i++) {
435 _buf[i] = w5100_get(_addr);
436 _addr++;
437 }
438 return _len;
439}
440
void gpio_setup_output(ioportid_t port, uint16_t gpios)
Setup one or more pins of the given GPIO port as outputs.
Definition gpio_arch.c:33
static void gpio_set(ioportid_t port, uint16_t pin)
Set a gpio output to high level.
Definition gpio_arch.h:104
static void gpio_clear(ioportid_t port, uint16_t pin)
Clear a gpio output to low level.
Definition gpio_arch.h:114
void sys_time_usleep(uint32_t us)
sys_time_usleep(uint32_t us)
static const float offset[]
Some architecture independent helper functions for GPIOs.
enum SPIClockPolarity cpol
clock polarity control
Definition spi.h:155
enum SPIClockPhase cpha
clock phase control
Definition spi.h:156
enum SPISlaveSelect select
slave selection behavior
Definition spi.h:154
enum SPIDataSizeSelect dss
data transfer word size
Definition spi.h:157
volatile uint8_t * output_buf
pointer to transmit buffer for DMA
Definition spi.h:150
uint16_t input_length
number of data words to read
Definition spi.h:151
enum SPIClockDiv cdiv
prescaler of main clock to use as SPI clock
Definition spi.h:159
volatile uint8_t * input_buf
pointer to receive buffer for DMA
Definition spi.h:149
uint8_t slave_idx
slave id: SPI_SLAVE0 to SPI_SLAVE4
Definition spi.h:153
enum SPIBitOrder bitorder
MSB/LSB order.
Definition spi.h:158
uint16_t output_length
number of data words to write
Definition spi.h:152
enum SPITransactionStatus status
Definition spi.h:162
bool spi_submit(struct spi_periph *p, struct spi_transaction *t)
Submit SPI transaction.
Definition spi_arch.c:533
@ SPICphaEdge1
CPHA = 0.
Definition spi.h:74
@ SPITransSuccess
Definition spi.h:99
@ SPICpolIdleLow
CPOL = 0.
Definition spi.h:83
@ SPISelectUnselect
slave is selected before transaction and unselected after
Definition spi.h:63
@ SPIMSBFirst
Definition spi.h:112
@ SPIDiv64
Definition spi.h:125
@ SPIDss8bit
Definition spi.h:90
SPI transaction structure.
Definition spi.h:148
static float p[2][2]
static uint32_t s
uint16_t foo
Definition main_demo5.c:58
int fd
Definition serial.c:26
Architecture independent SPI (Serial Peripheral Interface) API.
Architecture independent timing functions.
uint16_t val[TCOUPLE_NB]
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
#define SOCK_DPORT
Definition w5100.c:68
#define SOCK_MR
Definition w5100.c:62
static uint8_t ip[]
Definition w5100.c:98
#define REG_SHAR
Definition w5100.c:59
#define RXBUF_BASE
Definition w5100.c:34
static void w5100_set_buffer(uint16_t _reg, volatile uint8_t *_buf, uint16_t _len)
Definition w5100.c:144
static uint8_t dest[]
Definition w5100.c:99
#define SOCK_DHAR
Definition w5100.c:66
#define SNMR_MULTI
Definition w5100.c:45
void w5100_transmit(uint8_t data)
Definition w5100.c:266
void w5100_init(void)
Definition w5100.c:185
static void w5100_read_data(uint8_t s, volatile uint8_t *src, volatile uint8_t *dst, uint16_t len)
Definition w5100.c:412
#define SOCKETS
Definition w5100.c:35
#define CH_BASE
Definition w5100.c:48
#define SOCK_RSR
Definition w5100.c:70
#define SOCK_TX_WR
Definition w5100.c:69
static uint16_t dport
Definition w5100.c:101
uint8_t ck_a
Definition w5100.c:91
#define SOCK_CR
Definition w5100.c:63
#define SOCK_SEND
Definition w5100.c:42
static const uint8_t RST
Definition w5100.c:103
#define SOCK_OPEN
Definition w5100.c:40
#define REG_SUBR
Definition w5100.c:58
#define SOCK_PORT
Definition w5100.c:65
#define W5100_DRDY_GPIO
Definition w5100.c:82
void w5100_transmit_buffer(uint8_t *data, uint16_t len)
Definition w5100.c:281
static uint8_t subnet[]
Definition w5100.c:100
#define REG_SIPR
Definition w5100.c:60
#define W5100_SLAVE_IDX
Definition w5100.c:78
static const uint16_t SSIZE
Definition w5100.c:107
#define REG_TX_MEM
Definition w5100.c:55
#define SOCK_IR
Definition w5100.c:64
static const uint16_t RSIZE
Definition w5100.c:108
uint16_t w5100_rx_size(uint8_t _s)
Definition w5100.c:331
static int true_function(struct w5100_periph *p, long *fd, uint16_t len)
Definition w5100.c:173
#define SOCK_RXRD
Definition w5100.c:71
#define SOCK_CLOSE
Definition w5100.c:41
#define SOCK_DIPR
Definition w5100.c:67
static uint16_t w5100_read(uint16_t _addr, uint8_t *_buf, uint16_t _len)
Definition w5100.c:432
static void dev_transmit(struct w5100_periph *p, long fd, uint8_t byte)
Definition w5100.c:174
struct w5100_periph chip0
Definition w5100.c:90
static uint8_t w5100_sock_get(uint8_t _sock, uint16_t _reg)
Definition w5100.c:157
#define W5100_DRDY_GPIO_PIN
Definition w5100.c:86
#define W5100_SPI_DEV
Definition w5100.c:74
#define SNMR_UDP
Definition w5100.c:44
uint8_t ck_b
Definition w5100.c:91
uint8_t w5100_rx_buf[W5100_RX_BUFFER_SIZE]
Definition w5100.c:92
uint16_t RBASE[SOCKETS]
Definition w5100.c:106
#define CH_SIZE
Definition w5100.c:49
#define RMASK
Definition w5100.c:51
static uint8_t dev_getch(struct w5100_periph *p)
Definition w5100.c:178
static void w5100_close_socket(uint8_t _s)
Definition w5100.c:344
#define SOCK_RECV
Definition w5100.c:43
#define REG_MR
Definition w5100.c:53
uint16_t w5100_receive(uint8_t *buf, uint16_t len)
Definition w5100.c:386
static uint16_t w5100_sock_get16(uint8_t _sock, uint16_t _reg)
Definition w5100.c:162
void w5100_send()
Definition w5100.c:289
static int dev_char_available(struct w5100_periph *p)
Definition w5100.c:177
bool w5100_ch_available()
Definition w5100.c:378
struct spi_transaction w5100_spi
Definition w5100.c:110
static void dev_transmit_buffer(struct w5100_periph *p, long fd, uint8_t *data, uint16_t len)
Definition w5100.c:175
#define TXBUF_BASE
Definition w5100.c:33
static void w5100_set(uint16_t _reg, uint8_t _val)
Definition w5100.c:117
#define REG_GAR
Definition w5100.c:57
#define SMASK
Definition w5100.c:50
uint16_t SBASE[SOCKETS]
Definition w5100.c:105
static void configure_socket(uint8_t _s, uint8_t _flag, uint16_t _lport, uint16_t _dport, uint8_t *_dest)
Definition w5100.c:352
#define TELEM_SOCKET
Definition w5100.c:38
#define REG_RX_MEM
Definition w5100.c:54
static uint8_t w5100_get(uint16_t _reg)
Definition w5100.c:130
static void w5100_sock_set(uint8_t _sock, uint16_t _reg, uint8_t _val)
Definition w5100.c:152
static void dev_send(struct w5100_periph *p, long fd)
Definition w5100.c:176
#define CMD_SOCKET
Definition w5100.c:37
static uint8_t mac[]
Definition w5100.c:95
W5100 ethernet chip I/O.
#define W5100_TX_BUFFER_SIZE
Definition w5100.h:37
volatile uint16_t tx_extract_idx[W5100_BUFFER_NUM]
Definition w5100.h:60
volatile uint8_t work_tx[4]
Definition w5100.h:61
@ W5100StatusUninit
Definition w5100.h:45
volatile uint8_t work_rx[4]
Definition w5100.h:62
struct link_device device
Generic device interface.
Definition w5100.h:65
#define W5100_RX_BUFFER_SIZE
Definition w5100.h:36
int curbuf
Definition w5100.h:52
volatile uint8_t tx_buf[W5100_BUFFER_NUM][W5100_TX_BUFFER_SIZE]
Definition w5100.h:58
#define W5100_BUFFER_NUM
Definition w5100.h:38
volatile uint16_t tx_insert_idx[W5100_BUFFER_NUM]
Definition w5100.h:59
enum W5100Status status
Definition w5100.h:51