Application on PSoC 4200L

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
SoEL_4655151
Level 1
Level 1

Hi everybody,

I'm a beginner on PSoC development, and I have an application to do for my project, I have some questions to guide me:

The application has two operating modes: normal and low consumption.

After startup, the application directly enters normal mode. It switches to low consumption mode after pressing a button Switch SW1. It returns to normal mode after pressing the SW2 button. (On my card development PSoC 4200L I have two switches: SW1 for reset, and SW2 it's free and I don't know if possible to implement this function, What do you think, if you any suggestion feel free)

in low consumption mode, nothing happens.

in normal mode, here is what happens:

> an IDAC produces a fixed current, preconfigured, which passes through a resistance of 15 ohms. The voltage across its terminals is sent to the input of an AOP mounted as a non-inverting gain amplifier x2. The output voltage of this AOP must be equal to 1.65 V (it is, therefore, necessary to adjust the current of the IDAC according to the resistance and the gain).

> the output voltage of the AOP is converted by an ADC every 2 seconds and transmitted by UART to a PC

In this case, How can I configure the ADC SAR?

> an LED flashes every second to indicate that the PSoC is in normal mode.

In this part, I will use just a pin and led or I should use PWM components?

Thanks in advance,

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

__DATE__ and __TIME__ represents the time and date the project was compiled,

and it won't change during the run time.

So we need to use "RTC" to track the time.

And for the uart input, I utilized my tty_utils.

Re: tty_utils a utility sample for CLI type program

Anyway, I imitated your schematic and tried with CY8CKIT-044

and later ported the project to CY8CKIT-046 (4200L).

Note: Since I don't have CY8CKIT-046, I have not tested it with real hardware.

schematic

002-schematic.JPG

Tera Term log

001-TeraTerm-log.JPG

pins

CY8CKIT-044

003-pins.JPG

CY8CKIT-046

013-pins-046.JPG

main.c

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

#include "project.h"

#include "stdio.h"

#include "tty_utils.h"

#include "rtc_utils.h"

#define LED_ON  (0u)

#define LED_OFF (1u)

volatile int sw2_flag = 0 ;

volatile int adc_flag = 0 ;

CY_ISR(adc_isr)

{

    adc_flag = 1 ;

}

CY_ISR(sw2_isr)

{

    WakeUp_ClearInterrupt() ;

    isr_sw2wakeup_Disable() ;

    sw2_flag = 1 ;

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */   

    tty_init() ;

    PWM_LED_Start() ;

    Non_inverting_OpAmp_Start() ;

    IDAC_Start() ;

    isr_sw2wakeup_ClearPending() ;

    isr_sw2wakeup_StartEx(sw2_isr) ;

    ADC_Done_ClearPending() ;

    ADC_Done_StartEx(adc_isr) ;

    ADC_Start() ;

    PWM_ADC_Start() ;

}

void prepare_sleep(void)

{

    PWM_ADC_Stop() ;

    ADC_Stop() ;

    IDAC_Stop() ;

    Non_inverting_OpAmp_Stop() ;

    PWM_LED_Stop() ;

    PWM_LED_WriteCounter(0) ;

    LED_Write(LED_OFF) ;

    UART_Stop() ;

    isr_sw2wakeup_ClearPending() ;

    isr_sw2wakeup_Enable() ;

}

void prepare_wakeup(void)

{

    isr_sw2wakeup_ClearPending() ;

    isr_sw2wakeup_Enable() ;

   

    UART_Start() ;

    PWM_LED_WriteCounter(0) ;

    PWM_LED_Start() ;

    Non_inverting_OpAmp_Start() ;

    IDAC_Start() ;

    ADC_Start() ;

    PWM_ADC_WriteCounter(0) ;

    PWM_ADC_Start() ;

}

void sleep(void)

{

    print("Sleeping ... ") ;

    CyDelay(10) ;

    prepare_sleep() ;

    do {

        CySysPmDeepSleep();

    } while(sw2_flag == 0) ;

    sw2_flag = 0 ;

   

    // here we have already woken up

    prepare_wakeup() ;

    print("Woke up!\n\r") ;

}

void measure(void)

{

    uint16_t raw_count ;

    int16_t  mV ;

   

    raw_count = ADC_GetResult16(0) ;

    mV = ADC_CountsTo_mVolts(0, raw_count) ;

    snprintf(str, STR_BUF_LEN, "%d.%03d V\n\r",mV/1000, mV%1000) ;

    print_time() ;

    print(" ") ;

    print(str) ;

}

int main(void)

{

    init_hardware() ;

   

    splash("Sleep, IDAC, test CY8CKIT-046") ;

   

    setup_time() ;

    for(;;)

    {

        if (sw2_flag) {

            sw2_flag = 0 ;

            sleep() ;

        }

        if (adc_flag) {

            measure() ;

            adc_flag = 0 ;

        }

    }

}

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

