Subversion Repositories svn.mios32

Rev

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

Rev Author Line No. Line
2263 tk 1
// $Id: app.c 2425 2016-11-03 00:44:22Z tk $
2
/*
3
 * MIOS32 Application Template
4
 *
5
 * ==========================================================================
6
 *
7
 *  Copyright (C) <year> <your name> (<your email address>)
8
 *  Licensed for personal non-commercial use only.
9
 *  All other rights reserved.
10
 *
11
 * ==========================================================================
12
 */
13
 
14
/////////////////////////////////////////////////////////////////////////////
15
// Include files
16
/////////////////////////////////////////////////////////////////////////////
17
 
18
#include <mios32.h>
19
#include "app.h"
20
#include <blm_scalar_master.h>
21
 
22
// FreeRTOS
23
#include <FreeRTOS.h>
24
#include <portmacro.h>
25
#include <task.h>
26
#include <queue.h>
27
#include <semphr.h>
28
 
29
 
30
/////////////////////////////////////////////////////////////////////////////
31
// FreeRTOS tasks and semaphores
32
/////////////////////////////////////////////////////////////////////////////
33
 
34
// this semaphore (resp. mutex) ensures exclusive access to the MIDI Out port
35
xSemaphoreHandle xMIDIOUTSemaphore;
36
 
37
// simplify access to this mutex
38
#define MUTEX_MIDIOUT_TAKE { TASKS_MUTEX_MIDIOUT_Take(); }
39
#define MUTEX_MIDIOUT_GIVE { TASKS_MUTEX_MIDIOUT_Give(); }
40
 
41
// periodic task
42
static void TASK_Period1mS(void *pvParameters);
43
#define PRIORITY_TASK_PERIOD1MS          ( tskIDLE_PRIORITY + 2 ) // lower than MIDI
44
 
45
 
46
/////////////////////////////////////////////////////////////////////////////
47
// Local functions
48
/////////////////////////////////////////////////////////////////////////////
49
static s32 APP_SYSEX_Parser(mios32_midi_port_t port, u8 midi_in);
50
static s32 APP_MIDI_TimeOut(mios32_midi_port_t port);
51
 
52
static s32 APP_BLM_ButtonCallback(u8 blm, blm_scalar_master_element_t element_type, u8 button_x, u8 button_y, u8 button_depressed);
53
static s32 APP_BLM_FaderCallback(u8 blm, u8 fader, u8 value);
54
 
55
 
56
/////////////////////////////////////////////////////////////////////////////
57
// This hook is called after startup to initialize the application
58
/////////////////////////////////////////////////////////////////////////////
59
void APP_Init(void)
60
{
61
  u8 blm = 0; // currently only a single blm device is supported
62
 
63
  // create semaphores
64
  xMIDIOUTSemaphore = xSemaphoreCreateRecursiveMutex();
65
 
66
  // initialize all LEDs
67
  MIOS32_BOARD_LED_Init(0xffffffff);
68
 
69
  // initialize BLM_SCALAR_MASTER communication handler
70
  BLM_SCALAR_MASTER_Init(0);
71
 
72
  // install BLM callbacks
73
  BLM_SCALAR_MASTER_ButtonCallback_Init(APP_BLM_ButtonCallback);
74
  BLM_SCALAR_MASTER_FaderCallback_Init(APP_BLM_FaderCallback);
75
 
76
  // set MIDI port (change here if your MBHP_BLM_SCALAR is connected to a different port)
77
  BLM_SCALAR_MASTER_MIDI_PortSet(blm, UART2); // == IN3/OUT3
78
 
79
  // install SysEx callback
80
  MIOS32_MIDI_SysExCallback_Init(APP_SYSEX_Parser);
81
 
82
  // install timeout callback function
83
  MIOS32_MIDI_TimeOutCallback_Init(APP_MIDI_TimeOut);
84
 
85
  // start tasks
2425 tk 86
  xTaskCreate(TASK_Period1mS, "Period1mS", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_PERIOD1MS, NULL);
2263 tk 87
 
88
  // send layout request to MBHP_BLM_SCALAR
89
  BLM_SCALAR_MASTER_SendRequest(blm, 0x00);
90
}
91
 
