Code Examples Forum Discussions
Share a sample project which realized simple touch gestures (click, double-click, left flick, right flick) detection on a touch slider, project is created based on CY8CKIT-145 DVK.
Note: flick = touch down+fast move+lift off
Show Less
There was a post just recently by a user wanting to driver 3 digits of a 7-segment LED on a PSoC6 device.
There is a component to driver multiple segments (7,14 and 16) and multiple digits on the PSoC3 and PSoC5.
Sadly, this component was not available for the PSoC6.
Here is a project to drive 4 digits of a 7-segment LED display for the PSoC6. It implements most of the API calls for the PSoC3/PSoC5 component and is configured as 7-segment drive only.
This implementation differs from the Cypress component version in that:
- It is not a component. This requires copying the LED_7seg directory to the user's project directory. Then LED_7seg directory needs to be added in the "Build/Compiler/Additional Include Directories" for the project.
- It is intended as a 4 digit 7-segment LED display driver. Elements in the TopDesign can easily be removed to support less digits or added to supportmore digits.
- It is a 7-segment implementation only. 14-segment and 16-segment implementation code has been removed from LED_7seg.c
- This implementation does NOT use DMA resources.
- The refresh rate is fixed at 250 Hz. However, this is easily changed by adjusting the CMN_clk component value.
- The Segment drive is active HIGH and the common drive is active HIGH (going to the NPN transistors which invert the commons to an active LOW drive).
- Brightness control is NOT implemented.
- Most of the API calls of the Cypress component are implemented for 7-segments.
The following API calls are not implemented and will yield a compile error if called.
- void LED_7seg_Write14SegNumberDec(int32 number, uint8 position, uint8 digits, uint8 alignment);
- void LED_7seg_Write14SegNumberHex(uint32 number, uint8 position, uint8 digits, uint8 alignment);
- void LED_7seg_WriteString14Seg(char8 const character[], uint8 position);
- void LED_7seg_PutChar14Seg(char8 character , uint8 position);
- void LED_7seg_Write14SegDigitDec(uint8 digit, uint8 position);
- void LED_7seg_Write14SegDigitHex(uint8 digit, uint8 position);
- void LED_7seg_Write16SegNumberDec(int32 number, uint8 position, uint8 digits, uint8 alignment);
- void LED_7seg_Write16SegNumberHex(uint32 number, uint8 position, uint8 digits, uint8 alignment);
- void LED_7seg_WriteString16Seg(char8 const character[], uint8 position);
- void LED_7seg_PutChar16Seg(char8 character , uint8 position);
- void LED_7seg_Write16SegDigitDec(uint8 digit, uint8 position);
- void LED_7seg_Write16SegDigitHex(uint8 digit, uint8 position);
- uint16 LED_7seg_EncodeNumber14Seg(uint8 number);
- uint16 LED_7seg_EncodeChar14Seg(char8 input);
- uint16 LED_7seg_EncodeNumber16Seg(uint8 number);
- uint16 LED_7seg_EncodeChar16Seg(char8 input);
- void LED_7seg_SetBrightness(uint8 bright, uint8 position);
- uint8 LED_7seg_GetBrightness(uint8 position);
The file LED_7seg_Unit_Tests.c is supplied ONLY as test vectors to unit test this implementation. This file can be removed from the project.
To use the API calls supported refer to the component datasheet for the 4 Digit 7-segment LED display driver.
This implementation can be constructed as a component for PSoC Creator if the demand is sufficient. ModusToolbox doesn't directly* support UDBs or components at this time. With some effort, a ModusToolbox equivalent can be constructed.
With Cypress' permission, I can be convinced to modify their component to include a PSoC6-specific implementation that should be able to support 14- and 16-segments.
* ModusToolbox does not directly support UDBs for those PSoCs that have them. There is a utility (UDBport) available from an advance PSoC user (RoNo_264271 ) that can port a Creator UDB design to the ModusToolbox. You can find further information about this tool at this link: Re: How do I create a custom UDB solution in the Modus toolbox?
Project Requirements:
- This project is originally built with the PsoC6 used in the CY8CKIT-062-BLE. Other PSoC6s and kits that support UDBs can be used.
- PSoC Creator 4.3. It should be able to run on earlier version but it has not been tested.
- The TopDesign includes NPN transistors to drive the commons to the digits. This is HIGHLY recommended due to the combined current if all segments are turned on.
- The segments are being directly driven by the PSoC. I recommend that the maximum drive current be limited to 8mA. If more current is needed, I recommend that the segments be buffered using PNP transistors.
Len
Show LessThe CharLCD_I2C component provides an interface with the PCF8574AT I2C PC Board connected to the Industry Standard HD44780 LCD Controller (running in 4-bit mode) using only 2 I/O pins, SDA and SCL pins. The CharLCD_I2C component requires an I2C Master component to provide the I/O. For the PSoC 4 use the I2C (SBC mode)[v3.2] Master Component. For the PSoC 3 and PSoC 5 use the I2C Master (Fixed Function)[v3.50] Component. The instance name of the I2C Master Component needs to be I2C_ 'instance name of the CharLCD_I2C component'. It has been tested and works with the PSoC 3, PSoC 4 and the PSoC 5 provided with the C8YC KIT-001.
Show LessAs a seasoned *nix hacker, I still can't live without command line interface (CLI) type program(s).
After posting a response to such a question today, I realized that I may post this here, too.
Re: I want the program won't run until I type in a character into UART.
Although I still miss scanf(), printf(), I have learned that blocking type functions are not suitable for an embedded program.
And after writing a few dozens of sample programs, I noticed that I have written same function(s) again and again.
(Well, getting older may force you to repeat things...)
Namely for my type of sample programs, I wrote many
get_string() (or get_line()) /* fill str[] up to receiving delimiter or the buffer is full */
prompt() /* show a prompt "> " */
splash(char *program_name) /* print the name (and time) of the program, so that I can identify what it was */
print(char *str) ; /* to hide difference between UART_UartPutString() and UART_PutString() ... */
So I decided to make them my library so that I can save some time (but same time, lose warming up time)
schematic (PSoC 4)
schematic (PSoC 5LP)
tty_utils.h
=========================
#ifndef _TTY_UTILS_H_
#define _TTY_UTILS_H_
#include "project.h"
void tty_init(void) ;
void print(char *str) ;
/**
* get_string()
* check if we received any char via tty
* and store the char into str[]
* when a delimiter is detected
* it puts NULL at the current end of str[] and return the length of str
* if the length is exceeding that STR_BUF_LEN,
* it puts NULL at the end of str[] and returns -1
*/
int get_string(void) ;
/**
* get_line()
* similar with get_string() but only accept CR or LF for delimiter
* so you can get a line up to the STR_BUF_LEN
*/
int get_line(void) ;
void splash(char *prog_name) ;
void prompt(void) ;
extern char str[] ; /* print buf */
#endif /* _TTY_UTILS_H_ */
=========================
tty_utils.c (PSoC 4 (CY8CKIT-044))
=========================
#include "project.h"
#include "stdio.h"
#include "tty_utils.h"
#define TAB '\t'
#define SPACE ' '
#define CR '\r'
#define LF '\n'
#define RX_BUF_LEN 128
#define STR_BUF_LEN 64
volatile char rx_buf[RX_BUF_LEN] ;
volatile int rx_write_index = 0 ;
int rx_read_index = 0 ;
int str_buf_index = 0 ;
char str[STR_BUF_LEN + 1] ;
static inline int is_delimiter(char c)
{
return((c == TAB)||(c == SPACE)||(c == CR)||(c == LF)) ;
}
static inline int is_eol(char c)
{
return((c == CR) || (c == LF)) ;
}
void print(char *str)
{
UART_UartPutString(str) ; /* for PSoC 4 */
}
CY_ISR(tty_rx_isr)
{
if (UART_SpiUartGetRxBufferSize()) {
rx_buf[rx_write_index] = UART_UartGetByte() ;
rx_write_index = (rx_write_index + 1) % RX_BUF_LEN ;
}
UART_ClearRxInterruptSource(UART_INTR_RX_NOT_EMPTY) ;
}
void splash(char *prog_name)
{
if (prog_name && *prog_name) {
print(prog_name) ;
}
print(" (") ;
print(__DATE__) ;
print(" ") ;
print(__TIME__) ;
print(")\n") ;
}
void prompt(void)
{
print("> ") ;
}
void tty_init(void)
{
tty_rx_int_ClearPending() ;
UART_ClearRxInterruptSource(UART_INTR_RX_NOT_EMPTY) ;
tty_rx_int_StartEx(tty_rx_isr) ;
UART_Start() ;
}
int get_string(void)
{
int result = 0 ;
if (rx_read_index != rx_write_index) {
if (is_delimiter(rx_buf[rx_read_index])) {
str[str_buf_index] = (char)NULL ;
result = str_buf_index ;
str_buf_index = 0 ;
} else {
str[str_buf_index++] = rx_buf[rx_read_index] ;
if (str_buf_index >= STR_BUF_LEN) {
str[STR_BUF_LEN] = (char)NULL ;
str_buf_index = 0 ;
result = -1 ; /* str buf overflow */
}
}
rx_read_index = (rx_read_index + 1) % RX_BUF_LEN ;
}
return( result ) ;
}
int get_line(void)
{
int result = 0 ;
if (rx_read_index != rx_write_index) {
if (is_eol(rx_buf[rx_read_index])) {
str[str_buf_index] = (char)NULL ;
result = str_buf_index ;
str_buf_index = 0 ;
} else {
str[str_buf_index++] = rx_buf[rx_read_index] ;
if (str_buf_index >= STR_BUF_LEN) {
str[STR_BUF_LEN] = (char)NULL ;
str_buf_index = 0 ;
result = -1 ; /* str buf overflow */
}
}
rx_read_index = (rx_read_index + 1) % RX_BUF_LEN ;
}
return( result ) ;
}
=========================
tty_utils.c (PSoC 5LP (CY8CKIT-059))
=========================
#include "project.h"
#include "stdio.h"
#include "tty_utils.h"
#define TAB '\t'
#define SPACE ' '
#define CR '\r'
#define LF '\n'
#define RX_BUF_LEN 128
#define STR_BUF_LEN 64
volatile char rx_buf[RX_BUF_LEN] ;
volatile int rx_write_index = 0 ;
int rx_read_index = 0 ;
int str_buf_index = 0 ;
char str[STR_BUF_LEN + 1] ;
static inline int is_delimiter(char c)
{
return((c == TAB)||(c == SPACE)||(c == CR)||(c == LF)) ;
}
static inline int is_eol(char c)
{
return((c == CR) || (c == LF)) ;
}
void print(char *str)
{
UART_PutString(str) ; /* for PSoC 5LP */
}
CY_ISR(tty_rx_isr)
{
if (UART_GetRxBufferSize()) {
rx_buf[rx_write_index] = UART_GetByte() ;
rx_write_index = (rx_write_index + 1) % RX_BUF_LEN ;
}
tty_rx_int_ClearPending() ;
}
void splash(char *prog_name)
{
if (prog_name && *prog_name) {
print(prog_name) ;
}
print(" (") ;
print(__DATE__) ;
print(" ") ;
print(__TIME__) ;
print(")\n") ;
}
void prompt(void)
{
print("> ") ;
}
void tty_init(void)
{
tty_rx_int_ClearPending() ;
tty_rx_int_StartEx(tty_rx_isr) ;
UART_Start() ;
}
int get_string(void)
{
int result = 0 ;
if (rx_read_index != rx_write_index) {
if (is_delimiter(rx_buf[rx_read_index])) {
str[str_buf_index] = (char)NULL ;
result = str_buf_index ;
str_buf_index = 0 ;
} else {
str[str_buf_index++] = rx_buf[rx_read_index] ;
if (str_buf_index >= STR_BUF_LEN) {
str[STR_BUF_LEN] = (char)NULL ;
str_buf_index = 0 ;
result = -1 ; /* str buf overflow */
}
}
rx_read_index = (rx_read_index + 1) % RX_BUF_LEN ;
}
return( result ) ;
}
int get_line(void)
{
int result = 0 ;
if (rx_read_index != rx_write_index) {
if (is_eol(rx_buf[rx_read_index])) {
str[str_buf_index] = (char)NULL ;
result = str_buf_index ;
str_buf_index = 0 ;
} else {
str[str_buf_index++] = rx_buf[rx_read_index] ;
if (str_buf_index >= STR_BUF_LEN) {
str[STR_BUF_LEN] = (char)NULL ;
str_buf_index = 0 ;
result = -1 ; /* str buf overflow */
}
}
rx_read_index = (rx_read_index + 1) % RX_BUF_LEN ;
}
return( result ) ;
}
=========================
main.c as a sample program
=========================
#include "project.h"
#include "stdio.h"
#include "tty_utils.h"
void init_hardware(void)
{
tty_init() ;
CyGlobalIntEnable; /* Enable global interrupts. */
}
int main(void)
{
init_hardware() ;
splash("tty utils test") ;
prompt() ;
for(;;) {
// if (get_string() > 0) { // got a string
if (get_line()) { // got a line
print("Got: ") ;
print(str) ;
print("\n") ;
prompt() ;
}
}
}
=========================
moto
Show LessManchester Encoded Data
There are two Manchester encoding standard, depending on the data available in the first and second halves of bit time. Manchester encoded signal as per G.E. Thomas, a ‘0’ is transmitted by low-to-high transition and a ‘1’ is expressed by high-to-low transition. This is represented in Figure 1: Manchester Ecoded Data (As per G.E. Thomas). Manchester encoded signal as per IEEE 802.3 is the opposite of G.E. Thomas, where a ‘0’ is transmitted by high-to-low transition. In this document, G.E. Thomas standard has been used (Figure 2: An example of Manchester encoding (Source: https://en.wikipedia.org/wiki/Manchester_code).
Figure 1: Manchester Ecoded Data (As per G.E. Thomas)
Figure 2: An example of Manchester encoding (Source: https://en.wikipedia.org/wiki/Manchester_code)
Manchester Encoder Implementation
For Manchester Encoder, user needs to synchronize the clock edges and data input edges. SPI master provides the slave synchronization clock input to the device. Once you perform XOR of MOSI and SCLK outputs from SPI master, you can easily implement a Manchester Encoder as per G.E. Thomas standard.
Manchester Decoder Implementation
If a delay of three-fourths bit time is triggered by the incoming mid-bit transition, the value captured at the end of the delay tells the next bit value (Figure 5: Manchester Decoder Outputs).
Figure 5: Manchester Decoder Outputs (Source AN2358)
By using PWM and SmartIO we can easily captures input encoded data after ¾ bit time from the mid-bit transition and realize Manchester Decode.
Attached projects:
Encoder_PSoC4200M_AddSync_1K/ Encoder_PSoC4200M_AddSync_1K can generate 1K/4M data rate output. You can adjust the actual data rate of SPIM component for customize data rate.
SmartIO_Based_ManchesterDecoder_1K/ SmartIO_Based_ ManchesterDecoder_4M, can decode 1K/4M data rate Manchester data stream. You can adjust the NCO_Clk frequency and Compare value of NCO(PWM) component for customize data rate.
Show LessHi,
Provided below is a custom component, Pins Annotation v0.0, which facilitates PSoC pins configuration. It identifies terminals with direct access to PSoC internal hardware and graphically displays pin configuration. The Pins Annotation component can be used in conjunction with PSoC Annotation Library, as well as Cypress stock annotation components.
Attached archive contains Pins Annotation component library, a Datasheet and installation instructions. Upon installation it will show up in the folder:
/Community/Off-Chip/Annotation Library/Pins/
Demo project is provided.
The component provided as-is, no liabilities. It is free to use, modify and distribute.
regards,
odissey1
P.S. Demo projects use optional annotation components (which are also provided here in Support_libs.zip):
PSoC Annotation Library: PSoC Annotation Library v1.0
QuadDec_SW: Quad Decoder with Button Switch component for rotary shaft encoders
Figure 1. Component appearance with various options enabled
Figure 2. Pins and Annotations appearance in various Digital Input modes.
Figure 3. Pin and Annotation appearances in multi-mode configurations.
Show Less
SmartIO can be used to expand single-channel PWM to multiple channels, it is easy to realize multiple channels Breathing LED control use similar design.
Attached sample projects shows you how to realize that.
Show Less
In CapSense component 'Inactive Sense Connection' parameter defined the status of sensor not being scanned, the option can be set to GND, Shield or High-Z. Once the parameter is set, it apply to all sensors. But sometimes, we want to be able to flexibly define the state of the inactive sensor according to our needs, for example, when scanning sensor0, i want sensor1 connect to shield and sensor2 connect to GND etc.
Attached project shows you how to flexibly define the state of the inactive sensor in firmware without change component generated source code.
Show LessPSoC4000/41XX/42XX/BLE/M/L family parts (PSoC4 none S series) use CSD_V1 CapSense IP, which supports both mutual cap and self cap sensing method. Enable mutual cap and self cap sensing method needs three modulation caps CINTA, CINTB and CMOD. If IO resources is tight in design,it is possible multiplexing CintA/B as Cmod Cap (parallel CintA anf CintB together and reuse the combined cap as CMOD cap).
Attached sample project shows you how to realize this function in firmware, without change any component generated source code.
Show Less