Subversion Repositories svn.mios32

Rev

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

Rev Author Line No. Line
795 tk 1
// $Id: tasks.c 2425 2016-11-03 00:44:22Z tk $
2
/*
3
 * FreeRTOS Tasks
4
 * only used by MIOS32 build, as a Cocoa based Task handling is used on MacOS
5
 *
6
 * ==========================================================================
7
 *
8
 *  Copyright (C) 2008 Thorsten Klose (tk@midibox.org)
9
 *  Licensed for personal non-commercial use only.
10
 *  All other rights reserved.
11
 *
12
 * ==========================================================================
13
 */
14
 
15
/////////////////////////////////////////////////////////////////////////////
16
// Include files
17
/////////////////////////////////////////////////////////////////////////////
18
 
19
#include <mios32.h>
20
 
838 tk 21
#include "app.h"
795 tk 22
#include "tasks.h"
23
 
1165 tk 24
#if USE_MSD
25
#include <msd.h>
26
#endif
795 tk 27
 
1165 tk 28
 
29
 
795 tk 30
/////////////////////////////////////////////////////////////////////////////
31
// Global variables
32
/////////////////////////////////////////////////////////////////////////////
33
 
34
// for mutual exclusive SD Card access between different tasks
35
// The mutex is handled with MUTEX_SDCARD_TAKE and MUTEX_SDCARD_GIVE
36
// macros inside the application, which contain a different implementation 
37
// for emulation
38
xSemaphoreHandle xSDCardSemaphore;
39
 
40
// Mutex for MIDI IN/OUT handler
41
xSemaphoreHandle xMIDIINSemaphore;
42
xSemaphoreHandle xMIDIOUTSemaphore;
43
 
44
// Mutex for LCD access
45
xSemaphoreHandle xLCDSemaphore;
46
 
47
 
48
/////////////////////////////////////////////////////////////////////////////
49
// Local types
50
/////////////////////////////////////////////////////////////////////////////
51
 
1165 tk 52
#if USE_MSD
795 tk 53
typedef enum {
54
  MSD_DISABLED,
55
  MSD_INIT,
56
  MSD_READY,
57
  MSD_SHUTDOWN
58
} msd_state_t;
1165 tk 59
#endif
795 tk 60
 
61
 
62
/////////////////////////////////////////////////////////////////////////////
63
// Local definitions
64
/////////////////////////////////////////////////////////////////////////////
65
 
66
#define PRIORITY_TASK_PERIOD1MS      ( tskIDLE_PRIORITY + 2 )
67
#define PRIORITY_TASK_PERIOD1MS_LOW_PRIO ( tskIDLE_PRIORITY + 2 )
68
#define PRIORITY_TASK_PERIOD1S       ( tskIDLE_PRIORITY + 2 )
1165 tk 69
 
70
#if USE_MSD
795 tk 71
#define PRIORITY_TASK_MSD        ( tskIDLE_PRIORITY + 3 )
1165 tk 72
#endif
795 tk 73
 
74
 
75
/////////////////////////////////////////////////////////////////////////////
76
// Local Prototypes
77
/////////////////////////////////////////////////////////////////////////////
78
static void TASK_Period1mS(void *pvParameters);
79
static void TASK_Period1mS_LowPrio(void *pvParameters);
80
static void TASK_Period1S(void *pvParameters);
1165 tk 81
 
82
#if USE_MSD
795 tk 83
static void TASK_MSD(void *pvParameters);
1165 tk 84
#endif
795 tk 85
 
86
 
87
/////////////////////////////////////////////////////////////////////////////
88
// Local variables
89
/////////////////////////////////////////////////////////////////////////////
90
 
1165 tk 91
#if USE_MSD
795 tk 92
static msd_state_t msd_state;
93
static xTaskHandle xMSDHandle;
1165 tk 94
#endif
795 tk 95
 
96
 
97
/////////////////////////////////////////////////////////////////////////////
98
// Initialize all tasks
99
/////////////////////////////////////////////////////////////////////////////
100
s32 TASKS_Init(u32 mode)
101
{
1165 tk 102
#if USE_MSD
801 tk 103
  // disable MSD by default (has to be enabled in SID_UI_FILE menu)
1118 tk 104
  msd_state = MSD_DISABLED;
1165 tk 105
#endif
795 tk 106
 
107
  // start tasks
2425 tk 108
  xTaskCreate(TASK_Period1mS,         "Period1mS",    configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_PERIOD1MS, NULL);
109
  xTaskCreate(TASK_Period1mS_LowPrio, "Period1mS_LP", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_PERIOD1MS_LOW_PRIO, NULL);
110
  xTaskCreate(TASK_Period1S,          "Period1S",     configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_PERIOD1S, NULL);
1165 tk 111
#if USE_MSD
2425 tk 112
  xTaskCreate(TASK_MSD,               "MSD",          configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_MSD, &xMSDHandle);
1165 tk 113
#endif
795 tk 114
 
115
  // create semaphores
116
  xSDCardSemaphore = xSemaphoreCreateRecursiveMutex();
117
  xMIDIINSemaphore = xSemaphoreCreateRecursiveMutex();
118
  xMIDIOUTSemaphore = xSemaphoreCreateRecursiveMutex();
119
  xLCDSemaphore = xSemaphoreCreateRecursiveMutex();
120
  // TODO: here we could check for NULL and bring MBSEQ into halt state
121
 
122
  return 0; // no error
123
}
124
 
125
 
