Subversion Repositories svn.mios32

Rev

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

Rev Author Line No. Line
810 philetaylo 1
// $Id: app.c 346 2009-02-10 22:10:39Z tk $
2
/*
3
 * Demo application for DMX Controller.
4
 * It used a DOG GLCD but could be adapted for any LCD.
5
 * It has 2 banks of 12 faders (BANK A and BANKB)
6
 * Plus 2 master faders (MASTER A and MASTER B
7
 * It is currently just a simple 12 channel desk
8
 *
9
 * ==========================================================================
10
 *
11
 *  Copyright (C) 2008 Thorsten Klose (tk@midibox.org)
12
 *  Licensed for personal non-commercial use only.
13
 *  All other rights reserved.
14
 *
15
 * ==========================================================================
16
 */
17
 
18
/////////////////////////////////////////////////////////////////////////////
19
// Include files
20
/////////////////////////////////////////////////////////////////////////////
21
 
22
#include <mios32.h>
23
#include <math.h>
24
#include <FreeRTOS.h>
25
#include <portmacro.h>
26
#include <task.h>
27
#include <semphr.h>
28
 
29
#include "app.h"
30
#include "dmx.h"
31
#include "fs.h"
32
#include <glcd_font.h>
33
#include <uwindows.h>
34
#include <uip.h>
35
#include <uip_arp.h>
36
#include <timer.h>
37
#include "dhcpc.h"
38
#include "osc_client.h"
39
 
40
// Mutex for controlling access to SDCARD/ENC28J60
41
xSemaphoreHandle xSPI0Semaphore;   
42
 
43
#define PRIORITY_TASK_CHASE               ( tskIDLE_PRIORITY + 4 ) // lowest priority
44
#define DEBUG_VERBOSE_LEVEL 0
45
static UW_Window    FaderForm;
46
static UW_Window    SubmasterForm;
47
static UW_Window    ConfigForm;
48
static UW_Window    LabelName,LabelHome,LabelMob,LabelEmail;
49
static UW_Window    EditName,EditHome,EditMob,EditEmail;
50
static UW_Window    BtnOk,BtnCancel;
51
 
52
 
53
static UW_Window    LightsBtn,LightsLabel;
54
static UW_Window    Faders[26];
55
static UW_Window    Submasters[26];
56
static const char IconCaption[]="   MIDIbox Lights";
57
static const char FaderCaption[]="   Faders View";
58
static const char SubmasterCaption[]="Submaster View";
59
static const char ConfigCaption[]="SSSSSTTTTT";
60
static char LabelCaption[] = "Hello UWindows!";
61
static char BtnCaption[]= "Show/Hide";
62
 
63
static void TASK_CHASE(void *pvParameters);
64
const char Labels[]="AccountName:Home:Mob:Email:MaleSingleOkCancel";
65
u8 banka[12];
66
u8 bankb[12];
67
u8 sub[24];
68
u8 mastera, masterb;
69
u8 current_state;
70
u8 uip_configured=0;
71
static struct timer periodic_timer,arp_timer;
72
 