92
 
93
/////////////////////////////////////////////////////////////////////////////
94
// This task is running endless in background
95
/////////////////////////////////////////////////////////////////////////////
96
void APP_Background(void)
97
{
98
}
99
 
100
 
101
/////////////////////////////////////////////////////////////////////////////
102
// This hook is called each mS from the main task which also handles DIN, ENC
103
// and AIN events. You could add more jobs here, but they shouldn't consume
104
// more than 300 uS to ensure the responsiveness of buttons, encoders, pots.
105
// Alternatively you could create a dedicated task for application specific
106
// jobs as explained in $MIOS32_PATH/apps/tutorials/006_rtos_tasks
107
/////////////////////////////////////////////////////////////////////////////
108
void APP_Tick(void)
109
{
110
  u8 blm = 0; // currently only a single blm device is supported
111
  static blm_scalar_master_connection_state_t prev_connection_state = BLM_SCALAR_MASTER_CONNECTION_STATE_IDLE;
112
  blm_scalar_master_connection_state_t connection_state = BLM_SCALAR_MASTER_ConnectionStateGet(blm);
113
 
114
  // print message on connection change and turn on/off the status LED
115
  if( connection_state != prev_connection_state ) {
116
    prev_connection_state = connection_state;
117
 
118
    if( connection_state == BLM_SCALAR_MASTER_CONNECTION_STATE_IDLE ) {
119
      MUTEX_MIDIOUT_TAKE;
120
      MIOS32_MIDI_SendDebugMessage("BLM has been disconnected."); // will appear ca. 10 seconds after communication is broken
121
      MIOS32_BOARD_LED_Set(1, 0);
122
      MUTEX_MIDIOUT_GIVE;
123
    } else {
124
      MUTEX_MIDIOUT_TAKE;
125
      MIOS32_MIDI_SendDebugMessage("BLM has been connected."); // will appear ca. 5 seconds after BLM has been connected
126
      MIOS32_MIDI_SendDebugMessage("Reported grid layout: %dx%d with %d colours.", BLM_SCALAR_MASTER_NumColumnsGet(blm), BLM_SCALAR_MASTER_NumRowsGet(blm), BLM_SCALAR_MASTER_NumColoursGet(blm));
127
      MIOS32_BOARD_LED_Set(1, 1);
128
      MUTEX_MIDIOUT_GIVE;
129
    }
130
  }
131
}
132
 
133
 
134
/////////////////////////////////////////////////////////////////////////////
135
// This hook is called each mS from the MIDI task which checks for incoming
136
// MIDI events. You could add more MIDI related jobs here, but they shouldn't
137
// consume more than 300 uS to ensure the responsiveness of incoming MIDI.
138
/////////////////////////////////////////////////////////////////////////////
139
void APP_MIDI_Tick(void)
140
{
141
}
142
 
143
 
144
/////////////////////////////////////////////////////////////////////////////
145
// This hook is called when a MIDI package has been received
146
/////////////////////////////////////////////////////////////////////////////
147
void APP_MIDI_NotifyPackage(mios32_midi_port_t port, mios32_midi_package_t midi_package)
148
{
149
  // forward to BLM master
150
  BLM_SCALAR_MASTER_MIDI_Receive(port, midi_package);
151
}
152
 
153
 
154
/////////////////////////////////////////////////////////////////////////////
155
// This function parses an incoming sysex stream for MIOS32 commands
156
/////////////////////////////////////////////////////////////////////////////
157
static s32 APP_SYSEX_Parser(mios32_midi_port_t port, u8 midi_in)
158
{
159
  // forward SysEx to BLM MASTER
160
  BLM_SCALAR_MASTER_SYSEX_Parser(port, midi_in);
161
 
162
  return 0; // no error
163
}
164
 
165
 
166
/////////////////////////////////////////////////////////////////////////////
167
// This function parses an incoming sysex stream for MIOS32 commands
168
/////////////////////////////////////////////////////////////////////////////
169
static s32 APP_MIDI_TimeOut(mios32_midi_port_t port)
170
{
171
  // forward timeout to BLM MASTER
172
  BLM_SCALAR_MASTER_MIDI_TimeOut(port);
173
 
174
  return 0; // no error
175
}
176
 
