Subversion Repositories svn.mios32

Rev

Rev 1905 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1334 tk 1
// $Id: tasks.c 1906 2014-01-01 20:57:25Z 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
 
21
#include "app.h"
22
#include "tasks.h"
23
 
24
#include <msd.h>
25
 
26
 
27
 
28
/////////////////////////////////////////////////////////////////////////////
29
// Global variables
30
/////////////////////////////////////////////////////////////////////////////
31
 
32
// for mutual exclusive SD Card access between different tasks
33
// The mutex is handled with MUTEX_SDCARD_TAKE and MUTEX_SDCARD_GIVE
34
// macros inside the application, which contain a different implementation 
35
// for emulation
36
xSemaphoreHandle xSDCardSemaphore;
37
 
38
// Mutex for MIDI IN/OUT handler
39
xSemaphoreHandle xMIDIINSemaphore;
40
xSemaphoreHandle xMIDIOUTSemaphore;
41
 
42
// Mutex for LCD access
43
xSemaphoreHandle xLCDSemaphore;
44
 
45
 
46
/////////////////////////////////////////////////////////////////////////////
47
// Local types
48
/////////////////////////////////////////////////////////////////////////////
49
 
50
typedef enum {
51
  MSD_DISABLED,
52
  MSD_INIT,
53
  MSD_READY,
54
  MSD_SHUTDOWN
55
} msd_state_t;
56
 
57
 
58
/////////////////////////////////////////////////////////////////////////////
59
// Local definitions
60
/////////////////////////////////////////////////////////////////////////////
61
 
62
#define PRIORITY_TASK_PERIOD_1mS ( tskIDLE_PRIORITY + 3 )
63
#define PRIORITY_TASK_PERIOD_1mS_LP ( tskIDLE_PRIORITY + 2 )
1905 tk 64
#define PRIORITY_TASK_PERIOD_1mS_LP2 ( tskIDLE_PRIORITY + 1 )
1334 tk 65
#define PRIORITY_TASK_PERIOD_1mS_SD ( tskIDLE_PRIORITY + 2 )
66
 
67
// local prototype of the task function
68
static void TASK_Period_1mS(void *pvParameters);
69
static void TASK_Period_1mS_LP(void *pvParameters);
1905 tk 70
static void TASK_Period_1mS_LP2(void *pvParameters);
1334 tk 71
static void TASK_Period_1mS_SD(void *pvParameters);
72
 
73
 
74
/////////////////////////////////////////////////////////////////////////////
75
// Local variables
76
/////////////////////////////////////////////////////////////////////////////
77
 
78
static volatile msd_state_t msd_state;
79
 
80
 
81
/////////////////////////////////////////////////////////////////////////////
82
// Initialize all tasks
83
/////////////////////////////////////////////////////////////////////////////
84
s32 TASKS_Init(u32 mode)
85
{
86
  // disable MSD by default (has to be enabled in SID_UI_FILE menu)
87
  msd_state = MSD_DISABLED;
88
 
89
  // create semaphores
90
  xSDCardSemaphore = xSemaphoreCreateRecursiveMutex();
91
  xMIDIINSemaphore = xSemaphoreCreateRecursiveMutex();
92
  xMIDIOUTSemaphore = xSemaphoreCreateRecursiveMutex();
1905 tk 93
  xLCDSemaphore = xSemaphoreCreateRecursiveMutex();
1334 tk 94
 
95
  // start tasks
96
  xTaskCreate(TASK_Period_1mS, (signed portCHAR *)"1mS", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_PERIOD_1mS, NULL);
1906 tk 97
  xTaskCreate(TASK_Period_1mS_LP, (signed portCHAR *)"1mS_LP", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_PERIOD_1mS_LP, NULL);
98
  xTaskCreate(TASK_Period_1mS_LP2, (signed portCHAR *)"1mS_LP2", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_PERIOD_1mS_LP2, NULL);
99
  xTaskCreate(TASK_Period_1mS_SD, (signed portCHAR *)"1mS_SD", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_PERIOD_1mS_SD, NULL);
1334 tk 100
 
101
  return 0; // no error
102
}
103
 
104
 
105
/////////////////////////////////////////////////////////////////////////////
106
// This task is called periodically each mS
107
/////////////////////////////////////////////////////////////////////////////
108
static void TASK_Period_1mS(void *pvParameters)
109
{
110
  portTickType xLastExecutionTime;
111
 
112
  // Initialise the xLastExecutionTime variable on task entry
113
  xLastExecutionTime = xTaskGetTickCount();
114
 
115
  while( 1 ) {
116
    vTaskDelayUntil(&xLastExecutionTime, 1 / portTICK_RATE_MS);
117
 
118
    // skip delay gap if we had to wait for more than 5 ticks to avoid 
119
    // unnecessary repeats until xLastExecutionTime reached xTaskGetTickCount() again
120
    portTickType xCurrentTickCount = xTaskGetTickCount();
121
    if( xLastExecutionTime < (xCurrentTickCount-5) )
122
      xLastExecutionTime = xCurrentTickCount;
123
 
124
    // continue in application hook
125
    APP_TASK_Period_1mS();
126
  }
127
}
128
 
