EVE 1.0
ep.h
Go to the documentation of this file.
1 #ifndef EVE_NET_EP_H_INCLUDED
2 #define EVE_NET_EP_H_INCLUDED
3 /**********************************************************************/
4 /*
5  * Copyright (c) 2014-2016, Jetro AS
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without modification,
9  * are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice,
12  * this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote products
17  * derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONRIBUTORS ``AS IS'' AND ANY EXPRESS
20  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
22  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
24  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
28  * OF SUCH DAMAGE.
29  *
30  * This file is part of the EVE platform.
31  */
32 
33 /**
34  * \file
35  * @brief USB endpoint primitive.
36  *
37  * The endpoint queues and handles messages (URBs) to be send or received over USB interface.
38  *
39  * @author DT, Jetro AS
40  */ /******************************************************************/
41 
42 #include <lib/dlist.h>
43 
44 /**
45  * \addtogroup net_common
46  * @{
47  */
48 
49 /* forward */ struct urb_t;
50 /* forward */ struct ep_t;
51 
52 /** Endpoint transfer status */
53 typedef enum
54 {
55  EP_XFER_STATUS_OK = 0, /**< No errors detected. */
56  EP_XFER_STATUS_ABORTED, /**< Transfer was aborted. */
57  EP_XFER_STATUS_ERROR, /**< Transfer error. */
59 
60 /**
61  * EFM32-compatible callback type.
62  * \param status The transfer status.
63  * \param xferred Number of bytes actually transferred.
64  * \param remaining Number of bytes remaining.
65  */
66 typedef ep_xfer_status_t (*ep_if_xfer_cb_t)(ep_xfer_status_t status, uint32_t xferred, uint32_t remaining);
67 
68 /**
69  * Common prototype for generic URB send and URB receive functions
70  * \param ep The endpoint
71  * \param urb The URB to be send or received
72  */
73 typedef void (*ep_xfer_cb_t)(struct ep_t *ep, struct urb_t *urb);
74 
75 /**
76  * Common prototype for generic URB complete calback
77  * \param ep The endpoint
78  * \param urb The URB that was just sent or received
79  * \param status Status code for the transfer
80  */
81 typedef void (*ep_complete_cb_t)(struct ep_t *ep, struct urb_t *urb, ep_xfer_status_t status);
82 
83 /**
84  * USB complete callback for the EFM32 USB framework.
85  * The callback must call \ref ep_xfer_done for the endpoint like below:
86  *
87  * \code
88 static int rx_done_trap(ep_xfer_status_t status,
89  uint32_t xferred,
90  uint32_t remaining)
91 {
92  return ep_xfer_done(status, xferred, remaining, &theEndpoint);
93 }
94  * \endcode
95  */
97 
98 /**
99  * USB request block (URB), an atomical message sent or received over USB.
100  */
101 struct urb_t
102 {
103  struct dlist_t link; /**< List entry, link to other URBs in the endpoint queue */
104  uint8_t *buf; /**< Pointer to the buffer with actual data */
105  int size; /**< Size of the buffer or actual size of the data in the buffer */
106 };
107 
108 /**
109  * Endpoint defenition structure, constant part.
110  * The structure is supposed to be instantiated in flash memory.
111  */
112 struct ep_c_t {
113  ep_xfer_cb_t xfer; /**< Data transfer callback used by the endpoint */
114  ep_complete_cb_t complete; /**< Complete callback, will be called when transfer is done */
115  ep_done_trap_t done_trap; /**< Internal complete callback, called by the EFM32 USB framework */
116  int size; /**< Max size in bytes of a single URB buffer in the endpoint */
117 };
118 
119 /**
120  * Endpoint defenition structure, variable part.
121  * The structure is supposed to be instantiated in RAM memory.
122  */
123 struct ep_t {
124  struct dlist_t pool; /**< Pool (list) of empty URBs in the endpoint */
125  struct dlist_t head; /**< URB queue */
126  const struct ep_c_t *c; /**< Pointer to the constant part of the defenition */
127 };
128 
129 /**
130  * A (typically constant) structure used for endpoint (\ref ep_t structure) initialization.
131  */
132 struct ep_init_t {
133  struct ep_t *ep; /**< The endpoint */
134  const struct ep_c_t *c; /**< Constant part of the endpoint definition */
135  struct urb_t *urb; /**< Pointer to an array of URB structures for the endpoint */
136  int urb_count; /**< Number of URBs in the urb array */
137  uint8_t *buf; /**< Pointer to the memory are used as URB buffer space */
138  int buf_stride; /**< Difference in bytes between two consequtive addresses of
139  two buffers in the buffer space */
140 };
141 
142 /**
143  * Initialize an endpoint, allocate URBs and buffers
144  * \param ep The endpoint initialization description structure
145  */
146 void ep_init(const struct ep_init_t *ep);
147 
148 
149 /**
150  * Entry point for transfer done notifications
151  * See \ref ep_done_trap_t for details how the function should be called.
152  * \param status Transfer status
153  * \param xferred Number of bytes transferred
154  * \param remaining Number of bytes remaining
155  * \param ep The endpoint the function is called for
156  */
157 int ep_xfer_done(ep_xfer_status_t status,
158  uint32_t xferred,
159  uint32_t remaining,
160  struct ep_t *ep);
161 
162 /**
163  * Instantiation of ef ep_xfer_cb_t for receive endpoints
164  * \param ep The endpoint
165  * \param urb The URB to be received
166  */
167 void ep_xfer_in(struct ep_t *ep, struct urb_t *urb);
168 
169 /**
170  * Instantiation of ef ep_xfer_cb_t for transmit endpoints
171  * \param ep The endpoint
172  * \param urb The URB to be send
173  */
174 void ep_xfer_out(struct ep_t *ep, struct urb_t *urb);
175 
176 /**
177  * Cancel any ongoing transfer.
178  * The function internally called complete callback for the
179  * cancelled URBs.
180  * \param ep The endpoint
181  * \param device Device instance
182  */
183 void ep_kill_all_urbs(struct ep_t *ep, void *device);
184 
185 /**
186  * Allocate a URB from the endpoint
187  * \param ep The endpoint
188  */
189 static inline struct urb_t *ep_alloc_urb(struct ep_t *ep)
190 {
191  struct dlist_t *link = ep->pool.next;
192  if (dlist_is_empty(link)) {
193  link = NULL;
194  } else {
195  dlist_del(link);
196  ((struct urb_t *) link)->size = ep->c->size;
197  }
198  return (struct urb_t *) link;
199 }
200 
201 /**
202  * Free a URB
203  * \param ep The endpoint
204  * \param urb The URB
205  */
206 static inline void ep_free_urb(struct ep_t *ep, struct urb_t *urb)
207 {
208  dlist_append(&ep->pool, &urb->link);
209 }
210 
211 /**
212  * Check if no more URBs can be allocated from the endpoint
213  * \param ep The endpoint
214  * \return false if the endpoint is not empty
215  * \return true if the endpoint is empty
216  */
217 static inline bool ep_is_empty(struct ep_t *ep)
218 {
219  return dlist_is_empty(&ep->pool);
220 }
221 
222 /**
223  * Schedule the URB for receiving or transmitting
224  * \param ep The endpoint
225  * \param urb The URB
226  */
227 static inline void ep_schedule_urb(struct ep_t *ep, struct urb_t *urb)
228 {
229  dlist_append(&ep->head, &urb->link);
230  if (urb->link.next == urb->link.prev)
231  ep->c->xfer(ep, urb);
232 }
233 
234 /** @} */ /* net_common */
235 
236 #endif /* EVE_NET_EP_H_INCLUDED */
const struct ep_c_t * c
Definition: ep.h:134
ep_complete_cb_t complete
Definition: ep.h:114
struct dlist_t link
Definition: ep.h:103
int size
Definition: ep.h:105
struct process * device
Definition: usbnet.h:139
uint8_t * buf
Definition: ep.h:104
struct dlist_t pool
Definition: ep.h:124
static void ep_schedule_urb(struct ep_t *ep, struct urb_t *urb)
Definition: ep.h:227
int urb_count
Definition: ep.h:136
int ep_xfer_done(ep_xfer_status_t status, uint32_t xferred, uint32_t remaining, struct ep_t *ep)
Definition: ep.h:112
ep_if_xfer_cb_t ep_done_trap_t
Definition: ep.h:96
ep_done_trap_t done_trap
Definition: ep.h:115
Definition: ep.h:132
static void ep_free_urb(struct ep_t *ep, struct urb_t *urb)
Definition: ep.h:206
const struct ep_c_t * c
Definition: ep.h:126
The code implements Dummy Headed Doubly Linked Circularlist (DHDLC) primitive.
static bool ep_is_empty(struct ep_t *ep)
Definition: ep.h:217
static int dlist_is_empty(struct dlist_t *list)
Definition: dlist.h:125
uint8_t * buf
Definition: ep.h:137
void(* ep_xfer_cb_t)(struct ep_t *ep, struct urb_t *urb)
Definition: ep.h:73
ep_xfer_cb_t xfer
Definition: ep.h:113
ep_xfer_status_t(* ep_if_xfer_cb_t)(ep_xfer_status_t status, uint32_t xferred, uint32_t remaining)
Definition: ep.h:66
ep_xfer_status_t
Definition: ep.h:53
Definition: ep.h:123
void(* ep_complete_cb_t)(struct ep_t *ep, struct urb_t *urb, ep_xfer_status_t status)
Definition: ep.h:81
struct dlist_t * next
Definition: dlist.h:68
struct ep_t * ep
Definition: ep.h:133
int size
Definition: ep.h:116
struct dlist_t * prev
Definition: dlist.h:67
void ep_xfer_in(struct ep_t *ep, struct urb_t *urb)
static struct urb_t * ep_alloc_urb(struct ep_t *ep)
Definition: ep.h:189
Definition: dlist.h:66
void ep_init(const struct ep_init_t *ep)
Definition: ep.h:101
int buf_stride
Definition: ep.h:138
static void dlist_append(struct dlist_t *list, struct dlist_t *item)
Definition: dlist.h:114
void ep_xfer_out(struct ep_t *ep, struct urb_t *urb)
struct urb_t * urb
Definition: ep.h:135
struct dlist_t head
Definition: ep.h:125
void ep_kill_all_urbs(struct ep_t *ep, void *device)
static struct dlist_t * dlist_del(struct dlist_t *list)
Definition: dlist.h:100