Subversion Repositories svn.mios32

Rev

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

Rev Author Line No. Line
48 tk 1
// $Id: main.c 42 2008-09-30 21:49:43Z tk $
2
/*
3
 * Traditional Programming Model
4
 * Provides similar hooks like PIC based MIOS8 to the application
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
#include <app.h>
1657 tk 21
#ifndef MIOS32_DONT_USE_LCD
22
#include <app_lcd.h>
23
#endif
48 tk 24
 
25
#include <FreeRTOS.h>
26
#include <task.h>
27
#include <queue.h>
28
 
29
 
30
/////////////////////////////////////////////////////////////////////////////
1170 tk 31
// External Prototypes
32
/////////////////////////////////////////////////////////////////////////////
33
 
34
extern void __libc_init_array(void);  /* calls CTORS of static objects */
35
 
36
 
37
/////////////////////////////////////////////////////////////////////////////
48 tk 38
// Task Priorities
39
/////////////////////////////////////////////////////////////////////////////
40
 
244 tk 41
#define PRIORITY_TASK_HOOKS     ( tskIDLE_PRIORITY + 3 )
48 tk 42
 
43
 
44
/////////////////////////////////////////////////////////////////////////////
45
// Local prototypes
46
/////////////////////////////////////////////////////////////////////////////
244 tk 47
static void TASK_Hooks(void *pvParameters);
518 tk 48
static void TASK_MIDI_Hooks(void *pvParameters);
58 tk 49
 
90 tk 50
 
48 tk 51
/////////////////////////////////////////////////////////////////////////////
1919 tk 52
// Dummies for APP_Tick and APP_MIDI_Tick (if not used in app.c)
53
/////////////////////////////////////////////////////////////////////////////
54
 
55
__attribute__ ((weak)) void APP_Tick(void)
56
{
57
}
58
 
59
__attribute__ ((weak)) void APP_MIDI_Tick(void)
60
{
61
}
62
 
63
 
