Subversion Repositories svn.mios32

Rev

Rev 392 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
392 tk 1
// $Id: mbnet_task.c 2425 2016-11-03 00:44:22Z tk $
2
/*
3
 * MBNet handler as FreeRTOS task
4
 *
5
 * ==========================================================================
6
 *
7
 *  Copyright (C) 2009 Thorsten Klose (tk@midibox.org)
8
 *  Licensed for personal non-commercial use only.
9
 *  All other rights reserved.
10
 *
11
 * ==========================================================================
12
 */
13
 
14
/////////////////////////////////////////////////////////////////////////////
15
// Include files
16
/////////////////////////////////////////////////////////////////////////////
17
#include <mios32.h>
18
 
19
#include <FreeRTOS.h>
20
#include <task.h>
21
#include <queue.h>
22
 
23
#include <mbnet.h>
24
 
25
#include "mbnet_task.h"
26
 
27
 
28
/////////////////////////////////////////////////////////////////////////////
29
// Task Priorities
30
/////////////////////////////////////////////////////////////////////////////
31
 
32
// same priority like MIOS32 hooks
33
#define PRIORITY_TASK_UIP       ( tskIDLE_PRIORITY + 3 )
34
 
35
 
36
// for mutual exclusive access to MBNet functions
37
// The mutex is handled with MUTEX_MBNET_TAKE and MUTEX_MBNET_GIVE macros
38
xSemaphoreHandle xMBNETSemaphore;
39
 
40
 
41
/////////////////////////////////////////////////////////////////////////////
42
// for optional debugging messages via DEBUG_MSG (defined in mios32_config.h)
43
/////////////////////////////////////////////////////////////////////////////
44
 
45
#define DEBUG_VERBOSE_LEVEL 1
46
 
47
 
48
/////////////////////////////////////////////////////////////////////////////
49
// Local defines
50
/////////////////////////////////////////////////////////////////////////////
51
 
52
#define PATCH_BUFFER_SIZE 512
53
#define ENS_BUFFER_SIZE   64
54
 
55
/////////////////////////////////////////////////////////////////////////////
56
// local variables
57
/////////////////////////////////////////////////////////////////////////////
58
 
59
static u8 patch_buffer[PATCH_BUFFER_SIZE];
60
static u8 ens_buffer[ENS_BUFFER_SIZE];
61
 
62
/////////////////////////////////////////////////////////////////////////////
63
// Local prototypes
64
/////////////////////////////////////////////////////////////////////////////
65
static void MBNET_TASK_Handler(void *pvParameters);
66
static void MBNET_TASK_Service(u8 master_id, mbnet_tos_req_t tos, u16 control, mbnet_msg_t req_msg, u8 dlc);
67
 
68
 
69
/////////////////////////////////////////////////////////////////////////////
70
// Initialize the MBNet task
71
/////////////////////////////////////////////////////////////////////////////
72
s32 MBNET_TASK_Init(u32 mode)
73
{
74
  if( mode > 0 )
75
    return -1; // only mode 0 supported yet
76
 
77
  xMBNETSemaphore = xSemaphoreCreateMutex();
78
 
79
  // start task
2425 tk 80
  xTaskCreate(MBNET_TASK_Handler, "MBNet", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_UIP, NULL);
392 tk 81
 
82
  return 0; // no error
83
}
84
 
85
 
86
/////////////////////////////////////////////////////////////////////////////
87
// The MBNet Task is executed each mS
88
/////////////////////////////////////////////////////////////////////////////
89
static void MBNET_TASK_Handler(void *pvParameters)
90
{
91
  // Initialise the xLastExecutionTime variable on task entry
92
  portTickType xLastExecutionTime = xTaskGetTickCount();
93
 
94
  // initialize MBNet
95
  MUTEX_MBNET_TAKE;
96
  MBNET_Init(0);
97
  MBNET_NodeIDSet(0x10);
98
  MUTEX_MBNET_GIVE;
99
 
100
  // endless loop
101
  while( 1 ) {
102
    vTaskDelayUntil(&xLastExecutionTime, 1 / portTICK_RATE_MS);
103
 
104
    MUTEX_MBNET_TAKE;
105
    MBNET_Handler(MBNET_TASK_Service);
106
    MUTEX_MBNET_GIVE;
107
  }
108
}
109
 
