File indexing completed on 2025-05-11 08:23:52
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #ifndef GEN5200_BESTCOMM_H
0029 #define GEN5200_BESTCOMM_H
0030
0031 #include "bestcomm_ops.h"
0032
0033 #include <assert.h>
0034
0035 #include <rtems.h>
0036
0037 #include <bsp/mpc5200.h>
0038 #include <bsp/bestcomm/bestcomm_api.h>
0039 #include <bsp/bestcomm/bestcomm_glue.h>
0040
0041 #ifdef __cplusplus
0042 extern "C" {
0043 #endif
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 typedef struct {
0056 uint32_t *tdt_begin;
0057 uint32_t *tdt_last;
0058 volatile uint32_t (*var_table)[32];
0059 uint32_t fdt_and_pragmas;
0060 uint32_t reserved_0;
0061 uint32_t reserved_1;
0062 uint32_t *context_begin;
0063 uint32_t reserved_2;
0064 } bestcomm_task_entry;
0065
0066 #define BESTCOMM_TASK_ENTRY_TABLE ((volatile bestcomm_task_entry *) 0xf0008000)
0067
0068 #define BESTCOMM_IRQ_EVENT RTEMS_EVENT_13
0069
0070 typedef struct {
0071 int task_index;
0072 rtems_id event_task_id;
0073 } bestcomm_irq;
0074
0075 void bestcomm_irq_create(bestcomm_irq *self, int task_index);
0076
0077 void bestcomm_irq_destroy(const bestcomm_irq *self);
0078
0079 static inline void bestcomm_irq_enable(const bestcomm_irq *self)
0080 {
0081 bestcomm_glue_irq_enable(self->task_index);
0082 }
0083
0084 static inline void bestcomm_irq_disable(const bestcomm_irq *self)
0085 {
0086 bestcomm_glue_irq_disable(self->task_index);
0087 }
0088
0089 static inline void bestcomm_irq_clear(const bestcomm_irq *self)
0090 {
0091 SDMA_CLEAR_IEVENT(&mpc5200.sdma.IntPend, self->task_index);
0092 }
0093
0094 static inline int bestcomm_irq_get_task_index(const bestcomm_irq *self)
0095 {
0096 return self->task_index;
0097 }
0098
0099 static inline rtems_id bestcomm_irq_get_event_task_id(const bestcomm_irq *self)
0100 {
0101 return self->event_task_id;
0102 }
0103
0104 static inline void bestcomm_irq_set_event_task_id(bestcomm_irq *self, rtems_id id)
0105 {
0106 self->event_task_id = id;
0107 }
0108
0109 static inline void bestcomm_irq_wakeup_event_task(const bestcomm_irq *self)
0110 {
0111 rtems_status_code sc = rtems_event_send(self->event_task_id, BESTCOMM_IRQ_EVENT);
0112 assert(sc == RTEMS_SUCCESSFUL);
0113 (void) sc;
0114 }
0115
0116 static inline void bestcomm_irq_wait(const bestcomm_irq *self)
0117 {
0118 rtems_event_set events;
0119 rtems_status_code sc = rtems_event_receive(
0120 BESTCOMM_IRQ_EVENT,
0121 RTEMS_EVENT_ALL | RTEMS_WAIT,
0122 RTEMS_NO_TIMEOUT,
0123 &events
0124 );
0125 assert(sc == RTEMS_SUCCESSFUL);
0126 assert(events == BESTCOMM_IRQ_EVENT);
0127 (void) sc;
0128 }
0129
0130 static inline bool bestcomm_irq_peek(const bestcomm_irq *self)
0131 {
0132 rtems_event_set events;
0133 rtems_status_code sc = rtems_event_receive(0, 0, 0, &events);
0134 assert(sc == RTEMS_SUCCESSFUL);
0135 (void) sc;
0136
0137 return (events & BESTCOMM_IRQ_EVENT) != 0;
0138 }
0139
0140 typedef struct {
0141 volatile uint16_t *task_control_register;
0142
0143 volatile uint32_t (*variable_table)[32];
0144
0145 TaskId task_index;
0146
0147 bestcomm_irq irq;
0148
0149 uint32_t *tdt_begin;
0150
0151 size_t tdt_opcode_count;
0152 } bestcomm_task;
0153
0154 void bestcomm_task_create(bestcomm_task *self, TaskId task_index);
0155
0156 void bestcomm_task_create_and_load(
0157 bestcomm_task *self,
0158 TaskId task_index,
0159 const uint32_t *tdt_source_begin,
0160 size_t tdt_size
0161 );
0162
0163 void bestcomm_task_destroy(bestcomm_task *self);
0164
0165 void bestcomm_task_load(bestcomm_task *self, const uint32_t *tdt_source_begin, size_t tdt_size);
0166
0167 static inline void bestcomm_task_set_priority(bestcomm_task *self, int priority)
0168 {
0169
0170 mpc5200.sdma.ipr[self->task_index] = SDMA_IPR_PRIOR(priority);
0171 }
0172
0173 static inline void bestcomm_task_irq_enable(const bestcomm_task *self)
0174 {
0175 bestcomm_irq_enable(&self->irq);
0176 }
0177
0178 static inline void bestcomm_task_irq_disable(const bestcomm_task *self)
0179 {
0180 bestcomm_irq_disable(&self->irq);
0181 }
0182
0183 static inline void bestcomm_task_irq_clear(const bestcomm_task *self)
0184 {
0185 bestcomm_irq_clear(&self->irq);
0186 }
0187
0188 static inline rtems_id bestcomm_task_get_event_task_id(const bestcomm_task *self)
0189 {
0190 return bestcomm_irq_get_event_task_id(&self->irq);
0191 }
0192
0193 static inline void bestcomm_task_set_event_task_id(bestcomm_task *self, rtems_id id)
0194 {
0195 bestcomm_irq_set_event_task_id(&self->irq, id);
0196 }
0197
0198 static inline void bestcomm_task_associate_with_current_task(bestcomm_task *self)
0199 {
0200 bestcomm_task_set_event_task_id(self, rtems_task_self());
0201 }
0202
0203 static inline void bestcomm_task_start(const bestcomm_task *self)
0204 {
0205 *self->task_control_register = SDMA_TCR_EN | SDMA_TCR_HIGH_EN;
0206 }
0207
0208 static inline void bestcomm_task_start_with_autostart(const bestcomm_task *self)
0209 {
0210 *self->task_control_register = (uint16_t)
0211 (SDMA_TCR_EN | SDMA_TCR_HIGH_EN | SDMA_TCR_AUTO_START | SDMA_TCR_AS(self->task_index));
0212 }
0213
0214 static inline void bestcomm_task_stop(const bestcomm_task *self)
0215 {
0216 *self->task_control_register = 0;
0217 }
0218
0219 static inline void bestcomm_task_wakeup_event_task(const bestcomm_task *self)
0220 {
0221 bestcomm_irq_wakeup_event_task(&self->irq);
0222 }
0223
0224 static inline void bestcomm_task_wait(const bestcomm_task *self)
0225 {
0226 bestcomm_irq_wait(&self->irq);
0227 }
0228
0229 static inline bool bestcomm_task_peek(const bestcomm_task *self)
0230 {
0231 return bestcomm_irq_peek(&self->irq);
0232 }
0233
0234 static inline bool bestcomm_task_is_running(const bestcomm_task *self)
0235 {
0236 return (*self->task_control_register & SDMA_TCR_EN) != 0;
0237 }
0238
0239 static inline uint32_t bestcomm_get_task_variable(const bestcomm_task *self, size_t index)
0240 {
0241 assert(index < VAR_COUNT);
0242 return (*self->variable_table)[index];
0243 }
0244
0245 static inline volatile uint32_t *bestcomm_task_get_address_of_variable(const bestcomm_task *self, size_t index)
0246 {
0247 assert(index < VAR_COUNT);
0248 return &(*self->variable_table)[index];
0249 }
0250
0251 static inline void bestcomm_task_set_variable(const bestcomm_task *self, size_t index, uint32_t value)
0252 {
0253 assert(index < VAR_COUNT);
0254 (*self->variable_table)[index] = value;
0255 }
0256
0257 static inline uint32_t bestcomm_task_get_increment_and_condition(const bestcomm_task *self, size_t index)
0258 {
0259 assert(index < INC_COUNT);
0260 return (*self->variable_table)[INC(index)];
0261 }
0262
0263 static inline void bestcomm_task_set_increment_and_condition_32(
0264 const bestcomm_task *self,
0265 size_t index,
0266 uint32_t inc_and_cond
0267 )
0268 {
0269 assert(index < INC_COUNT);
0270 (*self->variable_table)[INC(index)] = inc_and_cond;
0271 }
0272
0273 static inline void bestcomm_task_set_increment_and_condition(
0274 const bestcomm_task *self,
0275 size_t index,
0276 int16_t inc,
0277 int cond
0278 )
0279 {
0280 bestcomm_task_set_increment_and_condition_32(self, index, INC_INIT(cond, inc));
0281 }
0282
0283 static inline void bestcomm_task_set_increment(const bestcomm_task *self, size_t index, int16_t inc)
0284 {
0285 bestcomm_task_set_increment_and_condition_32(self, index, INC_INIT(0, inc));
0286 }
0287
0288 void bestcomm_task_clear_variables(const bestcomm_task *self);
0289
0290 static inline uint32_t bestcomm_task_get_opcode(const bestcomm_task *self, size_t index)
0291 {
0292 assert(index < self->tdt_opcode_count);
0293 return self->tdt_begin[index];
0294 }
0295
0296 static inline void bestcomm_task_set_opcode(bestcomm_task *self, size_t index, uint32_t opcode)
0297 {
0298 assert(index < self->tdt_opcode_count);
0299 self->tdt_begin[index] = opcode;
0300 }
0301
0302 static inline void bestcomm_task_set_initiator(const bestcomm_task *self, int initiator)
0303 {
0304 rtems_interrupt_level level;
0305 rtems_interrupt_disable(level);
0306 *self->task_control_register = BSP_BFLD16SET(*self->task_control_register, initiator, 3, 7);
0307 rtems_interrupt_enable(level);
0308 }
0309
0310 static inline volatile bestcomm_task_entry *bestcomm_task_get_task_entry(const bestcomm_task *self)
0311 {
0312 return &BESTCOMM_TASK_ENTRY_TABLE[self->task_index];
0313 }
0314
0315 static inline void bestcomm_task_set_pragma(const bestcomm_task *self, int bit_pos, bool enable)
0316 {
0317 volatile bestcomm_task_entry *entry = bestcomm_task_get_task_entry(self);
0318 uint32_t mask = BSP_BIT32(bit_pos);
0319 uint32_t bit = enable ? mask : 0;
0320 entry->fdt_and_pragmas = (entry->fdt_and_pragmas & ~mask) | bit;
0321 }
0322
0323 static inline void bestcomm_task_enable_precise_increment(const bestcomm_task *self, bool enable)
0324 {
0325 bestcomm_task_set_pragma(self, SDMA_PRAGMA_BIT_PRECISE_INC, enable);
0326 }
0327
0328 static inline void bestcomm_task_enable_error_reset(const bestcomm_task *self, bool enable)
0329 {
0330 bestcomm_task_set_pragma(self, SDMA_PRAGMA_BIT_RST_ERROR_NO, !enable);
0331 }
0332
0333 static inline void bestcomm_task_enable_pack_data(const bestcomm_task *self, bool enable)
0334 {
0335 bestcomm_task_set_pragma(self, SDMA_PRAGMA_BIT_PACK, enable);
0336 }
0337
0338 static inline void bestcomm_task_enable_integer_mode(const bestcomm_task *self, bool enable)
0339 {
0340 bestcomm_task_set_pragma(self, SDMA_PRAGMA_BIT_INTEGER, enable);
0341 }
0342
0343 static inline void bestcomm_task_enable_speculative_read(const bestcomm_task *self, bool enable)
0344 {
0345 bestcomm_task_set_pragma(self, SDMA_PRAGMA_BIT_SPECREAD, enable);
0346 }
0347
0348 static inline void bestcomm_task_enable_combined_write(const bestcomm_task *self, bool enable)
0349 {
0350 bestcomm_task_set_pragma(self, SDMA_PRAGMA_BIT_CW, enable);
0351 }
0352
0353 static inline void bestcomm_task_enable_read_buffer(const bestcomm_task *self, bool enable)
0354 {
0355 bestcomm_task_set_pragma(self, SDMA_PRAGMA_BIT_RL, enable);
0356 }
0357
0358 static inline volatile uint16_t *bestcomm_task_get_task_control_register(const bestcomm_task *self)
0359 {
0360 return self->task_control_register;
0361 }
0362
0363 static inline int bestcomm_task_get_task_index(const bestcomm_task *self)
0364 {
0365 return self->task_index;
0366 }
0367
0368 static inline void bestcomm_task_free_tdt(bestcomm_task *self)
0369 {
0370 bestcomm_free(self->tdt_begin);
0371 self->tdt_begin = NULL;
0372 }
0373
0374 static inline void bestcomm_task_clear_pragmas(const bestcomm_task *self)
0375 {
0376 volatile bestcomm_task_entry *entry = bestcomm_task_get_task_entry(self);
0377 entry->fdt_and_pragmas &= ~0xffU;
0378 }
0379
0380
0381
0382 #ifdef __cplusplus
0383 }
0384 #endif
0385
0386 #endif