177
 
178
/////////////////////////////////////////////////////////////////////////////
179
// This function is called when a BLM button has been pressed/depressed
180
/////////////////////////////////////////////////////////////////////////////
181
static s32 APP_BLM_ButtonCallback(u8 blm, blm_scalar_master_element_t element_id, u8 button_x, u8 button_y, u8 button_depressed)
182
{
183
  // for demo purposes we implemented following:
184
  // - message will be print whenever a button has been pressed
185
  //   later you want to remove these messages from your application, because they consume time!
186
  // - button toggles between green and off
187
  // - if SHIFT button is pressed, the button toggles between red and off
188
  // - the SHIFT button toggles between yellow and off
189
 
190
  // the BLM_SCALAR driver doesn't store the button state, but we can retrieve it with the colour
191
  u8 shift_button_pressed = BLM_SCALAR_MASTER_LED_Get(blm, BLM_SCALAR_MASTER_ELEMENT_SHIFT, 0, 0) == BLM_SCALAR_MASTER_COLOUR_YELLOW;
192
 
193
  // current colour
194
  blm_scalar_master_colour_t colour = BLM_SCALAR_MASTER_LED_Get(blm, element_id, button_x, button_y);
195
 
196
  // set new colour
197
  if( element_id == BLM_SCALAR_MASTER_ELEMENT_SHIFT ) {
198
    blm_scalar_master_colour_t new_colour = button_depressed ? BLM_SCALAR_MASTER_COLOUR_OFF : BLM_SCALAR_MASTER_COLOUR_YELLOW;
199
    BLM_SCALAR_MASTER_LED_Set(blm, element_id, button_x, button_y, new_colour);
200
  } else {
201
    if( !button_depressed ) {
202
      blm_scalar_master_colour_t new_colour = BLM_SCALAR_MASTER_COLOUR_OFF;
203
      if( colour != BLM_SCALAR_MASTER_COLOUR_OFF ) {
204
    new_colour = BLM_SCALAR_MASTER_COLOUR_OFF;
205
      } else {
206
    new_colour = shift_button_pressed ? BLM_SCALAR_MASTER_COLOUR_RED : BLM_SCALAR_MASTER_COLOUR_GREEN;
207
      }
208
 
209
      BLM_SCALAR_MASTER_LED_Set(blm, element_id, button_x, button_y, new_colour);
210
    }
211
  }
212
 
213
 
214
  // print messages for debugging purposes
215
  switch( element_id ) {
216
  case BLM_SCALAR_MASTER_ELEMENT_GRID: {
217
    MUTEX_MIDIOUT_TAKE;
218
    MIOS32_MIDI_SendDebugMessage("BLM Grid Button x=%d y=%d %s\n", button_x, button_y, button_depressed ? "depressed" : "pressed");
219
    MUTEX_MIDIOUT_GIVE;
220
  } break;
221
 
222
  case BLM_SCALAR_MASTER_ELEMENT_EXTRA_ROW: {
223
    MUTEX_MIDIOUT_TAKE;
224
    MIOS32_MIDI_SendDebugMessage("BLM Extra Row Button: x=%d y=%d %s\n", button_x, button_y, button_depressed ? "depressed" : "pressed");
225
    MUTEX_MIDIOUT_GIVE;
226
  } break;
227
 
228
  case BLM_SCALAR_MASTER_ELEMENT_EXTRA_COLUMN: {
229
    MUTEX_MIDIOUT_TAKE;
230
    MIOS32_MIDI_SendDebugMessage("BLM Extra Column Button: x=%d y=%d %s\n", button_x, button_y, button_depressed ? "depressed" : "pressed");
231
    MUTEX_MIDIOUT_GIVE;
232
  } break;
233
 
234
  case BLM_SCALAR_MASTER_ELEMENT_SHIFT: {
235
    MUTEX_MIDIOUT_TAKE;
236
    MIOS32_MIDI_SendDebugMessage("BLM Shift Button: x=%d y=%d %s\n", button_x, button_y, button_depressed ? "depressed" : "pressed");
237
    MUTEX_MIDIOUT_GIVE;
238
  } break;
239
 
240
  default:
241
    return -1; // unexpected element_id
242
  }
243
 
244
  return 0; // no error
245
}
246
 