129
 
130
/////////////////////////////////////////////////////////////////////////////
131
// This task handles the SD Card
132
/////////////////////////////////////////////////////////////////////////////
133
static void TASK_Period_1mS_SD(void *pvParameters)
134
{
135
  u8 lun_available = 0;
136
 
137
  while( 1 ) {
138
    vTaskDelay(1 / portTICK_RATE_MS);
139
 
140
    if( msd_state == MSD_DISABLED ) {
141
      APP_TASK_Period_1mS_SD();
142
    } else {
143
      // MSD driver
144
      MUTEX_SDCARD_TAKE;
145
 
146
      switch( msd_state ) {
147
      case MSD_SHUTDOWN:
148
    // switch back to USB MIDI
149
    MIOS32_USB_Init(1);
150
    msd_state = MSD_DISABLED;
151
    break;
152
 
153
      case MSD_INIT:
154
    // LUN not mounted yet
155
    lun_available = 0;
156
 
157
    // enable MSD USB driver
158
    //MUTEX_J16_TAKE;
159
    if( MSD_Init(0) >= 0 )
160
      msd_state = MSD_READY;
161
    else
162
      msd_state = MSD_SHUTDOWN;
163
    //MUTEX_J16_GIVE;
164
    break;
165
 
166
      case MSD_READY:
167
    // service MSD USB driver
168
    MSD_Periodic_mS();
169
 
170
    // this mechanism shuts down the MSD driver if SD card has been unmounted by OS
171
    if( lun_available && !MSD_LUN_AvailableGet(0) )
172
      msd_state = MSD_SHUTDOWN;
173
    else if( !lun_available && MSD_LUN_AvailableGet(0) )
174
      lun_available = 1;
175
    break;
176
      }
177
 
178
      MUTEX_SDCARD_GIVE;
179
    }
180
  }
181
}
182
 
183
/////////////////////////////////////////////////////////////////////////////
184
// This task is called periodically each mS with low priority
185
/////////////////////////////////////////////////////////////////////////////
186
static void TASK_Period_1mS_LP(void *pvParameters)
187
{
188
  while( 1 ) {
189
    // using vTaskDelay instead of vTaskDelayUntil, since a periodical execution
190
    // isn't required, and this task could be invoked too often if it was blocked
191
    // for a long time
192
    vTaskDelay(1 / portTICK_RATE_MS);
193
 
194
    // continue in application hook
195
    APP_TASK_Period_1mS_LP();
196
  }
197
}
198
 
199
 
200
/////////////////////////////////////////////////////////////////////////////
1905 tk 201
// This task is called periodically each mS with very low priority
202
/////////////////////////////////////////////////////////////////////////////
203
static void TASK_Period_1mS_LP2(void *pvParameters)
204
{
205
  while( 1 ) {
206
    // using vTaskDelay instead of vTaskDelayUntil, since a periodical execution
207
    // isn't required, and this task could be invoked too often if it was blocked
208
    // for a long time
209
    vTaskDelay(1 / portTICK_RATE_MS);
210
 
211
    // continue in application hook
212
    APP_TASK_Period_1mS_LP2();
213
  }
214
}
215
 
216
 
217
/////////////////////////////////////////////////////////////////////////////
1334 tk 218
// MSD access functions
219
/////////////////////////////////////////////////////////////////////////////
220
s32 TASK_MSD_EnableSet(u8 enable)
221
{
222
  MIOS32_IRQ_Disable();
223
  if( msd_state == MSD_DISABLED && enable ) {
224
    msd_state = MSD_INIT;
225
  } else if( msd_state == MSD_READY && !enable )
226
    msd_state = MSD_SHUTDOWN;
227
  MIOS32_IRQ_Enable();
228
 
229
  return 0; // no error
230
}
231
 
232
s32 TASK_MSD_EnableGet()
233
{
234
  return (msd_state == MSD_READY) ? 1 : 0;
235
}
236
 
237
s32 TASK_MSD_FlagStrGet(char str[5])
238
{
239
  str[0] = MSD_CheckAvailable() ? 'U' : '-';
240
  str[1] = MSD_LUN_AvailableGet(0) ? 'M' : '-';
241
  str[2] = MSD_RdLEDGet(250) ? 'R' : '-';
242
  str[3] = MSD_WrLEDGet(250) ? 'W' : '-';
243
  str[4] = 0;
244
 
245
  return 0; // no error
246
}