73
// Initialize all views
74
void Views_Init(void)
75
{
76
    u8 f;
77
    /////////////////////////////////////////////////////////
78
    //FADER_VIEW
79
    /////////////////////////////////////////////////////////
80
    UW_Add(&FaderForm, UW_FORM, &UWindows, NULL);
81
    /* Set Form caption */
82
    UW_SetCaption(&FaderForm, FaderCaption, 22);
83
    /* Display the Form in Main Window  */
84
    UW_SetFont(&FaderForm, GLCD_FONT_NORMAL);
85
    UW_SetVisible(&FaderForm, 1);
86
    for (f=0;f<12;f++) {
87
        UW_Add(&Faders[f],UW_FADER, &FaderForm, NULL);
88
        UW_SetPosition(&Faders[f], (f*10)+10,50);
89
        UW_Add(&Faders[f+12],UW_FADER, &FaderForm, NULL);
90
        UW_SetPosition(&Faders[f+12], (f*10)+10,10);
91
    }
92
    // Master faders
93
    UW_Add(&Faders[24],UW_FADER, &FaderForm, NULL);
94
    UW_Add(&Faders[25],UW_FADER, &FaderForm, NULL);
95
    UW_SetPosition(&Faders[24], 140,30);
96
    UW_SetPosition(&Faders[25], 150,30);
97
    // Get current fader values
98
    for (f=0;f<26;f++)
99
        UW_SetValue(&Faders[f],MIOS32_AIN_PinGet(f)>>4);
100
    /////////////////////////////////////////////////////////
101
    //SUBMASTER_VIEW
102
    /////////////////////////////////////////////////////////
103
    UW_Add(&SubmasterForm, UW_FORM, &UWindows, NULL);
104
    /* Set Form caption */
105
    UW_SetCaption(&SubmasterForm, SubmasterCaption, 22);
106
    /* Hide the Form in Main Window */
107
    UW_SetVisible(&SubmasterForm, 0);
108
    for (f=0;f<12;f++) {
109
        UW_Add(&Submasters[f],UW_FADER, &SubmasterForm, NULL);
110
        UW_SetPosition(&Submasters[f], (f*10)+10,50);
111
        UW_Add(&Submasters[f+12],UW_FADER, &SubmasterForm, NULL);
112
        UW_SetPosition(&Submasters[f+12], (f*10)+10,10);
113
    }
114
    // Master faders
115
    UW_Add(&Submasters[24],UW_FADER, &SubmasterForm, NULL);
116
    UW_Add(&Submasters[25],UW_FADER, &SubmasterForm, NULL);
117
    UW_SetPosition(&Submasters[24], 140,30);
118
    UW_SetPosition(&Submasters[25], 150,30);
119
    // Get current fader values
120
    for (f=0;f<26;f++)
121
        UW_SetValue(&Submasters[f],0);
122
 
123
    /////////////////////////////////////////////////////////
124
    //CONFIG_VIEW
125
    /////////////////////////////////////////////////////////
126
    UW_Add(&ConfigForm, UW_FORM, &UWindows, NULL);
127
    /* Set Form caption */
128
    UW_SetCaption(&ConfigForm, ConfigCaption, 10);
129
    /* Hide the Form in Main Window */
130
    UW_SetVisible(&ConfigForm, 0);
131
    UW_SetFont(&ConfigForm, GLCD_FONT_BIG);
132
 
133
}
134
 
135
 
136
 
137
/////////////////////////////////////////////////////////////////////////////
138
// This hook is called after startup to initialize the application
139
/////////////////////////////////////////////////////////////////////////////
140
void APP_Init(void)
141
{
142
    MIOS32_BOARD_LED_Init(0xffffffff); // initialize all LEDs
143
    current_state=FADER_VIEW;
144
    UW_Init();
145
    DMX_Init(0);
146
    Views_Init();
147
    // MUST be initialized before the SPI functions
148
    xSPI0Semaphore = xSemaphoreCreateMutex();
149
 
150
    FS_Init(0);
151
    // start uIP task
152
    UIP_TASK_Init(0);
153
 
2425 tk 154
    xTaskCreate(TASK_CHASE, "CHASE", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_CHASE, NULL);
810 philetaylo 155
}
156
 
157
void Check_Faders(void)
158
{
159
    u8 f;
160
    for (f=0;f<24;f++)
161
    {
162
        if (f<12) {
163
            if (Faders[f].value!=banka[f]) {
164
                banka[f]=Faders[f].value;
165
                int q=(((banka[f]*mastera)/255)|((bankb[f]*(u8)~masterb)/255));
166
                DMX_SetChannel(f,(u8)q);
167
                //MIOS32_MIDI_SendDebugMessage("Channel: %d = %d (Fader: %d = %d)\n",f,(u8)q,f,banka[f]);
168
            }
169
        } else if (f>=12){
170
            if (Faders[f].value!=bankb[f-12]) {
171
                bankb[f-12]=Faders[f].value;
172
                int q=(((banka[f-12]*mastera)/255)|((bankb[f-12]*(u8)~masterb)/255));
173
                DMX_SetChannel(f-12,(u8)q);
174
                //MIOS32_MIDI_SendDebugMessage("Channel: %d = %d (Fader: %d = %d)\n",f,(u8)q,f,bankb[f-12]);
175
            }
176
        }
177
    }
178
}
179
 
