Standard MIDI file player for the eVY1 shield
Dependencies: DirectoryList SDFileSystem mbed
MicroSDカードからSMF(スタンダードMIDIファイル)を読み込み、データをシリアルでeVY1シールドに転送して再生します。 MIDIファイル形式は、Format 0のみ対応しています。
動作確認は、mbed LPC1114FN28とFRDM-K64Fで行っています。
eVY1でシリアルポートを有効にするには、シールドの端子側から+5V入力が必要なので、mbed LPC1114FN28を一部改造しています(JP2 9pinに+5V出力を接続しています)。 FRDM-K64Fの場合は、eVY1シールドをそのまま刺して使用できます(オンボードのMicroSDスロットを使います)。
eVY1を使用した場合、MIDIデータのCH.1は強制的にeVocalodによる歌声として使用されてしまうため(プログラムチェンジも不可)、強制的にCH.16に割り当てています。そのため、CH.16を使用しているMIDIファイルはデータ通りに再生する事が出来ません。
main.cpp@3:2a58b7f4b0cb, 2017-01-06 (annotated)
- Committer:
- MACRUM
- Date:
- Fri Jan 06 10:58:07 2017 +0000
- Revision:
- 3:2a58b7f4b0cb
- Parent:
- 2:4bcf9c18896b
Add dummy error function
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MACRUM | 1:c536df09d2e8 | 1 | /** |
MACRUM | 1:c536df09d2e8 | 2 | * Standard MIDI file player for the eVY1 shield |
MACRUM | 1:c536df09d2e8 | 3 | * |
MACRUM | 1:c536df09d2e8 | 4 | * @author Toyomasa Watarai |
MACRUM | 1:c536df09d2e8 | 5 | * @version 0.1 |
MACRUM | 1:c536df09d2e8 | 6 | * @date July-2015 |
MACRUM | 1:c536df09d2e8 | 7 | * |
MACRUM | 1:c536df09d2e8 | 8 | * This program parse MIDI format 0 files on SDCard |
MACRUM | 1:c536df09d2e8 | 9 | * and plays the data using eVY1 shield |
MACRUM | 1:c536df09d2e8 | 10 | * |
MACRUM | 1:c536df09d2e8 | 11 | * Ported by Arduino example code of the SWITCHSCIENCE, Thanks! |
MACRUM | 1:c536df09d2e8 | 12 | * https://github.com/SWITCHSCIENCE/eVY1_Shield |
MACRUM | 1:c536df09d2e8 | 13 | * |
MACRUM | 1:c536df09d2e8 | 14 | */ |
MACRUM | 1:c536df09d2e8 | 15 | |
MACRUM | 0:12d69da08021 | 16 | #include "mbed.h" |
MACRUM | 0:12d69da08021 | 17 | #include "SDFileSystem.h" |
MACRUM | 0:12d69da08021 | 18 | #include "DirectoryList.h" |
MACRUM | 0:12d69da08021 | 19 | |
MACRUM | 0:12d69da08021 | 20 | #define _DEBUG |
MACRUM | 0:12d69da08021 | 21 | #define _NO_eVocaloid_ |
MACRUM | 0:12d69da08021 | 22 | |
MACRUM | 0:12d69da08021 | 23 | #if defined(TARGET_K64F) |
MACRUM | 0:12d69da08021 | 24 | #define USE_DIRECTORY_LIST |
MACRUM | 0:12d69da08021 | 25 | SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd"); // MOSI, MISO, SCK, CS |
MACRUM | 0:12d69da08021 | 26 | RawSerial midi(D1, NC); |
MACRUM | 0:12d69da08021 | 27 | InterruptIn btn(PTA4); |
MACRUM | 0:12d69da08021 | 28 | |
MACRUM | 0:12d69da08021 | 29 | #elif defined(TARGET_LPC1114) |
MACRUM | 0:12d69da08021 | 30 | SDFileSystem sd(dp2, dp1, dp6, dp4, "sd"); // MOSI, MISO, SCK, CS |
MACRUM | 0:12d69da08021 | 31 | RawSerial midi(dp16, NC); |
MACRUM | 0:12d69da08021 | 32 | InterruptIn btn(dp9); |
MACRUM | 1:c536df09d2e8 | 33 | #if defined(_DEBUG) |
MACRUM | 1:c536df09d2e8 | 34 | #undef _DEBUG |
MACRUM | 1:c536df09d2e8 | 35 | #endif |
MACRUM | 0:12d69da08021 | 36 | |
MACRUM | 2:4bcf9c18896b | 37 | #elif defined(TARGET_WIZWIKI_W7500P) |
MACRUM | 2:4bcf9c18896b | 38 | SDFileSystem sd(PB_3, PB_2, PB_1, PB_0, "sd"); // MOSI, MISO, SCK, CS |
MACRUM | 2:4bcf9c18896b | 39 | RawSerial midi(D1, NC); |
MACRUM | 2:4bcf9c18896b | 40 | InterruptIn btn(PC_6); |
MACRUM | 2:4bcf9c18896b | 41 | #if defined(_DEBUG) |
MACRUM | 2:4bcf9c18896b | 42 | #undef _DEBUG |
MACRUM | 2:4bcf9c18896b | 43 | #endif |
MACRUM | 2:4bcf9c18896b | 44 | |
MACRUM | 0:12d69da08021 | 45 | #endif |
MACRUM | 0:12d69da08021 | 46 | |
MACRUM | 0:12d69da08021 | 47 | #ifdef _DEBUG |
MACRUM | 0:12d69da08021 | 48 | Serial pc(USBTX, USBRX); |
MACRUM | 0:12d69da08021 | 49 | #define DEBUG_PRINT(...) { pc.printf(__VA_ARGS__);} |
MACRUM | 0:12d69da08021 | 50 | #else |
MACRUM | 0:12d69da08021 | 51 | #define DEBUG_PRINT(...) |
MACRUM | 3:2a58b7f4b0cb | 52 | void error(const char* format, ...) {} |
MACRUM | 0:12d69da08021 | 53 | #endif |
MACRUM | 0:12d69da08021 | 54 | |
MACRUM | 0:12d69da08021 | 55 | FILE *fp; |
MACRUM | 0:12d69da08021 | 56 | Timer timer; |
MACRUM | 0:12d69da08021 | 57 | uint32_t tempo; |
MACRUM | 0:12d69da08021 | 58 | uint32_t delta_time; |
MACRUM | 0:12d69da08021 | 59 | uint32_t TIMER; |
MACRUM | 0:12d69da08021 | 60 | uint32_t STATE; |
MACRUM | 0:12d69da08021 | 61 | |
MACRUM | 0:12d69da08021 | 62 | #define midi_read() (fgetc(fp)) |
MACRUM | 0:12d69da08021 | 63 | |
MACRUM | 0:12d69da08021 | 64 | void disable_timer(void) |
MACRUM | 0:12d69da08021 | 65 | { |
MACRUM | 0:12d69da08021 | 66 | timer.stop(); |
MACRUM | 0:12d69da08021 | 67 | } |
MACRUM | 0:12d69da08021 | 68 | |
MACRUM | 0:12d69da08021 | 69 | uint32_t delta_time_read(void) |
MACRUM | 0:12d69da08021 | 70 | { |
MACRUM | 0:12d69da08021 | 71 | uint32_t r_buf; |
MACRUM | 0:12d69da08021 | 72 | uint32_t ret = 0; |
MACRUM | 0:12d69da08021 | 73 | |
MACRUM | 0:12d69da08021 | 74 | while(1) { |
MACRUM | 0:12d69da08021 | 75 | r_buf = midi_read(); |
MACRUM | 0:12d69da08021 | 76 | ret = (ret <<7) | (r_buf & 0x7f); |
MACRUM | 0:12d69da08021 | 77 | if ((r_buf & 0x80) == 0) |
MACRUM | 0:12d69da08021 | 78 | break; |
MACRUM | 0:12d69da08021 | 79 | } |
MACRUM | 0:12d69da08021 | 80 | |
MACRUM | 0:12d69da08021 | 81 | TIMER += ((ret * tempo) / delta_time); |
MACRUM | 0:12d69da08021 | 82 | return ret; |
MACRUM | 0:12d69da08021 | 83 | } |
MACRUM | 0:12d69da08021 | 84 | |
MACRUM | 0:12d69da08021 | 85 | void midi_play(void) |
MACRUM | 0:12d69da08021 | 86 | { |
MACRUM | 0:12d69da08021 | 87 | int32_t buf[256]; |
MACRUM | 0:12d69da08021 | 88 | uint32_t cnt; |
MACRUM | 0:12d69da08021 | 89 | uint32_t cmd; |
MACRUM | 0:12d69da08021 | 90 | |
MACRUM | 0:12d69da08021 | 91 | buf[0] = midi_read(); |
MACRUM | 0:12d69da08021 | 92 | buf[1] = midi_read(); |
MACRUM | 0:12d69da08021 | 93 | |
MACRUM | 0:12d69da08021 | 94 | cmd = (buf[0] & 0xf0); |
MACRUM | 0:12d69da08021 | 95 | if ((cmd == 0x80) || (cmd == 0x90) || (cmd == 0xA0) || (cmd == 0xB0) || (cmd == 0xE0)) { |
MACRUM | 0:12d69da08021 | 96 | buf[2] = midi_read(); |
MACRUM | 0:12d69da08021 | 97 | #if defined(_NO_eVocaloid_) |
MACRUM | 0:12d69da08021 | 98 | if ((buf[0] & 0x0f) == 0x0f) { // CH.16 |
MACRUM | 0:12d69da08021 | 99 | return; |
MACRUM | 0:12d69da08021 | 100 | } |
MACRUM | 0:12d69da08021 | 101 | if ((buf[0] & 0x0f) == 0x00) { // CH.1 |
MACRUM | 0:12d69da08021 | 102 | buf[0] = (buf[0] | 0x0f); // Force change to CH.16 |
MACRUM | 0:12d69da08021 | 103 | } |
MACRUM | 0:12d69da08021 | 104 | #endif |
MACRUM | 0:12d69da08021 | 105 | midi.putc(buf[0]); |
MACRUM | 0:12d69da08021 | 106 | midi.putc(buf[1]); |
MACRUM | 0:12d69da08021 | 107 | midi.putc(buf[2]); |
MACRUM | 0:12d69da08021 | 108 | } else if (cmd == 0xC0) { |
MACRUM | 0:12d69da08021 | 109 | #if defined(_NO_eVocaloid_) |
MACRUM | 0:12d69da08021 | 110 | if ((buf[0] & 0x0f) == 0x00) { // CH.1 |
MACRUM | 0:12d69da08021 | 111 | buf[0] = (buf[0] | 0x0f); // Force change to CH.16 |
MACRUM | 0:12d69da08021 | 112 | } |
MACRUM | 0:12d69da08021 | 113 | #endif |
MACRUM | 0:12d69da08021 | 114 | midi.putc(buf[0]); |
MACRUM | 0:12d69da08021 | 115 | midi.putc(buf[1]); |
MACRUM | 0:12d69da08021 | 116 | } else if (cmd == 0xD0) { |
MACRUM | 0:12d69da08021 | 117 | midi.putc(buf[0]); |
MACRUM | 0:12d69da08021 | 118 | midi.putc(buf[1]); |
MACRUM | 0:12d69da08021 | 119 | } else if (cmd == 0xF0) { |
MACRUM | 0:12d69da08021 | 120 | switch( buf[0] & 0x0F ) { |
MACRUM | 0:12d69da08021 | 121 | case 0x00 : // SysEx |
MACRUM | 0:12d69da08021 | 122 | case 0x07 : // SysEx2 |
MACRUM | 0:12d69da08021 | 123 | cnt = buf[1]; |
MACRUM | 0:12d69da08021 | 124 | midi.putc(buf[0]); |
MACRUM | 0:12d69da08021 | 125 | for(uint32_t i=1; i<cnt+1; i++) { |
MACRUM | 0:12d69da08021 | 126 | midi.putc(midi_read()); |
MACRUM | 0:12d69da08021 | 127 | } |
MACRUM | 0:12d69da08021 | 128 | break; |
MACRUM | 0:12d69da08021 | 129 | case 0x0f : // Meta event |
MACRUM | 0:12d69da08021 | 130 | switch ( buf[1] ) { |
MACRUM | 0:12d69da08021 | 131 | case 0x00: // Sequence number |
MACRUM | 0:12d69da08021 | 132 | midi_read(); |
MACRUM | 0:12d69da08021 | 133 | break; |
MACRUM | 0:12d69da08021 | 134 | case 0x51: // Set tempo |
MACRUM | 0:12d69da08021 | 135 | midi_read(); // len (== 3) |
MACRUM | 0:12d69da08021 | 136 | tempo = midi_read(); |
MACRUM | 0:12d69da08021 | 137 | tempo = (tempo << 8 ) | midi_read(); |
MACRUM | 0:12d69da08021 | 138 | tempo = (tempo << 8 ) | midi_read(); |
MACRUM | 0:12d69da08021 | 139 | tempo = tempo / 1000; |
MACRUM | 0:12d69da08021 | 140 | DEBUG_PRINT("Set tempo = %d\n", tempo); |
MACRUM | 0:12d69da08021 | 141 | break; |
MACRUM | 0:12d69da08021 | 142 | case 0x2f: // End of Track |
MACRUM | 0:12d69da08021 | 143 | midi_read(); // Read zero |
MACRUM | 0:12d69da08021 | 144 | disable_timer(); |
MACRUM | 0:12d69da08021 | 145 | STATE = 2; |
MACRUM | 0:12d69da08021 | 146 | break; |
MACRUM | 1:c536df09d2e8 | 147 | case 0x01: |
MACRUM | 1:c536df09d2e8 | 148 | case 0x02: |
MACRUM | 1:c536df09d2e8 | 149 | cnt = midi_read(); // len |
MACRUM | 1:c536df09d2e8 | 150 | for(uint32_t i=0; i<cnt; i++) |
MACRUM | 1:c536df09d2e8 | 151 | DEBUG_PRINT("%c", midi_read()); |
MACRUM | 1:c536df09d2e8 | 152 | DEBUG_PRINT("\n"); |
MACRUM | 1:c536df09d2e8 | 153 | break; |
MACRUM | 0:12d69da08021 | 154 | default: |
MACRUM | 0:12d69da08021 | 155 | cnt = midi_read(); // len |
MACRUM | 0:12d69da08021 | 156 | for(uint32_t i=0; i<cnt; i++) |
MACRUM | 0:12d69da08021 | 157 | midi_read(); |
MACRUM | 0:12d69da08021 | 158 | break; |
MACRUM | 0:12d69da08021 | 159 | } |
MACRUM | 0:12d69da08021 | 160 | break; |
MACRUM | 0:12d69da08021 | 161 | } |
MACRUM | 0:12d69da08021 | 162 | } |
MACRUM | 0:12d69da08021 | 163 | } |
MACRUM | 0:12d69da08021 | 164 | |
MACRUM | 0:12d69da08021 | 165 | |
MACRUM | 0:12d69da08021 | 166 | void smf_main_loop(void) |
MACRUM | 0:12d69da08021 | 167 | { |
MACRUM | 0:12d69da08021 | 168 | if(STATE == 1) { |
MACRUM | 0:12d69da08021 | 169 | if (TIMER < timer.read_ms()) { |
MACRUM | 0:12d69da08021 | 170 | midi_play(); |
MACRUM | 0:12d69da08021 | 171 | if (STATE != 2) |
MACRUM | 0:12d69da08021 | 172 | delta_time_read(); |
MACRUM | 0:12d69da08021 | 173 | } |
MACRUM | 0:12d69da08021 | 174 | } |
MACRUM | 0:12d69da08021 | 175 | } |
MACRUM | 0:12d69da08021 | 176 | |
MACRUM | 0:12d69da08021 | 177 | void smf_init(void) |
MACRUM | 0:12d69da08021 | 178 | { |
MACRUM | 0:12d69da08021 | 179 | TIMER = 0; |
MACRUM | 0:12d69da08021 | 180 | tempo = 500; // default value |
MACRUM | 0:12d69da08021 | 181 | |
MACRUM | 2:4bcf9c18896b | 182 | uint32_t ch; |
MACRUM | 2:4bcf9c18896b | 183 | for (ch=0; ch<16; ch++) { |
MACRUM | 2:4bcf9c18896b | 184 | midi.putc(0xB0|ch); |
MACRUM | 2:4bcf9c18896b | 185 | midi.putc(0x78); |
MACRUM | 2:4bcf9c18896b | 186 | midi.putc(0x00); |
MACRUM | 2:4bcf9c18896b | 187 | midi.putc(0xB0|ch); |
MACRUM | 2:4bcf9c18896b | 188 | midi.putc(0x79); |
MACRUM | 2:4bcf9c18896b | 189 | midi.putc(0x00); |
MACRUM | 2:4bcf9c18896b | 190 | } |
MACRUM | 2:4bcf9c18896b | 191 | |
MACRUM | 0:12d69da08021 | 192 | // Skip MIDI header |
MACRUM | 0:12d69da08021 | 193 | for (uint32_t i=0; i<8; i++) { |
MACRUM | 0:12d69da08021 | 194 | midi_read(); |
MACRUM | 0:12d69da08021 | 195 | } |
MACRUM | 0:12d69da08021 | 196 | |
MACRUM | 0:12d69da08021 | 197 | uint32_t format; |
MACRUM | 0:12d69da08021 | 198 | format = (midi_read() << 8); |
MACRUM | 0:12d69da08021 | 199 | format |= midi_read(); |
MACRUM | 0:12d69da08021 | 200 | |
MACRUM | 2:4bcf9c18896b | 201 | if ( format > 1) { |
MACRUM | 2:4bcf9c18896b | 202 | DEBUG_PRINT("This is not a MIDI format 0 file!\n", format); |
MACRUM | 1:c536df09d2e8 | 203 | STATE = 2; |
MACRUM | 1:c536df09d2e8 | 204 | return; |
MACRUM | 1:c536df09d2e8 | 205 | } |
MACRUM | 0:12d69da08021 | 206 | |
MACRUM | 0:12d69da08021 | 207 | uint32_t track; |
MACRUM | 0:12d69da08021 | 208 | track = (midi_read() << 8); |
MACRUM | 0:12d69da08021 | 209 | track |= midi_read(); |
MACRUM | 0:12d69da08021 | 210 | |
MACRUM | 1:c536df09d2e8 | 211 | DEBUG_PRINT("Number of tracks : %d\n", track); |
MACRUM | 0:12d69da08021 | 212 | |
MACRUM | 0:12d69da08021 | 213 | // timebase |
MACRUM | 0:12d69da08021 | 214 | delta_time = (midi_read() << 8); |
MACRUM | 0:12d69da08021 | 215 | delta_time |= midi_read(); |
MACRUM | 0:12d69da08021 | 216 | DEBUG_PRINT("tempo = %d, delta_time = %d\n", tempo, delta_time); |
MACRUM | 0:12d69da08021 | 217 | |
MACRUM | 0:12d69da08021 | 218 | // skip track chunk header |
MACRUM | 0:12d69da08021 | 219 | for (uint32_t i=0; i<0x8; i++) |
MACRUM | 0:12d69da08021 | 220 | midi_read(); |
MACRUM | 0:12d69da08021 | 221 | |
MACRUM | 0:12d69da08021 | 222 | TIMER = (delta_time_read() * tempo) / delta_time ; |
MACRUM | 0:12d69da08021 | 223 | DEBUG_PRINT("TIMER = %d\n", TIMER); |
MACRUM | 0:12d69da08021 | 224 | STATE = 1; |
MACRUM | 0:12d69da08021 | 225 | } |
MACRUM | 0:12d69da08021 | 226 | |
MACRUM | 0:12d69da08021 | 227 | void skip() |
MACRUM | 0:12d69da08021 | 228 | { |
MACRUM | 0:12d69da08021 | 229 | STATE = 2; |
MACRUM | 0:12d69da08021 | 230 | } |
MACRUM | 1:c536df09d2e8 | 231 | |
MACRUM | 0:12d69da08021 | 232 | int main() |
MACRUM | 0:12d69da08021 | 233 | { |
MACRUM | 0:12d69da08021 | 234 | DEBUG_PRINT("Initializing...\n"); |
MACRUM | 0:12d69da08021 | 235 | |
MACRUM | 1:c536df09d2e8 | 236 | btn.mode(PullUp); |
MACRUM | 0:12d69da08021 | 237 | btn.fall(&skip); |
MACRUM | 0:12d69da08021 | 238 | midi.baud(31250); |
MACRUM | 0:12d69da08021 | 239 | |
MACRUM | 0:12d69da08021 | 240 | wait(3.5); // Wait few seconds for booting eVY1-Shleld. |
MACRUM | 0:12d69da08021 | 241 | |
MACRUM | 0:12d69da08021 | 242 | #if !defined(_NO_eVocaloid_) |
MACRUM | 0:12d69da08021 | 243 | const uint8_t aMsg[] = "\xF0\x43\x79\x09\x00\x50\x10" "4 a\0" "\xF7"; |
MACRUM | 0:12d69da08021 | 244 | for (uint32_t i = 0; i < sizeof(aMsg)-1; midi.putc(aMsg[i++])); |
MACRUM | 0:12d69da08021 | 245 | #endif |
MACRUM | 0:12d69da08021 | 246 | |
MACRUM | 0:12d69da08021 | 247 | DEBUG_PRINT("Initialized.\n"); |
MACRUM | 0:12d69da08021 | 248 | |
MACRUM | 0:12d69da08021 | 249 | char buf[50]; |
MACRUM | 0:12d69da08021 | 250 | |
MACRUM | 0:12d69da08021 | 251 | #if defined(USE_DIRECTORY_LIST) |
MACRUM | 0:12d69da08021 | 252 | DirectoryList dir("/sd"); |
MACRUM | 0:12d69da08021 | 253 | if ( dir.error_check() ) { |
MACRUM | 0:12d69da08021 | 254 | DEBUG_PRINT("directory could not be opened\r\n"); |
MACRUM | 0:12d69da08021 | 255 | return -1; |
MACRUM | 0:12d69da08021 | 256 | } |
MACRUM | 1:c536df09d2e8 | 257 | |
MACRUM | 0:12d69da08021 | 258 | for ( int i = 0; i < dir.size(); i++ ) { |
MACRUM | 0:12d69da08021 | 259 | sprintf(buf, "/sd/%s", dir[ i ].c_str() ); |
MACRUM | 0:12d69da08021 | 260 | #else |
MACRUM | 1:c536df09d2e8 | 261 | for ( uint32_t i = 0; i < 10; i++ ) { |
MACRUM | 0:12d69da08021 | 262 | sprintf(buf, "/sd/%d.mid", i); |
MACRUM | 0:12d69da08021 | 263 | #endif |
MACRUM | 0:12d69da08021 | 264 | |
MACRUM | 0:12d69da08021 | 265 | fp = fopen(buf, "r"); |
MACRUM | 0:12d69da08021 | 266 | if (fp == NULL) { |
MACRUM | 0:12d69da08021 | 267 | DEBUG_PRINT("Unable to read the file \n"); |
MACRUM | 0:12d69da08021 | 268 | } else { |
MACRUM | 0:12d69da08021 | 269 | timer.reset(); |
MACRUM | 0:12d69da08021 | 270 | timer.start(); |
MACRUM | 0:12d69da08021 | 271 | smf_init(); |
MACRUM | 1:c536df09d2e8 | 272 | if ( STATE == 2 ) { |
MACRUM | 1:c536df09d2e8 | 273 | fclose(fp); |
MACRUM | 1:c536df09d2e8 | 274 | #if defined(__MICROLIB) && defined(__ARMCC_VERSION) // with microlib and ARM compiler |
MACRUM | 1:c536df09d2e8 | 275 | free(fp); |
MACRUM | 1:c536df09d2e8 | 276 | #endif |
MACRUM | 1:c536df09d2e8 | 277 | continue; |
MACRUM | 1:c536df09d2e8 | 278 | } |
MACRUM | 1:c536df09d2e8 | 279 | |
MACRUM | 0:12d69da08021 | 280 | DEBUG_PRINT("Now, playing (%s)... \n", buf); |
MACRUM | 0:12d69da08021 | 281 | while (1) { |
MACRUM | 0:12d69da08021 | 282 | smf_main_loop(); |
MACRUM | 0:12d69da08021 | 283 | if (STATE == 2) { |
MACRUM | 0:12d69da08021 | 284 | break; |
MACRUM | 0:12d69da08021 | 285 | } |
MACRUM | 0:12d69da08021 | 286 | } |
MACRUM | 0:12d69da08021 | 287 | fclose(fp); |
MACRUM | 0:12d69da08021 | 288 | #if defined(__MICROLIB) && defined(__ARMCC_VERSION) // with microlib and ARM compiler |
MACRUM | 0:12d69da08021 | 289 | free(fp); |
MACRUM | 0:12d69da08021 | 290 | #endif |
MACRUM | 0:12d69da08021 | 291 | DEBUG_PRINT("End.\n"); |
MACRUM | 0:12d69da08021 | 292 | } |
MACRUM | 0:12d69da08021 | 293 | } |
MACRUM | 0:12d69da08021 | 294 | } |