/*
 * A/D変換を行うルーチン
 * 
 * @author fenrir (M.Naruoka)
 * @since 04/06/02
 * @version 1.0
 */
#include "AKI3694.h"
#include <common.h>
#include <util/fifo_num.h>
#include "ad.h"

static num_t buffer_ad[(AD_BUFFER_SIZE + 1) * AD_CH];
fifo_num_t fifo_ad[AD_CH];

/**
 * A/D変換の初期設定をする関数
 * 
 */
void ad_init(){
    
    /* A/D変換後用のFIFOの初期化 */
    int i;
    for(i = 0; i < AD_CH; i++){
        fifo_num_init(&(fifo_ad[i]), &(buffer_ad[(AD_BUFFER_SIZE + 1) * i]), (AD_BUFFER_SIZE + 1));
    }
    
    /* A/D変換停止 */
    AD.ADCSR.BIT.ADST = 0;
    
    /* スキャンモード
     * 高速変換
     * 割り込み可
     * はじめはグループ0のAD0〜AD3を変換
     * 8チャンネル時はさらにその後グループ1のAD4〜AD7を変換
     */
  AD.ADCSR.BYTE = 0x5b;  //5
}

/**
 * A/D変換の開始をする関数
 * インターバルタイマの割り込みによって、
 * またグループ0のAD変換終了後に呼び出してもらう。
 * 
 * @see ad_end();
 */
void ad_start(){
    AD.ADCSR.BIT.ADST = 1; /* A/D変換スタート */
}

/**
 * A/D変換の終了後に起動される関数
 * 割り込みで呼び出してもらう
 * 
 * @see int_ad();
 */
void ad_end(){

    AD.ADCSR.BYTE &= 0x5f;  /* 終了フラグをクリア & AD変換を完全停止*/

#if AD_CH > 4
    /* どっちのグループを変換していたか */
    if((AD.ADCSR.BYTE & 0x04) == 0){
#endif

        /* グループ0(AD0〜AD3)を変換していた */
        
#if DEBUG > 2
        fifo_num_write(&fifo_ad[0], 230);
        fifo_num_write(&fifo_ad[1], 340);
        fifo_num_write(&fifo_ad[2], 560);
        fifo_num_write(&fifo_ad[3], 780);
#else
        /*fifo_num_write(&fifo_ad[0], ((AD.ADDRA_H << 8) | AD.ADDRA_L)); 旧方式 */
    fifo_num_write(&fifo_ad[0], AD.ADDRA.u16);
        fifo_num_write(&fifo_ad[1], AD.ADDRB.u16);
        fifo_num_write(&fifo_ad[2], AD.ADDRC.u16);
        fifo_num_write(&fifo_ad[3], AD.ADDRD.u16);
#endif

#if AD_CH > 4
        AD.ADCSR.BYTE |= 0x04; /* グループ1に切り替えて */
        ad_start(); /* 再度AD変換 */
    }else{
        
        /* グループ1(AD4〜AD7)を変換していた */

#if DEBUG > 2
        fifo_num_write(&fifo_ad[4], 230);
        fifo_num_write(&fifo_ad[5], 340);
        fifo_num_write(&fifo_ad[6], 560);
        fifo_num_write(&fifo_ad[7], 780);
#else
        fifo_num_write(&fifo_ad[4], AD.ADDRA.u16);
        fifo_num_write(&fifo_ad[5], AD.ADDRB.u16);
        fifo_num_write(&fifo_ad[6], AD.ADDRC.u16);
        fifo_num_write(&fifo_ad[7], AD.ADDRD.u16);
#endif
        
        AD.ADCSR.BYTE &= ~(0x04); /* グループ0に切り替え */
    }
#endif
}

/**
 * A/D変換の終了によって呼びだされる割り込み関数
 * 
 * @see ad_end
 */
#pragma interrupt
void int_ad(){
    if(AD.ADCSR.BIT.ADF){AD.ADCSR.BIT.ADF = 0;}
    ad_end();
}