rtc_utils.c

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

#include "project.h"

#include "stdio.h"

#include "tty_utils.h"

#include "rtc_utils.h"

#define WDT_EACH_1_SEC      (1000)

#define SYSTICK_EACH_10_HZ  (10u)

#define SYSTICK_RELOAD      (CYDEV_BCLK__SYSCLK__HZ / SYSTICK_EACH_10_HZ)

void SysTickIsrHandler(void)

{

    RTC_Update();

}

void print_time(void)

{

    char time_str[16] ;

    uint32_t time ;

   

    time = RTC_GetTime();

    /* Print Date and Time to UART */

    sprintf(time_str, "%02lu:%02lu:%02lu", RTC_GetHours(time), RTC_GetMinutes(time), RTC_GetSecond(time));

    print(time_str) ;

}

void print_date(void)

{

    char date_str[16] ;

    uint32_t date ;

   

    date = RTC_GetDate();

    sprintf(date_str, "%02lu/%02lu/%02lu", RTC_GetYear(date), RTC_GetMonth(date), RTC_GetDay(date));    

    print(date_str) ;

}

void setup_time(void)

{

    uint32_t year, month, day ;

    uint32_t hour, min, sec ;

    uint32_t input_time, input_date ;

   

    print("Enter date (YYYY/MM/DD) > ") ;

    while(get_line() == 0) { }

    sscanf(str, "%ld/%ld/%ld", &year, &month, &day) ;

    year  = RTC_ConvertDecToBCD(year) ;

    month = RTC_ConvertDecToBCD(month) ;

    day   = RTC_ConvertDecToBCD(day) ;

    input_date = ((uint32_t)(year  << RTC_YEAR_OFFSET)  | \

                  (uint32_t)(month << RTC_MONTH_OFFSET) | \

                  (uint32_t)(day   << RTC_DAY_OFFSET))  ;

   

    print("Enter time (hh:mm:ss) > ") ;

    while(get_line() == 0) { }

    sscanf(str, "%ld:%ld:%ld", &hour, &min, &sec) ;

    hour = RTC_ConvertDecToBCD(hour) ;

    min  = RTC_ConvertDecToBCD(min) ;

    sec  = RTC_ConvertDecToBCD(sec) ;

    input_time = ((uint32_t)(hour << RTC_HOURS_OFFSET)    | \

                  (uint32_t)(min  << RTC_MINUTES_OFFSET)  | \

                  (uint32_t)(sec  << RTC_SECONDS_OFFSET)) ;

   

    RTC_Start() ;

   

    RTC_SetDateAndTime(input_time, input_date) ;

   

    print("Time Set to: ") ;

    print_date() ;

    print(" ") ;

    print_time() ;

    print("\n\r") ;

}

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

moto

View solution in original post

0 Likes
3 Replies
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

There were two points I'd like to mention.

(1) Using SW1 (Reset) for application purpose may be impossible,

as it is connected to nRESET of the device, so I used SW2

for both entering and exiting the low-power mode.

(2) For 4200M, max current for a GPIO is 25mA, so if you connect a 16 Ohm it may damage the device.

And also, the maximum current the internal IDAC can supply is 612uA.

So I connected 4K (2K + 2K) externally to generate (about) 1.65V (note the current is very small).

So for your application, probably you need an external driver to drive 16 Ohm load.

Anyway, following is a sketch of mine.

I tried with CY8CKIT-044 (4200M) as I don't have a board with 4200L.

But I hope that if you change the device and pin assignment, probably program will work .

schematic

001-schematic.JPG

pins

002-pins.JPG

main.c

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

#include "project.h"

#include "stdio.h"

#define STR_LEN 32

char    str[STR_LEN+1] ;

void    print(char *str)

{

    UART_UartPutString(str) ;

}

void cls(void)

{

    print("\033c") ; /* reset */

    CyDelay(20) ;

    print("\033[2J") ; /* clear screen */

    CyDelay(20) ;

}

void splash(char *prog_name)

{

    cls() ;

    if (prog_name && *prog_name) {

        print(prog_name) ;

    }

    print(" (") ;

    print(__DATE__) ;

    print(" ") ;

    print(__TIME__) ;

    print(")\n") ;

}

#define LED_ON  (0u)

#define LED_OFF (1u)

volatile int sw2_flag = 0 ;

CY_ISR(sw2_isr)

{

    SW2_ClearInterrupt() ;

    sw2_flag = 1 ;

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */   

    LED_Write(LED_OFF) ;

    isr_sw2_int_ClearPending() ;

    isr_sw2_int_StartEx(sw2_isr) ;

    IDAC_Start() ;

    ADC_Start() ;

    UART_Start() ;

}

void sleep(void)

