User Tools

Site Tools


Tiny Shell sorce

main.c

main.c
/* $Id$ */
 
#include <ctype.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
 
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
 
 
#define BAUD 38400
#include <util/setbaud.h>
 
#include <fifo.h>
#include <tools.h>
#include <shell.h>
 
 
void uart_init(void) {
    /* UBRR - USART Baud Rate Register */
    UBRR0H = UBRRH_VALUE;
    UBRR0L = UBRRL_VALUE;
 
    /* UCSR  - USART Control and Status Register */
    /* U2X - Double Speed Operation */
    UCSR0A &= ~(1 << U2X0);
 
    /* UCSZ - USART Character Size, 8 bit */
    UCSR0B &= ~(1 << UCSZ02);
    UCSR0C |= (1 << UCSZ01) | (1 << UCSZ00);
 
    /* USBS - USART Stop Bit Select */
    /* UPM - USART Parity Mode */
    UCSR0C &= ~(1 << USBS0) /* One Stop Bit */ &~(1 << UPM00) & ~(1 << UPM01);  /* No Parity */
 
    UCSR0B |= (1 << TXEN0) | (1 << RXEN0);      /* Enable TX and RX */
    UCSR0B |= (1 << RXCIE0);    /* Enable Receive Interrupt */
    UCSR0B &= ~(1 << UDRIE0);   /* Disable Transmit Interrupt */
}
 
void wdt_init(void) {
    wdt_enable(WDTO_30MS);
    WDTCSR = (1 << WDIE);
}
 
#define CLKD1    (1<<CS20)                      /* CLK/8 */
#define CLKD8    (1<<CS21)                      /* CLK/8 */
#define CLKD32   (1<<CS20) | (1<<CS21)          /* CLK/32 */
#define CLKD64   (1<<CS22)                      /* CLK/64 */
#define CLKD128  (1<<CS20) | (1<<CS22)          /* CLK/128 */
#define CLKD256  (1<<CS21) | (1<<CS22)          /* CLK/256 */
#define CLKD1024 (1<<CS20) | (1<<CS21) | (1<<CS22)      /* CLK/1024 */
 
void timer_init(void) {
    TCCR2A = 0;
    TCCR2B = 0;
    TCCR2B = CLKD256;
    TIMSK2 |= (1 << TOIE2);
}
 
void pwm0_init(void) {
    /* Timer 0 */
    TCCR0A = (1 << COM0A1) | (1 << COM0B1) | (1 << WGM00) | (1 << WGM01);
    TCCR0B = CLKD128;
    DDRD |= (1 << PORTD5) | (1 << PORTD6);
 
    OCR0A = 10;                 /* #6 */
    OCR0B = 10;                 /* #5 */
}
 
void pwm1_init(void) {
 
    /* Timer 1 */
    TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM10) | (1 << WGM11);
    TCCR1B = (1 << WGM12) | (1 << CS10) | (1 << CS12);
    DDRB |= (1 << PORTB1) | (1 << PORTB2);
 
    OCR1A = 15;
    OCR1B = 15;
}
 
 
void pwm2_init(void) {
    /* Timer 2 */
    TCCR2A = (1 << COM2A1) | (1 << COM2B1) | (1 << WGM20) | (1 << WGM21);
    TCCR2B = (1 << CS20) | (1 << CS21) | (1 << CS22);
    DDRB |= (1 << PORTB3);
    DDRD |= (1 << PORTD3);
 
    OCR2A = 10;
    OCR2B = 10;
}
 
void adc_init() {
    ADMUX |= (1 << REFS0);
    ADCSRA = (1 << ADEN);                                  /* Enable ADC */
    ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);  /* Set base freq prescale */
}
 
uint16_t adc_read(uint8_t ch) {
 
    if (ch > 7)
        return 0;
 
    ADMUX = (ADMUX & 0xF0) | ch;        /* Channel selection */
    ADCSRA |= (1 << ADSC);              /* Start conversion */
 
    while (!ADCSRA & (1 << ADIF));
    ADCSRA |= (1 << ADIF);
 
    return (ADC);
}
 
 
ISR(TIMER2_OVF_vect) {
/* Dummy code */
}
 
