Subversion Repositories svn.mios32

Rev

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

Rev Author Line No. Line
1431 tk 1
// $Id: app.c 2425 2016-11-03 00:44:22Z tk $
2
/*
3
 * MIDIbox KB
4
 *
5
 * ==========================================================================
6
 *
7
 *  Copyright (C) 2012 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
 
18
#include <mios32.h>
19
 
20
#include <eeprom.h>
21
 
22
#include <FreeRTOS.h>
23
#include <task.h>
24
#include <queue.h>
25
 
1666 tk 26
#include <keyboard.h>
2194 tk 27
#include <ainser.h>
1492 tk 28
#include <midi_port.h>
29
#include <midi_router.h>
30
#include <midimon.h>
1431 tk 31
 
32
#include "app.h"
33
#include "presets.h"
34
#include "terminal.h"
35
#include "tasks.h"
36
#include "uip_task.h"
37
#include "osc_client.h"
38
 
39
 
40
/////////////////////////////////////////////////////////////////////////////
41
// Local defines
42
/////////////////////////////////////////////////////////////////////////////
43
 
44
// define priority level for sequencer
45
// use same priority as MIOS32 specific tasks
46
#define PRIORITY_TASK_PERIOD_1mS ( tskIDLE_PRIORITY + 3 )
47
 
48
 
49
/////////////////////////////////////////////////////////////////////////////
50
// Global variables
51
/////////////////////////////////////////////////////////////////////////////
52
// Mutex for MIDI IN/OUT handler
53
xSemaphoreHandle xMIDIINSemaphore;
54
xSemaphoreHandle xMIDIOUTSemaphore;
55
 
56
 
57
/////////////////////////////////////////////////////////////////////////////
1776 tk 58
//! global variables
1431 tk 59
/////////////////////////////////////////////////////////////////////////////
60
 
61
 
62
/////////////////////////////////////////////////////////////////////////////
63
// Local prototypes
64
/////////////////////////////////////////////////////////////////////////////
65
 
66
// local prototype of the task function
67
static void TASK_Period_1mS(void *pvParameters);
68
 
69
static s32 NOTIFY_MIDI_Rx(mios32_midi_port_t port, u8 byte);
70
static s32 NOTIFY_MIDI_Tx(mios32_midi_port_t port, mios32_midi_package_t package);
71
static s32 NOTIFY_MIDI_TimeOut(mios32_midi_port_t port);
72
 
2194 tk 73
static void APP_AINSER_NotifyChange(u32 module, u32 pin, u32 pin_value);
1431 tk 74
 
2194 tk 75
 
1431 tk 76
/////////////////////////////////////////////////////////////////////////////
77
// This hook is called after startup to initialize the application
78
/////////////////////////////////////////////////////////////////////////////
79
void APP_Init(void)
80
{
81
  // create semaphores
82
  xMIDIINSemaphore = xSemaphoreCreateRecursiveMutex();
83
  xMIDIOUTSemaphore = xSemaphoreCreateRecursiveMutex();
84
 
85
  // install SysEx callback
86
  MIOS32_MIDI_SysExCallback_Init(APP_SYSEX_Parser);
87
 
88
  // install MIDI Rx/Tx callback functions
89
  MIOS32_MIDI_DirectRxCallback_Init(&NOTIFY_MIDI_Rx);
90
  MIOS32_MIDI_DirectTxCallback_Init(&NOTIFY_MIDI_Tx);
91
 
92
  // install timeout callback function
93
  MIOS32_MIDI_TimeOutCallback_Init(&NOTIFY_MIDI_TimeOut);
94
 
1474 tk 95
  // limit the number of DIN/DOUT SRs which will be scanned for faster scan rate
96
  MIOS32_SRIO_ScanNumSet(2);
97
 
98
  // init keyboard functions
99
  KEYBOARD_Init(0);
100
 
1431 tk 101
  // read EEPROM content
102
  PRESETS_Init(0);
103
 
104
  // init MIDI port/router handling
1492 tk 105
  MIDI_PORT_Init(0);
106
  MIDI_ROUTER_Init(0);
1431 tk 107
 
2194 tk 108
  // initialize the AINSER module(s)
109
  AINSER_Init(0);
110
  AINSER_NumModulesSet(1); // 1 module
111
  AINSER_MuxedSet(0, 0);   // disable muxing
112
  AINSER_NumPinsSet(0, 8); // 8 pins
113
 
1431 tk 114
  // init terminal
115
  TERMINAL_Init(0);
116
 
117
  // init MIDImon
118
  MIDIMON_Init(0);
119
 
120
  // start uIP task
121
  UIP_TASK_Init(0);
122
 
123
  // print welcome message on MIOS terminal
124
  MIOS32_MIDI_SendDebugMessage("\n");
125
  MIOS32_MIDI_SendDebugMessage("=================\n");
126
  MIOS32_MIDI_SendDebugMessage("%s\n", MIOS32_LCD_BOOT_MSG_LINE1);
127
  MIOS32_MIDI_SendDebugMessage("=================\n");
128
  MIOS32_MIDI_SendDebugMessage("\n");
129
 
130
  // speed up SPI transfer rate (was MIOS32_SPI_PRESCALER_128, initialized by MIOS32_SRIO_Init())
1576 tk 131
  MIOS32_SPI_TransferModeInit(MIOS32_SRIO_SPI, MIOS32_SPI_MODE_CLK1_PHASE1, MIOS32_SPI_PRESCALER_128);
1431 tk 132
  // prescaler 64 results into a transfer rate of 0.64 uS per bit
133
  // when 2 SRs are transfered, we are able to scan the whole 16x8 matrix in 300 uS
134
 
135
  // standard SRIO scan has been disabled in programming_models/traditional/main.c via MIOS32_DONT_SERVICE_SRIO_SCAN in mios32_config.h
136
  // start the scan here - and retrigger it whenever it's finished
137
  APP_SRIO_ServicePrepare();
138
  MIOS32_SRIO_ScanStart(APP_SRIO_ServiceFinish);
139
 
140
  // start tasks
2425 tk 141
  xTaskCreate(TASK_Period_1mS, "1mS", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_PERIOD_1mS, NULL);
1431 tk 142
}
143
 
144
/////////////////////////////////////////////////////////////////////////////
145
// This task is running endless in background
146
/////////////////////////////////////////////////////////////////////////////
147
void APP_Background(void)
148
{
1920 tk 149
}
1431 tk 150
 
1920 tk 151
 
152
/////////////////////////////////////////////////////////////////////////////
153
// This hook is called each mS from the main task which also handles DIN, ENC
154
// and AIN events. You could add more jobs here, but they shouldn't consume
155
// more than 300 uS to ensure the responsiveness of buttons, encoders, pots.
156
// Alternatively you could create a dedicated task for application specific
157
// jobs as explained in $MIOS32_PATH/apps/tutorials/006_rtos_tasks
158
/////////////////////////////////////////////////////////////////////////////
159
void APP_Tick(void)
160
{
161
  // PWM modulate the status LED (this is a sign of life)
162
  u32 timestamp = MIOS32_TIMESTAMP_Get();
163
  MIOS32_BOARD_LED_Set(1, (timestamp % 20) <= ((timestamp / 100) % 10));
2194 tk 164
 
165
  // scan AINSER pins
166
  AINSER_Handler(APP_AINSER_NotifyChange);
1431 tk 167
}
168
 
169
 
170
/////////////////////////////////////////////////////////////////////////////
1920 tk 171
// This hook is called each mS from the MIDI task which checks for incoming
172
// MIDI events. You could add more MIDI related jobs here, but they shouldn't
173
// consume more than 300 uS to ensure the responsiveness of incoming MIDI.
174
/////////////////////////////////////////////////////////////////////////////
175
void APP_MIDI_Tick(void)
176
{
177
}
178
 
179
 
180
/////////////////////////////////////////////////////////////////////////////
1431 tk 181
// This hook is called when a MIDI package has been received
182
/////////////////////////////////////////////////////////////////////////////
183
void APP_MIDI_NotifyPackage(mios32_midi_port_t port, mios32_midi_package_t midi_package)
184
{
185
  // -> MIDI Router
1492 tk 186
  MIDI_ROUTER_Receive(port, midi_package);
1431 tk 187
 
188
  // -> MIDI Port Handler (used for MIDI monitor function)
1492 tk 189
  MIDI_PORT_NotifyMIDIRx(port, midi_package);
1431 tk 190
 
191
  // forward to MIDI Monitor
192
  // SysEx messages have to be filtered for USB0 and UART0 to avoid data corruption
193
  // (the SysEx stream would interfere with monitor messages)
194
  u8 filter_sysex_message = (port == USB0) || (port == UART0);
1911 tk 195
  MIDIMON_Receive(port, midi_package, filter_sysex_message);
1431 tk 196
}
197
 
198
 
199
/////////////////////////////////////////////////////////////////////////////
200
// This function parses an incoming sysex stream for MIOS32 commands
201
/////////////////////////////////////////////////////////////////////////////
202
s32 APP_SYSEX_Parser(mios32_midi_port_t port, u8 midi_in)
203
{
204
  // -> MIDI Router
1492 tk 205
  MIDI_ROUTER_ReceiveSysEx(port, midi_in);
1431 tk 206
 
207
  return 0; // no error
208
}
209
 
210
 
211
/////////////////////////////////////////////////////////////////////////////
212
// This hook is called before the shift register chain is scanned
213
/////////////////////////////////////////////////////////////////////////////
214
void APP_SRIO_ServicePrepare(void)
215
{
216
  // -> keyboard handler
217
  KEYBOARD_SRIO_ServicePrepare();
218
}
219
 
220
 
221
/////////////////////////////////////////////////////////////////////////////
222
// This hook is called after the shift register chain has been scanned
223
/////////////////////////////////////////////////////////////////////////////
224
void APP_SRIO_ServiceFinish(void)
225
{
226
  // -> keyboard handler
227
  KEYBOARD_SRIO_ServiceFinish();
228
 
229
  // standard SRIO scan has been disabled in programming_models/traditional/main.c via MIOS32_DONT_SERVICE_SRIO_SCAN in mios32_config.h
230
  // start the scan here - and retrigger it whenever it's finished
231
  APP_SRIO_ServicePrepare();
232
  MIOS32_SRIO_ScanStart(APP_SRIO_ServiceFinish);
233
}
234
 
235
 
236
/////////////////////////////////////////////////////////////////////////////
237
// This hook is called when a button has been toggled
238
// pin_value is 1 when button released, and 0 when button pressed
239
/////////////////////////////////////////////////////////////////////////////
240
void APP_DIN_NotifyToggle(u32 pin, u32 pin_value)
241
{
242
}
243
 
244
 
245
/////////////////////////////////////////////////////////////////////////////
246
// This hook is called when an encoder has been moved
247
// incrementer is positive when encoder has been turned clockwise, else
248
// it is negative
249
/////////////////////////////////////////////////////////////////////////////
250
void APP_ENC_NotifyChange(u32 encoder, s32 incrementer)
251
{
252
}
253
 
254
 
255
/////////////////////////////////////////////////////////////////////////////
256
// This hook is called when a pot has been moved
257
/////////////////////////////////////////////////////////////////////////////
258
void APP_AIN_NotifyChange(u32 pin, u32 pin_value)
259
{
1476 tk 260
  // -> keyboard
1911 tk 261
  KEYBOARD_AIN_NotifyChange(pin, pin_value);
1434 tk 262
#if 0
263
  MIOS32_MIDI_SendCC(DEFAULT, Chn1, 0x10 + pin, pin_value >> 5);
264
#endif
1431 tk 265
}
266
 
2194 tk 267
/////////////////////////////////////////////////////////////////////////////
268
// This hook is called when an AINSER pot has been moved
269
/////////////////////////////////////////////////////////////////////////////
270
static void APP_AINSER_NotifyChange(u32 module, u32 pin, u32 pin_value)
271
{
272
  // -> continue with normal AIN handler
273
  APP_AIN_NotifyChange(128 + pin, pin_value);
274
}
1431 tk 275
 
2194 tk 276
 
1431 tk 277
/////////////////////////////////////////////////////////////////////////////
278
// This task is called periodically each mS to check for keyboard MIDI events
279
/////////////////////////////////////////////////////////////////////////////
280
static void TASK_Period_1mS(void *pvParameters)
281
{
282
  portTickType xLastExecutionTime;
283
 
284
  // Initialise the xLastExecutionTime variable on task entry
285
  xLastExecutionTime = xTaskGetTickCount();
286
 
287
  while( 1 ) {
288
    vTaskDelayUntil(&xLastExecutionTime, 1 / portTICK_RATE_MS);
289
 
290
    // skip delay gap if we had to wait for more than 5 ticks to avoid
291
    // unnecessary repeats until xLastExecutionTime reached xTaskGetTickCount() again
292
    portTickType xCurrentTickCount = xTaskGetTickCount();
293
    if( xLastExecutionTime < (xCurrentTickCount-5) )
294
      xLastExecutionTime = xCurrentTickCount;
295
 
296
    // -> keyboard handler
297
    KEYBOARD_Periodic_1mS();
298
 
299
    // MIDI In/Out monitor
300
    // TODO: call from low-prio task
1492 tk 301
    MIDI_PORT_Period1mS();
1776 tk 302
 
303
    // update AINs with current value
304
    // the keyboard driver will only send events on value changes
305
    {
306
      int pin;
307
 
2195 tk 308
      for(pin=0; pin<8; ++pin) {
1911 tk 309
    KEYBOARD_AIN_NotifyChange(pin, MIOS32_AIN_PinGet(pin));
1776 tk 310
      }
311
    }
1431 tk 312
  }
313
}
314
 
315
/////////////////////////////////////////////////////////////////////////////
316
// Installed via MIOS32_MIDI_DirectRxCallback_Init
317
/////////////////////////////////////////////////////////////////////////////
318
static s32 NOTIFY_MIDI_Rx(mios32_midi_port_t port, u8 midi_byte)
319
{
320
  // filter MIDI In port which controls the MIDI clock
1492 tk 321
  if( MIDI_ROUTER_MIDIClockInGet(port) == 1 ) {
1431 tk 322
   // SEQ_BPM_NotifyMIDIRx(midi_byte);
323
  }
324
 
325
  return 0; // no error, no filtering
326
}
327
 
328
/////////////////////////////////////////////////////////////////////////////
329
// Installed via MIOS32_MIDI_DirectTxCallback_Init
330
/////////////////////////////////////////////////////////////////////////////
331
static s32 NOTIFY_MIDI_Tx(mios32_midi_port_t port, mios32_midi_package_t package)
332
{
1492 tk 333
  return MIDI_PORT_NotifyMIDITx(port, package);
1431 tk 334
}
335
 
336
/////////////////////////////////////////////////////////////////////////////
337
// Installed via MIOS32_MIDI_TimeoutCallback_Init
338
/////////////////////////////////////////////////////////////////////////////
339
static s32 NOTIFY_MIDI_TimeOut(mios32_midi_port_t port)
340
{
341
  // forward to SysEx parser
342
  // MBKB_SYSEX_TimeOut(port);
343
 
344
  // print message on screen
345
  //SCS_Msg(SCS_MSG_L, 2000, "MIDI Protocol", "TIMEOUT !!!");
346
 
347
  return 0;
348
}