commit 9d59a409cfb1984de20957ab20f8d1991c461a76 Author: Lillian Skinner <56081713+rvtr@users.noreply.github.com> Date: Tue Dec 17 04:24:29 2024 -0500 Add files via upload diff --git a/ADC.c b/ADC.c new file mode 100644 index 0000000..eddc427 --- /dev/null +++ b/ADC.c @@ -0,0 +1,463 @@ +#pragma interrupt INTAD callbk_int_ad + +/****************************************************************************** + 1Ch ADCリード + de JHL 藤田@開技 + '07 Dec +*******************************************************************************/ +#include "incs.h" + +extern bit adc_calib_mode; +extern u8 vregs[]; + +extern bit pwon_wt_sel; + + +// Vref = 2.8V +// F B 7 3 1 0 +u8 const threshold_Co[] = { 99, 82, 67, 31, 0 }; // batt == 0 +u8 const threshold_Co_NAND[] = { 99, 82, 68, 46, 27 }; +u8 const threshold_PSS[] = { 77, 52, 33, 11, 0 }; // batt == 5 +u8 const threshold_PSS_NAND[] = { 82, 55, 42, 30, 27 }; +u8 const threshold_IS[] = { 78, 62, 48, 32, 0 }; // batt == 3, vref = 3.3v、オフセットあり(1.8V) +u8 const threshold_IS_NAND[] = { 78, 62, 48, 32, 16 }; +// 非 NAND アプリは 0 になりません。 +/* +>> (AVref=3.3Vとした,AOUTの電圧) +>>  100% 1.95 〜 5 F +>>   75% 1.9 〜 1.95V 4 B +>>   50% 1.85 〜 1.9V 3 7 +>>   25% 1.8 〜 1.85V 2 3 +>>   5% 1.75 〜 1.8V 1 1 +>>   2% 1.7 〜 1.75V 0 0 + */ + +u16 vBatt_raw; // 補正値加算前 +u16 vBatt; // 移動平均をとった物 + +u8 adc_comp_val; // 補正値。閾値テーブルを作るときに加算 + +u16 Vbatt_threshold[5]; + +u8 battLvl; +u8 battLvl_old; // 割り込みをかけるため。使い回してます + + +/****************************************************************************** + 電池電圧→電池残量換算 + 電池劣化とか、負荷による電池電圧の降下は気にしません。 + BOOTモードのときは来ません + 25Hz( = 40ms間隔 )で呼ばれます + ******************************************************************************/ +void tsk_adc(){ + static u16 vBatt_vals[ 9 ]; + static u8 trigger_counter; + static u16 geta; + static u16 vBatt_last_wake; + + static u8 battLvl_hist; + static u8 battLvl_count; + u8 battLvl_now; + + static u8 vBatt_th_hys[ 5 ]; + + static u8 on_start = 0; + +#ifdef debug_codes + if( !pwon_wt_sel ){ +#endif + battLvl_old = battLvl; + + // パルス性のノイズを取り、データの取り込み + vBatt_vals[ 8 ] = vBatt_vals[ 7 ]; + vBatt_vals[ 7 ] = vBatt_vals[ 6 ]; + vBatt_vals[ 6 ] = vBatt_vals[ 5 ]; + vBatt_vals[ 5 ] = vBatt_vals[ 4 ]; + vBatt_vals[ 4 ] = vBatt_vals[ 3 ]; + vBatt_vals[ 3 ] = vBatt_vals[ 2 ]; + vBatt_vals[ 2 ] = vBatt_vals[ 1 ]; + if( ( ( vBatt_vals[ 0 ] << 1 ) < ( vBatt_vals[ 1 ] + vBatt_raw + 5 ) ) + && ( ( vBatt_vals[ 0 ] << 1 ) > ( vBatt_vals[ 1 ] + vBatt_raw - 5 ) ) ){ + vBatt_vals[ 1 ] = vBatt_vals[ 0 ]; + }else{ + vBatt_vals[ 1 ] = ( ( vBatt_vals[ 0 ] + vBatt_raw ) >> 1 ); + } + vBatt_vals[ 0 ] = vBatt_raw; + vBatt = ( ( vBatt_vals[ 8 ] + vBatt_vals[ 7 ] + vBatt_vals[ 6 ] + vBatt_vals[ 5 ] + + vBatt_vals[ 4 ] + vBatt_vals[ 3 ] + vBatt_vals[ 2 ] + vBatt_vals[ 1 ] ) >> 3 ); + + // スリープ時の、ゲタ見積もり + if( PM_SLP == 0 ){ + trigger_counter = 0; + geta = 0; + }else{ + trigger_counter++; + if( trigger_counter == 1 ){ + ; // カウンタの帳尻合わせです + }else if( trigger_counter == 2 ){ + vBatt_last_wake = vBatt_vals[ 8 ]; + if( vBatt_last_wake > vBatt_vals[ 7 ] ) vBatt_last_wake = vBatt_vals[ 7 ]; + if( vBatt_last_wake > vBatt_vals[ 6 ] ) vBatt_last_wake = vBatt_vals[ 6 ]; + if( vBatt_last_wake > vBatt_vals[ 5 ] ) vBatt_last_wake = vBatt_vals[ 5 ]; + if( vBatt_last_wake > vBatt_vals[ 4 ] ) vBatt_last_wake = vBatt_vals[ 4 ]; + if( vBatt_last_wake > vBatt_vals[ 3 ] ) vBatt_last_wake = vBatt_vals[ 3 ]; + if( vBatt_last_wake > vBatt_vals[ 2 ] ) vBatt_last_wake = vBatt_vals[ 2 ]; + if( vBatt_last_wake > vBatt_vals[ 1 ] ) vBatt_last_wake = vBatt_vals[ 1 ]; + }else if( trigger_counter < 127 ){ + geta = vBatt - vBatt_last_wake; + if( geta > 0x8000 ){ + geta = 0; + } + }else{ + trigger_counter--; + } + } + + if( ( vBatt - geta ) > Vbatt_threshold[ 0 ] ){ battLvl_now = 0x05; + }else if( ( vBatt - geta ) > Vbatt_threshold[ 1 ] ){ battLvl_now = 0x04; + }else if( ( vBatt - geta ) > Vbatt_threshold[ 2 ] ){ battLvl_now = 0x03; + }else if( ( vBatt - geta ) > Vbatt_threshold[ 3 ] ){ battLvl_now = 0x02; + }else if( ( vBatt - geta ) > Vbatt_threshold[ 4 ] ){ battLvl_now = 0x01; + }else{ battLvl_now = 0x00; + } + + DBG_IIC_REG_TMP3( (u8)vBatt ); + DBG_IIC_REG_TMP2( battLvl_now ); + + if( battLvl_hist != battLvl_now ){ + battLvl_count = 0; + battLvl_hist = battLvl_now; + }else{ + ++battLvl_count; + if( on_start < 30 ){ + // 起動直後は電池電圧早く出す + on_start++; + if( battLvl_count > 10 ){ // 何回か同じ値を連続でとったら、更新 + battLvl_count = 0; + battLvl = battLvl_now; + } + }else{ + // 通常運転 + if( battLvl_count > 25 ){ // 何回か同じ値を連続でとったら、更新 + battLvl_count = 0; + if( n_ac_supp == 0 ){ // アダプタの有無で一方通行 + // アダプタの有り + if( battLvl_now > battLvl ){ + battLvl++; + } + if( ( battLvl_now != battLvl ) + && ( battLvl_now == 0x00 ) ) { // タイミングが悪く、アダプタありにも関わらずbatt-empty + battLvl = 0; + } + }else{ + // アダプタなし + if( battLvl_now < battLvl ){ + battLvl--; + } + } + } + } + } +#ifdef debug_codes + } +#endif + switch( battLvl ){ // マイコン遅い + case( 2 ): vregs[ REG_INT_ADRS_POWER_INFO ] = 0x03; break; + case( 3 ): vregs[ REG_INT_ADRS_POWER_INFO ] = 0x07; break; + case( 4 ): vregs[ REG_INT_ADRS_POWER_INFO ] = 0x0B; break; + case( 5 ): vregs[ REG_INT_ADRS_POWER_INFO ] = 0x0F; break; + case( 0 ): vregs[ REG_INT_ADRS_POWER_INFO ] = 0x00; break; + default: vregs[ REG_INT_ADRS_POWER_INFO ] = 0x01; break; + } + +#ifdef debug_saito_special + GPIO_dir = 0; + GPIO_dat = (bit)( battLvl & 0x01 ); +#endif + + chk_obs_pmic_batt_low(); // NTR向け、電池残量減少通知 +#ifdef debug_codes + if( !pwon_wt_sel ){ + chk_irq0_batt(); // 電池残量減少割り込み + } +#else + chk_irq0_batt(); +#endif + ADC_Start(); +} + + + +/****************************************************************************** + NTRの一部のソフトが、PMIC側の battery_low ビットを見ているのでセットしてやる + ******************************************************************************/ +void chk_obs_pmic_batt_low(){ + // 減ってきたので通知 + if( ( 0x02 < battLvl_old ) + && ( battLvl <= 0x02 ) ){ + iic2m_write_data( IIC_SLV_ADDR_PMIC, 0x02, 0x10 ); // LEDを赤相当に + } + // 増えてきたので復帰 + if( ( battLvl_old <= 0x03 ) + && ( 0x03 < battLvl ) ){ + iic2m_write_data( IIC_SLV_ADDR_PMIC, 0x02, 0x00 ); // LEDを緑相当に + } +} + + + +/****************************************************************************** + 電池減ってきた割り込みをかける + ******************************************************************************/ +void chk_irq0_batt(){ + static u8 irq_hist = 0; + + // low割り込み + if( ( battLvl == 0x01 ) + && ( irq_hist == 0 ) ){ + irq_hist = 0x02; + vregs[ REG_INT_ADRS_IRQ ] |= 0x20; + if( is_TWL ){ +// DI(); + n_irq_ast; + n_irq_ngt; +// EI(); + } + } + + if( with_NAND ){ + // empty割り込み + // 電圧検出の所の仕様により、残量1を飛び越して0になることはない...はず。 + if( battLvl == 0x00 ){ + if( irq_hist == 0x00 ){ // 突然 emptyになった? + irq_hist = 0x03; + vregs[ REG_INT_ADRS_IRQ ] |= 0x30; // そうなら、両方立てる + if( is_TWL ){ +// DI(); + n_irq_ast; + n_irq_ngt; +// EI(); + } + }else if( irq_hist == 0x02 ){ // 以前にLow割り込みをかけた + irq_hist = 0x03; + vregs[ REG_INT_ADRS_IRQ ] |= 0x10; // 割り込みを掛けまくらないように + if( is_TWL ){ +// DI(); + n_irq_ast; + n_irq_ngt; +// EI(); + } + } + } + } + + // 電池あがってきたらフラグ消してしまう + if( battLvl >= 0x01 ){ // low以上なら +// DI(); + vregs[ REG_INT_ADRS_IRQ ] &= ~0x10; // emptyなかったことに +// EI(); + irq_hist &= ~0x01; + } + + if( battLvl >= 0x02 ){ // lowより上なら +// DI(); + vregs[ REG_INT_ADRS_IRQ ] &= ~0x30; // lowもemptyもなかったことに +// EI(); + irq_hist &= ~0x03; + } +} + + + + +/****************************************************************************** + 電池が判明/モード切替で閾値セット + ******************************************************************************/ +void set_batt_th(){ + u8 *p_tbl; + u8 tmp; + + if( with_NAND ){ + if( vregs[ REG_INT_ADRS_BATT_INFO ] == BATT_CO ){ // Co (0b000) + p_tbl = &threshold_Co_NAND[0]; + }else if( vregs[ REG_INT_ADRS_BATT_INFO ] == BATT_IS ){ // IS (0b011) + p_tbl = &threshold_IS_NAND[0]; + }else{ // PSS (0b111) + p_tbl = &threshold_PSS_NAND[0]; + } + }else{ // NAND 保護なし + if( vregs[ REG_INT_ADRS_BATT_INFO ] == BATT_CO ){ + p_tbl = &threshold_Co[0]; + }else if( vregs[ REG_INT_ADRS_BATT_INFO ] == BATT_IS ){ + p_tbl = &threshold_IS[0]; + IS_led_cam = 0; // 赤箱対応 + IS_led_cam_mode = 0; // 赤箱対応 + }else{ + p_tbl = &threshold_PSS[0]; + } + } + for( tmp = 0; tmp != 5; tmp++ ){ + Vbatt_threshold[ tmp ] = 512 + adc_comp_val + *p_tbl; + p_tbl++; + } +} + + + +/****************************************************************************** + VoffLの測定 + + 4ms間隔で取り込み、必要なところの8この平均取ります。 + ____________________________ + /RESET ______ + ---------_________|←30ms →| + VDET+ →+-----____ + | \____ + ADCサンプリング ***||||||||**** +  この辺 8個の平均とる + ******************************************************************************/ +void tsk_adc_calib(){ + u8 adc_avg; + static u8 count_for_IS = 0; + static u8 state = 0; + static u8 adc_raw_data_B[8], adc_raw_data_A[4]; // 平均対象のB,対象外のA + static u16 adc_sum8 = 0; + static u8 adc_rec_val = 0; + static u8 count = 0; + + switch( state ){ + case( 0 ): + // 下準備 + IIC0_Stop(); + TMH0_Stop(); // pow_R + TMH1_Stop(); // pow_B + TM50_Stop(); // wifi + P1.7 = 1; // Y + P1.5 = 1; // R + P1.6 = 1; // B + CR51 = 125 - 1 ; // T = 4ms + iic2m_write_data( IIC_SLV_ADDR_PMIC, 0x02, (u8*)0x00 ); + state = 1; + break; + case( 1 ): + // スリープ待ち。赤箱なら待たない +// if( vregs[ REG_INT_ADRS_BATT_INFO ] == BATT_IS ){ +// state = 2; +// }else{ + { + if( PM_SLP == 1 ){ + P1.7 = 0; // Y + vregs[ REG_INT_ADRS_POWER_SAVE ] = 0x07; + PM_set_VRSET(); + state = 2; + } + } + break; + + case( 2 ): + // vBatt_raw は補正されてない 素 の値です + // 値域がだいたい決まっているので、下8ビットしかみない。 + // 余裕をみて 3.1〜3.5Vでみても、567〜640なので、512引いて、55〜128でまだまだ余裕 + // それ以上だったら取得失敗扱い(無視) + if( ( vBatt_raw > ( 512 + 0x60 ) ) || ( vBatt_raw < ( 512 + 0x40 ) ) ){ + break; + } + // まず、計算対象のバッファ8個を埋める + adc_raw_data_B[ count ] = (u8)( vBatt_raw & 0x00FF ); // マスクしない。信じてる。 + adc_sum8 += ( vBatt_raw & 0x00FF ); + if( count == 7 ){ // 8回ためる + count = 0; + state = 3; + }else{ + count++; + } + break; + + case( 3 ): + // 次に、ディレイ用のバッファ4個を埋める + adc_raw_data_A[ count ] = (u8)( vBatt_raw & 0x00FF ); + if( count == 3 ){ // 4回ためる + P1.6 = 0; // B + count = 0; + state = 4; + }else{ + count++; + } + break; + + default: + if( n_sys_reset != 0 ){ // リセットを見るのはどちらかというと誤書き込み防止 + // 微妙タイミングなら、放電の方が早くてたぶん書き込み完了しない + + adc_avg = (u8)( adc_sum8 / 8 ); + // なんと、半端なシフトは割り算になる(25clk)シフト&調整より早いと言うことか。 + // IS対応 + if( vregs[ REG_INT_ADRS_BATT_INFO ] == BATT_IS ){ + adc_avg -= ( 9 + 16 ); // キャリブレーションが1.8V @ ref = 3.3 を1.65Vに換算 + if( flash_write( DAT_ADC_COMP, &adc_avg ) == 0 ){ // 目立たないけど、ここで書き込み + mcu_reset; + } + } + // 必要なら記録 + if( adc_rec_val != adc_avg ){ + if( flash_write( DAT_ADC_COMP, &adc_avg ) == 0 ){ + P1.5 = 0; // R + P1.6 = 1; // B + adc_rec_val = adc_avg; + P1.6 = 0; // B + P1.5 = 1; // R + } + } + + // リングバッファ等更新 + if( ( vBatt_raw & 0x00FF ) < 128 ){ + adc_sum8 -= adc_raw_data_B[ count ]; // 合計から古いのを引く + adc_raw_data_B[ count ] = adc_raw_data_A[ ( count & 0x03 ) ]; // プリバッファから補充 + adc_sum8 += adc_raw_data_B[ count ]; // 合計に 新しいのを足す + adc_raw_data_A[ ( count & 0x03 ) ] = (u8)( vBatt_raw & 0x00FF ); // プリバッファを更新 + // あんまりうれしくないかも.. + count = ( count < 7 )? count + 1: 0; // 上手な書き方募集 + } + } + } + ADC_Start(); +} + + + +//**************************************************************************** +__interrupt void callbk_int_ad(){ + EI(); + vBatt_raw = ( ADCR >> 6 ); // 右につめておきます...なんで。 + ADC_Stop(); +} + + + +//**************************************************************************** +void ADC_Init(){ + ADPC = PORT_ADPC_3DIO; // /IRQ_0 は親のほうがプルアップしてる + ADM = 0x90; // fAD = fPRS/6, wait:2〜13ClkSys + ADS = 0x03; +} + + + +void ADC_Start(){ + ADM.0 = 1; // ADCE + NOP(); // 1usあけなきゃいけないっす + NOP(); // nop : 2clkです。 + NOP(); + NOP(); + ADM.7 = 1; // ADCS + MK1L.0 = 0; // ADC割り込みマスク +} + + + +void ADC_Stop(){ + MK1L.0 = 1; // ADMK = 1; + ADM.7 = 0; // ADCS + ADM.0 = 0; // ADCE +} + diff --git a/ADC.h b/ADC.h new file mode 100644 index 0000000..fe4e5c2 --- /dev/null +++ b/ADC.h @@ -0,0 +1,31 @@ +#ifndef __ADC_H__ +#define __ADC_H__ + +#include "jhl_defs.h" + +void ADC_Init(); +void ADC_Start(); +void ADC_Stop(); + +void callbk_int_ad(); +void set_batt_th(); + +void tsk_adc(); +// tsk_adcの一連 +u16 getVBatt(); +u8 set_reg_power_info(); + +void chk_extension(); +void chk_obs_pmic_batt_low(); +void chk_irq0_batt(); + +void tsk_adc_calib(); + +enum BATT_TYPE{ + BATT_CO = 0x00, + BATT_PSS = 0x70, + BATT_IS = 0x30 +}; + +#endif + diff --git a/DCP.c b/DCP.c new file mode 100644 index 0000000..8956f04 --- /dev/null +++ b/DCP.c @@ -0,0 +1,137 @@ +/****************************************************************************** + ソフトウェアI2C通信 + de JHL 藤田@開技 + '07 Aug, '07 Dec + + !!注意!! + ・読み出し&書き込みを行うと (vol inc/dec) およそ1msかかります。 + ・クロックのデューティーなどを要求しないでください。 + ・割り込み禁止にしてないのでタイミングによっては割り込みが入ります。 + ・波形の対称性など気にしていません。最速でパタパタしますが、もともと遅いです。 + ・ウェイトコンディションをとりあえず気にしません。 +*******************************************************************************/ +#include "macrodriver.h" +#include "user_define.h" +#include "SW_I2C.h" +#include "DCP.h" +#include "vreg.h" + + +extern unsigned char vregs[]; + + +/****************************************************************************** + ここに書いちゃうけど、音量レベルから、DCPへのスケーリング + ******************************************************************************/ +#define VOL_INDEXES 32 +#define VOL_MAX ( VOL_INDEXES - 1 ) +#define VOL_INDEXES_MASK VOL_MAX + +static unsigned char const vol_table[VOL_INDEXES] = { + 0, 40, 51, 57, 64, 70, 76, 82, + 86, 90, 95, 100, 106, 111, 116, 121, + 126, 131, 137, 143, 148, 153, 157, 161, + 165, 168, 171, 174, 177, 180, 183, 186 }; + + + +/****************************************************************************** + 逆スケーリング。 + エラーや寿命で音量maxを超えてたときなどはデフォルト値?にする。 + ******************************************************************************/ +static unsigned char vol_2_raw( unsigned char rawVol ){ + u8 i; + + for( i = 0; i != VOL_INDEXES; i++ ){ + if( rawVol == vol_table[ i ] ){ + return i; + } + } + return( VOL_INDEXES - 9 ); // デフォルト?値 +} + + + +/****************************************************************************** + 前回の値を読み出す必要がある関係上、呼ぶの必須です。 + ******************************************************************************/ +void dcp_vol_read(){ + vregs[ REG_INT_ADRS_VOL ] = vol_2_raw( iic2m_read_byte( IIC_SLV_ADDR_DCP, 0 ) ); +} // 注:8段/32段のフラグは記憶しません。 + + + +// ボリュームスイッチを押したら&リピートが利く度に(× を変えた時。MAXとかでも。) +// VolChange割り込みかける。 +#define VOL_CHANGE_IRQ \ +{ \ + vregs[ REG_INT_ADRS_IRQ ] |= 0x40; \ + if( is_TWL ){ \ + n_irq_ast; \ + n_irq_ngt; \ + } \ +} + +/****************************************************************************** + ボリューム1チック上げる + ******************************************************************************/ +void vol_inc(){ + VOL_CHANGE_IRQ; + if( vregs[REG_INT_ADRS_VOL] != VOL_MAX ){ + if( !volSteps32 ){ + if( vregs[REG_INT_ADRS_VOL] <= 1 ){ + vregs[REG_INT_ADRS_VOL] += 2; + }else if( vregs[REG_INT_ADRS_VOL] <= 4 ){ + vregs[REG_INT_ADRS_VOL] += 4; + }else{ + vregs[REG_INT_ADRS_VOL] += 5; + } + }else{ + vregs[REG_INT_ADRS_VOL] += 1; // 32段階 + } + if( vregs[REG_INT_ADRS_VOL] > VOL_MAX ){ + vregs[REG_INT_ADRS_VOL] = VOL_MAX; + } + dcp_vol_set(); + } +} + + +/****************************************************************************** + ボリューム1チック下げる + ******************************************************************************/ +void vol_dec(){ + VOL_CHANGE_IRQ; + if( vregs[REG_INT_ADRS_VOL] != 0 ){ + if( !volSteps32 ){ + if( vregs[REG_INT_ADRS_VOL] >= 11 ){ + vregs[REG_INT_ADRS_VOL] -= 5; + }else if( vregs[REG_INT_ADRS_VOL] >= 6 ){ // 6 - 8 -> [1], 9 - 10 -> [3] + vregs[REG_INT_ADRS_VOL] -= 4; + }else if( vregs[REG_INT_ADRS_VOL] == 5 ){ // 5 -> [1] + vregs[REG_INT_ADRS_VOL] -= 3; + }else{ // 1 - 4 -> [0] + vregs[REG_INT_ADRS_VOL] -= 4; + } + }else{ + vregs[REG_INT_ADRS_VOL] -= 1; // 32段階 + } + if( vregs[REG_INT_ADRS_VOL] > 127 ){ + vregs[REG_INT_ADRS_VOL] = 0; + } + dcp_vol_set(); + } +} + + +/****************************************************************************** + DCP操作API + unsigned char vol にする。 volがすごいことになってても感知せず。 + volには0(mute)〜31(max)を引く(?)。 + ******************************************************************************/ +void dcp_vol_set(){ + u8 temp; + + temp = vol_table[ ( vregs[ REG_INT_ADRS_VOL ] & VOL_INDEXES_MASK ) ]; + iic2m_write_data( IIC_SLV_ADDR_DCP, 0, temp ); +} diff --git a/DCP.h b/DCP.h new file mode 100644 index 0000000..359a92b --- /dev/null +++ b/DCP.h @@ -0,0 +1,21 @@ +#ifndef __DCP_H__ +#define __DCP_H__ + +#include "jhl_defs.h" + +// DCPのスレーブアドレス。これに LSB 1bit の R/~W を or して出力してくださいませ。 +// いちいちシフトするのが面倒なのです。 +#define IIC_SLV_ADDR_DCP 0x50 +#define IIC_DCP_REG_ADR_VOL 0x00 + +static u8 dcp_read_vol(); +static u8 vol_2_raw( u8 vol ); + +void dcp_vol_set(); +void vol_inc(); +void vol_dec(); +void dcp_vol_read(); + + + +#endif diff --git a/EEPe.c b/EEPe.c new file mode 100644 index 0000000..5a09568 --- /dev/null +++ b/EEPe.c @@ -0,0 +1,50 @@ +/* + NECのライブラリを使う + */ + +//****************************************************************************** +#include "macrodriver.h" +#include "System.h" + +#include "eeelib.h" +#include "EEPe.h" + +#include "user_define.h" +#include "jhl_defs.h" + +#include "flash.h" + +//****************************************************************************** +// NEC謹製 EEPROM エミュレーション ライブラリ +#pragma section @@DATS ERAM AT 0xFE20 // エントリRAMは置けるところに制限があります。 +sreg UCHAR EntryRAM[100]; +#pragma section @@DATS @@DATS + +struct stEEPROM_Param eep_par; /* パラメータ・エリア */ + +UCHAR EepRAM[8]; + +extern u8 vregs[]; + +//****************************************************************************** +void eepe_init(){ + /* パラメータ・セット */ + eep_par.EntryRAM = EntryRAM; // エントリRAM + eep_par.EepRAM = EepRAM; // EEPROM 用RAM + eep_par.InfoFlag = 0b00000000; // 自動消去:しない、 EEPROM関係処理中にWDTを無効 + eep_par.BankNo = 0; // 使用バンク + eep_par.BlockNo = 0x0c; // 使用ブロック + eep_par.DataLen = 1; // データ長 + eep_par.DataNum = 2; // データ数量 + + flash_we = 1; + DI(); + ucEEPROMInitEx_A(&eep_par); // 初期設定関数実行 + if( ucEEPROMGetRemainEx_A() == 0 ){ + ucEEPROMChangeEx_A(); + } + EI(); + flash_we = 0; +} + + diff --git a/EEPe.h b/EEPe.h new file mode 100644 index 0000000..2b7353d --- /dev/null +++ b/EEPe.h @@ -0,0 +1,6 @@ +#ifndef __eepe_h__ +#define __eepe_h__ + +void eepe_init(); + +#endif diff --git a/I2C.c b/I2C.c new file mode 100644 index 0000000..0445ed6 --- /dev/null +++ b/I2C.c @@ -0,0 +1,172 @@ +#pragma interrupt INTIIC0 MD_INTIIC0 +#define ignore_NAK 0 + +#include "macrodriver.h" +#include "I2C.h" +#include "user_define.h" +#include "jhl_defs.h" +#include "vreg.h" +#include "I2C_selfprog.h" + +#include "wdt.h" + +extern u8 vregs[]; +#include "PMIC_TWL2.h" + + + + +extern bit self_prog_mode; + +/***************************************************************************** + 低レベル向け? + *****************************************************************************/ +volatile UCHAR gIic0SlaveStatusFlag; + + + +/***************************************************************************** + プロトコル層?向け + *****************************************************************************/ +extern UCHAR vregs[]; +UCHAR i2c_Send_start_addr; +UCHAR i2c_accessRegAdr; + +u8 vreg_adrs; +u8 rcvd_buff; + +u8 pre_dat; + + +// 注! ↓はマクロなので、returnはメインループに戻ります。 +#define wait_next { \ + while( IICIF0 != 1 ){ \ + if( SPD0 ){ \ + LREL0 = 1; \ + return; \ + } \ + } \ +} + + +__interrupt void MD_INTIIC0( void ){ + WREL0 = 1; // ウェイト解除して次のバイトを待つ + // フラグ1回目 スレーブアドレス,R/W + if( COI0 != 1 ){ // 被呼び出し? + LREL0 = 1; // 呼ばれたのは他のID + return; + }else{ +// ACKE0 = 1; // 自動でackを返すようにする +// WREL0 = 1; // ウェイト解除して次のバイトを待つ + } + + wait_next; // 1バイト受信完了を待つ + + // 2回目 R/W レジスタアドレス + WREL0 = 1; + IICIF0 = 0; + vreg_adrs = adrs_table_ext2int( IIC0 ); + + // 3回目 + // スタートコンディションか、データ受信完了フラグ待ち + + while( 1 ){ + if( IICIF0 == 1 ){ + // 受信 // + IICIF0 = 0; + WREL0 = 1; + + if( ( IIC0 == 0x4A ) && ( vreg_adrs == REG_INT_ADRS_TEMP7 ) ){ + // 自己プログラム書き換えモード // + // ここで分岐は美しくない気もします... + vregs[ REG_INT_ADRS_MODE ] = 0x00; // 電源オフ時間を短くせんがため。 + PM_set_VRSET(); + self_programming(); + // 帰ってきません + }else{ + // 通常アクセス(ライト) // + LREL0 = 1; + debug_led_on; + vregs_write( vreg_adrs, IIC0 ); + debug_led_off; + return; // 受信おしまい // + } + }else if( STD0 ){ + // 送信 // (スタートコンディション検出) + pre_dat = vregs_read( vreg_adrs ); // mcu内部アドレスを渡す。一バイト目の準備 IIc0に書き込むとウェイト解除 + + // 自局をRで呼ばれるのを待つ + wait_next; + IICIF0 = 0; + if( COI0 != 1 ){ // 被呼び出し? + LREL0 = 1; // 呼ばれたのは他のID(あれ?) + return; + } + IIC0 = pre_dat; // データを送る + + wait_next; + // 4回目。(送信データ後の、ACK/NACK後) どうしても発生してしまう。 + IICIF0 = 0; // おしまい + LREL0 = 1; + return; + }else if( SPD0 ){ // 強制終了 + LREL0 = 1; + return; + } + } +} + + + + +/***************************************************************************** + 基本API + *****************************************************************************/ +void IIC0_Init( void ) +{ + IICE0 = 0; /* IIC0 disable */ + + IICMK0 = 1; /* INTIIC0 disable */ + IICIF0 = 0; /* clear INTIIC0 interrupt flag */ + + IICPR0 = 0; /* set INTIIC0 high priority */ + + PM6 &= ~0x1; /* set clock pin for IIC0 */ + P6 &= ~0x1; + + PM6 &= ~0x2; /* set data transfer I/O pin for IIC0 */ + P6 &= ~0x2; + + IICCL0 = IICCL0_INITIALVALUE | IIC0_CLOCK4; // レジスタ初期化、高速モード + IICX0 = IIC0_EXPENSION0; // 〃 + SVA0 = IIC0_SLAVEADDRESS; + STCEN = 1; // リスタートの許可 + IICRSV = 1; // 通信予約をさせない:スレーブに徹する + + SPIE0 = 0; // ストップコンディションでの割り込みを禁止 + WTIM0 = 1; // 自動でACKを返した後clkをLに固定する + ACKE0 = 1; // ダメCPUは無視して次の通信をはじめるかもしれないんで早くclkを開放しないといけない + IICMK0 = 0; // 割り込みを許可 + + IICE0 = 1; +} + + +//**************************************************************************** +void IIC0_Stop( void ){ + IICE0 = 0; /* IIC0 disable */ +} + + + +void IIC0_SlaveReceiveStart(){ + gIic0SlaveStatusFlag = 0; + IICE0 = 1; + LREL0 = 1; + return; +} + + + + + diff --git a/I2C.h b/I2C.h new file mode 100644 index 0000000..6e43ba3 --- /dev/null +++ b/I2C.h @@ -0,0 +1,217 @@ +#ifndef _MDSERIAL_ +#define _MDSERIAL_ + + +/* IIC operation enable (IICE0) */ +#define IIC0_OPERATION 0x80 +#define IIC0_OPERATION_DISABLE 0x00 /* stop operation */ +#define IIC0_OPERATION_ENABLE 0x80 /* enable operation */ + +/* Exit from communications (LREL0) */ +#define IIC0_COMMUNICATION 0x40 +#define IIC0_COMMUNICATION_NORMAL 0x00 /* normal operation */ +#define IIC0_COMMUNICATION_EXIT 0x40 /* exit from current communication */ + +/* Wait cancellation (WREL0) */ +#define IIC0_WAITCANCEL 0x20 +#define IIC0_WAIT_NOTCANCEL 0x00 /* do not cancel wait */ +#define IIC0_WAIT_CANCEL 0x20 /* cancel wait */ + +/* Generation of interrupt when stop condition (SPIE0) */ +#define IIC0_STOPINT 0x10 +#define IIC0_STOPINT_DISABLE 0x00 /* disable */ +#define IIC0_STOPINT_ENABLE 0x10 /* enable */ + +/* Wait and interrupt generation (WTIM0) */ +#define IIC0_WAITINT 0x08 +#define IIC0_WAITINT_CLK8FALLING 0x00 /* generate at the eighth clocks falling edge */ +#define IIC0_WAITINT_CLK9FALLING 0x08 /* generated at the ninth clocks falling edge */ + +/* Acknowledgement control (ACKE0) */ +#define IIC0_ACK 0x04 +#define IIC0_ACK_DISABLE 0x00 /* enable acknowledgement */ +#define IIC0_ACK_ENABLE 0x04 /* disable acknowledgement */ + +/* Start condition trigger (STT0) */ +#define IIC0_STARTCONDITION 0x02 +#define IIC0_START_NOTGENERATE 0x00 /* do not generate start condition */ +#define IIC0_START_GENERATE 0x02 /* generate start condition */ + +/* Stop condition trigger (SPT0) */ +#define IIC0_STOPCONDITION 0x01 +#define IIC0_STOP_NOTGENERATE 0x00 /* do not generate stop condition */ +#define IIC0_STOP_GENERATE 0x01 /* generate stop condition */ + +/* + IIC Status Register 0 (IICS0) +*/ +/* Master device status (MSTS0) */ +#define IIC0_MASTERSTATUS 0x80 +#define IIC0_STATUS_NOTMASTER 0x00 /* slave device status or communication standby status */ +#define IIC0_STATUS_MASTER 0x80 /* master device communication status */ + +/* Detection of arbitration loss (ALD0) */ +#define IIC0_ARBITRATION 0x40 +#define IIC0_ARBITRATION_NO 0x00 /* arbitration win or no arbitration */ +#define IIC0_ARBITRATION_LOSS 0x40 /* arbitration loss */ + +/* Detection of extension code reception (EXC0) */ +#define IIC0_EXTENSIONCODE 0x20 +#define IIC0_EXTCODE_NOT 0x00 /* extension code not received */ +#define IIC0_EXTCODE_RECEIVED 0x20 /* extension code received */ + +/* Detection of matching addresses (COI0) */ +#define IIC0_ADDRESSMATCH 0x10 +#define IIC0_ADDRESS_NOTMATCH 0x00 /* addresses do not match */ +#define IIC0_ADDRESS_MATCH 0x10 /* addresses match */ + +/* Detection of transmit/receive status (TRC0) */ +#define IIC0_STATUS 0x08 +#define IIC0_STATUS_RECEIVE 0x00 /* receive status */ +#define IIC0_STATUS_TRANSMIT 0x08 /* transmit status */ + +/* Detection of acknowledge signal (ACKD0) */ +#define IIC0_ACKDETECTION 0x04 +#define IIC0_ACK_NOTDETECTED 0x00 /* ACK signal was not detected */ +#define IIC0_ACK_DETECTED 0x04 /* ACK signal was detected */ + +/* Detection of start condition (STD0) */ +#define IIC0_STARTDETECTION 0x02 +#define IIC0_START_NOTDETECTED 0x00 /* start condition not detected */ +#define IIC0_START_DETECTED 0x02 /* start condition detected */ + +/* Detection of stop condition (SPD0) */ +#define IIC0_STOPDETECTION 0x01 +#define IIC0_STOP_NOTDETECTED 0x00 /* stop condition not detected */ +#define IIC0_STOP_DETECTED 0x01 /* stop condition detected */ + +/* + IIC Flag Register 0 (IICF0) +*/ +/* STT0 clear flag (STCF) */ +#define IIC0_STARTFLAG 0x80 +#define IIC0_STARTFLAG_GENERATE 0x00 /* generate start condition */ +#define IIC0_STARTFLAG_UNSUCCESSFUL 0x80 /* start condition generation unsuccessful */ + +/* IIC bus status flag (IICBSY) */ +#define IIC0_BUSSTATUS 0x40 +#define IIC0_BUS_RELEASE 0x00 /* bus release status */ +#define IIC0_BUS_COMMUNICATION 0x40 /* bus communication status */ + +/* Initial start enable trigger (STCEN) */ +#define IIC0_STARTWITHSTOP 0x02 +#define IIC0_START_WITHSTOP 0x00 /* generation of a start condition without detecting a stop condition */ +#define IIC0_START_WITHOUTSTOP 0x02 /* generation of a start condition upon detection of a stop condition */ + +/* Communication reservation function disable bit (IICRSV) */ +#define IIC0_RESERVATION 0x01 +#define IIC0_RESERVATION_ENABLE 0x00 /* enable communication reservation */ +#define IIC0_RESERVATION_DISABLE 0x01 /* disable communication reservation */ + +/* + IIC clock selection register 0 (IICCL0) +*/ +#define IICCL0_INITIALVALUE 0x00 +/* Detection of SCL0 pin level (CLD0) */ +#define IIC0_SCLLEVEL 0x20 +#define IIC0_SCL_LOW 0x00 /* clock line at low level */ +#define IIC0_SCL_HIGH 0x20 /* clock line at high level */ + +/* Detection of SDA0 pin level (DAD0) */ +#define IIC0_SDALEVEL 0x10 +#define IIC0_SDA_LOW 0x00 /* data line at low level */ +#define IIC0_SDA_HIGH 0x10 /* data line at high level */ + +/* Operation mode switching (SMC0) */ +#define IIC0_OPERATIONMODE 0x08 +#define IIC0_MODE_STANDARD 0x00 /* operates in standard mode */ +#define IIC0_MODE_HIGHSPEED 0x08 /* operates in high-speed mode */ + +/* Digital filter operation control (DFC0) */ +#define IIC0_DIGITALFILTER 0x04 +#define IIC0_FILTER_OFF 0x00 /* digital filter off */ +#define IIC0_FILTER_ON 0x04 /* digital filter on */ + +/* Operation mode switching (CL01, CL00) */ +#define IIC0_CLOCKSELECTION 0x03 + +/* Combine of (SMC0, CL01, CL00)*/ +#define IIC0_CLOCK0 0x00 +#define IIC0_CLOCK1 0x01 +#define IIC0_CLOCK2 0x02 +#define IIC0_CLOCK3 0x03 +#define IIC0_CLOCK4 0x08 +#define IIC0_CLOCK5 0x09 +#define IIC0_CLOCK6 0x0a +#define IIC0_CLOCK7 0x0b + +/* + IIC function expansion register 0 (IICX0) +*/ +/* IIC clock expension (CLX0) */ +#define IIC0_CLOCKEXPENSION 0x01 +#define IIC0_EXPENSION0 0x00 +#define IIC0_EXPENSION1 0x01 + +/* Operation clock (CLX0, SMC0, CL01, CL00) + | IIC0_EXPENSION0 | IIC0_EXPENSION1 | +------------|-------------------|-------------------|---------------------- +IIC0_CLOCK0 | fprs/2 | prohibited | selection clock(fw) + | fprs/88 | | transfer clock + | normal | | mode +------------|-------------------|-------------------|---------------------- +IIC0_CLOCK1 | fprs/2 | prohibited | selection clock(fw) + | fprs/172 | | transfer clock + | normal | | mode +------------|-------------------|-------------------|---------------------- +IIC0_CLOCK2 | fprs/2 | prohibited | selection clock(fw) + | fprs/344 | | transfer clock + | normal | | mode +------------|-------------------|-------------------|---------------------- +IIC0_CLOCK3 |prohibited/fexscl0 | prohibited | selection clock(fw) + | fw/66 | | transfer clock + | normal | | mode +------------|-------------------|-------------------|---------------------- +IIC0_CLOCK4 | fprs/2 | fprs/2 | selection clock(fw) + | fprs/48 | fprs/24 | transfer clock + | high speed | high speed | mode +------------|-------------------|-------------------|---------------------- +IIC0_CLOCK5 | fprs/2 | fprs/2 | selection clock(fw) + | fprs/48 | fprs/24 | transfer clock + | high speed | high speed | mode +------------|-------------------|-------------------|---------------------- +IIC0_CLOCK6 | fprs/4 | fprs/4 | selection clock(fw) + | fprs/96 | fprs/48 | transfer clock + | high speed | high speed | mode +------------|-------------------|-------------------|---------------------- +IIC0_CLOCK7 |prohibited/fexscl0 | prohibited | selection clock(fw) + | fw/18 | | transfer clock + | high speed | | mode +------------|-------------------|-------------------|---------------------- +*/ + +#define ADDRESS_COMPLETE 0x80 +#define IIC0_MASTER_FLAG_CLEAR 0x00 + +/****************************************************************************** + * Macro define + ******************************************************************************/ +#define IIC0_SLAVEADDRESS 0x4A + + + +/****************************************************************************** + * Function define + ******************************************************************************/ +void IIC0_Init( void ); +void IIC0_SlaveSendStart( UCHAR* , UINT ); +void IIC0_SlaveReceiveStart(); +void IIC0_Stop( void ); + +static void IIC0_getStCond( void ); +static void IIC0_Contents_Send( void ); +static void IIC0_Contents_Rcv( void ); + +static void IIC0_parseContents( void ); + +#endif diff --git a/I2C_selfprog.c b/I2C_selfprog.c new file mode 100644 index 0000000..2db6d60 --- /dev/null +++ b/I2C_selfprog.c @@ -0,0 +1,272 @@ +#pragma section @@CODE c_flash +#pragma section @@BITS c_f_bits AT 0xFE88 +#pragma section @@DATA c_f_data AT 0xFE90 + +#pragma HALT +#pragma NOP + +#include "macrodriver.h" +#include "user_define.h" +#include "jhl_defs.h" +#include "I2C_selfprog.h" +#include "SelfLib.h" + +#include "user_define.h" +#include "Timer.h" + +extern sreg UCHAR EntryRAM[]; + + +bit self_prog_mode; + +u8 writeBuffer[16]; +struct stWordAddress self_prog_settings; + + + + +/***************************************************************************** + I2Cから自己書き換え + 書き換える範囲は 0x0000 - 0x1FFFまで。 + I2Cをほかで使っているので、フラグなどで飛んできてください。 + 書き換え完了後は電源再投入が必要です。 + マイコンは停止します。 + *****************************************************************************/ +void self_programming(){ + u8 status; + + self_write_init(); + + led_wifi = 1; + FlashStart(); + FlashEnv( EntryRAM ); + + if( self_write_eraseall() != 0 ){ + led_R_on; + FlashEnd(); + LREL0 = 1; + while(1){} + } + led_wifi = 0; + + /// フラッシュの準備 /// + self_prog_settings.WriteBank = 0; + + //// 各行の処理 //// + while( 1 ){ + led_wifi = 1; + status = i2c_firm_rcv_line(); + if( status != 0 ){ + led_G_on; + FlashEnd(); + LREL0 = 1; + LSRSTOP = 0; + WDTE = 0x4A; // リセット + while(1){} + } + led_wifi = 0; + + status = write_firm_line(); + if( ( status & 0x80 ) != 0 ){ + // フラッシュ異常中断 + FlashEnd(); + LREL0 = 1; + while(1){} + } + led_wifi = 0; + } + FlashEnd(); + WDTE = 0x01; // リセット + while(1){} +} + + + +/***************************************************************************** + 下準備 + *****************************************************************************/ +static void self_write_init(){ +// SPIE0 = 1; + WTIM0 = 1; // ウェイトコンディションをだす。(仮) + + // B // + TMHE1 = 0; /* stop TimerH0 */ + TOEN1 = 0; /* disable output */ + led_G_pwm; + + // R // + TMHE0 = 0; /* stop TimerH0 */ + TOEN0 = 0; /* disable output */ + led_R_pwm; + + // Y // + TCE50 = 0; /* TM50 counter disable */ + TOE50 = 0; /* output disabled */ + // TM50_Stop(); // LED_Wifi これ使っちゃだめ! + led_wifi = 1; + + LSRSTOP = 1; // WDT停止 + + DI(); + MK0 = 0xFFFF; + MK1 = 0xFFFF; + EI(); +} + + + +/***************************************************************************** + 書き込み対象の部分を消去 + *****************************************************************************/ +static u8 self_write_eraseall(){ + u8 flash_status = 0; + u8 temp; + + flash_we = 1; + if( CheckFLMD() != 0 ){ + return( 128 + 1 ); + } + + for( temp = 0; temp != (u8)( ( 0x2800 & 0xFC00 ) >> 10 ); temp++ ){ + if( FlashBlockBlankCheck( 0, temp ) == 0x1B ){ + flash_status |= FlashBlockErase( 0, temp ); + } + } + if( flash_status != 0 ){ + return( 128 + 2 ); + } +} + + + +/***************************************************************************** + 一行分受信。データ足りない部分は0xFFでパディングするようになってるけど、 + 元データをちゃんとしてあるので本来不要 + *****************************************************************************/ +static u8 i2c_firm_rcv_line(){ + u8 rec_length; + u8 data_counter; + u8 temp; + + // ':' レコードマーク + do{ + IICIF0 = 0; + WREL0 = 1; + while( ( IICIF0 == 0 ) && ( SPD0 == 0 ) ){ ; } + if( SPD0 == 1 ){ + return( 1 ); // 書き換え終了。 + } + }while( IIC0 != ':' ); // タイムアウトとかなしで永遠ループ + + // レコード長 + rec_length = rcvHex2bin(); + + // アドレス + temp = rcvHex2bin(); // 上位 + self_prog_settings.WriteAddress = (u8*)( ( (u16)temp << 8 ) + rcvHex2bin() ); // 下位 + + // "00" (レコードタイプ) + if( rcvHex2bin() == 01 ){ + return( 2 ); // 書き換え終了。 + } + + // ここからデータ + for( data_counter = 0; data_counter < rec_length; data_counter++){ + writeBuffer[ data_counter ] = rcvHex2bin(); + } + + // サム(読み捨て) + rcvHex2bin(); + // 改行コード \r\n はここでは見ないよ + + // 0xFFで残りをパディング + while( data_counter < 16 ){ + writeBuffer[ data_counter ] = 0xFF; + data_counter++; + } + return( 0 ); +} + + +/***************************************************************************** + 実書き込み 4ワード16バイトずつ。 + *****************************************************************************/ +static u8 write_firm_line(){ + // ライターアップデート1は、 + // 0x0000 - 0x1FFF ブート&本体を動かすコード + // 0x2000 - 0x27FF 自己書き換えコード + // 0x2800 - 空き。 + // + // ライターアップデート2`は、 + // 0x0000 - 0x1FFF ブート&本体を動かすコード + // 0x2000 - 0x27FF (空き) + // 0x2800 - 自己書き換えコード + // です + if( self_prog_settings.WriteAddress >= (u8*)0x2800 ){ + // EEPエミュレーションで書き換えない範囲 + return( 2 ); + }else{ + // 書き換える範囲 + led_R_on; + if( FlashWordWrite( &self_prog_settings, 4, writeBuffer ) != 0 ){ + return( 128 + 64 + 1 ); + } + led_G_on; + if( FlashBlockVerify( 0, (u8)( ( (u16)(self_prog_settings.WriteAddress) & 0xFC00 ) >> 10 ) ) != 0 ){ + // ライト リトライ + led_R_pwm; + if( FlashWordWrite( &self_prog_settings, 4, writeBuffer ) != 0 ){ + return( 128 + 64 + 2 ); + } + if( FlashBlockVerify( 0, (u8)( ( (u16)(self_prog_settings.WriteAddress) & 0xFC000 ) >> 10 ) ) != 0 ){ + // 内部電荷診断エラー + return( 128 + 64 + 3 ); + } + } + // 1行完了しました。 + led_G_pwm; + led_R_pwm; + } + return( 0 ); +} + + + +/***************************************************************************** + 2バイト分のヘキサを受信してバイナリを返す。 + 0x31 0x33 → 0x13 + エラー処理とかしてないです。 + ポーリングです。 + *****************************************************************************/ +static u8 rcvHex2bin(){ + u8 dat; + u8 temp; + + IICIF0 = 0; + WREL0 = 1; + while( IICIF0 == 0 ){ ; } + temp = IIC0; + if( ( '0' <= temp ) && ( temp <= '9' ) ){ + dat = ( temp - '0' ); + }else if( ( 'A' <= temp ) && ( temp <= 'Z' ) ){ + dat = ( temp - 'A' + 10 ); + }else if( ( 'a' <= temp ) && ( temp <= 'z' ) ){ + dat = ( temp - 'a' + 10 ); + } + dat <<= 4; + + IICIF0 = 0; + WREL0 = 1; + while( IICIF0 == 0 ){ ; } + temp = IIC0; + if( ( '0' <= temp ) && ( temp <= '9' ) ){ + dat |= ( temp - '0' ); + }else if( ( 'A' <= temp ) && ( temp <= 'Z' ) ){ + dat |= ( temp - 'A' + 10 ); + }else if( ( 'a' <= temp ) && ( temp <= 'z' ) ){ + dat |= ( temp - 'a' + 10 ); + } + + return( dat ); +} + diff --git a/I2C_selfprog.h b/I2C_selfprog.h new file mode 100644 index 0000000..5818864 --- /dev/null +++ b/I2C_selfprog.h @@ -0,0 +1,7 @@ +void self_programming(); +static u8 rcvHex2bin(); + +static void self_write_init(); +static u8 self_write_eraseall(); +static u8 i2c_firm_rcv_line(); +static u8 write_firm_line(); diff --git a/Int.h b/Int.h new file mode 100644 index 0000000..c7329a5 --- /dev/null +++ b/Int.h @@ -0,0 +1,54 @@ +#ifndef _MDINT_ +#define _MDINT_ + +/* + External Interrupt Rising Edge Enable Register (EGP) +*/ +/* INTPn pin valid edge selection(EGP.EGPn) */ +#define INTP_EGP_RESET_VALUE 0x00 +#define INTP0_EDGE_RISING_SEL 0x01 +#define INTP0_EDGE_RISING_UNSEL 0x00 +#define INTP1_EDGE_RISING_SEL 0x02 +#define INTP1_EDGE_RISING_UNSEL 0x00 +#define INTP2_EDGE_RISING_SEL 0x04 +#define INTP2_EDGE_RISING_UNSEL 0x00 +#define INTP3_EDGE_RISING_SEL 0x08 +#define INTP3_EDGE_RISING_UNSEL 0x00 +#define INTP4_EDGE_RISING_SEL 0x10 +#define INTP4_EDGE_RISING_UNSEL 0x00 +#define INTP5_EDGE_RISING_SEL 0x20 +#define INTP5_EDGE_RISING_UNSEL 0x00 + +/* + External Interrupt Falling Edge Enable Register (EGN) +*/ +/* INTPn pin valid edge selection(EGN.EGNn) */ +#define INTP_EGN_RESET_VALUE 0x00 +#define INTP0_EDGE_FALLING_SEL 0x01 +#define INTP0_EDGE_FALLING_UNSEL 0x00 +#define INTP1_EDGE_FALLING_SEL 0x02 +#define INTP1_EDGE_FALLING_UNSEL 0x00 +#define INTP2_EDGE_FALLING_SEL 0x04 +#define INTP2_EDGE_FALLING_UNSEL 0x00 +#define INTP3_EDGE_FALLING_SEL 0x08 +#define INTP3_EDGE_FALLING_UNSEL 0x00 +#define INTP4_EDGE_FALLING_SEL 0x10 +#define INTP4_EDGE_FALLING_UNSEL 0x00 +#define INTP5_EDGE_FALLING_SEL 0x20 +#define INTP5_EDGE_FALLING_UNSEL 0x00 + + + +enum MaskableSource { + INT_LVI, INT_INTP0, INT_INTP1, INT_INTP2, + INT_INTP3, INT_INTP4, INT_INTP5, INT_SRE6, + INT_SR6, INT_ST6, INT_CSI10_ST0, INT_TMH1, + INT_TMH0, INT_TM50, INT_TM000, INT_TM010, + INT_AD, INT_SR0, INT_TM51 = 19, + INT_IIC0 = 24 + }; + + + +void INTP_Init( void ); +#endif diff --git a/LEDs.c b/LEDs.c new file mode 100644 index 0000000..ef624e3 --- /dev/null +++ b/LEDs.c @@ -0,0 +1,418 @@ +#include "incs.h" + +#define led_pwr_G_duty CMP11 +#define led_pwr_R_duty CMP10 +#define led_wifi_duty CMP50 + +extern u8 vregs[]; + +extern u8 tsk_interval_power_led; +extern u8 tsk_interval_sw_vol; +extern u8 tsk_interval_wifi_led; +extern u8 tsk_interval_cnt_cam_led; + +u8 wifi_tx; + +extern u8 battLvl; + +u8 batt_rest; +u8 led_G_brightness_to; +u8 led_R_brightness_to; + +extern bit flg_BLChanged; + + +// 0 1 3 7 B F +const u8 LED_G_BRIGHTNESS[] = { 0, 0, 0, 255, 255, 255 }; +const u8 LED_R_BRIGHTNESS[] = { 255, 255, 255, 0, 0, 0 }; + +static u8 slp_state; // 変数のスコープに泣く + + +#ifdef debug_codes +extern bit pwon_wt_sel; +extern bit pwon_wt_vol_p; +extern bit pwon_wt_vol_n; +#endif + + +/****************************************************************************** + 電源LED管理 + この辺の明るさの変化とかは tsk_interval_power_led による +  何かみにくい(醜い/見にくい)コードだ + ******************************************************************************/ +void tsk_power_led(){ + // PM_OFFで0にグラデしようかと思ったけど、PM_OFFが短すぎた(約100ms) + if( PM_OFF ){ + TMHE1 = 0; /* stop TimerH0 */ + TOEN1 = 0; /* disable output */ + led_G_pwm; + TMHE0 = 0; /* stop TimerH0 */ + TOEN0 = 0; /* disable output */ + led_R_pwm; + }else{ + // 通常運転 + if( PM_SLP == 0 ){ + tsk_interval_power_led = 30; + power_led_status_watch_awake(); + }else{ + // スリープ + tsk_interval_power_led = 160; + power_led_status_watch_sleep(); + } + } +} + + + +/****************************************************************************** + 電源LEDの明るさを目標値にグラデーションしてく + 帰り値:3 : ともにゼロ + ******************************************************************************/ +void led_pwm_GR_grad(){ + static u8 delay = 0; + + if( PM_SLP && ( delay < 1 ) ){ // クラデの速度調節ウェイト。やりたくなかった...。 + delay++; + return; + } + delay = 0; + + if( led_pwr_G_duty != led_G_brightness_to ){ + led_pwr_G_duty += ( led_pwr_G_duty < led_G_brightness_to )? 1: -1; + } + + if( led_pwr_G_duty == 0 ){ + TMHE1 = 0; /* stop TimerH0 */ + TOEN1 = 0; /* disable output */ + led_G_pwm; + }else if( led_pwr_G_duty == 255 ){ + led_G_on; + TMHE1 = 0; /* stop TimerH0 */ + TOEN1 = 0; /* disable output */ + }else{ + led_G_pwm; + TOEN1 = 1; /* enable output */ + TMHE1 = 1; /* start TimerH0 */ + } + + if( led_pwr_R_duty != led_R_brightness_to ){ + led_pwr_R_duty += ( led_pwr_R_duty < led_R_brightness_to )? 1: -1; + } + + if( led_pwr_R_duty == 0 ){ + TMHE0 = 0; /* stop TimerH0 */ + TOEN0 = 0; /* disable output */ + led_R_pwm; + }else if( led_pwr_R_duty == 255 ){ + led_R_on; + TMHE0 = 0; /* stop TimerH0 */ + TOEN0 = 0; /* disable output */ + }else{ + led_R_pwm; + TOEN0 = 1; /* enable output */ + TMHE0 = 1; /* start TimerH0 */ + } +} + + + +/****************************************************************************** + 通常運転時。 + 電源LEDの明るさ変更をもうちょっと賢くやらせる + ******************************************************************************/ +static void power_led_status_watch_awake(){ + static u8 state; // 明滅用カウンタ + u8 led_dim; + + slp_state = 0; + if( battLvl >= 2 ){ + // レベル 3,7,B,F + + // BLに合わせて電源LED減光 + led_G_brightness_to = ( LED_G_BRIGHTNESS[ battLvl ] >> ( 4 - vregs[ REG_INT_ADRS_BL ] ) ); + led_R_brightness_to = ( LED_R_BRIGHTNESS[ battLvl ] >> ( 4 - vregs[ REG_INT_ADRS_BL ] ) ); + if( flg_BLChanged == 1 ){ + flg_BLChanged = 0; + led_pwr_G_duty = led_G_brightness_to; + led_pwr_R_duty = led_R_brightness_to; + } + state = 0; + }else{ + // 点滅 + led_pwr_G_duty = led_G_brightness_to = 0; + if( state == 0 ){ + led_pwr_R_duty = ( LED_R_BRIGHTNESS[0] >> ( 4 - vregs[ REG_INT_ADRS_BL ] ) ); // 点 + led_R_brightness_to = led_pwr_R_duty; + }else if( state == 2 ){ + led_pwr_R_duty = 0; // 滅 + led_R_brightness_to = 0; + } + state++; + if( state == 4 ){ + state = 0; + } + } + return; +} + + + +/****************************************************************************** + sleep時の電源蛍 + ******************************************************************************/ +static void power_led_status_watch_sleep(){ + switch( slp_state ){ + // 上げていく + case( 2 ): + case( 6 ): + case( 10 ): + case( 14 ): + if( battLvl > 2 ){ + led_G_brightness_to = 40; + led_R_brightness_to = 0; + }else{ + led_G_brightness_to = 0; + led_R_brightness_to = 40; + } + break; + // 下げていく + case( 0 ): + case( 4 ): + case( 8 ): + case( 12 ): + case( 16 ): + if( battLvl > 2 ){ + led_G_brightness_to = 5; + led_R_brightness_to = 0; + }else{ + led_G_brightness_to = 0; + led_R_brightness_to = 5; + } + break; + default: + // 現状を保持 何もしない + break; + } + slp_state++; + if( slp_state == 18 ){ + slp_state = 0; + } +} + + + +/****************************************************************************** + カメラLED。 + ******************************************************************************/ +void set_camled(){ + static camLed_mode reg_cam_old; + + if( reg_cam_old != camLed_blink ){ + tsk_cam_led(); + tsk_interval_cnt_cam_led = 0; + } + reg_cam_old = ( vregs[REG_INT_ADRS_CAM] & 0x03 ); +} + + +void set_camled_stop(){ + if( vregs[ REG_INT_ADRS_BATT_INFO ] != BATT_IS ){ +#ifdef after_x6 + led_cam = 0; +#else + IS_led_cam = 0; +#endif + }else{ + IS_led_cam = 0; + } +} + + +// bit型のポインタ というのはやっぱりないらしい。 +void tsk_cam_led(){ + if( PM_SLP ){ + return; + } +#ifdef after_x6 + if( vregs[ REG_INT_ADRS_BATT_INFO ] != BATT_IS ){ + switch( vregs[REG_INT_ADRS_CAM] & 0x03 ){ + case ( 1 ): // 点灯 + led_cam = 1; + break; + case( 2 ): // 点滅 + led_cam = ~led_cam; + break; + default: // 消灯 + led_cam = 0; + break; + } + + // 赤箱対応 // + } + else +#endif // 赤箱と、X6より古いボード + { + switch( vregs[REG_INT_ADRS_CAM] & 0x03 ){ + case ( 1 ): // 点灯 + IS_led_cam = 1; + break; + case( 2 ): // 点滅 + IS_led_cam = ~IS_led_cam; + break; + default: // 消灯 + IS_led_cam = 0; + break; + } + } +} + + + + +/****************************************************************************** + WiFiLED + 起きるとき、寝るとき + ******************************************************************************/ +void trig_to_sleep_wifiLed(){ + if( reg_wifi_led != 0 ){ + led_wifi = 0; + CR50 = 5; + TM50_Start(); + } +} + + + +void trig_to_wake_wifiLed(){ + if( reg_wifi_led != 0 ){ + TM50_Stop(); + led_wifi = 0; + } +} + + +/****************************************************************************** + WiFiLED。 +  動きがあるとうっとおしいよね...ほぼ常時点灯にするよね...。 + → 送信するときは点滅だって...。 + ■ 割り込みそのものは使っていません! +   条件さえそろえば割り込み待機フラグは立ち、マスクが解除されない限り、割り込み +   ルーチンには飛びません。 +   短いパルスをポーリングで捕まえるのがつらいので、ラッチとして使ってます。 +   また、割り込みを使いたくないのでこんな実装になっています。 + + ******************************************************************************/ +void tsk_wifi_led(){ // 10Hzで呼ばれます + static u8 state; + + // フライトモードではNTRパルスが出ても電波でない→ + // フライトレジスタ見なくてはならない + if( reg_wifi_led == 0 ){ + TM50_Stop(); + led_wifi = 0; + wifi_tx = 0; + return; + } + + // スリープ時 + if( PM_SLP == 1 ){ + // タスクで回すことはない trig_to_sleep_wifiLed() で減光状態にしてる + return; + } + + // 短いパルスを捕まえるために、割り込みフラグを見る + if( ( PIF2 == 1 ) || ( PIF3 == 1 ) ){ + wifi_tx = 2; + PIF2 = 0; // アセンブル結果はビット操作になってるので問題なし + PIF3 = 0; + } + +#ifdef debug_codes +#ifdef wifi_led_on_func + if( pwon_wt_sel ){ + if( n_key_func == 0 ){ + wifi_tx = 2; + } + } +#endif +#endif + + if( reg_wifi_led_blink != 0 ){ + if( wifi_tx != 0 ){ // TX active + switch( state ){ + case( 1 ): + case( 3 ): + case( 5 ): + led_wifi = 0; + TM50_Stop(); + break; + default: + if( vregs[ REG_INT_ADRS_BL ] >= 4 ){ + led_wifi = 1; + TM50_Stop(); + }else{ + CR50 = ( 255 >> ( 4 - ( vregs[ REG_INT_ADRS_BL ] ) ) ); + TM50_Start(); + led_wifi = 0; + } + } // switch〜 + state++; + if( state == 32 ){ + state = 0; + wifi_tx--; + } + return; + } // if〜 + }else{ + wifi_tx = 0; + } + ///// 点滅パターンここまで ///// + + state = 0; + // psy-no break // + if( reg_wifi_led != 0 ){ // 無線有効 + if( vregs[ REG_INT_ADRS_BL ] >= 4 ){ + led_wifi = 1; + TM50_Stop(); + }else{ + CR50 = ( 255 >> ( 4 - vregs[ REG_INT_ADRS_BL ] ) ); + TM50_Start(); + led_wifi = 0; + } + } +} + + + + + +void set_powLED_mode(){ + if( ( vregs[ REG_INT_ADRS_POWER_LED ] & 0x03 ) == 0x00 ){ // テストモード終了 + led_G_brightness_to = LED_G_BRIGHTNESS[ battLvl ]; + led_R_brightness_to = LED_R_BRIGHTNESS[ battLvl ]; + led_pwr_G_duty = 127; + led_pwr_R_duty = 127; + return; + }else{ + if( ( vregs[ REG_INT_ADRS_POWER_LED ] & 0x01 ) != 0 ){ // R + led_R_on; + TMHE0 = 0; /* stop TimerH0 */ + TOEN0 = 0; /* disable output */ + }else{ + TMHE0 = 0; /* stop TimerH0 */ + TOEN0 = 0; /* disable output */ + led_R_pwm; + } + if( ( vregs[ REG_INT_ADRS_POWER_LED ] & 0x02 ) != 0 ){ // B + led_G_on; + TMHE1 = 0; /* stop TimerH0 */ + TOEN1 = 0; /* disable output */ + }else{ + TMHE1 = 0; /* stop TimerH0 */ + TOEN1 = 0; /* disable output */ + led_G_pwm; + } + } +} + diff --git a/LEDs.h b/LEDs.h new file mode 100644 index 0000000..34892d5 --- /dev/null +++ b/LEDs.h @@ -0,0 +1,28 @@ +#ifndef __LEDS_H__ +#define __LEDS_H__ + +void tsk_power_led(); +static void power_led_status_watch_awake(); +static void power_led_status_watch_sleep(); +static void power_led_gradation(); +void led_pwm_GR_grad(); +void set_powLED_mode(); + +void tsk_wifi_led(); +void trig_to_sleep_wifiLed(); +void trig_to_wake_wifiLed(); + + +void set_camled(); +void set_camled_stop(); +void tsk_cam_led(); + +typedef enum camLed_mode_{ + camLed_off, + camLed_on, + camLed_blink, + camLed_def_on +}camLed_mode; + + +#endif diff --git a/PMIC_TWL2.c b/PMIC_TWL2.c new file mode 100644 index 0000000..8582302 --- /dev/null +++ b/PMIC_TWL2.c @@ -0,0 +1,132 @@ +/****************************************************************************** + 対PMIC_TWL2 I2C通信 + de JHL 藤田@開技 + nintendo + '07 Dec + +*******************************************************************************/ +#include "incs.h" + +extern u8 vregs[]; +extern bit rsv_set_BL; +bit eeprom_bl_dirty; +u8 bl_old; + +bit flg_BLChanged; + +extern u8 tsk_interval_cnt_power_led; +extern u8 tsk_interval_cnt_wifi_led; + + +u8 TBL_BL_Bright[5] = { 0, 2, 7, 14, 21 }; + + + +//****************************************************************************** +void pmic_init(){ + u8 temp; + + temp = iic2m_read_byte( IIC_SLV_ADDR_PMIC, 0x00 ); + vregs[ REG_INT_ADRS_PMIC_INFO ] = ( ( ( temp & 0x1C ) << 2 ) | ( temp & 0x03 ) ); + vregs[ REG_INT_ADRS_BATT_INFO ] = ( ( temp & 0xE0 ) >> 1 ); + PM_set_VRSET(); // 電源off時間1sec + + bl_old = TBL_BL_Bright[ vregs[ REG_INT_ADRS_BL ] ]; + iic2m_write_data( IIC_SLV_ADDR_PMIC, 0x03, bl_old ); // バックライト輝度復帰 +} + + + +/****************************************************************************** + バックライト1チック上げる + ******************************************************************************/ +void BL_inc(){ + if( vregs[REG_INT_ADRS_BL] != 0xFF ){ // 上限は BL_write() 内で制限&書き直し + vregs[REG_INT_ADRS_BL] += 1; + } + BL_write(); +} + + + +/****************************************************************************** + バックライト1チック下げる + ******************************************************************************/ +void BL_dec(){ + if( vregs[REG_INT_ADRS_BL] != 0 ){ + vregs[REG_INT_ADRS_BL] -= 1; + } + BL_write(); +} + + + +/****************************************************************************** + ******************************************************************************/ +void BL_write(){ + u8 dat; + +//*/ + // 最大値は BL_IND_MAX + if( vregs[REG_INT_ADRS_BL] > BL_IND_MAX ){ + vregs[REG_INT_ADRS_BL] = BL_IND_MAX; + } + dat = TBL_BL_Bright[ vregs[ REG_INT_ADRS_BL ] ]; +/*/ + // 最大値は32。テーブル引かない + if( vregs[REG_INT_ADRS_BL] > 31 ){ + vregs[REG_INT_ADRS_BL] = 31; + } + dat = vregs[REG_INT_ADRS_BL]; +//*/ + if( bl_old != dat ){ + bl_old = dat; + iic2m_write_data( IIC_SLV_ADDR_PMIC, 0x03, dat ); + eeprom_bl_dirty = 1; + flg_BLChanged = 1; + tsk_interval_cnt_power_led = 250; + tsk_interval_cnt_wifi_led = 250; + } +} + + + +/****************************************************************************** + ******************************************************************************/ +void PM_set_VRSET( void ){ + s8 tmp = 0; + + // PMICの電源ボタン押し時間セット + if( is_TWL ){ // tmp |= is_TWL? 0x06 : 0x02; はわかりづらい? + tmp |= 0x06; + }else{ + tmp |= 0x02; + } + + // PMICの省電力モードセット + + if( vregs[ REG_INT_ADRS_BATT_INFO ] != BATT_IS ){ + if( PM_SLP ){ + if( ( vregs[ REG_INT_ADRS_POWER_SAVE ] & 0x01 ) != 0 ){ tmp |= 0x40; } // 3.3 1でPFM + if( ( vregs[ REG_INT_ADRS_POWER_SAVE ] & 0x02 ) != 0 ){ tmp |= 0x20; } // 1.8 + if( ( vregs[ REG_INT_ADRS_POWER_SAVE ] & 0x04 ) != 0 ){ tmp |= 0x10; } // 1.2 +#ifdef after_x6 // X6以降は、スリープ中に無線を止め忘れてるのに対応 + if( TxPE == 1 ){ // 強制リセット + n_sys_reset_ast; + return; + } + if( RxPE == 1 ){ // Sleep中の無線停止忘れ対応 + tmp &= ~0x60; +#else // X6より前のは、強制的にPWMにします + { + tmp &= ~0x60; // ガイドライン違反なDSソフト、スリープ中にWiFi切り忘れ。シャットダウン防止 +#endif + } + }else{ // 通常時 + // nothing to do + } + }else{ // 赤箱 + // nothing to do + } + iic2m_write_data( IIC_SLV_ADDR_PMIC, 0x01, tmp ); +} diff --git a/PMIC_TWL2.h b/PMIC_TWL2.h new file mode 100644 index 0000000..0cc8cc5 --- /dev/null +++ b/PMIC_TWL2.h @@ -0,0 +1,22 @@ +#ifndef __PMIC_TWL2_H__ +#define __PMIC_TWL2_H__ + +#include "jhl_defs.h" + +#define IIC_SLV_ADDR_PMIC 0x82 + +enum PMIC_REG_ADRS{ + PMIC_REG_ADRS_VR_INF = 0x00, + PMIC_REG_ADRS_VR_SET, + PMIC_REG_ADRS_BT_CHK, + PMIC_REG_ADRS_BL_BRT +}; + + +void pmic_init(); +void BL_inc(); +void BL_dec(); +void BL_write(); +void PM_set_VRSET(); + +#endif diff --git a/Port.c b/Port.c new file mode 100644 index 0000000..63ce612 --- /dev/null +++ b/Port.c @@ -0,0 +1,34 @@ +#include "macrodriver.h" +#include "Port.h" + +#include "user_define.h" + + + +//***************************************************************************** +void PORT_Init( void ){ + PU1 = PUn0_PULLUP_ON | PUn1_PULLUP_ON | PUn3_PULLUP_ON | PUn4_PULLUP_ON; + + PM0 = PMn0_MODE_INPUT | PMn1_MODE_INPUT; + PM1 = PMn0_MODE_INPUT | PMn1_MODE_INPUT | PMn2_MODE_INPUT | PMn3_MODE_INPUT | PMn4_MODE_INPUT | PMn5_MODE_OUTPUT | PMn6_MODE_OUTPUT | PMn7_MODE_OUTPUT; + PM2 = PMn0_MODE_OUTPUT| PMn1_MODE_INPUT | PMn2_MODE_OUTPUT | PMn3_MODE_INPUT; + PM3 = PMn0_MODE_INPUT | PMn1_MODE_INPUT | PMn2_MODE_INPUT | PMn3_MODE_INPUT; + PM12= PMn0_MODE_INPUT | PMn1_MODE_OUTPUT | PMn2_MODE_INPUT; + + P0 = Pn1_OUTPUT_0; + P1 = Pn2_OUTPUT_1 | Pn5_OUTPUT_0 | Pn6_OUTPUT_0 | Pn7_OUTPUT_0; + P2 = Pn1_OUTPUT_0 | Pn2_OUTPUT_0 | Pn3_OUTPUT_0; + P3 = Pn1_OUTPUT_0 | Pn2_OUTPUT_0 | Pn3_OUTPUT_0; +//P6 はIICの初期化コード内でポートモード設定します。 + P12 = Pn0_OUTPUT_1 | Pn1_OUTPUT_0 | Pn2_OUTPUT_0; + + // 上りエッジで割り込み (for wifi)... + EGP = 0x0C; + // MK0L &= ~0x18; // マスクはしたまま。フラグを立てるだけ。ラッチです。非同期で短パルスを捕まえる + +#ifndef after_x6 // X6で回路変更があったため。 + IS_led_cam = 0; // X6以前の旧回路 + IS_led_cam_mode = 0; // X6以前の旧回路 (P0.1) +#endif +} + diff --git a/Port.h b/Port.h new file mode 100644 index 0000000..ec754f6 --- /dev/null +++ b/Port.h @@ -0,0 +1,95 @@ +#ifndef _MDPORT_ +#define _MDPORT_ + +/* Port mode register(PMn.0 to 7) */ +#define PMn0_NOT_USE 0x01 +#define PMn1_NOT_USE 0x02 +#define PMn2_NOT_USE 0x04 +#define PMn3_NOT_USE 0x08 +#define PMn4_NOT_USE 0x10 +#define PMn5_NOT_USE 0x20 +#define PMn6_NOT_USE 0x40 +#define PMn7_NOT_USE 0x80 + +#define PMn0_MODE_INPUT 0x01 +#define PMn0_MODE_OUTPUT 0x00 +#define PMn1_MODE_INPUT 0x02 +#define PMn1_MODE_OUTPUT 0x00 +#define PMn2_MODE_INPUT 0x04 +#define PMn2_MODE_OUTPUT 0x00 +#define PMn3_MODE_INPUT 0x08 +#define PMn3_MODE_OUTPUT 0x00 +#define PMn4_MODE_INPUT 0x10 +#define PMn4_MODE_OUTPUT 0x00 +#define PMn5_MODE_INPUT 0x20 +#define PMn5_MODE_OUTPUT 0x00 +#define PMn6_MODE_INPUT 0x40 +#define PMn6_MODE_OUTPUT 0x00 +#define PMn7_MODE_INPUT 0x80 +#define PMn7_MODE_OUTPUT 0x00 + +#define PMn0_CHANGE_OUTPUT 0xFE +#define PMn1_CHANGE_OUTPUT 0xFD +#define PMn2_CHANGE_OUTPUT 0xFB +#define PMn3_CHANGE_OUTPUT 0xF7 +#define PMn4_CHANGE_OUTPUT 0xEF +#define PMn5_CHANGE_OUTPUT 0xDF +#define PMn6_CHANGE_OUTPUT 0xBF +#define PMn7_CHANGE_OUTPUT 0x7F + +/* ADPC define */ +#define PORT_ADPC_0DIO 0 +#define PORT_ADPC_1DIO 1 +#define PORT_ADPC_2DIO 2 +#define PORT_ADPC_3DIO 3 +#define PORT_ADPC_4DIO 4 + +/* Port register(Pn.0 to 7) */ +#define Pn0_OUTPUT_0 0x00 +#define Pn0_OUTPUT_1 0x01 +#define Pn1_OUTPUT_0 0x00 +#define Pn1_OUTPUT_1 0x02 +#define Pn2_OUTPUT_0 0x00 +#define Pn2_OUTPUT_1 0x04 +#define Pn3_OUTPUT_0 0x00 +#define Pn3_OUTPUT_1 0x08 +#define Pn4_OUTPUT_0 0x00 +#define Pn4_OUTPUT_1 0x10 +#define Pn5_OUTPUT_0 0x00 +#define Pn5_OUTPUT_1 0x20 +#define Pn6_OUTPUT_0 0x00 +#define Pn6_OUTPUT_1 0x40 +#define Pn7_OUTPUT_0 0x00 +#define Pn7_OUTPUT_1 0x80 + +/* Pull-up resistor option register(PUn.0 to 7) */ +#define PUn0_PULLUP_OFF 0x00 +#define PUn0_PULLUP_ON 0x01 +#define PUn1_PULLUP_OFF 0x00 +#define PUn1_PULLUP_ON 0x02 +#define PUn2_PULLUP_OFF 0x00 +#define PUn2_PULLUP_ON 0x04 +#define PUn3_PULLUP_OFF 0x00 +#define PUn3_PULLUP_ON 0x08 +#define PUn4_PULLUP_OFF 0x00 +#define PUn4_PULLUP_ON 0x10 +#define PUn5_PULLUP_OFF 0x00 +#define PUn5_PULLUP_ON 0x20 +#define PUn6_PULLUP_OFF 0x00 +#define PUn6_PULLUP_ON 0x40 +#define PUn7_PULLUP_OFF 0x00 +#define PUn7_PULLUP_ON 0x80 + +#define PM0_DEFAULT 0xFC +#define PM2_DEFAULT 0xF0 +#define PM3_DEFAULT 0xF0 +#define PM6_DEFAULT 0xFC +#define PM12_DEFAULT 0xF8 + + + +void PORT_Init ( void ); + +void callbk_int_wifiTx(); + +#endif diff --git a/SW_I2C.c b/SW_I2C.c new file mode 100644 index 0000000..5c8fdec --- /dev/null +++ b/SW_I2C.c @@ -0,0 +1,187 @@ +/****************************************************************************** + ソフトウェアI2C通信 + de JHL 藤田@開技 + '07 Aug, '07 Dec + + !!注意!! + ・読み出し&書き込みを行うと (vol inc/dec) およそ1msかかります。 + ・クロックのデューティーなどを要求しないでください。 + ・割り込み禁止にしてないのでタイミングによっては割り込みが入ります。 + ・波形の対称性など気にしていません。最速でパタパタしますが、もともと遅いです。 + ・ウェイトコンディションをとりあえず気にしません。 + ・通信相手のセットアップタイムを気にせずに読みに行きます。でもともと遅いです(およそ1.2us)。 + ・通信中に割り込みなどでさらに通信が開始されることを想定していません。 +  (排他処理やバッファで受けたりしません)しないでください。 +*******************************************************************************/ +#include "macrodriver.h" +#include "port.h" +#include "user_define.h" +#include "SW_I2C.h" + +#define iics_sda_H PM1.1 = 1 +#define iics_sda_L { P1.1 = 0; PM1.1 = 0; } +#define iics_scl_H PM1.0 = 1 +#define iics_scl_L { P1.0 = 0; PM1.0 = 0; } +#define iics_sda P1.1 +#define iics_scl P1.0 + + +#define iic2m_send_start { iics_sda_H; iics_scl_H; iics_sda_L; iics_scl_L; } +#define iic2m_send_stop_0 { iics_sda_L; iics_scl_H; } +// ここでウェイトコンディションチェック // +#define iic2m_send_stop_1 { iics_sda_H; } +#define iic2m_send_stop { iic2m_send_stop_0; iic2m_send_stop_1; } + +#define iic2m_send_nack { iics_sda_H; iics_scl_H; iics_scl_H; iics_scl_L; } + +/****************************************************************************** + * スレーブアドレスアドレス slv_adrs の、レジスタ adrs (1バイト)返します。  + * リードエラーとかケアしません。危険。 + ******************************************************************************/ +u8 iic2m_read_byte( u8 slv_adrs, u8 adrs ){ + u8 b, tmp; + + iic2m_send_start; + if( iic2m_w_byte( slv_adrs | 0x00 ) != 0x00 ){ // スレーブアドレス + iic2m_send_stop; + return( 0x5A ); + } + iic2m_w_byte( adrs ); + + iic2m_send_start; + if( iic2m_w_byte( slv_adrs | 0x01 ) != 0x00 ){ // スレーブアドレス + iic2m_send_stop; + return( 0xA5 ); + } + // 実リード + iics_sda_H; + for( b = 0; b != 8; b++ ){ + tmp <<= 1; + iics_scl_H; + if( iics_sda != 0 ){ + tmp |= 0x01; + } + iics_scl_L; + } + iic2m_send_nack; // 最終バイトはNACKを返す。 + iic2m_send_stop; + return tmp; +} + + +/****************************************************************************** + * スレーブアドレスアドレス slv_adrs の、レジスタ adrs に1バイト書きます。 + * スレーブ呼び出しでNACKなら、0xFFで中断終了です。 + ******************************************************************************/ +unsigned char iic2m_write_data( u8 slv_adrs, u8 adrs, u8 dat ){ + u8 status; + + iic2m_send_start; + if( iic2m_w_byte( slv_adrs | 0x00 ) != 0x00 ){ // スレーブアドレス + iic2m_send_stop; + return( 0xFF ); + } + iic2m_w_byte( adrs ); // レジスタアドレス + iic2m_w_byte( dat ); // データ1バイト + iic2m_send_stop; + return( 0 ); +} + + +#if 0 +未使用です +/****************************************************************************** + * スレーブアドレスアドレス slv_adrs の、 + * レジスタ adrs を先頭に、 + * *strから + * len文字書きます。 + * エラーとかケアしません。危険。 + ******************************************************************************/ +void iic2m_write_nmem( u8 slv_adrs, u8 adrs, s8* str, u8 len ){ + u8 i; + + iic2m_send_start; + iic2m_w_byte( slv_adrs | 0x00 ); + iic2m_w_byte( adrs ); + for( i = 0; i < len; i++ ){ + iic2m_w_byte( *str ); + str++; + } + /* + while( *str != "\0" ){ + iic2m_w_byte( *str ); + str++; + } + */ + iic2m_send_stop; +} +#endif + + +/****************************************************************************** + バスのリセット + ストップコンディションが出せそうだったらすかさず出す。 + ******************************************************************************/ +void iic2m_bus_reset(){ + u8 count; + + for( count = 19; count != 0; count-- ){ + iics_sda_H; + iics_scl_H; + PM1.1 = 1; // SDA + if( iics_sda != 0 ){ + PM1.1 = 0; + iic2m_send_stop; + return; + } + PM1.1 = 0; + iics_scl_L; + } + return; +} + + +/****************************************************************************** + I2C単機能API + ほんとに1バイト書くだけ + ******************************************************************************/ +static unsigned char iic2m_w_byte( unsigned char dat ){ + unsigned char b; + unsigned int tot; + + // 引数の8bitを順々にだします。 + for( b = 0; b != 8; b++ ){ + if( ( dat & 0b10000000 ) != 0 ){ + iics_sda_H; + }else{ + iics_sda_L; + } + iics_scl_H; + dat <<= 1; // ついでに時間稼ぎ。アセンブラならもっと上手に書くのに! + iics_scl_L; + } + iics_sda_H; + iics_scl_H; + +#ifdef enable_swi2c_wait + tot = 0; + while( iics_scl == 0 ){ + // ウェイトコンディション + // まじめにやるとタイムアウトとかどうしようとか、何かスレーブが + // バスを開放してくれなくなったら、もう全デバイスと通信できないじゃんとか + if( ++tot > 10000 ){ + iics_scl_L; + return( 0xFE ); + } + } +#endif + + if( iics_sda != 0 ){ + // NACK + iics_scl_L; + return( 0xFF ); + } + iics_scl_L; + return( 0 ); +} + diff --git a/SW_I2C.h b/SW_I2C.h new file mode 100644 index 0000000..6a2fbc0 --- /dev/null +++ b/SW_I2C.h @@ -0,0 +1,15 @@ +#ifndef __sw_i2c__ +#define __sw_i2c__ + +#include "jhl_defs.h" + + +unsigned char iic2m_read_byte( u8 slv_adrs, u8 adrs ); +unsigned char iic2m_write_data( u8 slv_adrs, u8 adrs, u8 dat ); +static unsigned char iic2m_w_byte( u8 dat ); +void sw_i2c_send_stop(); +void iic2m_bus_reset(); + +void iic2m_write_nmem( u8 slv_adrs, u8 adrs, s8* str, u8 len ); + +#endif diff --git a/System.c b/System.c new file mode 100644 index 0000000..83825b8 --- /dev/null +++ b/System.c @@ -0,0 +1,22 @@ +#include "macrodriver.h" +#include "System.h" + +#include "user_define.h" + + + +void Clock_Init( void ) +{ + OSCCTL = CG_HISYSTEM_PORT; /* Set fxh */ + MSTOP = 1; + + RSTOP = 0; /* Set frh */ + + // システム = 8MHz + // CPU = 8MHz + // ペリフェラル = 8MHz + MCM = CG_MAINPERI_INTER; /* Set fprs */ + PCC = CG_CPUCLOCK_FXP; + + LSRSTOP = 0; /* Set frl */ +} diff --git a/System.h b/System.h new file mode 100644 index 0000000..4fa5636 --- /dev/null +++ b/System.h @@ -0,0 +1,140 @@ +#ifndef _MDSYSTEM_ +#define _MDSYSTEM_ +/* +******************************************************************************* +** Register bit define +******************************************************************************* +*/ +/* + Clock Operation Mode Select Register (OSCCTL) +*/ +/* High-speed system clock pin operation mode (EXCLK, OSCSEL) */ +#define CG_HISYSTEM_EXTCLK 0x80 /* external clock bit */ +#define CG_HISYSTEM_OSCSEL 0x40 /* clock/port bit */ + +#define CG_HISYSTEM_PIN 0xc0 +#define CG_HISYSTEM_PORT 0x00 /* X1, X2 as I/O port */ +#define CG_HISYSTEM_OSC 0x40 /* X1, X2 as crystal/ceramic resonator connection */ +#define CG_HISYSTEM_PORT1 0x80 /* X1, X2 as I/O port */ +#define CG_HISYSTEM_EXT 0xc0 /* X1 as External clock input, X2 as I/O port */ +/* Subsystem clock pin operation mode (EXCLKS, OSCSELS) */ +/** Note: valid when PCC.XTSTART = 0 **/ +#define CG_SUBCLOCK_OSCSELS 0x10 /* sub clock/port bit */ + +#define CG_SUBCLOCK 0x30 +#define CG_SUBCLOCK_PORT 0x00 /* XT1, XT2 as I/O port */ +#define CG_SUBCLOCK_OSC 0x10 /* XT1, XT2 as crystal resonator connection */ +#define CG_SUBCLOCK_PORT1 0x20 /* XT1, XT2 as I/O port mode */ +#define CG_SUBCLOCK_EXT 0x30 /* XT1 as External clock input, X2 as I/O port */ +/* Operating frequency control (AMPH) */ +#define CG_OPERATING_FREQ 0x01 +#define CG_OPERATING_UNDER10M 0x00 /* 1 MHz <=fxh <= 10 MHz */ +#define CG_OPERATING_OVER10M 0x01 /* 10 MHz < fxh <= 20 MHz */ + +/* + Processor Clock Control Register (PCC) +*/ +/* Subsystem clock pin operation mode (XTSTART) */ +#define CG_XTSTART 0x40 +#define CG_XTSTART_OTHER 0x00 /* sub clock pin mode set by OSCCTL */ +#define CG_XTSTART_OSC 0x40 /* XT1, XT2 as crystal resonator connection */ +/* System clock status *read only (CLS) */ +#define CG_CPUCLOCK_STATUS 0x20 +#define CG_CPUCLOCK_MAINSTATUS 0x00 /* main system clock status */ +#define CG_CPUCLOCK_SUBSTATUS 0x20 /* sub system clock status */ +/* CPU clock (fcpu) selection source (CSS) */ +#define CG_CPUCLOCK_SOURCE 0x10 +#define CG_CPUCLOCK_MAIN 0x00 /* main system clock */ +#define CG_CPUCLOCK_SUB 0x10 /* sub system clock */ +/* CPU clock (fcpu) selection (PCC0, PCC1, PCC2) */ +/** Note: valid when PCC.CSS = 0 **/ +#define CG_CPUCLOCK 0x07 +#define CG_CPUCLOCK_FXP 0x00 /* fcpu = fxp */ +#define CG_CPUCLOCK_FXP2 0x01 /* fcpu = fxp/2 (default) */ +#define CG_CPUCLOCK_FXP4 0x02 /* fcpu = fxp/4 */ +#define CG_CPUCLOCK_FXP8 0x03 /* fcpu = fxp/8 */ +#define CG_CPUCLOCK_FXP16 0x04 /* fcpu = fxp/16 */ + +/* + Internal Oscillation Mode Register (RCM) +*/ + +/* Status of internal high-speed oscillator *read only (RSTS) */ +#define CG_HIGHINTERNAL_STATUS 0x80 +#define CG_HIGHINTERNAL_WAIT 0x00 /* wait for ready */ +#define CG_HIGHINTERNAL_READY 0x80 /* ready for operation */ +/* Internal low-speed oscillator oscillating/stopped (LSRSTOP) */ +#define CG_LOWINTERNAL 0x02 +#define CG_LOWINTERNAL_RUN 0x00 /* internal low-speed oscillator oscillating */ +#define CG_LOWINTERNAL_STOP 0x02 /* internal low-speed oscillator stopped */ +/* Internal high-speed oscillator oscillating/stopped (RSTOP) */ +#define CG_HIGHINTERNAL 0x01 +#define CG_HIGHINTERNAL_RUN 0x00 /* internal high-speed oscillator oscillating */ +#define CG_HIGHINTERNAL_STOP 0x01 /* internal high-speed oscillator stopped */ + +/* + Main OSC control register (MOC) +/* Control of high-speed system clock operation (MSTOP) */ +#define CG_HISYSTEM 0x80 +#define CG_HISYSTEM_RUN 0x00 /* X1 oscillator/external clock enable */ +#define CG_HISYSTEM_STOP 0x80 /* X1 oscillator/external clock disable */ + +/* + Main Clock Mode Register (MCM) +*/ +/* Selection of clock supplied to main system clock and peripheral hardware (XSEL, MCM0) */ +#define CG_MAINPERI_CLOCK 0x05 +#define CG_MAINPERI_INTER 0x00 /* fxp = frh,fprs = frh */ +#define CG_MAINPERI_INTER1 0x01 /* fxp = frh,fprs = frh */ +#define CG_MAINPERI_INTER_SYS 0x04 /* fxp = frh,fprs = fxh */ +#define CG_MAINPERI_SYS 0x05 /* fxp = fxh,fprs = fxh */ +/* Main system clock status *read only (MCS) */ +#define CG_MAINSYSTEM_STATUS 0x02 +#define CG_MAINSYSTEM_INTER 0x00 /* Operates with internal high-speed oscillation clock */ +#define CG_MAINSYSTEM_SYS 0x02 /* Operates with high-speed system clock */ + +/* + Oscillation Stabilization Time Counter Status Register (OSTC) +*/ +/* Oscillation stabilization time status ( MOST11-16) */ +#define CG_OSCSTAB_STATUS 0x1f +#define CG_OSCSTAB_STATUS11 0x10 /* 2^11/fx */ +#define CG_OSCSTAB_STATUS13 0x18 /* 2^13/fx */ +#define CG_OSCSTAB_STATUS14 0x1c /* 2^14/fx */ +#define CG_OSCSTAB_STATUS15 0x1e /* 2^15/fx */ +#define CG_OSCSTAB_STATUS16 0x1f /* 2^16/fx */ + +/* + Oscillation Stabilization Time Select Register (OSTS) +*/ +/* Oscillation stabilization time selection (OSTS2-0) */ +#define CG_OSCSTAB_SELECT 0x07 +#define CG_OSCSTAB_SELECT11 0x01 /* 2^11/fx */ +#define CG_OSCSTAB_SELECT13 0x02 /* 2^13/fx */ +#define CG_OSCSTAB_SELECT14 0x03 /* 2^14/fx */ +#define CG_OSCSTAB_SELECT15 0x04 /* 2^15/fx */ +#define CG_OSCSTAB_SELECT16 0x05 /* 2^16/fx */ + + +/* +******************************************************************************* +** Macro define +******************************************************************************* +*/ +#define CG_FRHWAITTIME 40 +enum ClockMode { HIOCLK, SYSX1CLK, SYSEXTCLK, HIOSYSCLK }; +enum CPUClock { SYSTEMCLOCK, SYSONEHALF, SYSONEFOURTH, SYSONEEIGHTH, SYSONESIXTEENTH }; +enum PSLevel { PSSTOP, PSHALT }; +enum StabTime { STLEVEL0, STLEVEL1, STLEVEL2, STLEVEL3, STLEVEL4 }; + +/* +******************************************************************************* +** Function define +******************************************************************************* +*/ +void Clock_Init( void ); +void CG_ReadResetSource( void ); +/* Start user code for definition. Do not edit comment generated here */ +void hdwinit( void ); +/* End user code for definition. Do not edit comment generated here */ +#endif diff --git a/System_user.c b/System_user.c new file mode 100644 index 0000000..e724aab --- /dev/null +++ b/System_user.c @@ -0,0 +1,14 @@ +#include "macrodriver.h" +#include "System.h" + +#include "user_define.h" + + + +void CG_ReadResetSource( void ) +{ + UCHAR resetflag = RESF; + + if( resetflag & WDTRF ){ // 起動イルミを隠すかも + } +} diff --git a/TWL_MCU_33-MP_95811supp.hex b/TWL_MCU_33-MP_95811supp.hex new file mode 100644 index 0000000..32267a5 --- /dev/null +++ b/TWL_MCU_33-MP_95811supp.hex @@ -0,0 +1,620 @@ +:10000000F600FFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +:10002000FFFFFFFF350DFFFFFFFF6A0EFFFFFFFF22 +:10003000FFFFFFFF8813FFFFFFFFFFFFFFFFFFFF33 +:100080007E00000000CC23BAC37D94FE73A5E6FF7A +:1000900000080000000A00A00003000000000000AB +:1000A000000000000002070E150000000028333990 +:1000B00040464C52565A5F646A6F74797E83898FCA +:1000C00094999DA1A5A8ABAEB1B4B7BA6352431F32 +:1000D000006352442E1B4D34210B0052372A1E1B45 +:1000E0004E3E3020004E3E302010000000FFFFFF4B +:1000F000FFFFFF00000061D0EE1C1EFE9AB305104A +:1001000000000300FC161FFEA3C0A100BB8BFD1660 +:100110009000148AFCC6EAAC00AD0687958684FA86 +:10012000F41602FCC6EA8AFCAD06A1009786FAF432 +:1001300016800014A6FCC6EA8000AD06879586846A +:10014000FAF416A6FCC6EAA6FCAD06A1009786FA4C +:10015000F49AC501FAFE4D00AD1AB3D289BA61FC1A +:100160002530253083B92583B983B82583B88BEE34 +:1001700099BAC2B2AF83B85EBC83B883B95EBD839F +:10018000B9305EBA305EBB99BAAF1020FE0302FCF4 +:10019000100CFC0304FCA1009E06FC9E07FCA10CB5 +:1001A0009E08FCA1019E09FC419E0AFC0A027B1EDE +:1001B0001002FC9A0E199A42194252BD039A3A193A +:1001C0007A1E0B02AF9AD50DA1059E2EFCA1009EB2 +:1001D0006EFCA1209E71FC9AD90A9AA2149AAC02D4 +:1001E000311384161B84AC84059AF002FA0C310397 +:1001F00084059A840BFA039AFF017110FADCAF9A16 +:100200007B049A12058C00191492FC854D00AD11E7 +:10021000A100958E16FC9E71FC9A42159A4010FA28 +:1002200025310300211492FC8551AD1AA101958E50 +:1002300071FC9E16FCA1009E71FC9A42159A8005E5 +:100240009A58109AAC108E7BFC4D00BD14148CFC97 +:100250008541954814FC8D06A100959A6D0E9A99DA +:100260000E148EFC854195488FFC8D06A100959A51 +:10027000C7101490FC8541954891FC8D06A100950E +:100280009A6610148DFC8541954815FC8D06A100D9 +:10029000959A2A03148AFC854195488BFC8D06A10A +:1002A00000959A030731230C021B0CAF31738405B0 +:1002B0007B849A4010AC0C07A101482EFC8D039A58 +:1002C0008005314384054B849AE806315384055BED +:1002D000849A0815316384056B849A42153103852D +:1002E000050B859AD90A311385051B859A9211AFA2 +:1002F000AC010B31030332BC012F3A84FA2B9ADD97 +:10030000129ABE059A4C179A63173133840AA100DA +:100310009E76FC9AE806FA039A00069ADD129AA6DF +:10032000149AD90A9A96142A84AF8C03039BD80393 +:100330008C0018CC010E8E18FC41AD141418FC85ED +:100340004195FA0CA1009E18FCFA05A1009E18FC2C +:10035000A1009E1AFC9E19FCBC010E8E17FC41AD3B +:100360000D1417FC854195FA05A1009E17FCCC01E0 +:100370002E3133012A8E18FC51BD07A1029E15FCB7 +:10038000FA538E18FC4D05BD059A1406FA478E18CF +:10039000FC4D288D409A1406A1209E15FCFA36319A +:1003A00043012DBC012A8E17FC51BD07A1029E15E9 +:1003B000FCFA228E17FC4D05BD059A7506FA168EBD +:1003C00017FC4D288D0F9A7506A1209E15FCFA0585 +:1003D000A1029E15FC9B7A04310300039B7A04A1C1 +:1003E000009E18FC9E17FCCC010E8E1AFC41AD0D30 +:1003F000141AFC854195FA05A1009E1AFCBC010E59 +:100400008E19FC41AD0D1419FC854195FA05A1002A +:100410009E19FCCC012E3133012A8E1AFC51BD07E6 +:10042000A1029E15FCFA538E1AFC4D05BD059AE7F4 +:1004300014FA478E1AFC4D288D409AE714A1209E8D +:1004400015FCFA363143012DBC012A8E19FC51BD31 +:1004500007A1029E15FCFA228E19FC4D05BD059AD6 +:10046000F714FA168E19FC4D288D0F9AF714A12057 +:100470009E15FCFA05A1029E15FCAF9C02658E1B21 +:10048000FC41AD06141BFC8541958E93FC4D00BDCF +:10049000268E1BFC4884FC8D1EA1019E93FC8E7150 +:1004A000FC310F11146FFC856D08950B0C710B2C32 +:1004B0000A0C710A2CFA5A8E93FC51BD548E1BFC07 +:1004C0004885FC8D4CA1029E93FC8E71FC310F413E +:1004D000146FFC856D02950B0C710B2C0A0C710AC4 +:1004E0002CFA2E8E93FC51BD208E71FC310F13140B +:1004F0006FFC856D01950B0C710B2C0A0C710A2C8D +:10050000FA071470FC856D0195A1009E1BFC9E935B +:10051000FCAF8E70FC311F02FA0B8E70FC310F05A0 +:10052000712B212B01AC01528E1CFC4D029D081435 +:100530001CFC854195FA48A1009E6FFC9E70FC9EB4 +:1005400075FC9A5810A1009E71FCA1079E73FC9A3D +:10055000D90A6A84147BFC854D00AD06A100959AEA +:100560009211A1009E5CFC0A0C710A2C712A212AAE +:10057000017A1EA1039E93FCFA05A1009E1CFCAF0C +:10058000B7312385101477FCB5A0009AFD17B0424F +:1005900052BD022B85B6AF9A970D9A840D9A9D0D88 +:1005A0009A55149A620D9AC20D9A100E9A3D0E9A9F +:1005B000E60DAF7B1E13F0049A97057A1EAFA133A8 +:1005C0009E6CFCA1079E73FCA1109E84FCA1649EFE +:1005D00085FCAFB7B1B1891CD6A100BE01AE014DFB +:1005E00020AD1772B716AC00AAB64902BD05AE0120 +:1005F00072FA09AE0141BE01FAE3A217B0B0B6AF7C +:10060000A000B1A0509AEA11B03270329AD30562BC +:100610009E76FCAF146FFC856D40958E71FC310F9A +:100620000A0B0C710B2C0A0C710A2C8E76FC4D1FD8 +:10063000AD428E71FC317E29A1014876FC8D0914F2 +:1006400076FC850D0295FA1FA1044876FC8D0914ED +:1006500076FC850D0495FA0F1476FC850D0595FA48 +:10066000061476FC854195A11F4876FC9D039E7675 +:10067000FC9AE806AF146FFC856D40958E71FC31D5 +:100680000F0A0B0C710B2C0A0C710A2C8E76FC4D88 +:1006900000AD548E71FC317E398E76FC4D0B8D0988 +:1006A0001476FC851D0595FA2F8E76FC4D068D0976 +:1006B0001476FC851D0495FA1F8E76FC4D05BD0948 +:1006C0001476FC851D0395FA0F1476FC851D0495A0 +:1006D000FA061476FC855195A17F4876FC9D05A10C +:1006E000009E76FC9AE806AFB78E76FC5D1F72B767 +:1006F00016AC00AAB676B7A000B1A0509A9112B07D +:10070000B0B6AFB78E2EFC9E2FFC023EFC0340FC21 +:10071000023CFC033EFC023AFC033CFC0238FC03B6 +:100720003AFC0236FC0338FC0234FC0336FC02328D +:10073000FC0334FC0230FC3061013027D20232FC71 +:1007400030081EFC30281FFCCA05006143BD033081 +:1007500061429D280230FC3061013027D20232FC18 +:1007600030081EFC30281FFCDA0500614BBD033049 +:10077000614A9D080230FC0332FCFA130230FC305F +:10078000081EFC30281FFC21253025300332FC02D6 +:100790001EFC0330FC0240FC30083EFC30283FFCCD +:1007A00030083CFC30283DFC30083AFC30283BFC4B +:1007B000300838FC302839FC300836FC302837FC4B +:1007C000300834FC302835FC300832FC302833FC4B +:1007D000A20831820320FC8C000DA1009E42FCA0E7 +:1007E000000344FC9BBB081442FC85419551BD03AA +:1007F0009BBB088E42FC4D02AD039B91080240FC5E +:100800000346FC023EFC4847FCBD04304846FC9DC4 +:1008100006023EFC0346FC023CFC4847FCBD04309B +:100820004846FC9D06023CFC0346FC023AFC484755 +:10083000FCBD04304846FC9D06023AFC0346FC021F +:1008400038FC4847FCBD04304846FC9D060238FC95 +:100850000346FC0236FC4847FCBD04304846FC9D7C +:10086000060236FC0346FC0234FC4847FCBD04305B +:100870004846FC9D060234FC0346FC0232FC484715 +:10088000FCBD04304846FC9D320232FC0346FCFAB3 +:100890002A8E42FC4D7F9D1D0220FC301846FC3004 +:1008A0003847FC0344FCEA00808D10AD0E100000B8 +:1008B0000344FCFA061442FC8551950220FC3018D2 +:1008C00044FC303845FC4825FCBD04304824FC8DF0 +:1008D00006AD04A605FA720220FC301844FC30383C +:1008E00045FC4827FCBD04304826FC8D06AD04A617 +:1008F00004FA560220FC301844FC303845FC4829E4 +:10090000FCBD04304828FC8D06AD04A603FA3A026B +:1009100020FC301844FC303845FC482BFCBD04302A +:10092000482AFC8D06AD04A602FA1E0220FC3018EF +:1009300044FC303845FC482DFCBD0430482CFC8D6F +:1009400006AD04A601FA02A6008E48FC614EAD0B6E +:10095000A1009E49FC669E48FCFA5C1449FC854156 +:10096000958E94FC4D1E9D181494FC854195A10A0A +:100970004849FC9D42A1009E49FC669E2EFCFA3728 +:10098000A1194849FC9D30A1009E49FCBC031C8E66 +:100990002EFC614E9D06142EFC85419566482EFC6A +:1009A000AD154D00BD119E2EFCFA0C66482EFC9D27 +:1009B00006142EFC8551958E2EFC4D00AD2C4D0558 +:1009C000AD214D04AD164D03AD0B4D02BD23A1036A +:1009D0009E72FCFA21A1079E72FCFA1AA10B9E726C +:1009E000FCFA13A10F9E72FCFA0CA1009E72FCFA95 +:1009F00005A1019E72FC9A010A9A330A9A6C0DB6FF +:100A0000AFA102482FFC9D11482EFC8D0CA010B107 +:100A100070B1A0829A9112B0B0A103482FFC8D1240 +:100A2000482EFC9D0DA000B1A002B1A0829A9112A7 +:100A3000B0B0AF8E2EFC51BD221495FC854D00BD8B +:100A40001AA10295146FFC856D20958E71FC310FF3 +:100A50000A0B0C710B2C0A0C710A2C8E71FC311FC5 +:100A60004D8E2EFC4D00BD461495FC854D00BD1CE1 +:100A7000A10395146FFC856D30958E71FC310F2E9E +:100A80000B0C710B2C0A0C710A2CFA221495FC85A4 +:100A90004D02BD1AA10395146FFC856D10958E71E2 +:100AA000FC310F0A0B0C710B2C0A0C710A2C8E2EC8 +:100AB000FC4D018D0E146FFC855DEF951495FC8542 +:100AC0005DFE958E2EFC4D028D0E146FFC855DCF64 +:100AD000951495FC855DFC95AFB7B1B1891CD68E98 +:100AE00071FC311F2C8E6EFC4D00BD0A10D100BE72 +:100AF0000330BE02FA4A8E6EFC4D30BD0A10E5008E +:100B0000BE0330BE02FA3910DB00BE0330BE02FA6B +:100B10002F8E6EFC4D00BD0A10CC00BE0330BE020D +:100B2000FA1E8E6EFC4D30BD0F10E000BE0330BECD +:100B3000021B00711B20FA0810D600BE0330BE0253 +:100B4000A100BE01AE014D05AD368E22FCA00030E5 +:100B50000D02D2AE0230AE03D48561029D0143AED8 +:100B600001A0023188CA24FCD46295638495AE0248 +:100B700030AE0380BE0330BE02AE0141BE01FAC4F6 +:100B8000B0B0B6AFB7B1891CD68E97FC4D03BD038C +:100B90009B3E0C4D02AD594D01AD314D00AD039B57 +:100BA0006E0C9A92149A360E9A630E9A090E7A0176 +:100BB0005A016A0113417CA000B1A002B1A0829A3F +:100BC0009112B0B0A1019E97FC9B2F0D8E6EFC4D33 +:100BD00030BD07A1029E97FCFA133103000F7B0181 +:100BE000A1079E73FC9A4215A1029E97FC9B2F0DB4 +:100BF000021EFC5D00EA7F008D05AD039B2F0D02F8 +:100C00001EFC5D0030728E9BFC73B762164FFCBBFE +:100C1000B6021EFC5D00D20298FC30610A30612BE6 +:100C20000398FC149BFC854D07BD0AA10095A10308 +:100C30009E97FCFA06149BFC8541959B2F0D021E86 +:100C4000FC5D0030728E9BFC73B7621657FCBBB61E +:100C50008E9BFC4D03BD0E6B01A1009E9BFCA1046D +:100C60009E97FCFA06149BFC8541959B2F0DAC01C9 +:100C7000039B2F0D0298FCA208318260BE018E6E8C +:100C8000FC4D30BD16AE011D19BE01C680B1A001DC +:100C90009AFD17B04252BD0313995A8E9AFC49012E +:100CA000AD1AC680B1A0019AFD17B04252BD0D5BCE +:100CB000016A01AE019E9AFC6B015A01021EFC5DA5 +:100CC00000EA80009D698E9BFC72B7164FFCAAB6A5 +:100CD000720298FC30611A303D000398FC8E9BFC38 +:100CE0005D0372B71657FCAAB6728E9BFC73B7628F +:100CF000164FFCBBB68E9BFC72B7164FFCAAB672A1 +:100D00000298FC30610A302D000398FC021EFC5D45 +:100D10000030728E9BFC5D0373B7621657FCBBB646 +:100D20008E9BFC4D079D0341FA02A1009E9BFC9AFD +:100D30006C0DB0B6AFB1B3B589B8B189BAB189BCE1 +:100D4000B189BEB17A1E8908A2403182031EFC9A85 +:100D50007A0DB099BEB099BCB099BAB099B8B4B296 +:100D6000B08F132F03132890132903AF710A2800A3 +:100D7000000000717A28710BE6AF710AE6717B28DA +:100D8000710B28AF139F00717AA2710BA013A10001 +:100D900013FB00711BA0AFB7F4AC76B6AF13311BD9 +:100DA00013200313211F13220A13230F132C0511E1 +:100DB0000000110104110200110300110C0113487D +:100DC0000CAF717B43713AE6713BE2138C06134121 +:100DD0009B134300AF713BE6717A43AF717B437164 +:100DE0003AE6713BE2AF717B6B715AE5715BE113DF +:100DF0006A03F4215D7FF621D8017F11177F136B01 +:100E000040AF710A6B717A6BAF717B6B710B6BAF1B +:100E1000717B69714AE5714BE11369281118FF1163 +:100E20001900F4215DDFF621D801DFAF111900713F +:100E30000A69717A69AF717B69710B69AF717B6CFB +:100E4000713AE5713BE1136C18111AFF111B00F4A4 +:100E5000215DBFF621D801BFAF111B00710A6C7173 +:100E60007A6CAF717B6C710B6CAF1A848F31230C71 +:100E700012717B6C710B6C6B01717B69710B695B1F +:100E800001FA158C000AA11E9E14FC9A2F0FFA0875 +:100E9000A1A09E14FC9ACF0FAF310300108E9CFCD2 +:100EA0004D019D09149CFC8541959B2E0FA1009E30 +:100EB0009CFCF01B485EFCAD11F01B485EFC9D04E1 +:100EC000A101FA02A1FF0E1BF21BC81B00BD0A7193 +:100ED0007B6C710B6C6B01FA17C81BFFBD0A6A01B2 +:100EE000717B6C710B6CFA086B01710A6C717A6C16 +:100EF000F019485FFCAD11F019485FFC9D04A10199 +:100F0000FA02A1FF0E19F219C81900BD0A717B6916 +:100F1000710B695B01FA17C819FFBD0A5A01717B91 +:100F200069710B69FA085B01710A69717A69AFB777 +:100F3000A1009E60FC8E2EFC4D028D4DA104187701 +:100F4000FC728E2EFC73B716EA00ABB65242AD04AB +:100F500021258AFC9E5EFCA1041877FC728E2EFC73 +:100F600073B716F000ABB65242AD0421258AFC9E41 +:100F70005FFC3133850C3B858E5EFCF21B8E5FFC83 +:100F8000F219A1009E61FCFA44A1009E5EFCF21BD6 +:100F90008E61FC4D00BD1AA1041877FC728EF00022 +:100FA0005242AD0421258AFCF219F0199E5FFCFA29 +:100FB0000F8E61FC4D02BD08111900A1009E5FFC5F +:100FC0001461FC8541954D04BD03A10095B6AF8E1B +:100FD00060FC4D10AD3F4D0CAD3B4D08AD374D04A1 +:100FE000AD334D00AD2F4D0EAD0C4D0AAD084D0685 +:100FF000AD044D02BD3CA102482EFC9D0CA1289ED3 +:101000005EFCA1009E5FFCFA29A1009E5EFCA12867 +:101010009E5FFCFA1DA102482EFC9D0CA1059E5E60 +:10102000FCA1009E5FFCFA0AA1009E5EFCA1059E49 +:101030005FFC1460FC8541954D12BD03A10095AF86 +:101040008E62FC4D02AD089A6610A1009E90FC8E47 +:1010500075FC5D039E62FCAF8E6EFC4D30AD042BC3 +:1010600002FA021B00AF31030002FA3F8E6EFC4D04 +:1010700030AD1D8E75FC5D034D02AD0751BD0D2ACF +:1010800002FA2871240201712102FA1F2B02FA1BB5 +:101090008E75FC5D034D02AD0751BD0D1A00FA0BB4 +:1010A00071140001711100FA021B00AF8E74FC3143 +:1010B0000F087B011117059A020EAF8E74FC310FD9 +:1010C000059A090E7B01AF8E74FC310E0D9A090E44 +:1010D0007B01A1009E5CFC9B9111310300039B915D +:1010E000113136E0043147E00BA1029E5CFC713BFC +:1010F000E0714BE08E74FC311F5C8E5CFC4D00ADEA +:101100005A8E63FC4D05AD074D03AD0351BD077B02 +:10111000019A090EFA2B8E77FC4D048D077A019AFD +:10112000090EFA1DA1041877FC61617210FF00AD71 +:101130000861FC253025308AF860F2179A020E7B90 +:10114000011463FC8541954D20BD46A10095145CBA +:10115000FC855195FA3BA1009E5CFCA1009E63FCBE +:101160008E74FC310F2B8E77FC4D048D077A019A1B +:10117000090EFA1DA1041877FC61617210FF00AD21 +:101180000861FC253025308AF860F2179A020E7B40 +:1011900001AFB78E7BFC5D03BD1E8E2EFC7216EA7E +:1011A00000AA9E5EFC8E2EFC7216F000AA9E5FFCCA +:1011B000111B7F11197FFA308E7BFC310F0A5A0107 +:1011C000717B69710B69FA08717B69710B695B014D +:1011D0008E7BFC311F0A6A01717B6C710B6CFA0803 +:1011E000717B6C710B6C6B01B6AFB7B1B1891CD65A +:1011F000711A21710A211B01711B210B01710B2135 +:10120000AE02709A0F134252AD0F1B01711B217178 +:101210000A21711A21A25AFA74AE08709A0F13713A +:101220001A21710A211B01711B210B01710B21AEC7 +:10123000026D01709A0F134252AD0F1B01711B21F9 +:10124000710A21711A21A2A5FA43711A21A100BEC7 +:1012500001AE014D08AD1B87610197710A21311361 +:101260000104876D01970B01710B21AE0141BE0195 +:10127000FADF711A21710A21710A210B01710B2108 +:101280001B01711B21710A21711A218772B0B0B63E +:10129000AFB7B1B1891CD6711A21710A211B017136 +:1012A0001B210B01710B21AE02709A0F134252AD3C +:1012B0000F1B01711B21710A21711A21A2FFFA195A +:1012C000AE08709A0F13AE0A709A0F131B01711BB0 +:1012D00021710A21711A21A200B0B0B6AFB7A613CE +:1012E000664D00AD28711A21710A21711A2131133E +:1012F0000110711B211B01711B21710A21711A211F +:10130000FA0B711B210B01710B2156FAD3B6AFB743 +:10131000B1B1B1891CD6A100BE03AE034D08AD2406 +:10132000AE04317F05711A21FA051B01711B217171 +:101330000A21AE046101BE040B01710B21AE034111 +:10134000BE03FAD6711A21710A21A100BE01BE02A4 +:101350008C011CAE0130AE0280BE0230BE0130EA0C +:1013600010278DECADEA0B01710B21A2FEFA1431AE +:101370001301090B01710B21A2FFFA070B01710B7D +:1013800021A200B0B0B0B6AFB1B3B589B8B189BAD7 +:10139000B189BCB189BEB1715AA63146AA06716A3B +:1013A000A69B45143106E30A3107AAF8716AA69B89 +:1013B0004514715AA6710BE3F4A5709A7916629ED2 +:1013C00067FC3107E331710BE3715AA6F4A54D4A6E +:1013D000BD148E67FC4D17BD0DA1009E71FC9A4295 +:1013E000159A0028FADC716AA6F4A570B18E67FC24 +:1013F000709A9E15B0FA4E3117AA3E8E67FC709A0D +:101400004216629E69FC3106E3093107AAF8716A47 +:10141000A6FA32710BE33146AA05716AA6FA268E46 +:1014200069FCF6A53106E3093107AAF8716AA6FA44 +:1014300014710BE3716AA6FA0C3107AA05716AA64A +:10144000FA039BC213B099BEB099BCB099BAB099D7 +:10145000B8B4B2B08F717BA6710AE7710BE3710B60 +:10146000EBF4265DFEF626D806FEF4265DFDF62694 +:10147000D806FD13A80813A90013A74A711AAB7167 +:101480000AAB714BA6713AA6712AA6710BE7717A65 +:10149000A6AF717BA6AFA1009E64FC717AA6716AAB +:1014A000A6AF1399ACAFB7A000B1A0829AEA11B071 +:1014B00062765D1C26265DFC72665D03616A9E6D28 +:1014C000FC665DE021259E6EFC9A42158E77FC72CB +:1014D000B7169EFCAAB69E6AFC70B1A003B1A082AA +:1014E0009A9112B0B0B6AF8E77FC41AD061477FC7E +:1014F0008541959A0815AF8E77FC4D00AD0614779F +:10150000FC8551959A0815AFB7A1044877FC9D0357 +:101510009E77FC8E77FC72B7169EFCAAB6768E6A12 +:10152000FC614EAD1B669E6AFCB7A003B1A0829A17 +:101530009112B0B02A853A85A1FA9E8CFC9E8EFC51 +:10154000B6AFB7A6008E71FC310F06A1066166FA30 +:1015500004A10261668E6EFC4D30AD353103003161 +:101560008E73FC310F04A14061668E73FC311F0441 +:10157000A12061668E73FC312F04A11061663123B6 +:101580000307712B212B01FA1331130004A19F6172 +:1015900056B7A001B1A0829A9112B0B0B6AFB7B160 +:1015A000891CD68730AE06D6A119614E9D039B3F9C +:1015B00016664D108D0BC6A100CA6CFCD46795FA57 +:1015C0007E664D088D584D0FAD4C4D0CAD3A4D0B10 +:1015D000AD2E4D0AAD204D09AD144D08BD61679E7D +:1015E00074FC67314E041B0CFA551A0CFA51679EB5 +:1015F00075FC7A84FA49675D1F9E76FC4A84FA3F3F +:10160000679E77FC5A84FA37679E78FC675D0151C4 +:10161000BD2D0A84FA29679E7BFC1A85FA21664D46 +:1016200005AD144D07AD0A4D04BD14679E70FCFA5C +:101630000E679E73FCFA08679E71FC6A840A85B087 +:10164000B6AFB7D6A100CA6CFCD4859E86FC664DA9 +:10165000FFAD1B4D06AD0B4D03BD18A1009E6FFCE9 +:10166000FA11BC030E1486FC856D8095FA05A15A0B +:101670009E86FC8E86FC72B6AFB7D6665DF09E87FE +:10168000FC665D0F9E88FCA1804887FC9D05A2FF3B +:101690009B4A178E87FC4D50BD05A2FF9B4A17A1A0 +:1016A000304887FC8D51A1104887FC8D238E87FC24 +:1016B0004D10BD0FA1024888FC8D3A410888FC728C +:1016C0009B4A17A1024888FC8D2B8E88FC72FA7AFF +:1016D0008E87FC4D20BD0FA1014888FC8D17A10607 +:1016E0000888FC72FA64A1014888FC8D5BA1080897 +:1016F00088FC72FA55FA51A1604887FC8D258E87C7 +:10170000FC4D60BD0FA1034888FC8D3CA10C0888EE +:10171000FC72FA36A1014888FC8D2DA10A0888FCCC +:1017200072FA278E87FC4D70BD0FA1074888FC8D8B +:1017300017A1100888FC72FA11A1014888FC8D08D5 +:10174000A1180888FC72FA02A2FFB6AFA001B1A0EE +:10175000509AEA11B062317E074A859A8A01FA02EC +:101760004B85AFB7B1B1891CD6C6CA0300B1A00181 +:101770009A9718B062BE01CC8539C6CA0200B1A0E2 +:10178000029A9718B0AE0249039D02BE03C6CA0270 +:1017900000B1A0039A9718B0AE0249039D02BE03A0 +:1017A000C6CA0200B1A0049A9718B0AE0249039DC0 +:1017B00002BE03AE014D00BD0CAE039E22FCA10192 +:1017C0009E79FCFA0AA1509E22FCA1E09E79FC8E33 +:1017D00022FC9E7AFCC6CA0300B1A0009A9718B0FA +:1017E00062BE014D00BD0DA10449038D07AE039EED +:1017F00077FCFA05A1039E77FCB0B0B6AFB7B1B1E4 +:10180000891CD6314385497B1E9A92149ADC0D9A25 +:101810007A0D0A02AE0830AE09B1AE02709A2619EE +:10182000B062BE014D00AD169AC6189AD218AE0825 +:1018300030AE09B1AE02709A2619B062BE010B0239 +:101840009A96149AD50D9A6C0D7A1EAE0172FA43CF +:10185000AE0251BD2814A4FC855D0395AE0830AEE0 +:1018600009D48570B1AE020D027014A4FC854195B7 +:10187000516100B1A0509A9112B0B0FA16AE083082 +:10188000AE09D48570B1AE020D0270B1A0509A912C +:1018900012B0B0B0B0B6AFB7B1891CD63143850E27 +:1018A000AE0630AE07B187709A1219B0FA15870DDF +:1018B0000270B1A0509AEA11B0AE0630AE07D46201 +:1018C00095A200B0B6AF314385059A3E19FA02A23F +:1018D00000AF314385059A3A19FA02A200AF3143AD +:1018E000850D7B1E9A92149ADC0D9A7A0D0A02AF2E +:1018F0003143850D0B029A96149AD50D9A6C0D7A88 +:101900001EAF314385059A4219FA02A2FFAF9A46EB +:1019100019AFB7B1891CD6AE0630AE07D4AE0030D1 +:101920009A6E1AB0B6AFB7B1891CD6AE0630AE0704 +:10193000D4AE00309AC21AB0B6AF9AA81BAF9ABD07 +:101940001DAF9A4B1EAFB7B5B19AC5214D00AD057D +:10195000A2F49B671A9A5822A1FF9EB4FCA1009E94 +:10196000B5FC9EBDFC8EB5FC9AE820D69AF6204DBB +:1019700000AD5B9A2F214DFFAD0F8EB4FC4DFFBD26 +:10198000088EB5FC9EB4FCFA459AEB1F9AFB1F4DDE +:1019900000AD039B531AA1019EBEFC8EB5FC728E56 +:1019A000ABFC308EACFC610A309A14204D00AD1BAC +:1019B0008EBEFC519EBEFCBDE2A1019EBDFC8EB55B +:1019C000FC9A9A1F4D00AD039B5A1A9AF31F9A581E +:1019D000228EB5FC4148AFFC9D059EB5FCFA868E73 +:1019E000B4FC4DFFBD62A1009EB5FC8EB5FC9AE82B +:1019F00020D69A68214D00BD41B702A8FCD6A1555A +:101A000097869786978697B69AEB1F9AFB1F4D008D +:101A1000BD41C6D48EABFCA3039A63204D00BD0527 +:101A20009AF31FFA238EB5FC9A9A1F4D00BD2B9A8C +:101A3000F31F9A5822A1019EBDFC8EB5FC4148AF10 +:101A4000FC9D229EB5FCFAA38EBDFC4D00BD12A2EA +:101A500000FA149AF31FA2FEFA0D9AF31FA2FDFAE0 +:101A600006A201FA02A2FB9A5822B0B4B6AFB7B5EB +:101A7000B1891CD69A4B224D00AD04A2F3FA3F9ACD +:101A8000921E4DFFAD363087309A4B1FEA0000ADF5 +:101A90002780D2AE0230AE03D4C2D6A2006248ADD7 +:101AA000FC9D078795868442FAF3665D034D03BD6E +:101AB00003948795A200FA06A2F7FA02A2FAB0B43C +:101AC000B6AFB7B5B1891CD69A4B224D00AD05A271 +:101AD000F39BA41B9A921E4DFFBD039B8F1B9EB4CC +:101AE000FC02A8FC3008B1FC302D00D4A1FF959475 +:101AF00095949594958772B702A8FCD66297B6AE76 +:101B00000230AE03D402A8FCD686A2008597868454 +:101B1000426248ADFC8DF502A8FC3008B1FC302DC6 +:101B200000DA0100D687A00030978630978EB4FC8B +:101B30009AE8203008B2FC3028B3FC03B8FCA101BD +:101B40009EBEFC8EB4FC9AFE1E03BAFC9AEB1F9A52 +:101B5000FB1F4D00BD3D02BAFC48B9FC8D07304863 +:101B6000B8FC9D3330D48EB1FC738EABFC9A6320ED +:101B70004D00AD2B4D1EAD098EBEFC51AD1D9EBE60 +:101B8000FCC43008B1FC302D008003BAFCFAC7A2B7 +:101B9000FAFA11A2FEFA0AA2F5FA06A2F6FA02A2CF +:101BA000009AF31FB0B4B6AFB7B5B19A58229A4BAA +:101BB000224D00AD05A2F39BB61DA1009EBDFC9A6F +:101BC000921E4DFFBD039B9F1D9EB4FC8EB4FC9ED8 +:101BD000B5FC9AE82003B6FC8EB5FC4148AFFC8DFD +:101BE00002A10048B4FCBD039BA71D9EB5FC9AE86A +:101BF0002003B8FCD69AF6204D00ADDC8EAAFC314D +:101C00000F509AEB1F9AFB1F4D00AD039BA31DA124 +:101C1000019EBEFC8EB5FC728EABFC308EACFC61BE +:101C20000A309A14204D00AD238EBEFC519EBEFC9E +:101C3000BDE28EB5FC9A9A1F4D00AD039BAF1DA16E +:101C4000019EBDFC9AF31F9A5822FA8C9AF31F9AB0 +:101C5000582202B8FCD69A68214D00AD039BD81BD0 +:101C600002B8FCCA080003BAFCA1009EBEFC8EAEFE +:101C7000FC41308EBEFC61488D039B311D308EB41B +:101C8000FC9A4B1FEA0000BD039B241DD602A8FC52 +:101C9000D4A200879586846248B1FC9D0342FAF382 +:101CA0009AEB1F9AFB1F4D00AD039BA31DA1019E44 +:101CB000BFFC02BAFCD43008B1FC302D005DFC70D2 +:101CC00094655DFC614884AD2602A8FCD6A15597B9 +:101CD00086978697869702B8FCCA0400D4A3038E21 +:101CE000ABFC9A63204D00BD719AF31F9BD81B8EED +:101CF000B1FC738EABFC9A63204D00AD184D1EAD48 +:101D0000098EBFFC519EBFFCAD50C43008B1FC3001 +:101D10002D0080FAA0C43008B1FC302D008003BA39 +:101D2000FC9AF31F8EBEFC419EBEFC9A58229B6E0D +:101D30001C9AEB1F9AFB1F4D00AD02FA6602A8FC2D +:101D4000D6A1559786978697869702B8FCD4A303A9 +:101D50008EABFC9A63204D00AD188EB5FC9A9A1F8D +:101D60004D00BD4B9A5822A1019EBDFC9AF31F9BCA +:101D7000D81B02B6FCCA0400D48EABFCA3039A6342 +:101D8000204D00AD0F8EB4FC9A9A1F4D00BD20A1CE +:101D9000019EBDFC8EBDFC4D00BD10A200FA14A238 +:101DA000FAFA13A2FEFA0CA2F8FA0BA201FA04A2A4 +:101DB000FDFA009AF31F9A5822B0B4B6AFB7B5B186 +:101DC0009A4B224D00AD04A2F3FA7C9A921E4DFF6D +:101DD000AD649EB4FC73634D00BD048EAFFC7353C1 +:101DE0008EB4FC614BAD57639AE820D69AF6204D2D +:101DF00000ADE3639EB5FC9AEB1F9AFB1F4D00BD3F +:101E000039A1019EBEFC8EB5FC728EABFC308EAC4F +:101E1000FC610A309A14204D00AD278EBEFC519E05 +:101E2000BEFCBDE28EB5FC9A9A1F4D00AD04A2FD2A +:101E3000FA12A2FCFA0EA2FAFA0DA2FEFA06A2F912 +:101E4000FA05A2009AF31FB0B4B6AFB7B5B19A4B7A +:101E5000224D00BD379A921E4DFFAD30729AE82098 +:101E6000D6629AFE1ED4C63008B2FC3028B3FC30CD +:101E7000611C30613DD6A0008EB1FC3080D4C6A27A +:101E80000030611C30613D8D0542FAF5A2FFB0B40F +:101E9000B6AFB7A6006648AFFC9D5F9AE82003C0C6 +:101EA000FC66A700674D089D167202C0FCB7D6AA53 +:101EB000B6726773B702A8FCD662BBB647FAE5B73D +:101EC00002A8FCD6AE0030AE01EA5555BD28868684 +:101ED000AE0030AE01EA5555BD1C8686AE0030AE70 +:101EE00001EAFFFFBD108686AE0030AE01EAFFFFBB +:101EF000BD04B666FA06B646FA9BA1FFB6AFB79A1E +:101F0000E820D43008B2FC3008B3FCD603C0FCC4CF +:101F1000CA0800D4C63018B1FC303D0090D6614DDF +:101F20008D24BD0530614C8D1DB58EB1FCA00030F7 +:101F300090D4C630610C30612DD485B44DFFBD0600 +:101F4000C603C0FCFACE02C0FCB6AFB73073309AFD +:101F5000E820D43008B2FC3008B3FCD6C4CA08006C +:101F6000D4C63018B1FC303D0090D6614D8D26BDF1 +:101F70000530614C8D1FB58EB1FCA0003090D4C6E9 +:101F800030610C30612DD485B44D00BDD487614BD8 +:101F9000BDCFC6FA03100000B6AFB79AE820D4024E +:101FA000A8FCD6A100BE00BE01BE02BE03A701A6CA +:101FB00001A3048EABFC9AA9204D00BD04A700FA32 +:101FC0000356BDEDC4CA0400D4A601A3048EABFC25 +:101FD0009AA9204D00BD04A700FA0356BDED674D38 +:101FE00000AD04A1FFFA02A100B6AF7B1E9A002D3E +:101FF0007A1EAF7B1E9A0D2D7A1EAFB3B502A6FCDA +:102000009A1A2D9A7B2E624D00AD04A1FFFA02A10F +:1020100000B4B2AFB7B3B5D69A5822C63072A10099 +:10202000A300B37B1E9AB52D7A1E62B24D1BBD1E56 +:102030009A5822C63072A100A300B37B1E9A2C2DA1 +:102040007A1E62B24D00ADD04D1FADCCFA084D00E6 +:10205000AD084D1FADC2A1FFFA02A1009A5822B4EB +:10206000B2B6AFB7B3B59EC4FCC403C2FC632424AC +:102070005D3F4172A3009A582202A8FCD6B7B31064 +:10208000C2FC7B1E9A8A2E7A1E62B2B64D00AD103B +:102090004D1FADD94D1EAD04A1FFFA06A11EFA02D7 +:1020A000A1009A5822B4B2B6AFB7B3B59EC4FCC46F +:1020B00003C2FC635124245D3F4172A3009A58225D +:1020C00002A8FCD6B7B310C2FC7B1E9A522D7A1E12 +:1020D00062B2B64D00AD084D1FADD8A1FFFAC3A145 +:1020E000009A5822B4B2B6AFB7728EACFC610AA0A7 +:1020F00000212727B6AFB7AE004D00BD12AE014D8F +:1021000000BD0CAE024D00BD06AE034D00AD1CAED1 +:10211000044D00BD12AE054D00BD0CAE064D00BD18 +:1021200006AE074D00AD04A1FFFA02A100B6AFB79D +:10213000AE004D55BD2EAE014D55BD28AE024D55DC +:10214000BD22AE034D55BD1CAE044DFFBD16AE0500 +:102150004DFFBD10AE064DFFBD0AAE074DFFBD04DD +:10216000A100FA02A1FFB6AFB7AE004DFFBD2EAE83 +:10217000014DFFBD28AE024DFFBD22AE034DFFBD98 +:102180001CAE044DFFBD16AE054DFFBD10AE064D95 +:10219000FFBD0AAE074DFFBD04A100FA02A1FFB6C4 +:1021A000AFD6AE054D069D1AAE064D399D14AE074D +:1021B0004D018D0E4DFF9D0AAE084DFE9D04A10000 +:1021C000FA02A1FFAFB110B4FCD6DAA6FCA10096CA +:1021D0009750BDFBB0D69AA1214DFFAD6DAE00303A +:1021E000AE0103A6FC8686AE0030AE0103A8FC86D5 +:1021F00086879EAAFC86879EABFC86879EACFCA148 +:10220000049EAFFC86879EADFC86879EAEFC8EAD9D +:10221000FC41A00030A204318240A1043188D49056 +:10222000309EB1FC100800A200D630610C30612D48 +:10223000EA01049D0342FAF1C603B2FC629EB0FCBF +:102240008EAAFC61FA9EAAFCA100AF8EAAFC317F87 +:1022500004A100FA02A1FFAFB18EAAFC311F04A1B4 +:10226000ACF699B0AFFFFFFFFFFFFFFFFFFFFFFFDF +:10280000B79A5C287A019A002D1020FE9A1A2D9A08 +:1028100087284252AD0A5A019A0D2D716AA6FAFE16 +:102820007B01A1009EA2FE7A019AC62862764D0025 +:10283000AD106A019A0D2D716AA6711BA013994AF9 +:10284000FAFE7B019A4F296276317F089A0D2D712D +:102850006AA6FAFE7B01FACFFAFEB6AF713AA6710C +:102860007B6C710B6C6B01717B69710B695B017126 +:102870007B6B710B6B7A01711AA07B1EFEE4FFFF6C +:10288000FEE6FFFF7A1EAFB7A6000A029A7B2E4231 +:1028900052AD04A281FA2DA700674D0AAD1F377013 +:1028A00037B1A0009AB52DB0624D1BBD0D37703702 +:1028B000B1A0009A2C2DB062616647FADC664D002B +:1028C000AD02A282B6AFB7B1B1891CD6710BE3716C +:1028D0005AA63106E3063106AA02FAF63107AA041F +:1028E000A201FA67F4A54D3ABDE29AD82962BE0367 +:1028F0009AD82962BE01A0003030B19AD829B030F0 +:10290000610A302D0003A0FE9AD82952BD04A2020C +:10291000FA39A100BE02AE0249039D149AD829AE2D +:102920000273B7621690FEBBB6AE0241BE02FAE673 +:102930009AD829AE024D109D1072B7A1FF1690FED5 +:10294000BAB6AE0241BE02FAEAA200B0B0B6AFB764 +:1029500002A0FEEA00288D04A202FA7A5A0116901B +:10296000FEB7A004B110A0FE9A522DB0B04252ADF5 +:1029700004A2C1FA616A0102A0FE5DFCA000242449 +:102980005D3F30B1709A8F2DB04252AD435B01165E +:1029900090FEB7A004B110A0FE9A522DB0B04252E2 +:1029A000AD04A2C2FA3002A0FE99B8EEBA0000EE61 +:1029B000BC00C0100F009A7501A10A9A5601F0B828 +:1029C00070B1A0009A8F2DB04252AD04A2C3FA0696 +:1029D0006B015B01A200B6AFB7710BE3715AA63170 +:1029E00006E302FAFAF4A5774D308D0CA139614F58 +:1029F0008D06671D3076FA20674D418D0CA15A6116 +:102A00004F8D06671D3776FA0F674D618D0AA17AE3 +:102A1000614F8D04671D577666262626265DF07663 +:102A2000710BE3715AA63106E302FAFAF4A5774D69 +:102A3000308D0DA139614F8D07671D306166FA2217 +:102A4000674D418D0DA15A614F8D07671D37616636 +:102A5000FA10674D618D0BA17A614F8D05671D5787 +:102A60006166367236B6AFFFFFFFFFFFFFFFFFFF65 +:102D000013C0A513C40113C4FE13C401AF13C0A59F +:102D100013C40013C4FF13C400AF22B161F8B6A2FC +:102D2000009A0081A109BE13BE1423AFB7D2891C3B +:102D3000D6AE0473629AC72EAD1122B161F8B0BE4F +:102D400003A2039A008123F0E3FA02A10572A30013 +:102D5000B6AFB7D4891CD6AE0473AE0630AE07D674 +:102D6000C49AE62EAD2222B1B3B761F8B0BE0560B9 +:102D7000BE04B0BE0360BE00B0BE0260BE01A204CD +:102D80009A008123F0E3FA02A10572A300B6AFB75F +:102D9000D2891CD6AE0473629AC72EAD1122B161DE +:102DA000F8B0BE03A2069A008123F0E3FA02A1055F +:102DB00072A300B6AFB7D2891CD6AE0473629AC7AD +:102DC0002EAD1122B161F8B0BE03A2089A00812392 +:102DD000F0E3FA02A10572A300B6AFB7D2891CD600 +:102DE000AE0430AE05E2D6C2D4AE004D05BD1870BB +:102DF000AE0273AE019AC72EAD153022B5B161F89F +:102E0000B030BE0060FA124D03AD084D04AD04A110 +:102E100005FA4722B5B161F8B0BE03B0BE0560BE89 +:102E200004A2099A0081234D05BD2D634D00AD28F4 +:102E3000324D208D234D309D1F62E4D6AE0170AE21 +:102E400002E4BE02A0002626262626273027E430EC +:102E5000611C30613D60BE01F0E372A300B6AF605B +:102E6000B12261F8891CCA0200BE0560BE04A20A34 +:102E70009A008123B0F0E372A300AF2261F8A20EA2 +:102E80009A008123F0E372A300AFB7D4891CD6AEB9 +:102E90000473AE0630AE07D6C49AE62EAD2222B138 +:102EA000B3B761F8B0BE0560BE04B0BE0360BE003B +:102EB000B0BE0260BE01A2179A008123F0E3FA02BD +:102EC000A10572A300B6AF334D208D174D309D1371 +:102ED00033724D069D0B26262626610B323332FABD +:102EE00002A1FF4DFFAFB7D6AE0070AE01EA008081 +:102EF0008D25EA00C09D20753072A000AE024D06FF +:102F00009D10262626262627302730610D302D00DD +:102F1000FA0910FFFFFA043072A100B6EAFFFFAF12 +:00000001FF diff --git a/Timer.c b/Timer.c new file mode 100644 index 0000000..ce5b7a8 --- /dev/null +++ b/Timer.c @@ -0,0 +1,141 @@ +#include "macrodriver.h" +#include "Timer.h" +/* Start user code for include definition. Do not edit comment generated here */ +/* End user code for include definition. Do not edit comment generated here */ +#include "user_define.h" + +/* Start user code for global definition. Do not edit comment generated here */ +/* + タイマーはイベントループを駆動するのと、 + TM51 : イベントループ用 + LEDのPWM制御に使ってます。 + TM50 : wifi LED + TMH0 : PowR + TMH1 : PowG +*/ + +/****************************************************************************** + イベントタイマ + ******************************************************************************/ +void TM51_Init(){ + TCE51 = 0; /* TM51 counter disable */ + TMMK51 = 1; /* INTTM51 interrupt disabled */ + TMIF51 = 0; /* clear interrupt flag */ +// TMPR51 = 1; /* set low priority level */ + + TCL51 = TM5_INTER_CLOCK_5; // 2^8 分周 = 31.25kHz + + /* TM51 interval mode */ + CR51 = TM51_COMPARE_VALUE; // 155 -> 4.975ms + TMC51 = TM5_TMC5_INITIALVALUE | TM5_OPT_MODE_OTHER | TM5_OUTPUT_FF_DISABLE; +} + +void TM51_Start(){ + TMMK51 = 0; /* INTTM51 interrupt enabled */ + TCE51 = 1; /* count operation start */ +} + +void TM51_Stop(){ + TCE51 = 0; /* TM51 counter disable */ + TMMK51 = 1; /* INTTM51 interrupt disabled */ + TMIF51 = 0; /* clear interrupt flag */ +} + + +/****************************************************************************** + TM00 使いません。 + CAM LED はソフトで点滅します。しくしく。 + ******************************************************************************/ + + +/****************************************************************************** + TM50 WiFi LED + Duty は CR50 (0(1/256) 〜 254(255/256)) + ******************************************************************************/ +void TM50_Init(){ + TCE50 = 0; /* TM50 counter disable */ + TMMK50 = 1; /* INTTM50 interrupt disabled */ + TMIF50 = 0; /* clear interrupt flag */ + + TCL50 = TM5_INTER_CLOCK_2; + + /* TM50 PWM output mode */ + /* Set TM50 output pin */ + PM1 &= 0x7F; + P1 &= 0x7F; + CR50 = TM50_COMPARE_VALUE; + TMC50 = TM5_TMC5_INITIALVALUE | TM5_OPT_MODE_PWM | TM5_OUTPUT_ACTIVE_HIGH; +} + +void TM50_Start(){ + TOE50 = 1; /* output enabled */ + TCE50 = 1; /* count operation start */ +} + +void TM50_Stop(){ + TCE50 = 0; /* TM50 counter disable */ + TOE50 = 0; /* output disabled */ +} + + +/****************************************************************************** + TMH0 POW 赤 + CMP0x との一致でピンをアクティブにして、カウンタをクリア + CMP1x との一致でピンをインアクティブにする。動作中に変更可能。 +  → アクティブHiにしておいて、CMP1xを動かせばよし + CMP00は255にしてある。CMP1xは0〜254 (範囲に注意!255禁止!) + ******************************************************************************/ +void TMH0_Init(void){ + TMHE0 = 0; /* stop TimerH0 */ + TMMKH0 = 1; /* INTTMH0 Interrupt servicing disabled */ + TMIFH0 = 0; /* clear interrupt request flag of INTTMH0 */ + + TMHMD0 = TMH_TMHMDn_INITIALVALUE | TMH_INTER_CLOCK_3 | TMH_PWM_MODE | TMH_OUTPUT_LVL_LOW; + CMP00 = TMH0_CMP0_VALUE; + CMP10 = TMH0_CMP1_VALUE; + + /* TMH0 pin setting */ + PM1 &= ~0x20; + P1 &= ~0x20; +} + +void TMH0_Start(void){ + CMP10 = TMH0_CMP1_VALUE; + TOEN0 = 1; /* enable output */ + TMHE0 = 1; /* start TimerH0 */ +} + +void TMH0_Stop(void){ + TMHE0 = 0; /* stop TimerH0 */ + TOEN0 = 0; /* disable output */ +} + + +/****************************************************************************** + TMH1 POW 緑 + ******************************************************************************/ +void TMH1_Init(void){ + TMHE1 = 0; /* stop TimerH1 */ + TMMKH1 = 1; /* INTTMH1 Interrupt servicing disabled */ + TMIFH1 = 0; /* clear interrupt request flag of INTTMH1 */ + + TMHMD1 = TMH_TMHMDn_INITIALVALUE | TMH_INTER_CLOCK_2 | TMH_PWM_MODE | TMH_OUTPUT_LVL_LOW; + CMP01 = TMH1_CMP0_VALUE; + CMP11 = TMH1_CMP1_VALUE; + + /* TMH1 pin setting */ + PM1 &= ~0x40; + P1 &= ~0x40; +} + +void TMH1_Start(void){ + CMP11 = TMH1_CMP1_VALUE; + TOEN1 = 1; /* enable output */ + TMHE1 = 1; /* start TimerH1 */ +} + +void TMH1_Stop(void){ + TMHE1 = 0; /* stop TimerH1 */ + TOEN1 = 0; /* disable output */ +} + diff --git a/Timer.h b/Timer.h new file mode 100644 index 0000000..347a201 --- /dev/null +++ b/Timer.h @@ -0,0 +1,246 @@ +/* +******************************************************************************* +** +** This device driver was created by Applilet2 for 78K0/Kx2 +** 8-Bit Single-Chip Microcontrollers +** +** Copyright(C) NEC Electronics Corporation 2002 - 2007 +** All rights reserved by NEC Electronics Corporation. +** +** This program should be used on your own responsibility. +** NEC Electronics Corporation assumes no responsibility for any losses +** incurred by customers or third parties arising from the use of this file. +** +** Filename : Timer.h +** Abstract : This file implements device driver for Timer module. +** APIlib : Applilet2 for 78K0/Kx2 V2.10 [6 Mar. 2007] +** +** Device : uPD78F0500_30 +** +** Compiler : CC78K0 +** +** Creation date: 2007/07/11 +** +******************************************************************************* +*/ +#ifndef _MDTIMER_ +#define _MDTIMER_ +/* +******************************************************************************* +** Register bit define +******************************************************************************* +*/ +/* + TM0n Mode Control Register(TMC0n) +*/ +/* Initial Value */ +#define TM0_TMC0_INITIALVALUE 0x00 +/* Operating mode and clear mode selection(TMC0n.TMC0n3 & TMC0n.TMC0n2) */ +#define TM0_OPERATE 0x0C /* for clear the bits */ +#define TM0_OPERATE_DISABLE 0x00 /* operation stop(TM0n cleared to 0) */ +#define TM0_OPERATE_FREERUNNING 0x04 /* free-running mode */ +#define TM0_CLEAR_BY_TI00_EDGE 0x08 /* clear & start occurs on TI00n pin valid edge */ +#define TM0_CLEAR_BY_MATCH_CR00 0x0C /* clear & start occurs on match between TM0n and CR00n */ +/* Condition to reverse timer output (TO0n) TMC0n.TMC0n1 */ +#define TM0_TO0n_MATCH_CR0n 0x00 /* match between TM0n and CR00n or match between TM0n and CR01n */ +#define TM0_TO0n_MATCH_CR0n_TI00 0x02 /* match between TM0n and CR00n or match between TM0n and CR01n or trigger input of TI00n pin valid edge */ +/* TM0n overflow detection(TMC0n.OVF0n) */ +#define TM0_OVERFLOW_FLAG 0x01 /* overflow detected */ + +/* + Capture/Compare Control Register(CRC0n) +*/ +/* Initial Value */ +#define TM0_CRC0_INITIALVALUE 0x00 +/* CR00n operating mode selection(CRC0n.CRC0n0) */ +#define TM0_CR00_MODE 0x01 +#define TM0_CR00_COMPARE 0x00 /* operates as compare register */ +#define TM0_CR00_CAPTURE 0x01 /* operates as capture register */ +/* CR01n operating mode selection(CRC0n.CRC0n2) */ +#define TM0_CR01_MODE 0x04 +#define TM0_CR01_COMPARE 0x00 /* operates as compare register */ +#define TM0_CR01_CAPTURE 0x04 /* operates as capture register */ +/* CR00n capture trigger selection(CRC0n.CRC0n1) */ +#define TM0_CR00_CAPTURE_MODE 0x02 +#define TM0_CR00_CAPTURE_TI01 0x00 /* captures on valid edge of TI01n pin */ +#define TM0_CR00_CAPTURE_TI00 0x02 /* captures on valid edge of TI00n pin by reverse phase */ + +/* + Prescaler Mode Register(PRM0n) +*/ +/* Initial Value */ +#define TM0_PRM0_INITIALVALUE 0x00 +/* Count clock selection(PRM0n.PRM0n1 & PRM0n.PRM0n0) */ +#define TM0_COUNT_CLOCK 0x03 /* for clear the bits */ +#define TM0_INTER_CLOCK_1 0x00 /* fprs */ +#define TM0_INTER_CLOCK_2 0x01 /* fprs/2^2 */ +#define TM0_INTER_CLOCK_3 0x02 /* fprs/2^8 */ +#define TM0_EXTER_CLOCK 0x03 /* TI00n valid edge */ +/* TI00n pin valid edge selection(PRM0n.ES0n1 & PRM0n.ES0n0) */ +#define TM0_TI00_VALID_EDGE 0x30 /* for clear the bits */ +#define TM0_TI00_VALID_EDGE_FALL 0x00 /* falling edge */ +#define TM0_TI00_VALID_EDGE_RISE 0x10 /* rising edge */ +#define TM0_TI00_VALID_EDGE_BOTH 0x30 /* both falling and rising edges */ +/* TI01n pin valid edge selection(PRM0n.ES1n1 & PRM0n.ES1n0) */ +#define TM0_TI01_VALID_EDGE 0xC0 /* for clear the bits */ +#define TM0_TI01_VALID_EDGE_FALL 0x00 /* falling edge */ +#define TM0_TI01_VALID_EDGE_RISE 0x40 /* rising edge */ +#define TM0_TI01_VALID_EDGE_BOTH 0xC0 /* both falling and rising edges */ + +/* + Timer Output Control Register(TOC0n) +*/ +/* Initial Value */ +#define TM0_TOC0_INITIALVALUE 0x00 +/* Timer output F/F status setting(TOC0n.LVSn1 & TOC0n.LVRn1) */ +#define TM0_OUTPUT_INIT_LEVEL_CLR 0x0C /* for clear the bits */ +#define TM0_OUTPUT_INIT_LEVEL_LOW 0x04 /* timer output F/F reset (0) */ +#define TM0_OUTPUT_INIT_LEVEL_HIGH 0x08 /* timer output F/F set (1) */ +/* Timer output F/F control using match of CR00n and TM0n(TOC0n.TOC0n1) */ +#define TM0_CR00_OUTPUT_FF_OFF_MODE 0x00 /* disables inversion operation */ +#define TM0_CR00_OUTPUT_FF_ON_MODE 0x02 /* enables inversion operation */ +/* Timer output F/F control using match of CR01n and TM0n(TOC0n.TOC0n4) */ +#define TM0_CR01_OUTPUT_FF_OFF_MODE 0x00 /* disables inversion operation */ +#define TM0_CR01_OUTPUT_FF_ON_MODE 0x10 /* enables inversion operation */ +/* One-shot pulse output trigger control via software(TOC0n.OSPT0n) */ +#define TM0_SOFTWARE_TRIGGER_OFF 0x00 /* no one-shot pulse output trigger */ +#define TM0_SOFTWARE_TRIGGER_ON 0x40 /* one-shot pulse output trigger */ +/* One-shot pulse output operation control(TOC0#n.OSPE0n) */ +#define TM0_SUCCESSIVE_MODE 0x00 /* successive pulse output mode */ +#define TM0_ONESHOT_MODE 0x20 /* one-shot pulse output mode */ +/* Timer output control(TOC0n.TOE0n) */ +#define TM0_OUTPUT_DISABLE_BIT 0x00 /* disables output (output fixed to level 0) */ +#define TM0_OUTPUT_ENABLE_BIT 0x01 /* enables output */ +/* + Timer Clock Selection Register 5n (TCL5n) +*/ +/* TM5 internal clock selection(TCL5n) */ +#define TM5_INTER_CLOCK_1 0x02 /* internal clock = fpsr */ +#define TM5_INTER_CLOCK_2 0x03 /* internal clock = fpsr/2 */ +#define TM5_INTER_CLOCK_3 0x04 /* when n=0, internal clock = fpsr/2^2; when n=1, internal clock = fpsr/2^4 */ +#define TM5_INTER_CLOCK_4 0x05 /* internal clock = fpsr/2^6 */ +#define TM5_INTER_CLOCK_5 0x06 /* interna clock = fpsr/2^8 */ +#define TM5_INTER_CLOCK_6 0x07 /* when n=0, internal clock = fpsr/2^13; when n=1, internal clock = fpsr/2^12 */ + +/* TM5 external clock selection(TCL5n) */ +#define TM5_EXTER_CLOCK_FALLING 0x00 /* TI5n pin falling edge */ +#define TM5_EXTER_CLOCK_RISING 0x01 /* TI5n pin rising edge */ + +/* TM5 count edge selection(in external event counter)(TCL5n) */ +#define TM5_COUNT_EDGE_FALLING 0x00 /* TI5n pin falling edge */ +#define TM5_COUNT_EDGE_RISING 0x01 /* TI5n pin rising edge */ + +/* + Timer Mode Control Register 5n (TMC5n) +*/ +#define TM5_TMC5_INITIALVALUE 0x00 +/* TM5 operating mode selection (TMC5n.TMC5n6)*/ +#define TM5_OPT_MODE_OTHER 0x00 /* mode in which clear & start occurs on a match between TM5n and CR5n */ +#define TM5_OPT_MODE_PWM 0x40 /* PWM (free-running) mode */ + +/* TM5 F/F control (in other than PWM mode)(TMC5n.TMC5n1)*/ +#define TM5_OUTPUT_FF_ENABLE 0x02 /* inversion operation enabled */ +#define TM5_OUTPUT_FF_DISABLE 0x00 /* inversion operation disabled */ + +/* TM5 active level selection (in PWM mode)(TMC5n.TMC5n1) */ +#define TM5_OUTPUT_ACTIVE_HIGH 0x00 /* active-high */ +#define TM5_OUTPUT_ACTIVE_LOW 0x02 /* active-low */ + +/* TM5 output F/F status setting (in other than PWM mode) (TMC5n.LVS5n & TMC5n.LVR5n) */ +#define TM5_OUTPUT_INIT_CLR 0x0C /* for clear bits */ +#define TM5_OUTPUT_INIT_HIGH 0x08 /* TM5 output F/F set (1) */ +#define TM5_OUTPUT_INIT_LOW 0x04 /* TM5 output F/F clear (0) */ + +/* TM5 output control (TMC5n.TOE5n) */ +#define TM5_OUTPUT_ENABLE_BIT 0x01 /* output enabled */ +#define TM5_OUTPUT_DISABLE_BIT 0x00 /* output disabled (TM5n output is low level) */ + +/* TM5 count operation control (TMC5n.TCE5n) */ +#define TM5_COUNTER_ENABLE_BIT 0x80 /* count operation start */ +#define TM5_COUNTER_DISABLE_BIT 0x00 /* after clearing to 0, count operation disabled (counter stopped) */ +/* + 8-bit timer H mode register n (TMHMDn) +*/ +#define TMH_TMHMDn_INITIALVALUE 0x00 /* TMHMDn initial value */ +/* Count clock selection(TMHMDn.CKSn2~CKSn0) */ +#define TMH_INTER_CLOCK_1 0x00 /* TMH0: fPRS, TMH1: fPRS */ +#define TMH_INTER_CLOCK_2 0x10 /* TMH0: fPRS/2, TMH1: fPRS/2^2 */ +#define TMH_INTER_CLOCK_3 0x20 /* TMH0: fPRS/2^2, TMH1: fPRS/2^4 */ +#define TMH_INTER_CLOCK_4 0x30 /* TMH0: fPRS/2^6, TMH1: fPRS/2^6 */ +#define TMH_INTER_CLOCK_5 0x40 /* TMH0: fPRS/2^10, TMH1: fPRS/2^12 */ +#define TMH_INTER_CLOCK_6 0x50 /* TMH0: TM50 output, TMH1: fRL/2^7 */ +#define TMH_INTER_CLOCK_7 0x60 /* TMH1: fRL/2^9 */ +#define TMH_INTER_CLOCK_8 0x70 /* TMH1: fRL */ + +/* Timer operation mode(TMHMD#n.TMMDn1~TMMDn0) */ +#define TMH_INTERVAL_SQUARE_MODE 0x00 /* interval/square-wave timer mode */ +#define TMH_PWM_MODE 0x08 /* PWM output mode */ +#define TMH1_CARRIER_MODE 0x04 /* Carrier generator mode */ + +/* Timer output level control (in default mode)(TMHMD#n.TOLEVn) */ +#define TMH_OUTPUT_LVL_LOW 0x00 /* low level */ +#define TMH_OUTPUT_LVL_HIGH 0x02 /* high level */ + +/* + 8-bit timer H carrier control register 1 (TMCYC1) +*/ +/* Remote control output in carrier mode(TMCYC1.RMC1 & NRZB1) */ +#define TMH_REMOTE_LOW_LEVEL 0x00 /* low-level output */ +#define TMH_REMOTE_HIGH_LEVEL 0x02 /* high-level output */ +#define TMH_REMOTE_CARRIER 0x06 /* carrier pulse output */ + +/* Carrier pulse output status flag(TMCYC1.NRZ1) */ +#define TMH1_CARRIER_OUTPUT_DISABLE 0x00 /* Carrier output disabled status (low-level status) */ + + +/* +******************************************************************************* +** Macro define +******************************************************************************* +*/ +/* 8-bit timer compare register 50 (CR50)*/ +#define TM50_COMPARE_VALUE 0x7F +/* 8-bit timer compare register 51 (CR51)*/ +#define TM51_COMPARE_VALUE 155 +/* 8-bit timer compare register H0 (CMP00)*/ +#define TMH0_CMP0_VALUE 0xFF +/* 8-bit timer compare register H0 (CMP10)*/ +#define TMH0_CMP1_VALUE 0x0 +/* 8-bit timer compare register H1 (CMP01)*/ +#define TMH1_CMP0_VALUE 0xFF +/* 8-bit timer compare regiser H1 (CMP11)*/ +#define TMH1_CMP1_VALUE 0x0 +enum TMChannel { TMCHANNEL0, TMCHANNEL1 }; + +/* +******************************************************************************* +** Function define +******************************************************************************* +*/ +void TM50_Init(void); +void TM50_Start(void); +void TM50_Stop(void); +void TM50_ChangeDuty(UCHAR ratio); + +void TM51_Init(void); +void TM51_Start(void); +void TM51_Stop(void); +void TM51_ChangeTimerCondition(UCHAR value); + +void TMH0_Init(void); +void TMH0_Start(void); +void TMH0_Stop(void); +MD_STATUS TMH0_ChangeTimerCondition(UCHAR* array_reg, UCHAR array_num); +void TMH0_ChangeDuty(UCHAR ratio); +void TMH1_Init(void); +void TMH1_Start(void); +void TMH1_Stop(void); +MD_STATUS TMH1_ChangeTimerCondition(UCHAR* array_reg, UCHAR array_num); +void TMH1_ChangeDuty(UCHAR ratio); + +/* Start user code for definition. Do not edit comment generated here */ +void TM00_Init(); +void TM00_Start(); +void TM00_Stop(); +/* End user code for definition. Do not edit comment generated here */ +#endif diff --git a/Timer_user.c b/Timer_user.c new file mode 100644 index 0000000..872e407 --- /dev/null +++ b/Timer_user.c @@ -0,0 +1,17 @@ +#pragma interrupt INTTM51 MD_INTTM51 + + +#include "macrodriver.h" +#include "Timer.h" +#include "user_define.h" + +extern bit flg_interval; + + +/* + イベントフラグを立てる だけ +*/ +__interrupt void MD_INTTM51( void ){ + flg_interval = 1; +} + diff --git a/WDT.c b/WDT.c new file mode 100644 index 0000000..fe0609c --- /dev/null +++ b/WDT.c @@ -0,0 +1,9 @@ +#include "macrodriver.h" +#include "WDT.h" + +#include "user_define.h" + +void WDT_Restart( void ){ + WDTE = 0xAC; /* restart watch dog timer */ +} + diff --git a/WDT.h b/WDT.h new file mode 100644 index 0000000..95c6b96 --- /dev/null +++ b/WDT.h @@ -0,0 +1,8 @@ +#ifndef _MDT_ +#define _MDT_ + +#define mcu_reset WDTE = 0x5A + +void WDT_Restart(void); + +#endif diff --git a/callback_funcs.c b/callback_funcs.c new file mode 100644 index 0000000..84e5f8a --- /dev/null +++ b/callback_funcs.c @@ -0,0 +1,30 @@ +#include "incs.h" // jhl いやな実装だなぁ。慣れてないししょうがないかなぁ。 + + +extern mcu_mode_ mcu_mode; +extern unsigned char vregs[]; +extern unsigned char vregs_changed[]; + +extern unsigned char tsk_interval_power_led; +extern unsigned char tsk_interval_sw_vol; +extern unsigned char tsk_interval_led_cam; +extern unsigned char tsk_interval_wifi_led; + + +/****************************************************************************** + コールバック?関数たち + シリアル受信後、関係するビットに変化があると呼ばれる。 +  (同値書き込みでは呼ばれない) + ******************************************************************************/ +void call_clr_reset_rq(){ // registor_changed[0] & 0x01 + vregs_changed[REG_INT_ADRS_IRQ] &= ~0x01; // 変化フラグを消す + if( ( vregs[REG_INT_ADRS_IRQ] & 0x01 ) == 0 ){ + n_irq_ngt; + } +} + + +void call_vol(){ // registor_changed[3] & 0x3F != 0 + vregs_changed[REG_INT_ADRS_VOL] &= ~0x1F; + dcp_set_vol(); +} diff --git a/callback_funcs.h b/callback_funcs.h new file mode 100644 index 0000000..439ebe4 --- /dev/null +++ b/callback_funcs.h @@ -0,0 +1,12 @@ +/* + 内部仮想レジスタの無いように変更があったときに呼ぶ + */ +#ifndef __callback_funcs_ +#define __callback_funcs_ +void call_clr_reset_rq(); // registor_changed[0] & 0x01 +void call_sys_mode(); // registor_changed[1] & 0xC0 +void call_wifi_led(); // registor_changed[1] & 0x01 != 0 +void call_cam_led(); // registor_changed[2] != 0 +void call_vol(); // registor_changed[3] & 0x3F != 0 +void call_card_lock(); +#endif diff --git a/config.h b/config.h new file mode 100644 index 0000000..610903f --- /dev/null +++ b/config.h @@ -0,0 +1,20 @@ +#ifndef __config__ +#define __config__ + + +//#define debug_codes +//#define wifi_led_on_func // funcキーでwifiLEDを点滅有 + +//#define debug_saito_special + +//#define iic_debug_msg + +#define enable_swi2c_wait + +#define after_x6 + +//#define wifi_led_blink_always_on +//#define wifi_led_blink_default_on + + +#endif diff --git a/demo.c b/demo.c new file mode 100644 index 0000000..20530e7 --- /dev/null +++ b/demo.c @@ -0,0 +1,117 @@ +#include "macrodriver.h" +#include "System.h" +#include "Port.h" +#include "Timer.h" +#include "SW_I2C.h" // jhl +#include "user_define.h" // jhl +#include "demo.h" // jhl + +/****************************************************************************** + デバッグがさびしいので、デモ。 + ******************************************************************************/ +void demos(){ +// demo_pwr_led_0_inv_dim(); +// demo_dcp_0_trig(); // こいつは1ms位掛かる +} + +#if 0 +/****************************************************************************** + DCP 三角波を出し続けるデモ + ******************************************************************************/ +static void demo_dcp_0_trig(){ + static unsigned char i,j; + static char direction = 0; + if( ++i == 100 ){ + i = 0; + if( direction == 0 ){ + if( dcp_inc_vol() != 0 ){ + direction = 1; + } + }else{ + if( dcp_dec_vol() != 0 ){ + direction = 0; + } + } + } +} +#endif + + +/****************************************************************************** + 動作確認用LEDデモ + ******************************************************************************/ +static void demo_pwr_led_0_inv_dim(){ + static unsigned char i,j; + if( i++ == 9 ){ + i = 0; + if( ++j == 100 ){ + j = 0; + } +// TMH0_ChangeDuty( j ); +// TMH1_ChangeDuty( 100 - j ); + } +} + + + +/***************************************************************************** + デバッグタスク + フラッシュ耐久試験など + 意味なかった + ****************************************************************************/ +void tsk_eep_test(){ +#ifdef _eep_test_ + static u8 flash_status[17]; + static u8 count_H = 0; + static u8 count_M = 0; + static u8 count_L = 0; + static u8 count_BC_H = 0; + static u8 count_BC_L = 0; + + flash_enable(); + flash_status[ 15 ] = flash_write( DAT_BL_BRIGHT, &count_L ); + if( flash_status[ 15 ] == 0x00 ){ // 正常書き込み正常終了 + if( ++count_L == 100 ){ + count_L = 0; + if( ++count_M == 100 ){ + count_M = 0; + if( ++count_H == 100 ){ + count_H = 0; + } + } + } + } + if( ( flash_status[15] == 0xF5 ) // ブロックデータフル + || ( flash_status[15] == 0xF6 ) // 書き込みエラー + || ( flash_status[15] == 0xFA ) ){ // 有効ブロックなし + flash_status[6] = flash_erase(); + flash_status[14] = flash_block_change(); + if( flash_status[14] == 0 ){ + if( ++count_BC_L == 100 ){ + count_BC_L = 0; + ++count_BC_H; + } + flash_status[7] = count_BC_H; + flash_status[8] = count_BC_L; + }else{ + flash_status[5] = flash_status[14]; + } + } + flash_disable(); + + if( ( flash_status[15] != 0x00 ) + && ( flash_status[15] != 0xF5 ) ){ + flash_status[4] = flash_status[15]; + } + + flash_status[ 0 ] = count_H; + flash_status[ 1 ] = count_M; + flash_status[ 2 ] = count_L; + + flash_status[ 3 ] = self_free_space(); + + flash_status[ 9 ] = 0; + + iic2m_write_nmem( IIC_SLV_ADDR_MONITOR, 0x5A, flash_status, 9 ); +#endif +} diff --git a/demo.h b/demo.h new file mode 100644 index 0000000..79f8788 --- /dev/null +++ b/demo.h @@ -0,0 +1,7 @@ +#ifndef __demo_h__ +#define __demo_h__ + +void demos(); +//static void demo_dcp_0_trig(); +static void demo_pwr_led_0_inv_dim(); +#endif diff --git a/flash.c b/flash.c new file mode 100644 index 0000000..a67e278 --- /dev/null +++ b/flash.c @@ -0,0 +1,182 @@ +#include "incs.h" +#include "eeelib.h" +#include "eepe.h" + + + +extern u8 vregs[]; +extern u8 adc_comp_val; + +bit EEPemu; + + + +/***************************************************************************** +  + ****************************************************************************/ +void flash_init(){ + if( ( iic2m_read_byte( IIC_SLV_ADDR_DCP, 1 ) & 0x80 ) == 0 ){ // == isl95810 +// if( ( iic2m_read_byte( IIC_SLV_ADDR_DCP, 1 ) & 0x80 ) != 0 ){ // == isl95811 + EEPemu = 1; + eepe_init(); + }else{ + EEPemu = 0; + } +} + + + +/***************************************************************************** +  + ****************************************************************************/ +void restore_params(){ + u8 temp,temp2; + u8 eep_status; + + // ADC補正パラメータ復帰 // + eep_status = flash_read( DAT_ADC_COMP, &temp ); + if( EEPemu == 0 ){ + // ISL95811で、書き込みに失敗してたら確実に 0xFF なのだそうだ + flash_read( DAT_ADC_COMP + 1 , &temp2 ); + if( temp2 < temp ){ temp = temp2; } + flash_read( DAT_ADC_COMP + 2 , &temp2 ); + if( temp2 < temp ){ temp = temp2; } + flash_read( DAT_ADC_COMP + 3 , &temp2 ); + if( temp2 < temp ){ temp = temp2; } + } + if( eep_status == EEE_NORMAL ){ + adc_comp_val = temp; + vregs[ REG_INT_ADRS_ADC_CALIB_STATUS ] = 1; + }else{ // 何かエラー + adc_comp_val = 0x50; // 512にこれを足す。余裕を持って 3.40V とする + vregs[ REG_INT_ADRS_ADC_CALIB_STATUS ] = 0xE0; + } + vregs[ REG_INT_ADRS_ADC_CALIB_VALUE ] = adc_comp_val; + DBG_IIC_REG_TMP1( adc_comp_val ); + + // バックライト輝度復帰 // + eep_status = flash_read( DAT_BL_BRIGHT, &temp ); + if( ( eep_status == EEE_NORMAL ) && + ( temp <= BL_IND_MAX ) ){ + vregs[ REG_INT_ADRS_BL ] = temp; + }else{ + vregs[ REG_INT_ADRS_BL ] = 3; // TWL初期値 + } +// rsv_set_BL = 1; // 不要。/resetの解除を待って、pmic_init()が書く。 +} + + +/***************************************************************************** + 内部で使用 + ****************************************************************************/ + +// 内部で一度だけリトライを行います。 +// だめだったらエラーを返します。 +// 返り値:エラーコード +u8 flash_write( u8 adrs, u8* dat ){ + static u8 EEPe_counter = 0; + u8 status; + + if( EEPemu == 1 ){ // 内部フラッシュでEEPROMエミュレーション + + // 前処理 + DI(); + IIC0_Stop(); + TM51_Stop(); + ADC_Stop(); + flash_we = 1; + + status = ucEEPROMWriteEx_A( adrs, dat ); + if( status != 0x00 ){ // 一回だけリトライ + flash_erase(); + flash_block_change(); + status = ucEEPROMWriteEx_A( adrs, dat ); + } + + // 後処理 + flash_we = 0; + IIC0_SlaveReceiveStart(); + TM51_Start(); + ADC_Start(); + EI(); + return( status ); // 書き込み失敗とか + }else{ + // 95811向け。ノーチェックなのですが。 + if( adrs == DAT_ADC_COMP ){ + EEPe_counter &= 0x03; + return( iic2m_write_data( IIC_SLV_ADDR_DCP, adrs + 2 + EEPe_counter++, *dat ) ); // nakとか。 + }else{ + return( iic2m_write_data( IIC_SLV_ADDR_DCP, adrs + 2, *dat ) ); + } + } +} + + +// 返り値:エラーコード +u8 flash_read( u8 adrs, u8* dat ){ + if( EEPemu == 1 ){ // 内部フラッシュでEEPROMエミュレーション + return( ucEEPROMReadEx_A( adrs, dat ) ); + }else{ + // 95811向け。ノーチェック + *dat = iic2m_read_byte( IIC_SLV_ADDR_DCP, adrs + 2 ); + return 0; + } +} + + +// 返り値:エラーコード +u8 flash_erase(){ + if( EEPemu == 1 ){ // 内部フラッシュでEEPROMエミュレーション + return( ucEEPROMEraseEx_A() ); + }else{ + return( 0 ); + // nothing to do + } +} + + +// 返り値:エラーコード +u8 flash_block_change(){ + if( EEPemu == 1 ){ // 内部フラッシュでEEPROMエミュレーション + return( ucEEPROMChangeEx_A() ); + }else{ + // nothing to do + return 0; + } +} + + +void flash_enable(){ + if( EEPemu == 1 ){ // 内部フラッシュでEEPROMエミュレーション + DI(); + IIC0_Stop(); + TM51_Stop(); + ADC_Stop(); + flash_we = 1; + }else{ + // nothing to do + } +} + + +void flash_disable(){ + if( EEPemu == 1 ){ // 内部フラッシュでEEPROMエミュレーション + flash_we = 0; + IIC0_SlaveReceiveStart(); + TM51_Start(); + ADC_Start(); + EI(); + }else{ + // nothing to do + } +} + + +// 未使用 +u8 self_free_space(){ + if( EEPemu == 1 ){ // 内部フラッシュでEEPROMエミュレーション + return( ucEEPROMGetRemainEx_A() ); + }else{ + return( 0xFF ); + } +} diff --git a/flash.h b/flash.h new file mode 100644 index 0000000..5493cf6 --- /dev/null +++ b/flash.h @@ -0,0 +1,23 @@ +#ifndef __flash_h__ +#define __flash_h__ + +u8 flash_write( u8 adrs, u8* dat ); +u8 flash_erase(); +u8 flash_read( u8 adrs, u8* dat ); +u8 flash_read( u8 adrs, u8* dat ); +u8 flash_block_change(); +void flash_enable(); +void flash_disable(); + +void flash_init(); +void restore_params(); + +void self_flash_write_enable(); +void self_flash_write_protect(); +void dummy_func_void(); +u8 dummy_func_ret0(); + +u8 self_free_space(); + + +#endif diff --git a/incs.h b/incs.h new file mode 100644 index 0000000..680c8e8 --- /dev/null +++ b/incs.h @@ -0,0 +1,30 @@ +#ifndef _incs_h_ +#define _incs_h_ + +#include "macrodriver.h" + +#include "jhl_defs.h" + +#include "System.h" +#include "Port.h" +#include "WDT.h" +#include "vreg.h" + +#include "Timer.h" +#include "I2C.h" + +#include "user_define.h" +#include "config.h" + +#include "flash.h" +#include "SW_I2C.h" +#include "DCP.h" +#include "PMIC_TWL2.h" +#include "ADC.h" +#include "LEDs.h" + +#ifdef debug_codes +#include "debug.h" +#endif + +#endif diff --git a/jhl_defs.h b/jhl_defs.h new file mode 100644 index 0000000..c2b370b --- /dev/null +++ b/jhl_defs.h @@ -0,0 +1,20 @@ +#ifndef __jhl_defs_h__ +#define __jhl_defs_h__ + +typedef unsigned char u8; +typedef char s8; +typedef unsigned short u16; +typedef short s16; + + + +#ifdef __dbg__ +#define debug_led_on P2.2 = 1; +#define debug_led_off P2.2 = 0; +#else // 何かもっといい方法があるんじゃないかなぁ。 +#define debug_led_on ; +#define debug_led_off ; +#endif + + +#endif diff --git a/lk.dr b/lk.dr new file mode 100644 index 0000000..c206a72 --- /dev/null +++ b/lk.dr @@ -0,0 +1,30 @@ +; 変えたら死 + + +;本物ファームが使う +;0x0000 - 0x27FF ファーム +;0x2800 - 0x2FFF 自己書き換えコード +;0x3000 - 0x3FFF EEPROM領域 + +;p1 +;0x0000 - 0x17FF ブートなど +;0x1800 - 0x1FFF 自己書き換えコード +;0x2000 - 0x2FFF ブートなどの続き +;0x3000 - 0x3FFF EEPROM領域 + +;p2 +;0x0000 - 0x17FF ブートなど +;0x1800 - 0x1FFF 使用禁止(自己書き換えコードのため予約) +;0x2800 - 0x2FFF 新自己書き換えコード +;0x3000 - 0x3FFF EEPROM領域 + + + +MERGE c_flash : AT ( 2800H ) SEQUENT +MERGE SELF_PRG : AT ( 2D00H ) SEQUENT +;ここに書いてはだめみたい。 +;MERGE c_f_bits : AT ( FE88H ) SEQUENT + + + +; 3000H - 3FFFH が、EEPROMエミュレーションのデータ領域です diff --git a/macrodriver.h b/macrodriver.h new file mode 100644 index 0000000..0dbf270 --- /dev/null +++ b/macrodriver.h @@ -0,0 +1,69 @@ +#ifndef _MDSTATUS_ +#define _MDSTATUS_ + +#pragma sfr +#pragma DI +#pragma EI +#pragma NOP +#pragma HALT +#pragma STOP + + +typedef unsigned long ULONG; +typedef unsigned int UINT; +typedef unsigned short USHORT; +typedef unsigned char UCHAR; +typedef unsigned char BOOL; + + +#define ON 1 +#define OFF 0 + +#define TRUE 1 +#define FALSE 0 + +#define IDLE 0 /* idle status */ +#define READ 1 /* read mode */ +#define WRITE 2 /* write mode */ + +#define SET 1 +#define CLEAR 0 + +#define MD_STATUS unsigned short +#define MD_STATUSBASE 0x0 + +/* status list definition */ +#define MD_OK MD_STATUSBASE+0x0 /* register setting OK */ +#define MD_RESET MD_STATUSBASE+0x1 /* reset input */ +#define MD_SENDCOMPLETE MD_STATUSBASE+0x2 /* send data complete */ +#define MD_OVF MD_STATUSBASE+0x3 /* timer count overflow */ + +/* error list definition */ +#define MD_ERRORBASE 0x80 +#define MD_ERROR MD_ERRORBASE+0x0 /* error */ +#define MD_RESOURCEERROR MD_ERRORBASE+0x1 /* no resource available */ +#define MD_PARITYERROR MD_ERRORBASE+0x2 /* UARTn parity error */ +#define MD_OVERRUNERROR MD_ERRORBASE+0x3 /* UARTn overrun error */ +#define MD_FRAMEERROR MD_ERRORBASE+0x4 /* UARTn frame error */ +#define MD_ARGERROR MD_ERRORBASE+0x5 /* Error agrument input error */ +#define MD_TIMINGERROR MD_ERRORBASE+0x6 /* Error timing operation error */ +#define MD_SETPROHIBITED MD_ERRORBASE+0x7 /* setting prohibited */ +#define MD_DATAEXISTS MD_ERRORBASE+0x8 /* Data to be transferred next exists in TXBn register */ +#define MD_SPT MD_STATUSBASE+0x8 /*IIC stop*/ +#define MD_NACK MD_STATUSBASE+0x9 /*IIC no ACK*/ +#define MD_SLAVE_SEND_END MD_STATUSBASE+0x10 /*IIC slave send end*/ +#define MD_SLAVE_RCV_END MD_STATUSBASE+0x11 /*IIC slave receive end*/ +#define MD_MASTER_SEND_END MD_STATUSBASE+0x12 /*IIC master send end*/ +#define MD_MASTER_RCV_END MD_STATUSBASE+0x13 /*IIC master receive end*/ +#define MD_BUSY MD_STATUSBASE+0x14 /*IIC is busy*/ + +/* the value for IMS and IXS */ +//#define MEMORY_IMS_SET 0x42 // 0500A +#define MEMORY_IMS_SET 0x04 // 0501A + +/* +******************************************************************************* +** Function define +******************************************************************************* +*/ +#endif diff --git a/main.c b/main.c new file mode 100644 index 0000000..792a07e --- /dev/null +++ b/main.c @@ -0,0 +1,528 @@ +/***************************************************************************** + TWL マイコン + de JHL 藤田@開技 + nintendo + '07 Jun., '07 Dec. + +仕事 + *ボリューム + *リセット + *カメラ LED + *電源 LED + *WiFi LED + *CPUとのI2C通信 +******************************************************************************/ +#include "incs.h" + + +void reg_init(); + +void running_immediately(); +void running(); +void tsk_sw_vol(); // tsk_〜 …イベントループで呼ばれる +void tsk_sw_pow(); +void tsk_command_exec(); +void wait_for_system_boot(); + +void save_BL_param(); + + + +//***************************************************************************** +// タスクのインターバル用カウンタ、初期位相 インターバルはいくつにしよう? (1単位5ms) +u8 tsk_interval_cnt_adc = 0, tsk_interval_adc = 200/25; // 200/x で x[Hz] +u8 tsk_interval_cnt_power_led = 0, tsk_interval_power_led; +u8 tsk_interval_cnt_sw_vol = 0, tsk_interval_sw_vol; +u8 tsk_interval_cnt_wifi_led = 0, tsk_interval_wifi_led = 10; +u8 tsk_interval_cnt_cam_led = 0, tsk_interval_cam_led = 160; // T = 0.8s + +bit adc_calib_mode; +bit flg_interval; +bit system_inited; +bit vol_mute_start; + +bit rsv_set_vol; +bit rsv_set_BL; +bit rsv_set_PMIC_VRSET; +bit rsv_set_camLED; +bit rsv_set_batt_th; +bit rsv_set_powLED; + +extern bit eeprom_bl_dirty; + +extern u8 battLvl; + +extern u8 vregs[]; + +sleep_status_ sleep_status = Wake; + +static u8 pwsw_state = 3; // スイッチ無視のためのもの。グローバルでないと困る + +extern u8 wifi_tx; // WifiLED の点滅ステート + +//############################################################################ + +//***************************************************************************** +void main( void ){ + // hdwinit( void ); // ←はmain()の前に自動で呼ばれています。 + TM51_Start(); // イベントタイマ 標準で5ms間隔 + + // 電池残量少で電源入れた時のため // + battLvl = 5; + vregs[ REG_INT_ADRS_BATT_INFO ] = BATT_CO; + vregs[ REG_INT_ADRS_MODE ] = 0x20; + set_batt_th(); + + // メインループ // + while( 1 ){ + WDT_Restart(); + + running_immediately(); // インターバルタイマ外。割り込みなど起動 // + // ↓インターバルタイマ内 + if( flg_interval ){ // 5ms間隔で呼ばれます。他の割り込みでまわさないため。 + flg_interval = 0; + + if( !system_inited ){ + wait_for_system_boot(); + // 電池残量 … リセット解除まではHiZ // + +#ifdef debug_codes + dbg_keyCheck(); +#endif + }else{ + if( adc_calib_mode != 0 ){ // ADC補正モード? + tsk_adc_calib(); // T=4msに書き換えてしまいます。 + }else{ + // 通常運転 // +#ifdef debug_codes + pow_led_demo(); +#endif + running(); + } + } + } + HALT(); + } +} + + + +/****************************************************************************** + インターバルを置いて毎周呼ばれるタスク + ******************************************************************************/ +void running(){ + static u8 mcu_mode_in_wake; + + // 電源スイッチ・リセット線管理 + tsk_sw_pow(); + tsk_command_exec(); + + // スリープ/復帰の遷移時などにしなくてはいけないこと // + if( ( PM_SLP == 0 ) && ( sleep_status != Wake ) ){ + // sleepからwakeに遷移したところ。 + sleep_status = Wake; + vregs[ REG_INT_ADRS_MODE ] = mcu_mode_in_wake; // 復帰。きれいに書きたい + PM_set_VRSET(); // twpwswと、sleep中の省電力設定 + set_camled(); // カメラLED復帰 +// trig_to_wake_wifiLed(); + + }else if( ( PM_SLP != 0 ) && ( sleep_status != Sleep ) ){ + // wakeからsleepに + sleep_status = Sleep; + mcu_mode_in_wake = vregs[ REG_INT_ADRS_MODE ]; + vregs[ REG_INT_ADRS_MODE ] = 0; + PM_set_VRSET(); + save_BL_param(); + set_camled_stop(); + trig_to_sleep_wifiLed(); + } + + // 電源LED // + if( vregs[ REG_INT_ADRS_POWER_LED ] == 0 ){ + if( ++tsk_interval_cnt_power_led >= tsk_interval_power_led ){ + tsk_interval_cnt_power_led = 0; + tsk_power_led(); + } + led_pwm_GR_grad(); + } + + // WiFi LED // + if( ++tsk_interval_cnt_wifi_led >= tsk_interval_wifi_led ){ + tsk_interval_cnt_wifi_led = 0; + tsk_wifi_led(); + } + + // cam LED // + if( ++tsk_interval_cnt_cam_led >= tsk_interval_cam_led ){ + tsk_interval_cnt_cam_led = 0; + tsk_cam_led(); + } + + // 音量/バックライト輝度スイッチ + if( ++tsk_interval_cnt_sw_vol >= tsk_interval_sw_vol ){ // 間隔可変 + tsk_interval_cnt_sw_vol = 0; + tsk_sw_vol(); + } + + // 電池残量 // + if( ++tsk_interval_cnt_adc >= tsk_interval_adc ){ // ← 注意! カウンタ再利用してます! + tsk_interval_cnt_adc = 0; + tsk_adc(); + } + + // 電源off時に、wifi reset をアサート + if( PM_OFF ){ + n_wifi_reset_ast; + } +} + + + +/****************************************************************************** + レジスタ書き込みなどで起動が指示されたタスク + ******************************************************************************/ +void running_immediately(){ + // I2Cで書き込まれたとき。 + // ここで書かないと、キー操作でのS/W I2C中に H/W I2Cが入った際にバスが使用中だったりで困る。 + if( rsv_set_camLED ){ + rsv_set_camLED = 0; + set_camled(); + } + // BL保存。 pmoffもしくは、電池切れそう + // PM_OFFは80ms出る。 + if( PM_OFF || ( battLvl <= 1 ) ){ + save_BL_param(); + } + if( rsv_set_vol ){ + rsv_set_vol = 0; + dcp_vol_set(); + } + if( rsv_set_BL ){ + rsv_set_BL = 0; + BL_write(); + } + // NTR or TWLでtw_pww2の値を変える + if( rsv_set_PMIC_VRSET ){ + rsv_set_PMIC_VRSET = 0; + PM_set_VRSET(); + } + // NAND保護の関係で、電池電圧検出のテーブルを切り替える + if( rsv_set_batt_th ){ + rsv_set_batt_th = 0; + set_batt_th(); + } + // LED点灯試験のため + if( rsv_set_powLED ){ + rsv_set_powLED = 0; + set_powLED_mode(); + } +} + + + + +/****************************************************************************** + 起動直後の1秒はブートモード + ・vol- が押されたらミュート + ******************************************************************************/ +void wait_for_system_boot(){ + if( !n_sys_reset ){ + // リセット解除まで、【何度も】実行 // + if( ( n_key_func == 1 ) + && ( n_key_minus == 0 ) ){ + vol_mute_start = 1; + } + }else{ + // リセット解除後、【一回だけ】実行 // + iic2m_bus_reset(); + reg_init(); // 仮想レジスタの初期値のセット。(特に初期値セットしていないメモリはスタートアップルーチンで全クリアされる) + flash_init(); + restore_params(); // バックライト輝度、ADC補正値読んでくる + if( vol_mute_start == 1 ){// mute? + vregs[REG_INT_ADRS_VOL] = 0; + dcp_vol_set(); // DCPへの書き込み、20msかかる。次のアクセス注意 + }else{ + dcp_vol_read(); // ボリューム読んでくる + } + iic2m_bus_reset(); + pmic_init(); // 電池情報取得など。リセット解除から3msは経ってるはず... + set_batt_th(); + IIC0_SlaveReceiveStart(); + system_inited = 1; + } +} + + + +/****************************************************************************** + キーの判定。一回呼ばれると1上がる。T = 16ms で呼べば、約4sでカンストとなる。 + マクロ無理やりすぎだ + ******************************************************************************/ +#define btn_check( btn, cntr ) { \ + if( btn == 0 ){ \ + if( cntr != 0xFF ){ \ + cntr++; \ + } \ + }else{ \ + cntr = 0; \ + } \ +} + + + +/****************************************************************************** + ボリューム/バックライト輝度変更 チェック + ******************************************************************************/ +enum vol_or_bl { VOL, BL }; + +void tsk_sw_vol(){ + static u8 vol_mns_cntr, vol_pls_cntr; + static u8 BL_mns_cntr, BL_pls_cntr; + + if( n_key_func != 0 ){ + // VOL操作 + if( PM_SLP == 0 ){ + btn_check( n_key_plus, vol_pls_cntr ); // 起きていないと vol+ は見ない + }else{ + vol_pls_cntr = 0; + } + BL_pls_cntr = 0; + BL_mns_cntr = 0; + + btn_check( n_key_minus, vol_mns_cntr ); + if( n_key_plus == 0 && n_key_minus != 0 ){ // キーチェック + if( vol_pls_cntr == 1 ){ + tsk_interval_sw_vol = 2; + }else if( vol_pls_cntr == 5 ){ + vol_inc(); + }else if( vol_pls_cntr >= 40 ){ + vol_inc(); + tsk_interval_sw_vol = 32; + } + }else if( n_key_plus != 0 && n_key_minus == 0 ){ // キーチェック + if( vol_mns_cntr == 1 ){ + tsk_interval_sw_vol = 2; + }else if( vol_mns_cntr == 5 ){ + vol_dec(); + }else if( vol_mns_cntr >= 40 ){ + vol_dec(); + tsk_interval_sw_vol = 32; + } + }else{ + tsk_interval_sw_vol = 2; + } + }else{ + // func押されてるとき:バックライト輝度操作 + if( PM_SLP == 1 ){ + return; + } + vol_pls_cntr = 0; + vol_mns_cntr = 0; + + btn_check( n_key_plus, BL_pls_cntr ); + btn_check( n_key_minus, BL_mns_cntr ); + if( n_key_plus == 0 && n_key_minus != 0 ){ + if( BL_pls_cntr == 1 ){ + tsk_interval_sw_vol = 2; + }else if( BL_pls_cntr == 5 ){ + BL_inc(); + }else if( BL_pls_cntr >= 40 ){ + BL_inc(); + tsk_interval_sw_vol = 32; + } + }else if( n_key_plus != 0 && n_key_minus == 0 ){ + if( BL_mns_cntr == 1 ){ + tsk_interval_sw_vol = 2; + }else if( BL_mns_cntr == 5 ){ + BL_dec(); + }else if( BL_mns_cntr >= 40 ){ + BL_dec(); + tsk_interval_sw_vol = 32; + } + }else{ + tsk_interval_sw_vol = 2; + } + } +} + + + +/****************************************************************************** + 1)電源スイッチのカウント、 +   TWLと、NDSで挙動が違いますよ +   チャタリング除去は外でやってくれてます(20ms) + 2)I2Cでコマンドかかれたときの動作 + ! 方針変えました。 +   ・NTRのとき、offはPMICに任せます。 +   ・押したままスリープから復帰したら離すまで無視はします。が、実機ではおこらない + ******************************************************************************/ +void tsk_sw_pow(){ + static u8 rst_cntr; + +/* + if( PM_SLP == 1 ){ // スリープ時は逃げる + pwsw_state = 3; // 押したままスリープから復帰なら、離すまで無視フラグ + return; + } +*/ + + if( n_key_pwsw == 0 ){ + /// 押されてる /// + if( rst_cntr != 255 ){ + rst_cntr++; + } + + if( ( pwsw_state == 0 ) && + ( rst_cntr >= vregs[ REG_INT_ADRS_TIME_PWSW_DELAY ] ) ){ // 無視時間経過? + pwsw_state = 1; + if( is_TWL ){ +// DI(); + vregs[REG_INT_ADRS_IRQ] |= 0x08; + n_irq_ast; + n_irq_ngt; +// EI(); + }else{ + // 何もしない + } + return; + } + if( ( pwsw_state == 1 ) && + ( rst_cntr >= vregs[ REG_INT_ADRS_TIME_PWSW_THRESHOLD ] ) ){ // 電源オフ確定 + pwsw_state = 2; // /IRQ をかけまくらないように + if( is_TWL ){ +// DI(); + vregs[REG_INT_ADRS_IRQ] |= 0x02; + n_irq_ast; + n_irq_ngt; +// EI(); + }else{ + // 何もしない + } + return; + } + return; // 以降スイッチ無視 + }else{ + /// 離されてる /// + if( pwsw_state == 1 ){ // リセット確定 + if( is_TWL ){ +// DI(); + vregs[REG_INT_ADRS_IRQ] |= 0x01; + n_irq_ast; + n_irq_ngt; +// EI(); + }else{ + vregs[REG_INT_ADRS_COMMAND] |= 0x01; + } + } + rst_cntr = 0; + pwsw_state = 0; + } +} + + + +/****************************************************************************** + I2Cでコマンドかかれたときの解釈と、後始末など + ******************************************************************************/ +void tsk_command_exec(){ + static u8 count; + + // レジスタチェック // + if( ( vregs[ REG_INT_ADRS_COMMAND ] & 0x02 ) != 0 ){ // 電源オフ + // 将来的には電源オフコマンドを送る...かな + }else if( ( vregs[ REG_INT_ADRS_COMMAND ] & 0x01 ) != 0 ){ // リセット処理 + n_sys_reset_ast; + } + + // リセットボタン処理 // + if( n_sys_reset == 0 ){ + if( count < 2 ){ + count++; + }else{ + vregs[ REG_INT_ADRS_IRQ ] = 0; + vregs[ REG_INT_ADRS_COMMAND ] = 0; + vregs[ REG_INT_ADRS_CAM ] = 0; + set_camled_stop(); + vregs[ REG_INT_ADRS_MODE ] = 0; + // ↑ volSteps32 = 0 + // is_TWL = 0 + // with_NAND = 0 + vregs[ REG_INT_ADRS_POWER_SAVE ] = 0x07; + set_batt_th(); + rsv_set_PMIC_VRSET = 1; + if( vregs[ REG_INT_ADRS_POWER_LED ] != 0 ){ + vregs[ REG_INT_ADRS_POWER_LED ] = 0; + set_powLED_mode(); + } + wifi_tx = 0; + n_irq_ngt; + n_sys_reset_ngt; + EI(); + pwsw_state = 3; + } + }else{ + count = 0; + } +} + + + +/****************************************************************************** + バックライト輝度保存 + sleep中 or PM_OFF 時、NTRモードで電池が無くなったら即時記録。 + ******************************************************************************/ +void save_BL_param(){ + u8 status; + + if( eeprom_bl_dirty == 1 ){ + if( flash_write( DAT_BL_BRIGHT, &vregs[REG_INT_ADRS_BL] ) == 0 ){ + eeprom_bl_dirty = 0; + } + } +} + + + +void SystemInit( void ){ + CG_ReadResetSource(); /*Process of reset*/ + Clock_Init(); /*initialize the clock generator*/ + PORT_Init(); /*Initialize the I/O ports*/ + IIC0_Init(); /*Initialize the IIC0*/ + ADC_Init(); + TM51_Init(); /*Initialize TM51 function*/ + + TMH0_Init(); /*Initialize TMH0 function*/ + TMH1_Init(); /*Initialize TMH1 function*/ + TM50_Init(); /*Initialize TM50 function*/ +} + + + +void hdwinit( void ){ + DI(); + IMS = MEMORY_IMS_SET; + SystemInit(); + EI(); +} + + +void reg_init(){ +#ifdef after_x6 + // Ver.3(TWL,X6以降改造(RxPE監視), Rev.0(自己書き換え対応) + // 1(Func + +/- がおかしい件) + vregs[ REG_INT_ADRS_VER_INFO ] = 0x33; +#else + // Ver.2(TWL), Rev.1(K,TS-X4以降) + // Ver.2(TWL), Rev.2(自己書き換え対応) + vregs[ REG_INT_ADRS_VER_INFO ] = 0x25; +#endif + vregs[ REG_INT_ADRS_POWER_SAVE ] = 0x07; + vregs[ REG_INT_ADRS_TIME_PWSW_DELAY ] = ( 80 ) / 5; + vregs[ REG_INT_ADRS_TIME_PWSW_THRESHOLD ] = ( 500 ) / 5; + +#ifdef wifi_led_blink_default_on + // ランチャー対応待ち、WiFiLEDブリンクデフォルトON + vregs[ REG_INT_ADRS_WIFI ] = 0x02; +#endif + +} diff --git a/option.asm b/option.asm new file mode 100644 index 0000000..d26c8f9 --- /dev/null +++ b/option.asm @@ -0,0 +1,64 @@ +;/* +;****************************************************************************** +;* +;* This device driver was created by Applilet2 for the Applilet2 for 78K0/Kx2 +;* 8-Bit Single-Chip Microcontrollers +;* +;* Copyright(C) NEC Electronics Corporation 2002 - 2007 +;* All rights reserved by NEC Electronics Corporation. +;* +;* This program should be used on your own responsibility. +;* NEC Electronics Corporation assumes no responsibility for any losses +;* incurred by customers or third parties arising from the use of this file. +;* +;* Filename : option.asm +;* Abstract : This file implements OPTION-BYTES/SECURITY-ID setting. +;* APIlib : Applilet2 for 78K0/Kx2 V2.10 [6 Mar. 2007] +;* +;* Device : uPD78F0500_30 +;* +;* Compiler : CC78K0 +;* +;* Creation date: 2007/07/11 +;* +;****************************************************************************** +;*/ + +;/* +;****************************************************************************** +;* Include files +;****************************************************************************** +;*/ +$ INCLUDE (option.inc) +;/* +;****************************************************************************** +;* Macro define +;****************************************************************************** +;*/ + +;/* +;****************************************************************************** +;* Global define +;****************************************************************************** +;*/ + OPT_SET CSEG AT 80H +OPTION: DB OPTION_BYTE + DB POC81 + DB POC82 + DB POC83 + + ONC_SET CSEG AT 84H +ONCHIP: DB CG_ONCHIP + + ONC_SBR CSEG AT 7EH +ONCSBR: DB 0FFH, 0FFH + + ONC_STK1 DSEG AT 0FD00H +ONCSTK1: DS 9 + + ONC_STK2 DSEG AT 0FEDFH +ONCSTK2: DS 1 + +; Start adding user code. Do not edit comment generated here +; End user code adding. Do not edit comment generated here + END diff --git a/option.inc b/option.inc new file mode 100644 index 0000000..937e341 --- /dev/null +++ b/option.inc @@ -0,0 +1,83 @@ +;/* +;****************************************************************************** +;* +;* This device driver was created by Applilet2 for the Applilet2 for 78K0/Kx2 +;* 8-Bit Single-Chip Microcontrollers +;* +;* Copyright(C) NEC Electronics Corporation 2002 - 2007 +;* All rights reserved by NEC Electronics Corporation. +;* +;* This program should be used on your own responsibility. +;* NEC Electronics Corporation assumes no responsibility for any losses +;* incurred by customers or third parties arising from the use of this file. +;* +;* Filename : option.inc +;* Abstract : This file implements OPTION-BYTES/SECURITY-ID setting. +;* APIlib : Applilet2 for 78K0/Kx2 V2.10 [6 Mar. 2007] +;* +;* Device : uPD78F0500_30 +;* +;* Compiler : CC78K0 +;* +;* Creation date: 2007/07/11 +;* +;****************************************************************************** +;*/ + +;/* +;****************************************************************************** +;* Macro define +;****************************************************************************** +;*/ +;/* +;****************************************************************************** +;* Register bit define +;****************************************************************************** +;*/ +;*** OPTION-BYTES bit define *** +; Option at 80H +; Watchdog timer window open period (WINDOW1-0) +WDT_WINDOW_OPEN EQU 60H +WDT_WINDOW_OPEN_PERIOD0 EQU 00H ;25% +WDT_WINDOW_OPEN_PERIOD1 EQU 20H ;50% +WDT_WINDOW_OPEN_PERIOD2 EQU 40H ;75% +WDT_WINDOW_OPEN_PERIOD3 EQU 60H ;100% +; Watchdog timer counter control (WDTON) +WDT_OPERATION EQU 10H +WDT_OPERATION_ENABLE EQU 10H ;Counter operation enabled +WDT_OPERATION_DISABLE EQU 00H ;Counter operation disabled +; Watchdog timer overflow time (WDCS2-0) +WDT_OVERFLOW EQU 0EH +WDT_OVERFLOW_TIME0 EQU 00H ;2^10/fRL (3.88 ms) +WDT_OVERFLOW_TIME1 EQU 02H ;2^11/fRL (7.76 ms) +WDT_OVERFLOW_TIME2 EQU 04H ;2^12/fRL (15.52 ms) +WDT_OVERFLOW_TIME3 EQU 06H ;2^13/fRL (31.03 ms) +WDT_OVERFLOW_TIME4 EQU 08H ;2^14/fRL (62.06 ms) +WDT_OVERFLOW_TIME5 EQU 0AH ;2^15/fRL (124.12 ms) +WDT_OVERFLOW_TIME6 EQU 0CH ;2^16/fRL (248.24 ms) +WDT_OVERFLOW_TIME7 EQU 0EH ;2^17/fRL (496.48 ms) +; Internal low-speed oscillator operation (RINGOSC) +CG_LOWINTERNAL EQU 01H +CG_LOWINTERNAL_CANSTOP EQU 00H ;can be stopped by software +CG_LOWINTERNAL_CANNOT EQU 01H ;cannot be stopped + +; Option at 81H +; POC mode selection (POCMODE) +CG_POCMODE EQU 01H +CG_POCMODE_1DOT59V EQU 00H ;1.59 V POC mode (default) +CG_POCMODE_2DOT7V EQU 01H ;2.7 V/1.59 V POC mode + +; Option at 84H +; On-chip debug operation control (OCDEN1-0) +CG_FLASH EQU 02H ;when security ID code authenticaiton fails +CG_FLASH_NOTERASE EQU 02H ;data is not deleted +CG_FLASH_ERASE EQU 01H ;data is deleted + +;*** OPTION-BYTES/SECURITY-ID define *** +OPTION_BYTE EQU WDT_WINDOW_OPEN_PERIOD3 OR WDT_OPERATION_ENABLE OR WDT_OVERFLOW_TIME7 OR CG_LOWINTERNAL_CANSTOP +POC81 EQU 00H +POC82 EQU 00H +POC83 EQU 00H + +;CG_ONCHIP EQU CG_FLASH_NOTERASE +CG_ONCHIP EQU 00 diff --git a/twl2mcu2.h b/twl2mcu2.h new file mode 100644 index 0000000..6803e4f --- /dev/null +++ b/twl2mcu2.h @@ -0,0 +1,4 @@ +#ifndef __twl2_mcu2_h__ +#define __twl2_mcu2_h__ + +#endif diff --git a/user_define.h b/user_define.h new file mode 100644 index 0000000..31786d0 --- /dev/null +++ b/user_define.h @@ -0,0 +1,166 @@ +#ifndef _MD_USER_DEF_ +#define _MD_USER_DEF_ + +#include "config.h" + +#define n_sys_reset ( P1.2 ) +#define n_sys_reset_ast { PM1.2 = 0; P1.2 = 0; } +#define n_sys_reset_ngt { PM1.2 = 1; P1.2 = 1; } + +#define n_irq_ast { P12.0 = 0; PM12.0 = 0; } // 念のため。 +#define n_irq_ngt { P12.0 = 1; PM12.0 = 1; } + +#define n_wifi_reset_ast ( P12.1 = 0 ) +#define n_wifi_reset_ngt ( P12.1 = 1 ) // H にするとリセットがかかる + +#define PM_OFF ( P12.2 ) // オフ直前に H になる +#define PM_SLP ( P0.0 ) + +#define n_key_minus ( P1.3 ) +#define n_key_plus ( P1.4 ) + +// Vref = 2.8V 対応前、実力で動作/デバイスにダメージあり + +#define GPIO_dir ( PM2.2 ) +#define GPIO_dat ( P2.2 ) + +#define flash_we ( P2.0 ) +#define n_key_pwsw ( P2.1 ) +#define n_key_func ( P3.0 ) // select +#define n_ac_supp ( P3.3 ) + +#define led_wifi ( P1.7 ) + +#define led_G_on ( P1.6 = 1 ) +#define led_G_pwm ( P1.6 = 0 ) + +#define led_R_on ( P1.5 = 1 ) +#define led_R_pwm ( P1.5 = 0 ) + +#define led_cam ( P2.2 ) + +#define WDTRF 0x10 + +#define TxPE ( P3.2 ) +#define RxPE ( P0.1 ) + +#define IS_led_cam_mode ( PM0.1 ) // 赤箱対応 +#define IS_led_cam RxPE // 赤箱対応 + +enum EEP_DAT_NAME { DAT_BL_BRIGHT, DAT_ADC_COMP }; + + + +/* + * 外から見たときの、マイコンレジスタアドレス。 + * 拡張性などを考えて、飛び飛び + */ +/* + * 割り込み要因フラグは + * MSB:外部電源供給有り/なし変化 (未実装) + * 6:Volキー操作(変更に限らず。MAX時に+でも。) + * 5:電池電圧 少 検出 + * 4: 僅 + * 3:電源スイッチ 押され検出 + * 2:(未設定) + * 1:電源スイッチ OFF 時間押され検出 + * LSB: リセット + */ +enum REG_ADRS{ // 未定義アドレスへ書き込んだ際の動作は不定 + REG_ADRS_VER_INFO = 0x00, + REG_ADRS_PMIC_INFO, + REG_ADRS_BATT_INFO, + REG_ADRS_IRQ = 0x10, + REG_ADRS_COMMAND, + REG_ADRS_MODE, + REG_ADRS_POWER_INFO = 0x20, + REG_ADRS_POWER_SAVE, + REG_ADRS_WIFI = 0x30, + REG_ADRS_CAM, + REG_ADRS_VOL = 0x40, + REG_ADRS_BL, + REG_ADRS_ADC_CALIB = 0x60, + REG_ADRS_ADC_CALIB_STATUS, + REG_ADRS_ADC_CALIB_VALUE, + REG_ADRS_POWER_LED, + REG_ADRS_TEMP0 = 0x70, // 〜0x77 まで。 + REG_ADRS_TEMP1, + REG_ADRS_TEMP2, + REG_ADRS_TEMP3, + REG_ADRS_TEMP4, + REG_ADRS_TEMP5, + REG_ADRS_TEMP6, + REG_ADRS_TEMP7, + REG_ADRS_TIME_PWSW_DELAY = 0x80, + REG_ADRS_TIME_PWSW_THRESHOLD +}; + + +/* + * マイコン内部でのレジスタの実装 + * もちろん効率を考えて、つめてある + */ +enum REG_ADRS_INSIDE_MCU{ + REG_INT_ADRS_VER_INFO = 0x00, + REG_INT_ADRS_PMIC_INFO, + REG_INT_ADRS_BATT_INFO, + REG_INT_ADRS_IRQ, // 0x10, + REG_INT_ADRS_COMMAND, + REG_INT_ADRS_MODE, + REG_INT_ADRS_POWER_INFO, // 0x20, + REG_INT_ADRS_POWER_SAVE, + REG_INT_ADRS_WIFI, // 0x30, + REG_INT_ADRS_CAM, + REG_INT_ADRS_VOL, // 0x40, + REG_INT_ADRS_BL, + REG_INT_ADRS_ADC_CALIB, // 0x60, + REG_INT_ADRS_ADC_CALIB_STATUS, + REG_INT_ADRS_ADC_CALIB_VALUE, + REG_INT_ADRS_POWER_LED, + REG_INT_ADRS_TEMP0, // 0x70 - 0x77 + REG_INT_ADRS_TEMP1, + REG_INT_ADRS_TEMP2, + REG_INT_ADRS_TEMP3, + REG_INT_ADRS_TEMP4, + REG_INT_ADRS_TEMP5, + REG_INT_ADRS_TEMP6, + REG_INT_ADRS_TEMP7, + REG_INT_ADRS_TIME_PWSW_DELAY, + REG_INT_ADRS_TIME_PWSW_THRESHOLD +}; + +#define REGISTER_SIZE 27 + +#define BL_IND_MAX 4 // 配列番。配列数じゃないよ + +#define IIC_SLV_ADDR_MONITOR 0x6E + +typedef enum { Wake, Sleep } sleep_status_; + +enum { NTR, TWL }; + +#ifdef iic_debug_msg +#define DBG_IIC_REG_TMP0( x ) vregs[ REG_INT_ADRS_TEMP0 ] = x +#define DBG_IIC_REG_TMP1( x ) vregs[ REG_INT_ADRS_TEMP1 ] = x +#define DBG_IIC_REG_TMP2( x ) vregs[ REG_INT_ADRS_TEMP2 ] = x +#define DBG_IIC_REG_TMP3( x ) vregs[ REG_INT_ADRS_TEMP3 ] = x +#define DBG_IIC_REG_TMP4( x ) vregs[ REG_INT_ADRS_TEMP4 ] = x +#define DBG_IIC_REG_TMP5( x ) vregs[ REG_INT_ADRS_TEMP5 ] = x +#define DBG_IIC_REG_TMP6( x ) vregs[ REG_INT_ADRS_TEMP6 ] = x +#define DBG_IIC_REG_TMP7( x ) vregs[ REG_INT_ADRS_TEMP7 ] = x + +#else +#define DBG_IIC_REG_TMP0( x ) ; +#define DBG_IIC_REG_TMP1( x ) ; +#define DBG_IIC_REG_TMP2( x ) ; +#define DBG_IIC_REG_TMP3( x ) ; +#define DBG_IIC_REG_TMP4( x ) ; +#define DBG_IIC_REG_TMP5( x ) ; +#define DBG_IIC_REG_TMP6( x ) ; +#define DBG_IIC_REG_TMP7( x ) ; + + +#endif + + +#endif diff --git a/vreg.c b/vreg.c new file mode 100644 index 0000000..c85cf15 --- /dev/null +++ b/vreg.c @@ -0,0 +1,189 @@ +#include "incs.h" + +// レジスタマップは user_define.h 参照 +u8 vregs[REG_INT_ADRS_TIME_PWSW_THRESHOLD+1]; + +extern u8 battLvl; + +// もっといい方法がある気がする。 +// 直接書くのは良くない気がする +// タスクのインターバル用カウンタ。レジスタ変更通知で強制起動用 +extern u8 tsk_interval_cnt_adc; +extern u8 tsk_interval_cnt_power_led; +extern u8 tsk_interval_cnt_wifi_led; +extern bit rsv_set_vol; +extern bit rsv_set_BL; +extern bit rsv_set_PMIC_VRSET; +extern bit rsv_set_batt_th; +extern bit rsv_set_camLED; +extern bit rsv_set_powLED; + +extern bit adc_calib_mode; + +extern bit self_prog_mode; + + +//******************************************************************************* +// I2C仮想レジスタに書きます。 +// 引数 adrs は内部アドレス +//  存在しないアドレスにアクセスした場合、何もしません。 +void vregs_write( u8 adrs, u8 data ){ + + if( REG_INT_ADRS_TIME_PWSW_THRESHOLD < adrs ){ // アドレス範囲外 + return; + }else if( REG_INT_ADRS_TEMP0 <= adrs ){ // 70 - 77 + vregs[ adrs ] = data; +/* +// マジックナンバーチェック +// 呼び出し元で解決に変更。 + if( adrs == REG_INT_ADRS_TEMP7 ){ + if( data == 0x4A ){ + self_prog_mode = 1; // 自己書き換えもーど + } + } +*/ + return; + }else if( REG_INT_ADRS_WIFI <= adrs ){ // 40 - + switch( adrs ){ + case( REG_INT_ADRS_WIFI ): + vregs[ REG_INT_ADRS_WIFI ] = data; + if( ( data & 0x10 ) == 0 ){ + n_wifi_reset_ast; + }else{ + n_wifi_reset_ngt; + } + break; + case( REG_INT_ADRS_CAM ): + vregs[ REG_INT_ADRS_CAM ] = data; + rsv_set_camLED = 1; + break; + case( REG_INT_ADRS_VOL ): + vregs[ REG_INT_ADRS_VOL ] = data & 0x1F; + rsv_set_vol = 1; + break; + case( REG_INT_ADRS_BL ): + vregs[ REG_INT_ADRS_BL ] = data; + rsv_set_BL = 1; + break; + case( REG_INT_ADRS_ADC_CALIB ): + vregs[ REG_INT_ADRS_ADC_CALIB ] = data; + if( ( data & 0x01 ) == 1 ) adc_calib_mode = 1; + break; + case( REG_INT_ADRS_POWER_LED ): + vregs[ REG_INT_ADRS_POWER_LED ] = data; + rsv_set_powLED = 1; + break; + } + return; + }else{ + switch( adrs ){ // 0 - + case( REG_INT_ADRS_COMMAND ): + vregs[ REG_INT_ADRS_COMMAND ] = data; + // 将来的にはここからさらにPMICにコマンド + break; + case( REG_INT_ADRS_POWER_SAVE ): + vregs[ REG_INT_ADRS_POWER_SAVE ] = data; + break; + case( REG_INT_ADRS_MODE ): + vregs[ REG_INT_ADRS_MODE ] = data; + rsv_set_PMIC_VRSET = 1; + rsv_set_batt_th = 1; + break; + } + return; + } +} + + + +//******************************************************************************* +// I2C仮想レジスタから読みます。 +// 引数 adrs 外から見たときの、アドレス +// 戻り xx データ +//  存在しないアドレスにアクセスした場合、戻り値は0x5A +u8 vregs_read( u8 phy_adrs ){ + static u8 dat; + + dat = vregs[ phy_adrs ]; + + switch( phy_adrs ){ + case( REG_INT_ADRS_IRQ ): + vregs[ REG_INT_ADRS_IRQ ] = 0; + break; + case( REG_INT_ADRS_POWER_INFO ): + if( n_ac_supp == 0 ){ // 必要なとき合成。”刺さっていればゼロ” + dat |= 0x80; + } + break; + case( 0xFF ): + dat = ( 0x5A ); + break; + } + return( dat ); +} + + + +//******************************************************************************* +// 外部から見える虫食いアドレスを、内部の連続アドレスに読み替える +// 0xFFは存在しないアドレス。 +u8 adrs_table_ext2int( u8 img ){ + static u8 adrsH, adrsL; + + adrsH = ( img & 0xF0 ); + adrsL = ( img & 0x0F ); + if( adrsH > 0x80 ){ + return( 0xFF ); + } + if( adrsH == 0x50 ){ + return( 0xFF ); + } + + if( adrsH <= 0x30 ){ // 0x00 - 0x3F + if( adrsH <= 0x10 ){ // 0x00 - 0x1F + if( adrsH == 0x10 ){ // 0x1* + if( adrsL <= ( REG_ADRS_MODE & 0x0F ) ){ + return( REG_INT_ADRS_IRQ + adrsL ); + } + }else{ // 0x0* + if( adrsL <= ( REG_ADRS_BATT_INFO & 0x0F ) ){ + return( REG_INT_ADRS_VER_INFO + adrsL ); + } + } + }else{ // 0x20 - 0x3F + if( adrsH == 0x20 ){ // 0x2? + if( adrsL <= ( REG_ADRS_POWER_SAVE & 0x0F ) ){ + return( REG_INT_ADRS_POWER_INFO + adrsL ); + } + }else{ // 0x3* + if( adrsL <= ( REG_ADRS_CAM & 0x0F ) ){ + return( REG_INT_ADRS_WIFI + adrsL ); + } + } + } + }else{ + if( adrsH <= 0x60 ){ + if( adrsH == 0x60 ){ + if( adrsL <= ( REG_ADRS_POWER_LED & 0x0F ) ){ + return( REG_INT_ADRS_ADC_CALIB + adrsL ); + } + }else{ // 40台 + if( adrsL <= ( REG_ADRS_BL & 0x0F ) ){ + return( REG_INT_ADRS_VOL + adrsL ); + } + } + }else{ + if( adrsH == 0x70 ){ + if( adrsL <= ( REG_ADRS_TEMP7 & 0x0F ) ){ + return( REG_INT_ADRS_TEMP0 + adrsL ); + } + }else{ // 80台 + if( adrsL <= ( REG_ADRS_TIME_PWSW_THRESHOLD & 0x0F ) ){ + return( REG_INT_ADRS_TIME_PWSW_DELAY + adrsL ); + } + } + } + } + return( 0xFF ); +} + diff --git a/vreg.h b/vreg.h new file mode 100644 index 0000000..5aa8a9b --- /dev/null +++ b/vreg.h @@ -0,0 +1,17 @@ +#ifndef __vreg_h__ +#define __vreg_h__ + +#define is_TWL ( vregs[ REG_INT_ADRS_MODE ] & 0x01 ) +#define with_NAND ( vregs[ REG_INT_ADRS_MODE ] & 0x02 ) +#define volSteps32 ( vregs[ REG_INT_ADRS_MODE ] & 0x80 ) + +#define reg_wifi_led ( vregs[REG_INT_ADRS_WIFI] & 0x01 ) +#define reg_wifi_led_blink ( vregs[REG_INT_ADRS_WIFI] & 0x02 ) + +void vregs_write( u8 adrs, u8 data ); +u8 vregs_read( u8 adrs ); +u8 vregs_check_changed(); +u8 adrs_table_ext2int( u8 img ); +u8 vregs_read( u8 phy_adrs ); + +#endif