m2c_tn10.h、m2c_tn10_c

「m2c_tn10.h」内の #define で、GATE 出力などのピン・アサインを変更できますが、CV 出力については PB0 (1 番ピン) に固定です。
シリアル MIDI (38.4 kbps) 時の CPU クロック周波数を 7.9872 MHz に、および、レガシー MIDI (31.25 kbps) 時のクロック周波数を 6.5 MHz に設定するための OSCCAL の補正値が、それぞれ OSCCAL_ADJ_8M、OSCCAL_ADJ_6M5 です。
あるサンプル 1 個についての測定データから求めた値なので、厳密には、各個体ごとに測定を行って決定する必要があります。
他のサンプル 2 個について、そのままプログラムを書きこんで実行してみましたが、特に問題はありませんでした。
CPU クロック周波数を調整する場合には次のようにします。
CPU クロックを 512 分周したものが PWM 周波数となっているので、まず、PB0 (1 番ピン) の周波数を測って 512 倍して CPU クロック周波数を求め、目的の周波数との差を算出します。
OSCCAL の値を 1 増減すると、CPU クロック周波数は約 40 kHz 増減するので、CPU クロック周波数差を 40 kHz で割れば、OSCCAL_ADJ のおよその修正量が計算できます。
あとは、修正したプログラムを書いてみて、クロック周波数を再測定し、精度が十分でなければ、数値の微調整、再書き込み、再測定を必要なだけ繰り返します。

/*************************************************/
/* m2c_tn10.h : MIDI to CV converter             */
/*              for ATtiny10                     */
/*                                               */
/* 2012/01/16 : Created by pcm1723               */
/*************************************************/
  
#ifndef _M2C_TN10_H_
#define _M2C_TN10_H_

// uncomment following '#define'
// to use GATE output as UART DEBUG output
//#define UART_DEBUG

// Synth CV output port bit assign (PWM DAC)
#define CV_BIT   (PORTB0)
// Synth GATE output port bit assign
#define GATE_BIT (PORTB1)
// MIDI RxD input port bit assign
#define RXD_BIT  (PORTB2)
// serial MIDI / legacy MIDI sense input port bit assign
#define SENS_BIT (PORTB1)

// Synth GATE delay queue length (1..16)
// in terms of Timer0 OVerFlow count 
// at 15.625 kHz (serial MIDI) 
//    12.695 kHz (legacy MIDI) rate
// 16 / 15.625 [kHz] = 1.024 [ms]
#define GATE_QUE_LEN (16)

//
// OSCCAL byte adjustment value @ 5 V
// for serial MIDI (38.4 kbps)
// for 7.9872 MHz CPU clock
//
#define OSCCAL_ADJ_8M (0x9E - 0x98)
//
// OSCCAL byte adjustment value @ 5 V
// for (legacy) MIDI (31.25 kbps)
// for 6.5 MHz CPU clock
//
#define OSCCAL_ADJ_6M5 (0x78 - 0x98) 

#endif
/*************************************************/
/* m2c_tn10.c : MIDI to CV converter             */
/*              for ATtiny10                     */
/*                                               */
/* 2012/01/16 : Created by pcm1723               */
/*************************************************/
  
#include <avr/io.h>
#include <avr/interrupt.h>
#include "m2c_tn10.h"
#include "sw_uart_rx.h"
#include "mididec.h"
#include "midifunc.h"

typedef union tag_u16_u8_union_t {
  uint16_t u16;
  uint8_t  u8[2];
} u16_u8_union_t;

void tn10_port_setup( void )
{
// set serial MIDI / legacy MIDI SENS input
  DDRB &= ~(_BV(SENS_BIT)); // input mode
  PUEB |=   _BV(SENS_BIT);  // enable pull up 
// wait a while to stabilize port input
  ch_prop[0].MD_bend_range = 0xff; 
  MD_ch = 255;
  do {
    calc_pitch(0); // dummy call to spent time
  } while (0 != (--MD_ch));  
  if (_BV(SENS_BIT) & PINB) { // SENS input == 'H'
// add OSCCAL offset for 8 MHz (serial MIDI, 38.4 kbps)
    CCP     = 0xD8; // set protection signature
    OSCCAL += OSCCAL_ADJ_8M; // add OSCCAL offset for 8 MHz
  } // if
  if (0 == (_BV(SENS_BIT) & PINB)) { // SENS input == 'L'
// add OSCCAL offset for 6.5 MHz (legacy MIDI, 31.25 kbps)
    CCP     = 0xD8; // set protection signature
    OSCCAL += OSCCAL_ADJ_6M5; // add OSCCAL offset for 6.5 MHz
  } // if (_BV(CV_BIT) ...
// set clock prescaler to 1/1 (8 MHz clock)
  CCP     = 0xD8; // set protection signature
  CLKPSR  = 0;    // clock prescale = 1/1 (8 MHz clock)
// disable pull up for SENS port
  PUEB &=  ~(_BV(SENS_BIT)); 
// setup PWM (fs = 31.25 kHz @ 8 MHz, fs = 12.695 kHz @ 6.5 MHz)
// timer mode = 9 bit Fast PWM (WGM0[3:0] = 0110)
  TCCR0A  =  _BV(WGM01); // WGM01:WGM00 = 10
  TCCR0B  = (_BV(WGM02)  // WGM03:WGM02 = 01
            |_BV(CS00)); // CS02:CS00 = 001 (clk/1)
// set compare output mode to set at BOTTOM
  TCCR0A |= _BV(COM0A1); // COM0A1:COM0A0 = 10 
  DDRB   |= (_BV(DDB0)   // set OC0A (pin 1) to output (PWM-CV)
            |_BV(GATE_BIT)); // set PB1  (pin 3) to output (GATE)
  OCR0A  = 0x00;
//  TIMSK0  = _BV (TOIE0); // timer overflow interrupt enable
  tn10_sw_uart_setup(); // software UART setup
  sei(); // enable global interrupt flag
} // void tn10_port_setup()

int main() 
{
  cli(); // disable interrupt
  SP = RAMEND; // re-initialize SP to save SRAM
  tn10_port_setup(); // hardware and software setup
  GM_reset();
  for (;;) { // infinite loop
    if (_BV(sw_RXC) & uart_flag) { // UART Rx ready?
      uart_flag &= ~(_BV(sw_RXC)); // clear UART flag
      if (0x80 & uart_rx_buf) { // MIDI status byte
        mididec(uart_rx_buf); // decode MIDI status byte
      } else { // MIDI data byte
        MD_data = uart_rx_buf; // received data
        if (md_data_byte()) { // process data byte
          md_cc_func(); // process Control Change
        } // if (md_data_byte()) { ...
      } // if(0x80 & ...
    } // if (_BV(sw_RXC) ...
    if (_BV(TOV0) & TIFR0) { // Timer0 OVerFlow detected?
      TIFR0 |= _BV(TOV0); // clear TOV0 flag
#if !defined(UART_DEBUG)
      if ((1 << (16-GATE_QUE_LEN)) & unit_prop[0].gate_que) {
        GATE_ON;
      } else {
        GATE_OFF;
      } // if ((1 << (16-GATE_QUE_LEN)) & unit_prop[0].gate_que)
#endif
      unit_prop[0].gate_que >>= 1;
    } // if (_BV(TOV0) & TIFR0) { ...
  } // for (;;)
} // int main()