RTEMS 7.0-rc1
Loading...
Searching...
No Matches
bestcomm.h
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/*
4 * Copyright (C) 2010, 2013 embedded brains GmbH & Co. KG
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifndef GEN5200_BESTCOMM_H
29#define GEN5200_BESTCOMM_H
30
31#include "bestcomm_ops.h"
32
33#include <assert.h>
34
35#include <rtems.h>
36
37#include <bsp/mpc5200.h>
39#include <bsp/bestcomm/bestcomm_glue.h>
40
41#ifdef __cplusplus
42extern "C" {
43#endif /* __cplusplus */
44
55typedef struct {
56 uint32_t *tdt_begin;
57 uint32_t *tdt_last;
58 volatile uint32_t (*var_table)[32];
59 uint32_t fdt_and_pragmas;
60 uint32_t reserved_0;
61 uint32_t reserved_1;
62 uint32_t *context_begin;
63 uint32_t reserved_2;
65
66#define BESTCOMM_TASK_ENTRY_TABLE ((volatile bestcomm_task_entry *) 0xf0008000)
67
68#define BESTCOMM_IRQ_EVENT RTEMS_EVENT_13
69
70typedef struct {
71 int task_index;
72 rtems_id event_task_id;
74
75void bestcomm_irq_create(bestcomm_irq *self, int task_index);
76
77void bestcomm_irq_destroy(const bestcomm_irq *self);
78
79static inline void bestcomm_irq_enable(const bestcomm_irq *self)
80{
81 bestcomm_glue_irq_enable(self->task_index);
82}
83
84static inline void bestcomm_irq_disable(const bestcomm_irq *self)
85{
86 bestcomm_glue_irq_disable(self->task_index);
87}
88
89static inline void bestcomm_irq_clear(const bestcomm_irq *self)
90{
91 SDMA_CLEAR_IEVENT(&mpc5200.sdma.IntPend, self->task_index);
92}
93
94static inline int bestcomm_irq_get_task_index(const bestcomm_irq *self)
95{
96 return self->task_index;
97}
98
99static inline rtems_id bestcomm_irq_get_event_task_id(const bestcomm_irq *self)
100{
101 return self->event_task_id;
102}
103
104static inline void bestcomm_irq_set_event_task_id(bestcomm_irq *self, rtems_id id)
105{
106 self->event_task_id = id;
107}
108
109static inline void bestcomm_irq_wakeup_event_task(const bestcomm_irq *self)
110{
111 rtems_status_code sc = rtems_event_send(self->event_task_id, BESTCOMM_IRQ_EVENT);
112 assert(sc == RTEMS_SUCCESSFUL);
113 (void) sc;
114}
115
116static inline void bestcomm_irq_wait(const bestcomm_irq *self)
117{
118 (void) self;
119
120 rtems_event_set events;
122 BESTCOMM_IRQ_EVENT,
125 &events
126 );
127 assert(sc == RTEMS_SUCCESSFUL);
128 assert(events == BESTCOMM_IRQ_EVENT);
129 (void) sc;
130}
131
132static inline bool bestcomm_irq_peek(const bestcomm_irq *self)
133{
134 (void) self;
135
136 rtems_event_set events;
137 rtems_status_code sc = rtems_event_receive(0, 0, 0, &events);
138 assert(sc == RTEMS_SUCCESSFUL);
139 (void) sc;
140
141 return (events & BESTCOMM_IRQ_EVENT) != 0;
142}
143
144typedef struct {
145 volatile uint16_t *task_control_register;
146
147 volatile uint32_t (*variable_table)[32];
148
149 TaskId task_index;
150
151 bestcomm_irq irq;
152
153 uint32_t *tdt_begin;
154
155 size_t tdt_opcode_count;
157
158void bestcomm_task_create(bestcomm_task *self, TaskId task_index);
159
160void bestcomm_task_create_and_load(
161 bestcomm_task *self,
162 TaskId task_index,
163 const uint32_t *tdt_source_begin,
164 size_t tdt_size
165);
166
167void bestcomm_task_destroy(bestcomm_task *self);
168
169void bestcomm_task_load(bestcomm_task *self, const uint32_t *tdt_source_begin, size_t tdt_size);
170
171static inline void bestcomm_task_set_priority(bestcomm_task *self, int priority)
172{
173 /* Allow higher priority initiator to block current initiator */
174 mpc5200.sdma.ipr[self->task_index] = SDMA_IPR_PRIOR(priority);
175}
176
177static inline void bestcomm_task_irq_enable(const bestcomm_task *self)
178{
179 bestcomm_irq_enable(&self->irq);
180}
181
182static inline void bestcomm_task_irq_disable(const bestcomm_task *self)
183{
184 bestcomm_irq_disable(&self->irq);
185}
186
187static inline void bestcomm_task_irq_clear(const bestcomm_task *self)
188{
189 bestcomm_irq_clear(&self->irq);
190}
191
192static inline rtems_id bestcomm_task_get_event_task_id(const bestcomm_task *self)
193{
194 return bestcomm_irq_get_event_task_id(&self->irq);
195}
196
197static inline void bestcomm_task_set_event_task_id(bestcomm_task *self, rtems_id id)
198{
199 bestcomm_irq_set_event_task_id(&self->irq, id);
200}
201
202static inline void bestcomm_task_associate_with_current_task(bestcomm_task *self)
203{
204 bestcomm_task_set_event_task_id(self, rtems_task_self());
205}
206
207static inline void bestcomm_task_start(const bestcomm_task *self)
208{
209 *self->task_control_register = SDMA_TCR_EN | SDMA_TCR_HIGH_EN;
210}
211
212static inline void bestcomm_task_start_with_autostart(const bestcomm_task *self)
213{
214 *self->task_control_register = (uint16_t)
215 (SDMA_TCR_EN | SDMA_TCR_HIGH_EN | SDMA_TCR_AUTO_START | SDMA_TCR_AS(self->task_index));
216}
217
218static inline void bestcomm_task_stop(const bestcomm_task *self)
219{
220 *self->task_control_register = 0;
221}
222
223static inline void bestcomm_task_wakeup_event_task(const bestcomm_task *self)
224{
225 bestcomm_irq_wakeup_event_task(&self->irq);
226}
227
228static inline void bestcomm_task_wait(const bestcomm_task *self)
229{
230 bestcomm_irq_wait(&self->irq);
231}
232
233static inline bool bestcomm_task_peek(const bestcomm_task *self)
234{
235 return bestcomm_irq_peek(&self->irq);
236}
237
238static inline bool bestcomm_task_is_running(const bestcomm_task *self)
239{
240 return (*self->task_control_register & SDMA_TCR_EN) != 0;
241}
242
243static inline uint32_t bestcomm_get_task_variable(const bestcomm_task *self, size_t index)
244{
245 assert(index < VAR_COUNT);
246 return (*self->variable_table)[index];
247}
248
249static inline volatile uint32_t *bestcomm_task_get_address_of_variable(const bestcomm_task *self, size_t index)
250{
251 assert(index < VAR_COUNT);
252 return &(*self->variable_table)[index];
253}
254
255static inline void bestcomm_task_set_variable(const bestcomm_task *self, size_t index, uint32_t value)
256{
257 assert(index < VAR_COUNT);
258 (*self->variable_table)[index] = value;
259}
260
261static inline uint32_t bestcomm_task_get_increment_and_condition(const bestcomm_task *self, size_t index)
262{
263 assert(index < INC_COUNT);
264 return (*self->variable_table)[INC(index)];
265}
266
267static inline void bestcomm_task_set_increment_and_condition_32(
268 const bestcomm_task *self,
269 size_t index,
270 uint32_t inc_and_cond
271)
272{
273 assert(index < INC_COUNT);
274 (*self->variable_table)[INC(index)] = inc_and_cond;
275}
276
277static inline void bestcomm_task_set_increment_and_condition(
278 const bestcomm_task *self,
279 size_t index,
280 int16_t inc,
281 int cond
282)
283{
284 bestcomm_task_set_increment_and_condition_32(self, index, INC_INIT(cond, inc));
285}
286
287static inline void bestcomm_task_set_increment(const bestcomm_task *self, size_t index, int16_t inc)
288{
289 bestcomm_task_set_increment_and_condition_32(self, index, INC_INIT(0, inc));
290}
291
292void bestcomm_task_clear_variables(const bestcomm_task *self);
293
294static inline uint32_t bestcomm_task_get_opcode(const bestcomm_task *self, size_t index)
295{
296 assert(index < self->tdt_opcode_count);
297 return self->tdt_begin[index];
298}
299
300static inline void bestcomm_task_set_opcode(bestcomm_task *self, size_t index, uint32_t opcode)
301{
302 assert(index < self->tdt_opcode_count);
303 self->tdt_begin[index] = opcode;
304}
305
306static inline void bestcomm_task_set_initiator(const bestcomm_task *self, int initiator)
307{
310 *self->task_control_register = BSP_BFLD16SET(*self->task_control_register, initiator, 3, 7);
312}
313
314static inline volatile bestcomm_task_entry *bestcomm_task_get_task_entry(const bestcomm_task *self)
315{
316 return &BESTCOMM_TASK_ENTRY_TABLE[self->task_index];
317}
318
319static inline void bestcomm_task_set_pragma(const bestcomm_task *self, int bit_pos, bool enable)
320{
321 volatile bestcomm_task_entry *entry = bestcomm_task_get_task_entry(self);
322 uint32_t mask = BSP_BIT32(bit_pos);
323 uint32_t bit = enable ? mask : 0;
324 entry->fdt_and_pragmas = (entry->fdt_and_pragmas & ~mask) | bit;
325}
326
327static inline void bestcomm_task_enable_precise_increment(const bestcomm_task *self, bool enable)
328{
329 bestcomm_task_set_pragma(self, SDMA_PRAGMA_BIT_PRECISE_INC, enable);
330}
331
332static inline void bestcomm_task_enable_error_reset(const bestcomm_task *self, bool enable)
333{
334 bestcomm_task_set_pragma(self, SDMA_PRAGMA_BIT_RST_ERROR_NO, !enable);
335}
336
337static inline void bestcomm_task_enable_pack_data(const bestcomm_task *self, bool enable)
338{
339 bestcomm_task_set_pragma(self, SDMA_PRAGMA_BIT_PACK, enable);
340}
341
342static inline void bestcomm_task_enable_integer_mode(const bestcomm_task *self, bool enable)
343{
344 bestcomm_task_set_pragma(self, SDMA_PRAGMA_BIT_INTEGER, enable);
345}
346
347static inline void bestcomm_task_enable_speculative_read(const bestcomm_task *self, bool enable)
348{
349 bestcomm_task_set_pragma(self, SDMA_PRAGMA_BIT_SPECREAD, enable);
350}
351
352static inline void bestcomm_task_enable_combined_write(const bestcomm_task *self, bool enable)
353{
354 bestcomm_task_set_pragma(self, SDMA_PRAGMA_BIT_CW, enable);
355}
356
357static inline void bestcomm_task_enable_read_buffer(const bestcomm_task *self, bool enable)
358{
359 bestcomm_task_set_pragma(self, SDMA_PRAGMA_BIT_RL, enable);
360}
361
362static inline volatile uint16_t *bestcomm_task_get_task_control_register(const bestcomm_task *self)
363{
364 return self->task_control_register;
365}
366
367static inline int bestcomm_task_get_task_index(const bestcomm_task *self)
368{
369 return self->task_index;
370}
371
372static inline void bestcomm_task_free_tdt(bestcomm_task *self)
373{
374 bestcomm_free(self->tdt_begin);
375 self->tdt_begin = NULL;
376}
377
378static inline void bestcomm_task_clear_pragmas(const bestcomm_task *self)
379{
380 volatile bestcomm_task_entry *entry = bestcomm_task_get_task_entry(self);
381 entry->fdt_and_pragmas &= ~0xffU;
382}
383
386#ifdef __cplusplus
387}
388#endif /* __cplusplus */
389
390#endif /* GEN5200_BESTCOMM_H */
This header file provides the interfaces of the Assert Handler.
rtems_status_code rtems_event_send(rtems_id id, rtems_event_set event_in)
Sends the event set to the task.
Definition: eventsend.c:46
rtems_status_code rtems_event_receive(rtems_event_set event_in, rtems_option option_set, rtems_interval ticks, rtems_event_set *event_out)
Receives or gets an event set from the calling task.
Definition: eventreceive.c:47
uint32_t rtems_event_set
This integer type represents a bit field which can hold exactly 32 individual events.
Definition: event.h:436
ISR_Level rtems_interrupt_level
This integer type represents interrupt levels.
Definition: intr.h:111
#define rtems_interrupt_enable(_isr_cookie)
Restores the previous interrupt level on the current processor.
Definition: intr.h:311
#define rtems_interrupt_disable(_isr_cookie)
Disables the maskable interrupts on the current processor.
Definition: intr.h:264
#define RTEMS_WAIT
This option constant indicates that the task wants to wait on the resource.
Definition: options.h:139
#define RTEMS_EVENT_ALL
This option constant indicates that the task wishes to wait until all events of interest are availabl...
Definition: options.h:93
rtems_status_code
This enumeration provides status codes for directives of the Classic API.
Definition: status.h:85
@ RTEMS_SUCCESSFUL
This status code indicates successful completion of a requested operation.
Definition: status.h:90
rtems_id rtems_task_self(void)
Gets the task identifier of the calling task.
#define RTEMS_NO_TIMEOUT
This clock tick interval constant indicates that the calling task is willing to wait potentially fore...
Definition: types.h:236
Objects_Id rtems_id
This type represents RTEMS object identifiers.
Definition: types.h:94
This header file defines the RTEMS Classic API.
Definition: bestcomm.h:70
Definition: bestcomm.h:55
Definition: bestcomm.h:144
Definition: mmu-config.c:53