110
 
111
// Application specific ETOS, READ, WRITE and PING requests are forwarded to
112
// this callback function
113
// In any case, the function has to send an acknowledge message back
114
// to the master node!
115
static void MBNET_TASK_Service(u8 master_id, mbnet_tos_req_t tos, u16 control, mbnet_msg_t req_msg, u8 dlc)
116
{
117
  mbnet_msg_t ack_msg;
118
  ack_msg.data_l = 0;
119
  ack_msg.data_h = 0;
120
 
121
  // branch depending on TOS
122
  switch( tos ) {
123
    case MBNET_REQ_SPECIAL:
124
      // no support for MBSID specific ETOS yet - just accept them all
125
      MBNET_SendAck(master_id, MBNET_ACK_OK, ack_msg, 0); // master_id, tos, msg, dlc
126
      break;
127
 
128
    case MBNET_REQ_RAM_READ:
129
      if( control >= 0xff00 ) { // ensemble buffer selected?
130
    int i;
131
    for(i=0; i<8; ++i) {
132
      u32 addr = (control & 0xff) + i;
133
      if( addr < ENS_BUFFER_SIZE ) // no error if address is greater than allowed, just ignore it
134
        ack_msg.bytes[i] = ens_buffer[addr];
135
      else
136
        ack_msg.bytes[i] = 0;
137
    }
138
      } else { // patch buffer selected
139
    int i;
140
    for(i=0; i<8; ++i) {
141
      u32 addr = control + i;
142
      if( addr < PATCH_BUFFER_SIZE ) // no error if address is greater than allowed, just ignore it
143
        ack_msg.bytes[i] = patch_buffer[addr];
144
      else
145
        ack_msg.bytes[i] = 0;
146
    }
147
      }
148
      MBNET_SendAck(master_id, MBNET_ACK_READ, ack_msg, 8); // master_id, tos, msg, dlc
149
      break;
150
 
151
    case MBNET_REQ_RAM_WRITE:
152
      if( dlc == 0 ) { // error of no byte has been received
153
    MBNET_SendAck(master_id, MBNET_ACK_ERROR, ack_msg, 0); // master_id, tos, msg, dlc
154
      } else {
155
    if( control >= 0xff00 ) { // ensemble buffer selected?
156
      int i;
157
      for(i=0; i<dlc; ++i) {
158
        u32 addr = (control & 0xff) + i;
159
        if( addr < ENS_BUFFER_SIZE ) // no error if address is greater than allowed, just ignore it
160
          ens_buffer[addr] = req_msg.bytes[i];
161
      }
162
    } else { // patch buffer selected
163
      int i;
164
      for(i=0; i<dlc; ++i) {
165
        u32 addr = control + i;
166
        if( addr < PATCH_BUFFER_SIZE ) // no error if address is greater than allowed, just ignore it
167
          patch_buffer[addr] = req_msg.bytes[i];
168
      }
169
    }
170
    MBNET_SendAck(master_id, MBNET_ACK_OK, ack_msg, 0); // master_id, tos, msg, dlc
171
      }
172
      break;
173
 
174
    case MBNET_REQ_PING:
175
      ack_msg.protocol_version = 1;   // should be 1
176
      ack_msg.node_type[0]    = 'S'; // 4 characters which identify the node type
177
      ack_msg.node_type[1]    = 'I';
178
      ack_msg.node_type[2]    = 'D';
179
      ack_msg.node_type[3]    = ' ';
180
      ack_msg.node_version    = 2;   // version number (0..255)
181
      ack_msg.node_subversion = 0;   // subversion number (0..65535)
182
      MBNET_SendAck(master_id, MBNET_ACK_OK, ack_msg, 8); // master_id, tos, msg, dlc
183
      break;
184
 
185
    default:
186
      // unexpected TOS
187
      MBNET_SendAck(master_id, MBNET_ACK_ERROR, ack_msg, 0); // master_id, tos, msg, dlc
188
  }
189
}
190
 