126
/////////////////////////////////////////////////////////////////////////////
127
// This task is called periodically each mS
128
/////////////////////////////////////////////////////////////////////////////
129
static void TASK_Period1mS(void *pvParameters)
130
{
131
  portTickType xLastExecutionTime;
132
 
133
  // Initialise the xLastExecutionTime variable on task entry
134
  xLastExecutionTime = xTaskGetTickCount();
135
 
136
  while( 1 ) {
137
    vTaskDelayUntil(&xLastExecutionTime, 1 / portTICK_RATE_MS);
138
 
139
    // skip delay gap if we had to wait for more than 5 ticks to avoid 
140
    // unnecessary repeats until xLastExecutionTime reached xTaskGetTickCount() again
141
    portTickType xCurrentTickCount = xTaskGetTickCount();
142
    if( xLastExecutionTime < (xCurrentTickCount-5) )
143
      xLastExecutionTime = xCurrentTickCount;
144
 
145
    // continue in application hook
801 tk 146
    SID_TASK_Period1mS();
795 tk 147
  }
148
}
149
 
150
 
151
/////////////////////////////////////////////////////////////////////////////
152
// This task is called periodically each mS with low priority
153
/////////////////////////////////////////////////////////////////////////////
154
static void TASK_Period1mS_LowPrio(void *pvParameters)
155
{
156
  while( 1 ) {
157
    // using vTaskDelay instead of vTaskDelayUntil, since a periodical execution
158
    // isn't required, and this task could be invoked too often if it was blocked
159
    // for a long time
160
    vTaskDelay(1 / portTICK_RATE_MS);
161
 
162
    // continue in application hook
801 tk 163
    SID_TASK_Period1mS_LowPrio();
795 tk 164
  }
165
}
166
 
167
 
168
/////////////////////////////////////////////////////////////////////////////
169
// This task is called periodically each second
170
/////////////////////////////////////////////////////////////////////////////
171
static void TASK_Period1S(void *pvParameters)
172
{
173
  while( 1 ) {
174
    // using vTaskDelay instead of vTaskDelayUntil, since a periodical execution
175
    // isn't required, and this task could be invoked too often if it was blocked
176
    // for a long time
177
    vTaskDelay(1000 / portTICK_RATE_MS);
178
 
179
    // continue in application hook
801 tk 180
    SID_TASK_Period1S();
795 tk 181
  }
182
}
183
 
184
 
1165 tk 185
#if USE_MSD
795 tk 186
/////////////////////////////////////////////////////////////////////////////
187
// This task is called periodically each mS when USB MSD access is enabled
188
/////////////////////////////////////////////////////////////////////////////
189
static void TASK_MSD(void *pvParameters)
190
{
191
  u8 lun_available = 0;
192
 
193
  while( 1 ) {
194
    // using vTaskDelay instead of vTaskDelayUntil, since a periodical execution
195
    // isn't required, and this task could be invoked too often if it was blocked
196
    // for a long time
197
    vTaskDelay(1 / portTICK_RATE_MS);
198
 
199
 
200
    // MSD driver handling
1118 tk 201
    if( msd_state != MSD_DISABLED ) {
795 tk 202
      MUTEX_SDCARD_TAKE;
203
 
204
      switch( msd_state ) {
205
        case MSD_SHUTDOWN:
206
      // switch back to USB MIDI
207
      MIOS32_USB_Init(1);
1118 tk 208
      msd_state = MSD_DISABLED;
795 tk 209
      MUTEX_SDCARD_GIVE;
210
      vTaskSuspend(NULL); // will be resumed from TASK_MSD_EnableSet()
211
      MUTEX_SDCARD_TAKE;
212
      break;
213
 
214
        case MSD_INIT:
215
      // LUN not mounted yet
216
      lun_available = 0;
217
 
218
      // enable MSD USB driver
219
      if( MSD_Init(0) >= 0 )
220
        msd_state = MSD_READY;
221
      else
222
        msd_state = MSD_SHUTDOWN;
223
      break;
224
 
225
        case MSD_READY:
226
      // service MSD USB driver
227
      MSD_Periodic_mS();
228
 
229
      // this mechanism shuts down the MSD driver if SD card has been unmounted by OS
230
      if( lun_available && !MSD_LUN_AvailableGet(0) )
231
        msd_state = MSD_SHUTDOWN;
232
      else if( !lun_available && MSD_LUN_AvailableGet(0) )
233
        lun_available = 1;
234
      break;
235
      }
236
 
237
      MUTEX_SDCARD_GIVE;
238
    }
239
  }
240
}
241
 
242
 
243
// MSD access functions
244
s32 TASK_MSD_EnableSet(u8 enable)
245
{
246
  MIOS32_IRQ_Disable();
247
  if( msd_state == MSD_DISABLED && enable ) {
248
    msd_state = MSD_INIT;
249
    vTaskResume(xMSDHandle);
250
  } else if( msd_state == MSD_READY && !enable )
251
    msd_state = MSD_SHUTDOWN;
252
  MIOS32_IRQ_Enable();
253
 
254
  return 0; // no error
255
}
256
 
257
s32 TASK_MSD_EnableGet()
258
{
259
  return (msd_state == MSD_READY) ? 1 : 0;
260
}
261
 
262
s32 TASK_MSD_FlagStrGet(char str[5])
263
{
264
  str[0] = MSD_CheckAvailable() ? 'U' : '-';
265
  str[1] = MSD_LUN_AvailableGet(0) ? 'M' : '-';
266
  str[2] = MSD_RdLEDGet(250) ? 'R' : '-';
267
  str[3] = MSD_WrLEDGet(250) ? 'W' : '-';
268
  str[4] = 0;
269
 
270
  return 0; // no error
271
}
1165 tk 272
#endif