From 8c950a02ea21551e32a02a55a8881d7c922d196b Mon Sep 17 00:00:00 2001 From: Markus Koch Date: Sat, 16 May 2020 16:27:38 +0200 Subject: [PATCH] Fix more bugs --- ioc/kernel-driver/lw35ioc.c | 29 +++++++++++++++++++----- printer/avr/main.c | 45 ++++++++++++++++++++++++++----------- 2 files changed, 56 insertions(+), 18 deletions(-) diff --git a/ioc/kernel-driver/lw35ioc.c b/ioc/kernel-driver/lw35ioc.c index e59aea6..78c47b9 100644 --- a/ioc/kernel-driver/lw35ioc.c +++ b/ioc/kernel-driver/lw35ioc.c @@ -80,7 +80,7 @@ struct lw35ioc_chardev { struct lw35ioc_printer_status{ int buffer_free; int status; - int reserved0; + int rx_count; int reserved1; }; @@ -106,6 +106,9 @@ struct lw35ioc_priv { enum lw35ioc_state state; 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; break; case 2: /* Reserved */ - priv->printer_status_temp.reserved0 = (int)c; + priv->printer_status_temp.rx_count = (int)c; break; case 3: /* Reserved */ priv->printer_status_temp.reserved1 = (int)c; 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.buffer_free, - priv->printer_status_temp.reserved0, + priv->printer_status_temp.rx_count, priv->printer_status_temp.reserved1); if (priv->printer_status_temp.status == 0xFF) { dev_err(&serdev->dev, @@ -292,6 +295,9 @@ static int lw35ioc_chardev_open(struct inode *inodep, struct file *filep) { break; case INIT: case PASSIVE: + // TODO: locks + priv->pbuf_tail = 0; + priv->pbuf_head = 0; lw35ioc_reset_ioc_hw(serdev); usleep_range(2100000, 2210000); 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 } + priv->tx_count_resync = 1; priv->chardev.open_count++; 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"); 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) bsize = priv->printer_status.buffer_free; 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"); break; } - + priv->tx_count += bsize; serdev_device_write_buf(serdev, priv->pbuf + tail, bsize); @@ -615,6 +631,9 @@ static int lw35ioc_probe(struct serdev_device *serdev) priv->printer_status.buffer_free = 0; priv->printer_status.status = 0; + + priv->tx_count = 0; + priv->tx_count_resync = 1; priv->serdev = serdev; static_serdev = serdev; diff --git a/printer/avr/main.c b/printer/avr/main.c index cb0a803..e9d9795 100644 --- a/printer/avr/main.c +++ b/printer/avr/main.c @@ -1,4 +1,7 @@ -#include +// Known bugs: +// When having linebreak at the auto-linebreak width, bad things will happen. + +#include #include #include #include @@ -88,7 +91,13 @@ void debug_putc(char c) {}; unsigned int debug_printf(char *format,...) {return 0;}; #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(); PORTB = 0; PORTC = 0; @@ -104,6 +113,7 @@ void hardfault() { uart_putc(0x00); uart_putc(0x00); uart_putc(0x00); + uart_putc(reason); debug_write("HARDFAULT!\r\n"); while(1); } @@ -616,7 +626,7 @@ void tx_buffer_putc(char c) { if (tx_buffer_async) { if (tx_buffer_rd == tx_buffer_wr + 1) // implicit % 256 - hardfault(); + hardfault(HARDFAULT_REASON_TXOVERFLOW); tx_buffer[tx_buffer_wr++] = c; // implicit % 256 } else { uart_putc(c); @@ -632,7 +642,7 @@ void tx_status() tx_buffer_putc(0xAA); /* Header[1] */ 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(0); /* RESERVED */ + tx_buffer_putc(print_buffer_wr); /* RX byte count*/ tx_buffer_putc(0); /* RESERVED */ } @@ -692,7 +702,7 @@ void move_carriage_to_far_left(uint8_t reset) DCMOTOR_STOP; } 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++) { STEPPER_NEXT(CARRIAGE, 1); @@ -733,7 +743,7 @@ void align_daisy_wheel() stepper_status_WHEEL.target_pos = 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; ) { if (block_for(TIM_WHEEL, STEPPER_CFG_WHEEL.delay)) { 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])) 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) { @@ -826,7 +836,7 @@ int8_t move_one_character(uint8_t backward) stepper_status_CARRIAGE.target_pos -= PRINT_CHARACTER_WIDTH; } else { if (stepper_status_CARRIAGE.target_pos >= print_margin_right - PRINT_CHARACTER_WIDTH) { - return 1; + return 1; } 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; uint8_t translated; 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; carriage_position = print_margin_left; @@ -934,7 +944,7 @@ enum printer_state process_special_command(uint8_t command) return INIT; case PRINT_COMMAND_HARDFAULLT: - hardfault(); + hardfault(HARDFAULT_REASON_USER); return INIT; case PRINT_COMMAND_BACKLIGHT_ON: @@ -1014,6 +1024,8 @@ void printer_process() static uint8_t print_buffer_recovery = 0; static uint8_t current_is_linebreak = 0; + static int8_t last_linebreak_was_auto = 0; + uint8_t current_char; static uint8_t special_command; uint8_t translated; @@ -1040,6 +1052,7 @@ void printer_process() } /* 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'); if (current_is_linebreak) { if (backward) { @@ -1081,7 +1094,8 @@ void printer_process() break; 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) debug_putc(' '); break; @@ -1091,6 +1105,8 @@ void printer_process() state = HAMMER; break; } + + last_linebreak_was_auto = 0; } else { /* TODO: Special commands */ special_command = current_char; state = SPECIAL_COMMAND; @@ -1117,13 +1133,16 @@ void printer_process() arm_hammer(); _delay_ms(50); // TODO: replace with timer 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; } break; case SPECIAL_COMMAND: state = process_special_command(special_command); + if (state != SPECIAL_COMMAND) + tx_status(); break; case INIT: @@ -1145,7 +1164,7 @@ void printer_process() if (stepper_status_CARRIAGE.target_pos > PRINTER_STOP_RIGHT || 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_CARRIAGE, &STEPPER_CFG_CARRIAGE);