lab05 ready
This commit is contained in:
parent
6efb7921ff
commit
e991f970a8
149
src/cli_microrl.c
Normal file
149
src/cli_microrl.c
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include "../lib/hd44780_111/hd44780.h"
|
||||||
|
#include "../lib/andygock_avr-uart/uart.h"
|
||||||
|
#include "hmi_msg.h"
|
||||||
|
#include "print_helper.h"
|
||||||
|
#include "cli_microrl.h"
|
||||||
|
|
||||||
|
typedef struct cli_cmd {
|
||||||
|
PGM_P cmd;
|
||||||
|
PGM_P help;
|
||||||
|
void (*func_p)();
|
||||||
|
const uint8_t func_argc;
|
||||||
|
} cli_cmd_t;
|
||||||
|
|
||||||
|
|
||||||
|
const cli_cmd_t cli_cmds[] = {
|
||||||
|
{help_cmd, help_help, cli_print_help, 0},
|
||||||
|
{ver_cmd, ver_help, cli_print_ver, 0},
|
||||||
|
{ascii_cmd, ascii_help, cli_print_ascii_tbls, 0},
|
||||||
|
{month_cmd, month_help, cli_handle_month, 1}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void cli_print(const char *str)
|
||||||
|
{
|
||||||
|
printf("%s", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char cli_get_char(void)
|
||||||
|
{
|
||||||
|
if (uart0_peek() != UART_NO_DATA) {
|
||||||
|
return uart0_getc() & UART_STATUS_MASK;
|
||||||
|
} else {
|
||||||
|
return 0x00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cli_print_help(const char *const *argv)
|
||||||
|
{
|
||||||
|
(void) argv;
|
||||||
|
putc('\n', stdout);
|
||||||
|
printf_P(PSTR(CLI_HELP_MSG "\n"));
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < NUM_ELEMS(cli_cmds); i++) {
|
||||||
|
printf_P(cli_cmds[i].cmd);
|
||||||
|
printf_P(PSTR(" : "));
|
||||||
|
printf_P(cli_cmds[i].help);
|
||||||
|
putc('\n', stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void print_version(FILE *stream)
|
||||||
|
{
|
||||||
|
// Print program and libc versions
|
||||||
|
fprintf_P(stream, PSTR(PROG_VERSION "\n"),
|
||||||
|
PSTR(GIT_DESCR), PSTR(__DATE__), PSTR(__TIME__));
|
||||||
|
fprintf_P(stream, PSTR(LIBC_VERSION "\n"),
|
||||||
|
PSTR(__AVR_LIBC_VERSION_STRING__),
|
||||||
|
PSTR(__VERSION__));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cli_print_ver(const char *const *argv)
|
||||||
|
{
|
||||||
|
(void) argv;
|
||||||
|
putc('\n', stdout);
|
||||||
|
print_version(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cli_print_ascii_tbls(const char *const *argv)
|
||||||
|
{
|
||||||
|
(void) argv;
|
||||||
|
putc('\n', stdout);
|
||||||
|
// ASCII table print
|
||||||
|
print_ascii_tbl(stdout);
|
||||||
|
unsigned char ascii[128];
|
||||||
|
for (unsigned char i = 0; i < sizeof(ascii); i++) {
|
||||||
|
ascii[i] = i;
|
||||||
|
}
|
||||||
|
print_for_human(stdout, ascii, sizeof(ascii));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cli_handle_month(const char *const *argv)
|
||||||
|
{
|
||||||
|
putc('\n', stdout);
|
||||||
|
lcd_goto(0x40); // Got to the beginning of the next line
|
||||||
|
char spaces_to_print = 16;
|
||||||
|
fprintf(stderr, "arg: %s\n", argv[1]);
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
if (!strncmp_P(argv[1],
|
||||||
|
(PGM_P)pgm_read_word(&months[i]),
|
||||||
|
strlen(argv[1]))) {
|
||||||
|
char printed_count;
|
||||||
|
printed_count = fprintf_P(stdout, (PGM_P)pgm_read_word(&months[i]));
|
||||||
|
fputc('\n', stdout);
|
||||||
|
lcd_puts_P((PGM_P)pgm_read_word(&months[i]));
|
||||||
|
lcd_putc(' ');
|
||||||
|
spaces_to_print -= (printed_count + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Clear the end of the line
|
||||||
|
for (; spaces_to_print > -1; spaces_to_print--) {
|
||||||
|
lcd_putc(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cli_print_cmd_error(void)
|
||||||
|
{
|
||||||
|
putc('\n', stdout);
|
||||||
|
printf_P(PSTR(CLI_NO_CMD "\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cli_print_cmd_arg_error(void)
|
||||||
|
{
|
||||||
|
putc('\n', stdout);
|
||||||
|
printf_P(PSTR(CLI_ARGS_MSG "\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int cli_execute(int argc, const char *const *argv)
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < NUM_ELEMS(cli_cmds); i++) {
|
||||||
|
if (!strcmp_P(argv[0], cli_cmds[i].cmd)) {
|
||||||
|
// Test do we have correct arguments to run command
|
||||||
|
// Function arguments count shall be defined in struct
|
||||||
|
if ((argc - 1) != cli_cmds[i].func_argc) {
|
||||||
|
cli_print_cmd_arg_error();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hand argv over to function pointer,
|
||||||
|
// cross fingers and hope that funcion handles it properly
|
||||||
|
cli_cmds[i].func_p (argv);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cli_print_cmd_error();
|
||||||
|
return 0;
|
||||||
|
}
|
19
src/cli_microrl.h
Normal file
19
src/cli_microrl.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef _CLI_MICRORL_H_
|
||||||
|
#define _CLI_MICRORL_H_
|
||||||
|
|
||||||
|
#define NUM_ELEMS(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
|
#define UART_STATUS_MASK 0x00FF
|
||||||
|
|
||||||
|
void cli_print(const char * str);
|
||||||
|
char cli_get_char(void);
|
||||||
|
void cli_print_help(const char *const *argv);
|
||||||
|
void print_version(FILE *stream);
|
||||||
|
void cli_print_ver(const char *const *argv);
|
||||||
|
void cli_print_ascii_tbls(const char *const *argv);
|
||||||
|
void cli_handle_month(const char *const *argv);
|
||||||
|
void cli_print_cmd_error(void);
|
||||||
|
void cli_print_cmd_arg_error(void);
|
||||||
|
int cli_execute(int argc, const char *const *argv);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _CLI_MICRORL_H_ */
|
@ -8,4 +8,13 @@ static const char m4[] PROGMEM = "April";
|
|||||||
static const char m5[] PROGMEM = "May";
|
static const char m5[] PROGMEM = "May";
|
||||||
static const char m6[] PROGMEM = "June";
|
static const char m6[] PROGMEM = "June";
|
||||||
|
|
||||||
PGM_P const months[] PROGMEM = {m1,m2,m3,m4,m5,m6};
|
PGM_P const months[] PROGMEM = {m1, m2, m3, m4, m5, m6};
|
||||||
|
|
||||||
|
const char help_cmd[] PROGMEM = HELP_CMD;
|
||||||
|
const char help_help[] PROGMEM = HELP_HELP;
|
||||||
|
const char ver_cmd[] PROGMEM = VER_CMD;
|
||||||
|
const char ver_help[] PROGMEM = VER_HELP;
|
||||||
|
const char ascii_cmd[] PROGMEM = ASCII_CMD;
|
||||||
|
const char ascii_help[] PROGMEM = ASCII_HELP;
|
||||||
|
const char month_cmd[] PROGMEM = MONTH_CMD;
|
||||||
|
const char month_help[] PROGMEM = MONTH_HELP;
|
||||||
|
@ -2,11 +2,32 @@
|
|||||||
#define _HMI_MSG_H_
|
#define _HMI_MSG_H_
|
||||||
|
|
||||||
#define PROG_VERSION "Version: %S built on: %S %S"
|
#define PROG_VERSION "Version: %S built on: %S %S"
|
||||||
#define LIBC_VERSION "avr-libc version: %S"
|
#define LIBC_VERSION "avr-libc version: %S avr-gcc version: %S"
|
||||||
#define STUD_NAME "Arti Zirk"
|
#define STUD_NAME "Arti Zirk"
|
||||||
#define GET_MONTH_MSG "Enter Month name first letter >"
|
#define GET_MONTH_MSG "Enter Month name first letter >"
|
||||||
#define UPTIME_MSG "Uptime: %lu s"
|
#define UPTIME_MSG "Uptime: %lu s"
|
||||||
|
|
||||||
|
#define HELP_CMD "help"
|
||||||
|
#define HELP_HELP "Get help"
|
||||||
|
#define VER_CMD "version"
|
||||||
|
#define VER_HELP "Print FW version"
|
||||||
|
#define ASCII_CMD "ascii"
|
||||||
|
#define ASCII_HELP "print ASCII tables"
|
||||||
|
#define MONTH_CMD "month"
|
||||||
|
#define MONTH_HELP "Find matching month from lookup list. Usage: month <string>"
|
||||||
|
#define CLI_HELP_MSG "Implemented commands:"
|
||||||
|
#define CLI_NO_CMD "Command not implemented.\n Use <help> to get help."
|
||||||
|
#define CLI_ARGS_MSG "To few or to many arguments for this command\nUse <help>"
|
||||||
|
|
||||||
extern PGM_P const months[];
|
extern PGM_P const months[];
|
||||||
|
|
||||||
|
extern const char help_cmd[];
|
||||||
|
extern const char help_help[];
|
||||||
|
extern const char ver_cmd[];
|
||||||
|
extern const char ver_help[];
|
||||||
|
extern const char ascii_cmd[];
|
||||||
|
extern const char ascii_help[];
|
||||||
|
extern const char month_cmd[];
|
||||||
|
extern const char month_help[];
|
||||||
|
|
||||||
#endif /* _HMI_MSG_H_ */
|
#endif /* _HMI_MSG_H_ */
|
||||||
|
60
src/main.c
60
src/main.c
@ -10,12 +10,20 @@
|
|||||||
#include "uart_wrap.h"
|
#include "uart_wrap.h"
|
||||||
#include "print_helper.h"
|
#include "print_helper.h"
|
||||||
#include "../lib/hd44780_111/hd44780.h"
|
#include "../lib/hd44780_111/hd44780.h"
|
||||||
|
#include "../lib/helius_microrl/microrl.h"
|
||||||
|
#include "cli_microrl.h"
|
||||||
|
|
||||||
|
|
||||||
#define BAUDRATE 9600
|
#define BAUDRATE 9600
|
||||||
|
|
||||||
// For configuring arduino mega pin 25
|
// For configuring arduino mega pin 25
|
||||||
#define LED_INIT DDRA |= _BV(DDA3);
|
#define LED_INIT DDRA |= _BV(DDA3);
|
||||||
#define LED_TOGGLE PORTA ^= _BV(PORTA3)
|
#define LED_TOGGLE PORTA ^= _BV(PORTA3)
|
||||||
|
#define UART_STATUS_MASK 0x00FF
|
||||||
|
|
||||||
|
// Create microrl object and pointer on it
|
||||||
|
static microrl_t rl;
|
||||||
|
static microrl_t *prl = &rl;
|
||||||
|
|
||||||
static inline void init_system_clock(void)
|
static inline void init_system_clock(void)
|
||||||
{
|
{
|
||||||
@ -26,6 +34,7 @@ static inline void init_system_clock(void)
|
|||||||
TIMSK5 |= _BV(OCIE5A); // Output Compare A Match Interrupt Enable
|
TIMSK5 |= _BV(OCIE5A); // Output Compare A Match Interrupt Enable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void init_hw (void)
|
static inline void init_hw (void)
|
||||||
{
|
{
|
||||||
// IO init
|
// IO init
|
||||||
@ -51,51 +60,20 @@ static inline void init_hw (void)
|
|||||||
|
|
||||||
static inline void start_ui (void)
|
static inline void start_ui (void)
|
||||||
{
|
{
|
||||||
// Print program and libc versions
|
print_version(stderr);
|
||||||
fprintf_P(stderr, PSTR(PROG_VERSION "\n"),
|
|
||||||
PSTR(GIT_DESCR), PSTR(__DATE__), PSTR(__TIME__));
|
|
||||||
fprintf_P(stderr, PSTR(LIBC_VERSION "\n"), PSTR(__AVR_LIBC_VERSION_STRING__));
|
|
||||||
|
|
||||||
// print student name
|
// print student name
|
||||||
fprintf_P(stdout, PSTR(STUD_NAME));
|
fprintf_P(stdout, PSTR(STUD_NAME));
|
||||||
fputc('\n', stdout); // Add a new line to the uart printout
|
fputc('\n', stdout); // Add a new line to the uart printout
|
||||||
lcd_puts_P(PSTR(STUD_NAME));
|
lcd_puts_P(PSTR(STUD_NAME));
|
||||||
|
|
||||||
// ASCII table print
|
|
||||||
print_ascii_tbl(stdout);
|
|
||||||
unsigned char ascii[128];
|
|
||||||
for (unsigned char i = 0; i < sizeof(ascii); i++) {
|
|
||||||
ascii[i] = i;
|
|
||||||
}
|
|
||||||
print_for_human(stdout, ascii, sizeof(ascii));
|
|
||||||
|
|
||||||
// Bootstrap search_month message
|
|
||||||
fprintf_P(stdout, PSTR(GET_MONTH_MSG));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void search_month (void)
|
static inline void start_cli(void)
|
||||||
{
|
{
|
||||||
char letter;
|
// Call init with ptr to microrl instance and print callback
|
||||||
|
microrl_init (prl, cli_print);
|
||||||
fscanf(stdin, "%c", &letter);
|
// Set callback for execute
|
||||||
fprintf(stdout, "%c\n", letter);
|
microrl_set_execute_callback (prl, cli_execute);
|
||||||
lcd_goto(0x40); // Got to the beginning of the next line
|
|
||||||
char spaces_to_print = 16;
|
|
||||||
for (int i = 0; i < 6; i++) {
|
|
||||||
if (!strncmp_P(&letter, (PGM_P)pgm_read_word(&months[i]), 1)) {
|
|
||||||
char printed_count;
|
|
||||||
printed_count = fprintf_P(stdout, (PGM_P)pgm_read_word(&months[i]));
|
|
||||||
fputc('\n', stdout);
|
|
||||||
lcd_puts_P((PGM_P)pgm_read_word(&months[i]));
|
|
||||||
lcd_putc(' ');
|
|
||||||
spaces_to_print -= (printed_count + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Clear the end of the line
|
|
||||||
for (; spaces_to_print > -1; spaces_to_print--) {
|
|
||||||
lcd_putc(' ');
|
|
||||||
}
|
|
||||||
fprintf_P(stdout, PSTR(GET_MONTH_MSG));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void heartbeat (void)
|
static inline void heartbeat (void)
|
||||||
@ -110,19 +88,21 @@ static inline void heartbeat (void)
|
|||||||
LED_TOGGLE;
|
LED_TOGGLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main (void)
|
int main (void)
|
||||||
{
|
{
|
||||||
init_hw();
|
init_hw();
|
||||||
start_ui();
|
start_ui();
|
||||||
|
start_cli();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
heartbeat();
|
heartbeat();
|
||||||
if (uart0_available()) {
|
// CLI commands are handled in cli_execute()
|
||||||
search_month();
|
microrl_insert_char (prl, cli_get_char());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// System clock
|
// System clock
|
||||||
ISR(TIMER5_COMPA_vect)
|
ISR(TIMER5_COMPA_vect)
|
||||||
{
|
{
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "../lib/andygock_avr-uart/uart.h"
|
#include "../lib/andygock_avr-uart/uart.h"
|
||||||
|
|
||||||
|
#define UART_STATUS_MASK 0x00FF
|
||||||
|
|
||||||
int uart0_putc_wrap(char c, FILE *stream)
|
int uart0_putc_wrap(char c, FILE *stream)
|
||||||
{
|
{
|
||||||
(void) stream;
|
(void) stream;
|
||||||
@ -21,7 +23,7 @@ int uart0_getc_wrap(FILE *stream)
|
|||||||
// this function is only called out when there is at least one character
|
// this function is only called out when there is at least one character
|
||||||
// available in the input buffer (see main.c line 114) then error checking
|
// available in the input buffer (see main.c line 114) then error checking
|
||||||
// is not currently necessary.
|
// is not currently necessary.
|
||||||
return uart0_getc() & 0xff;
|
return uart0_getc() & UART_STATUS_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int uart3_putc_wrap(char c, FILE *stream)
|
int uart3_putc_wrap(char c, FILE *stream)
|
||||||
|
Loading…
Reference in New Issue
Block a user