1 Reply Latest reply on Aug 25, 2020 11:06 PM by EktaN_26

    CY8CKIT-044 Sensor Hub for UART

    MoTa_728816

      Hi,

      こんばんは、

       

      I'm going to teach a 10 days FPGA design course starting from next Monday.

      And during the course I'm also planning to teach the basic hands on of PSoC 4 (CY8CKIT-044).

      So I was browsing sample projects and I found that "CY8CKIT-044 Sensor Hub" is very nice.

      But it requires Micrium uC-Probe to show its best.

      Although uC-Probe is free download, after 45 days it may require additional cost.

      So I decide to hack-up a more affordable sample for students.

       

      来週から10日間の FPGA 実習講座を教えるのですが、その中で PSoC 4 (CY8CKIT-044) を使用したハンズオンも企んでいます。

      何か良さそうなサンプルないかなとみていたら、キットについてくるサンプルの "CY8CKIT-044 Sensor Hub" がとても良さそうなのですが、

      Micrium uC-Probe 経由でないと一番格好の良いところは見せられそうもありません。

      uC-Probe って、ダウンロード時は無償なのですが、45日経つと無償期間が終わってしまうようなので、

      学生さん向けに、もう少しお財布にやさしいデモにでっち上げてみました。

       

      Although the original example project was using WDT I chose SysTick.

      So that it will be easier to change the interval(s) of each sensors.

      I cheated by using my previous samples

       

      元サンプルは WDT を使用してタイミングをとっていましたが、各センサーのインターバルを

      変更しやすいように SysTick を使用しました。

      また、先に投稿してあった下記のサンプルを使用して、少し楽をさせてもらいました。

       

      tty_utils a utility sample for CLI type program

      https://community.cypress.com/message/200391#200391

       

      A simple VT100 Escape Sequence Emulator

      https://community.cypress.com/message/188161#188161

       

      RTC with 32kHz Crystal Sample

      https://community.cypress.com/thread/54092

       

      schematic / 回路図

      001-schematic-1.JPG

      002-schematic-2.JPG

      003-schematic-3.JPG

      004-schematic-4.JPG

      pins / ピンアサイン

      005-pins.JPG

       

      main.c

      ========================

      #include "project.h"

      #include "stdio.h"

      #include "tty_utils.h"

      #include "vt100.h"

      #include "rtc_utils.h"

      #include "main.h"

      #include "accelerometer.h"

       

      /*****************************************************************************

      * Local Function Prototypes

      *****************************************************************************/

      CY_ISR_PROTO(Accelerometer_Interrupt);

      CY_ISR_PROTO(SW2_Pressed) ;

      CY_ISR_PROTO(SysTick_ISR) ;

       

      #define LOC_DATE_X 20

      #define LOC_DATE_Y 4

      #define LOC_TEMP_X 10

      #define LOC_TEMP_Y 8

      #define LOC_AMB_X  40

      #define LOC_AMB_Y  8

      #define LOC_ACC_X  10

      #define LOC_ACC_Y  12

      #define LOC_ACCX_X 16

      #define LOC_ACCY_X 28

      #define LOC_ACCZ_X 40

       

      /*****************************************************************************

      * Global Variable Declarations

      *****************************************************************************/

      int16 ambientLight             = ZERO;

      int8  temperatureInteger       = ZERO;

      int16 x_dirMovement            = ACC_NO_MOVEMENT;

      int16 y_dirMovement            = ACC_NO_MOVEMENT;

      int16 z_dirMovement            = ACC_NO_MOVEMENT;

      uint8 temperatureFractional    = ZERO;

      uint8 acclerometer_configured  = FALSE;

      uint8 accRequest               = FALSE;

      uint8 oneSecondTrigger         = FALSE;

      uint8 displayErrorOnce         = FALSE;

      int   rtc_configured           = FALSE ;

       

      volatile int      g_redraw     = TRUE ;

      volatile uint32_t g_tick_count = ZERO ;

      volatile int      sec_flag     = FALSE;

      volatile int      acc_flag     = FALSE ;

      volatile int      temp_flag    = FALSE ;

      volatile int      light_flag   = FALSE ;

       

      char *temp_title    = "Temperature: " ;

      char *amb_title     = "Ambient Light: " ;

      char *acc_title     = "Acc:" ;

      char *accx_title    = "X: " ;

      char *accy_title    = "Y: " ;

      char *accz_title    = "Z: " ;

      int  temp_title_len = ZERO ;

      int  amb_title_len  = ZERO ;

      int  acc_title_len  = ZERO ;

      int  accx_title_len = ZERO ;

      int  accy_title_len = ZERO ;

      int  accz_title_len = ZERO ;

       

      void draw_frame(void)

      {

          splash("CY8CKIT-044 Sensor Test") ;

          locate(LOC_TEMP_X, LOC_TEMP_Y) ;

          print(temp_title) ;

          temp_title_len = strlen(temp_title) ;

          locate(LOC_AMB_X, LOC_AMB_Y) ;

          print(amb_title) ;

          amb_title_len = strlen(amb_title) ;

          locate(LOC_ACC_X, LOC_ACC_Y) ;

          print(acc_title) ;

          acc_title_len = strlen(acc_title) ;

          locate(LOC_ACCX_X, LOC_ACC_Y) ;

          print(accx_title) ;

          accx_title_len = strlen(accx_title) ;

          locate(LOC_ACCY_X, LOC_ACC_Y) ;

          print(accy_title) ;

          accy_title_len = strlen(accy_title) ;

          locate(LOC_ACCZ_X, LOC_ACC_Y) ;

          print(accz_title) ;

          accz_title_len = strlen(accz_title) ;

      }

       

      int find_empty_slot(void)

      {

          int result = -1 ;

          uint32_t i ;

          for (i = 0 ; i < CY_SYS_SYST_NUM_OF_CALLBACKS ; i++ ) {

              if (CySysTickGetCallback(i) == NULL) {

                  result = i ;

                  break ;

              }

          }

          return(result) ;

      }

       

      void do_acc(void)

      {

      /* Dummy variable to read the interrupt release register of accelerometer. */

      uint8 dummy = ZERO;

        

          if (accRequest == TRUE && acclerometer_configured == TRUE) {

      accRequest = FALSE;

       

       

      /* Read the accelerometer data and update the global variables. */

      ReadAccelerometer(&x_dirMovement, &y_dirMovement, &z_dirMovement);

       

       

      /* Read interrupt release register to clear the latched interrupt. */

      Accelerometer_RegRead(ACC_INT_REL, &dummy);

          }

          locate(LOC_ACCX_X + accx_title_len, LOC_ACC_Y) ;

          snprintf(str, STR_BUF_LEN, "%5d", x_dirMovement) ;

          print(str) ;

          locate(LOC_ACCY_X + accy_title_len, LOC_ACC_Y) ;  

          snprintf(str, STR_BUF_LEN, "%5d", y_dirMovement) ;

          print(str) ;  

          locate(LOC_ACCZ_X + accz_title_len,LOC_ACC_Y) ;  

          snprintf(str, STR_BUF_LEN, "%5d ", z_dirMovement) ;

          print(str) ;

      }

       

      void do_temp(void)

      {

          /* Local Variables */

      uint8 tempError = FALSE;

      int16 temperatureReturnVal = ZERO;

        

      /* Check if temperature measurement is complete. */

      tempError = Temperature_Sense_ConversionStatus();

       

       

      /* If conversion is complete, update the temperature variable. */

      if((tempError & Temperature_Sense_STATUS_COMPLETE) == Temperature_Sense_STATUS_COMPLETE) {

      /* Read the temperature value. */

      temperatureReturnVal = Temperature_Sense_GetTemperature(DEFAULT_SENSOR);

       

       

      /* Temperature measured is in 1/100th of a degree Celsius.

      * Scale the value for comfortable viewing on UART. */

      temperatureInteger = temperatureReturnVal/DIVISOR_HUNDRED;

       

       

      /* Find the fractional part of temperature data for logging in the F-RAM. */

      if(temperatureReturnVal < ZERO) {

      temperatureFractional = DIVISOR_HUNDRED - temperatureReturnVal%DIVISOR_HUNDRED;

      } else {

      temperatureFractional = temperatureReturnVal%DIVISOR_HUNDRED;

      }

       

       

      /* Trigger next conversion when the current conversion is complete. */

      Temperature_Sense_Trigger();

      }

        

          locate(LOC_TEMP_X + temp_title_len, LOC_TEMP_Y) ;

          snprintf(str, STR_BUF_LEN, "%d.%d ", temperatureInteger, temperatureFractional) ;

          print(str) ;

      }

       

      void do_light(void)

      {

          locate(LOC_AMB_X + amb_title_len, LOC_AMB_Y) ;

          snprintf(str, STR_BUF_LEN, "%hd ", ambientLight) ;

          print(str) ;

      }

       

      void update_time(void)

      {

          locate(LOC_DATE_X, LOC_DATE_Y) ;

          print_date() ;

          print(" ") ;

          print_time() ;

          print(" ") ;

      }

       

      int main(void)

      {

          Initialize_Project() ;

               

          for(;;) {

              if (g_redraw) {

                  draw_frame() ;

                  g_redraw = FALSE ;

              }

              if (acc_flag) {

                  do_acc() ;

                  acc_flag = FALSE ;

              }

              if (temp_flag) {

                  do_temp() ;

                  temp_flag = FALSE ;

              }

              if (light_flag) {

                  do_light() ;

                  light_flag = FALSE ;

              }

              if (sec_flag) {

                  update_time() ;

                  sec_flag = 0 ;

              } 

          }

      }

       

      /*******************************************************************************

      * Function Name: Initialize_Project

      ********************************************************************************

      * Summary:

      *  Starts and initializes all the Components in the project. Enables

         global interrupt.

      *

      * Parameters:

      *  void

      *

      * Return:

      *  void

      *

      *******************************************************************************/

      void Initialize_Project(void)

      {

          int sys_tick_slot = 0 ;

        

      /* Enable global interrupt. */

      CyGlobalIntEnable;

       

      /* Start the Opamp hardware. */

      Opamp_Start();

       

      /* Enable and start ADC block. */

      ADC_Start();

       

      /* Enable the DMA Component. This API also sets the

      * source and destination addresses. */

      DMA_Start((void *)ADC_SAR_CHAN0_RESULT_PTR, (void *)&ambientLight);

       

      /* Start ADC conversions. */

      ADC_StartConvert();

       

      /* Enable and start accelerometer I2C block. */

      I2C_Start();

       

      /* Enable the interrupt from accelerometer. */

      isr_Accelerometer_Interrupt_StartEx(Accelerometer_Interrupt);

       

      /* Start the TMP05 temperature sensor Component. */

      Temperature_Sense_Start();

       

      /* Trigger the temperature sensor Component to start measurement. */

      Temperature_Sense_Trigger();

       

      /* Enable and start UART communication block. */

          tty_init() ;

       

      /* Wait for 50ms for the accelerometer to start up. */

      CyDelay(ACC_STARTUP_TIME);

        

          sys_tick_slot = find_empty_slot() ;

          if (sys_tick_slot < 0) {

              print("Sorry No empty SysTick Slot available\n\r") ;

              while(1) { } /* halting here */

          } else {

              CySysTickStart() ;

              CySysTickSetCallback(sys_tick_slot, SysTick_ISR) ;

          }

        

          /* Initialize the accelerometer after a self-test. */

      InitializeAccelerometer();

        

          sw2_int_ClearPending() ;

          sw2_int_StartEx(SW2_Pressed) ;

        

          cls() ;

          setup_time() ;

      }

       

      CY_ISR(Accelerometer_Interrupt)

      {

          accRequest = TRUE;

      Pin_Accelerometer_Interrupt_ClearInterrupt();

      }

       

      CY_ISR_PROTO(SW2_Pressed)

      {

          g_redraw = TRUE ;

        

          SW2_ClearInterrupt() ;

      }

       

      CY_ISR(SysTick_ISR)

      {

          g_tick_count++ ;

          if ((g_tick_count % 100) == 0) { /* 0.1 sec */

              acc_flag = TRUE ;

              if ((g_tick_count % 1000) == 0) { /* 1 sec */

                  sec_flag   = TRUE ;

                  light_flag = TRUE ;

                  temp_flag  = TRUE ;

                  g_tick_count = 0 ;

              }

          }

      }

      ========================

       

      Tera Term output / Tera Term 出力

       

      When the program starts, it asks for date and time.

      起動すると、日付と時間の入力が要求されます。

      006-startup.JPG

      When date and time were given, program starts polling the sensor(s)

      日時の設定が終わるとプログラムは各センサの値を表示します。

      007-running.JPG

      But as the program only rewrites the value, if you scroll or resize the window, titles will be lost.

      プログラムは値のみアップデートしていますので、ターミナルをスクロールしたり

      リサイズしたりすると値のタイトルが消えてしまいます。

      008-screen-broken.JPG

       

      Push SW2 to redraw the titles.

      その場合には、SW2 を押すとタイトルが再表示されます。

      009-frame-drew.JPG

       

      moto

      19-Aug-2020 Edited to correct some English.