180
void Check_Submasters(void)
181
{
182
    u8 f;
183
    for (f=0;f<24;f++)
184
    {
185
        if (f<12) {
186
            if (Faders[f].value!=banka[f]) {
187
                banka[f]=Faders[f].value;
188
                int q=(((banka[f]*mastera)>>8)|((bankb[f]*(u8)~masterb)>>8));
189
                DMX_SetChannel(f,(u8)q);
190
                //MIOS32_MIDI_SendDebugMessage("Channel: %d = %d\n",f,(u8)q);
191
            }
192
        } else if (f>=12){
193
            if (Faders[f].value!=bankb[f-12]) {
194
                bankb[f-12]=Faders[f].value;
195
                int q=(((banka[f-12]*mastera)>>8)|((bankb[f-12]*(u8)~masterb)>>8));
196
                DMX_SetChannel(f-12,(u8)q);
197
                //MIOS32_MIDI_SendDebugMessage("Channel: %d = %d\n",f-12,(u8)q);
198
            }
199
        }
200
    }
201
}
202
 
203
/////////////////////////////////////////////////////////////////////////////
204
// This task is running endless in background
205
/////////////////////////////////////////////////////////////////////////////
206
void APP_Background(void)
207
{
208
    u32 g;
209
    u8 temp_mastera, temp_masterb;
210
 
211
    // endless loop
212
    while( 1 )
213
    {
214
        UW_Run();   // Do any outstanding window function.
215
        if (current_state==FADER_VIEW) {
216
            Check_Faders(); // Scan all of the faders and update the DMX value if faders have moved.
217
            temp_mastera=Faders[24].value;
218
            temp_masterb=Faders[25].value;
219
        } else if (current_state==SUBMASTER_VIEW) {
220
            Check_Submasters(); // Scan all of the faders and update the DMX value if faders have moved.
221
            temp_mastera=Submasters[24].value;
222
            temp_masterb=Submasters[25].value;
223
        }
224
        // Master faders are always live!
225
        if ((temp_mastera!=mastera) || (temp_masterb!=masterb)) {
226
            // If either of the master faders have moved, we must recalculate the whole universe.
227
            mastera=temp_mastera;
228
            masterb=temp_masterb;
229
            MIOS32_MIDI_SendDebugMessage("Master A = %d  Master B = %d\n",mastera,(u8)~masterb);
230
            for(g=0; g<12; g++) {
231
                u8 q=(((banka[g]*mastera)>>8)|((bankb[g]*(u8)~masterb)>>8));
232
                if (DMX_GetChannel(g) != q)
233
                    DMX_SetChannel(g,(u8)q);
234
            }
235
        }
236
    }
237
}
238
 
239
 
240
/////////////////////////////////////////////////////////////////////////////
241
// This hook is called when a MIDI package has been received
242
/////////////////////////////////////////////////////////////////////////////
243
void APP_MIDI_NotifyPackage(mios32_midi_port_t port, mios32_midi_package_t midi_package)
244
{
245
}
246
 
247
 
248
/////////////////////////////////////////////////////////////////////////////
249
// This hook is called before the shift register chain is scanned
250
/////////////////////////////////////////////////////////////////////////////
251
void APP_SRIO_ServicePrepare(void)
252
{
253
}
254
 
255
 
256
/////////////////////////////////////////////////////////////////////////////
257
// This hook is called after the shift register chain has been scanned
258
/////////////////////////////////////////////////////////////////////////////
259
void APP_SRIO_ServiceFinish(void)
260
{
261
}
262
 
263
 