64
/////////////////////////////////////////////////////////////////////////////
48 tk 65
// Main function
66
/////////////////////////////////////////////////////////////////////////////
67
int main(void)
68
{
69
  // initialize hardware and MIOS32 modules
58 tk 70
#ifndef MIOS32_DONT_USE_SYS
48 tk 71
  MIOS32_SYS_Init(0);
58 tk 72
#endif
118 tk 73
#ifndef MIOS32_DONT_USE_DELAY
74
  MIOS32_DELAY_Init(0);
75
#endif
1910 tk 76
#ifndef MIOS32_DONT_USE_TIMESTAMP
77
  MIOS32_TIMESTAMP_Init(0);
78
#endif
506 tk 79
#ifndef MIOS32_DONT_USE_BOARD
80
  MIOS32_BOARD_Init(0);
81
#endif
358 tk 82
#ifndef MIOS32_DONT_USE_SPI
83
  MIOS32_SPI_Init(0);
84
#endif
58 tk 85
#ifndef MIOS32_DONT_USE_SRIO
48 tk 86
  MIOS32_SRIO_Init(0);
58 tk 87
#endif
88
#if !defined(MIOS32_DONT_USE_DIN) && !defined(MIOS32_DONT_USE_SRIO)
48 tk 89
  MIOS32_DIN_Init(0);
58 tk 90
#endif
91
#if !defined(MIOS32_DONT_USE_DOUT) && !defined(MIOS32_DONT_USE_SRIO)
48 tk 92
  MIOS32_DOUT_Init(0);
58 tk 93
#endif
94
#if !defined(MIOS32_DONT_USE_ENC) && !defined(MIOS32_DONT_USE_SRIO)
95
  MIOS32_ENC_Init(0);
96
#endif
92 tk 97
#if !defined(MIOS32_DONT_USE_MF)
98
  MIOS32_MF_Init(0);
99
#endif
90 tk 100
#if !defined(MIOS32_DONT_USE_AIN)
101
  MIOS32_AIN_Init(0);
102
#endif
78 tk 103
#ifndef MIOS32_DONT_USE_IIC_BS
104
  MIOS32_IIC_BS_Init(0);
105
#endif
100 tk 106
#ifndef MIOS32_DONT_USE_USB
107
  MIOS32_USB_Init(0);
108
#endif
58 tk 109
#ifndef MIOS32_DONT_USE_MIDI
110 tk 110
  MIOS32_MIDI_Init(0);
58 tk 111
#endif
380 tk 112
#ifndef MIOS32_DONT_USE_OSC
113
  MIOS32_OSC_Init(0);
114
#endif
100 tk 115
#ifndef MIOS32_DONT_USE_COM
110 tk 116
  MIOS32_COM_Init(0);
100 tk 117
#endif
58 tk 118
#ifndef MIOS32_DONT_USE_LCD
48 tk 119
  MIOS32_LCD_Init(0);
1311 tk 120
 
1934 tk 121
# if defined(MIOS32_BOARD_MBHP_CORE_STM32) || defined(MIOS32_BOARD_MBHP_CORE_LPC17) || defined(MIOS32_BOARD_STM32F4DISCOVERY) || defined(MIOS32_BOARD_MBHP_CORE_STM32F4)
1311 tk 122
  // init second LCD as well (if available)
123
  MIOS32_LCD_DeviceSet(1);
1657 tk 124
  APP_LCD_Init(0);
1311 tk 125
  MIOS32_LCD_DeviceSet(0);
126
# endif
58 tk 127
#endif
113 tk 128
#ifdef MIOS32_USE_I2S
129
  MIOS32_I2S_Init(0);
130
#endif
48 tk 131
 
1168 tk 132
  // call C++ constructors
133
  __libc_init_array();
134
 
48 tk 135
  // initialize application
136
  APP_Init();
137
 
495 tk 138
#if MIOS32_LCD_BOOT_MSG_DELAY
229 tk 139
  // print boot message
495 tk 140
# ifndef MIOS32_DONT_USE_LCD
229 tk 141
  MIOS32_LCD_PrintBootMessage();
495 tk 142
# endif
229 tk 143
 
495 tk 144
  // wait for given delay (usually 2 seconds)
145
# ifndef MIOS32_DONT_USE_DELAY
229 tk 146
  int delay = 0;
495 tk 147
  for(delay=0; delay<MIOS32_LCD_BOOT_MSG_DELAY; ++delay)
229 tk 148
    MIOS32_DELAY_Wait_uS(1000);
495 tk 149
# endif
229 tk 150
#endif
151
 
244 tk 152
  // start the task which calls the application hooks
153
  xTaskCreate(TASK_Hooks, (signed portCHAR *)"Hooks", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_HOOKS, NULL);
518 tk 154
#if !defined(MIOS32_DONT_USE_MIDI)
1744 tk 155
  xTaskCreate(TASK_MIDI_Hooks, (signed portCHAR *)"MIDI_Hooks", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_HOOKS, NULL);
518 tk 156
#endif
48 tk 157
 
158
  // start the scheduler
159
  vTaskStartScheduler();
160
 
161
  // Will only get here if there was not enough heap space to create the idle task
162
  return 0;
163
}
164
 
165
 
166
/////////////////////////////////////////////////////////////////////////////
167
// Application Tick Hook (called by FreeRTOS each mS)
168
/////////////////////////////////////////////////////////////////////////////
169
void SRIO_ServiceFinish(void)
170
{
58 tk 171
#ifndef MIOS32_DONT_USE_SRIO
172
 
173
# ifndef MIOS32_DONT_USE_ENC
174
  // update encoder states
175
  MIOS32_ENC_UpdateStates();
176
# endif
177
 
48 tk 178
  // notify application about finished SRIO scan
179
  APP_SRIO_ServiceFinish();
58 tk 180
#endif
48 tk 181
}
182
 
