- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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,
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Tera Term log
pins
CY8CKIT-044
CY8CKIT-046
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
pins
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
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Tera Term log
pins
CY8CKIT-044
CY8CKIT-046
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