unsigned write_flash(unsigned * dst, char * src, unsigned no_of_bytes) { unsigned i; if(no_of_bytes == FLASH_BUF_SIZE) { for(i = 0;i<no_of_bytes;i++) { flash_buf[i] = *(src+i); } find_prepare_sector(SystemCoreClock/1000, (unsigned)dst); if(result_table[0] != CMD_SUCCESS) { serial_writestr("Error: preparing to write data\n"); } write_data( SystemCoreClock/1000, (unsigned)dst, (void *)flash_buf, FLASH_BUF_SIZE); if(result_table[0] != CMD_SUCCESS) { serial_writestr("Error: writing data\n"); } compare_data( SystemCoreClock/1000, (unsigned)dst, (void *)flash_buf, FLASH_BUF_SIZE); if(result_table[0] != CMD_SUCCESS) { serial_writestr("Error: verifying data\n"); } /* Reset flash address */ dst = 0; } else return 1; return(CMD_SUCCESS); }
void find_prepare_sector(unsigned cclk, unsigned dst) { unsigned i; __disable_irq(); for(i = USER_START_SECTOR; i <= MAX_USER_SECTOR; i++) { if(dst < sector_end_map[i]) { if(dst == sector_start_map[i]) { prepare_sector(i, i, cclk); } prepare_sector(i , i, cclk); break; } } __enable_irq(); if(result_table[0] != CMD_SUCCESS) { serial_writestr("Error: preparing to write data\n"); } }
void find_erase_sector(unsigned cclk, unsigned dst) { unsigned k; __disable_irq(); for(k = USER_START_SECTOR;k <= MAX_USER_SECTOR; k++) { if(dst < sector_end_map[k]) { if(dst == sector_start_map[k]) { erase_sector(k, k, cclk); } break; } } __enable_irq(); if(result_table[0] != CMD_SUCCESS) { serial_writestr("Error: erasing data\n"); } }
// ------------------------------------------------------- // This is the one function called by the timer interrupt. // It calls a few other functions, though. // ------------------------------------------------------- void queue_step() { // do our next step if (movebuffer[mb_tail].live) { if (movebuffer[mb_tail].waitfor_temp) { if (temp_achieved(EXTRUDER_0)) { movebuffer[mb_tail].live = movebuffer[mb_tail].waitfor_temp = 0; serial_writestr("Temp achieved\r\n"); } } else { // NOTE: dda_step makes this interrupt interruptible after steps have been sent but before new speed is calculated. dda_step(&(movebuffer[mb_tail])); } } // fall directly into dda_start instead of waiting for another step // the dda dies not directly after its last step, but when the timer fires and there's no steps to do if (movebuffer[mb_tail].live == 0) next_move(); }
void erase_user_flash(void) { prepare_sector(USER_START_SECTOR,MAX_USER_SECTOR,SystemCoreClock/1000); erase_sector(USER_START_SECTOR,MAX_USER_SECTOR,SystemCoreClock/1000); if(result_table[0] != CMD_SUCCESS) { serial_writestr("Error: erasing data\n"); } }
void read_device_serial_number(void) { param_table[0] = READ_DEVICE_SERIAL; IAP_entry(param_table,result_table); if(result_table[0] != CMD_SUCCESS) { serial_writestr("Error: reading serial "); } else { serwrite_uint32(result_table[1]); serial_writestr(" "); serwrite_uint32(result_table[2]); serial_writestr(" "); serwrite_uint32(result_table[3]); serial_writestr(" "); serwrite_uint32(result_table[4]); serial_writestr(" "); } }
void init(void) { // set up inputs and outputs io_init(); /* Initialize Gcode parse variables */ gcode_parse_init(); // set up default feedrate //TODO current_position.F = startpoint.F = next_target.target.F = config.search_feedrate_z; AddSlowTimer (&temperatureTimer); StartSlowTimer (&temperatureTimer, 10, temperatureTimerCallback); temperatureTimer.AutoReload = 1; // say hi to host serial_writestr("Start\r\nOK\r\n"); }
/** List a given directory. \param path The path to list. Toplevel path is "/". A slash is added to directory names, to make it easier for users to recognize them. */ void sd_list(const char* path) { FILINFO fno; DIR dir; result = pf_opendir(&dir, path); if (result == FR_OK) { for (;;) { result = pf_readdir(&dir, &fno); if (result != FR_OK || fno.fname[0] == 0) break; serial_writestr((uint8_t *)fno.fname); if (fno.fattrib & AM_DIR) serial_writechar('/'); serial_writechar('\n'); delay_ms(2); // Time for sending the characters. } } else { sersendf_P(PSTR("E: failed to open dir. (%su)\n"), result); } }
/**************************************************************************** * * * Request a resend of the current line - used from various places. * * * * Relies on the global variable next_target.N being valid. * * * ****************************************************************************/ void request_resend(void) { serial_writestr("rs "); serwrite_uint8(next_target.N); serial_writestr("\r\n"); }
eParseResult gcode_parse_line (tLineBuffer *pLine) { int j; eParseResult result = PR_OK; for (j=0; j < pLine->len; j++) { gcode_parse_char (pLine->data [j]); } // end of line //if ((c == 10) || (c == 13)) { if ( #ifdef REQUIRE_LINENUMBER (next_target.N >= next_target.N_expected) && (next_target.seen_N == 1) #else 1 #endif ) { if ( #ifdef REQUIRE_CHECKSUM ((next_target.checksum_calculated == next_target.checksum_read) && (next_target.seen_checksum == 1)) #else ((next_target.checksum_calculated == next_target.checksum_read) || (next_target.seen_checksum == 0)) #endif ) { if (sd_writing_file) { if (next_target.seen_M && (next_target.M >= 20) && (next_target.M <= 29)) { if (next_target.seen_M && next_target.M == 29) { // M29 - stop writing sd_writing_file = false; sd_close (&file); serial_writestr("Done saving file\r\n"); } else { // else - do not write SD M-codes to file serial_writestr("ok\r\n"); } } else { // lines in files must be LF terminated for sd_read_file to work if (pLine->data [pLine->len-1] == 13) { pLine->data [pLine->len-1] = 10; } if (sd_write_to_file(pLine->data, pLine->len)) { serial_writestr("ok\r\n"); } else { serial_writestr("error writing to file\r\n"); } } } else { // process result = process_gcode_command(); // expect next line number if (next_target.seen_N == 1) { next_target.N_expected = next_target.N + 1; } } } else { serial_writestr("Expected checksum "); serwrite_uint8(next_target.checksum_calculated); serial_writestr("\r\n"); request_resend(); } } else { serial_writestr("Expected line number "); serwrite_uint32(next_target.N_expected); serial_writestr("\r\n"); request_resend(); } // reset variables next_target.seen_X = next_target.seen_Y = next_target.seen_Z = \ next_target.seen_E = next_target.seen_F = next_target.seen_S = \ next_target.seen_P = next_target.seen_N = next_target.seen_M = \ next_target.seen_checksum = next_target.seen_semi_comment = \ next_target.seen_parens_comment = next_target.checksum_read = \ next_target.checksum_calculated = 0; next_target.chpos = 0; last_field = 0; read_digit.sign = read_digit.exponent = 0; value = 0; // dont assume a G1 by default next_target.seen_G = 0; next_target.G = 0; if (next_target.option_relative) { next_target.target.x = next_target.target.y = next_target.target.z = 0.0; next_target.target.e = 0.0; } } return result; }
void serial_writeDec(int i) { char str[12]; snprintf(str, sizeof(str), "%d", i); serial_writestr(str); }
void serial_writestrln(char* s) { serial_writestr(s); serial_writestr("\n"); }
void sersendf(char *format, ...) { va_list args; va_start(args, format); unsigned long int i = 0; unsigned char c, j = 0; while ((c = format[i++])) { if (j) { switch(c) { case 's': j = 1; break; case 'l': j = 4; break; case 'u': if (j == 4) serwrite_uint32(va_arg(args, unsigned long int)); else serwrite_uint16(va_arg(args, unsigned int)); j = 0; break; case 'd': if (j == 4) serwrite_int32(va_arg(args, long int)); else serwrite_int16(va_arg(args, int)); j = 0; break; case 'c': serial_writechar(va_arg(args, unsigned int)); j = 0; break; case 'x': serial_writestr(str_ox); if (j == 4) serwrite_hex32(va_arg(args, unsigned long int)); else if (j == 1) serwrite_hex8(va_arg(args, unsigned int)); else serwrite_hex16(va_arg(args, unsigned int)); j = 0; break; /* case 'p': serwrite_hex16(va_arg(args, unsigned short int));*/ case 'q': serwrite_int32_vf(va_arg(args, long int), 3); j = 0; break; default: serial_writechar(c); j = 0; break; } } else { if (c == '%') { j = 2; } else { serial_writechar(c); } } }
// write from flash void serial_writestr_P(PGM_P data) { serial_writestr((uint8_t *)data); }
int app_main (void) { long timer1 = 0; eParseResult parse_result; buzzer_init(); buzzer_play(1500, 100); /* low beep */ buzzer_wait(); buzzer_play(2500, 200); /* high beep */ init(); read_config(); // grbl init plan_init(); st_init(); // main loop for (;;) { // process characters from the serial port while (!serial_line_buf.seen_lf && (serial_rxchars() != 0) ) { unsigned char c = serial_popchar(); if (serial_line_buf.len < MAX_LINE) serial_line_buf.data [serial_line_buf.len++] = c; if ((c==10) || (c==13)) { if (serial_line_buf.len > 1) serial_line_buf.seen_lf = 1; else serial_line_buf.len = 0; } } // process SD file if no serial command pending if (!sd_line_buf.seen_lf && sd_printing) { if (sd_read_file (&sd_line_buf)) { sd_line_buf.seen_lf = 1; } else { sd_printing = false; serial_writestr ("Done printing file\r\n"); } } // if queue is full, we wait if (!plan_queue_full()) { /* At end of each line, put the "GCode" on movebuffer. * If there are movement to do, Timer will start and execute code which * will take data from movebuffer and generate the required step pulses * for stepper motors. */ // give priority to user commands if (serial_line_buf.seen_lf) { parse_result = gcode_parse_line (&serial_line_buf); serial_line_buf.len = 0; serial_line_buf.seen_lf = 0; } else if (sd_line_buf.seen_lf) { parse_result = gcode_parse_line (&sd_line_buf); sd_line_buf.len = 0; sd_line_buf.seen_lf = 0; } } /* Do every 100ms */ #define DELAY1 100 if (timer1 < millis()) { timer1 = millis() + DELAY1; /* If there are no activity during 30 seconds, power off the machine */ if (steptimeout > (30 * 1000/DELAY1)) { power_off(); } else { steptimeout++; } } #ifdef USE_BOOT_BUTTON // OPTION: enter bootloader on "Boot" button check_boot_request(); #endif } }
void sersendf(char *format, ...) { va_list args; va_start(args, format); unsigned int i = 0; unsigned char c, j = 0; while ((c = format[i++])) { if (j) { switch(c) { case 'l': j = 4; break; case 'u': if (j == 4) serwrite_uint32(va_arg(args, unsigned int)); else serwrite_uint16(va_arg(args, unsigned int)); j = 0; break; case 'd': if (j == 4) serwrite_int32(va_arg(args, int)); else serwrite_int16(va_arg(args, int)); j = 0; break; /* print a double in normal notation */ case 'g': serwrite_double(va_arg(args, double)); j = 0; break; case 'p': case 'x': serial_writestr(str_ox); if (j == 4) serwrite_hex32(va_arg(args, unsigned int)); else serwrite_hex16(va_arg(args, unsigned int)); j = 0; break; case 'c': serial_writechar(va_arg(args, unsigned int)); j = 0; break; case 's': serial_writestr(va_arg(args, char *)); j = 0; break; default: j = 0; break; } } else { if (c == '%') { j = 2; } else { serial_writechar(c); } } } va_end(args); }