{

    print("Sleeping ... ") ;

    CyDelay(10) ;

    LED_Write(LED_OFF) ;

    UART_Stop() ;   

    IDAC_Stop() ;

    ADC_Stop() ;

    // CySysPmSleep();      // you can also try "sleep"

    CySysPmDeepSleep(); // I used  "deep sleep"

   

    // here we have already woken up

    SW2_ClearInterrupt() ;   

    ADC_Start() ;

    IDAC_Start() ;

    UART_Start() ;

    print("Woke up!\n\r") ;

}

void measure(void)

{

    uint16_t raw_count ;

    int16_t  mV ;

   

    ADC_StartConvert() ;

    ADC_IsEndConversion(ADC_WAIT_FOR_RESULT) ;

    raw_count = ADC_GetResult16(0) ;

    mV = ADC_CountsTo_mVolts(0, raw_count) ;

    snprintf(str, STR_LEN, "%d.%03d V\n\r",mV/1000, mV%1000) ;

    print(str) ;

}

int main(void)

{

    int count_500ms = 0 ;

    init_hardware() ;

   

    splash("PSoC 4 Sleep and IDAC/ADC test") ;

   

    for(;;)

    {

        if (sw2_flag) {

            sleep() ;

            count_500ms = 0 ;

            sw2_flag = 0 ;

        }

        if (count_500ms % 2) {

            LED_Write(LED_OFF) ;

        } else {

            LED_Write(LED_ON) ;

        }

        if (count_500ms == 3) {

            measure() ;

        }

        count_500ms = (count_500ms + 1) % 4 ; // 0, 1, 2, 3, 0, 1...

        CyDelay(500) ;

    }

}

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

Tera Term log

000-TeraTerm-log.JPG

One last thing!

I used "CyDelay(500)" to make a 0.5 sec delay, but timing error will be accumulated in the long run.

So if you'd like to have precise timing, please use "SysTick" or other hardware timer.

moto

0 Likes

Hi,

Sorry I was a little late to answer you,

First of all, thank you for the application, I really appreciated.

Since I have a PSoC 4200L development board and I am limited in the number of switches I tried to modify the specifications.

For this, here is the new application

The application has two operating modes: Low consumption and normal mode

So it will be done through the switch SW2

in low consumption mode, nothing happens.

in normal mode, here is what happens:

> an IDAC produces a fixed current, preconfigured, which passes through a resistance of 10 ohms. The voltage across its terminals is sent to the input of an AOP follower. The output voltage of this AOP must be equal to 1.65 V (it is, therefore, necessary to adjust the current of the IDAC according to the resistance).

> the output voltage of the AOP is converted by an ADC every 2 seconds and transmitted by UART to a PC

In this case, I use the PWM signal

> an LED flashes every second to indicate that the PSoC is in normal mode.

In this part, I use a PWM two

The app adds another RTC component that displays the date and time

is this function dedicated for the RTC component ?

void splash(char *prog_name)

{

    cls() ;

    if (prog_name && *prog_name) {

        print(prog_name) ;

    }

    print(" (") ;

    print(__DATE__) ;

    print(" ") ;

    print(__TIME__) ;

    print(")\n") ;

}

Schematic on PSoC creator:

Thanks in advance

0 Likes
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

__DATE__ and __TIME__ represents the time and date the project was compiled,

and it won't change during the run time.

So we need to use "RTC" to track the time.

And for the uart input, I utilized my tty_utils.

Re: tty_utils a utility sample for CLI type program

Anyway, I imitated your schematic and tried with CY8CKIT-044

and later ported the project to CY8CKIT-046 (4200L).

Note: Since I don't have CY8CKIT-046, I have not tested it with real hardware.

schematic

002-schematic.JPG

Tera Term log

001-TeraTerm-log.JPG

pins

CY8CKIT-044

003-pins.JPG

CY8CKIT-046

013-pins-046.JPG

main.c

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

#include "project.h"

#include "stdio.h"

#include "tty_utils.h"

#include "rtc_utils.h"

#define LED_ON  (0u)

#define LED_OFF (1u)

volatile int sw2_flag = 0 ;

volatile int adc_flag = 0 ;

CY_ISR(adc_isr)

{

    adc_flag = 1 ;

}

CY_ISR(sw2_isr)

{

    WakeUp_ClearInterrupt() ;

    isr_sw2wakeup_Disable() ;

    sw2_flag = 1 ;

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */   

    tty_init() ;

    PWM_LED_Start() ;

    Non_inverting_OpAmp_Start() ;

    IDAC_Start() ;

    isr_sw2wakeup_ClearPending() ;

    isr_sw2wakeup_StartEx(sw2_isr) ;

    ADC_Done_ClearPending() ;

    ADC_Done_StartEx(adc_isr) ;

    ADC_Start() ;

    PWM_ADC_Start() ;

}