264
/////////////////////////////////////////////////////////////////////////////
265
// This hook is called when a button has been toggled
266
// pin_value is 1 when button released, and 0 when button pressed
267
/////////////////////////////////////////////////////////////////////////////
268
void APP_DIN_NotifyToggle(u32 pin, u32 pin_value)
269
{
270
    u32 temp_state=current_state;
271
    if (pin_value==0) { // Button Pressed   
272
        if (pin==0)
273
            current_state--;
274
        else if (pin==1)
275
            current_state++;
276
        switch (current_state) {
277
            case FADER_VIEW:
278
                UW_SetVisible(&ConfigForm, 0);
279
                UW_SetVisible(&SubmasterForm, 0);
280
                UW_SetVisible(&FaderForm, 1);
281
                break;
282
            case SUBMASTER_VIEW:
283
                UW_SetVisible(&FaderForm, 0);
284
                UW_SetVisible(&ConfigForm, 0);
285
                UW_SetVisible(&SubmasterForm, 1);
286
                break;
287
            case CONFIG_VIEW:
288
                UW_SetVisible(&FaderForm, 0);
289
                UW_SetVisible(&ConfigForm, 1);
290
                UW_SetVisible(&SubmasterForm, 0);
291
                break;
292
            default:
293
                current_state=temp_state;
294
        }
295
    }
296
    UW_Keypress(pin, pin_value);
297
}
298
 
299
 
300
/////////////////////////////////////////////////////////////////////////////
301
// This hook is called when an encoder has been moved
302
// incrementer is positive when encoder has been turned clockwise, else
303
// it is negative
304
/////////////////////////////////////////////////////////////////////////////
305
void APP_ENC_NotifyChange(u32 encoder, s32 incrementer)
306
{
307
}
308
 
309
 
310
/////////////////////////////////////////////////////////////////////////////
311
// This hook is called when a pot has been moved
312
/////////////////////////////////////////////////////////////////////////////
313
void APP_AIN_NotifyChange(u32 pin, u32 pin_value)
314
{  
315
    pin=((pin%4)<<3)+(pin>>2);  // change muxed pin order.
316
 
317
        pin_value=pin_value>>4;
318
    if (current_state==FADER_VIEW) {
319
        if (pin<26)
320
            UW_SetValue(&Faders[pin],pin_value);
321
    } else if (current_state==SUBMASTER_VIEW) {
322
        if (pin<26)
323
            UW_SetValue(&Submasters[pin],pin_value);
324
    }
325
 
326
    if (uip_configured) // UIP Is active and working!
327
    {
328
#if DEBUG_VERBOSE_LEVEL >= 1
329
        MIOS32_MIDI_SendDebugMessage("[AIN] %d %d\n", pin, pin_value);
330
#endif
331
        // send AIN value as OSC message
332
        mios32_osc_timetag_t timetag;
333
        timetag.seconds = 0;
334
        timetag.fraction = 1;
335
        OSC_CLIENT_SendPotValue(timetag, pin, (float)pin_value / 255.0);
336
 
337
    }
338
 
339
}
340
 
