Subversion Repositories svn.mios32

Compare Revisions

Ignore whitespace Rev 1215 → Rev 1216

/trunk/apps/quickies/csc/app.c
New file
0,0 → 1,395
// $Id$
/*
* Code is used from some MIOS32 tutorials
*
* ==========================================================================
*
* Copyright (C) 2011 Thorsten Klose (tk@midibox.org)
* Licensed for personal non-commercial use only.
* All other rights reserved.
*
* ==========================================================================
*/
 
/////////////////////////////////////////////////////////////////////////////
// Include files
/////////////////////////////////////////////////////////////////////////////
 
#include <mios32.h>
#include "app.h"
 
#include <glcd_font.h>
 
// include everything FreeRTOS related we don't understand yet ;)
#include <FreeRTOS.h>
#include <portmacro.h>
#include <task.h>
#include <queue.h>
#include <semphr.h>
 
 
/////////////////////////////////////////////////////////////////////////////
// Local definitions
/////////////////////////////////////////////////////////////////////////////
 
#define NUM_ENCODERS 40
#define NUM_MATRICES 2
 
// define priority level for MATRIX_SCAN task:
// use same priority as MIOS32 specific tasks (3)
#define PRIORITY_TASK_MATRIX_SCAN ( tskIDLE_PRIORITY + 3 )
 
// local prototype of the task function
static void TASK_MATRIX_Scan(void *pvParameters);
 
/////////////////////////////////////////////////////////////////////////////
// Local variables
/////////////////////////////////////////////////////////////////////////////
 
static u8 enc_virtual_pos[NUM_ENCODERS];
 
static u16 matrix16x16_button_row_values[NUM_MATRICES][16];
static u16 matrix16x16_button_row_changed[NUM_MATRICES][16];
 
static u8 matrix16x16_ctr;
 
// "ampelcode"
const u8 ledring_pattern[8] = {
0x01,
0x03,
0x07,
0x0f,
0x1f,
0x3f,
0x7f,
0xff,
};
 
