//#################################
//② I/O設定関数 (io_config.c 想定)
//#################################
#include "main.h"

void IO_Config(void) {
    // クロック有効化
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | RCC_APB2Periph_TIM1 , ENABLE);
    RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3 | RCC_APB1Periph_TIM4, ENABLE);


    // 1-1. GPIOクロックおよびSPI1クロック有効化   PB7 OSC
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_SPI1, ENABLE);

    GPIO_InitTypeDef GPIO_InitStructure = {0};

    // PA5(SCK), PA7(MOSI) -> SPIオルタネート出力GMT130 (SCK)(SDA) 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // PB3(DC),PB4(RES)-> 一般出力 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 ;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    // PB7(AGC),PB6(BF),PB5(Fo)設定ロック入力(SWをGNDで設定値固定)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5 ;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    // 1-2. SPI1 設定
    SPI_InitTypeDef SPI_InitStructure = {0};
    SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; // 送信専用
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; // 144MHz/4 = 36MHz (ST7735の高速通信用)
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_Init(SPI1, &SPI_InitStructure);
    SPI_Cmd(SPI1, ENABLE);


    // 2-1. アナログ入力ピン設定 (PA0〜PA4: 可変抵抗, PB0: 音声入力)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // PB0
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    // 2-2. ADC1 & ADC2設定
    ADC_InitTypeDef ADC_InitStructure = {0};
    ADC_InitStructure.ADC_Mode =ADC_Mode_Independent;//ADC_独立モード;
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel = 1;
    // ADC1初期化 (メインループの可変抵抗用)
    ADC_Init(ADC1, &ADC_InitStructure);
    ADC_Cmd(ADC1, ENABLE);

    // ADC2初期化 (💡 割り込みの音声用に追加)
    ADC_Init(ADC2, &ADC_InitStructure);
    ADC_Cmd(ADC2, ENABLE);

    // 2-3.校正
    ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1));
    ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1));

    ADC_ResetCalibration(ADC2); while(ADC_GetResetCalibrationStatus(ADC2));
    ADC_StartCalibration(ADC2); while(ADC_GetCalibrationStatus(ADC2));

// TIM共通
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = {0};
    TIM_OCInitTypeDef TIM_OCInitStructure = {0};

// TIM1_1 GMT130用 PWM スクリーン輝度制御
// TIM1_2 LCDの表示タイミング 200ms周期
    // 3-1. バックライトPWMピン設定 (PA8 - TIM1_CH1)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 3-2. タイマー基本設定 (144MHzベースで100Hzを作る)
    TIM_TimeBaseStructure.TIM_Period = 99;         // 0-100%制御用 (0-100 -> 100 - 1 = 99で設定 )
    TIM_TimeBaseStructure.TIM_Prescaler = 14399;    // 144MHz / 14400 = 10kHz (1カウント = 0.1ms)
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); // 0.1ms * 100 = 10ms (100Hz)
    
    // 3-3. TIM1_CH1設定 (バックライトPWM用)
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 50;             // 初期値50%
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC1Init(TIM1, &TIM_OCInitStructure);

    // 3-4. TIM1_CH2設定 (200ms割り込み生成用)
  //  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing; // ピン出力は使わず内部タイマーのみ
  //  TIM_OCInitStructure.TIM_Pulse = 0;              // カウンターが0の時に一致（任意でOK）


    // 3-5. タイマーの「更新(Update)」割り込みを有効化
    TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE); // TIM_IT_CC2 から変更

    // 3-6. NVIC（割り込みコントローラ）の設定
    NVIC_InitTypeDef NVIC_InitStructure = {0};
    NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn; // 💡TIM1_CC_IRQn から TIM1_UP_IRQn に変更
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    // 3-7. 高級タイマー出力許可 ＆ タイマースタート
    TIM_CtrlPWMOutputs(TIM1, ENABLE); 
    TIM_Cmd(TIM1, ENABLE);


// TIM3 音声出力 PWM

    // 4-1. 音声出力PWM設定 (PA6 - TIM3_CH1)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 4-2. タイマー基本設定 (144MHzベースで約35.16 kHzを作る)
    TIM_TimeBaseStructure.TIM_Period  = 4095; // 12bit PWM
    TIM_TimeBaseStructure.TIM_Prescaler = 0;   // 最高速
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

    // 4-3. TIM3_CH1設定 PWM
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 2048; // 初期値センター
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC1Init(TIM3, &TIM_OCInitStructure);
    TIM_CtrlPWMOutputs(TIM3, ENABLE);
    TIM_Cmd(TIM3, ENABLE);

// TIM4 AD BPF処理割り込み   
    // 144MHz(SYSCLK)ベースで8kHzを作る設定例
    TIM_TimeBaseStructure.TIM_Period = 18000 - 1; 
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

    TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
    
    NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    
    TIM_Cmd(TIM4, ENABLE);
}

// チャンネル切り替え用ADC読込関数
uint16_t Read_ADC(uint8_t ch) {
    ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5);
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
    return ADC_GetConversionValue(ADC1);
}

// 💡 割り込み専用のADC2読み込み関数
uint16_t Read_ADC2(uint8_t ch) {
    ADC_RegularChannelConfig(ADC2, ch, 1, ADC_SampleTime_239Cycles5);
    ADC_SoftwareStartConvCmd(ADC2, ENABLE);
    while(!ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC));
    return ADC_GetConversionValue(ADC2);
}

