Subversion Repositories svn.mios32

Rev

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

Rev Author Line No. Line
141 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
 
1049 tk 21
#include "uip_task.h"
589 tk 22
 
141 tk 23
#include "tasks.h"
24
 
25
 
290 tk 26
/////////////////////////////////////////////////////////////////////////////
27
// Global variables
28
/////////////////////////////////////////////////////////////////////////////
141 tk 29
 
290 tk 30
// for mutual exclusive SD Card access between different tasks
31
// The mutex is handled with MUTEX_SDCARD_TAKE and MUTEX_SDCARD_GIVE
32
// macros inside the application, which contain a different implementation 
33
// for emulation
34
xSemaphoreHandle xSDCardSemaphore;
35
 
419 tk 36
// Mutex for MIDI IN/OUT handler
303 tk 37
xSemaphoreHandle xMIDIINSemaphore;
419 tk 38
xSemaphoreHandle xMIDIOUTSemaphore;
290 tk 39
 
353 tk 40
// Mutex for LCD access
41
xSemaphoreHandle xLCDSemaphore;
303 tk 42
 
1049 tk 43
// Mutex for J16 access (SDCard/Ethernet)
44
xSemaphoreHandle xJ16Semaphore;
353 tk 45
 
1049 tk 46
 
141 tk 47
/////////////////////////////////////////////////////////////////////////////
588 tk 48
// Local types
49
/////////////////////////////////////////////////////////////////////////////
50
 
51
 
52
/////////////////////////////////////////////////////////////////////////////
141 tk 53
// Local definitions
54
/////////////////////////////////////////////////////////////////////////////
55
 
625 tk 56
#define PRIORITY_TASK_MIDI       ( tskIDLE_PRIORITY + 4 )
57
#define PRIORITY_TASK_PERIOD1MS      ( tskIDLE_PRIORITY + 2 )
634 tk 58
#define PRIORITY_TASK_PERIOD1MS_LOW_PRIO ( tskIDLE_PRIORITY + 2 )
59
#define PRIORITY_TASK_PATTERN            ( tskIDLE_PRIORITY + 2 )
141 tk 60
 
1049 tk 61
// priority of uIP task defined in uip_task.c (-> using 3)
141 tk 62
 
1049 tk 63
 
141 tk 64
/////////////////////////////////////////////////////////////////////////////
184 tk 65
// Local Prototypes
141 tk 66
/////////////////////////////////////////////////////////////////////////////
290 tk 67
static void TASK_MIDI(void *pvParameters);
159 tk 68
static void TASK_Period1mS(void *pvParameters);
625 tk 69
static void TASK_Period1mS_LowPrio(void *pvParameters);
184 tk 70
static void TASK_Pattern(void *pvParameters);
141 tk 71
 
72
 
73
/////////////////////////////////////////////////////////////////////////////
184 tk 74
// Local variables
75
/////////////////////////////////////////////////////////////////////////////
76
 
290 tk 77
static xTaskHandle xPatternHandle;
184 tk 78
 
290 tk 79
 
184 tk 80
/////////////////////////////////////////////////////////////////////////////
141 tk 81
// Initialize all tasks
82
/////////////////////////////////////////////////////////////////////////////
83
s32 TASKS_Init(u32 mode)
84
{
1070 tk 85
  // create semaphores
86
  xSDCardSemaphore = xSemaphoreCreateRecursiveMutex();
87
  xMIDIINSemaphore = xSemaphoreCreateRecursiveMutex();
88
  xMIDIOUTSemaphore = xSemaphoreCreateRecursiveMutex();
89
  xLCDSemaphore = xSemaphoreCreateRecursiveMutex();
90
  xJ16Semaphore = xSemaphoreCreateRecursiveMutex();
91
  // TODO: here we could check for NULL and bring MBSEQ into halt state
92
 
290 tk 93
  // start tasks
2425 tk 94
  xTaskCreate(TASK_MIDI,              "MIDI",         configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_MIDI, NULL);
95
  xTaskCreate(TASK_Period1mS,         "Period1mS",    configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_PERIOD1MS, NULL);
96
  xTaskCreate(TASK_Period1mS_LowPrio, "Period1mS_LP", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_PERIOD1MS_LOW_PRIO, NULL);
97
  xTaskCreate(TASK_Pattern,           "Pattern",      configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_PATTERN, &xPatternHandle);
141 tk 98
 
1049 tk 99
  // finally init the uIP task
100
  UIP_TASK_Init(0);
101
 
141 tk 102
  return 0; // no error
103
}
104
 
105
 