void prepare_sleep(void)

{

    PWM_ADC_Stop() ;

    ADC_Stop() ;

    IDAC_Stop() ;

    Non_inverting_OpAmp_Stop() ;

    PWM_LED_Stop() ;

    PWM_LED_WriteCounter(0) ;

    LED_Write(LED_OFF) ;

    UART_Stop() ;

    isr_sw2wakeup_ClearPending() ;

    isr_sw2wakeup_Enable() ;

}

void prepare_wakeup(void)

{

    isr_sw2wakeup_ClearPending() ;

    isr_sw2wakeup_Enable() ;

   

    UART_Start() ;

    PWM_LED_WriteCounter(0) ;

    PWM_LED_Start() ;

    Non_inverting_OpAmp_Start() ;

    IDAC_Start() ;

    ADC_Start() ;

    PWM_ADC_WriteCounter(0) ;

    PWM_ADC_Start() ;

}

void sleep(void)

{

    print("Sleeping ... ") ;

    CyDelay(10) ;

    prepare_sleep() ;

    do {

        CySysPmDeepSleep();

    } while(sw2_flag == 0) ;

    sw2_flag = 0 ;

   

    // here we have already woken up

    prepare_wakeup() ;

    print("Woke up!\n\r") ;

}

void measure(void)

{

    uint16_t raw_count ;

    int16_t  mV ;

   

    raw_count = ADC_GetResult16(0) ;

    mV = ADC_CountsTo_mVolts(0, raw_count) ;

    snprintf(str, STR_BUF_LEN, "%d.%03d V\n\r",mV/1000, mV%1000) ;

    print_time() ;

    print(" ") ;

    print(str) ;

}

int main(void)

{

    init_hardware() ;

   

    splash("Sleep, IDAC, test CY8CKIT-046") ;

   

    setup_time() ;

    for(;;)

    {

        if (sw2_flag) {

            sw2_flag = 0 ;

            sleep() ;

        }

        if (adc_flag) {

            measure() ;

            adc_flag = 0 ;

        }

    }

}

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

rtc_utils.c

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

#include "project.h"

#include "stdio.h"

#include "tty_utils.h"

#include "rtc_utils.h"

#define WDT_EACH_1_SEC      (1000)

#define SYSTICK_EACH_10_HZ  (10u)

#define SYSTICK_RELOAD      (CYDEV_BCLK__SYSCLK__HZ / SYSTICK_EACH_10_HZ)

void SysTickIsrHandler(void)

{

    RTC_Update();

}

void print_time(void)

{

    char time_str[16] ;

    uint32_t time ;

   

    time = RTC_GetTime();

    /* Print Date and Time to UART */

    sprintf(time_str, "%02lu:%02lu:%02lu", RTC_GetHours(time), RTC_GetMinutes(time), RTC_GetSecond(time));

    print(time_str) ;

}

void print_date(void)

{

    char date_str[16] ;

    uint32_t date ;

   

    date = RTC_GetDate();

    sprintf(date_str, "%02lu/%02lu/%02lu", RTC_GetYear(date), RTC_GetMonth(date), RTC_GetDay(date));    

    print(date_str) ;

}

void setup_time(void)

{

    uint32_t year, month, day ;

    uint32_t hour, min, sec ;

    uint32_t input_time, input_date ;

   

    print("Enter date (YYYY/MM/DD) > ") ;

    while(get_line() == 0) { }

    sscanf(str, "%ld/%ld/%ld", &year, &month, &day) ;

    year  = RTC_ConvertDecToBCD(year) ;

    month = RTC_ConvertDecToBCD(month) ;

    day   = RTC_ConvertDecToBCD(day) ;

    input_date = ((uint32_t)(year  << RTC_YEAR_OFFSET)  | \

                  (uint32_t)(month << RTC_MONTH_OFFSET) | \

                  (uint32_t)(day   << RTC_DAY_OFFSET))  ;

   

    print("Enter time (hh:mm:ss) > ") ;

    while(get_line() == 0) { }

    sscanf(str, "%ld:%ld:%ld", &hour, &min, &sec) ;

    hour = RTC_ConvertDecToBCD(hour) ;

    min  = RTC_ConvertDecToBCD(min) ;

    sec  = RTC_ConvertDecToBCD(sec) ;

    input_time = ((uint32_t)(hour << RTC_HOURS_OFFSET)    | \

                  (uint32_t)(min  << RTC_MINUTES_OFFSET)  | \

                  (uint32_t)(sec  << RTC_SECONDS_OFFSET)) ;

   

    RTC_Start() ;

   

    RTC_SetDateAndTime(input_time, input_date) ;

   

    print("Time Set to: ") ;

    print_date() ;

    print(" ") ;

    print_time() ;

    print("\n\r") ;

}

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

moto

0 Likes