183
void vApplicationTickHook(void)
184
{
1910 tk 185
#if !defined(MIOS32_DONT_USE_TIMESTAMP)
186
  MIOS32_TIMESTAMP_Inc();
187
#endif
188
 
1086 tk 189
#if !defined(MIOS32_DONT_USE_SRIO) && !defined(MIOS32_DONT_SERVICE_SRIO_SCAN)
48 tk 190
  // notify application about SRIO scan start
191
  APP_SRIO_ServicePrepare();
192
 
193
  // start next SRIO scan - IRQ notification to SRIO_ServiceFinish()
194
  MIOS32_SRIO_ScanStart(SRIO_ServiceFinish);
58 tk 195
#endif
48 tk 196
}
197
 
198
 
199
/////////////////////////////////////////////////////////////////////////////
200
// Idle Hook (called by FreeRTOS when nothing else to do)
201
/////////////////////////////////////////////////////////////////////////////
202
void vApplicationIdleHook(void)
203
{
1744 tk 204
  APP_Background();
48 tk 205
}
206
 
207
 
208
/////////////////////////////////////////////////////////////////////////////
518 tk 209
// MIDI task (separated from TASK_Hooks() to ensure parallel handling of
210
// MIDI events if a hook in TASK_Hooks() blocks)
211
/////////////////////////////////////////////////////////////////////////////
212
#if !defined(MIOS32_DONT_USE_MIDI)
213
static void TASK_MIDI_Hooks(void *pvParameters)
214
{
215
  portTickType xLastExecutionTime;
216
 
217
  // Initialise the xLastExecutionTime variable on task entry
218
  xLastExecutionTime = xTaskGetTickCount();
219
 
220
  while( 1 ) {
221
    vTaskDelayUntil(&xLastExecutionTime, 1 / portTICK_RATE_MS);
222
 
636 tk 223
    // skip delay gap if we had to wait for more than 5 ticks to avoid 
224
    // unnecessary repeats until xLastExecutionTime reached xTaskGetTickCount() again
225
    portTickType xCurrentTickCount = xTaskGetTickCount();
226
    if( xLastExecutionTime < (xCurrentTickCount-5) )
227
      xLastExecutionTime = xCurrentTickCount;
228
 
528 tk 229
    // handle timeout/expire counters and USB packages
230
    MIOS32_MIDI_Periodic_mS();
518 tk 231
 
674 tk 232
    // check for incoming MIDI packages and call hook
233
    MIOS32_MIDI_Receive_Handler(APP_MIDI_NotifyPackage);
1919 tk 234
 
235
    // optional application specific hook
236
    // helps to save memory (re-use the TASK_Hooks for other purposes...)
237
    APP_MIDI_Tick();
518 tk 238
  }
239
}
240
#endif
241
 
242
 
