- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As 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
- Labels:
-
PSoC 345 LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A minor update
(1) cls() function added
(2) STR_BUF_LEN was moved from tty_utils.c to tty_utils.h
so that in the main body of the program we can do
snprintf(str, STR_BUF_LEN, "%d %s\n", ivalue, char_ptr) ;
(3) In the beginning of splash() cls() function was added.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Last night while I was debugging my MCU Tester
I was frustrated as it did not accept "Backspace"
MCU Tester, a Swiss Army Knife for PSoC (CY8CKIT-044 version)
For a very long time (years), I've been using my Tera Term with Local Echo (ON).
But recently while I was porting the TinyBasic, I came across with a Backspace process.
And with the CardKb, Backspace was working fine.
Tiny Basic for PSoC (CY8CKIT-044 / TSoC / CY8CKIT-059 / CY8CKIT-062-BLE)
Then why can't I do it with tty? ... It should be done if I turn off Local Echo.
So here it is, now "Backspace" works... sorry I must be slow.
moto