RTEMS  5.0.0
bestcomm.h
1 /*
2  * Copyright (c) 2010-2013 embedded brains GmbH. All rights reserved.
3  *
4  * embedded brains GmbH
5  * Dornierstr. 4
6  * 82178 Puchheim
7  * Germany
8  * <rtems@embedded-brains.de>
9  *
10  * The license and distribution terms for this file may be
11  * found in the file LICENSE in this distribution or at
12  * http://www.rtems.org/license/LICENSE.
13  */
14 
15 #ifndef GEN5200_BESTCOMM_H
16 #define GEN5200_BESTCOMM_H
17 
18 #include "bestcomm_ops.h"
19 
20 #include <assert.h>
21 
22 #include <rtems.h>
23 
24 #include <bsp/mpc5200.h>
26 #include <bsp/bestcomm/bestcomm_glue.h>
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif /* __cplusplus */
31 
42 typedef struct {
43  uint32_t *tdt_begin;
44  uint32_t *tdt_last;
45  volatile uint32_t (*var_table)[32];
46  uint32_t fdt_and_pragmas;
47  uint32_t reserved_0;
48  uint32_t reserved_1;
49  uint32_t *context_begin;
50  uint32_t reserved_2;
52 
53 #define BESTCOMM_TASK_ENTRY_TABLE ((volatile bestcomm_task_entry *) 0xf0008000)
54 
55 #define BESTCOMM_IRQ_EVENT RTEMS_EVENT_13
56 
57 typedef struct {
58  int task_index;
59  rtems_id event_task_id;
60 } bestcomm_irq;
61 
62 void bestcomm_irq_create(bestcomm_irq *self, int task_index);
63 
64 void bestcomm_irq_destroy(const bestcomm_irq *self);
65 
66 static inline void bestcomm_irq_enable(const bestcomm_irq *self)
67 {
68  bestcomm_glue_irq_enable(self->task_index);
69 }
70 
71 static inline void bestcomm_irq_disable(const bestcomm_irq *self)
72 {
73  bestcomm_glue_irq_disable(self->task_index);
74 }
75 
76 static inline void bestcomm_irq_clear(const bestcomm_irq *self)
77 {
78  SDMA_CLEAR_IEVENT(&mpc5200.sdma.IntPend, self->task_index);
79 }
80 
81 static inline int bestcomm_irq_get_task_index(const bestcomm_irq *self)
82 {
83  return self->task_index;
84 }
85 
86 static inline rtems_id bestcomm_irq_get_event_task_id(const bestcomm_irq *self)
87 {
88  return self->event_task_id;
89 }
90 
91 static inline void bestcomm_irq_set_event_task_id(bestcomm_irq *self, rtems_id id)
92 {
93  self->event_task_id = id;
94 }
95 
96 static inline void bestcomm_irq_wakeup_event_task(const bestcomm_irq *self)
97 {
98  rtems_status_code sc = rtems_event_send(self->event_task_id, BESTCOMM_IRQ_EVENT);
99  assert(sc == RTEMS_SUCCESSFUL);
100  (void) sc;
101 }
102 
103 static inline void bestcomm_irq_wait(const bestcomm_irq *self)
104 {
105  rtems_event_set events;
107  BESTCOMM_IRQ_EVENT,
110  &events
111  );
112  assert(sc == RTEMS_SUCCESSFUL);
113  assert(events == BESTCOMM_IRQ_EVENT);
114  (void) sc;
115 }
116 
117 static inline bool bestcomm_irq_peek(const bestcomm_irq *self)
118 {
119  rtems_event_set events;
120  rtems_status_code sc = rtems_event_receive(0, 0, 0, &events);
121  assert(sc == RTEMS_SUCCESSFUL);
122  (void) sc;
123 
124  return (events & BESTCOMM_IRQ_EVENT) != 0;
125 }
126 
127 typedef struct {
128  volatile uint16_t *task_control_register;
129 
130  volatile uint32_t (*variable_table)[32];
131 
132  TaskId task_index;
133 
134  bestcomm_irq irq;
135 
136  uint32_t *tdt_begin;
137 
138  size_t tdt_opcode_count;
139 } bestcomm_task;
140 
141 void bestcomm_task_create(bestcomm_task *self, TaskId task_index);
142 
143 void bestcomm_task_create_and_load(
144  bestcomm_task *self,
145  TaskId task_index,
146  const uint32_t *tdt_source_begin,
147  size_t tdt_size
148 );
149 
150 void bestcomm_task_destroy(bestcomm_task *self);
151 
152 void bestcomm_task_load(bestcomm_task *self, const uint32_t *tdt_source_begin, size_t tdt_size);
153 
154 static inline void bestcomm_task_set_priority(bestcomm_task *self, int priority)
155 {
156  /* Allow higher priority initiator to block current initiator */
157  mpc5200.sdma.ipr[self->task_index] = SDMA_IPR_PRIOR(priority);
158 }
159 
160 static inline void bestcomm_task_irq_enable(const bestcomm_task *self)
161 {
162  bestcomm_irq_enable(&self->irq);
163 }
164 
165 static inline void bestcomm_task_irq_disable(const bestcomm_task *self)
166 {
167  bestcomm_irq_disable(&self->irq);
168 }
169 
170 static inline void bestcomm_task_irq_clear(const bestcomm_task *self)
171 {
172  bestcomm_irq_clear(&self->irq);
173 }
174 
175 static inline rtems_id bestcomm_task_get_event_task_id(const bestcomm_task *self)
176 {
177  return bestcomm_irq_get_event_task_id(&self->irq);
178 }
179 
180 static inline void bestcomm_task_set_event_task_id(bestcomm_task *self, rtems_id id)
181 {
182  bestcomm_irq_set_event_task_id(&self->irq, id);
183 }
184 
185 static inline void bestcomm_task_associate_with_current_task(bestcomm_task *self)
186 {
187  bestcomm_task_set_event_task_id(self, rtems_task_self());
188 }
189 
190 static inline void bestcomm_task_start(const bestcomm_task *self)
191 {
192  *self->task_control_register = SDMA_TCR_EN | SDMA_TCR_HIGH_EN;
193 }
194 
195 static inline void bestcomm_task_start_with_autostart(const bestcomm_task *self)
196 {
197  *self->task_control_register = (uint16_t)
198  (SDMA_TCR_EN | SDMA_TCR_HIGH_EN | SDMA_TCR_AUTO_START | SDMA_TCR_AS(self->task_index));
199 }
200 
201 static inline void bestcomm_task_stop(const bestcomm_task *self)
202 {
203  *self->task_control_register = 0;
204 }
205 
206 static inline void bestcomm_task_wakeup_event_task(const bestcomm_task *self)
207 {
208  bestcomm_irq_wakeup_event_task(&self->irq);
209 }
210 
211 static inline void bestcomm_task_wait(const bestcomm_task *self)
212 {
213  bestcomm_irq_wait(&self->irq);
214 }
215 
216 static inline bool bestcomm_task_peek(const bestcomm_task *self)
217 {
218  return bestcomm_irq_peek(&self->irq);
219 }
220 
221 static inline bool bestcomm_task_is_running(const bestcomm_task *self)
222 {
223  return (*self->task_control_register & SDMA_TCR_EN) != 0;
224 }
225 
226 static inline uint32_t bestcomm_get_task_variable(const bestcomm_task *self, size_t index)
227 {
228  assert(index < VAR_COUNT);
229  return (*self->variable_table)[index];
230 }
231 
232 static inline volatile uint32_t *bestcomm_task_get_address_of_variable(const bestcomm_task *self, size_t index)
233 {
234  assert(index < VAR_COUNT);
235  return &(*self->variable_table)[index];
236 }
237 
238 static inline void bestcomm_task_set_variable(const bestcomm_task *self, size_t index, uint32_t value)
239 {
240  assert(index < VAR_COUNT);
241  (*self->variable_table)[index] = value;
242 }
243 
244 static inline uint32_t bestcomm_task_get_increment_and_condition(const bestcomm_task *self, size_t index)
245 {
246  assert(index < INC_COUNT);
247  return (*self->variable_table)[INC(index)];
248 }
249 
250 static inline void bestcomm_task_set_increment_and_condition_32(
251  const bestcomm_task *self,
252  size_t index,
253  uint32_t inc_and_cond
254 )
255 {
256  assert(index < INC_COUNT);
257  (*self->variable_table)[INC(index)] = inc_and_cond;
258 }
259 
260 static inline void bestcomm_task_set_increment_and_condition(
261  const bestcomm_task *self,
262  size_t index,
263  int16_t inc,
264  int cond
265 )
266 {
267  bestcomm_task_set_increment_and_condition_32(self, index, INC_INIT(cond, inc));
268 }
269 
270 static inline void bestcomm_task_set_increment(const bestcomm_task *self, size_t index, int16_t inc)
271 {
272  bestcomm_task_set_increment_and_condition_32(self, index, INC_INIT(0, inc));
273 }
274 
275 void bestcomm_task_clear_variables(const bestcomm_task *self);
276 
277 static inline uint32_t bestcomm_task_get_opcode(const bestcomm_task *self, size_t index)
278 {
279  assert(index < self->tdt_opcode_count);
280  return self->tdt_begin[index];
281 }
282 
283 static inline void bestcomm_task_set_opcode(bestcomm_task *self, size_t index, uint32_t opcode)
284 {
285  assert(index < self->tdt_opcode_count);
286  self->tdt_begin[index] = opcode;
287 }
288 
289 static inline void bestcomm_task_set_initiator(const bestcomm_task *self, int initiator)
290 {
291  rtems_interrupt_level level;
293  *self->task_control_register = BSP_BFLD16SET(*self->task_control_register, initiator, 3, 7);
294  rtems_interrupt_enable(level);
295 }
296 
297 static inline volatile bestcomm_task_entry *bestcomm_task_get_task_entry(const bestcomm_task *self)
298 {
299  return &BESTCOMM_TASK_ENTRY_TABLE[self->task_index];
300 }
301 
302 static inline void bestcomm_task_set_pragma(const bestcomm_task *self, int bit_pos, bool enable)
303 {
304  volatile bestcomm_task_entry *entry = bestcomm_task_get_task_entry(self);
305  uint32_t mask = BSP_BIT32(bit_pos);
306  uint32_t bit = enable ? mask : 0;
307  entry->fdt_and_pragmas = (entry->fdt_and_pragmas & ~mask) | bit;
308 }
309 
310 static inline void bestcomm_task_enable_precise_increment(const bestcomm_task *self, bool enable)
311 {
312  bestcomm_task_set_pragma(self, SDMA_PRAGMA_BIT_PRECISE_INC, enable);
313 }
314 
315 static inline void bestcomm_task_enable_error_reset(const bestcomm_task *self, bool enable)
316 {
317  bestcomm_task_set_pragma(self, SDMA_PRAGMA_BIT_RST_ERROR_NO, !enable);
318 }
319 
320 static inline void bestcomm_task_enable_pack_data(const bestcomm_task *self, bool enable)
321 {
322  bestcomm_task_set_pragma(self, SDMA_PRAGMA_BIT_PACK, enable);
323 }
324 
325 static inline void bestcomm_task_enable_integer_mode(const bestcomm_task *self, bool enable)
326 {
327  bestcomm_task_set_pragma(self, SDMA_PRAGMA_BIT_INTEGER, enable);
328 }
329 
330 static inline void bestcomm_task_enable_speculative_read(const bestcomm_task *self, bool enable)
331 {
332  bestcomm_task_set_pragma(self, SDMA_PRAGMA_BIT_SPECREAD, enable);
333 }
334 
335 static inline void bestcomm_task_enable_combined_write(const bestcomm_task *self, bool enable)
336 {
337  bestcomm_task_set_pragma(self, SDMA_PRAGMA_BIT_CW, enable);
338 }
339 
340 static inline void bestcomm_task_enable_read_buffer(const bestcomm_task *self, bool enable)
341 {
342  bestcomm_task_set_pragma(self, SDMA_PRAGMA_BIT_RL, enable);
343 }
344 
345 static inline volatile uint16_t *bestcomm_task_get_task_control_register(const bestcomm_task *self)
346 {
347  return self->task_control_register;
348 }
349 
350 static inline int bestcomm_task_get_task_index(const bestcomm_task *self)
351 {
352  return self->task_index;
353 }
354 
355 static inline void bestcomm_task_free_tdt(bestcomm_task *self)
356 {
357  bestcomm_free(self->tdt_begin);
358  self->tdt_begin = NULL;
359 }
360 
361 static inline void bestcomm_task_clear_pragmas(const bestcomm_task *self)
362 {
363  volatile bestcomm_task_entry *entry = bestcomm_task_get_task_entry(self);
364  entry->fdt_and_pragmas &= ~0xffU;
365 }
366 
369 #ifdef __cplusplus
370 }
371 #endif /* __cplusplus */
372 
373 #endif /* GEN5200_BESTCOMM_H */
Definition: status.h:47
rtems_status_code rtems_event_receive(rtems_event_set event_in, rtems_option option_set, rtems_interval ticks, rtems_event_set *event_out)
Receives pending events.
Definition: eventreceive.c:26
rtems_status_code
Classic API Status.
Definition: status.h:43
#define rtems_interrupt_disable(_isr_cookie)
Disable RTEMS Interrupt.
Definition: intr.h:99
uint32_t rtems_event_set
Integer type to hold an event set of up to 32 events represented as a bit field.
Definition: event.h:40
#define RTEMS_WAIT
Definition: options.h:53
#define RTEMS_EVENT_ALL
Definition: options.h:65
Definition: bestcomm.h:127
#define rtems_interrupt_enable(_isr_cookie)
Enable RTEMS Interrupt.
Definition: intr.h:110
Definition: bestcomm.h:42
ISR_Level rtems_interrupt_level
Interrupt level type.
Definition: intr.h:42
rtems_id rtems_task_self(void)
RTEMS Get Self Task Id.
Definition: taskself.c:23
#define RTEMS_NO_TIMEOUT
Constant for indefinite wait.
Definition: rtems.h:170
Objects_Id rtems_id
Used to manage and manipulate RTEMS object identifiers.
Definition: types.h:83
Definition: bestcomm.h:57
Definition: mmu-config.c:39
#define NULL
Requests a GPIO pin group configuration.
Definition: bestcomm_api.h:77
rtems_status_code rtems_event_send(rtems_id id, rtems_event_set event_in)
Sends an Event Set to the Target Task.
Definition: eventsend.c:25