Subversion Repositories svn.mios32

Rev

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

Rev Author Line No. Line
1824 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);
1824 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
#if 0
176
      ack_msg.protocol_version = 1;   // should be 1
177
      ack_msg.node_type[0]    = 'S'; // 4 characters which identify the node type
178
      ack_msg.node_type[1]    = 'I';
179
      ack_msg.node_type[2]    = 'D';
180
      ack_msg.node_type[3]    = ' ';
181
      ack_msg.node_version    = 2;   // version number (0..255)
182
      ack_msg.node_subversion = 0;   // subversion number (0..65535)
183
#else
184
      // for demo app
185
      ack_msg.protocol_version = 1;   // should be 1
186
      ack_msg.node_type[0]    = 'A'; // 4 characters which identify the node type
187
      ack_msg.node_type[1]    = 'B';
188
      ack_msg.node_type[2]    = 'C';
189
      ack_msg.node_type[3]    = 'D';
190
      ack_msg.node_version    = 1;   // version number (0..255)
191
      ack_msg.node_subversion = 0;   // subversion number (0..65535)
192
#endif
193
      MBNET_SendAck(master_id, MBNET_ACK_OK, ack_msg, 8); // master_id, tos, msg, dlc
194
      break;
195
 
196
    default:
197
      // unexpected TOS
198
      MBNET_SendAck(master_id, MBNET_ACK_ERROR, ack_msg, 0); // master_id, tos, msg, dlc
199
  }
200
}
201
 
202
 
203
 
204
/////////////////////////////////////////////////////////////////////////////
205
// This function transfers a 8bit value into patch memory
206
/////////////////////////////////////////////////////////////////////////////
207
s32 MBNET_TASK_PatchWrite8(u8 sid, u16 addr, u8 value)
208
{
209
  s32 status;
210
 
211
#if 1
212
  MIOS32_BOARD_LED_Set(1, 1); // flicker LED for debugging
213
#endif
214
 
215
  MUTEX_MBNET_TAKE;
216
 
217
  mbnet_msg_t msg;
218
  msg.bytes[0] = value;
219
  u8 dlc = 1;
220
 
221
  if( (status=MBNET_SendReq(sid, MBNET_REQ_RAM_WRITE, addr, msg, dlc)) < 0 ) {
222
#if DEBUG_VERBOSE_LEVEL >= 1
223
    DEBUG_MSG("[MBNET_TASK_WritePatch8] MBNET_SendReq failed with status %d\n", status);
224
#endif
225
  } else {
226
    mbnet_msg_t ack_msg;
227
    if( (status=MBNET_WaitAck(sid, &ack_msg, &dlc)) < 0 ) {
228
#if DEBUG_VERBOSE_LEVEL >= 1
229
    DEBUG_MSG("[MBNET_TASK_WritePatch8] MBNET_WaitAck failed with status %d\n", status);
230
#endif
231
    }
232
  }
233
 
234
  MUTEX_MBNET_GIVE;
235
 
236
#if 1
237
  MIOS32_BOARD_LED_Set(1, 0); // flicker LED for debugging
238
#endif
239
 
240
  return status;
241
}
242
 
243
 
244
/////////////////////////////////////////////////////////////////////////////
245
// This function transfers a 16bit value into patch memory
246
/////////////////////////////////////////////////////////////////////////////
247
s32 MBNET_TASK_PatchWrite16(u8 sid, u16 addr, u16 value)
248
{
249
  s32 status;
250
 
251
#if 1
252
  MIOS32_BOARD_LED_Set(1, 1); // flicker LED for debugging
253
#endif
254
 
255
  MUTEX_MBNET_TAKE;
256
 
257
  mbnet_msg_t msg;
258
  msg.bytes[0] = value & 0xff;
259
  msg.bytes[1] = value >> 8;
260
  u8 dlc = 2;
261
 
262
  if( (status=MBNET_SendReq(sid, MBNET_REQ_RAM_WRITE, addr, msg, dlc)) < 0 ) {
263
#if DEBUG_VERBOSE_LEVEL >= 1
264
    DEBUG_MSG("[MBNET_TASK_WritePatch16] MBNET_SendReq failed with status %d\n", status);
265
#endif
266
  } else {
267
    mbnet_msg_t ack_msg;
268
    if( (status=MBNET_WaitAck(sid, &ack_msg, &dlc)) < 0 ) {
269
#if DEBUG_VERBOSE_LEVEL >= 1
270
    DEBUG_MSG("[MBNET_TASK_WritePatch16] MBNET_WaitAck failed with status %d\n", status);
271
#endif
272
    }
273
  }
274
 
275
  MUTEX_MBNET_GIVE;
276
 
277
#if 1
278
  MIOS32_BOARD_LED_Set(1, 0); // flicker LED for debugging
279
#endif
280
 
281
 
282
  return status;
283
}
284
 
285
 
286
 
287