ATtiny10 用プログラム (4)
ATtiny10 用のサイン波発生プログラムを作りました。
(12/27 追記: 「sin_tn10.c」で USE_ADC 未定義の場合にコンパイル・エラーになる問題と、「stab128.S」の 2 の補数計算のバグを修正したプログラムに差し替えました)
フェーズ・アキュムレータとサイン波テーブルを使っており、任意の周波数を発生できます。
Timer1 の 8 ビット phase correct PWM を DAC として利用しており、数 kHz のカットオフ周波数の LPF を接続してアナログ波形を得ます。
内部クロック、外部クロックどちらにも対応しており、サンプリング周波数は 8 MHz 内部/外部クロックで 16.525 kHz、12 MHz 外部クロックで 23.4375 kHz です。
最大で 2 波を独立に発生可能で、PB0 (ピン 1) 側の周波数は固定あるいは PB2 (ピン 4) に加える外部電圧で可変の、どちらかを選択可能で、PB1 (ピン 3) 側の周波数は固定です。 (外部クロックではPB0 (ピン 1) 側のみ有効)
Arduino とつないだまま使用する場合の回路図を下に示します。
PB2 (ピン 4) は周波数可変のための AD 入力専用とし、外部から電圧を与えるだけで、負荷となるものは付けないようにします。
PB0 (ピン 1)、PB1 (ピン 3) は書き込みに使われるので、「重い」負荷を付けると書き込みに失敗するようになります。 図のアクティブ・フィルタによる LPF のように、数十 kΩ 以上のインピーダンスにします。
外部クロックを設ける場合には、図のように、抵抗を介して Arduino 側に接続します。
本来のアプリケーション回路ではクロック・ジェネレータ出力と ATtiny10 の 3 番ピンは直結すべきですが、Arduino と接続したままプログラム書き込み/実行を行うために、このようにしています。
書き込みのために Arduino がディジタル 13 番ピンを低インピーダンスでドライブすると、クロック・ジェネレータ出力は抵抗を介して接続されているので、クロック・ジェネレータ側は「負け」、Arduino の出力側が「勝ち」、ATtiny10 の 3 番ピン側には書き込み信号だけが伝わります。
プログラムのソースを下に示します。
AVR Studio 4.19 で新規の C プロジェクトを立ち上げ、プロジェクト名を「sin_tn10」とし、自動生成された中身が空白の「sin_tn10.c」に下の内容をコピー・アンド・ペーストします。
「sin_tn10.c」
/*************************************************/ /* sin_tn10.c : sine wave generator for ATtiny10 */ /* using phase accumulator */ /* and sine wave table */ /* */ /* 2011/12/27 : bug fixed */ /* 2011/12/24 : Created by pcm1723 */ /*************************************************/ #include <avr/io.h> #include <avr/interrupt.h> // // mode selection defines // #define USE_SIGMADM // 1st order Sigma-DM PWM #define USE_ADC // PB2 (pin 4) = freq control AD input // // PB1 (pin 3) function select // //#define USE_EXTCLK // PB1 = ext clock in //#define USE_BUSY // PB1 = busy indicator out #define USE_OC0B // PB1 = echo of ADCL / freq2 out #define USE_FOUT2 // PB1 = fixed freq sine out2 // external clock input is top priority #if defined(USE_EXTCLK) #undef USE_BUSY #undef USE_OC0B #undef USE_FOUT2 #endif // busy output is second priority #if defined(USE_BUSY) #undef USE_OC0B #undef USE_FOUT2 #endif // f-number table has 72 entries per octave #define STEPS_PER_OCTAVE (72) // phase increment for 440 Hz @ fs = 15.625 kHz // // PHASE_INC = 440.0 * (2 ** 24) / fs // = 440.0 * (2 ** 24) * 512 / F_CPU // = 440.0 * (2 ** 24) / 15.625e3 // = 440.0 * 1073.742 // = 472446.4 // #define CALC_PHASE_INC(f) ((uint32_t)(0.5+((f)*0x1000000UL*512.0/F_CPU))) #if defined(F_CPU) #define PHASE_INC CALC_PHASE_INC(440.0) #define PHASE_INC2 CALC_PHASE_INC(440.0) #endif // #if defined(F_CPU) #if !defined(PHASE_INC) #define PHASE_INC (472446UL) // for F_CPU = 8 MHz #define PHASE_INC2 (472446UL) // for F_CPU = 8 MHz #endif // pitch index offset #define PITCH_OFS (27) // // OSCCAL byte adjustment value // #define OSCCAL_ADJ (0) typedef union tag_u16_u8_union_t { uint16_t u16; uint8_t u8[2]; } u16_u8_union_t; extern int16_t get_sin(uint16_t ind); // sine wave gerarator extern uint16_t get_fnum(uint16_t ind); // get f-number for the index uint32_t ph_acc; // phase accumulator uint8_t da8_val; // 8 bit DA value #if defined(USE_ADC) uint32_t ph_inc; // phase increment uint16_t idx; // pitch index uint8_t oct; // octave code uint16_t ad_ave; // averaged AD value #endif #if defined(USE_SIGMADM) u16_u8_union_t sdm_work; // for 1st order Sigma-DM #endif #if defined(USE_FOUT2) uint32_t ph_acc2; uint8_t da8_val2; #endif void attiny10_port_setup( void ) { #if defined(USE_EXTCLK) CCP = 0xD8; // set protection signature // CLocK Main Settings Register CLKMS1:CLKMS0 = 10 CLKMSR = _BV(CLKMS1); // select external clock #endif // set clock prescaler to 1/1 (8 MHz clock) CCP = 0xD8; // set protection signature CLKPSR = 0; // clock prescale = 1/1 (8 MHz clock) // add OSCCAL offset CCP = 0xD8; // set protection signature OSCCAL += OSCCAL_ADJ; // add OSCCAL offset // setup PWM // timer mode = 8 bit ph_acc correct PWM (WGM0[3:0] = 0001) TCCR0A = _BV(WGM00); // WGM01:WGM00 = 01 TCCR0B = _BV(CS00); // WGM03:WGM02 = 00, CS00 = 1 (clk/1) // set compare output mode to clear at up, set at down TCCR0A |= _BV(COM0A1); // COM0A1:COM0A0 = 10 #if defined(USE_OC0B) TCCR0A |= _BV(COM0B1); // COM0B1:COM0B0 = 10 DDRB |= _BV(DDB1); // set OC0B (pin 3) to output OCR0BL = 0x80; #endif DDRB |= _BV(DDB0); // set OC0A (pin 1) to output #if defined(USE_BUSY) // BUSY (IDLE) indicator DDRB |= _BV(DDB1); // set PB1 to output #endif OCR0AL = 0x80; #if defined(USE_ADC) DIDR0 = _BV(ADC2D); // Digital Input Disable for PB2 DDRB &= ~(_BV(DDB2)); // set PB2 (pin 4) to input PORTB &= ~(_BV(PORTB2)); // disable PB2 pullup ADMUX = 2; // ADC input from PB2 (pin 4) ADCSRB = _BV(ADTS2); // ADC Auto Trigger Source = Timer0 OVF // ADC clock = 125.0 kHz @ 8 MHz CPU clock // 187.5 kHz @ 12 MHz CPU clock // ADC conversion rate = 1/2 fs = 7.8125 kHz @ 8 MHz CPU clock ADCSRA = ( _BV(ADEN) // ADc ENable | _BV(ADATE) // ADc Auto Trigger Enable | 6 ); // prescaler = 1/32 #endif // #if defined(USE_ADC) } // void attiny10_port_setup() int main() { attiny10_port_setup(); for (;;) { // infinite loop if (_BV(TOV0) & TIFR0) {// Timer0 OVerflow occurred? TIFR0 |= _BV(TOV0); // clear Timer OVerflow flag OCR0AL = da8_val; // output to PWM DAC #if defined(USE_FOUT2) OCR0BL = da8_val2; // output to PWM DAC #endif // #if defined(USE_FOUT2) #if defined(USE_BUSY) PORTB |= _BV(PORTB1); // indicate BUSY #endif // #if defined(USE_BUSY) #if defined(USE_ADC) // variable frequency if (_BV(ADIF) & ADCSRA) { // ADC data ready ADCSRA |= _BV(ADIF); // clear ADc Interrupt Flag // averaging AD value using IIR leaky integrator // X(z) = (1/256) / (1 - (255/256) * z**(-1)) // Time constant = 256/f_adconv = 32.8 ms // DC gain = 1 ad_ave -= (ad_ave >> 8); // decay ad_ave += ADCL; // add new AD value #if (!defined(USE_BUSY) & defined(USE_OC0B) & !defined(USE_FOUT2)) OCR0BL = ADCL; // echo ADC data (8 bit) to OC0B #endif // #if !defined(USE_BUSY) // form averaged ADC data to (1/3) seminote step index idx = (uint8_t)(ad_ave >> 8); // 0..255 idx = (idx << 1) + PITCH_OFS; oct = 0; // assume octave 0 at first // calc octave (oct = idx / STEPS_PER_OCTAVE) // index (idx = idx % STEPS_PER_OCTAVE) while (STEPS_PER_OCTAVE <= idx) { // division loop idx -= STEPS_PER_OCTAVE; // subtract index oct++; // next octave } // while () // get f-number from index and apply octave shift ph_inc = ((uint32_t)get_fnum(idx) << oct); } // if (_BV(ADIF) ... ph_acc += ph_inc; // update phase accumulator #else // fixed frequency ph_acc += PHASE_INC; // update phase accumulator #endif // #if defined(USE_ADC) #if defined(USE_FOUT2) ph_acc2 += PHASE_INC2; // update phase accumulator2 #endif // #if defined(USE_FOUT2) #if defined(USE_SIGMADM) // 1st order Sigma-DM calculation sdm_work.u16 = sdm_work.u8[0] + get_sin(ph_acc >> 8); da8_val = 0x80 ^ sdm_work.u8[1]; #else // ordinal PWM da8_val = 0x80 ^ ((uint16_t) get_sin(ph_acc >> 8) >> 8); #endif // #if defined(USE_SIGMADM)1 #if defined(USE_FOUT2) da8_val2 = 0x80 ^ ((uint16_t) get_sin(ph_acc2 >> 8) >> 8); #endif // #if defined(USE_FOUT2) #if defined(USE_BUSY) PORTB &= ~(_BV(PORTB1)); // indicate IDLE #endif // #if defined(USE_BUSY) } // if (_BV(TOV0) & TIFR0) { ... } // for (;;) } // int main()
プロジェクト・フォルダに下のふたつの (gas で使用する) アセンブラ・ソースファイル (拡張子が「.S」 英大文字の「エス」) を作成し、プロジェクトに追加します。
「stab128.S」
; 512 point sine table ; only first 128 points (0..pi) for symmetry ; (even symmetry table) #include <avr/io.h> .global stab128 stab128: ; ; index/total_points .dc.w 0x00c7 ; 0.5/512 .dc.w 0x0256 ; 1.5/512 .dc.w 0x03e5 ; 2.5/512 .dc.w 0x0574 ; 3.5/512 .dc.w 0x0702 ; 4.5/512 .dc.w 0x0891 ; 5.5/512 .dc.w 0x0a1f ; 6.5/512 .dc.w 0x0bac ; 7.5/512 .dc.w 0x0d39 ; 8.5/512 .dc.w 0x0ec6 ; 9.5/512 .dc.w 0x1052 ; 10.5/512 .dc.w 0x11dd ; 11.5/512 .dc.w 0x1368 ; 12.5/512 .dc.w 0x14f1 ; 13.5/512 .dc.w 0x167b ; 14.5/512 .dc.w 0x1803 ; 15.5/512 .dc.w 0x198a ; 16.5/512 .dc.w 0x1b10 ; 17.5/512 .dc.w 0x1c96 ; 18.5/512 .dc.w 0x1e1a ; 19.5/512 .dc.w 0x1f9d ; 20.5/512 .dc.w 0x211f ; 21.5/512 .dc.w 0x229f ; 22.5/512 .dc.w 0x241e ; 23.5/512 .dc.w 0x259c ; 24.5/512 .dc.w 0x2718 ; 25.5/512 .dc.w 0x2893 ; 26.5/512 .dc.w 0x2a0d ; 27.5/512 .dc.w 0x2b84 ; 28.5/512 .dc.w 0x2cfa ; 29.5/512 .dc.w 0x2e6e ; 30.5/512 .dc.w 0x2fe1 ; 31.5/512 .dc.w 0x3151 ; 32.5/512 .dc.w 0x32c0 ; 33.5/512 .dc.w 0x342d ; 34.5/512 .dc.w 0x3598 ; 35.5/512 .dc.w 0x3700 ; 36.5/512 .dc.w 0x3867 ; 37.5/512 .dc.w 0x39cb ; 38.5/512 .dc.w 0x3b2d ; 39.5/512 .dc.w 0x3c8d ; 40.5/512 .dc.w 0x3deb ; 41.5/512 .dc.w 0x3f46 ; 42.5/512 .dc.w 0x409f ; 43.5/512 .dc.w 0x41f5 ; 44.5/512 .dc.w 0x4348 ; 45.5/512 .dc.w 0x449a ; 46.5/512 .dc.w 0x45e8 ; 47.5/512 .dc.w 0x4734 ; 48.5/512 .dc.w 0x487d ; 49.5/512 .dc.w 0x49c3 ; 50.5/512 .dc.w 0x4b06 ; 51.5/512 .dc.w 0x4c47 ; 52.5/512 .dc.w 0x4d84 ; 53.5/512 .dc.w 0x4ebf ; 54.5/512 .dc.w 0x4ff6 ; 55.5/512 .dc.w 0x512b ; 56.5/512 .dc.w 0x525c ; 57.5/512 .dc.w 0x538a ; 58.5/512 .dc.w 0x54b5 ; 59.5/512 .dc.w 0x55dc ; 60.5/512 .dc.w 0x5701 ; 61.5/512 .dc.w 0x5822 ; 62.5/512 .dc.w 0x593f ; 63.5/512 .dc.w 0x5a59 ; 64.5/512 .dc.w 0x5b70 ; 65.5/512 .dc.w 0x5c83 ; 66.5/512 .dc.w 0x5d93 ; 67.5/512 .dc.w 0x5e9f ; 68.5/512 .dc.w 0x5fa7 ; 69.5/512 .dc.w 0x60ab ; 70.5/512 .dc.w 0x61ac ; 71.5/512 .dc.w 0x62a9 ; 72.5/512 .dc.w 0x63a3 ; 73.5/512 .dc.w 0x6498 ; 74.5/512 .dc.w 0x658a ; 75.5/512 .dc.w 0x6677 ; 76.5/512 .dc.w 0x6761 ; 77.5/512 .dc.w 0x6847 ; 78.5/512 .dc.w 0x6929 ; 79.5/512 .dc.w 0x6a06 ; 80.5/512 .dc.w 0x6ae0 ; 81.5/512 .dc.w 0x6bb5 ; 82.5/512 .dc.w 0x6c87 ; 83.5/512 .dc.w 0x6d54 ; 84.5/512 .dc.w 0x6e1d ; 85.5/512 .dc.w 0x6ee1 ; 86.5/512 .dc.w 0x6fa2 ; 87.5/512 .dc.w 0x705e ; 88.5/512 .dc.w 0x7115 ; 89.5/512 .dc.w 0x71c9 ; 90.5/512 .dc.w 0x7278 ; 91.5/512 .dc.w 0x7322 ; 92.5/512 .dc.w 0x73c8 ; 93.5/512 .dc.w 0x746a ; 94.5/512 .dc.w 0x7507 ; 95.5/512 .dc.w 0x75a0 ; 96.5/512 .dc.w 0x7634 ; 97.5/512 .dc.w 0x76c4 ; 98.5/512 .dc.w 0x774f ; 99.5/512 .dc.w 0x77d5 ; 100.5/512 .dc.w 0x7857 ; 101.5/512 .dc.w 0x78d4 ; 102.5/512 .dc.w 0x794d ; 103.5/512 .dc.w 0x79c0 ; 104.5/512 .dc.w 0x7a30 ; 105.5/512 .dc.w 0x7a9a ; 106.5/512 .dc.w 0x7b00 ; 107.5/512 .dc.w 0x7b61 ; 108.5/512 .dc.w 0x7bbd ; 109.5/512 .dc.w 0x7c14 ; 110.5/512 .dc.w 0x7c67 ; 111.5/512 .dc.w 0x7cb5 ; 112.5/512 .dc.w 0x7cfe ; 113.5/512 .dc.w 0x7d42 ; 114.5/512 .dc.w 0x7d81 ; 115.5/512 .dc.w 0x7dbc ; 116.5/512 .dc.w 0x7df1 ; 117.5/512 .dc.w 0x7e22 ; 118.5/512 .dc.w 0x7e4e ; 119.5/512 .dc.w 0x7e75 ; 120.5/512 .dc.w 0x7e98 ; 121.5/512 .dc.w 0x7eb5 ; 122.5/512 .dc.w 0x7ecd ; 123.5/512 .dc.w 0x7ee1 ; 124.5/512 .dc.w 0x7ef0 ; 125.5/512 .dc.w 0x7ef9 ; 126.5/512 .dc.w 0x7efe ; 127.5/512 ; ; uint16_t get_sin(uint16_t ind); ; ; input parameter : ; uint16_t ind = R25:R24 ; ; function result : R25:R24 ; ; volatile register : R16, Z (R31:R30) ; ; R17 == 0 assumed (AVR C convention) ; .global get_sin .func get_sin FL_START = 0x4000 ; mapped address of FLASH memory get_sin: ; Z (R31:R30) <- stab128 mapped address ldi ZL,lo8(stab128+FL_START) ldi ZH,hi8(stab128+FL_START) lsl r24 ; rol r25 ; C <-- R25:R24 <-- 0 ror r16 ; MSB of R16 <-- C (MSB of R25) sbrc r25,7 ; skip if b7 of R25 cleared (2SB of R25 on entry) com r25 ; 1's complement (bitwise NOT) add ZL,r25 adc ZH,r17 ; add offset add ZL,r25 adc ZH,r17 ; add offset for 2byte data ld r24,Z+ ld r25,Z ; get sine value in R25:R24 sbrs r16,7 ; skip if b7 of R16 set (MSB of R25 on ertry) ret ; positive number ; com r25 neg r24 sbci r25,0xff ; 2's complement of R25:R24 ret ; negative number .endfunc
「fnum6.S」
; 16-bit precision f-number table ; 6 steps per semitone ; 100/6 = 16.66667 cent step #include <avr/io.h> .global fnum6 .global get_fnum FL_START = 0x4000 ; mapped address of FLASH memory fnum6: ;/*** C ***/ .dc.w 0x8000 ; 0.0 cent .dc.w 0x813d ; 16.7 cent .dc.w 0x827d ; 33.3 cent .dc.w 0x83c0 ; 50.0 cent .dc.w 0x8506 ; 66.7 cent .dc.w 0x8650 ; 83.3 cent ;/*** C# ***/ .dc.w 0x879c ; 100.0 cent .dc.w 0x88ec ; 116.7 cent .dc.w 0x8a3f ; 133.3 cent .dc.w 0x8b96 ; 150.0 cent .dc.w 0x8cef ; 166.7 cent .dc.w 0x8e4c ; 183.3 cent ;/*** D ***/ .dc.w 0x8fad ; 200.0 cent .dc.w 0x9111 ; 216.7 cent .dc.w 0x9278 ; 233.3 cent .dc.w 0x93e3 ; 250.0 cent .dc.w 0x9551 ; 266.7 cent .dc.w 0x96c3 ; 283.3 cent ;/*** D# ***/ .dc.w 0x9838 ; 300.0 cent .dc.w 0x99b1 ; 316.7 cent .dc.w 0x9b2e ; 333.3 cent .dc.w 0x9cae ; 350.0 cent .dc.w 0x9e32 ; 366.7 cent .dc.w 0x9fba ; 383.3 cent ;/*** E ***/ .dc.w 0xa145 ; 400.0 cent .dc.w 0xa2d4 ; 416.7 cent .dc.w 0xa468 ; 433.3 cent .dc.w 0xa5ff ; 450.0 cent .dc.w 0xa79a ; 466.7 cent .dc.w 0xa939 ; 483.3 cent ;/*** F ***/ .dc.w 0xaadc ; 500.0 cent .dc.w 0xac83 ; 516.7 cent .dc.w 0xae2e ; 533.3 cent .dc.w 0xafde ; 550.0 cent .dc.w 0xb191 ; 566.7 cent .dc.w 0xb349 ; 583.3 cent ;/*** F# ***/ .dc.w 0xb505 ; 600.0 cent .dc.w 0xb6c5 ; 616.7 cent .dc.w 0xb88a ; 633.3 cent .dc.w 0xba53 ; 650.0 cent .dc.w 0xbc20 ; 666.7 cent .dc.w 0xbdf2 ; 683.3 cent ;/*** G ***/ .dc.w 0xbfc9 ; 700.0 cent .dc.w 0xc1a3 ; 716.7 cent .dc.w 0xc383 ; 733.3 cent .dc.w 0xc567 ; 750.0 cent .dc.w 0xc750 ; 766.7 cent .dc.w 0xc93e ; 783.3 cent ;/*** G# ***/ .dc.w 0xcb30 ; 800.0 cent .dc.w 0xcd27 ; 816.7 cent .dc.w 0xcf23 ; 833.3 cent .dc.w 0xd124 ; 850.0 cent .dc.w 0xd32a ; 866.7 cent .dc.w 0xd535 ; 883.3 cent ;/*** A ***/ .dc.w 0xd745 ; 900.0 cent .dc.w 0xd95a ; 916.7 cent .dc.w 0xdb74 ; 933.3 cent .dc.w 0xdd94 ; 950.0 cent .dc.w 0xdfb9 ; 966.7 cent .dc.w 0xe1e3 ; 983.3 cent ;/*** A# ***/ .dc.w 0xe412 ; 1000.0 cent .dc.w 0xe647 ; 1016.7 cent .dc.w 0xe881 ; 1033.3 cent .dc.w 0xeac1 ; 1050.0 cent .dc.w 0xed06 ; 1066.7 cent .dc.w 0xef51 ; 1083.3 cent ;/*** B ***/ .dc.w 0xf1a2 ; 1100.0 cent .dc.w 0xf3f8 ; 1116.7 cent .dc.w 0xf654 ; 1133.3 cent .dc.w 0xf8b6 ; 1150.0 cent .dc.w 0xfb1e ; 1166.7 cent .dc.w 0xfd8c ; 1183.3 cent ; ; uint16_t get_fnum(uint16_t ind); ; ; input parameter : ; uint16_t ind = R25:R24 ; ; function result : R25:R24 ; ; volatile register : Z (R31:R30) ; .func get_fnum get_fnum: ; Z (R31:R30) <- fnum6 mapped address ldi ZL,lo8(fnum6+FL_START) ldi ZH,hi8(fnum6+FL_START) add ZL,r24 adc ZH,r25 ; add offset add ZL,r24 adc ZH,r25 ; add offset for 2byte data ld r24,Z+ ld r25,Z ; get f-number value in R25:R24 ret ; ;
これを最適化オプション「-Os」でコンパイルすると、プログラム・サイズ 906 バイト、データ・サイズ 21 バイトになります。
sin_tn10.c のソース中の #define で各種の設定ができますが、上のソースでの設定は、
- 内部クロック使用 (USE_EXTCLK 未定義)
- シグマーデルタ変調使用 (USE_SIGMADM 定義)
- 電圧入力による周波数可変 (USE_ADC 定義)
- 2 出力モード (USE_FOUT2 定義)
になっています。
PB0 (ピン 1) から出力されるサイン波の周波数は PB2 (ピン 4) への電圧入力を AD 変換した数値でコントロールされています。
AD 変換後の数値 0 〜 255 に対して、88 鍵ピアノの音域程度 (40 Hz 〜 4 kHz 程度) を割り当てており、数値が 1 変化すると周波数は 1/3 半音 (1.944 %) 変化します。
PB2 (ピン 4) から出力される第二のサイン波の周波数はソースファイル上の定数で決まり、実行時に可変はできません。
上のソースファイルでは、440 Hz に設定してあります。 (正確には 8 MHz クロックで 439.99963 Hz)
もちろん、内部クロックの精度は ±10 % 程度なので、正確な周波数が必要ならば、クロックの周波数を測定して、設定する数値を修正する必要があります。
長くなってきたので、#define による設定の詳細は次回にまわします。
最後にコンパイル結果を fix_lds プログラムに通して lds/sts を書き換えて正常に動作するようにした HEX ファイルを下に示します。 これを ATiny10 に書き込めば動作します。
「sin_tn10_fixed.hex」
:100000000AC019C018C017C016C015C014C013C04C :1000100012C011C010C011271FBFCFE5D0E0DEBF56 :10002000CDBF10E0A0E4B0E001C01D93A535B1073D :10003000E1F720D0A8C1E4CF88ED8CBF16BF8CBFFC :1000400089B789BF81E08EBD8DBD8EB580688EBDBC :100050008EB580628EBD099A80E884BD089A86BDFF :1000600084E087BB0A98129892E09BBB8CBB86EA1F :100070008DBB0895CF93DF93DFDF0AB500FFFDCF7F :100080008AB581608ABD89A1000086BD88A1000073 :1000900084BD8DB384FF3EC0EC9A81A3000092A37F :1000A0000000292F3327821B930B92AB000081ABFA :1000B000000029B3820F911F92AB000081AB0000BA :1000C000892F90E0880F991F855E9F4F20E003C025 :1000D00088549040232F322F3F5F88349107C0F718 :1000E0008EA900009FA9000020AB000043D1A0E032 :1000F000B0E000A3000004C0880F991FAA1FBB1F17 :100100000A95D2F780A9000091A90000A2A90000D9 :10011000B3A9000020A1000031A1000042A100000D :1001200053A1000084A1000095A10000A6A1000039 :10013000B7A10000280F391F4A1F5B1F24A9000028 :1001400035A9000046A9000057A900008AA10000B7 :100150009BA10000ACA10000BDA1000082589A4CF8 :10016000A84FBF4F8AA900009BA90000ACA90000BE :10017000BDA9000083A30000C82FD0E0BB27A52F96 :10018000942F832F9CD0C80FD91FD4AB0000C3ABD2 :10019000000084A30000805889A900008AA1000003 :1001A0009BA10000ACA10000BDA10000892F9A2FE7 :1001B000AB2FBB2784D0905898A900005ECFC70012 :1001C0005602E5037405020791081F0AAC0B390DAE :1001D000C60E5210DD116813F1147B1603188A192C :1001E000101B961C1A1E9D1F1F219F221E249C253A :1001F000182793280D2A842BFA2C6E2EE12F5131CB :10020000C0322D34983500376738CB392D3B8D3CC3 :10021000EB3D463F9F40F54148439A44E84534470B :100220007D48C349064B474C844DBF4EF64F2B517A :100230005C528A53B554DC55015722583F59595ADC :10024000705B835C935D9F5EA75FAB60AC61A962EE :10025000A36398648A657766616747682969066A57 :10026000E06AB56B876C546D1D6EE16EA26F5E70B7 :100270001571C97178722273C8736A740775A07595 :100280003476C4764F77D5775778D4784D79C0795E :10029000307A9A7A007B617BBD7B147C677CB57C6D :1002A000FE7C427D817DBC7DF17D227E4E7E757E11 :1002B000987EB57ECD7EE17EF07EF97EFE7EEEEB11 :1002C000F1E4880F991F079597FD9095E90FF11FAD :1002D000E90FF11F8191908107FF08959095819515 :1002E0009F4F089500803D817D82C08306855086A2 :1002F0009C87EC883F8A968BEF8C4C8EAD8F11914A :100300007892E3935195C3963898B1992E9BAE9C01 :10031000329EBA9F45A1D4A268A4FFA59AA739A985 :10032000DCAA83AC2EAEDEAF91B149B305B5C5B63C :100330008AB853BA20BCF2BDC9BFA3C183C367C585 :1003400050C73EC930CB27CD23CF24D12AD335D5B2 :1003500045D75AD974DB94DDB9DFE3E112E447E60F :1003600081E8C1EA06ED51EFA2F1F8F354F6B6F8D0 :100370001EFB8CFDE4EEF2E4E80FF91FE80FF91F15 :0A038000819190810895F894FFCF59 :00000001FF