Rev 163 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
163 | tk | 1 | HEADER 3 MIOS C Example |
2 | |||
3 | <H3>Sending 14bit NRPN Events on Rotary Encoder movements</H3> |
||
4 | |||
5 | <P CLASS=INFO>We want to send absolute 14bit values on encoder movements in following format: <I>NRPN <low:encoder> <high:00> <LSB:value & 0x7f> <MSB:value >> 7></I>.</P> |
||
6 | |||
7 | <P CLASS=INFO>Copy the SDCC skeleton into a new directory, open the main.c file and enhance the hooks like described below. Thereafter type "make" in the command shell, and upload the new project.hex file to the core.</P> |
||
8 | |||
9 | <P CLASS=INFO>At the top of the main.c file, we have to specify an array of "unsigned int" (16bit values) which hold the absolute value:</P> |
||
10 | |||
11 | <TT><PRE> |
||
12 | // absolute values are stored in this array |
||
13 | unsigned int enc_value[8]; |
||
14 | </PRE></TT> |
||
15 | |||
16 | <P CLASS=INFO>Within the Init() function, you have to specify, how many shift registers are connected to the core, and which encoder speed mode should be taken:</P> |
||
17 | |||
18 | <TT><PRE> |
||
19 | ///////////////////////////////////////////////////////////////////////////// |
||
20 | // This function is called by MIOS after startup to initialize the |
||
21 | // application |
||
22 | ///////////////////////////////////////////////////////////////////////////// |
||
23 | void Init(void) __wparam |
||
24 | { |
||
25 | unsigned char i; |
||
26 | |||
27 | // set shift register update frequency |
||
28 | MIOS_SRIO_UpdateFrqSet(1); // ms |
||
29 | |||
30 | // we need to set at least one IO shift register pair |
||
31 | MIOS_SRIO_NumberSet(16); // for 128 pins |
||
32 | |||
33 | // set speed mode for 8 encoders |
||
34 | for(i=0; i<8; ++i) { |
||
35 | // available speed modes: SLOW, NORMAL and FAST |
||
36 | MIOS_ENC_SpeedSet(i, MIOS_ENC_SPEED_FAST, 7); // encoder, speed mode, divider |
||
37 | } |
||
38 | } |
||
39 | </PRE></TT> |
||
40 | |||
41 | <P CLASS=INFO>We add the code which should be executed on rotary encoder movements to the ENC_NotifyChange() function. It increments/decrements the absolute value depending on the encoder turn direction and sends the new value over the MIDI interface, if it has been changed:</P> |
||
42 | |||
43 | <TT><PRE> |
||
44 | ///////////////////////////////////////////////////////////////////////////// |
||
45 | // This function is called by MIOS when an encoder has been moved |
||
46 | // incrementer is positive when encoder has been turned clockwise, else |
||
47 | // it is negative |
||
48 | ///////////////////////////////////////////////////////////////////////////// |
||
49 | void ENC_NotifyChange(unsigned char encoder, char incrementer) __wparam |
||
50 | { |
||
51 | unsigned int value; |
||
52 | |||
53 | // do nothing if encoder number greater than array size |
||
54 | if( encoder >= sizeof(enc_value) ) |
||
55 | return; |
||
56 | |||
57 | // add incrementer to absolute 16bit value by using a MIOS help function |
||
58 | value = enc_value[encoder]; |
||
59 | if( MIOS_HLP_16bitAddSaturate(incrementer, &value, 0x3fff) ) { |
||
60 | // store new value and send it |
||
61 | enc_value[encoder] = value; |
||
62 | |||
63 | MIOS_MIDI_TxBufferPut(0xb0); // NRPN CC at MIDI Channel #1 |
||
64 | MIOS_MIDI_TxBufferPut(0x62); // NRPN# LSB |
||
65 | MIOS_MIDI_TxBufferPut(encoder); |
||
66 | MIOS_MIDI_TxBufferPut(0x63); // NRPN# MSB |
||
67 | MIOS_MIDI_TxBufferPut(0x00); |
||
68 | MIOS_MIDI_TxBufferPut(0x26); // NRPN Data LSB |
||
69 | MIOS_MIDI_TxBufferPut((unsigned char)(value & 0x7f)); |
||
70 | MIOS_MIDI_TxBufferPut(0x06); // NRPN Data MSB |
||
71 | MIOS_MIDI_TxBufferPut((unsigned char)((value >> 7) & 0x7f)); |
||
72 | } |
||
73 | } |
||
74 | </PRE></TT> |
||
75 | |||
76 | |||
878 | tk | 77 | <P CLASS=INFO>The pins to which the encoders are connected must be specified in MIOS_ENC_TABLE, which can be placed at the top of your main.c file:</P> |
163 | tk | 78 | |
79 | <TT><PRE> |
||
878 | tk | 80 | MIOS_ENC_TABLE { |
81 | // sr pin mode |
||
82 | MIOS_ENC_ENTRY( 1, 0, MIOS_ENC_MODE_NON_DETENTED), // V-Pot 1 |
||
83 | MIOS_ENC_ENTRY( 1, 2, MIOS_ENC_MODE_NON_DETENTED), // V-Pot 2 |
||
84 | MIOS_ENC_ENTRY( 1, 4, MIOS_ENC_MODE_NON_DETENTED), // V-Pot 3 |
||
85 | MIOS_ENC_ENTRY( 1, 6, MIOS_ENC_MODE_NON_DETENTED), // V-Pot 4 |
||
86 | MIOS_ENC_ENTRY( 2, 0, MIOS_ENC_MODE_NON_DETENTED), // V-Pot 5 |
||
87 | MIOS_ENC_ENTRY( 2, 2, MIOS_ENC_MODE_NON_DETENTED), // V-Pot 6 |
||
88 | MIOS_ENC_ENTRY( 2, 4, MIOS_ENC_MODE_NON_DETENTED), // V-Pot 7 |
||
89 | MIOS_ENC_ENTRY( 2, 6, MIOS_ENC_MODE_NON_DETENTED), // V-Pot 8 |
||
90 | |||
91 | MIOS_ENC_EOT |
||
92 | }; |
||
163 | tk | 93 | </PRE></TT> |
94 | |||
878 | tk | 95 | <P CLASS=INFO><B>IMPORTANT:</B> the default encoder table has to be disabled in the <B>Makefile</B> via -DDONT_INCLUDE_MIOS_ENC_TABLE. You could add this define to the MIOS_WRAPPER_DEFINES variable:</P> |
96 | <TT><PRE> |
||
97 | MIOS_WRAPPER_DEFINES = -DSTACK_HEAD=0x37f -DSTACK_IRQ_HEAD=0x33f -DDONT_INCLUDE_MIOS_ENC_TABLE |
||
98 | </PRE></TT> |
||
99 | |||
163 | tk | 100 | <P CLASS=INFO>A list of available MIOS function can be found <A HREF="cmios_fun.html">here</A>.</P> |
101 | |||
102 | FOOTER |