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 | #define NDEBUG |
---|
16 | |
---|
17 | #include <bsp/bestcomm.h> |
---|
18 | |
---|
19 | #include <string.h> |
---|
20 | |
---|
21 | #include <bsp/mpc5200.h> |
---|
22 | |
---|
23 | static void bestcomm_irq_handler(void *arg) |
---|
24 | { |
---|
25 | bestcomm_irq *self = arg; |
---|
26 | |
---|
27 | bestcomm_irq_clear(self); |
---|
28 | bestcomm_irq_wakeup_event_task(self); |
---|
29 | } |
---|
30 | |
---|
31 | void bestcomm_irq_create(bestcomm_irq *self, int task_index) |
---|
32 | { |
---|
33 | assert(task_index >= 0 && task_index <= 15); |
---|
34 | |
---|
35 | self->task_index = task_index; |
---|
36 | self->event_task_id = rtems_task_self(); |
---|
37 | bestcomm_glue_irq_install(task_index, bestcomm_irq_handler, self); |
---|
38 | } |
---|
39 | |
---|
40 | void bestcomm_irq_destroy(const bestcomm_irq *self) |
---|
41 | { |
---|
42 | bestcomm_glue_irq_install(self->task_index, NULL, NULL); |
---|
43 | } |
---|
44 | |
---|
45 | void bestcomm_task_create(bestcomm_task *self, TaskId task_index) |
---|
46 | { |
---|
47 | self->task_control_register = &mpc5200.sdma.tcr[task_index]; |
---|
48 | self->variable_table = BESTCOMM_TASK_ENTRY_TABLE[task_index].var_table; |
---|
49 | self->task_index = task_index; |
---|
50 | self->tdt_begin = NULL; |
---|
51 | self->tdt_opcode_count = 0; |
---|
52 | bestcomm_task_stop(self); |
---|
53 | bestcomm_irq_create(&self->irq, task_index); |
---|
54 | } |
---|
55 | |
---|
56 | void bestcomm_task_create_and_load( |
---|
57 | bestcomm_task *self, |
---|
58 | TaskId task_index, |
---|
59 | const uint32_t *tdt_source_begin, |
---|
60 | size_t tdt_size |
---|
61 | ) |
---|
62 | { |
---|
63 | bestcomm_task_create(self, task_index); |
---|
64 | bestcomm_task_load(self, tdt_source_begin, tdt_size); |
---|
65 | } |
---|
66 | |
---|
67 | void bestcomm_task_destroy(bestcomm_task *self) |
---|
68 | { |
---|
69 | bestcomm_task_stop(self); |
---|
70 | bestcomm_task_free_tdt(self); |
---|
71 | } |
---|
72 | |
---|
73 | void bestcomm_task_load(bestcomm_task *self, const uint32_t *tdt_source_begin, size_t tdt_size) |
---|
74 | { |
---|
75 | assert(tdt_size % 4 == 0); |
---|
76 | |
---|
77 | bestcomm_task_irq_disable(self); |
---|
78 | bestcomm_task_stop(self); |
---|
79 | bestcomm_task_irq_clear(self); |
---|
80 | bestcomm_task_irq_enable(self); |
---|
81 | bestcomm_task_free_tdt(self); |
---|
82 | bestcomm_task_clear_variables(self); |
---|
83 | |
---|
84 | self->tdt_opcode_count = tdt_size / 4; |
---|
85 | |
---|
86 | self->tdt_begin = bestcomm_malloc(tdt_size); |
---|
87 | assert(self->tdt_begin != NULL); |
---|
88 | uint32_t *tdt_last = self->tdt_begin + self->tdt_opcode_count - 1; |
---|
89 | |
---|
90 | memcpy(self->tdt_begin, tdt_source_begin, tdt_size); |
---|
91 | |
---|
92 | volatile bestcomm_task_entry *entry = bestcomm_task_get_task_entry(self); |
---|
93 | entry->tdt_begin = self->tdt_begin; |
---|
94 | entry->tdt_last = tdt_last; |
---|
95 | |
---|
96 | bestcomm_task_clear_pragmas(self); |
---|
97 | bestcomm_task_set_priority(self, 0); |
---|
98 | } |
---|
99 | |
---|
100 | void bestcomm_task_clear_variables(const bestcomm_task *self) |
---|
101 | { |
---|
102 | int i; |
---|
103 | |
---|
104 | for (i = 0; i < 32; ++i) { |
---|
105 | (*self->variable_table)[i] = 0; |
---|
106 | } |
---|
107 | } |
---|