243
/////////////////////////////////////////////////////////////////////////////
244 tk 244
// Remaining application hooks
48 tk 245
/////////////////////////////////////////////////////////////////////////////
244 tk 246
static void TASK_Hooks(void *pvParameters)
48 tk 247
{
248
  portTickType xLastExecutionTime;
249
 
250
  // Initialise the xLastExecutionTime variable on task entry
251
  xLastExecutionTime = xTaskGetTickCount();
252
 
253
  while( 1 ) {
254
    vTaskDelayUntil(&xLastExecutionTime, 1 / portTICK_RATE_MS);
255
 
636 tk 256
    // skip delay gap if we had to wait for more than 5 ticks to avoid 
257
    // unnecessary repeats until xLastExecutionTime reached xTaskGetTickCount() again
258
    portTickType xCurrentTickCount = xTaskGetTickCount();
259
    if( xLastExecutionTime < (xCurrentTickCount-5) )
260
      xLastExecutionTime = xCurrentTickCount;
261
 
244 tk 262
#if !defined(MIOS32_DONT_USE_DIN) && !defined(MIOS32_DONT_USE_SRIO)
90 tk 263
    // check for DIN pin changes, call APP_DIN_NotifyToggle on each toggled pin
48 tk 264
    MIOS32_DIN_Handler(APP_DIN_NotifyToggle);
58 tk 265
 
266
    // check for encoder changes, call APP_ENC_NotifyChanged on each change
267
# ifndef MIOS32_DONT_USE_ENC
268
    MIOS32_ENC_Handler(APP_ENC_NotifyChange);
269
# endif
270
#endif
48 tk 271
 
1960 tk 272
#if !defined(MIOS32_DONT_USE_AIN) && !defined(MIOS32_DONT_SERVICE_AIN)
90 tk 273
    // check for AIN pin changes, call APP_AIN_NotifyChange on each pin change
274
    MIOS32_AIN_Handler(APP_AIN_NotifyChange);
275
#endif
276
 
244 tk 277
#if !defined(MIOS32_DONT_USE_COM)
674 tk 278
    // check for incoming COM messages
279
    MIOS32_COM_Receive_Handler();
244 tk 280
#endif
1660 tk 281
 
282
    // optional APP_Tick() hook
283
    // helps to save memory (re-use the TASK_Hooks for other purposes...)
284
    APP_Tick();
100 tk 285
  }
286
}
735 tk 287
 
288
 
289
 
290
/////////////////////////////////////////////////////////////////////////////
1111 tk 291
// This function aborts any operations, but keeps MIDI alive (for uploading
292
// a new firmware)
293
// If MIDI isn't enabled, the status LED will be flashed
735 tk 294
/////////////////////////////////////////////////////////////////////////////
1111 tk 295
void _abort(void)
735 tk 296
{
297
#ifndef MIOS32_DONT_USE_MIDI
736 tk 298
  // keep MIDI alive, so that program code can be updated
299
  u32 delay_ctr = 0;
300
  while( 1 ) {
1170 tk 301
    ++delay_ctr;
736 tk 302
 
1170 tk 303
    if( (delay_ctr % 100) == 0 ) {
736 tk 304
      // handle timeout/expire counters and USB packages
305
      MIOS32_MIDI_Periodic_mS();
306
    }
307
 
308
    // check for incoming MIDI packages and call hook
309
    MIOS32_MIDI_Receive_Handler(APP_MIDI_NotifyPackage);
310
 
1170 tk 311
    if( (delay_ctr % 10000) == 0 ) {
312
      // toggle board LED
313
      MIOS32_BOARD_LED_Set(1, ~MIOS32_BOARD_LED_Get());
314
    }
736 tk 315
  }
316
#else
317
  u32 delay_ctr = 0;
318
  while( 1 ) {
1170 tk 319
    ++delay_ctr;
736 tk 320
 
1170 tk 321
    if( (delay_ctr % 1000000) == 0 ) {
736 tk 322
      // toggle board LED
323
      MIOS32_BOARD_LED_Set(1, ~MIOS32_BOARD_LED_Get());
324
    }
325
  }
735 tk 326
#endif
327
}
1111 tk 328
 
329
 
330
/////////////////////////////////////////////////////////////////////////////
331
// enabled in FreeRTOSConfig.h
332
/////////////////////////////////////////////////////////////////////////////
333
void vApplicationMallocFailedHook(void)
334
{
335
#ifndef MIOS32_DONT_USE_LCD
336
  // TODO: here we should select the normal font - but only if available!
337
  // MIOS32_LCD_FontInit((u8 *)GLCD_FONT_NORMAL);
338
  MIOS32_LCD_BColourSet(0xffffff);
339
  MIOS32_LCD_FColourSet(0x000000);
340
 
341
  MIOS32_LCD_DeviceSet(0);
342
  MIOS32_LCD_Clear();
343
  MIOS32_LCD_CursorSet(0, 0);
344
  MIOS32_LCD_PrintString("FATAL: FreeRTOS "); // 16 chars
345
  MIOS32_LCD_CursorSet(0, 1);
346
  MIOS32_LCD_PrintString("Malloc Error!!! "); // 16 chars
347
#endif
348
 
349
#ifndef MIOS32_DONT_USE_MIDI
350
  // Note: message won't be sent if MIDI task cannot be created!
351
  MIOS32_MIDI_SendDebugMessage("FATAL: FreeRTOS Malloc Error!!!\n");
352
#endif
353
 
354
  _abort();
355
}
356
 