106
/////////////////////////////////////////////////////////////////////////////
290 tk 107
// This task is called periodically each mS as well
108
// it handles sequencer and MIDI events
109
/////////////////////////////////////////////////////////////////////////////
110
static void TASK_MIDI(void *pvParameters)
111
{
112
  portTickType xLastExecutionTime;
113
 
114
  // Initialise the xLastExecutionTime variable on task entry
115
  xLastExecutionTime = xTaskGetTickCount();
116
 
117
  while( 1 ) {
118
    vTaskDelayUntil(&xLastExecutionTime, 1 / portTICK_RATE_MS);
119
 
637 tk 120
    // skip delay gap if we had to wait for more than 5 ticks to avoid 
121
    // unnecessary repeats until xLastExecutionTime reached xTaskGetTickCount() again
122
    portTickType xCurrentTickCount = xTaskGetTickCount();
123
    if( xLastExecutionTime < (xCurrentTickCount-5) )
124
      xLastExecutionTime = xCurrentTickCount;
125
 
1806 tk 126
    // continue in application hook
127
    SEQ_TASK_MIDI();
290 tk 128
  }
129
}
130
 
131
 
132
/////////////////////////////////////////////////////////////////////////////
141 tk 133
// This task is called periodically each mS
134
/////////////////////////////////////////////////////////////////////////////
159 tk 135
static void TASK_Period1mS(void *pvParameters)
141 tk 136
{
137
  portTickType xLastExecutionTime;
138
 
139
  // Initialise the xLastExecutionTime variable on task entry
140
  xLastExecutionTime = xTaskGetTickCount();
141
 
142
  while( 1 ) {
143
    vTaskDelayUntil(&xLastExecutionTime, 1 / portTICK_RATE_MS);
144
 
637 tk 145
    // skip delay gap if we had to wait for more than 5 ticks to avoid 
146
    // unnecessary repeats until xLastExecutionTime reached xTaskGetTickCount() again
147
    portTickType xCurrentTickCount = xTaskGetTickCount();
148
    if( xLastExecutionTime < (xCurrentTickCount-5) )
149
      xLastExecutionTime = xCurrentTickCount;
150
 
141 tk 151
    // continue in application hook
152
    SEQ_TASK_Period1mS();
153
  }
154
}
159 tk 155
 
156
 
157
/////////////////////////////////////////////////////////////////////////////
625 tk 158
// This task is called periodically each mS with low priority
159
/////////////////////////////////////////////////////////////////////////////
160
static void TASK_Period1mS_LowPrio(void *pvParameters)
161
{
1234 tk 162
  u16 ms_ctr = 0;
163
 
625 tk 164
  while( 1 ) {
637 tk 165
    // using vTaskDelay instead of vTaskDelayUntil, since a periodical execution
166
    // isn't required, and this task could be invoked too often if it was blocked
167
    // for a long time
168
    vTaskDelay(1 / portTICK_RATE_MS);
625 tk 169
 
170
    // continue in application hook
171
    SEQ_TASK_Period1mS_LowPrio();
172
 
1234 tk 173
    // 1 second task
174
    if( ++ms_ctr >= 1000 ) {
175
      ms_ctr = 0;
176
      // continue in application hook
177
      SEQ_TASK_Period1S();
178
    }
159 tk 179
  }
180
}
184 tk 181
 
290 tk 182
 
184 tk 183
/////////////////////////////////////////////////////////////////////////////
184
// This task is triggered from SEQ_PATTERN_Change to transport the new patch
185
// into RAM
186
/////////////////////////////////////////////////////////////////////////////
187
static void TASK_Pattern(void *pvParameters)
188
{
189
  do {
190
    // suspend task - will be resumed from SEQ_PATTERN_Change()
191
    vTaskSuspend(NULL);
192
 
193
    SEQ_TASK_Pattern();
194
  } while( 1 );
195
}
196
 
197
// use this function to resume the task
198
void SEQ_TASK_PatternResume(void)
199
{
588 tk 200
  vTaskResume(xPatternHandle);
184 tk 201
}
588 tk 202
 
203
 
204
/////////////////////////////////////////////////////////////////////////////
1049 tk 205
// functions to access J16 semaphore
206
// see also mios32_config.h
207
/////////////////////////////////////////////////////////////////////////////
208
void TASKS_J16SemaphoreTake(void)
209
{
1806 tk 210
  if( xJ16Semaphore != NULL )
1123 tk 211
    MUTEX_J16_TAKE;
1049 tk 212
}
213
 
214
void TASKS_J16SemaphoreGive(void)
215
{
1806 tk 216
  if( xJ16Semaphore != NULL )
1123 tk 217
    MUTEX_J16_GIVE;
1049 tk 218
}
1311 tk 219
 
220
 
221
/////////////////////////////////////////////////////////////////////////////
222
// functions to access MIDI IN/Out Mutex
223
// see also mios32_config.h
224
/////////////////////////////////////////////////////////////////////////////
225
void TASKS_MUTEX_MIDIOUT_Take(void) { MUTEX_MIDIOUT_TAKE; }
226
void TASKS_MUTEX_MIDIOUT_Give(void) { MUTEX_MIDIOUT_GIVE; }
227
void TASKS_MUTEX_MIDIIN_Take(void) { MUTEX_MIDIIN_TAKE; }
228
void TASKS_MUTEX_MIDIIN_Give(void) { MUTEX_MIDIIN_GIVE; }