ISR(USART_RX_vect) {
    volatile uint8_t c = UDR0;
 
    if (c == '\r') {
        fifo_putc(in, '\n');
        fifo_putc(out, '\n');
    }
 
    fifo_putc(in, c);
    fifo_putc(out, c);
}
 
ISR(WDT_vect) {
    wdt_reset();
    volatile uint8_t c;
    while ((c = fifo_getc(out)) > 0) {
        while (!(UCSR0A & (1 << UDRE0)));
        UDR0 = c;
    }
    WDTCSR = (1 << WDIE);
}
 
int16_t cmd_help(void) {
    outl("Available commands:");
    outl("[s3|s5|s6] pos - set servo position");
    outl("help - this help");
    return 1;
}
 
 
int16_t cmd_hello(void) {
    outl("Hello!");
    return 1;
}
 
 
 
int16_t cmd_serv3(uint8_t * arg) {
    int8_t i = str2int(arg);
    if (i >= 10 && i <= 37) {
        OCR2B = i;
        return i;
    } else {
        return -1;
    }
}
 
int16_t cmd_serv5(uint8_t * arg) {
    int8_t i = str2int(arg);
    if (i >= 10 && i <= 37) {
        OCR0B = i;
        return i;
    } else {
        return -1;
    }
}
 
int16_t cmd_serv6(uint8_t * arg) {
    int8_t i = str2int(arg);
    if (i >= 10 && i <= 37) {
        OCR2A = i;
        return i;
    } else {
        return -1;
    }
}
 
 
int16_t cmd_delay(uint8_t * arg) {
    int16_t n = str2int(arg), i = n;
    if (i < 0)
        i = -i;
    while (i > 0) {
        _delay_ms(100);
        i--;
    }
    return n;
}
 
cdef_t cdef[] = {
    {"help", &cmd_help, 0},
    {"hello", &cmd_hello, 0},
    {"s3", &cmd_serv3, 1},
    {"s5", &cmd_serv5, 1},
    {"s6", &cmd_serv6, 1},
    {"delay", &cmd_delay, 1} ,
    {"sleep", &cmd_delay, 1}
};
 
#define STR_LEN 64
 
uint8_t *prompt = "READY>";
 
int main() {
    fifo_iohook();
    uart_init();
    wdt_init();
    timer_init();
    pwm0_init();
    pwm1_init();
    pwm2_init();
    adc_init();
    sei();
 
    outl("\r\nTINY SHELL V01");
    outs(prompt);
 
    uint8_t str[STR_LEN];
    memset(str, 0, STR_LEN);
 
    _delay_ms(1000);
 
    while (1) {
 
        uint8_t *s;
        s = str;
        while (fifo_gett(in, str, STR_LEN, '\r') > 0) {
 
            shell(str, cdef, sizeof(cdef) / sizeof(cdef[0]));
            outs("\r\n");
            outs(prompt);
 
        }
        _delay_ms(100);
    }
}

fifo.c

fifo.c
/* $Id$ */
 
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
 
 
#include <tools.h>
#include <fifo.h>
 
#ifndef FIFO_BUFFER_SIZE
#define FIFO_BUFFER_SIZE 128
#endif
 
static uint8_t inbuf[FIFO_BUFFER_SIZE];
static uint8_t outbuf[FIFO_BUFFER_SIZE];
 
FIFO fifo_in, fifo_out;
FIFO *in, *out;
 
void outc(uint8_t c) {
    fifo_putc(out, c);
}
 
void outs(uint8_t * str) {
    fifo_puts(out, str);
}
 
void outl(uint8_t * str) {
    fifo_puts(out, str);
    fifo_puts(out, "\r\n");
}
 
 
int uart_putchar(char c, FILE * stream) {
    return fifo_putc(&fifo_out, c);
}
 
int uart_getchar(FILE * stream) {
    return (int)fifo_getc(&fifo_out);
}
 
FILE uart_str = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
 