357
 
358
/////////////////////////////////////////////////////////////////////////////
359
// _exit() for newer newlib versions
360
/////////////////////////////////////////////////////////////////////////////
1114 tk 361
void exit(int par)
1111 tk 362
{
363
#ifndef MIOS32_DONT_USE_LCD
364
  // TODO: here we should select the normal font - but only if available!
365
  // MIOS32_LCD_FontInit((u8 *)GLCD_FONT_NORMAL);
366
  MIOS32_LCD_BColourSet(0xffffff);
367
  MIOS32_LCD_FColourSet(0x000000);
368
 
369
  MIOS32_LCD_DeviceSet(0);
370
  MIOS32_LCD_Clear();
371
  MIOS32_LCD_CursorSet(0, 0);
372
  MIOS32_LCD_PrintString("Goodbye!");
373
#endif
374
 
375
#ifndef MIOS32_DONT_USE_MIDI
376
  // Note: message won't be sent if MIDI task cannot be created!
377
  MIOS32_MIDI_SendDebugMessage("Goodbye!\n");
378
#endif
379
 
380
  // pro forma: since this is a noreturn function, loop endless and call _abort (which will never exit)
381
  while( 1 )
382
    _abort();
383
}
1168 tk 384
 
385
// see http://www.linuxquestions.org/questions/programming-9/fyi-shared-libs-and-iostream-c-331113/
386
void *__dso_handle = NULL;
1170 tk 387
 
388
 
389
/////////////////////////////////////////////////////////////////////////////
390
// Customized HardFault Handler which prints out debugging informations
391
/////////////////////////////////////////////////////////////////////////////
392
void HardFault_Handler_c(unsigned int * hardfault_args)
393
{
394
  // from the book: "The definiteve guide to the ARM Cortex-M3"
395
  volatile unsigned int stacked_r0;
396
  volatile unsigned int stacked_r1;
397
  volatile unsigned int stacked_r2;
398
  volatile unsigned int stacked_r3;
399
  volatile unsigned int stacked_r12;
400
  volatile unsigned int stacked_lr;
401
  volatile unsigned int stacked_pc;
402
  volatile unsigned int stacked_psr;
403
 
404
  stacked_r0 = ((unsigned long) hardfault_args[0]);
405
  stacked_r1 = ((unsigned long) hardfault_args[1]);
406
  stacked_r2 = ((unsigned long) hardfault_args[2]);
407
  stacked_r3 = ((unsigned long) hardfault_args[3]);
408
 
409
  stacked_r12 = ((unsigned long) hardfault_args[4]);
410
  stacked_lr = ((unsigned long) hardfault_args[5]);
411
  stacked_pc = ((unsigned long) hardfault_args[6]);
412
  stacked_psr = ((unsigned long) hardfault_args[7]);
413
 
1908 tk 414
  MIOS32_MIDI_SendDebugMessage("Hard Fault PC = %08x\n", stacked_pc); // ensure that at least the PC will be sent
1170 tk 415
  MIOS32_MIDI_SendDebugMessage("==================\n");
416
  MIOS32_MIDI_SendDebugMessage("!!! HARD FAULT !!!\n");
417
  MIOS32_MIDI_SendDebugMessage("==================\n");
418
  MIOS32_MIDI_SendDebugMessage("R0 = %08x\n", stacked_r0);
419
  MIOS32_MIDI_SendDebugMessage("R1 = %08x\n", stacked_r1);
420
  MIOS32_MIDI_SendDebugMessage("R2 = %08x\n", stacked_r2);
421
  MIOS32_MIDI_SendDebugMessage("R3 = %08x\n", stacked_r3);
422
  MIOS32_MIDI_SendDebugMessage("R12 = %08x\n", stacked_r12);
423
  MIOS32_MIDI_SendDebugMessage("LR = %08x\n", stacked_lr);
424
  MIOS32_MIDI_SendDebugMessage("PC = %08x\n", stacked_pc);
425
  MIOS32_MIDI_SendDebugMessage("PSR = %08x\n", stacked_psr);
426
  MIOS32_MIDI_SendDebugMessage("BFAR = %08x\n", (*((volatile unsigned long *)(0xE000ED38))));
427
  MIOS32_MIDI_SendDebugMessage("CFSR = %08x\n", (*((volatile unsigned long *)(0xE000ED28))));
428
  MIOS32_MIDI_SendDebugMessage("HFSR = %08x\n", (*((volatile unsigned long *)(0xE000ED2C))));
429
  MIOS32_MIDI_SendDebugMessage("DFSR = %08x\n", (*((volatile unsigned long *)(0xE000ED30))));
430
  MIOS32_MIDI_SendDebugMessage("AFSR = %08x\n", (*((volatile unsigned long *)(0xE000ED3C))));
431
 
432
#ifndef MIOS32_DONT_USE_LCD
433
  // TODO: here we should select the normal font - but only if available!
434
  // MIOS32_LCD_FontInit((u8 *)GLCD_FONT_NORMAL);
435
  MIOS32_LCD_BColourSet(0xffffff);
436
  MIOS32_LCD_FColourSet(0x000000);
437
 
438
  MIOS32_LCD_DeviceSet(0);
439
  MIOS32_LCD_Clear();
440
  MIOS32_LCD_CursorSet(0, 0);
441
  MIOS32_LCD_PrintString("!! HARD FAULT !!");
1240 tk 442
  MIOS32_LCD_CursorSet(0, 1);
443
  MIOS32_LCD_PrintFormattedString("at PC=0x%08x", stacked_pc);
1170 tk 444
#endif
445
 
446
  _abort();
447
}
448
 
