printer: implement SPI based controller
This commit is contained in:
parent
7408dce74f
commit
37cfd93bef
@ -1,5 +1,5 @@
|
|||||||
MCU=atmega8
|
MCU=atmega8
|
||||||
CFLAGS=-g -Wall -mcall-prologues -mmcu=$(MCU) -Os -DF_CPU=8000000
|
CFLAGS=-g -Wall -mcall-prologues -mmcu=$(MCU) -O2 -DF_CPU=8000000
|
||||||
LDFLAGS=-Wl,-gc-sections -Wl,-relax
|
LDFLAGS=-Wl,-gc-sections -Wl,-relax
|
||||||
CC=avr-gcc
|
CC=avr-gcc
|
||||||
TARGET=main
|
TARGET=main
|
||||||
@ -15,6 +15,7 @@ clean:
|
|||||||
|
|
||||||
%.obj: $(OBJECT_FILES)
|
%.obj: $(OBJECT_FILES)
|
||||||
$(CC) $(CFLAGS) $(OBJECT_FILES) $(LDFLAGS) -o $@
|
$(CC) $(CFLAGS) $(OBJECT_FILES) $(LDFLAGS) -o $@
|
||||||
|
avr-size -C --mcu=atmega8 main.obj
|
||||||
|
|
||||||
program: $(TARGET).obj
|
program: $(TARGET).obj
|
||||||
avrdude -p $(MCU) -c usbasp -U flash:w:$(TARGET).hex
|
avrdude -p $(MCU) -c usbasp -U flash:w:$(TARGET).hex
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -7,6 +7,8 @@
|
|||||||
#define BAUDRATE 9600
|
#define BAUDRATE 9600
|
||||||
#define UBRR 51 // (F_CPU / BAUDRATE) / 32
|
#define UBRR 51 // (F_CPU / BAUDRATE) / 32
|
||||||
|
|
||||||
|
inline void spi_process_data();
|
||||||
|
|
||||||
/* System functions */
|
/* System functions */
|
||||||
/* Timers */
|
/* Timers */
|
||||||
enum TIMERS{TIM_CARRIAGE,
|
enum TIMERS{TIM_CARRIAGE,
|
||||||
@ -28,6 +30,8 @@ uint8_t block_for(uint8_t channel, uint16_t time_systicks)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t system_status; // CAUTION: Must not be updated from interrupts!
|
||||||
|
|
||||||
ISR (TIMER1_COMPA_vect)
|
ISR (TIMER1_COMPA_vect)
|
||||||
{
|
{
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
@ -36,7 +40,8 @@ ISR (TIMER1_COMPA_vect)
|
|||||||
timer[i]--;
|
timer[i]--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
if (SPSR & (1<<SPIF)) // We need to check and jump here, otherwise we'll be too slow.
|
||||||
|
spi_process_data();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Look-up-tables */
|
/* Look-up-tables */
|
||||||
@ -44,7 +49,8 @@ ISR (TIMER1_COMPA_vect)
|
|||||||
#define PRINTER_CONTROL_CHAR 56
|
#define PRINTER_CONTROL_CHAR 56
|
||||||
#define PRINTER_NO_CHAR 128
|
#define PRINTER_NO_CHAR 128
|
||||||
|
|
||||||
const uint8_t ascii_translation_table[128 + 12] PROGMEM = {
|
#define ASCII_TRANSLATION_TABLE_SIZE 128 + 12
|
||||||
|
const uint8_t ascii_translation_table[ASCII_TRANSLATION_TABLE_SIZE] PROGMEM = {
|
||||||
PRINTER_CONTROL_CHAR,
|
PRINTER_CONTROL_CHAR,
|
||||||
PRINTER_CONTROL_CHAR,
|
PRINTER_CONTROL_CHAR,
|
||||||
PRINTER_CONTROL_CHAR,
|
PRINTER_CONTROL_CHAR,
|
||||||
@ -202,21 +208,23 @@ const uint8_t ascii_translation_table[128 + 12] PROGMEM = {
|
|||||||
|
|
||||||
/* Hardware functions */
|
/* Hardware functions */
|
||||||
|
|
||||||
void uart_tx(char c)
|
void uart_putc(char c)
|
||||||
{
|
{
|
||||||
while (!(UCSRA & (1 << UDRE)));
|
while (!(UCSRA & (1 << UDRE)));
|
||||||
UDR = c;
|
UDR = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uart_write(char *c)
|
#define ENABLE_SERIAL_DEBUG
|
||||||
|
#ifdef ENABLE_SERIAL_DEBUG
|
||||||
|
void debug_write(char *c)
|
||||||
{
|
{
|
||||||
while (*c) {
|
while (*c) {
|
||||||
uart_tx(*c);
|
uart_putc(*c);
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int uart_printf(char *format,...)
|
unsigned int debug_printf(char *format,...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@ -227,10 +235,14 @@ unsigned int uart_printf(char *format,...)
|
|||||||
i = vsprintf (printbuffer, format, args);
|
i = vsprintf (printbuffer, format, args);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
|
|
||||||
uart_write(printbuffer);
|
debug_write(printbuffer);
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
void debug_write(char *c) {};
|
||||||
|
unsigned int debug_printf(char *format,...) {return 0;};
|
||||||
|
#endif
|
||||||
|
|
||||||
/* DC drive */
|
/* DC drive */
|
||||||
#define MOTLIM(t) t##C
|
#define MOTLIM(t) t##C
|
||||||
@ -298,6 +310,18 @@ const struct stepper_config STEPPER_CFG_WHEEL = {
|
|||||||
.wraparound = 96 * 2
|
.wraparound = 96 * 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define STEPPER_CFG_HW_LINEFEED(t) t##D
|
||||||
|
const struct stepper_config STEPPER_CFG_LINEFEED= {
|
||||||
|
.port = 'D',
|
||||||
|
.timch = TIM_LINEFEED,
|
||||||
|
.pin_a = (1 << 4),
|
||||||
|
.pin_b = (1 << 7),
|
||||||
|
.pin_c = (1 << 6),
|
||||||
|
.pin_d = (1 << 5),
|
||||||
|
.delay = 6 * TIMESCALE,
|
||||||
|
.wraparound = 0 /* No wraparound */
|
||||||
|
};
|
||||||
|
|
||||||
/* Stepper helpers */
|
/* Stepper helpers */
|
||||||
#define STEPPER_CFG(NAME) STEPPER_CFG_##NAME
|
#define STEPPER_CFG(NAME) STEPPER_CFG_##NAME
|
||||||
#define STEPPER_NEXT(NAME, DIR) stepper_next_f(&stepper_status_##NAME, \
|
#define STEPPER_NEXT(NAME, DIR) stepper_next_f(&stepper_status_##NAME, \
|
||||||
@ -318,6 +342,11 @@ struct stepper_status stepper_status_CARRIAGE = {
|
|||||||
.dir = -1,
|
.dir = -1,
|
||||||
.lpstate = 0
|
.lpstate = 0
|
||||||
};
|
};
|
||||||
|
struct stepper_status stepper_status_LINEFEED = {
|
||||||
|
.step = 0,
|
||||||
|
.dir = -1,
|
||||||
|
.lpstate = 0
|
||||||
|
};
|
||||||
|
|
||||||
/* Stepper functions */
|
/* Stepper functions */
|
||||||
uint8_t stepper_calc_ioc(uint8_t pstate, const struct stepper_config *cfg)
|
uint8_t stepper_calc_ioc(uint8_t pstate, const struct stepper_config *cfg)
|
||||||
@ -358,12 +387,12 @@ void stepper_next_f(struct stepper_status *stat,
|
|||||||
/* Apply current state */
|
/* Apply current state */
|
||||||
if (dir == 0) {
|
if (dir == 0) {
|
||||||
stat->lpstate = pstate;
|
stat->lpstate = pstate;
|
||||||
//if (cfg->port == 'B') uart_printf("[%d] stop at: %x\r\n", stat->step, pstate & 0xF);
|
//if (cfg->port == 'B') debug_printf("[%d] stop at: %x\r\n", stat->step, pstate & 0xF);
|
||||||
pstate &= ~(cfg->pin_a | cfg->pin_b | cfg->pin_c | cfg->pin_d);
|
pstate &= ~(cfg->pin_a | cfg->pin_b | cfg->pin_c | cfg->pin_d);
|
||||||
} else {
|
} else {
|
||||||
if (stat->dir == 0) { /* If this is the first step */
|
if (stat->dir == 0) { /* If this is the first step */
|
||||||
pstate |= stat->lpstate & (cfg->pin_a | cfg->pin_b | cfg->pin_c | cfg->pin_d);
|
pstate |= stat->lpstate & (cfg->pin_a | cfg->pin_b | cfg->pin_c | cfg->pin_d);
|
||||||
//if (cfg->port == 'B') uart_printf("[%d] restore to : %x\r\n", stat->step, pstate & 0xF);
|
//if (cfg->port == 'B') debug_printf("[%d] restore to : %x\r\n", stat->step, pstate & 0xF);
|
||||||
} else {
|
} else {
|
||||||
switch (stat->step) {
|
switch (stat->step) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -385,7 +414,7 @@ void stepper_next_f(struct stepper_status *stat,
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//if (cfg->port == 'B') uart_printf("[%d] set to : %x\r\n", stat->step, pstate & 0xF);
|
//if (cfg->port == 'B') debug_printf("[%d] set to : %x\r\n", stat->step, pstate & 0xF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,11 +493,11 @@ uint8_t stepper_perform_movement(struct stepper_status *stat,
|
|||||||
dir = stepper_required_direction(stat, cfg);
|
dir = stepper_required_direction(stat, cfg);
|
||||||
if ((dir == -1) && (stat->dir == 1)) { /* Reversal */
|
if ((dir == -1) && (stat->dir == 1)) { /* Reversal */
|
||||||
dir = 0;
|
dir = 0;
|
||||||
uart_write("[stp] Hard reversal detected. Pausing. -->|\r\n");
|
//debug_write("[stp] Hard reversal detected. Pausing. -->|\r\n");
|
||||||
set_timer(cfg->timch, cfg->delay * REVERSAL_MULTIPLIER);
|
set_timer(cfg->timch, cfg->delay * REVERSAL_MULTIPLIER);
|
||||||
} else if ((dir == 1) && (stat->dir == -1)) { /* Reversal */
|
} else if ((dir == 1) && (stat->dir == -1)) { /* Reversal */
|
||||||
dir = 0;
|
dir = 0;
|
||||||
uart_write("[stp] Hard reversal detected. Pausing. |<--\r\n");
|
//debug_write("[stp] Hard reversal detected. Pausing. |<--\r\n");
|
||||||
set_timer(cfg->timch, cfg->delay * REVERSAL_MULTIPLIER);
|
set_timer(cfg->timch, cfg->delay * REVERSAL_MULTIPLIER);
|
||||||
}
|
}
|
||||||
stepper_next_f(stat, cfg, dir);
|
stepper_next_f(stat, cfg, dir);
|
||||||
@ -477,7 +506,7 @@ uint8_t stepper_perform_movement(struct stepper_status *stat,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define POSITION_REACHED(NAME) (stepper_status_##NAME.pos == stepper_status_##NAME.target_pos)
|
#define POSITION_REACHED(NAME) ((stepper_status_##NAME.dir == 0) && (stepper_status_##NAME.pos == stepper_status_##NAME.target_pos))
|
||||||
|
|
||||||
#define SET_TARGET(NAME, target) stepper_set_target(&stepper_status_##NAME, \
|
#define SET_TARGET(NAME, target) stepper_set_target(&stepper_status_##NAME, \
|
||||||
&STEPPER_CFG_##NAME,\
|
&STEPPER_CFG_##NAME,\
|
||||||
@ -490,11 +519,11 @@ void stepper_set_target(struct stepper_status *stat,
|
|||||||
{
|
{
|
||||||
if (cfg->wraparound) {
|
if (cfg->wraparound) {
|
||||||
while (target >= -cfg->wraparound) {
|
while (target >= -cfg->wraparound) {
|
||||||
uart_printf("WRAP- %u\r\n", target);
|
debug_printf("WRAP- %u\r\n", target);
|
||||||
target += cfg->wraparound;
|
target += cfg->wraparound;
|
||||||
}
|
}
|
||||||
while (target >= cfg->wraparound) {
|
while (target >= cfg->wraparound) {
|
||||||
uart_printf("WRAP+ %u\r\n", target);
|
debug_printf("WRAP+ %u\r\n", target);
|
||||||
target -= cfg->wraparound;
|
target -= cfg->wraparound;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -511,6 +540,7 @@ void arm_hammer()
|
|||||||
|
|
||||||
#define DCMOTOR_EN MOTLIM(PORT) |= PIN_DCMOTOR
|
#define DCMOTOR_EN MOTLIM(PORT) |= PIN_DCMOTOR
|
||||||
#define DCMOTOR_STOP MOTLIM(PORT) &= ~PIN_DCMOTOR
|
#define DCMOTOR_STOP MOTLIM(PORT) &= ~PIN_DCMOTOR
|
||||||
|
#define DCMOTOR_ISACTIVE (MOTLIM(PORT) & PIN_DCMOTOR)
|
||||||
#define LIMITSWITCH (!(MOTLIM(PIN) & PIN_LIMITSWITCH))
|
#define LIMITSWITCH (!(MOTLIM(PIN) & PIN_LIMITSWITCH))
|
||||||
|
|
||||||
|
|
||||||
@ -526,7 +556,22 @@ void move_carriage_to_far_left(uint8_t reset)
|
|||||||
}
|
}
|
||||||
stepper_status_CARRIAGE.dir = -1;
|
stepper_status_CARRIAGE.dir = -1;
|
||||||
|
|
||||||
uart_write("[car] Moving carriage to far left...\r\n");
|
if (LIMITSWITCH) {
|
||||||
|
debug_write("[car] Clearing switch area...\r\n");
|
||||||
|
while (LIMITSWITCH) {
|
||||||
|
if (block_for(TIM_CARRIAGE, STEPPER_CFG_CARRIAGE.delay)) {
|
||||||
|
STEPPER_NEXT(CARRIAGE, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (cnt = 0; cnt < 16; cnt++) {
|
||||||
|
STEPPER_NEXT(CARRIAGE, 1);
|
||||||
|
}
|
||||||
|
STEPPER_STOP(CARRIAGE);
|
||||||
|
_delay_ms(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_write("[car] Moving carriage to far left...\r\n");
|
||||||
|
cnt = 0;
|
||||||
while (!LIMITSWITCH) {
|
while (!LIMITSWITCH) {
|
||||||
if (block_for(TIM_CARRIAGE, STEPPER_CFG_CARRIAGE.delay)) {
|
if (block_for(TIM_CARRIAGE, STEPPER_CFG_CARRIAGE.delay)) {
|
||||||
cnt++;
|
cnt++;
|
||||||
@ -539,14 +584,14 @@ void move_carriage_to_far_left(uint8_t reset)
|
|||||||
stepper_status_CARRIAGE.pos = 0;
|
stepper_status_CARRIAGE.pos = 0;
|
||||||
stepper_status_CARRIAGE.target_pos = 0;
|
stepper_status_CARRIAGE.target_pos = 0;
|
||||||
|
|
||||||
uart_printf("[car] Carriage left after %u steps.\r\n", cnt);
|
debug_printf("[car] Carriage left after %u steps.\r\n", cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void align_daisy_wheel()
|
void align_daisy_wheel()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
uart_write("[whl] Aligning wheel...\r\n");
|
debug_write("[whl] Aligning wheel...\r\n");
|
||||||
stepper_status_WHEEL.dir = 0;
|
stepper_status_WHEEL.dir = 0;
|
||||||
stepper_status_WHEEL.lpstate = 0;
|
stepper_status_WHEEL.lpstate = 0;
|
||||||
stepper_status_WHEEL.pos = 0;
|
stepper_status_WHEEL.pos = 0;
|
||||||
@ -554,6 +599,15 @@ void align_daisy_wheel()
|
|||||||
stepper_status_WHEEL.target_pos = 0;
|
stepper_status_WHEEL.target_pos = 0;
|
||||||
stepper_status_WHEEL.ldir = 0;
|
stepper_status_WHEEL.ldir = 0;
|
||||||
|
|
||||||
|
/* Rotate right for one revolution -> lock daisy wheel to assembly */
|
||||||
|
for (i = 0; i < (96 + 1) * 2; ) {
|
||||||
|
if (block_for(TIM_WHEEL, STEPPER_CFG_WHEEL.delay)) {
|
||||||
|
STEPPER_NEXT(WHEEL, 1);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rotate left for one revolution -> align daisy wheel assembly */
|
||||||
for (i = 0; i < (96 + 1) * 2; ) {
|
for (i = 0; i < (96 + 1) * 2; ) {
|
||||||
if (block_for(TIM_WHEEL, STEPPER_CFG_WHEEL.delay)) {
|
if (block_for(TIM_WHEEL, STEPPER_CFG_WHEEL.delay)) {
|
||||||
STEPPER_NEXT(WHEEL, -1);
|
STEPPER_NEXT(WHEEL, -1);
|
||||||
@ -576,190 +630,548 @@ void align_daisy_wheel()
|
|||||||
stepper_status_WHEEL.target_pos = 0;
|
stepper_status_WHEEL.target_pos = 0;
|
||||||
stepper_status_WHEEL.pos = 4;
|
stepper_status_WHEEL.pos = 4;
|
||||||
|
|
||||||
uart_write("[whl] Alignment completed.\r\n");
|
debug_write("[whl] Alignment completed.\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset_printhead()
|
void reset_printhead()
|
||||||
{
|
{
|
||||||
uart_write("[hmr] Resetting printhead...\r\n");
|
debug_write("[hmr] Resetting printhead...\r\n");
|
||||||
DCMOTOR_EN;
|
DCMOTOR_EN;
|
||||||
_delay_ms(200);
|
_delay_ms(200);
|
||||||
DCMOTOR_STOP;
|
DCMOTOR_STOP;
|
||||||
uart_write("[hmr] Printhead reset completed.\r\n");
|
debug_write("[hmr] Printhead reset completed.\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int system_test_auto()
|
void initialize_paperfeed()
|
||||||
{
|
{
|
||||||
char c;
|
int i;
|
||||||
int do_it = 0;
|
|
||||||
int print_stat = 0;
|
|
||||||
|
|
||||||
uart_write("[sys] Entering system test mode\r\n");
|
debug_write("[lfd] Initializing paperfeed...\r\n");
|
||||||
uart_write(">");
|
|
||||||
|
|
||||||
while(1) {
|
for (i = 0; i < 10;) {
|
||||||
if (UCSRA & (1 << RXC)) {
|
if (block_for(TIM_LINEFEED, STEPPER_CFG_LINEFEED.delay)) {
|
||||||
print_stat = 1;
|
STEPPER_NEXT(LINEFEED, 1);
|
||||||
c = UDR;
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
STEPPER_STOP(LINEFEED);
|
||||||
|
|
||||||
|
stepper_status_LINEFEED.dir = 0;
|
||||||
|
stepper_status_LINEFEED.lpstate = 0;
|
||||||
|
stepper_status_LINEFEED.pos = 32768;
|
||||||
|
stepper_status_LINEFEED.step = 0;
|
||||||
|
stepper_status_LINEFEED.target_pos = 32768;
|
||||||
|
stepper_status_LINEFEED.ldir = 0;
|
||||||
|
|
||||||
|
debug_write("[lfd] Initialization completed.\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
//int system_test_auto()
|
||||||
|
//{
|
||||||
|
// char c;
|
||||||
|
// int do_it = 0;
|
||||||
|
// int print_stat = 0;
|
||||||
|
|
||||||
|
// debug_write("[sys] Entering system test mode\r\n");
|
||||||
|
// debug_write(">");
|
||||||
|
|
||||||
|
// while(1) {
|
||||||
|
// if (UCSRA & (1 << RXC)) {
|
||||||
|
// print_stat = 1;
|
||||||
|
// c = UDR;
|
||||||
|
|
||||||
|
// if (c >= '0' && c <= '9') {
|
||||||
|
// stepper_status_CARRIAGE.target_pos = 100 * (c - '0');
|
||||||
|
// } else {
|
||||||
|
// switch (c) {
|
||||||
|
// case ' ':
|
||||||
|
// stepper_status_CARRIAGE.target_pos += 10;
|
||||||
|
// break;
|
||||||
|
// case 'z':
|
||||||
|
// if (stepper_status_CARRIAGE.target_pos >= 10)
|
||||||
|
// stepper_status_CARRIAGE.target_pos -= 10;
|
||||||
|
// break;
|
||||||
|
// case 'r':
|
||||||
|
// move_carriage_to_far_left(0);
|
||||||
|
// break;
|
||||||
|
// case 'h':
|
||||||
|
// DCMOTOR_EN;
|
||||||
|
// arm_hammer();
|
||||||
|
// _delay_ms(100); /* Note, this also locks the carriage movement -> important! */
|
||||||
|
// DCMOTOR_STOP;
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// switch (c) {
|
||||||
|
// case '\'':
|
||||||
|
// //if (stepper_status_WHEEL.target_pos >= 2)
|
||||||
|
// SET_TARGET_DELTA(WHEEL, -2);
|
||||||
|
// debug_printf("[whl] New wheel: %d\r\n", stepper_status_WHEEL.target_pos);
|
||||||
|
// break;
|
||||||
|
// case ',':
|
||||||
|
// SET_TARGET_DELTA(WHEEL, 2);
|
||||||
|
// debug_printf("[whl] New wheel: %d\r\n", stepper_status_WHEEL.target_pos);
|
||||||
|
// break;
|
||||||
|
// case 'w':
|
||||||
|
// align_daisy_wheel();
|
||||||
|
// break;
|
||||||
|
// case 't':
|
||||||
|
// stepper_status_WHEEL.target_pos += 2;
|
||||||
|
// stepper_status_CARRIAGE.target_pos += 10;
|
||||||
|
// do_it = 1;
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// stepper_perform_movement(&stepper_status_CARRIAGE, &STEPPER_CFG_CARRIAGE);
|
||||||
|
// stepper_perform_movement(&stepper_status_WHEEL, &STEPPER_CFG_WHEEL);
|
||||||
|
|
||||||
|
// if (POSITION_REACHED(WHEEL) && POSITION_REACHED(CARRIAGE) && print_stat) {
|
||||||
|
// print_stat = 0;
|
||||||
|
// debug_printf("[pos] CAR: %u\r\n[pos] WHL: %u\r\n",
|
||||||
|
// stepper_status_CARRIAGE.pos,
|
||||||
|
// stepper_status_WHEEL.pos);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (do_it) {
|
||||||
|
// if (stepper_status_CARRIAGE.pos == stepper_status_CARRIAGE.target_pos) {
|
||||||
|
// do_it = 0;
|
||||||
|
// DCMOTOR_EN;
|
||||||
|
// arm_hammer();
|
||||||
|
// _delay_ms(100);
|
||||||
|
// DCMOTOR_STOP;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//void printer_test()
|
||||||
|
//{
|
||||||
|
// uint8_t buf[80] = {0};
|
||||||
|
// uint8_t *ptr = buf;
|
||||||
|
// uint8_t *rdptr = buf;
|
||||||
|
// uint8_t translated = 0;
|
||||||
|
// int state = 0;
|
||||||
|
|
||||||
|
// debug_write("[sys] Entering printer test mode\r\n");
|
||||||
|
|
||||||
|
// while(1) {
|
||||||
|
|
||||||
|
// switch (state) {
|
||||||
|
// case 0:
|
||||||
|
// _delay_ms(100); // Motor turnoff delay
|
||||||
|
// DCMOTOR_STOP;
|
||||||
|
|
||||||
|
// stepper_status_CARRIAGE.target_pos = 80;
|
||||||
|
// stepper_status_WHEEL.target_pos = 0;stat->lpstate = pstate;
|
||||||
|
// ptr = buf;
|
||||||
|
// debug_write(">");
|
||||||
|
// state++;
|
||||||
|
// break;
|
||||||
|
// case 1:
|
||||||
|
// if (UCSRA & (1 << RXC)) {
|
||||||
|
// //stepper_status_WHEEL.target_pos += 2;
|
||||||
|
// *ptr = UDR;
|
||||||
|
// uart_putc(*ptr);
|
||||||
|
// if (*ptr == '\r') {
|
||||||
|
// debug_write("\r\nOK.\r\n");
|
||||||
|
// DCMOTOR_EN;
|
||||||
|
// _delay_ms(100); // Let motor get up to speed
|
||||||
|
|
||||||
|
// state++;
|
||||||
|
|
||||||
|
// stepper_status_CARRIAGE.target_pos = 80;
|
||||||
|
// rdptr = buf;
|
||||||
|
// } else {
|
||||||
|
// ptr++;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// break;
|
||||||
|
// case 2:
|
||||||
|
// stepper_status_CARRIAGE.target_pos += 10;
|
||||||
|
// translated = pgm_read_byte(&ascii_translation_table[*rdptr]);
|
||||||
|
// if (translated != PRINTER_NO_CHAR) {
|
||||||
|
// //debug_printf("Prepare: %x (%c) -> %d", *rdptr, *rdptr, translated);
|
||||||
|
// SET_TARGET(WHEEL, translated * 2);
|
||||||
|
// state++;
|
||||||
|
// } else {
|
||||||
|
// //debug_printf("Skip: %x (%c) -> %d\r\n", *rdptr, *rdptr, translated);
|
||||||
|
// rdptr++;
|
||||||
|
// if (rdptr == ptr) {
|
||||||
|
// state = 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// break;
|
||||||
|
// case 3:
|
||||||
|
// if (POSITION_REACHED(CARRIAGE) && POSITION_REACHED(WHEEL)) {
|
||||||
|
// //debug_write("!!!\r\n");
|
||||||
|
// //DCMOTOR_EN;
|
||||||
|
// arm_hammer();
|
||||||
|
// _delay_ms(50);
|
||||||
|
// //DCMOTOR_STOP;
|
||||||
|
// rdptr++;
|
||||||
|
// if (rdptr == ptr) {
|
||||||
|
// state = 0;
|
||||||
|
// } else {
|
||||||
|
// state--;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// stepper_perform_movement(&stepper_status_CARRIAGE, &STEPPER_CFG_CARRIAGE);
|
||||||
|
// stepper_perform_movement(&stepper_status_WHEEL, &STEPPER_CFG_WHEEL);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//void systick_test()
|
||||||
|
//{
|
||||||
|
// debug_write("[tmr] System timer test\r\n");
|
||||||
|
// while (1) {
|
||||||
|
// if (block_for(0, 1000*4)) {
|
||||||
|
// debug_write("hello");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
void hardfault() {
|
||||||
|
debug_write("HARDFAULT!\r\n");
|
||||||
|
STEPPER_STOP(WHEEL);
|
||||||
|
STEPPER_STOP(CARRIAGE);
|
||||||
|
STEPPER_STOP(LINEFEED);
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SPI */
|
||||||
|
#define PRINT_BUFFER_SIZE 256 // Important: must be 256 atm, when changed, you need to change code handling print_buffer_*.
|
||||||
|
volatile char print_buffer[PRINT_BUFFER_SIZE];
|
||||||
|
volatile uint8_t print_buffer_wr = 0;
|
||||||
|
volatile uint8_t print_buffer_rd = 0;
|
||||||
|
|
||||||
|
#define SPI_COMMAND_NONE 0x00
|
||||||
|
|
||||||
|
#define SPI_COMMAND_PRINTER_WRITE 0x01
|
||||||
|
#define SPI_COMMAND_PRINTER_RESET 0x02
|
||||||
|
#define SPI_COMMAND_PRINTER_SETMODE 0x03
|
||||||
|
#define SPI_COMMAND_PRINTER_MANUAL 0x04
|
||||||
|
#define SPI_COMMAND_PRINTER_PAUSE 0x05
|
||||||
|
#define SPI_COMMAND_PRINTER_RESUME 0x06
|
||||||
|
#define SPI_COMMAND_PRINTER_CLEARBUF 0x07
|
||||||
|
|
||||||
|
#define SPI_COMMAND_KEYBOARD_GETKEY 0x20
|
||||||
|
#define SPI_COMMAND_KEYBOARD_CLEARBUF 0x21
|
||||||
|
|
||||||
|
#define SPI_COMMAND_SYSTEM_BACKLIGHT 0x40
|
||||||
|
|
||||||
|
#define UART_CMD_ACK_KEYPRESS 'A'
|
||||||
|
|
||||||
|
#define SPI_GET_CS (!(PINB & (1 << 2)))
|
||||||
|
#define UART_BYTE_READY (UCSRA & (1 << RXC))
|
||||||
|
|
||||||
|
volatile uint8_t spi_command = SPI_COMMAND_NONE;
|
||||||
|
volatile uint8_t keys_to_be_acked = 0;
|
||||||
|
|
||||||
|
/* This function needs to be fast AF! */
|
||||||
|
inline void spi_process_data()
|
||||||
|
{
|
||||||
|
switch (spi_command) {
|
||||||
|
case SPI_COMMAND_KEYBOARD_GETKEY: /* Needs to be first, quick reply expected. */
|
||||||
|
if (UART_BYTE_READY) {
|
||||||
|
SPDR = UDR;
|
||||||
|
keys_to_be_acked++;
|
||||||
|
} else {
|
||||||
|
SPDR = 0x00;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* !!! Only no-reply commands below !!! */
|
||||||
|
case SPI_COMMAND_NONE: /* This is the start of the transaction */
|
||||||
|
spi_command = SPDR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SPI_COMMAND_PRINTER_WRITE:
|
||||||
|
print_buffer[print_buffer_wr++] = SPDR; // WARNING: No overflow protection
|
||||||
|
// Will auto wrap at 256; print_buffer_wr = print_buffer_wr % PRINT_BUFFER_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
//SPDR = 0x0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(SPI_STC_vect)
|
||||||
|
{
|
||||||
|
spi_process_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ioc_process()
|
||||||
|
{
|
||||||
|
if (!SPI_GET_CS) {
|
||||||
|
/* Cancel the current command */
|
||||||
|
spi_command = SPI_COMMAND_NONE;
|
||||||
|
SPDR = system_status; // TODO: status 1
|
||||||
|
}
|
||||||
|
if (keys_to_be_acked && (UCSRA & (1 << UDRE))) {
|
||||||
|
UDR = UART_CMD_ACK_KEYPRESS;
|
||||||
|
keys_to_be_acked--;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PRINT_CHARACTER_WIDTH 10
|
||||||
|
#define PRINT_LINE_HEIGHT 34
|
||||||
|
#define PRINTER_STOP_RIGHT 1100
|
||||||
|
|
||||||
|
enum printer_mode_t {MANUAL, INTELLIGENT};
|
||||||
|
|
||||||
|
#define GET_PRINT_CODE(c) (pgm_read_byte(&ascii_translation_table[c]))
|
||||||
|
|
||||||
|
uint16_t print_margin_left = 100;
|
||||||
|
uint16_t print_margin_right = PRINTER_STOP_RIGHT - 100;
|
||||||
|
|
||||||
|
int8_t move_one_character(uint8_t backward)
|
||||||
|
{
|
||||||
|
if (backward) {
|
||||||
|
if (stepper_status_CARRIAGE.target_pos < print_margin_left + PRINT_CHARACTER_WIDTH) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
stepper_status_CARRIAGE.target_pos -= PRINT_CHARACTER_WIDTH;
|
||||||
|
} else {
|
||||||
|
if (stepper_status_CARRIAGE.target_pos >= print_margin_right - PRINT_CHARACTER_WIDTH) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
stepper_status_CARRIAGE.target_pos += PRINT_CHARACTER_WIDTH;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void move_carriage_to_left_margin()
|
||||||
|
{
|
||||||
|
stepper_status_CARRIAGE.target_pos = print_margin_left;
|
||||||
|
debug_putc('\r');
|
||||||
|
debug_putc('{');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Simulates the print of one line and returns the end position of the printhead */
|
||||||
|
/* It's only called once, so inline is good. */
|
||||||
|
inline int8_t simulate_print_run(uint8_t *start_end_index, uint8_t *recovery_index)
|
||||||
|
{
|
||||||
|
char current_char;
|
||||||
|
uint8_t index;
|
||||||
|
uint16_t carriage_position;
|
||||||
|
uint8_t translated;
|
||||||
|
uint8_t status = 0;
|
||||||
|
uint8_t line_matters = 0;
|
||||||
|
|
||||||
|
index = *start_end_index;
|
||||||
|
carriage_position = print_margin_left;
|
||||||
|
|
||||||
|
while (!status) {
|
||||||
|
current_char = print_buffer[index];
|
||||||
|
|
||||||
|
if (index == print_buffer_wr) { /* END OF BUFFER - Can't determine length */
|
||||||
|
status = 3;
|
||||||
|
line_matters = 1;
|
||||||
|
carriage_position = print_margin_right;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_char == '\n') {
|
||||||
|
index--;
|
||||||
|
status = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
} else if (current_char < ASCII_TRANSLATION_TABLE_SIZE) {
|
||||||
|
translated = GET_PRINT_CODE(current_char);
|
||||||
|
|
||||||
|
if (translated == PRINTER_CONTROL_CHAR) {
|
||||||
|
// ignore
|
||||||
|
|
||||||
if (c >= '0' && c <= '9') {
|
|
||||||
stepper_status_CARRIAGE.target_pos = 100 * (c - '0');
|
|
||||||
} else {
|
} else {
|
||||||
switch (c) {
|
if (carriage_position >= print_margin_right - PRINT_CHARACTER_WIDTH) {
|
||||||
case ' ':
|
status = 2;
|
||||||
stepper_status_CARRIAGE.target_pos += 10;
|
carriage_position += PRINT_CHARACTER_WIDTH;
|
||||||
break;
|
//(*recovery_index) = index + 1;
|
||||||
case 'z':
|
break; /* Don't consume character */
|
||||||
if (stepper_status_CARRIAGE.target_pos >= 10)
|
} else {
|
||||||
stepper_status_CARRIAGE.target_pos -= 10;
|
carriage_position += PRINT_CHARACTER_WIDTH;
|
||||||
break;
|
if (translated != PRINTER_NO_CHAR) {
|
||||||
case 'r':
|
line_matters = 1;
|
||||||
move_carriage_to_far_left(0);
|
}
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
DCMOTOR_EN;
|
|
||||||
arm_hammer();
|
|
||||||
_delay_ms(100); /* Note, this also locks the carriage movement -> important! */
|
|
||||||
DCMOTOR_STOP;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (c) {
|
|
||||||
case '\'':
|
|
||||||
//if (stepper_status_WHEEL.target_pos >= 2)
|
|
||||||
SET_TARGET_DELTA(WHEEL, -2);
|
|
||||||
uart_printf("[whl] New wheel: %d\r\n", stepper_status_WHEEL.target_pos);
|
|
||||||
break;
|
|
||||||
case ',':
|
|
||||||
SET_TARGET_DELTA(WHEEL, 2);
|
|
||||||
uart_printf("[whl] New wheel: %d\r\n", stepper_status_WHEEL.target_pos);
|
|
||||||
break;
|
|
||||||
case 'w':
|
|
||||||
align_daisy_wheel();
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
stepper_status_WHEEL.target_pos += 2;
|
|
||||||
stepper_status_CARRIAGE.target_pos += 10;
|
|
||||||
do_it = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stepper_perform_movement(&stepper_status_CARRIAGE, &STEPPER_CFG_CARRIAGE);
|
index++; /* Consume character */
|
||||||
stepper_perform_movement(&stepper_status_WHEEL, &STEPPER_CFG_WHEEL);
|
(*recovery_index) = index + 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (POSITION_REACHED(WHEEL) && POSITION_REACHED(CARRIAGE) && print_stat) {
|
carriage_position -= PRINT_CHARACTER_WIDTH;
|
||||||
print_stat = 0;
|
*start_end_index = index;
|
||||||
uart_printf("[pos] CAR: %u\r\n[pos] WHL: %u\r\n",
|
|
||||||
stepper_status_CARRIAGE.pos,
|
|
||||||
stepper_status_WHEEL.pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (do_it) {
|
//debug_printf("$ restore to: %d M=%d S=%d\n", print_buffer[*recovery_index], line_matters, status);
|
||||||
if (stepper_status_CARRIAGE.pos == stepper_status_CARRIAGE.target_pos) {
|
//debug_printf("CMP %d <= %d\n", ((carriage_position - print_margin_left) / 2) , (stepper_status_CARRIAGE.target_pos - print_margin_left));
|
||||||
do_it = 0;
|
if (!line_matters) {
|
||||||
|
return 0;
|
||||||
|
} else if (((carriage_position - print_margin_left) / 2) < (stepper_status_CARRIAGE.target_pos - print_margin_left)) {
|
||||||
|
//debug_printf("next char: %c\n", print_buffer[index]);
|
||||||
|
//_delay_ms(5000);
|
||||||
|
stepper_status_CARRIAGE.target_pos = carriage_position;
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum printer_state {INIT, IDLE, HAMMER, PAUSED};
|
||||||
|
void printer_process()
|
||||||
|
{
|
||||||
|
static enum printer_state state = INIT;
|
||||||
|
static uint8_t backward = 0;
|
||||||
|
static uint8_t print_buffer_backward = 0;
|
||||||
|
static uint8_t print_buffer_recovery = 0;
|
||||||
|
|
||||||
|
static uint8_t current_is_linebreak = 0;
|
||||||
|
char current_char;
|
||||||
|
uint8_t translated;
|
||||||
|
|
||||||
|
uint8_t end_of_next_line = 0;
|
||||||
|
int8_t temp;
|
||||||
|
static char debug_character = 0;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case IDLE:
|
||||||
|
if (print_buffer_rd != print_buffer_wr) { // maybe add "|| current_is_linebreak"
|
||||||
|
if (!DCMOTOR_ISACTIVE) {
|
||||||
DCMOTOR_EN;
|
DCMOTOR_EN;
|
||||||
arm_hammer();
|
_delay_ms(100); /* Let the motor get up to speed */
|
||||||
_delay_ms(100);
|
|
||||||
DCMOTOR_STOP;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void printer_test()
|
/* Fetch new character from buffer */
|
||||||
{
|
if (!current_is_linebreak) {
|
||||||
uint8_t buf[80] = {0};
|
if (backward) {
|
||||||
uint8_t *ptr = buf;
|
current_char = print_buffer[print_buffer_backward];
|
||||||
uint8_t *rdptr = buf;
|
print_buffer_backward--;
|
||||||
uint8_t translated = 0;
|
|
||||||
int state = 0;
|
|
||||||
|
|
||||||
uart_write("[sys] Entering printer test mode\r\n");
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
case 0:
|
|
||||||
_delay_ms(100); // Motor turnoff delay
|
|
||||||
DCMOTOR_STOP;
|
|
||||||
|
|
||||||
stepper_status_CARRIAGE.target_pos = 80;
|
|
||||||
stepper_status_WHEEL.target_pos = 0;
|
|
||||||
ptr = buf;
|
|
||||||
uart_write(">");
|
|
||||||
state++;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if (UCSRA & (1 << RXC)) {
|
|
||||||
//stepper_status_WHEEL.target_pos += 2;
|
|
||||||
*ptr = UDR;
|
|
||||||
uart_tx(*ptr);
|
|
||||||
if (*ptr == '\r') {
|
|
||||||
uart_write("\r\nOK.\r\n");
|
|
||||||
DCMOTOR_EN;
|
|
||||||
_delay_ms(100); // Let motor get up to speed
|
|
||||||
|
|
||||||
state++;
|
|
||||||
|
|
||||||
stepper_status_CARRIAGE.target_pos = 80;
|
|
||||||
rdptr = buf;
|
|
||||||
} else {
|
} else {
|
||||||
ptr++;
|
current_char = print_buffer[print_buffer_rd];
|
||||||
|
print_buffer_rd++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
stepper_status_CARRIAGE.target_pos += 10;
|
|
||||||
translated = pgm_read_byte(&ascii_translation_table[*rdptr]);
|
|
||||||
if (translated != PRINTER_NO_CHAR) {
|
|
||||||
//uart_printf("Prepare: %x (%c) -> %d", *rdptr, *rdptr, translated);
|
|
||||||
SET_TARGET(WHEEL, translated * 2);
|
|
||||||
state++;
|
|
||||||
} else {
|
} else {
|
||||||
//uart_printf("Skip: %x (%c) -> %d\r\n", *rdptr, *rdptr, translated);
|
current_char = '\0';
|
||||||
rdptr++;
|
|
||||||
if (rdptr == ptr) {
|
|
||||||
state = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
if (POSITION_REACHED(CARRIAGE) && POSITION_REACHED(WHEEL)) {
|
|
||||||
//uart_write("!!!\r\n");
|
|
||||||
//DCMOTOR_EN;
|
|
||||||
arm_hammer();
|
|
||||||
_delay_ms(50);
|
|
||||||
//DCMOTOR_STOP;
|
|
||||||
rdptr++;
|
|
||||||
if (rdptr == ptr) {
|
|
||||||
state = 0;
|
|
||||||
} else {
|
|
||||||
state--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
stepper_perform_movement(&stepper_status_CARRIAGE, &STEPPER_CFG_CARRIAGE);
|
/* Check whether the current character is a command or something to print */
|
||||||
stepper_perform_movement(&stepper_status_WHEEL, &STEPPER_CFG_WHEEL);
|
current_is_linebreak += (current_char == '\n');
|
||||||
|
if (current_is_linebreak) {
|
||||||
|
if (backward) {
|
||||||
|
uart_putc('=');
|
||||||
|
print_buffer_rd = print_buffer_recovery;
|
||||||
|
}
|
||||||
|
backward = 0; // Re-evaluate backward. Default is forward.
|
||||||
|
|
||||||
|
stepper_status_LINEFEED.target_pos -= PRINT_LINE_HEIGHT;
|
||||||
|
uart_putc('\n');
|
||||||
|
current_is_linebreak--;
|
||||||
|
//_delay_ms(1000);
|
||||||
|
|
||||||
|
/* Decide whether we move the carriage back to the left, or
|
||||||
|
* whether print the new line in reverse. */
|
||||||
|
|
||||||
|
end_of_next_line = print_buffer_rd;
|
||||||
|
temp = simulate_print_run(&end_of_next_line, &print_buffer_recovery);
|
||||||
|
|
||||||
|
if (temp == -1) {
|
||||||
|
//uart_putc('\r');
|
||||||
|
uart_putc('[');
|
||||||
|
backward = 1;
|
||||||
|
print_buffer_backward = end_of_next_line;
|
||||||
|
|
||||||
|
} else if (temp == 0) {
|
||||||
|
// do nothing
|
||||||
|
uart_putc('#');
|
||||||
|
|
||||||
|
} else {
|
||||||
|
move_carriage_to_left_margin();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (current_char < ASCII_TRANSLATION_TABLE_SIZE) {
|
||||||
|
translated = GET_PRINT_CODE(current_char);
|
||||||
|
debug_character = current_char;
|
||||||
|
|
||||||
|
switch (translated) {
|
||||||
|
case PRINTER_CONTROL_CHAR:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PRINTER_NO_CHAR:
|
||||||
|
current_is_linebreak += move_one_character(backward);
|
||||||
|
if (!current_is_linebreak)
|
||||||
|
uart_putc(' ');
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: /* It's a printable character */
|
||||||
|
SET_TARGET(WHEEL, translated * 2);
|
||||||
|
state = HAMMER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO: Handle special commands
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
DCMOTOR_STOP;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAMMER:
|
||||||
|
if (POSITION_REACHED(WHEEL) && POSITION_REACHED(CARRIAGE) && POSITION_REACHED(LINEFEED)) {
|
||||||
|
arm_hammer();
|
||||||
|
_delay_ms(50); // TODO: replace with timer
|
||||||
|
uart_putc(debug_character);
|
||||||
|
current_is_linebreak += move_one_character(backward);
|
||||||
|
state = IDLE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INIT:
|
||||||
|
move_carriage_to_left_margin();
|
||||||
|
state = IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// if (print_buffer_rd != print_buffer_wr) {
|
||||||
|
// if (UCSRA & (1 << UDRE)) {
|
||||||
|
// UDR = print_buffer[print_buffer_rd++];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// // debug only: load the CPU with some stepper movements
|
||||||
|
// pgm_read_byte(&ascii_translation_table[123]);
|
||||||
|
// stepper_status_CARRIAGE.target_pos += 10;
|
||||||
|
// stepper_status_WHEEL.target_pos += 10;
|
||||||
|
// // -----------
|
||||||
|
|
||||||
|
if (stepper_status_CARRIAGE.target_pos > PRINTER_STOP_RIGHT) { // Right margin safety
|
||||||
|
hardfault();
|
||||||
|
}
|
||||||
|
stepper_perform_movement(&stepper_status_LINEFEED, &STEPPER_CFG_LINEFEED);
|
||||||
|
stepper_perform_movement(&stepper_status_CARRIAGE, &STEPPER_CFG_CARRIAGE);
|
||||||
|
stepper_perform_movement(&stepper_status_WHEEL, &STEPPER_CFG_WHEEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void systick_test()
|
void mainloop()
|
||||||
{
|
{
|
||||||
uart_write("[tmr] System timer test\r\n");
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (block_for(0, 1000*4)) {
|
printer_process();
|
||||||
uart_write("hello");
|
ioc_process();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -778,6 +1190,10 @@ int main()
|
|||||||
UBRRH = (UBRR >> 8) & 0xFF;
|
UBRRH = (UBRR >> 8) & 0xFF;
|
||||||
UBRRL = UBRR & 0xFF;
|
UBRRL = UBRR & 0xFF;
|
||||||
|
|
||||||
|
/* Set up SPI */
|
||||||
|
DDRB |= (1 << PB4);
|
||||||
|
SPCR = (1 << SPE) | (1 << CPOL) | (1 << CPHA) | (1 << SPIE);
|
||||||
|
|
||||||
/* Set up DC components */
|
/* Set up DC components */
|
||||||
MOTLIM(DDR) |= PIN_DCMOTOR;
|
MOTLIM(DDR) |= PIN_DCMOTOR;
|
||||||
MOTLIM(DDR) &= ~(PIN_LIMITSWITCH);
|
MOTLIM(DDR) &= ~(PIN_LIMITSWITCH);
|
||||||
@ -788,6 +1204,7 @@ int main()
|
|||||||
/* Set up steppers */
|
/* Set up steppers */
|
||||||
STEPPER_SET_IO(CARRIAGE);
|
STEPPER_SET_IO(CARRIAGE);
|
||||||
STEPPER_SET_IO(WHEEL);
|
STEPPER_SET_IO(WHEEL);
|
||||||
|
STEPPER_SET_IO(LINEFEED);
|
||||||
|
|
||||||
/* Set up SysTick Timer */
|
/* Set up SysTick Timer */
|
||||||
TCCR1B = (1 << WGM12) | (1 << CS11); // f_tim = 8 MHz / 8
|
TCCR1B = (1 << WGM12) | (1 << CS11); // f_tim = 8 MHz / 8
|
||||||
@ -795,22 +1212,25 @@ int main()
|
|||||||
TIMSK = (1 << OCIE1A);
|
TIMSK = (1 << OCIE1A);
|
||||||
|
|
||||||
/* Init system */
|
/* Init system */
|
||||||
uart_write("\n\n\r[sys] STARTING IO CONTROLLER...\r\n");
|
system_status = 0;
|
||||||
uart_write("[sys] Enabling interrupts.\r\n");
|
debug_write("\n\n\r[sys] STARTING IO CONTROLLER...\r\n");
|
||||||
|
debug_write("[sys] Enabling interrupts.\r\n");
|
||||||
sei();
|
sei();
|
||||||
|
|
||||||
/* Align printer */
|
/* Align printer */
|
||||||
|
initialize_paperfeed();
|
||||||
move_carriage_to_far_left(1);
|
move_carriage_to_far_left(1);
|
||||||
align_daisy_wheel();
|
align_daisy_wheel();
|
||||||
reset_printhead();
|
reset_printhead();
|
||||||
|
|
||||||
uart_write("[sys] Startup completed.\r\n");
|
debug_write("[sys] Startup completed.\r\n");
|
||||||
|
|
||||||
/* Run system */
|
/* Run system */
|
||||||
printer_test();
|
mainloop();
|
||||||
system_test_auto();
|
// printer_test();
|
||||||
systick_test();
|
// system_test_auto();
|
||||||
|
// systick_test();
|
||||||
|
|
||||||
uart_write("[sys] REACHED END OF MAIN. HALTING.\r\n");
|
debug_write("[sys] REACHED END OF MAIN. HALTING.\r\n");
|
||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
@ -7,3 +7,5 @@ INCLUDEPATH += /usr/avr/include
|
|||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
main.c
|
main.c
|
||||||
|
|
||||||
|
DEFINES += __AVR_ATmega8__
|
||||||
|
Loading…
Reference in New Issue
Block a user