Fix more bugs

This commit is contained in:
Markus Koch 2020-05-16 16:27:38 +02:00
parent 97a9f9f402
commit 8c950a02ea
2 changed files with 56 additions and 18 deletions

View File

@ -80,7 +80,7 @@ struct lw35ioc_chardev {
struct lw35ioc_printer_status{ struct lw35ioc_printer_status{
int buffer_free; int buffer_free;
int status; int status;
int reserved0; int rx_count;
int reserved1; int reserved1;
}; };
@ -106,6 +106,9 @@ struct lw35ioc_priv {
enum lw35ioc_state state; enum lw35ioc_state state;
struct lw35ioc_packet packet; struct lw35ioc_packet packet;
u8 tx_count;
u8 tx_count_resync;
}; };
@ -164,16 +167,16 @@ static int lw35ioc_process_buf(struct serdev_device *serdev,
priv->printer_status_temp.buffer_free = (int)c; priv->printer_status_temp.buffer_free = (int)c;
break; break;
case 2: /* Reserved */ case 2: /* Reserved */
priv->printer_status_temp.reserved0 = (int)c; priv->printer_status_temp.rx_count = (int)c;
break; break;
case 3: /* Reserved */ case 3: /* Reserved */
priv->printer_status_temp.reserved1 = (int)c; priv->printer_status_temp.reserved1 = (int)c;
dev_info(&serdev->dev, dev_info(&serdev->dev,
"New printer status. status=0x%02X buffer_free=0x%02X [0x%02X,0x%02X].\n", "New printer status. status=0x%02X buffer_free=0x%02X rx_count=0x%02X reserved=0x%02X.\n",
priv->printer_status_temp.status, priv->printer_status_temp.status,
priv->printer_status_temp.buffer_free, priv->printer_status_temp.buffer_free,
priv->printer_status_temp.reserved0, priv->printer_status_temp.rx_count,
priv->printer_status_temp.reserved1); priv->printer_status_temp.reserved1);
if (priv->printer_status_temp.status == 0xFF) { if (priv->printer_status_temp.status == 0xFF) {
dev_err(&serdev->dev, dev_err(&serdev->dev,
@ -292,6 +295,9 @@ static int lw35ioc_chardev_open(struct inode *inodep, struct file *filep) {
break; break;
case INIT: case INIT:
case PASSIVE: case PASSIVE:
// TODO: locks
priv->pbuf_tail = 0;
priv->pbuf_head = 0;
lw35ioc_reset_ioc_hw(serdev); lw35ioc_reset_ioc_hw(serdev);
usleep_range(2100000, 2210000); usleep_range(2100000, 2210000);
dev_info(&serdev->dev, "Put ioc into active mode.\n"); dev_info(&serdev->dev, "Put ioc into active mode.\n");
@ -312,6 +318,7 @@ static int lw35ioc_chardev_open(struct inode *inodep, struct file *filep) {
//return -EBUSY; // TODO //return -EBUSY; // TODO
} }
priv->tx_count_resync = 1;
priv->chardev.open_count++; priv->chardev.open_count++;
return 0; return 0;
@ -498,6 +505,15 @@ void pbuf_work_handler(struct work_struct *work)
dev_warn(&serdev->dev, "Cannot transmit data to device. Device is not ready.\n"); dev_warn(&serdev->dev, "Cannot transmit data to device. Device is not ready.\n");
break; break;
} }
if (priv->tx_count_resync) {
priv->tx_count = priv->printer_status.rx_count;
priv->tx_count_resync = 0;
}
if (priv->printer_status.rx_count != priv->tx_count) {
dev_info(&serdev->dev, "Not transmitting any data to device because rx is unconfirmed [tx=%d, rx=%d].\n",
priv->tx_count, priv->printer_status.rx_count);
break;
}
if (bsize > priv->printer_status.buffer_free) if (bsize > priv->printer_status.buffer_free)
bsize = priv->printer_status.buffer_free; bsize = priv->printer_status.buffer_free;
if (bsize > CIRC_CNT_TO_END(head, tail, PBUF_SIZE)) if (bsize > CIRC_CNT_TO_END(head, tail, PBUF_SIZE))
@ -515,7 +531,7 @@ void pbuf_work_handler(struct work_struct *work)
dev_warn(&serdev->dev, "Cannot transmit data to device. Device buffer is full.\n"); dev_warn(&serdev->dev, "Cannot transmit data to device. Device buffer is full.\n");
break; break;
} }
priv->tx_count += bsize;
serdev_device_write_buf(serdev, serdev_device_write_buf(serdev,
priv->pbuf + tail, priv->pbuf + tail,
bsize); bsize);
@ -615,6 +631,9 @@ static int lw35ioc_probe(struct serdev_device *serdev)
priv->printer_status.buffer_free = 0; priv->printer_status.buffer_free = 0;
priv->printer_status.status = 0; priv->printer_status.status = 0;
priv->tx_count = 0;
priv->tx_count_resync = 1;
priv->serdev = serdev; priv->serdev = serdev;
static_serdev = serdev; static_serdev = serdev;

View File

@ -1,4 +1,7 @@
#include <avr/io.h> // Known bugs:
// When having linebreak at the auto-linebreak width, bad things will happen.
#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>
@ -88,7 +91,13 @@ void debug_putc(char c) {};
unsigned int debug_printf(char *format,...) {return 0;}; unsigned int debug_printf(char *format,...) {return 0;};
#endif #endif
void hardfault() { enum hardfault_reason {HARDFAULT_REASON_NONE = 0,
HARDFAULT_REASON_MARGIN,
HARDFAULT_REASON_TXOVERFLOW,
HARDFAULT_REASON_USER,
HARDFAULT_REASON_LIMITSWITCH};
void hardfault(enum hardfault_reason reason) {
cli(); cli();
PORTB = 0; PORTB = 0;
PORTC = 0; PORTC = 0;
@ -104,6 +113,7 @@ void hardfault() {
uart_putc(0x00); uart_putc(0x00);
uart_putc(0x00); uart_putc(0x00);
uart_putc(0x00); uart_putc(0x00);
uart_putc(reason);
debug_write("HARDFAULT!\r\n"); debug_write("HARDFAULT!\r\n");
while(1); while(1);
} }
@ -616,7 +626,7 @@ void tx_buffer_putc(char c)
{ {
if (tx_buffer_async) { if (tx_buffer_async) {
if (tx_buffer_rd == tx_buffer_wr + 1) // implicit % 256 if (tx_buffer_rd == tx_buffer_wr + 1) // implicit % 256
hardfault(); hardfault(HARDFAULT_REASON_TXOVERFLOW);
tx_buffer[tx_buffer_wr++] = c; // implicit % 256 tx_buffer[tx_buffer_wr++] = c; // implicit % 256
} else { } else {
uart_putc(c); uart_putc(c);
@ -632,7 +642,7 @@ void tx_status()
tx_buffer_putc(0xAA); /* Header[1] */ tx_buffer_putc(0xAA); /* Header[1] */
tx_buffer_putc((char) (global_status | local_status)); tx_buffer_putc((char) (global_status | local_status));
tx_buffer_putc(RINGBUF_FREE(print_buffer_wr, print_buffer_rd, PRINT_BUFFER_SIZE)); tx_buffer_putc(RINGBUF_FREE(print_buffer_wr, print_buffer_rd, PRINT_BUFFER_SIZE));
tx_buffer_putc(0); /* RESERVED */ tx_buffer_putc(print_buffer_wr); /* RX byte count*/
tx_buffer_putc(0); /* RESERVED */ tx_buffer_putc(0); /* RESERVED */
} }
@ -692,7 +702,7 @@ void move_carriage_to_far_left(uint8_t reset)
DCMOTOR_STOP; DCMOTOR_STOP;
} }
if (LIMITSWITCH) { // If the switch is still not released, there's some problem we can't fix from SW if (LIMITSWITCH) { // If the switch is still not released, there's some problem we can't fix from SW
hardfault(); hardfault(HARDFAULT_REASON_LIMITSWITCH);
} }
for (cnt = 0; cnt < 16; cnt++) { for (cnt = 0; cnt < 16; cnt++) {
STEPPER_NEXT(CARRIAGE, 1); STEPPER_NEXT(CARRIAGE, 1);
@ -733,7 +743,7 @@ 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 */ /* Rotate right for two revolutions -> lock daisy wheel to 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);
@ -815,7 +825,7 @@ enum printer_mode_t {MANUAL, INTELLIGENT};
#define GET_PRINT_CODE(c) (pgm_read_byte(&ascii_translation_table[c])) #define GET_PRINT_CODE(c) (pgm_read_byte(&ascii_translation_table[c]))
uint16_t print_margin_left = 100; uint16_t print_margin_left = 100;
uint16_t print_margin_right = PRINTER_STOP_RIGHT - 100; uint16_t print_margin_right = PRINTER_STOP_RIGHT - 90; // TODO: should be - 100; see top comment in this source file
int8_t move_one_character(uint8_t backward) int8_t move_one_character(uint8_t backward)
{ {
@ -826,7 +836,7 @@ int8_t move_one_character(uint8_t backward)
stepper_status_CARRIAGE.target_pos -= PRINT_CHARACTER_WIDTH; stepper_status_CARRIAGE.target_pos -= PRINT_CHARACTER_WIDTH;
} else { } else {
if (stepper_status_CARRIAGE.target_pos >= print_margin_right - PRINT_CHARACTER_WIDTH) { if (stepper_status_CARRIAGE.target_pos >= print_margin_right - PRINT_CHARACTER_WIDTH) {
return 1; return 1;
} }
stepper_status_CARRIAGE.target_pos += PRINT_CHARACTER_WIDTH; stepper_status_CARRIAGE.target_pos += PRINT_CHARACTER_WIDTH;
} }
@ -849,7 +859,7 @@ inline int8_t simulate_print_run(uint8_t *start_end_index, uint8_t *recovery_ind
uint16_t carriage_position; uint16_t carriage_position;
uint8_t translated; uint8_t translated;
uint8_t status = 0; uint8_t status = 0;
uint8_t line_matters = 0; uint8_t line_matters = 0; /* A printable character was somewhere on it */
index = *start_end_index; index = *start_end_index;
carriage_position = print_margin_left; carriage_position = print_margin_left;
@ -934,7 +944,7 @@ enum printer_state process_special_command(uint8_t command)
return INIT; return INIT;
case PRINT_COMMAND_HARDFAULLT: case PRINT_COMMAND_HARDFAULLT:
hardfault(); hardfault(HARDFAULT_REASON_USER);
return INIT; return INIT;
case PRINT_COMMAND_BACKLIGHT_ON: case PRINT_COMMAND_BACKLIGHT_ON:
@ -1014,6 +1024,8 @@ void printer_process()
static uint8_t print_buffer_recovery = 0; static uint8_t print_buffer_recovery = 0;
static uint8_t current_is_linebreak = 0; static uint8_t current_is_linebreak = 0;
static int8_t last_linebreak_was_auto = 0;
uint8_t current_char; uint8_t current_char;
static uint8_t special_command; static uint8_t special_command;
uint8_t translated; uint8_t translated;
@ -1040,6 +1052,7 @@ void printer_process()
} }
/* Check whether the current character is a command or something to print */ /* Check whether the current character is a command or something to print */
//if (!last_linebreak_was_auto) FIXME: This doesn't work yet!!! Eat newlines (and doesn't work anyways)
current_is_linebreak += (current_char == '\n'); current_is_linebreak += (current_char == '\n');
if (current_is_linebreak) { if (current_is_linebreak) {
if (backward) { if (backward) {
@ -1081,7 +1094,8 @@ void printer_process()
break; break;
case PRINTER_NO_CHAR: case PRINTER_NO_CHAR:
current_is_linebreak += move_one_character(backward); last_linebreak_was_auto = move_one_character(backward);
current_is_linebreak += last_linebreak_was_auto;
if (!current_is_linebreak) if (!current_is_linebreak)
debug_putc(' '); debug_putc(' ');
break; break;
@ -1091,6 +1105,8 @@ void printer_process()
state = HAMMER; state = HAMMER;
break; break;
} }
last_linebreak_was_auto = 0;
} else { /* TODO: Special commands */ } else { /* TODO: Special commands */
special_command = current_char; special_command = current_char;
state = SPECIAL_COMMAND; state = SPECIAL_COMMAND;
@ -1117,13 +1133,16 @@ void printer_process()
arm_hammer(); arm_hammer();
_delay_ms(50); // TODO: replace with timer _delay_ms(50); // TODO: replace with timer
debug_putc(debug_character); debug_putc(debug_character);
current_is_linebreak += move_one_character(backward); last_linebreak_was_auto = move_one_character(backward);
current_is_linebreak += last_linebreak_was_auto;
state = IDLE; state = IDLE;
} }
break; break;
case SPECIAL_COMMAND: case SPECIAL_COMMAND:
state = process_special_command(special_command); state = process_special_command(special_command);
if (state != SPECIAL_COMMAND)
tx_status();
break; break;
case INIT: case INIT:
@ -1145,7 +1164,7 @@ void printer_process()
if (stepper_status_CARRIAGE.target_pos > PRINTER_STOP_RIGHT || if (stepper_status_CARRIAGE.target_pos > PRINTER_STOP_RIGHT ||
stepper_status_CARRIAGE.target_pos < 0) { // Margin safety stepper_status_CARRIAGE.target_pos < 0) { // Margin safety
hardfault(); hardfault(HARDFAULT_REASON_MARGIN);
} }
stepper_perform_movement(&stepper_status_LINEFEED, &STEPPER_CFG_LINEFEED); stepper_perform_movement(&stepper_status_LINEFEED, &STEPPER_CFG_LINEFEED);
stepper_perform_movement(&stepper_status_CARRIAGE, &STEPPER_CFG_CARRIAGE); stepper_perform_movement(&stepper_status_CARRIAGE, &STEPPER_CFG_CARRIAGE);