449
 
450
void HardFault_Handler(void)
451
{
452
  __asm("TST LR, #4");
453
  __asm("ITE EQ");
454
  __asm("MRSEQ R0, MSP");
455
  __asm("MRSNE R0, PSP");
456
  __asm("B HardFault_Handler_c");
457
}
458
 
1534 tk 459
// used if configCHECK_FOR_STACK_OVERFLOW enabled (set to 1 or 2) in FreeRTOSConfig.h
460
#if configCHECK_FOR_STACK_OVERFLOW
461
void vApplicationStackOverflowHook(xTaskHandle xTask, signed portCHAR *pcTaskName)
462
{
463
  MIOS32_MIDI_SendDebugMessage("======================\n");
464
  MIOS32_MIDI_SendDebugMessage("!!! STACK OVERFLOW !!!\n");
465
  MIOS32_MIDI_SendDebugMessage("======================\n");
466
  MIOS32_MIDI_SendDebugMessage("Function: %s\n", pcTaskName);
467
 
468
#ifndef MIOS32_DONT_USE_LCD
469
  // TODO: here we should select the normal font - but only if available!
470
  // MIOS32_LCD_FontInit((u8 *)GLCD_FONT_NORMAL);
471
  MIOS32_LCD_BColourSet(0xffffff);
472
  MIOS32_LCD_FColourSet(0x000000);
473
 
474
  MIOS32_LCD_DeviceSet(0);
475
  MIOS32_LCD_Clear();
476
  MIOS32_LCD_CursorSet(0, 0);
477
  MIOS32_LCD_PrintString("!! STACK OVERFLOW !!");
478
  MIOS32_LCD_CursorSet(0, 1);
479
  MIOS32_LCD_PrintFormattedString("in Task %s", pcTaskName);
480
#endif
481
 
482
  _abort();
483
}
484
#endif
485