void fifo_iohook(void) {
    in = &fifo_in;
    out = &fifo_out;
 
    fifo_init(in, inbuf, sizeof(inbuf));
    fifo_init(out, outbuf, sizeof(outbuf));
 
    stdout = stdin = stderr = &uart_str;
}
 
void fifo_init(FIFO * b, uint8_t * buffer, uint8_t buffer_len) {
    if (b && buffer) {
        memset((void **)buffer, 0, buffer_len);
        b->buffer_len = buffer_len;
        b->buffer = buffer;
        b->head = 0;
        b->tail = 0;
    }
}
 
uint8_t fifo_count(const FIFO * b) {
    if (b) {
        return (b->head - b->tail);
    }
    return 0;
}
 
static bool fifo_full(const FIFO * b) {
    if (b) {
        return (fifo_count(b) == b->buffer_len);
    }
    return true;
}
 
bool fifo_empty(const FIFO * b) {
    if (b) {
        return (fifo_count(b) == 0);
    }
    return true;
}
 
uint8_t fifo_peek(const FIFO * b) {
    uint8_t data = 0;
 
    if (!fifo_empty(b)) {
        data = b->buffer[b->tail % b->buffer_len];
    }
    return data;
}
 
bool fifo_back(FIFO * b) {
    if (!fifo_empty(b)) {
        b->head--;
        return true;
    }
    return false;
}
 
uint8_t fifo_getc(FIFO * b) {
    uint8_t data = 0;
 
    if (!fifo_empty(b)) {
        data = b->buffer[b->tail % b->buffer_len];
        b->tail++;
    }
    return data;
}
 
bool fifo_putc(FIFO * b, uint8_t data) {
    bool status = false;
 
    if (b) {
        if (!fifo_full(b)) {
            b->buffer[b->head % b->buffer_len] = data;
            b->head++;
            status = true;
        }
    }
    return status;
}
 
uint8_t fifo_puts(FIFO * b, uint8_t * string) {
    if (b) {
        for (uint8_t i = 0; i < str_len(string); i++) {
            if (!fifo_putc(b, string[i]))
                return i;
        }
    }
}
 
bool fifo_scanc(FIFO * b, uint8_t c) {
    if (b) {
        if (!fifo_empty(b)) {
            uint8_t tail = b->tail;
 
            for (uint8_t i = 0; i < fifo_count(b); i++) {
                uint8_t data = b->buffer[tail % b->buffer_len];
 
                if (data == c) {
                    return true;
                }
                tail++;
            }
        }
        return false;
    }
}
 
uint8_t fifo_gett(FIFO * b, uint8_t * str, uint8_t len, uint8_t term) {
    if (b) {
        memset((void *)str, 0, len);
 
        if (fifo_scanc(b, term) && str) {
            uint8_t i = 0, c = 0;
 
            while ((c = fifo_getc(b)) != 0 && c != term && i < len) {
                str[i] = c;
                i++;
            }
            return i;
        }
        return 0;
    }
}
 
/* EOF */

fifo.h

fifo.h
/* $Id$ */
 
#ifndef UART_H_IUI
#define UART_H_IUI
 
#define FIFO_BUFFER_SIZE 128
//extern static uint8_t inbuf[FIFO_BUFFER_SIZE];
//extern static uint8_t outbuf[FIFO_BUFFER_SIZE];
 
typedef struct fifo {
    volatile unsigned head;
    volatile unsigned tail;
    volatile uint8_t *buffer;
    unsigned buffer_len;
} FIFO;
 
extern FIFO fifo_in, fifo_out;
extern FIFO *in, *out;
 
void fifo_iohook(void);
 
void fifo_init(FIFO * b, uint8_t * buffer, uint8_t buffer_len);
uint8_t fifo_count(const FIFO * b);
static bool fifo_full(const FIFO * b);
bool fifo_empty(const FIFO * b);
uint8_t fifo_peek(const FIFO * b);
uint8_t fifo_getc(FIFO * b);
bool fifo_putc(FIFO * b, uint8_t data);
uint8_t fifo_puts(FIFO * b, uint8_t * str);
bool fifo_scanc(FIFO * b, uint8_t c);
uint8_t fifo_gett(FIFO * b, uint8_t * str, uint8_t len, uint8_t);
 