341
/////////////////////////////////////////////////////////////////////////////
342
// This task is called periodically each mS to handle chases
343
/////////////////////////////////////////////////////////////////////////////
344
static void TASK_CHASE(void *pvParameters)
345
{
346
  portTickType xLastExecutionTime;
347
  u8 sdcard_available = 0;
348
  int sdcard_check_ctr = 0;
349
  MIOS32_MIDI_SendDebugMessage("About to initialize SDCard Reader\n");
350
 
351
  // initialize SD Card
352
  MIOS32_SDCARD_Init(0);
353
 
354
  // Initialise the xLastExecutionTime variable on task entry
355
  xLastExecutionTime = xTaskGetTickCount();
356
 
357
  while( 1 ) {
358
    vTaskDelayUntil(&xLastExecutionTime, 1 / portTICK_RATE_MS);
359
 
360
#if 1
361
 
362
    // each second: check if SD card (still) available
363
    if( ++sdcard_check_ctr >= 1000 ) {
364
      sdcard_check_ctr = 0;
365
 
366
      // check if SD card is available
367
      // High-speed access if SD card was previously available
368
      u8 prev_sdcard_available = sdcard_available;
369
      sdcard_available = MIOS32_SDCARD_CheckAvailable(prev_sdcard_available);
370
 
371
      if( sdcard_available && !prev_sdcard_available ) {
372
        MIOS32_MIDI_SendDebugMessage("SD Card has been connected!\n");
373
 
374
        s32 status;
375
        if( (status=FS_mount_fs()) < 0 ) {
376
          MIOS32_MIDI_SendDebugMessage("File system cannot be mounted, status: %d\n", status);
377
        } //else {
378
 
379
        // }
380
      } else if( !sdcard_available && prev_sdcard_available ) {
381
        MIOS32_MIDI_SendDebugMessage("SD Card has been disconnected!\n");
382
 
383
      }
384
    }
385
#endif
386
 
387
  }
388
}
389
 
390
 
391
void APP_MutexSPI0Take(void)
392
{
393
    // This must block as we aren't telling the calling process that the semaphore couldn't be obtained!
394
    while( xSemaphoreTake(xSPI0Semaphore, (portTickType)1) != pdTRUE );
395
    //MIOS32_MIDI_SendDebugMessage("Semaphore taken\n");
396
 
397
 
398
    /*s32 ret=pdFALSE;
399
    while (ret!=pdTRUE) {  
400
    if (xSemaphoreTake(xSPI0Semaphore, (portTickType)portTICK_RATE_MS*1000) != pdTRUE);
401
        MIOS32_MIDI_SendDebugMessage("Semaphore (SPI0) not released in 1 second *HELP*\n");
402
    }*/
403
 
404
    return;
405
}
406
 
407
 
408
void APP_MutexSPI0Give(void)
409
{
410
    xSemaphoreGive(xSPI0Semaphore);
411
    //MIOS32_MIDI_SendDebugMessage("Semaphore given\n");
412
 
413
    return;
414
}
415
 
416
 
417
void dhcpc_configured(const struct dhcpc_state *s)
418
{  
419
    MIOS32_MIDI_SendDebugMessage("Got IP address %d.%d.%d.%d\n",
420
        uip_ipaddr1(s->ipaddr), uip_ipaddr2(s->ipaddr),
421
        uip_ipaddr3(s->ipaddr), uip_ipaddr4(s->ipaddr));
422
    MIOS32_MIDI_SendDebugMessage("Got netmask %d.%d.%d.%d\n",
423
        uip_ipaddr1(s->netmask), uip_ipaddr2(s->netmask),
424
        uip_ipaddr3(s->netmask), uip_ipaddr4(s->netmask));
425
    MIOS32_MIDI_SendDebugMessage("Got DNS server %d.%d.%d.%d\n",
426
        uip_ipaddr1(s->dnsaddr), uip_ipaddr2(s->dnsaddr),
427
        uip_ipaddr3(s->dnsaddr), uip_ipaddr4(s->dnsaddr));
428
    MIOS32_MIDI_SendDebugMessage("Got default router %d.%d.%d.%d\n",
429
        uip_ipaddr1(s->default_router), uip_ipaddr2(s->default_router),
430
        uip_ipaddr3(s->default_router), uip_ipaddr4(s->default_router));
431
    MIOS32_MIDI_SendDebugMessage("Lease expires in %d hours\n",
432
        (ntohs(s->lease_time[0])*65536ul + ntohs(s->lease_time[1]))/3600);
433
 
434
 
435
    uip_sethostaddr(s->ipaddr);
436
    uip_setnetmask(s->netmask);
437
    uip_setdraddr(s->default_router);
438
      // start telnet daemon
439
    telnetd_init(); //(now we have an IP address)
440
    // start OSC daemon and client
441
    OSC_CLIENT_Init(0);
442
    OSC_SERVER_Init(0);
443
    uip_configured=1;
2425 tk 444
}