Subversion Repositories svn.mios32

Rev

Rev 392 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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