bool fifo_back(FIFO * b);
 
void outc(uint8_t c);
void outs(uint8_t * str);
void outl(uint8_t * str);
 
 
#endif
/* EOF */

tools.c

tools.c
/* $Id$ */
 
#include <stdint.h>
#include <stdbool.h>
#include <tools.h>
 
uint16_t str_len(uint8_t * str) {
    uint16_t i = 0;
    while (str[i] != 0)
        i++;
    return i;
}
 
uint8_t *str_replc(uint8_t ** str, uint8_t c, uint8_t r) {
    uint16_t i = 0;
    while ((*str)[i] != 0) {
        if ((*str)[i] == c)
            (*str)[i] = r;
        i++;
    }
    return (*str);
}
 
bool str_cmp(uint8_t * str1, uint8_t * str2) {
    uint8_t i = 0;
    while (str1[i] != 0 && str2[i] != 0) {
        if ((str1[i] != str2[i]) || (str1[i + 1] != str2[i + 1]))
            return false;
        i++;
    }
    return true;
}
 
uint8_t *str_ltrim(uint8_t * str, uint8_t c) {
    while (str[0] == c && str[0] != 0)
        str++;
    return str;
}
 
uint8_t *str_trim(uint8_t * str, uint8_t c) {
    while (str[0] == c && str[0] != 0)
        str++;
 
    uint8_t i = str_len(str) - 1;
    while (str[i] == c && i > 0) {
        i--;
    }
    str[++i] = 0;
    return str;
}
 
int32_t int_pow(uint8_t n, uint8_t s) {
    int64_t i = 1;
    while (s--) {
        i = i * n;
    }
    return i;
}
 
int32_t str2int(uint8_t * str) {
    uint8_t l = str_len(str);
    uint8_t i = l;
    int16_t n = 0;
    while (i > 0) {
        if (str[i - 1] <= '9' && str[i - 1] >= '0')
            n += (str[i - 1] - '0') * int_pow(10, l - i);
        i--;
    }
    if (str[0] == '-')
        n = -n;
    return n;
}
 
uint8_t int2str(int32_t num, uint8_t * str, uint8_t buf_len, int16_t base) {
    static char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
    uint8_t i = 0, sign = 0;
    if (num < 0) {
        sign = '-';
        num = -num;
    }
    do {
        str[i++] = digits[num % base];
    } while ((num /= base) > 0 && i < buf_len);
 
    if (sign)
        str[i++] = '-';
    str[i] = 0;
 
    uint8_t len = i - 1;
    uint8_t c, b = 0;
 
    while (i-- && b < i) {
        c = str[b];
        str[b] = str[i];
        str[i] = c;
        b++;
    }
    return len;
}
 
uint8_t *tok_comp(uint8_t ** str, uint8_t c, uint8_t * end) {
    uint8_t *p = *str;
    if (p >= end)
        return 0;
    if (p[0] == 0)
        return 0;
 
    uint8_t i = 0;
 
    while (i < str_len(p)) {
        if (p[i] == c || p[i] == 0)
            break;
        i++;
    }
    p[i] = 0;
 
    (*str) += ++i;
    i = 0;
 
    while ((*str)[i] == c)
        (*str)++;
    return p;
}
 
/* EOF */

tools.h

tools.h
/* $Id$ */
 
#ifndef TOOLS_H_IRT
#define TOOLS_H_IRT
 
#define MAX_LINE_LEN 1024
 
uint16_t str_len(uint8_t * str);
bool str_cmp(uint8_t * str1, uint8_t * str2);
uint8_t *str_ltrim(uint8_t * str, uint8_t c);
uint8_t *str_trim(uint8_t * str, uint8_t c);
int32_t int_pow(uint8_t n, uint8_t s);
int32_t str2int(uint8_t * str);
uint8_t int2str(int32_t num, uint8_t * str, uint8_t str_len, int16_t base);
uint8_t *str_endp(uint8_t * str);
uint8_t *tok_comp(uint8_t ** str, uint8_t c, uint8_t * end);
 
#endif
/* EOF */