CuriosityでmTouchを試してみる。その10 TIMER0編(2)

とりあえずなんとかできそうなアタリがついたところで、やってみたいと思います。

まずは mTouch CVD で AFA を有効にしたソースを生成します。このとき、TIMER4 や TIMER6 を使うので、プロジェクトに追加して適切に設定しておきます。
また TIMER2 の身代わりとなる TIMER0 も追加して、割り込みを有効にするように設定しておきます。

すると、mTouch 専用に 設定された tmr2.[ch] と、tmr0/4/6.[ch] が出力されているはずですなのでこれをいじります。同時に mtouch_sensor.[ch] もいじります。

まず最初に、生成されたファイルをコミットして差分が取れるようにしておきます。

次に tmr0.c を tmr2.c と同様の内容になっているかチェックします。すでに MCC で設定しているので、動作としては同じことができるはずです。もしも設定が違っていたら、データシートとにらみ合いながら修正します。

終わったら mtouch_sensor.c です。
tmr2.h をインクルードしているところを、tmr0.h に変更します。
TMR2_LoadPeriodRegister() は TMR0_Reload() に変更します。
TMR2 のところをすべて TMR0 に変更します。
また、T2CONbits.T2CKPS を T0CON1bits.T0CKPS に変更します。
diff -r d49f637e026f mcc_generated_files/interrupt_manager.c
--- a/mcc_generated_files/interrupt_manager.c Fri Mar 01 13:34:06 2019 +0900
+++ b/mcc_generated_files/interrupt_manager.c Sat Mar 02 08:50:47 2019 +0900
@@ -58,11 +58,7 @@
     }
     else if(INTCONbits.PEIE == 1)
     {
-        if(PIE1bits.TMR2IE == 1 && PIR1bits.TMR2IF == 1)
-        {
-            TMR2_ISR();
-        } 
-        else if(PIE1bits.TMR1IE == 1 && PIR1bits.TMR1IF == 1)
+        if(PIE1bits.TMR1IE == 1 && PIR1bits.TMR1IF == 1)
         {
             TMR1_ISR();
         } 
diff -r d49f637e026f mcc_generated_files/mtouch/mtouch_sensor.c
--- a/mcc_generated_files/mtouch/mtouch_sensor.c Fri Mar 01 13:34:06 2019 +0900
+++ b/mcc_generated_files/mtouch/mtouch_sensor.c Sat Mar 02 08:50:47 2019 +0900
@@ -37,7 +37,7 @@
 #include 
 #include 
 
-#include "../tmr2.h"
+#include "../tmr0.h"
 
 #include "mtouch_sensor.h"
 #include "mtouch_sensor_scan.h"
@@ -177,7 +177,7 @@
  */
 void MTOUCH_Sensor_Scan_Initialize(void)
 {
-    T2CONbits.T2CKPS = 0x0;
+    T0CON1bits.T0CKPS = 0x0;
 
     ADCON0 = (uint8_t)0;                            /* overwrite the ADC configuration for mTouch scan */
     ADCON1 = (uint8_t)( 0x1<<7 | 0x2<<4 | 0x0 );
@@ -311,9 +311,9 @@
     sensor_globalFlags.packet_done = 0;
     packet_noise = 0;
     
-    TMR2_SetInterruptHandler(Sensor_Acq_ExecuteScan);  /* Use timer2 to schedule the scan */
-    TMR2_LoadPeriodRegister(sample_period);
-    TMR2_StartTimer();
+    TMR0_SetInterruptHandler(Sensor_Acq_ExecuteScan);  /* Use timer0 to schedule the scan */
+    TMR0_Reload(sample_period);
+    TMR0_StartTimer();
     
     sensor_globalFlags.interrupted = false;
     
@@ -329,7 +329,7 @@
     } while(sensor_globalFlags.packet_done == 0);
 
 
-    TMR2_StopTimer();
+    TMR0_StopTimer();
     ADCON0 = ADCON0_temp;       /* restore the previous ADC configuration */
     ADCON1 = ADCON1_temp;
     ADACT = ADACT_temp;
@@ -630,4 +630,4 @@
     {
        mtouch_sensor[name].oversampling =  (mtouch_sensor_packetcounter_t)(value);
     }
-}
\ No newline at end of file
+}
diff -r d49f637e026f mcc_generated_files/tmr2.c
--- a/mcc_generated_files/tmr2.c Fri Mar 01 13:34:06 2019 +0900
+++ b/mcc_generated_files/tmr2.c Sat Mar 02 08:50:47 2019 +0900
@@ -55,8 +55,6 @@
   Section: Global Variables Definitions
 */
 
-void (*TMR2_InterruptHandler)(void);
-
 /**
   Section: TMR2 APIs
 */
@@ -71,17 +69,11 @@
     // TMR2 0; 
     TMR2 = 0x00;
 
-    // Clearing IF flag before enabling the interrupt.
+    // Clearing IF flag.
     PIR1bits.TMR2IF = 0;
 
