Subversion Repositories svn.mios32

Rev

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

Rev Author Line No. Line
705 tk 1
// $Id: app.c 1920 2014-01-08 19:29:35Z tk $
2
/*
3
 * MIOS32 Tutorial #023: Exclusive access to LCD device (using a Mutex)
4
 * see README.txt for details
5
 *
6
 * ==========================================================================
7
 *
8
 *  Copyright (C) 2009 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
#include "app.h"
21
 
22
 
23
// include everything FreeRTOS related we don't understand yet ;)
24
#include <FreeRTOS.h>
25
#include <portmacro.h>
26
#include <task.h>
27
#include <queue.h>
28
#include <semphr.h>
29
 
30
 
31
// define priority levels for LCD tasks:
32
// use a lower priority as MIOS32 specific tasks (3)
33
#define PRIORITY_TASK_LCD1  ( tskIDLE_PRIORITY + 2 )
34
// use the same priority like MIOS32 specific tasks (3)
35
#define PRIORITY_TASK_LCD2  ( tskIDLE_PRIORITY + 3 )
36
 
37
// local prototype of the task functions
38
static void TASK_LCD1(void *pvParameters);
39
static void TASK_LCD2(void *pvParameters);
40
 
41
 
42
// define a Mutex for LCD access
43
xSemaphoreHandle xLCDSemaphore;
44
#define MUTEX_LCD_TAKE { while( xSemaphoreTakeRecursive(xLCDSemaphore, (portTickType)1) != pdTRUE ); }
45
#define MUTEX_LCD_GIVE { xSemaphoreGiveRecursive(xLCDSemaphore); }
46
 
47
 
48
 
49
/////////////////////////////////////////////////////////////////////////////
50
// This hook is called after startup to initialize the application
51
/////////////////////////////////////////////////////////////////////////////
52
void APP_Init(void)
53
{
54
  // initialize all LEDs
55
  MIOS32_BOARD_LED_Init(0xffffffff);
56
 
57
  // create Mutex for LCD access
58
  xLCDSemaphore = xSemaphoreCreateRecursiveMutex();
59
 
60
  // start tasks
61
  xTaskCreate(TASK_LCD1, (signed portCHAR *)"LCD1", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_LCD1, NULL);
62
  xTaskCreate(TASK_LCD2, (signed portCHAR *)"LCD2", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_LCD2, NULL);
63
}
64
 
65
 
66
/////////////////////////////////////////////////////////////////////////////
67
// This task is running endless in background
68
/////////////////////////////////////////////////////////////////////////////
69
void APP_Background(void)
70
{
71
}
72
 
73
 
74
/////////////////////////////////////////////////////////////////////////////
1919 tk 75
// This hook is called each mS from the main task which also handles DIN, ENC
76
// and AIN events. You could add more jobs here, but they shouldn't consume
77
// more than 300 uS to ensure the responsiveness of buttons, encoders, pots.
78
// Alternatively you could create a dedicated task for application specific
79
// jobs as explained in $MIOS32_PATH/apps/tutorials/006_rtos_tasks
80
/////////////////////////////////////////////////////////////////////////////
81
void APP_Tick(void)
82
{
1920 tk 83
  // PWM modulate the status LED (this is a sign of life)
84
  //u32 timestamp = MIOS32_TIMESTAMP_Get();
85
  //MIOS32_BOARD_LED_Set(1, (timestamp % 20) <= ((timestamp / 100) % 10));
1919 tk 86
}
87
 
88
 
89
/////////////////////////////////////////////////////////////////////////////
90
// This hook is called each mS from the MIDI task which checks for incoming
91
// MIDI events. You could add more MIDI related jobs here, but they shouldn't
92
// consume more than 300 uS to ensure the responsiveness of incoming MIDI.
93
/////////////////////////////////////////////////////////////////////////////
94
void APP_MIDI_Tick(void)
95
{
96
}
97
 
98
 
99
/////////////////////////////////////////////////////////////////////////////
705 tk 100
// This hook is called when a MIDI package has been received
101
/////////////////////////////////////////////////////////////////////////////
102
void APP_MIDI_NotifyPackage(mios32_midi_port_t port, mios32_midi_package_t midi_package)
103
{
104
}
105
 
106
 
107
/////////////////////////////////////////////////////////////////////////////
108
// This hook is called before the shift register chain is scanned
109
/////////////////////////////////////////////////////////////////////////////
110
void APP_SRIO_ServicePrepare(void)
111
{
112
}
113
 
114
 
115
/////////////////////////////////////////////////////////////////////////////
116
// This hook is called after the shift register chain has been scanned
117
/////////////////////////////////////////////////////////////////////////////
118
void APP_SRIO_ServiceFinish(void)
119
{
120
}
121
 
122
 
123
/////////////////////////////////////////////////////////////////////////////
124
// This hook is called when a button has been toggled
125
// pin_value is 1 when button released, and 0 when button pressed
126
/////////////////////////////////////////////////////////////////////////////
127
void APP_DIN_NotifyToggle(u32 pin, u32 pin_value)
128
{
129
}
130
 
131
 
132
/////////////////////////////////////////////////////////////////////////////
133
// This hook is called when an encoder has been moved
134
// incrementer is positive when encoder has been turned clockwise, else
135
// it is negative
136
/////////////////////////////////////////////////////////////////////////////
137
void APP_ENC_NotifyChange(u32 encoder, s32 incrementer)
138
{
139
}
140
 
141
 
142
/////////////////////////////////////////////////////////////////////////////
143
// This hook is called when a pot has been moved
144
/////////////////////////////////////////////////////////////////////////////
145
void APP_AIN_NotifyChange(u32 pin, u32 pin_value)
146
{
147
}
148
 
149
 
150
/////////////////////////////////////////////////////////////////////////////
151
// The first task which accesses the LCD
152
// (running at lower priority than MIOS32 tasks)
153
/////////////////////////////////////////////////////////////////////////////
154
static void TASK_LCD1(void *pvParameters)
155
{
156
  portTickType xLastExecutionTime;
157
 
158
  // Initialise the xLastExecutionTime variable on task entry
159
  xLastExecutionTime = xTaskGetTickCount();
160
 
161
  while( 1 ) {
162
    // called again after 500 mS
163
    vTaskDelayUntil(&xLastExecutionTime, 500 / portTICK_RATE_MS);
164
 
165
    // print an animated vertical bar
166
    // we print characters multiple times to *ensure*
167
    // many conflicts with TASK_LCD2()
168
    // (this isn't a realistic usecase, but perfectly demonstrates
169
    // the need for a Mutex)
170
 
171
    int repeat, i, j;
172
    for(i=0; i<16; ++i) {
173
      for(repeat=0; repeat<100; ++repeat) {
174
    // request LCD access
175
    MUTEX_LCD_TAKE;
176
 
177
    // print my part of the LCD screen
178
    MIOS32_LCD_CursorSet(0, 0); // X, Y
179
    for(j=0; j<16; ++j)
180
      MIOS32_LCD_PrintChar((j < i) ? '#' : ' ');
181
 
182
    // release LCD access for other tasks
183
    MUTEX_LCD_GIVE;
184
      }
185
    }
186
  }
187
}
188
 
189
 
190
/////////////////////////////////////////////////////////////////////////////
191
// The second task which accesses the LCD
192
// (running at same priority as MIOS32 tasks)
193
/////////////////////////////////////////////////////////////////////////////
194
static void TASK_LCD2(void *pvParameters)
195
{
196
  portTickType xLastExecutionTime;
197
 
198
  // Initialise the xLastExecutionTime variable on task entry
199
  xLastExecutionTime = xTaskGetTickCount();
200
 
201
  // clear LCD
202
  MIOS32_LCD_Clear();
203
 
204
  while( 1 ) {
205
    vTaskDelayUntil(&xLastExecutionTime, 1 / portTICK_RATE_MS);
206
 
207
    // print system time
208
 
209
    // request LCD access
210
    MUTEX_LCD_TAKE;
211
 
212
    // print my part of the LCD screen
213
    MIOS32_LCD_CursorSet(0, 1); // X, Y
214
    mios32_sys_time_t t = MIOS32_SYS_TimeGet();
215
    int hours = t.seconds / 3600;
216
    int minutes = (t.seconds % 3600) / 60;
217
    int seconds = (t.seconds % 3600) % 60;
218
    int milliseconds = t.fraction_ms;
219
    MIOS32_LCD_PrintFormattedString("%02d:%02d:%02d.%03d", hours, minutes, seconds, milliseconds);
220
 
221
    // release LCD access for other tasks
222
    MUTEX_LCD_GIVE;
223
  }
224
}