191
 
192
 
193
/////////////////////////////////////////////////////////////////////////////
194
// This function transfers a 8bit value into patch memory
195
/////////////////////////////////////////////////////////////////////////////
196
s32 MBNET_TASK_PatchWrite8(u8 sid, u16 addr, u8 value)
197
{
198
  s32 status;
199
 
200
#if 1
201
  MIOS32_BOARD_LED_Set(1, 1); // flicker LED for debugging
202
#endif
203
 
204
  MUTEX_MBNET_TAKE;
205
 
206
  mbnet_msg_t msg;
207
  msg.bytes[0] = value;
208
  u8 dlc = 1;
209
 
210
  if( (status=MBNET_SendReq(sid, MBNET_REQ_RAM_WRITE, addr, msg, dlc)) < 0 ) {
211
#if DEBUG_VERBOSE_LEVEL >= 1
212
    DEBUG_MSG("[MBNET_TASK_WritePatch8] MBNET_SendReq failed with status %d\n", status);
213
#endif
214
  } else {
215
    mbnet_msg_t ack_msg;
216
    if( (status=MBNET_WaitAck(sid, &ack_msg, &dlc)) < 0 ) {
217
#if DEBUG_VERBOSE_LEVEL >= 1
218
    DEBUG_MSG("[MBNET_TASK_WritePatch8] MBNET_WaitAck failed with status %d\n", status);
219
#endif
220
    }
221
  }
222
 
223
  MUTEX_MBNET_GIVE;
224
 
225
#if 1
226
  MIOS32_BOARD_LED_Set(1, 0); // flicker LED for debugging
227
#endif
228
 
229
  return status;
230
}
231
 
232
 
233
/////////////////////////////////////////////////////////////////////////////
234
// This function transfers a 16bit value into patch memory
235
/////////////////////////////////////////////////////////////////////////////
236
s32 MBNET_TASK_PatchWrite16(u8 sid, u16 addr, u16 value)
237
{
238
  s32 status;
239
 
240
#if 1
241
  MIOS32_BOARD_LED_Set(1, 1); // flicker LED for debugging
242
#endif
243
 
244
  MUTEX_MBNET_TAKE;
245
 
246
  mbnet_msg_t msg;
247
  msg.bytes[0] = value & 0xff;
248
  msg.bytes[1] = value >> 8;
249
  u8 dlc = 2;
250
 
251
  if( (status=MBNET_SendReq(sid, MBNET_REQ_RAM_WRITE, addr, msg, dlc)) < 0 ) {
252
#if DEBUG_VERBOSE_LEVEL >= 1
253
    DEBUG_MSG("[MBNET_TASK_WritePatch16] MBNET_SendReq failed with status %d\n", status);
254
#endif
255
  } else {
256
    mbnet_msg_t ack_msg;
257
    if( (status=MBNET_WaitAck(sid, &ack_msg, &dlc)) < 0 ) {
258
#if DEBUG_VERBOSE_LEVEL >= 1
259
    DEBUG_MSG("[MBNET_TASK_WritePatch16] MBNET_WaitAck failed with status %d\n", status);
260
#endif
261
    }
262
  }
263
 
264
  MUTEX_MBNET_GIVE;
265
 
266
#if 1
267
  MIOS32_BOARD_LED_Set(1, 0); // flicker LED for debugging
268
#endif
269
 
270
 
271
  return status;
272
}
273
 
274
 
275
 
276