247
/////////////////////////////////////////////////////////////////////////////
248
// This function is called when a BLM fader has been moved
249
/////////////////////////////////////////////////////////////////////////////
250
static s32 APP_BLM_FaderCallback(u8 blm, u8 fader, u8 value)
251
{
252
  // just forward as CC event
253
  MUTEX_MIDIOUT_TAKE;
254
  MIOS32_MIDI_SendCC(DEFAULT, fader, 1, value);
255
  MUTEX_MIDIOUT_GIVE;
256
 
257
  return 0; // no error
258
}
259
 
260
 
261
/////////////////////////////////////////////////////////////////////////////
262
// This hook is called before the shift register chain is scanned
263
/////////////////////////////////////////////////////////////////////////////
264
void APP_SRIO_ServicePrepare(void)
265
{
266
}
267
 
268
 
269
/////////////////////////////////////////////////////////////////////////////
270
// This hook is called after the shift register chain has been scanned
271
/////////////////////////////////////////////////////////////////////////////
272
void APP_SRIO_ServiceFinish(void)
273
{
274
}
275
 
276
 
277
/////////////////////////////////////////////////////////////////////////////
278
// This hook is called when a button has been toggled
279
// pin_value is 1 when button released, and 0 when button pressed
280
/////////////////////////////////////////////////////////////////////////////
281
void APP_DIN_NotifyToggle(u32 pin, u32 pin_value)
282
{
283
}
284
 
285
 
286
/////////////////////////////////////////////////////////////////////////////
287
// This hook is called when an encoder has been moved
288
// incrementer is positive when encoder has been turned clockwise, else
289
// it is negative
290
/////////////////////////////////////////////////////////////////////////////
291
void APP_ENC_NotifyChange(u32 encoder, s32 incrementer)
292
{
293
}
294
 
295
 
296
/////////////////////////////////////////////////////////////////////////////
297
// This hook is called when a pot has been moved
298
/////////////////////////////////////////////////////////////////////////////
299
void APP_AIN_NotifyChange(u32 pin, u32 pin_value)
300
{
301
}
302
 
303
 
304
/////////////////////////////////////////////////////////////////////////////
305
// This task is called periodically each mS
306
/////////////////////////////////////////////////////////////////////////////
307
static void TASK_Period1mS(void *pvParameters)
308
{
309
  portTickType xLastExecutionTime;
310
 
311
  // Initialise the xLastExecutionTime variable on task entry
312
  xLastExecutionTime = xTaskGetTickCount();
313
 
314
  while( 1 ) {
315
    vTaskDelayUntil(&xLastExecutionTime, 1 / portTICK_RATE_MS);
316
 
317
    // skip delay gap if we had to wait for more than 5 ticks to avoid 
318
    // unnecessary repeats until xLastExecutionTime reached xTaskGetTickCount() again
319
    portTickType xCurrentTickCount = xTaskGetTickCount();
320
    if( xLastExecutionTime < (xCurrentTickCount-5) )
321
      xLastExecutionTime = xCurrentTickCount;
322
 
323
    // call BLM handler, e.g. to send LED updates
324
    BLM_SCALAR_MASTER_Periodic_mS();
325
  }
326
}
327
 
328
 
329
/////////////////////////////////////////////////////////////////////////////
330
// Function to take/give MIDI OUT Semaphore
331
// Note: mios32_defines.h provides special macros which call this function,
332
// so that it can also be used by drivers (such as BLM_SCALAR_MASTER)
333
/////////////////////////////////////////////////////////////////////////////
334
 
335
void TASKS_MUTEX_MIDIOUT_Take(void)
336
{
337
  if( xMIDIOUTSemaphore ) {
338
    while( xSemaphoreTakeRecursive(xMIDIOUTSemaphore, (portTickType)1) != pdTRUE );
339
  }
340
}
341
 
342
void TASKS_MUTEX_MIDIOUT_Give(void)
343
{
344
  if( xMIDIOUTSemaphore ) {
345
    xSemaphoreGiveRecursive(xMIDIOUTSemaphore);
346
  }
347
}