-    // Enabling TMR2 interrupt.
-    PIE1bits.TMR2IE = 1;
-
-    // Set Default Interrupt Handler
-    TMR2_SetInterruptHandler(TMR2_DefaultInterruptHandler);
-
-    // T2CKPS 1:1; T2OUTPS 1:1; TMR2ON on; 
-    T2CON = 0x04;
+    // T2CKPS 1:64; T2OUTPS 1:1; TMR2ON on; 
+    T2CON = 0x07;
 }
 
 void TMR2_StartTimer(void)
@@ -116,28 +108,17 @@
    PR2 = periodVal;
 }
 
-void TMR2_ISR(void)
+bool TMR2_HasOverflowOccured(void)
 {
-
-    // clear the TMR2 interrupt flag
-    PIR1bits.TMR2IF = 0;
-
-    if(TMR2_InterruptHandler)
+    // check if  overflow has occurred by checking the TMRIF bit
+    bool status = PIR1bits.TMR2IF;
+    if(status)
     {
-        TMR2_InterruptHandler();
+        // Clearing IF flag.
+        PIR1bits.TMR2IF = 0;
     }
+    return status;
 }
-
-
-void TMR2_SetInterruptHandler(void (* InterruptHandler)(void)){
-    TMR2_InterruptHandler = InterruptHandler;
-}
-
-void TMR2_DefaultInterruptHandler(void){
-    // add your TMR2 interrupt custom code
-    // or set custom function using TMR2_SetInterruptHandler()
-}
-
 /**
   End of File
 */
\ No newline at end of file
diff -r d49f637e026f mcc_generated_files/tmr2.h
--- a/mcc_generated_files/tmr2.h Fri Mar 01 13:34:06 2019 +0900
+++ b/mcc_generated_files/tmr2.h Sat Mar 02 08:50:47 2019 +0900
@@ -291,76 +291,38 @@
 
 /**
   @Summary
-    Timer Interrupt Service Routine
+    Boolean routine to poll or to check for the match flag on the fly.
 
   @Description
-    Timer Interrupt Service Routine is called by the Interrupt Manager.
+    This function is called to check for the timer match flag.
+    This function is used in timer polling method.
 
   @Preconditions
-    Initialize  the TMR2 module with interrupt before calling this isr.
+    Initialize  the TMR2 module before calling this routine.
 
   @Param
     None
 
   @Returns
-    None
-*/
-void TMR2_ISR(void);
-
-/**
-  @Summary
-    Set Timer Interrupt Handler
-
-  @Description
-    This sets the function to be called during the ISR
-
-  @Preconditions
-    Initialize  the TMR2 module with interrupt before calling this.
-
-  @Param
-    Address of function to be set
-
-  @Returns
-    None
-*/
- void TMR2_SetInterruptHandler(void (* InterruptHandler)(void));
-
-/**
-  @Summary
-    Timer Interrupt Handler
-
-  @Description
-    This is a function pointer to the function that will be called during the ISR
+    true - timer match has occurred.
+    false - timer match has not occurred.
 
-  @Preconditions
-    Initialize  the TMR2 module with interrupt before calling this isr.
-
-  @Param
-    None
-
-  @Returns
-    None
-*/
-extern void (*TMR2_InterruptHandler)(void);
-
-/**
-  @Summary
-    Default Timer Interrupt Handler
+  @Example
+    
+    while(1)
+    {
+        // check the match flag
+        if(TMR2_HasOverflowOccured())
+        {
+            // Do something else...
 
-  @Description
-    This is the default Interrupt Handler function
-
-  @Preconditions
-    Initialize  the TMR2 module with interrupt before calling this isr.
-
-  @Param
-    None
-
-  @Returns
-    None
+            // Reload the TMR2 value
+            TMR2_Reload();
+        }
+    }
+    
 */
-void TMR2_DefaultInterruptHandler(void);
-
+bool TMR2_HasOverflowOccured(void);
 
  #ifdef __cplusplus  // Provide C++ Compatibility
 
これだけでいいはずなので、コンパイルしてみます。
いくつか警告が出ていますが、これはエラーチェックを厳密にしているためのようで、変更前のプロジェクトでも同様の警告が出ていたので無視します。

で、結論ですが、ちゃんと動きました。オシロスコープでも、mTouch 波形はタイミングを調整されて出ているのが確認できました。

バイナリライブラリでなにか処理をされていたら手が出ないかなとも考えていたのですが、すべてCソースレベルで実現されているようです。Cソースながら中身はインラインアセンブラで組まれている関数もありましたが、問題ないようです。

ということで、mTouch で専有されているピリオドタイマを開放して、TIMER0 をピリオドタイマに割り当てることはできました。これによって TIMER2/4/6 を自分の目的に割り当てることもできるようになりました。

0 件のコメント:

コメントを投稿

AstroNvimでtelescope.nvimがエラーを吐いたとき。

Windowsの環境でAstroNvimをインストールして、Find Fileしたらtelescopeがエラーを吐いてきました。 メッセージは、 Failed to run `config` for telescope.nvim ...a/lazy/telescope.nvim/...