/////////////////////////////////////////////////////////////////////////////
// Local prototypes
/////////////////////////////////////////////////////////////////////////////
static void TASK_MATRIX_Scan(void *pvParameters);
 
 
/////////////////////////////////////////////////////////////////////////////
// This hook is called after startup to initialize the application
/////////////////////////////////////////////////////////////////////////////
void APP_Init(void)
{
// initialize all LEDs
MIOS32_BOARD_LED_Init(0xffffffff);
 
// initialize rotary encoders of the same type (DETENTED2)
int enc;
for(enc=0; enc<NUM_ENCODERS; ++enc) {
#if FIRST_ENC_DIN_SR
u8 pin_sr = (FIRST_ENC_DIN_SR-1) + (enc >> 2); // each DIN SR has 4 encoders connected
u8 pin_pos = (enc & 0x3) << 1; // Pin position of first ENC channel: either 0, 2, 4 or 6
 
mios32_enc_config_t enc_config = MIOS32_ENC_ConfigGet(enc);
enc_config.cfg.type = DETENTED2; // see mios32_enc.h for available types
enc_config.cfg.sr = pin_sr;
enc_config.cfg.pos = pin_pos;
#if 1
// normal speed, incrementer either 1 or -1
enc_config.cfg.speed = NORMAL;
enc_config.cfg.speed_par = 0;
#else
// higher incrementer values on fast movements
enc_config.cfg.speed = FAST;
enc_config.cfg.speed_par = 2;
#endif
MIOS32_ENC_ConfigSet(enc, enc_config);
#endif
 
// reset virtual positions
enc_virtual_pos[enc] = 0;
}
 
matrix16x16_ctr = 0;
 
u8 mod;
for(mod=0; mod<NUM_MATRICES; ++mod) {
u8 row;
for(row=0; row<16; ++row) {
matrix16x16_button_row_values[mod][row] = 0xffff;
matrix16x16_button_row_changed[mod][row] = 0x0000;
}
}
 
// start task
xTaskCreate(TASK_MATRIX_Scan, (signed portCHAR *)"MATRIX_Scan", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_MATRIX_SCAN, NULL);
}
 
 
/////////////////////////////////////////////////////////////////////////////
// This task is running endless in background
/////////////////////////////////////////////////////////////////////////////
void APP_Background(void)
{
// print static screen
MIOS32_LCD_FontInit((u8 *)GLCD_FONT_NORMAL);
 
// clear LCD
MIOS32_LCD_Clear();
 
// endless loop - LED will flicker on each iteration
while( 1 ) {
// toggle the state of all LEDs (allows to measure the execution speed with a scope)
MIOS32_BOARD_LED_Set(0xffffffff, ~MIOS32_BOARD_LED_Get());
 
// X/Y "position" of displays (see also comments in $MIOS32_PATH/modules/app_lcd/pcd8544/README.txt)
const u8 lcd_x[8] = {0, 1, 2, 0, 1, 2, 0, 1}; // CS#0..7
const u8 lcd_y[8] = {0, 0, 0, 1, 1, 1, 2, 2};
 
u8 i;
for(i=0; i<8; ++i) {
u8 x_offset = 84*lcd_x[i];
u8 y_offset = 6*8*lcd_y[i];
 
// print text
MIOS32_LCD_GCursorSet(x_offset + 0, y_offset + 0*8);
MIOS32_LCD_PrintFormattedString(" PCD8544 #%d", i+1);
 
MIOS32_LCD_GCursorSet(x_offset + 0, y_offset + 2*8);
MIOS32_LCD_PrintString(" powered by ");
 
MIOS32_LCD_FontInit((u8 *)GLCD_FONT_BIG);
MIOS32_LCD_GCursorSet(x_offset + 0, y_offset + 3*8);
MIOS32_LCD_PrintString("MIOS");
 
MIOS32_LCD_FontInit((u8 *)GLCD_FONT_NORMAL);
MIOS32_LCD_GCursorSet(x_offset + 64, y_offset + 4*8);
MIOS32_LCD_PrintString("32");
}
}
}
 
 
/////////////////////////////////////////////////////////////////////////////
// This hook is called when a MIDI package has been received
/////////////////////////////////////////////////////////////////////////////
void APP_MIDI_NotifyPackage(mios32_midi_port_t port, mios32_midi_package_t midi_package)
{
}
 
 
/////////////////////////////////////////////////////////////////////////////
// This hook is called before the shift register chain is scanned
/////////////////////////////////////////////////////////////////////////////
void APP_SRIO_ServicePrepare(void)
{
// 2 * 16x16 Matrix DOUTs
if( ++matrix16x16_ctr >= 16 )
matrix16x16_ctr = 0;
 
u16 matrix_select = (1 << matrix16x16_ctr);
 
#if DOUT_16x16_L
MIOS32_DOUT_SRSet(DOUT_16x16_L-1, (matrix_select >> 0) & 0xff);
#endif
#if DOUT_16x16_R
MIOS32_DOUT_SRSet(DOUT_16x16_R-1, (matrix_select >> 8) & 0xff);
#endif
 
// 32x8 LED rings DOUTs
u8 enc_offset = matrix16x16_ctr % 8;
#if DOUT_LEDRINGS_CATHODES
u8 ledring_cathodes = ~(1 << enc_offset);
MIOS32_DOUT_SRSet(DOUT_LEDRINGS_CATHODES-1, ledring_cathodes);
#endif
 
#if DOUT_LEDRINGS_1_8
{
u8 pattern = ledring_pattern[enc_virtual_pos[0 + enc_offset] >> 4];
MIOS32_DOUT_SRSet(DOUT_LEDRINGS_1_8-1, pattern);
}
#endif
#if DOUT_LEDRINGS_9_16
{
u8 pattern = ledring_pattern[enc_virtual_pos[8 + enc_offset] >> 4];
MIOS32_DOUT_SRSet(DOUT_LEDRINGS_9_16-1, pattern);
}
#endif
#if DOUT_LEDRINGS_17_24
{
u8 pattern = ledring_pattern[enc_virtual_pos[16 + enc_offset] >> 4];
MIOS32_DOUT_SRSet(DOUT_LEDRINGS_17_24-1, pattern);
}
#endif
#if DOUT_LEDRINGS_25_32
{
u8 pattern = ledring_pattern[enc_virtual_pos[24 + enc_offset] >> 4];
MIOS32_DOUT_SRSet(DOUT_LEDRINGS_25_32-1, pattern);
}
#endif
 
}
 
 
/////////////////////////////////////////////////////////////////////////////
// This hook is called after the shift register chain has been scanned
/////////////////////////////////////////////////////////////////////////////
void APP_SRIO_ServiceFinish(void)
{
const u8 din_map[2*2] = {
DIN_16x16_L0,
DIN_16x16_R0,
DIN_16x16_L1,
DIN_16x16_R1
};
 
// check for DIN changes
// Note: matrix16x16_ctr was incremented before in APP_SRIO_ServicePrepare()
int selected_row = (matrix16x16_ctr-1) & 0xf;
 
// check DINs
int mod;
for(mod=0; mod<NUM_MATRICES; ++mod) {
u8 sr_ix;
for(sr_ix=0; sr_ix<2; ++sr_ix) {
int sr0 = din_map[mod+2*sr_ix + 0];
int sr1 = din_map[mod+2*sr_ix + 1];
 
u16 sr_value = 0;
if( sr0 ) {
MIOS32_DIN_SRChangedGetAndClear(sr0-1, 0xff); // ensure that change won't be propagated to normal DIN handler
sr_value |= (MIOS32_DIN_SRGet(sr0-1) << 0);
}
 
if( sr1 ) {
MIOS32_DIN_SRChangedGetAndClear(sr1-1, 0xff); // ensure that change won't be propagated to normal DIN handler
sr_value |= (MIOS32_DIN_SRGet(sr1-1) << 8);
}
 
// determine pin changes
u16 changed = sr_value ^ matrix16x16_button_row_values[mod][selected_row];
 
if( changed ) {
// add them to existing notifications
matrix16x16_button_row_changed[mod][selected_row] |= changed;
 
// store new value
matrix16x16_button_row_values[mod][selected_row] = sr_value;
}
}
}
}
 
 
/////////////////////////////////////////////////////////////////////////////
// This hook is called when a button has been toggled
// pin_value is 1 when button released, and 0 when button pressed
/////////////////////////////////////////////////////////////////////////////
void APP_DIN_NotifyToggle(u32 pin, u32 pin_value)
{
}
 
 
/////////////////////////////////////////////////////////////////////////////
// This hook is called when an encoder has been moved
// incrementer is positive when encoder has been turned clockwise, else
// it is negative
/////////////////////////////////////////////////////////////////////////////
void APP_ENC_NotifyChange(u32 encoder, s32 incrementer)
{
// increment to virtual position and ensure that the value is in range 0..127
int value = enc_virtual_pos[encoder] + incrementer;
if( value < 0 )
value = 0;
else if( value > 127 )
value = 127;
 
// only send if value has changed
if( enc_virtual_pos[encoder] != value ) {
// store new value
enc_virtual_pos[encoder] = value;
 
// send event
MIOS32_MIDI_SendCC(DEFAULT, Chn1, 0x20 + encoder, value);
}
}
 
 
/////////////////////////////////////////////////////////////////////////////
// This hook is called when a pot has been moved
/////////////////////////////////////////////////////////////////////////////
void APP_AIN_NotifyChange(u32 pin, u32 pin_value)
{
// we have 128 pots
// 8 pots assigned per channel
 
// channel
u8 chn = pin / 8;
 
// CC number
u8 cc_number = 0x10 + (pin % 8);
 
// convert 12bit value to 7bit value
u8 value_7bit = pin_value >> 5;
 
// send MIDI event
MIOS32_MIDI_SendCC(DEFAULT, chn, cc_number, value_7bit);
}
 
 
/////////////////////////////////////////////////////////////////////////////
// This task scans MATRIX pins periodically
/////////////////////////////////////////////////////////////////////////////
static void TASK_MATRIX_Scan(void *pvParameters)
{
u8 old_state[12]; // to store the state of 12 pins
u8 debounce_ctr[12]; // to store debounce delay counters
portTickType xLastExecutionTime;
 
// initialize pin state and debounce counters to inactive value
int pin;
for(pin=0; pin<12; ++pin) {
old_state[pin] = 1;
debounce_ctr[pin] = 0;
}
 
// Initialise the xLastExecutionTime variable on task entry
xLastExecutionTime = xTaskGetTickCount();
 
while( 1 ) {
vTaskDelayUntil(&xLastExecutionTime, 1 / portTICK_RATE_MS);
 
// check all shift registers for DIN pin changes
int mod;
for(mod=0; mod<NUM_MATRICES; ++mod) {
int row;
for(row=0; row<16; ++row) {
// check if there are pin changes - must be atomic!
MIOS32_IRQ_Disable();
u8 changed = matrix16x16_button_row_changed[mod][row];
matrix16x16_button_row_changed[mod][row] = 0;
MIOS32_IRQ_Enable();
 
// any pin change at this SR?
if( !changed )
continue;
 
// check all 16 pins of the SR
int sr_pin;
for(sr_pin=0; sr_pin<16; ++sr_pin)
if( changed & (1 << sr_pin) ) {
u32 pin = 16*row + sr_pin;
u8 value = (matrix16x16_button_row_values[mod][row] & (1 << sr_pin)) ? 1 : 0;
 
// decoding: 2*256 pins mapped to channel 1..16
u8 chn = pin / 16;
 
// each channel has 16 buttons
u8 note = mod*16 + 0x3c; // 0x3c is C-3
 
// velocity: 0x7f if button pressed, 0x00 if button depressed
u8 velocity = value ? 0x00 : 0x7f;
 
// send MIDI event
MIOS32_MIDI_SendNoteOn(DEFAULT, chn, note, velocity);
}
}
}
}
}
Property changes:
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: csc/app.h
===================================================================
--- csc/app.h (revision 0)
+++ csc/app.h (revision 1216)
@@ -0,0 +1,47 @@
+// $Id$
+/*
+ * Header file of application
+ *
+ * ==========================================================================
+ *
+ * Copyright (C) <year> <your name> (<your email address>)
+ * Licensed for personal non-commercial use only.
+ * All other rights reserved.
+ *
+ * ==========================================================================
+ */
+
+#ifndef _APP_H
+#define _APP_H
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Global definitions
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Global Types
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+extern void APP_Init(void);
+extern void APP_Background(void);
+extern void APP_MIDI_NotifyPackage(mios32_midi_port_t port, mios32_midi_package_t midi_package);
+extern void APP_SRIO_ServicePrepare(void);
+extern void APP_SRIO_ServiceFinish(void);
+extern void APP_DIN_NotifyToggle(u32 pin, u32 pin_value);
+extern void APP_ENC_NotifyChange(u32 encoder, s32 incrementer);
+extern void APP_AIN_NotifyChange(u32 pin, u32 pin_value);
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Export global variables
+/////////////////////////////////////////////////////////////////////////////
+
+
+#endif /* _APP_H */
/csc/app.h
Property changes:
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: csc/mios32_config.h
===================================================================
--- csc/mios32_config.h (revision 0)
+++ csc/mios32_config.h (revision 1216)
@@ -0,0 +1,80 @@
+// $Id$
+/*
+ * Local MIOS32 configuration file
+ *
+ * this file allows to disable (or re-configure) default functions of MIOS32
+ * available switches are listed in $MIOS32_PATH/modules/mios32/MIOS32_CONFIG.txt
+ *
+ */
+
+#ifndef _MIOS32_CONFIG_H
+#define _MIOS32_CONFIG_H
+
+// The boot message which is print during startup and returned on a SysEx query
+#define MIOS32_LCD_BOOT_MSG_LINE1 "CSC Controller"
+#define MIOS32_LCD_BOOT_MSG_LINE2 "(C) 2011 T.Klose"
+
+
+// AIN configuration:
+
+// bit mask to enable channels
+//
+// Pin mapping on MBHP_CORE_STM32 module:
+// 15 14 13 12 11 10 9 8
+// J16.SO J16.SI J16.SC J16.RC J5C.A11 J5C.A10 J5C.A9 J5C.A8
+// 7 6 5 4 3 2 1 0
+// J5B.A7 J5B.A6 J5B.A5 J5B.A4 J5A.A3 J5A.A2 J5A.A1 J5A.A0
+//
+// Examples:
+// mask 0x000f will enable all J5A channels
+// mask 0x00f0 will enable all J5B channels
+// mask 0x0f00 will enable all J5C channels
+// mask 0x0fff will enable all J5A/B/C channels
+// (all channels are disabled by default)
+#define MIOS32_AIN_CHANNEL_MASK 0xffff
+
+// define the deadband (min. difference to report a change to the application hook)
+// typically set to (2^(12-desired_resolution)-1)
+// e.g. for a resolution of 7 bit, it's set to (2^(12-7)-1) = (2^5 - 1) = 31
+#define MIOS32_AIN_DEADBAND 31
+
+// muxed or unmuxed mode (0..3)?
+// 0 == unmuxed mode
+// 1 == 1 mux control line -> *2 channels
+// 2 == 2 mux control line -> *4 channels
+// 3 == 3 mux control line -> *8 channels
+#define MIOS32_AIN_MUX_PINS 3
+
+// control pins to select the muxed channel
+#define MIOS32_AIN_MUX0_PIN GPIO_Pin_13 // J19.RC1
+#define MIOS32_AIN_MUX0_PORT GPIOC
+#define MIOS32_AIN_MUX1_PIN GPIO_Pin_14 // J19.RC2
+#define MIOS32_AIN_MUX1_PORT GPIOC
+#define MIOS32_AIN_MUX2_PIN GPIO_Pin_6 // J19.SC
+#define MIOS32_AIN_MUX2_PORT GPIOB
+
+
+// first SR to which encoders are connected
+// we have 40 encoders, they will allocate 1..10 (counted from 1)
+#define FIRST_ENC_DIN_SR 1
+
+// DINs of first 16x16 matrix (counted from 1)
+#define DIN_16x16_L0 11
+#define DIN_16x16_R0 12
+
+// DINs of second 16x16 matrix (counted from 1)
+#define DIN_16x16_L1 13
+#define DIN_16x16_R1 14
+
+// DOUTs of both matrices
+#define DOUT_16x16_L 1
+#define DOUT_16x16_R 2
+
+// DOUTs of LED rings
+#define DOUT_LEDRINGS_CATHODES 3
+#define DOUT_LEDRINGS_1_8 4
+#define DOUT_LEDRINGS_9_16 5
+#define DOUT_LEDRINGS_17_24 6
+#define DOUT_LEDRINGS_25_32 7
+
+#endif /* _MIOS32_CONFIG_H */
/csc/mios32_config.h
Property changes:
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: csc/Makefile
===================================================================
--- csc/Makefile (revision 0)
+++ csc/Makefile (revision 1216)
@@ -0,0 +1,57 @@
+# $Id$
+
+################################################################################
+# following setup taken from environment variables
+################################################################################
+
+PROCESSOR = $(MIOS32_PROCESSOR)
+FAMILY = $(MIOS32_FAMILY)
+BOARD = $(MIOS32_BOARD)
+
+#explicitely select PCD8544 display
+#LCD = $(MIOS32_LCD)
+LCD = pcd8544
+
+
+################################################################################
+# Source Files, include paths and libraries
+################################################################################
+
+THUMB_SOURCE = app.c
+
+# (following source stubs not relevant for Cortex M3 derivatives)
+THUMB_AS_SOURCE =
+ARM_SOURCE =
+ARM_AS_SOURCE =
+
+C_INCLUDE = -I .
+A_INCLUDE = -I .
+
+LIBS =
+
+
+################################################################################
+# Remaining variables
+################################################################################
+
+LD_FILE = $(MIOS32_PATH)/etc/ld/$(FAMILY)/$(PROCESSOR).ld
+PROJECT = project
+
+DEBUG = -g
+OPTIMIZE = -Os
+
+CFLAGS = $(DEBUG) $(OPTIMIZE)
+
+
+################################################################################
+# Include source modules via additional makefiles
+################################################################################
+
+# sources of programming model
+include $(MIOS32_PATH)/programming_models/traditional/programming_model.mk
+
+# application specific LCD driver (selected via makefile variable)
+include $(MIOS32_PATH)/modules/app_lcd/$(LCD)/app_lcd.mk
+
+# common make rules
+include $(MIOS32_PATH)/include/makefile/common.mk
/csc/Makefile
Property changes:
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property