Radio Junk Box
/
KAMUI_USBHOST_MIDI-CV_Example
KAMUI USB HOST MIDI-CV Example based on Peter Barrett's BlueUSB
main.cpp@0:3b4e3e2ec6a5, 2012-05-11 (annotated)
- Committer:
- radiojunkbox
- Date:
- Fri May 11 15:31:59 2012 +0000
- Revision:
- 0:3b4e3e2ec6a5
Rev. 0.1 alfa
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
radiojunkbox | 0:3b4e3e2ec6a5 | 1 | //------------------------------------------------------------- |
radiojunkbox | 0:3b4e3e2ec6a5 | 2 | // KAMUI MIDI-CV Exapmple |
radiojunkbox | 0:3b4e3e2ec6a5 | 3 | // Copyright (C) 2012 RJB RadioJunkBox |
radiojunkbox | 0:3b4e3e2ec6a5 | 4 | // Released under the MIT License: http://mbed.org/license/mit |
radiojunkbox | 0:3b4e3e2ec6a5 | 5 | //------------------------------------------------------------- |
radiojunkbox | 0:3b4e3e2ec6a5 | 6 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 7 | /* |
radiojunkbox | 0:3b4e3e2ec6a5 | 8 | Copyright (c) 2010 Peter Barrett |
radiojunkbox | 0:3b4e3e2ec6a5 | 9 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy |
radiojunkbox | 0:3b4e3e2ec6a5 | 11 | of this software and associated documentation files (the "Software"), to deal |
radiojunkbox | 0:3b4e3e2ec6a5 | 12 | in the Software without restriction, including without limitation the rights |
radiojunkbox | 0:3b4e3e2ec6a5 | 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
radiojunkbox | 0:3b4e3e2ec6a5 | 14 | copies of the Software, and to permit persons to whom the Software is |
radiojunkbox | 0:3b4e3e2ec6a5 | 15 | furnished to do so, subject to the following conditions: |
radiojunkbox | 0:3b4e3e2ec6a5 | 16 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 17 | The above copyright notice and this permission notice shall be included in |
radiojunkbox | 0:3b4e3e2ec6a5 | 18 | all copies or substantial portions of the Software. |
radiojunkbox | 0:3b4e3e2ec6a5 | 19 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
radiojunkbox | 0:3b4e3e2ec6a5 | 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
radiojunkbox | 0:3b4e3e2ec6a5 | 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
radiojunkbox | 0:3b4e3e2ec6a5 | 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
radiojunkbox | 0:3b4e3e2ec6a5 | 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
radiojunkbox | 0:3b4e3e2ec6a5 | 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
radiojunkbox | 0:3b4e3e2ec6a5 | 26 | THE SOFTWARE. |
radiojunkbox | 0:3b4e3e2ec6a5 | 27 | */ |
radiojunkbox | 0:3b4e3e2ec6a5 | 28 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 29 | #include "mbed.h" |
radiojunkbox | 0:3b4e3e2ec6a5 | 30 | #include "TextLCD.h" |
radiojunkbox | 0:3b4e3e2ec6a5 | 31 | #include "USBHost.h" |
radiojunkbox | 0:3b4e3e2ec6a5 | 32 | #include "Utils.h" |
radiojunkbox | 0:3b4e3e2ec6a5 | 33 | #include "FATFileSystem.h" |
radiojunkbox | 0:3b4e3e2ec6a5 | 34 | #include <stdlib.h> |
radiojunkbox | 0:3b4e3e2ec6a5 | 35 | #include <math.h> |
radiojunkbox | 0:3b4e3e2ec6a5 | 36 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 37 | int MassStorage_ReadCapacity(int device, u32* blockCount, u32* blockSize); |
radiojunkbox | 0:3b4e3e2ec6a5 | 38 | int MassStorage_Read(int device, u32 blockAddr, u32 blockCount, u8* dst, u32 blockSize); |
radiojunkbox | 0:3b4e3e2ec6a5 | 39 | int MassStorage_Write(int device, u32 blockAddr, u32 blockCount, u8* dst, u32 blockSize); |
radiojunkbox | 0:3b4e3e2ec6a5 | 40 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 41 | class USBFileSystem : public FATFileSystem |
radiojunkbox | 0:3b4e3e2ec6a5 | 42 | { |
radiojunkbox | 0:3b4e3e2ec6a5 | 43 | int _device; |
radiojunkbox | 0:3b4e3e2ec6a5 | 44 | u32 _blockSize; |
radiojunkbox | 0:3b4e3e2ec6a5 | 45 | u32 _blockCount; |
radiojunkbox | 0:3b4e3e2ec6a5 | 46 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 47 | public: |
radiojunkbox | 0:3b4e3e2ec6a5 | 48 | USBFileSystem() : FATFileSystem("usb"),_device(0),_blockSize(0),_blockCount(0) |
radiojunkbox | 0:3b4e3e2ec6a5 | 49 | { |
radiojunkbox | 0:3b4e3e2ec6a5 | 50 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 51 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 52 | void SetDevice(int device) |
radiojunkbox | 0:3b4e3e2ec6a5 | 53 | { |
radiojunkbox | 0:3b4e3e2ec6a5 | 54 | _device = device; |
radiojunkbox | 0:3b4e3e2ec6a5 | 55 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 56 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 57 | virtual int disk_initialize() |
radiojunkbox | 0:3b4e3e2ec6a5 | 58 | { |
radiojunkbox | 0:3b4e3e2ec6a5 | 59 | return MassStorage_ReadCapacity(_device,&_blockCount,&_blockSize); |
radiojunkbox | 0:3b4e3e2ec6a5 | 60 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 61 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 62 | virtual int disk_write(const char *buffer, int block_number) |
radiojunkbox | 0:3b4e3e2ec6a5 | 63 | { |
radiojunkbox | 0:3b4e3e2ec6a5 | 64 | return MassStorage_Write(_device,block_number,1,(u8*)buffer,_blockSize); |
radiojunkbox | 0:3b4e3e2ec6a5 | 65 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 66 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 67 | virtual int disk_read(char *buffer, int block_number) |
radiojunkbox | 0:3b4e3e2ec6a5 | 68 | { |
radiojunkbox | 0:3b4e3e2ec6a5 | 69 | return MassStorage_Read(_device,block_number,1,(u8*)buffer,_blockSize); |
radiojunkbox | 0:3b4e3e2ec6a5 | 70 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 71 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 72 | virtual int disk_sectors() |
radiojunkbox | 0:3b4e3e2ec6a5 | 73 | { |
radiojunkbox | 0:3b4e3e2ec6a5 | 74 | return _blockCount; |
radiojunkbox | 0:3b4e3e2ec6a5 | 75 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 76 | }; |
radiojunkbox | 0:3b4e3e2ec6a5 | 77 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 78 | void DumpFS(int depth, int count) |
radiojunkbox | 0:3b4e3e2ec6a5 | 79 | { |
radiojunkbox | 0:3b4e3e2ec6a5 | 80 | DIR *d = opendir("/usb"); |
radiojunkbox | 0:3b4e3e2ec6a5 | 81 | if (!d) |
radiojunkbox | 0:3b4e3e2ec6a5 | 82 | { |
radiojunkbox | 0:3b4e3e2ec6a5 | 83 | printf("USB file system borked\n"); |
radiojunkbox | 0:3b4e3e2ec6a5 | 84 | return; |
radiojunkbox | 0:3b4e3e2ec6a5 | 85 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 86 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 87 | printf("\nDumping root dir\n"); |
radiojunkbox | 0:3b4e3e2ec6a5 | 88 | struct dirent *p; |
radiojunkbox | 0:3b4e3e2ec6a5 | 89 | for(;;) |
radiojunkbox | 0:3b4e3e2ec6a5 | 90 | { |
radiojunkbox | 0:3b4e3e2ec6a5 | 91 | p = readdir(d); |
radiojunkbox | 0:3b4e3e2ec6a5 | 92 | if (!p) |
radiojunkbox | 0:3b4e3e2ec6a5 | 93 | break; |
radiojunkbox | 0:3b4e3e2ec6a5 | 94 | int len = sizeof( dirent); |
radiojunkbox | 0:3b4e3e2ec6a5 | 95 | printf("%s %d\n", p->d_name, len); |
radiojunkbox | 0:3b4e3e2ec6a5 | 96 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 97 | closedir(d); |
radiojunkbox | 0:3b4e3e2ec6a5 | 98 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 99 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 100 | int OnDiskInsert(int device) |
radiojunkbox | 0:3b4e3e2ec6a5 | 101 | { |
radiojunkbox | 0:3b4e3e2ec6a5 | 102 | USBFileSystem fs; |
radiojunkbox | 0:3b4e3e2ec6a5 | 103 | fs.SetDevice(device); |
radiojunkbox | 0:3b4e3e2ec6a5 | 104 | DumpFS(0,0); |
radiojunkbox | 0:3b4e3e2ec6a5 | 105 | return 0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 106 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 107 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 108 | /* |
radiojunkbox | 0:3b4e3e2ec6a5 | 109 | Simple test shell to exercise mouse,keyboard,mass storage and hubs. |
radiojunkbox | 0:3b4e3e2ec6a5 | 110 | Add 2 15k pulldown resistors between D+/D- and ground, attach a usb socket and have at it. |
radiojunkbox | 0:3b4e3e2ec6a5 | 111 | */ |
radiojunkbox | 0:3b4e3e2ec6a5 | 112 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 113 | Serial pc(USBTX, USBRX); |
radiojunkbox | 0:3b4e3e2ec6a5 | 114 | int GetConsoleChar() |
radiojunkbox | 0:3b4e3e2ec6a5 | 115 | { |
radiojunkbox | 0:3b4e3e2ec6a5 | 116 | if (!pc.readable()) |
radiojunkbox | 0:3b4e3e2ec6a5 | 117 | return -1; |
radiojunkbox | 0:3b4e3e2ec6a5 | 118 | char c = pc.getc(); |
radiojunkbox | 0:3b4e3e2ec6a5 | 119 | pc.putc(c); // echo |
radiojunkbox | 0:3b4e3e2ec6a5 | 120 | return c; |
radiojunkbox | 0:3b4e3e2ec6a5 | 121 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 122 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 123 | //------------------------------------------------------------- |
radiojunkbox | 0:3b4e3e2ec6a5 | 124 | // Define |
radiojunkbox | 0:3b4e3e2ec6a5 | 125 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 126 | #define AD5551 // 14bitDAC |
radiojunkbox | 0:3b4e3e2ec6a5 | 127 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 128 | #define SPI_RATE 1000000 // 1Mbps |
radiojunkbox | 0:3b4e3e2ec6a5 | 129 | #define MIDI_RATE 31250 // 31.25kbps |
radiojunkbox | 0:3b4e3e2ec6a5 | 130 | #define BEEP_FREQ 1760.0 // 1760Hz |
radiojunkbox | 0:3b4e3e2ec6a5 | 131 | #define UPDATE_INTERVAL 100 // 100us |
radiojunkbox | 0:3b4e3e2ec6a5 | 132 | #define SW_WATCH_INTERVAL (25000/UPDATE_INTERVAL) // 25ms |
radiojunkbox | 0:3b4e3e2ec6a5 | 133 | #define PARAM_GLIDE 6554.0 |
radiojunkbox | 0:3b4e3e2ec6a5 | 134 | #define PARAM_DP 6912.0 // UPDATE_INTERVAL = 100us |
radiojunkbox | 0:3b4e3e2ec6a5 | 135 | //#define PARAM_DP 8192.0 // UPDATE_INTERVAL = 50us |
radiojunkbox | 0:3b4e3e2ec6a5 | 136 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 137 | #define UPDATE_MODE0 0 // Update Interval CV ch1-6 1200us, ch7,8 400us |
radiojunkbox | 0:3b4e3e2ec6a5 | 138 | #define UPDATE_MODE1 1 // Update Interval CV ch1-6 N/A, ch7,8 200us |
radiojunkbox | 0:3b4e3e2ec6a5 | 139 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 140 | #define GATE1 0x01 |
radiojunkbox | 0:3b4e3e2ec6a5 | 141 | #define GATE2 0x02 |
radiojunkbox | 0:3b4e3e2ec6a5 | 142 | #define GATE3 0x04 |
radiojunkbox | 0:3b4e3e2ec6a5 | 143 | #define GATE4 0x08 |
radiojunkbox | 0:3b4e3e2ec6a5 | 144 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 145 | #define SYNC1CLK 0x01 |
radiojunkbox | 0:3b4e3e2ec6a5 | 146 | #define SYNC1RUN 0x02 |
radiojunkbox | 0:3b4e3e2ec6a5 | 147 | #define SYNC2CLK 0x04 |
radiojunkbox | 0:3b4e3e2ec6a5 | 148 | #define SYNC2RUN 0x08 |
radiojunkbox | 0:3b4e3e2ec6a5 | 149 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 150 | #define MODE_CV 0x00 |
radiojunkbox | 0:3b4e3e2ec6a5 | 151 | #define MODE_GATE 0x40 |
radiojunkbox | 0:3b4e3e2ec6a5 | 152 | #define MODE_SYNC 0x80 |
radiojunkbox | 0:3b4e3e2ec6a5 | 153 | #define MODE_SET_SYNC 0xC0 |
radiojunkbox | 0:3b4e3e2ec6a5 | 154 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 155 | #define SW1 0x01 |
radiojunkbox | 0:3b4e3e2ec6a5 | 156 | #define SW2 0x02 |
radiojunkbox | 0:3b4e3e2ec6a5 | 157 | #define SW3 0x04 |
radiojunkbox | 0:3b4e3e2ec6a5 | 158 | #define SW4 0x08 |
radiojunkbox | 0:3b4e3e2ec6a5 | 159 | #define SYNC1CLK_IN 0x10 |
radiojunkbox | 0:3b4e3e2ec6a5 | 160 | #define SYNC1RUN_IN 0x20 |
radiojunkbox | 0:3b4e3e2ec6a5 | 161 | #define SYNC2CLK_IN 0x40 |
radiojunkbox | 0:3b4e3e2ec6a5 | 162 | #define GATE_IN 0x80 |
radiojunkbox | 0:3b4e3e2ec6a5 | 163 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 164 | #define _ENABLE 0 |
radiojunkbox | 0:3b4e3e2ec6a5 | 165 | #define _DISABLE 1 |
radiojunkbox | 0:3b4e3e2ec6a5 | 166 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 167 | #define BUFSIZE 32 // size of ring buffer (ex 4,8,16,32...) |
radiojunkbox | 0:3b4e3e2ec6a5 | 168 | #define LFO_WF_TRI 0 |
radiojunkbox | 0:3b4e3e2ec6a5 | 169 | #define LFO_WF_SQR 1 |
radiojunkbox | 0:3b4e3e2ec6a5 | 170 | #define LFO_WF_SAW 2 |
radiojunkbox | 0:3b4e3e2ec6a5 | 171 | #define LFO_WF_NONE 3 |
radiojunkbox | 0:3b4e3e2ec6a5 | 172 | #define MINIMUMNOTE 12 |
radiojunkbox | 0:3b4e3e2ec6a5 | 173 | #define SYNC_TURN_TIME (5000/UPDATE_INTERVAL) // 5ms |
radiojunkbox | 0:3b4e3e2ec6a5 | 174 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 175 | #define MENULOOP_INTERVAL 25000 // 25ms |
radiojunkbox | 0:3b4e3e2ec6a5 | 176 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 177 | //------------------------------------------------------------- |
radiojunkbox | 0:3b4e3e2ec6a5 | 178 | // Functions |
radiojunkbox | 0:3b4e3e2ec6a5 | 179 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 180 | void MenuLoop(void); |
radiojunkbox | 0:3b4e3e2ec6a5 | 181 | void InitKamui(void); |
radiojunkbox | 0:3b4e3e2ec6a5 | 182 | void UpdateCV(void); |
radiojunkbox | 0:3b4e3e2ec6a5 | 183 | unsigned char CheckSW(unsigned char); |
radiojunkbox | 0:3b4e3e2ec6a5 | 184 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 185 | void RcvMIDI(void); |
radiojunkbox | 0:3b4e3e2ec6a5 | 186 | void GetMIDI(void); |
radiojunkbox | 0:3b4e3e2ec6a5 | 187 | void MidiCV(void); |
radiojunkbox | 0:3b4e3e2ec6a5 | 188 | void CalcHzVTbl(void); |
radiojunkbox | 0:3b4e3e2ec6a5 | 189 | unsigned short OctVtoHzV(unsigned short); |
radiojunkbox | 0:3b4e3e2ec6a5 | 190 | void DinSync(void); |
radiojunkbox | 0:3b4e3e2ec6a5 | 191 | extern void MIDI_Parser(unsigned char); |
radiojunkbox | 0:3b4e3e2ec6a5 | 192 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 193 | //------------------------------------------------------------- |
radiojunkbox | 0:3b4e3e2ec6a5 | 194 | // Global Variables |
radiojunkbox | 0:3b4e3e2ec6a5 | 195 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 196 | int gUpdateMode; |
radiojunkbox | 0:3b4e3e2ec6a5 | 197 | unsigned short gCV[8]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 198 | unsigned char gGATE; |
radiojunkbox | 0:3b4e3e2ec6a5 | 199 | unsigned char gSYNC; |
radiojunkbox | 0:3b4e3e2ec6a5 | 200 | unsigned char gSW; |
radiojunkbox | 0:3b4e3e2ec6a5 | 201 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 202 | union { |
radiojunkbox | 0:3b4e3e2ec6a5 | 203 | unsigned short WORD; |
radiojunkbox | 0:3b4e3e2ec6a5 | 204 | struct { |
radiojunkbox | 0:3b4e3e2ec6a5 | 205 | unsigned char L; |
radiojunkbox | 0:3b4e3e2ec6a5 | 206 | unsigned char H; |
radiojunkbox | 0:3b4e3e2ec6a5 | 207 | } BYTE; |
radiojunkbox | 0:3b4e3e2ec6a5 | 208 | } gDAC; |
radiojunkbox | 0:3b4e3e2ec6a5 | 209 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 210 | int gPtr_buf_in, gPtr_buf_out; |
radiojunkbox | 0:3b4e3e2ec6a5 | 211 | unsigned char gRxBuf[BUFSIZE]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 212 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 213 | float gGLIDE[4]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 214 | unsigned short gLFO_DP[4]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 215 | unsigned char gLFO_FORM[4]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 216 | unsigned char gMIDI_CH[4]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 217 | short gTblHzV[3072]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 218 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 219 | extern unsigned char gPlayNoteBuf[]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 220 | extern unsigned char gGateBuf[]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 221 | extern unsigned char gPitchBendBuf[]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 222 | extern unsigned char gModWheelBuf[]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 223 | extern unsigned char gMIDISYNC_CLK; |
radiojunkbox | 0:3b4e3e2ec6a5 | 224 | extern unsigned char gMIDISYNC_RUN; |
radiojunkbox | 0:3b4e3e2ec6a5 | 225 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 226 | int pot[4],_pot[4]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 227 | unsigned char mode = 7; // for Intialize |
radiojunkbox | 0:3b4e3e2ec6a5 | 228 | unsigned char edit[4]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 229 | int val[2][4] = { 0, 0, 0, 0, 50, 50, 50, 50 }; |
radiojunkbox | 0:3b4e3e2ec6a5 | 230 | char *wave[4] = { "TR","SQ","SW","--" }; |
radiojunkbox | 0:3b4e3e2ec6a5 | 231 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 232 | //------------------------------------------------------------- |
radiojunkbox | 0:3b4e3e2ec6a5 | 233 | // mbed Functions |
radiojunkbox | 0:3b4e3e2ec6a5 | 234 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 235 | // TextLCD |
radiojunkbox | 0:3b4e3e2ec6a5 | 236 | TextLCD gLCD(p23, p24, p25, p26, p29, p30); // rs, e, d4-d7 |
radiojunkbox | 0:3b4e3e2ec6a5 | 237 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 238 | // SPI |
radiojunkbox | 0:3b4e3e2ec6a5 | 239 | SPI gSPI(p11,p12,p13); |
radiojunkbox | 0:3b4e3e2ec6a5 | 240 | DigitalOut gCSA(p14); |
radiojunkbox | 0:3b4e3e2ec6a5 | 241 | DigitalOut gCSB(p22); |
radiojunkbox | 0:3b4e3e2ec6a5 | 242 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 243 | // Sirial MIDI |
radiojunkbox | 0:3b4e3e2ec6a5 | 244 | Serial gMIDI(p9,p10); |
radiojunkbox | 0:3b4e3e2ec6a5 | 245 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 246 | // AnalogIn |
radiojunkbox | 0:3b4e3e2ec6a5 | 247 | AnalogIn gAIN1(p15); // VR1 |
radiojunkbox | 0:3b4e3e2ec6a5 | 248 | AnalogIn gAIN2(p16); // VR2 |
radiojunkbox | 0:3b4e3e2ec6a5 | 249 | AnalogIn gAIN3(p17); // VR3 |
radiojunkbox | 0:3b4e3e2ec6a5 | 250 | AnalogIn gAIN4(p18); // VR4 |
radiojunkbox | 0:3b4e3e2ec6a5 | 251 | AnalogIn gAIN5(p19); // IN1 |
radiojunkbox | 0:3b4e3e2ec6a5 | 252 | AnalogIn gAIN6(p20); // IN2 |
radiojunkbox | 0:3b4e3e2ec6a5 | 253 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 254 | // BEEP |
radiojunkbox | 0:3b4e3e2ec6a5 | 255 | PwmOut gBEEP(p21); |
radiojunkbox | 0:3b4e3e2ec6a5 | 256 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 257 | // LED |
radiojunkbox | 0:3b4e3e2ec6a5 | 258 | DigitalOut gLED1(LED1); |
radiojunkbox | 0:3b4e3e2ec6a5 | 259 | DigitalOut gLED2(LED2); |
radiojunkbox | 0:3b4e3e2ec6a5 | 260 | DigitalOut gLED3(LED3); |
radiojunkbox | 0:3b4e3e2ec6a5 | 261 | DigitalOut gLED4(LED4); |
radiojunkbox | 0:3b4e3e2ec6a5 | 262 | BusOut gLEDS(LED1,LED2,LED3,LED4); |
radiojunkbox | 0:3b4e3e2ec6a5 | 263 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 264 | // Ticker |
radiojunkbox | 0:3b4e3e2ec6a5 | 265 | Ticker gTICKER; |
radiojunkbox | 0:3b4e3e2ec6a5 | 266 | Ticker gTICKER2; |
radiojunkbox | 0:3b4e3e2ec6a5 | 267 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 268 | // Implemented in TestShell.cpp |
radiojunkbox | 0:3b4e3e2ec6a5 | 269 | void TestShell(); |
radiojunkbox | 0:3b4e3e2ec6a5 | 270 | void USBInit(); |
radiojunkbox | 0:3b4e3e2ec6a5 | 271 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 272 | //------------------------------------------------------------- |
radiojunkbox | 0:3b4e3e2ec6a5 | 273 | // main |
radiojunkbox | 0:3b4e3e2ec6a5 | 274 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 275 | int main() { |
radiojunkbox | 0:3b4e3e2ec6a5 | 276 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 277 | int i; |
radiojunkbox | 0:3b4e3e2ec6a5 | 278 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 279 | USBInit(); |
radiojunkbox | 0:3b4e3e2ec6a5 | 280 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 281 | // Initialize |
radiojunkbox | 0:3b4e3e2ec6a5 | 282 | gPtr_buf_in = gPtr_buf_out = 0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 283 | for( i=0; i<4; i++) { |
radiojunkbox | 0:3b4e3e2ec6a5 | 284 | pot[i] = _pot[i] = 0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 285 | edit[i] = 0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 286 | gGLIDE[i] = 1.0 / expf(val[0][i]*656.0/PARAM_GLIDE); |
radiojunkbox | 0:3b4e3e2ec6a5 | 287 | gLFO_DP[i] = expf(val[1][i]*656.0/PARAM_DP); |
radiojunkbox | 0:3b4e3e2ec6a5 | 288 | gLFO_FORM[i] = LFO_WF_TRI; |
radiojunkbox | 0:3b4e3e2ec6a5 | 289 | gMIDI_CH[i] = i; |
radiojunkbox | 0:3b4e3e2ec6a5 | 290 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 291 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 292 | for( i=0; i<16; i++) { // MIDI Data Buffers |
radiojunkbox | 0:3b4e3e2ec6a5 | 293 | gPlayNoteBuf[i] =24; |
radiojunkbox | 0:3b4e3e2ec6a5 | 294 | gGateBuf[i] = 0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 295 | gPitchBendBuf[i] = 0x40; |
radiojunkbox | 0:3b4e3e2ec6a5 | 296 | gModWheelBuf[i] = 0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 297 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 298 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 299 | gSW = 1; // for Intialize |
radiojunkbox | 0:3b4e3e2ec6a5 | 300 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 301 | CalcHzVTbl(); |
radiojunkbox | 0:3b4e3e2ec6a5 | 302 | InitKamui(); |
radiojunkbox | 0:3b4e3e2ec6a5 | 303 | gTICKER2.attach_us(&MenuLoop, MENULOOP_INTERVAL); |
radiojunkbox | 0:3b4e3e2ec6a5 | 304 | TestShell(); |
radiojunkbox | 0:3b4e3e2ec6a5 | 305 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 306 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 307 | //------------------------------------------------------------- |
radiojunkbox | 0:3b4e3e2ec6a5 | 308 | // Menu LOOP |
radiojunkbox | 0:3b4e3e2ec6a5 | 309 | void MenuLoop() |
radiojunkbox | 0:3b4e3e2ec6a5 | 310 | { |
radiojunkbox | 0:3b4e3e2ec6a5 | 311 | int i; |
radiojunkbox | 0:3b4e3e2ec6a5 | 312 | static unsigned char ch; |
radiojunkbox | 0:3b4e3e2ec6a5 | 313 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 314 | // Read pot |
radiojunkbox | 0:3b4e3e2ec6a5 | 315 | pot[0] = gAIN1.read_u16(); |
radiojunkbox | 0:3b4e3e2ec6a5 | 316 | pot[1] = gAIN2.read_u16(); |
radiojunkbox | 0:3b4e3e2ec6a5 | 317 | pot[2] = gAIN3.read_u16(); |
radiojunkbox | 0:3b4e3e2ec6a5 | 318 | pot[3] = gAIN4.read_u16(); |
radiojunkbox | 0:3b4e3e2ec6a5 | 319 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 320 | // change pot amount? |
radiojunkbox | 0:3b4e3e2ec6a5 | 321 | if(abs(pot[ch] - _pot[ch]) > 0x2000) edit[ch] = 1; |
radiojunkbox | 0:3b4e3e2ec6a5 | 322 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 323 | if(edit[ch]) { |
radiojunkbox | 0:3b4e3e2ec6a5 | 324 | switch(mode) { |
radiojunkbox | 0:3b4e3e2ec6a5 | 325 | case 0: |
radiojunkbox | 0:3b4e3e2ec6a5 | 326 | gGLIDE[ch] = 1.0 / expf(pot[ch]/PARAM_GLIDE); |
radiojunkbox | 0:3b4e3e2ec6a5 | 327 | val[0][ch] = pot[ch] / 656; |
radiojunkbox | 0:3b4e3e2ec6a5 | 328 | break; |
radiojunkbox | 0:3b4e3e2ec6a5 | 329 | case 1: |
radiojunkbox | 0:3b4e3e2ec6a5 | 330 | gLFO_DP[ch] = expf(pot[ch]/PARAM_DP); |
radiojunkbox | 0:3b4e3e2ec6a5 | 331 | val[1][ch] = pot[ch] / 656; |
radiojunkbox | 0:3b4e3e2ec6a5 | 332 | break; |
radiojunkbox | 0:3b4e3e2ec6a5 | 333 | case 2: |
radiojunkbox | 0:3b4e3e2ec6a5 | 334 | gLFO_FORM[ch] = pot[ch] / 0x4000; |
radiojunkbox | 0:3b4e3e2ec6a5 | 335 | break; |
radiojunkbox | 0:3b4e3e2ec6a5 | 336 | case 3: |
radiojunkbox | 0:3b4e3e2ec6a5 | 337 | gMIDI_CH[ch] = pot[ch] / 0x1000; |
radiojunkbox | 0:3b4e3e2ec6a5 | 338 | break; |
radiojunkbox | 0:3b4e3e2ec6a5 | 339 | default: |
radiojunkbox | 0:3b4e3e2ec6a5 | 340 | break; |
radiojunkbox | 0:3b4e3e2ec6a5 | 341 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 342 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 343 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 344 | // Push Mode SW |
radiojunkbox | 0:3b4e3e2ec6a5 | 345 | if(gSW & SW1) { |
radiojunkbox | 0:3b4e3e2ec6a5 | 346 | mode++; |
radiojunkbox | 0:3b4e3e2ec6a5 | 347 | mode &= 0x03; |
radiojunkbox | 0:3b4e3e2ec6a5 | 348 | for( i=0; i<4; i++) { |
radiojunkbox | 0:3b4e3e2ec6a5 | 349 | _pot[i] = pot[i]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 350 | edit[i] = 0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 351 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 352 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 353 | gSW = 0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 354 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 355 | // LCD Display |
radiojunkbox | 0:3b4e3e2ec6a5 | 356 | gLCD.locate( 0, 1 ); |
radiojunkbox | 0:3b4e3e2ec6a5 | 357 | switch(mode) { |
radiojunkbox | 0:3b4e3e2ec6a5 | 358 | case 0: |
radiojunkbox | 0:3b4e3e2ec6a5 | 359 | gLCD.printf("GLID %02d %02d %02d %02d", |
radiojunkbox | 0:3b4e3e2ec6a5 | 360 | val[0][0], val[0][1], val[0][2], val[0][3]); |
radiojunkbox | 0:3b4e3e2ec6a5 | 361 | break; |
radiojunkbox | 0:3b4e3e2ec6a5 | 362 | case 1: |
radiojunkbox | 0:3b4e3e2ec6a5 | 363 | gLCD.printf("FREQ %02d %02d %02d %02d", |
radiojunkbox | 0:3b4e3e2ec6a5 | 364 | val[1][0], val[1][1], val[1][2], val[1][3]); |
radiojunkbox | 0:3b4e3e2ec6a5 | 365 | break; |
radiojunkbox | 0:3b4e3e2ec6a5 | 366 | case 2: |
radiojunkbox | 0:3b4e3e2ec6a5 | 367 | gLCD.printf("FORM %s %s %s %s", |
radiojunkbox | 0:3b4e3e2ec6a5 | 368 | wave[gLFO_FORM[0]], wave[gLFO_FORM[1]], |
radiojunkbox | 0:3b4e3e2ec6a5 | 369 | wave[gLFO_FORM[2]], wave[gLFO_FORM[3]]); |
radiojunkbox | 0:3b4e3e2ec6a5 | 370 | break; |
radiojunkbox | 0:3b4e3e2ec6a5 | 371 | case 3: |
radiojunkbox | 0:3b4e3e2ec6a5 | 372 | gLCD.printf("MIDI %02d %02d %02d %02d", |
radiojunkbox | 0:3b4e3e2ec6a5 | 373 | gMIDI_CH[0]+1, gMIDI_CH[1]+1, |
radiojunkbox | 0:3b4e3e2ec6a5 | 374 | gMIDI_CH[2]+1, gMIDI_CH[3]+1); |
radiojunkbox | 0:3b4e3e2ec6a5 | 375 | break; |
radiojunkbox | 0:3b4e3e2ec6a5 | 376 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 377 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 378 | ch++; |
radiojunkbox | 0:3b4e3e2ec6a5 | 379 | ch &= 0x03; |
radiojunkbox | 0:3b4e3e2ec6a5 | 380 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 381 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 382 | //------------------------------------------------------------- |
radiojunkbox | 0:3b4e3e2ec6a5 | 383 | // Initialize KAMUI |
radiojunkbox | 0:3b4e3e2ec6a5 | 384 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 385 | void InitKamui() |
radiojunkbox | 0:3b4e3e2ec6a5 | 386 | { |
radiojunkbox | 0:3b4e3e2ec6a5 | 387 | // Init. Variables |
radiojunkbox | 0:3b4e3e2ec6a5 | 388 | for( int i=0; i<8; i++) { |
radiojunkbox | 0:3b4e3e2ec6a5 | 389 | gCV[i] = 0x8000; |
radiojunkbox | 0:3b4e3e2ec6a5 | 390 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 391 | gGATE = 0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 392 | gSYNC = 0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 393 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 394 | gUpdateMode = UPDATE_MODE0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 395 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 396 | // Init. SPI |
radiojunkbox | 0:3b4e3e2ec6a5 | 397 | gCSA = _DISABLE; |
radiojunkbox | 0:3b4e3e2ec6a5 | 398 | gCSB = _DISABLE; |
radiojunkbox | 0:3b4e3e2ec6a5 | 399 | gSPI.format(8,0); |
radiojunkbox | 0:3b4e3e2ec6a5 | 400 | gSPI.frequency(SPI_RATE); |
radiojunkbox | 0:3b4e3e2ec6a5 | 401 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 402 | // Init. Serial MIDI |
radiojunkbox | 0:3b4e3e2ec6a5 | 403 | gMIDI.baud(MIDI_RATE); |
radiojunkbox | 0:3b4e3e2ec6a5 | 404 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 405 | // Ticker |
radiojunkbox | 0:3b4e3e2ec6a5 | 406 | gTICKER.attach_us(&UpdateCV, UPDATE_INTERVAL); |
radiojunkbox | 0:3b4e3e2ec6a5 | 407 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 408 | // Beep |
radiojunkbox | 0:3b4e3e2ec6a5 | 409 | gBEEP.period(1.0/BEEP_FREQ); |
radiojunkbox | 0:3b4e3e2ec6a5 | 410 | gBEEP.write(0.5); |
radiojunkbox | 0:3b4e3e2ec6a5 | 411 | wait(0.2); |
radiojunkbox | 0:3b4e3e2ec6a5 | 412 | gBEEP.write(0.0); |
radiojunkbox | 0:3b4e3e2ec6a5 | 413 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 414 | // Init Display |
radiojunkbox | 0:3b4e3e2ec6a5 | 415 | gLCD.locate( 0, 0 ); |
radiojunkbox | 0:3b4e3e2ec6a5 | 416 | // 123456789ABCDEF |
radiojunkbox | 0:3b4e3e2ec6a5 | 417 | gLCD.printf("USBHOST MIDI-CV"); |
radiojunkbox | 0:3b4e3e2ec6a5 | 418 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 419 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 420 | //------------------------------------------------------------- |
radiojunkbox | 0:3b4e3e2ec6a5 | 421 | // Update CV, GATE, SYNC |
radiojunkbox | 0:3b4e3e2ec6a5 | 422 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 423 | void UpdateCV() |
radiojunkbox | 0:3b4e3e2ec6a5 | 424 | { |
radiojunkbox | 0:3b4e3e2ec6a5 | 425 | unsigned char rcv,ch; |
radiojunkbox | 0:3b4e3e2ec6a5 | 426 | unsigned char ptn[] = { 0,1,6,7,2,3,6,7,4,5,6,7 }; |
radiojunkbox | 0:3b4e3e2ec6a5 | 427 | const int numptn = (sizeof ptn / sizeof ptn[0]) - 1; |
radiojunkbox | 0:3b4e3e2ec6a5 | 428 | static unsigned char cnt; |
radiojunkbox | 0:3b4e3e2ec6a5 | 429 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 430 | // SET DAC |
radiojunkbox | 0:3b4e3e2ec6a5 | 431 | ch = ptn[cnt]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 432 | if(gUpdateMode) ch |= 0x06; |
radiojunkbox | 0:3b4e3e2ec6a5 | 433 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 434 | #ifdef AD5551 // 14bitDAC |
radiojunkbox | 0:3b4e3e2ec6a5 | 435 | gDAC.WORD = gCV[ch] >> 2; |
radiojunkbox | 0:3b4e3e2ec6a5 | 436 | #else |
radiojunkbox | 0:3b4e3e2ec6a5 | 437 | gDAC.WORD = gCV[ch]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 438 | #endif |
radiojunkbox | 0:3b4e3e2ec6a5 | 439 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 440 | gCSA = _ENABLE; |
radiojunkbox | 0:3b4e3e2ec6a5 | 441 | gSPI.write(gDAC.BYTE.H); |
radiojunkbox | 0:3b4e3e2ec6a5 | 442 | gSPI.write(gDAC.BYTE.L); |
radiojunkbox | 0:3b4e3e2ec6a5 | 443 | gCSA = _DISABLE; |
radiojunkbox | 0:3b4e3e2ec6a5 | 444 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 445 | // GATE or SYNC OUT |
radiojunkbox | 0:3b4e3e2ec6a5 | 446 | if(cnt & 0x01) { |
radiojunkbox | 0:3b4e3e2ec6a5 | 447 | // GATE OUT |
radiojunkbox | 0:3b4e3e2ec6a5 | 448 | gCSB = _ENABLE; |
radiojunkbox | 0:3b4e3e2ec6a5 | 449 | rcv = gSPI.write(gGATE | MODE_GATE) & 0x0F; |
radiojunkbox | 0:3b4e3e2ec6a5 | 450 | gCSB = _DISABLE; |
radiojunkbox | 0:3b4e3e2ec6a5 | 451 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 452 | else { |
radiojunkbox | 0:3b4e3e2ec6a5 | 453 | // SYNC OUT |
radiojunkbox | 0:3b4e3e2ec6a5 | 454 | gCSB = _ENABLE; |
radiojunkbox | 0:3b4e3e2ec6a5 | 455 | rcv = gSPI.write(gSYNC | MODE_SYNC); |
radiojunkbox | 0:3b4e3e2ec6a5 | 456 | gCSB = _DISABLE; |
radiojunkbox | 0:3b4e3e2ec6a5 | 457 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 458 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 459 | // SEL CV CHANNEL |
radiojunkbox | 0:3b4e3e2ec6a5 | 460 | gCSB = _ENABLE; |
radiojunkbox | 0:3b4e3e2ec6a5 | 461 | gSPI.write(ch); |
radiojunkbox | 0:3b4e3e2ec6a5 | 462 | gCSB = _DISABLE; |
radiojunkbox | 0:3b4e3e2ec6a5 | 463 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 464 | cnt < numptn ? cnt++ : cnt = 0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 465 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 466 | gSW |= CheckSW(rcv); |
radiojunkbox | 0:3b4e3e2ec6a5 | 467 | RcvMIDI(); |
radiojunkbox | 0:3b4e3e2ec6a5 | 468 | GetMIDI(); |
radiojunkbox | 0:3b4e3e2ec6a5 | 469 | DinSync(); |
radiojunkbox | 0:3b4e3e2ec6a5 | 470 | MidiCV(); |
radiojunkbox | 0:3b4e3e2ec6a5 | 471 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 472 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 473 | //------------------------------------------------------------- |
radiojunkbox | 0:3b4e3e2ec6a5 | 474 | // Check SW |
radiojunkbox | 0:3b4e3e2ec6a5 | 475 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 476 | unsigned char CheckSW(unsigned char c) { |
radiojunkbox | 0:3b4e3e2ec6a5 | 477 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 478 | static unsigned char swbuf[2]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 479 | static unsigned int cntsw; |
radiojunkbox | 0:3b4e3e2ec6a5 | 480 | unsigned char ret = 0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 481 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 482 | if(cntsw > SW_WATCH_INTERVAL) { |
radiojunkbox | 0:3b4e3e2ec6a5 | 483 | if(c &= 0x0F) { |
radiojunkbox | 0:3b4e3e2ec6a5 | 484 | if(!swbuf[1]) { |
radiojunkbox | 0:3b4e3e2ec6a5 | 485 | if( swbuf[0] == c) { |
radiojunkbox | 0:3b4e3e2ec6a5 | 486 | swbuf[1] = c; |
radiojunkbox | 0:3b4e3e2ec6a5 | 487 | ret = c; |
radiojunkbox | 0:3b4e3e2ec6a5 | 488 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 489 | else { |
radiojunkbox | 0:3b4e3e2ec6a5 | 490 | swbuf[0] = c; |
radiojunkbox | 0:3b4e3e2ec6a5 | 491 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 492 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 493 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 494 | else { |
radiojunkbox | 0:3b4e3e2ec6a5 | 495 | swbuf[1] = 0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 496 | swbuf[0] = 0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 497 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 498 | cntsw = 0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 499 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 500 | cntsw++; |
radiojunkbox | 0:3b4e3e2ec6a5 | 501 | return ret; |
radiojunkbox | 0:3b4e3e2ec6a5 | 502 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 503 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 504 | //------------------------------------------------------------- |
radiojunkbox | 0:3b4e3e2ec6a5 | 505 | // Receive MIDI Data & Store Ring Buffer |
radiojunkbox | 0:3b4e3e2ec6a5 | 506 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 507 | void RcvMIDI() { |
radiojunkbox | 0:3b4e3e2ec6a5 | 508 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 509 | if(!gMIDI.readable()) return; |
radiojunkbox | 0:3b4e3e2ec6a5 | 510 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 511 | gPtr_buf_in++; |
radiojunkbox | 0:3b4e3e2ec6a5 | 512 | gPtr_buf_in &= (BUFSIZE - 1); |
radiojunkbox | 0:3b4e3e2ec6a5 | 513 | gRxBuf[gPtr_buf_in] = gMIDI.getc(); |
radiojunkbox | 0:3b4e3e2ec6a5 | 514 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 515 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 516 | //------------------------------------------------------------- |
radiojunkbox | 0:3b4e3e2ec6a5 | 517 | // Get MIDI Data from Ring Buffer |
radiojunkbox | 0:3b4e3e2ec6a5 | 518 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 519 | void GetMIDI() { |
radiojunkbox | 0:3b4e3e2ec6a5 | 520 | unsigned char rb; |
radiojunkbox | 0:3b4e3e2ec6a5 | 521 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 522 | // ring buffer empty? |
radiojunkbox | 0:3b4e3e2ec6a5 | 523 | if(gPtr_buf_in != gPtr_buf_out) { |
radiojunkbox | 0:3b4e3e2ec6a5 | 524 | // get 1byte from ring buffer |
radiojunkbox | 0:3b4e3e2ec6a5 | 525 | gPtr_buf_out++; |
radiojunkbox | 0:3b4e3e2ec6a5 | 526 | gPtr_buf_out &= (BUFSIZE - 1); |
radiojunkbox | 0:3b4e3e2ec6a5 | 527 | rb = gRxBuf[gPtr_buf_out]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 528 | MIDI_Parser(rb); |
radiojunkbox | 0:3b4e3e2ec6a5 | 529 | gMIDI.putc(rb); |
radiojunkbox | 0:3b4e3e2ec6a5 | 530 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 531 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 532 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 533 | //------------------------------------------------------------- |
radiojunkbox | 0:3b4e3e2ec6a5 | 534 | // MIDI Data to CV, GATE |
radiojunkbox | 0:3b4e3e2ec6a5 | 535 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 536 | void MidiCV() |
radiojunkbox | 0:3b4e3e2ec6a5 | 537 | { |
radiojunkbox | 0:3b4e3e2ec6a5 | 538 | static unsigned char ch; |
radiojunkbox | 0:3b4e3e2ec6a5 | 539 | static unsigned short phase[4]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 540 | static float cvf[4]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 541 | int lfo,mod; |
radiojunkbox | 0:3b4e3e2ec6a5 | 542 | unsigned char midi_ch; |
radiojunkbox | 0:3b4e3e2ec6a5 | 543 | unsigned int cv; |
radiojunkbox | 0:3b4e3e2ec6a5 | 544 | unsigned int note; |
radiojunkbox | 0:3b4e3e2ec6a5 | 545 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 546 | midi_ch = gMIDI_CH[ch]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 547 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 548 | note = gPlayNoteBuf[midi_ch]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 549 | if( note < MINIMUMNOTE) note = MINIMUMNOTE; |
radiojunkbox | 0:3b4e3e2ec6a5 | 550 | note -= MINIMUMNOTE; |
radiojunkbox | 0:3b4e3e2ec6a5 | 551 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 552 | // DDS Phase |
radiojunkbox | 0:3b4e3e2ec6a5 | 553 | phase[ch] += gLFO_DP[ch]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 554 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 555 | // LFO DDS Genelator |
radiojunkbox | 0:3b4e3e2ec6a5 | 556 | switch(gLFO_FORM[ch]) { |
radiojunkbox | 0:3b4e3e2ec6a5 | 557 | case LFO_WF_TRI: |
radiojunkbox | 0:3b4e3e2ec6a5 | 558 | if(phase[ch] < 32738) lfo = phase[ch] - 16384; |
radiojunkbox | 0:3b4e3e2ec6a5 | 559 | else lfo = (16383 + 32768) - phase[ch]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 560 | break; |
radiojunkbox | 0:3b4e3e2ec6a5 | 561 | case LFO_WF_SQR: |
radiojunkbox | 0:3b4e3e2ec6a5 | 562 | if(phase[ch] < 32738) lfo = 32767; |
radiojunkbox | 0:3b4e3e2ec6a5 | 563 | else lfo = 0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 564 | break; |
radiojunkbox | 0:3b4e3e2ec6a5 | 565 | case LFO_WF_SAW: |
radiojunkbox | 0:3b4e3e2ec6a5 | 566 | lfo = phase[ch] / 2 - 16384; |
radiojunkbox | 0:3b4e3e2ec6a5 | 567 | break; |
radiojunkbox | 0:3b4e3e2ec6a5 | 568 | default : |
radiojunkbox | 0:3b4e3e2ec6a5 | 569 | lfo = 0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 570 | break; |
radiojunkbox | 0:3b4e3e2ec6a5 | 571 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 572 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 573 | // Modulation amount |
radiojunkbox | 0:3b4e3e2ec6a5 | 574 | mod = lfo * gModWheelBuf[midi_ch] >> 8; |
radiojunkbox | 0:3b4e3e2ec6a5 | 575 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 576 | // Calculate CV |
radiojunkbox | 0:3b4e3e2ec6a5 | 577 | cvf[ch] = ((float)(note << 8) - cvf[ch]) * gGLIDE[ch] + cvf[ch]; |
radiojunkbox | 0:3b4e3e2ec6a5 | 578 | cv = (unsigned int)cvf[ch] + (0x8000 - (0x0040 << 3)) |
radiojunkbox | 0:3b4e3e2ec6a5 | 579 | + (gPitchBendBuf[midi_ch] << 2) + mod; |
radiojunkbox | 0:3b4e3e2ec6a5 | 580 | if(cv > 0xFFFF) cv = 0xFFFF; |
radiojunkbox | 0:3b4e3e2ec6a5 | 581 | gCV[ch] = (unsigned short)cv; |
radiojunkbox | 0:3b4e3e2ec6a5 | 582 | gCV[ch+4] = OctVtoHzV(gCV[ch]); |
radiojunkbox | 0:3b4e3e2ec6a5 | 583 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 584 | // GATE |
radiojunkbox | 0:3b4e3e2ec6a5 | 585 | gGateBuf[midi_ch] ? gGATE |= (1<<ch) : gGATE &= ~(1<<ch); |
radiojunkbox | 0:3b4e3e2ec6a5 | 586 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 587 | ch++; |
radiojunkbox | 0:3b4e3e2ec6a5 | 588 | ch &= 0x03; |
radiojunkbox | 0:3b4e3e2ec6a5 | 589 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 590 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 591 | //------------------------------------------------------------- |
radiojunkbox | 0:3b4e3e2ec6a5 | 592 | // Oct/V to Hz/V Converter |
radiojunkbox | 0:3b4e3e2ec6a5 | 593 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 594 | void CalcHzVTbl() // Calc Conv. Table |
radiojunkbox | 0:3b4e3e2ec6a5 | 595 | { |
radiojunkbox | 0:3b4e3e2ec6a5 | 596 | int i; |
radiojunkbox | 0:3b4e3e2ec6a5 | 597 | float v; |
radiojunkbox | 0:3b4e3e2ec6a5 | 598 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 599 | for( i=0; i<3072; i++) { |
radiojunkbox | 0:3b4e3e2ec6a5 | 600 | v = 24576.0 * pow(2.0,(i/3072.0)); |
radiojunkbox | 0:3b4e3e2ec6a5 | 601 | gTblHzV[i] = (unsigned short)v; |
radiojunkbox | 0:3b4e3e2ec6a5 | 602 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 603 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 604 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 605 | unsigned short OctVtoHzV( unsigned short vin) |
radiojunkbox | 0:3b4e3e2ec6a5 | 606 | { |
radiojunkbox | 0:3b4e3e2ec6a5 | 607 | int oct,res; |
radiojunkbox | 0:3b4e3e2ec6a5 | 608 | unsigned short vout; |
radiojunkbox | 0:3b4e3e2ec6a5 | 609 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 610 | if(vin > 0xE400) vin = 0xE400; // Maximum Note E8 Vin = 10.794V |
radiojunkbox | 0:3b4e3e2ec6a5 | 611 | if(vin < 0x6800) vin = 0x6800; // Minimum Note C-2 Vin = -2.000V |
radiojunkbox | 0:3b4e3e2ec6a5 | 612 | vin -= 0x6800; |
radiojunkbox | 0:3b4e3e2ec6a5 | 613 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 614 | oct = vin / 0xC00; // 0xC00 : 3072 |
radiojunkbox | 0:3b4e3e2ec6a5 | 615 | res = vin % 0xC00; |
radiojunkbox | 0:3b4e3e2ec6a5 | 616 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 617 | vout = ((unsigned short)gTblHzV[res] >> (10 - oct)) + 0x8000; |
radiojunkbox | 0:3b4e3e2ec6a5 | 618 | return vout; |
radiojunkbox | 0:3b4e3e2ec6a5 | 619 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 620 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 621 | //------------------------------------------------------------- |
radiojunkbox | 0:3b4e3e2ec6a5 | 622 | // DIN SYNC Control |
radiojunkbox | 0:3b4e3e2ec6a5 | 623 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 624 | void DinSync() |
radiojunkbox | 0:3b4e3e2ec6a5 | 625 | { |
radiojunkbox | 0:3b4e3e2ec6a5 | 626 | static unsigned int cnt; |
radiojunkbox | 0:3b4e3e2ec6a5 | 627 | static unsigned int cnt24 = 10; |
radiojunkbox | 0:3b4e3e2ec6a5 | 628 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 629 | if(gMIDISYNC_RUN) gSYNC |= (SYNC1RUN | SYNC2RUN); |
radiojunkbox | 0:3b4e3e2ec6a5 | 630 | else gSYNC &= ~(SYNC1RUN | SYNC2RUN); |
radiojunkbox | 0:3b4e3e2ec6a5 | 631 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 632 | if(cnt >= SYNC_TURN_TIME) gSYNC &= ~(SYNC1CLK | SYNC2CLK); |
radiojunkbox | 0:3b4e3e2ec6a5 | 633 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 634 | if(gMIDISYNC_CLK) { |
radiojunkbox | 0:3b4e3e2ec6a5 | 635 | gSYNC |= (SYNC1CLK | SYNC2CLK); |
radiojunkbox | 0:3b4e3e2ec6a5 | 636 | gMIDISYNC_CLK = 0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 637 | cnt = 0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 638 | cnt24++; |
radiojunkbox | 0:3b4e3e2ec6a5 | 639 | } |
radiojunkbox | 0:3b4e3e2ec6a5 | 640 | if(cnt24 >= 24) cnt24 = 0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 641 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 642 | gLED3 = gSYNC & SYNC1RUN ? 1 : 0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 643 | gLED4 = cnt24 < 4 ? 1 : 0; |
radiojunkbox | 0:3b4e3e2ec6a5 | 644 | |
radiojunkbox | 0:3b4e3e2ec6a5 | 645 | cnt++; |
radiojunkbox | 0:3b4e3e2ec6a5 | 646 | } |