KAMUI USB HOST MIDI-CV Example based on Peter Barrett's BlueUSB

Dependencies:   TextLCD mbed

Committer:
radiojunkbox
Date:
Fri May 11 15:31:59 2012 +0000
Revision:
0:3b4e3e2ec6a5
Rev. 0.1 alfa

Who changed what in which revision?

UserRevisionLine numberNew 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 }