cleaned up serial completing support for non blocking tx and refactoring formatting functions into a new module 'print'
This commit is contained in:
parent
8793b555e0
commit
c0b4b8309a
2
Makefile
2
Makefile
@ -31,7 +31,7 @@ DEVICE = atmega328p
|
|||||||
CLOCK = 16000000
|
CLOCK = 16000000
|
||||||
PROGRAMMER = -c avrisp2 -P usb
|
PROGRAMMER = -c avrisp2 -P usb
|
||||||
OBJECTS = main.o motion_control.o gcode.o spindle_control.o serial.o protocol.o stepper.o \
|
OBJECTS = main.o motion_control.o gcode.o spindle_control.o serial.o protocol.o stepper.o \
|
||||||
eeprom.o settings.o planner.o nuts_bolts.o limits.o
|
eeprom.o settings.o planner.o nuts_bolts.o limits.o print.o
|
||||||
# FUSES = -U hfuse:w:0xd9:m -U lfuse:w:0x24:m
|
# FUSES = -U hfuse:w:0xd9:m -U lfuse:w:0x24:m
|
||||||
FUSES = -U hfuse:w:0xd2:m -U lfuse:w:0xff:m
|
FUSES = -U hfuse:w:0xd2:m -U lfuse:w:0xff:m
|
||||||
# update that line with this when programmer is back up:
|
# update that line with this when programmer is back up:
|
||||||
|
@ -3,7 +3,7 @@ Allocation of AVR peripherals in Grbl
|
|||||||
|
|
||||||
See config.h for pin allocation.
|
See config.h for pin allocation.
|
||||||
|
|
||||||
The UART is handled by 'wiring_serial' and used primarily for streaming gcode
|
The UART is handled by 'serial' and used primarily for streaming gcode
|
||||||
|
|
||||||
16 bit Timer 1 and the TIMER1_COMPA interrupt is used by the 'stepper' module to handle step events
|
16 bit Timer 1 and the TIMER1_COMPA interrupt is used by the 'stepper' module to handle step events
|
||||||
|
|
||||||
|
@ -36,4 +36,6 @@ Supporting files:
|
|||||||
|
|
||||||
'nuts_bolts.h' : A tiny collection of useful constants and macros used everywhere
|
'nuts_bolts.h' : A tiny collection of useful constants and macros used everywhere
|
||||||
|
|
||||||
'serial' : Low level serial communications
|
'serial' : Low level serial communications
|
||||||
|
|
||||||
|
'print' : Functions to print strings of different formats (using serial)
|
6
main.c
6
main.c
@ -22,6 +22,7 @@
|
|||||||
#include <avr/sleep.h>
|
#include <avr/sleep.h>
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
|
#include "config.h"
|
||||||
#include "planner.h"
|
#include "planner.h"
|
||||||
#include "stepper.h"
|
#include "stepper.h"
|
||||||
#include "spindle_control.h"
|
#include "spindle_control.h"
|
||||||
@ -33,12 +34,9 @@
|
|||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
|
|
||||||
// #ifndef __AVR_ATmega328P__
|
|
||||||
// # error "As of version 0.6 Grbl only supports atmega328p. If you want to run Grbl on an 168 check out 0.51 ('git co v0_51')"
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
serial_init(BAUD_RATE);
|
||||||
protocol_init();
|
protocol_init();
|
||||||
settings_init();
|
settings_init();
|
||||||
plan_init();
|
plan_init();
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
#include "nuts_bolts.h"
|
#include "nuts_bolts.h"
|
||||||
#include "stepper.h"
|
#include "stepper.h"
|
||||||
#include "planner.h"
|
#include "planner.h"
|
||||||
#include "serial.h"
|
|
||||||
|
|
||||||
|
|
||||||
void mc_dwell(uint32_t milliseconds)
|
void mc_dwell(uint32_t milliseconds)
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
#include "stepper.h"
|
#include "stepper.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "serial.h"
|
|
||||||
|
|
||||||
// The number of linear motions that can be in the plan at any give time
|
// The number of linear motions that can be in the plan at any give time
|
||||||
#ifdef __AVR_ATmega328P__
|
#ifdef __AVR_ATmega328P__
|
||||||
|
58
print.c
Normal file
58
print.c
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#include <math.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include "serial.h"
|
||||||
|
|
||||||
|
void printString(const char *s)
|
||||||
|
{
|
||||||
|
while (*s)
|
||||||
|
serial_write(*s++);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print a string stored in PGM-memory
|
||||||
|
void printPgmString(const char *s)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
while ((c = pgm_read_byte_near(s++)))
|
||||||
|
serial_write(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printIntegerInBase(unsigned long n, unsigned long base)
|
||||||
|
{
|
||||||
|
unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
|
||||||
|
unsigned long i = 0;
|
||||||
|
|
||||||
|
if (n == 0) {
|
||||||
|
serial_write('0');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (n > 0) {
|
||||||
|
buf[i++] = n % base;
|
||||||
|
n /= base;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i > 0; i--)
|
||||||
|
serial_write(buf[i - 1] < 10 ?
|
||||||
|
'0' + buf[i - 1] :
|
||||||
|
'A' + buf[i - 1] - 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printInteger(long n)
|
||||||
|
{
|
||||||
|
if (n < 0) {
|
||||||
|
serial_write('-');
|
||||||
|
n = -n;
|
||||||
|
}
|
||||||
|
|
||||||
|
printIntegerInBase(n, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printFloat(double n)
|
||||||
|
{
|
||||||
|
double integer_part, fractional_part;
|
||||||
|
fractional_part = modf(n, &integer_part);
|
||||||
|
printInteger(integer_part);
|
||||||
|
serial_write('.');
|
||||||
|
printInteger(round(fractional_part*1000));
|
||||||
|
}
|
||||||
|
|
14
print.h
Normal file
14
print.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef print_h
|
||||||
|
#define print_h
|
||||||
|
|
||||||
|
void printNewline(void);
|
||||||
|
void printString(const char *s);
|
||||||
|
void printPgmString(const char *s);
|
||||||
|
void printInteger(long n);
|
||||||
|
void printHex(unsigned long n);
|
||||||
|
void printOctal(unsigned long n);
|
||||||
|
void printBinary(unsigned long n);
|
||||||
|
void printIntegerInBase(unsigned long n, unsigned long base);
|
||||||
|
void printFloat(double n);
|
||||||
|
|
||||||
|
#endif
|
@ -22,6 +22,7 @@
|
|||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
#include "gcode.h"
|
#include "gcode.h"
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
|
#include "print.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -55,7 +56,6 @@ static void status_message(int status_code) {
|
|||||||
|
|
||||||
void protocol_init()
|
void protocol_init()
|
||||||
{
|
{
|
||||||
beginSerial(BAUD_RATE);
|
|
||||||
printPgmString(PSTR("\r\nGrbl " GRBL_VERSION));
|
printPgmString(PSTR("\r\nGrbl " GRBL_VERSION));
|
||||||
printPgmString(PSTR("\r\n"));
|
printPgmString(PSTR("\r\n"));
|
||||||
}
|
}
|
||||||
@ -72,7 +72,7 @@ uint8_t protocol_execute_line(char *line) {
|
|||||||
void protocol_process()
|
void protocol_process()
|
||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
while((c = serialRead()) != -1)
|
while((c = serial_read()) != 0xff)
|
||||||
{
|
{
|
||||||
if((char_counter > 0) && ((c == '\n') || (c == '\r'))) { // Line is complete. Then execute!
|
if((char_counter > 0) && ((c == '\n') || (c == '\r'))) { // Line is complete. Then execute!
|
||||||
line[char_counter] = 0; // treminate string
|
line[char_counter] = 0; // treminate string
|
||||||
|
114
serial.c
114
serial.c
@ -21,9 +21,8 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
|
#include <avr/sleep.h>
|
||||||
|
|
||||||
// Define constants and variables for buffering incoming serial data. We're
|
// Define constants and variables for buffering incoming serial data. We're
|
||||||
// using a ring buffer (I think), in which rx_buffer_head is the index of the
|
// using a ring buffer (I think), in which rx_buffer_head is the index of the
|
||||||
@ -46,7 +45,7 @@ uint8_t tx_buffer_head = 0;
|
|||||||
volatile uint8_t tx_buffer_tail = 0;
|
volatile uint8_t tx_buffer_tail = 0;
|
||||||
|
|
||||||
|
|
||||||
void beginSerial(long baud)
|
void serial_init(long baud)
|
||||||
{
|
{
|
||||||
UBRR0H = ((F_CPU / 16 + baud / 2) / baud - 1) >> 8;
|
UBRR0H = ((F_CPU / 16 + baud / 2) / baud - 1) >> 8;
|
||||||
UBRR0L = ((F_CPU / 16 + baud / 2) / baud - 1);
|
UBRR0L = ((F_CPU / 16 + baud / 2) / baud - 1);
|
||||||
@ -60,56 +59,50 @@ void beginSerial(long baud)
|
|||||||
|
|
||||||
// enable interrupt on complete reception of a byte
|
// enable interrupt on complete reception of a byte
|
||||||
UCSR0B |= 1<<RXCIE0;
|
UCSR0B |= 1<<RXCIE0;
|
||||||
|
|
||||||
// defaults to 8-bit, no parity, 1 stop bit
|
// defaults to 8-bit, no parity, 1 stop bit
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialWrite(uint8_t data) {
|
void serial_write(uint8_t data) {
|
||||||
|
// Calculate next head
|
||||||
uint8_t next_head = (tx_buffer_head + 1) % TX_BUFFER_SIZE;
|
uint8_t next_head = (tx_buffer_head + 1) % TX_BUFFER_SIZE;
|
||||||
|
|
||||||
// wait until there's a space in the buffer
|
// Wait until there's a space in the buffer
|
||||||
while (next_head == tx_buffer_tail) ;
|
while (next_head == tx_buffer_tail) { sleep_mode(); };
|
||||||
|
|
||||||
|
// Store data and advance head
|
||||||
tx_buffer[tx_buffer_head] = data;
|
tx_buffer[tx_buffer_head] = data;
|
||||||
tx_buffer_head = next_head;
|
tx_buffer_head = next_head;
|
||||||
|
|
||||||
// enable the Data Register Empty Interrupt
|
// Enable Data Register Empty Interrupt
|
||||||
UCSR0B |= (1 << UDRIE0);
|
UCSR0B |= (1 << UDRIE0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// interrupt called on Data Register Empty
|
// Data Register Empty Interrupt handler
|
||||||
SIGNAL(USART_UDRE_vect) {
|
SIGNAL(USART_UDRE_vect) {
|
||||||
// temporary tx_buffer_tail
|
|
||||||
// (to optimize for volatile, there are no interrupts inside an interrupt routine)
|
// temporary tx_buffer_tail (to optimize for volatile)
|
||||||
uint8_t tail = tx_buffer_tail;
|
uint8_t tail = tx_buffer_tail;
|
||||||
|
|
||||||
// get a byte from the buffer
|
// Send a byte from the buffer
|
||||||
uint8_t data = tx_buffer[tail];
|
UDR0 = tx_buffer[tail];
|
||||||
// send the byte
|
|
||||||
UDR0 = data;
|
|
||||||
|
|
||||||
// update tail position
|
// Update tail position
|
||||||
tail ++;
|
tail ++;
|
||||||
tail %= TX_BUFFER_SIZE;
|
tail %= TX_BUFFER_SIZE;
|
||||||
|
tx_buffer_tail = tail;
|
||||||
|
|
||||||
// if the buffer is empty, disable the interrupt
|
// Turn off Data Register Empty Interrupt if this concludes the transfer
|
||||||
if (tail == tx_buffer_head) {
|
if (tail == tx_buffer_head) {
|
||||||
UCSR0B &= ~(1 << UDRIE0);
|
UCSR0B &= ~(1 << UDRIE0);
|
||||||
}
|
}
|
||||||
|
|
||||||
tx_buffer_tail = tail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if there is any data in the read buffer
|
uint8_t serial_read()
|
||||||
int serialAnyAvailable()
|
|
||||||
{
|
{
|
||||||
return (rx_buffer_head != rx_buffer_tail);
|
if (rx_buffer_head != rx_buffer_tail) {
|
||||||
}
|
return 0xff;
|
||||||
|
|
||||||
uint8_t serialRead()
|
|
||||||
{
|
|
||||||
if (!serialAnyAvailable()) {
|
|
||||||
return -1;
|
|
||||||
} else {
|
} else {
|
||||||
uint8_t data = rx_buffer[rx_buffer_tail];
|
uint8_t data = rx_buffer[rx_buffer_tail];
|
||||||
rx_buffer_tail = (rx_buffer_tail + 1) % RX_BUFFER_SIZE;
|
rx_buffer_tail = (rx_buffer_tail + 1) % RX_BUFFER_SIZE;
|
||||||
@ -132,62 +125,3 @@ SIGNAL(USART_RX_vect)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void printByte(unsigned char c)
|
|
||||||
{
|
|
||||||
serialWrite((uint8_t) c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void printString(const char *s)
|
|
||||||
{
|
|
||||||
while (*s)
|
|
||||||
printByte(*s++);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print a string stored in PGM-memory
|
|
||||||
void printPgmString(const char *s)
|
|
||||||
{
|
|
||||||
char c;
|
|
||||||
while ((c = pgm_read_byte_near(s++)))
|
|
||||||
printByte(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void printIntegerInBase(unsigned long n, unsigned long base)
|
|
||||||
{
|
|
||||||
unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
|
|
||||||
unsigned long i = 0;
|
|
||||||
|
|
||||||
if (n == 0) {
|
|
||||||
printByte('0');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (n > 0) {
|
|
||||||
buf[i++] = n % base;
|
|
||||||
n /= base;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; i > 0; i--)
|
|
||||||
printByte(buf[i - 1] < 10 ?
|
|
||||||
'0' + buf[i - 1] :
|
|
||||||
'A' + buf[i - 1] - 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
void printInteger(long n)
|
|
||||||
{
|
|
||||||
if (n < 0) {
|
|
||||||
printByte('-');
|
|
||||||
n = -n;
|
|
||||||
}
|
|
||||||
|
|
||||||
printIntegerInBase(n, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
void printFloat(double n)
|
|
||||||
{
|
|
||||||
double integer_part, fractional_part;
|
|
||||||
fractional_part = modf(n, &integer_part);
|
|
||||||
printInteger(integer_part);
|
|
||||||
printByte('.');
|
|
||||||
printInteger(round(fractional_part*1000));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
18
serial.h
18
serial.h
@ -25,20 +25,8 @@
|
|||||||
#ifndef serial_h
|
#ifndef serial_h
|
||||||
#define serial_h
|
#define serial_h
|
||||||
|
|
||||||
void beginSerial(long);
|
void serial_init(long);
|
||||||
void serialWrite(uint8_t);
|
void serial_write(uint8_t);
|
||||||
int serialAnyAvailable(void);
|
uint8_t serial_read(void);
|
||||||
uint8_t serialRead(void);
|
|
||||||
void printMode(int);
|
|
||||||
void printByte(unsigned char c);
|
|
||||||
void printNewline(void);
|
|
||||||
void printString(const char *s);
|
|
||||||
void printPgmString(const char *s);
|
|
||||||
void printInteger(long n);
|
|
||||||
void printHex(unsigned long n);
|
|
||||||
void printOctal(unsigned long n);
|
|
||||||
void printBinary(unsigned long n);
|
|
||||||
void printIntegerInBase(unsigned long n, unsigned long base);
|
|
||||||
void printFloat(double n);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include "nuts_bolts.h"
|
#include "nuts_bolts.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "eeprom.h"
|
#include "eeprom.h"
|
||||||
#include "serial.h"
|
#include "print.h"
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
Loading…
Reference in New Issue
Block a user