/* $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); } }
/* $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 */
/* $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 */
/* $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 */
/* $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 */