Merge pull request #14 from TheZeroBeast/MMU-MK3-FSensorBuild-Patch1

Mmu mk3 f sensor build patch1
This commit is contained in:
TheZeroBeast 2018-11-10 22:41:42 +10:00 committed by GitHub
commit 3caaa01eb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 15392 additions and 15196 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

BIN
Firmware/.DS_Store vendored Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -2954,6 +2954,7 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float
{ {
st_synchronize(); st_synchronize();
float lastpos[4]; float lastpos[4];
mmuFSensorLoading = false;
if (farm_mode) if (farm_mode)
{ {
@ -6896,11 +6897,13 @@ Sigma_Exit:
mmu_command(MMU_CMD_T0 + tmp_extruder); mmu_command(MMU_CMD_T0 + tmp_extruder);
manage_response(true, true); manage_response(true, true);
delay(100);
mmu_command(MMU_CMD_C0); mmu_command(MMU_CMD_C0);
mmu_extruder = tmp_extruder; //filament change is finished mmu_extruder = tmp_extruder; //filament change is finished
if (*(strchr_pointer + index) == '?')// for single material usage with mmu if (*(strchr_pointer + index) == '?')// for single material usage with mmu
{ {
delay(100);
mmu_load_to_nozzle(); mmu_load_to_nozzle();
} }
} }
@ -7452,14 +7455,8 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) //default argument s
} }
} }
} else { } else {
if (mcode_in_progress != 600) //M600 not in progress if ((lcd_commands_type != LCD_COMMAND_V2_CAL) && !wizard_active && mmuFSensorLoading) {
{ fsensor_check_autoload();
if ((lcd_commands_type != LCD_COMMAND_V2_CAL) && !wizard_active && mmuFSensorLoading) {
fsensor_check_autoload();
} else {
fsensor_autoload_check_stop();
//fsensor_update();
}
} }
} }
#endif //FILAMENT_SENSOR #endif //FILAMENT_SENSOR

View File

@ -12,21 +12,21 @@ uint16_t adc_sim_mask;
#ifdef ADC_CALLBACK #ifdef ADC_CALLBACK
extern void ADC_CALLBACK(void); extern void ADC_CALLBACK(void);
#endif //ADC_CALLBACK #endif //ADC_CALLBACK
void adc_init(void) void adc_init(void)
{ {
printf_P(PSTR("adc_init\n")); printf_P(PSTR("adc_init\n"));
adc_sim_mask = 0x00; adc_sim_mask = 0x00;
ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
ADMUX |= (1 << REFS0); ADMUX |= (1 << REFS0);
ADCSRA |= (1 << ADEN); ADCSRA |= (1 << ADEN);
// ADCSRA |= (1 << ADIF) | (1 << ADSC); // ADCSRA |= (1 << ADIF) | (1 << ADSC);
DIDR0 = (ADC_CHAN_MSK & 0xff); DIDR0 = (ADC_CHAN_MSK & 0xff);
DIDR2 = (ADC_CHAN_MSK >> 8); DIDR2 = (ADC_CHAN_MSK >> 8);
adc_reset(); adc_reset();
// adc_sim_mask = 0b0101; // adc_sim_mask = 0b0101;
// adc_sim_mask = 0b100101; // adc_sim_mask = 0b100101;
// adc_values[0] = 1023 * 16; // adc_values[0] = 1023 * 16;
@ -36,59 +36,60 @@ void adc_init(void)
void adc_reset(void) void adc_reset(void)
{ {
adc_state = 0; adc_state = 0;
adc_count = 0; adc_count = 0;
uint8_t i; for (i = 0; i < ADC_CHAN_CNT; i++) uint8_t i;
if ((adc_sim_mask & (1 << i)) == 0) for (i = 0; i < ADC_CHAN_CNT; i++)
adc_values[i] = 0; if ((adc_sim_mask & (1 << i)) == 0)
adc_values[i] = 0;
} }
void adc_setmux(uint8_t ch) void adc_setmux(uint8_t ch)
{ {
ch &= 0x0f; ch &= 0x0f;
if (ch & 0x08) ADCSRB |= (1 << MUX5); if (ch & 0x08) ADCSRB |= (1 << MUX5);
else ADCSRB &= ~(1 << MUX5); else ADCSRB &= ~(1 << MUX5);
ADMUX = (ADMUX & ~(0x07)) | (ch & 0x07); ADMUX = (ADMUX & ~(0x07)) | (ch & 0x07);
} }
uint8_t adc_chan(uint8_t index) uint8_t adc_chan(uint8_t index)
{ {
uint8_t chan = 0; uint8_t chan = 0;
uint16_t mask = 1; uint16_t mask = 1;
while (mask) while (mask)
{ {
if ((mask & ADC_CHAN_MSK) && (index-- == 0)) break; if ((mask & ADC_CHAN_MSK) && (index-- == 0)) break;
mask <<= 1; mask <<= 1;
chan++; chan++;
} }
return chan; return chan;
} }
void adc_cycle(void) void adc_cycle(void)
{ {
if (adc_state & 0x80) if (adc_state & 0x80)
{ {
uint8_t index = adc_state & 0x0f; uint8_t index = adc_state & 0x0f;
if ((adc_sim_mask & (1 << index)) == 0) if ((adc_sim_mask & (1 << index)) == 0)
adc_values[index] += ADC; adc_values[index] += ADC;
if (index++ >= ADC_CHAN_CNT) if (index++ >= ADC_CHAN_CNT)
{ {
index = 0; index = 0;
adc_count++; adc_count++;
if (adc_count >= ADC_OVRSAMPL) if (adc_count >= ADC_OVRSAMPL)
{ {
#ifdef ADC_CALLBACK #ifdef ADC_CALLBACK
ADC_CALLBACK(); ADC_CALLBACK();
#endif //ADC_CALLBACK #endif //ADC_CALLBACK
adc_reset(); adc_reset();
} }
} }
adc_setmux(adc_chan(index)); adc_setmux(adc_chan(index));
adc_state = index; adc_state = index;
} }
else else
{ {
ADCSRA |= (1 << ADSC); //start conversion ADCSRA |= (1 << ADSC); //start conversion
adc_state |= 0x80; adc_state |= 0x80;
} }
} }

View File

@ -11,45 +11,45 @@ extern FILE _uartout;
void bootapp_print_vars(void) void bootapp_print_vars(void)
{ {
fprintf_P(uartout, PSTR("boot_src_addr =0x%08lx\n"), boot_src_addr); fprintf_P(uartout, PSTR("boot_src_addr =0x%08lx\n"), boot_src_addr);
fprintf_P(uartout, PSTR("boot_dst_addr =0x%08lx\n"), boot_dst_addr); fprintf_P(uartout, PSTR("boot_dst_addr =0x%08lx\n"), boot_dst_addr);
fprintf_P(uartout, PSTR("boot_copy_size =0x%04x\n"), boot_copy_size); fprintf_P(uartout, PSTR("boot_copy_size =0x%04x\n"), boot_copy_size);
fprintf_P(uartout, PSTR("boot_reserved =0x%02x\n"), boot_reserved); fprintf_P(uartout, PSTR("boot_reserved =0x%02x\n"), boot_reserved);
fprintf_P(uartout, PSTR("boot_app_flags =0x%02x\n"), boot_app_flags); fprintf_P(uartout, PSTR("boot_app_flags =0x%02x\n"), boot_app_flags);
fprintf_P(uartout, PSTR("boot_app_magic =0x%08lx\n"), boot_app_magic); fprintf_P(uartout, PSTR("boot_app_magic =0x%08lx\n"), boot_app_magic);
} }
void bootapp_ram2flash(uint16_t rptr, uint16_t fptr, uint16_t size) void bootapp_ram2flash(uint16_t rptr, uint16_t fptr, uint16_t size)
{ {
cli(); cli();
boot_app_magic = BOOT_APP_MAGIC; boot_app_magic = BOOT_APP_MAGIC;
boot_app_flags |= BOOT_APP_FLG_COPY; boot_app_flags |= BOOT_APP_FLG_COPY;
boot_app_flags |= BOOT_APP_FLG_ERASE; boot_app_flags |= BOOT_APP_FLG_ERASE;
/* uint16_t ui; for (ui = 0; ui < size; ui++) /* uint16_t ui; for (ui = 0; ui < size; ui++)
{ {
uint8_t uc = ram_array[ui+rptr]; uint8_t uc = ram_array[ui+rptr];
if (pgm_read_byte(ui+fptr) & uc != uc) if (pgm_read_byte(ui+fptr) & uc != uc)
{ {
boot_app_flags |= BOOT_APP_FLG_ERASE; boot_app_flags |= BOOT_APP_FLG_ERASE;
break; break;
} }
}*/ }*/
boot_copy_size = (uint16_t)size; boot_copy_size = (uint16_t)size;
boot_src_addr = (uint32_t)rptr; boot_src_addr = (uint32_t)rptr;
boot_dst_addr = (uint32_t)fptr; boot_dst_addr = (uint32_t)fptr;
bootapp_print_vars(); bootapp_print_vars();
wdt_enable(WDTO_15MS); wdt_enable(WDTO_15MS);
while(1); while(1);
} }
void bootapp_reboot_user0(uint8_t reserved) void bootapp_reboot_user0(uint8_t reserved)
{ {
cli(); cli();
boot_app_magic = BOOT_APP_MAGIC; boot_app_magic = BOOT_APP_MAGIC;
boot_app_flags = BOOT_APP_FLG_USER0; boot_app_flags = BOOT_APP_FLG_USER0;
boot_reserved = reserved; boot_reserved = reserved;
bootapp_print_vars(); bootapp_print_vars();
wdt_enable(WDTO_15MS); wdt_enable(WDTO_15MS);
while(1); while(1);
} }

View File

@ -171,12 +171,13 @@ bool fsensor_enable(void)
else else
fsensor_not_responding = true; fsensor_not_responding = true;
fsensor_enabled = true; fsensor_enabled = true;
fsensor_autoload_enabled = true; fsensor_autoload_set(true);
fsensor_autoload_enabled = false;
fsensor_oq_meassure = false; fsensor_oq_meassure = false;
fsensor_err_cnt = 0; fsensor_err_cnt = 0;
fsensor_dy_old = 0; fsensor_dy_old = 0;
eeprom_update_byte((uint8_t*)EEPROM_FSENSOR, fsensor_enabled ? 0x01 : 0x00); eeprom_update_byte((uint8_t*)EEPROM_FSENSOR, 0x01);
FSensorStateMenu = fsensor_enabled ? 1 : 0; FSensorStateMenu = 1;
} }
return fsensor_enabled; return fsensor_enabled;
} }
@ -215,7 +216,7 @@ void fsensor_autoload_check_start(void)
printf_P(ERRMSG_PAT9125_NOT_RESP, 3); printf_P(ERRMSG_PAT9125_NOT_RESP, 3);
return; return;
} }
puts_P(_N("fsensor_autoload_check_start - autoload ENABLED\n")); if (!mmu_enabled) puts_P(_N("fsensor_autoload_check_start - autoload ENABLED\n"));
fsensor_autoload_y = pat9125_y; //save current y value fsensor_autoload_y = pat9125_y; //save current y value
fsensor_autoload_c = 0; //reset number of changes counter fsensor_autoload_c = 0; //reset number of changes counter
fsensor_autoload_sum = 0; fsensor_autoload_sum = 0;
@ -233,7 +234,7 @@ void fsensor_autoload_check_stop(void)
if (!fsensor_autoload_enabled) return; if (!fsensor_autoload_enabled) return;
// puts_P(_N("fsensor_autoload_check_stop 2\n")); // puts_P(_N("fsensor_autoload_check_stop 2\n"));
if (!fsensor_watch_autoload) return; if (!fsensor_watch_autoload) return;
puts_P(_N("fsensor_autoload_check_stop - autoload DISABLED\n")); if (!mmu_enabled) puts_P(_N("fsensor_autoload_check_stop - autoload DISABLED\n"));
fsensor_autoload_sum = 0; fsensor_autoload_sum = 0;
fsensor_watch_autoload = false; fsensor_watch_autoload = false;
fsensor_watch_runout = true; fsensor_watch_runout = true;
@ -284,11 +285,10 @@ bool fsensor_check_autoload(void)
// if ((fsensor_autoload_c >= 15) && (fsensor_autoload_sum > 30)) // if ((fsensor_autoload_c >= 15) && (fsensor_autoload_sum > 30))
if ((fsensor_autoload_c >= 12) && (fsensor_autoload_sum > 20)) if ((fsensor_autoload_c >= 12) && (fsensor_autoload_sum > 20))
{ {
puts_P(_N("fsensor_check_autoload = true !!!\n")); //puts_P(_N("fsensor_check_autoload = true !!!\n"));
//if (mmu_enabled) { if (mmu_enabled) mmu_command(MMU_CMD_FS);
mmuFilamentMK3Moving = true;
fsensor_autoload_check_stop(); fsensor_autoload_check_stop();
//} fsensor_autoload_enabled = false;
return true; return true;
} }
return false; return false;

View File

@ -14,7 +14,7 @@ extern bool fsensor_not_responding;
//enable/disable quality meassurement //enable/disable quality meassurement
extern bool fsensor_oq_meassure_enabled; extern bool fsensor_oq_meassure_enabled;
extern bool mmuFilamentMK3Moving; //extern bool mmuFilamentMK3Moving;
extern bool mmuFSensorLoading; extern bool mmuFSensorLoading;

View File

@ -17,12 +17,22 @@ uint8_t lang_selected = 0;
#if (LANG_MODE == 0) //primary language only #if (LANG_MODE == 0) //primary language only
uint8_t lang_select(uint8_t lang) { return 0; } uint8_t lang_select(uint8_t lang) {
uint8_t lang_get_count() { return 1; } return 0;
uint16_t lang_get_code(uint8_t lang) { return LANG_CODE_EN; } }
const char* lang_get_name_by_code(uint16_t code) { return _n("English"); } uint8_t lang_get_count() {
return 1;
}
uint16_t lang_get_code(uint8_t lang) {
return LANG_CODE_EN;
}
const char* lang_get_name_by_code(uint16_t code) {
return _n("English");
}
void lang_reset(void) { } void lang_reset(void) { }
uint8_t lang_is_selected(void) { return 1; } uint8_t lang_is_selected(void) {
return 1;
}
#else //(LANG_MODE == 0) //secondary languages in progmem or xflash #else //(LANG_MODE == 0) //secondary languages in progmem or xflash
@ -37,227 +47,235 @@ lang_table_t* lang_table = 0;
const char* lang_get_translation(const char* s) const char* lang_get_translation(const char* s)
{ {
if (lang_selected == 0) return s + 2; //primary language selected, return orig. str. if (lang_selected == 0) return s + 2; //primary language selected, return orig. str.
if (lang_table == 0) return s + 2; //sec. lang table not found, return orig. str. if (lang_table == 0) return s + 2; //sec. lang table not found, return orig. str.
uint16_t ui = pgm_read_word(((uint16_t*)s)); //read string id uint16_t ui = pgm_read_word(((uint16_t*)s)); //read string id
if (ui == 0xffff) return s + 2; //translation not found, return orig. str. if (ui == 0xffff) return s + 2; //translation not found, return orig. str.
ui = pgm_read_word(((uint16_t*)(((char*)lang_table + 16 + ui*2)))); //read relative offset ui = pgm_read_word(((uint16_t*)(((char*)lang_table + 16 + ui*2)))); //read relative offset
if (pgm_read_byte(((uint8_t*)((char*)lang_table + ui))) == 0) //read first character if (pgm_read_byte(((uint8_t*)((char*)lang_table + ui))) == 0) //read first character
return s + 2;//zero length string == not translated, return orig. str. return s + 2;//zero length string == not translated, return orig. str.
return (const char*)((char*)lang_table + ui); //return calculated pointer return (const char*)((char*)lang_table + ui); //return calculated pointer
} }
uint8_t lang_select(uint8_t lang) uint8_t lang_select(uint8_t lang)
{ {
if (lang == LANG_ID_PRI) //primary language if (lang == LANG_ID_PRI) //primary language
{ {
lang_table = 0; lang_table = 0;
lang_selected = lang; lang_selected = lang;
} }
#ifdef W25X20CL #ifdef W25X20CL
if (lang_get_code(lang) == lang_get_code(LANG_ID_SEC)) lang = LANG_ID_SEC; if (lang_get_code(lang) == lang_get_code(LANG_ID_SEC)) lang = LANG_ID_SEC;
if (lang == LANG_ID_SEC) //current secondary language if (lang == LANG_ID_SEC) //current secondary language
{ {
if (pgm_read_dword(((uint32_t*)_SEC_LANG_TABLE)) == LANG_MAGIC) //magic valid if (pgm_read_dword(((uint32_t*)_SEC_LANG_TABLE)) == LANG_MAGIC) //magic valid
{ {
if (lang_check(_SEC_LANG_TABLE)) if (lang_check(_SEC_LANG_TABLE))
if (pgm_read_dword(((uint32_t*)(_SEC_LANG_TABLE + 12))) == pgm_read_dword(((uint32_t*)(_PRI_LANG_SIGNATURE)))) //signature valid if (pgm_read_dword(((uint32_t*)(_SEC_LANG_TABLE + 12))) == pgm_read_dword(((uint32_t*)(_PRI_LANG_SIGNATURE)))) //signature valid
{ {
lang_table = (lang_table_t*)(_SEC_LANG_TABLE); // set table pointer lang_table = (lang_table_t*)(_SEC_LANG_TABLE); // set table pointer
lang_selected = lang; // set language id lang_selected = lang; // set language id
} }
} }
} }
#else //W25X20CL #else //W25X20CL
if (lang == LANG_ID_SEC) if (lang == LANG_ID_SEC)
{ {
uint16_t table = _SEC_LANG_TABLE; uint16_t table = _SEC_LANG_TABLE;
if (pgm_read_dword(((uint32_t*)table)) == LANG_MAGIC) //magic valid if (pgm_read_dword(((uint32_t*)table)) == LANG_MAGIC) //magic valid
{ {
if (lang_check(table)) if (lang_check(table))
if (pgm_read_dword(((uint32_t*)(table + 12))) == pgm_read_dword(((uint32_t*)(_PRI_LANG_SIGNATURE)))) //signature valid if (pgm_read_dword(((uint32_t*)(table + 12))) == pgm_read_dword(((uint32_t*)(_PRI_LANG_SIGNATURE)))) //signature valid
{ {
lang_table = table; // set table pointer lang_table = table; // set table pointer
lang_selected = lang; // set language id lang_selected = lang; // set language id
} }
} }
} }
#endif //W25X20CL #endif //W25X20CL
if (lang_selected == lang) if (lang_selected == lang)
{ {
eeprom_update_byte((unsigned char*)EEPROM_LANG, lang_selected); eeprom_update_byte((unsigned char*)EEPROM_LANG, lang_selected);
return 1; return 1;
} }
return 0; return 0;
} }
uint8_t lang_check(uint16_t addr) uint8_t lang_check(uint16_t addr)
{ {
uint16_t sum = 0; uint16_t sum = 0;
uint16_t size = pgm_read_word((uint16_t*)(addr + 4)); uint16_t size = pgm_read_word((uint16_t*)(addr + 4));
uint16_t lt_sum = pgm_read_word((uint16_t*)(addr + 8)); uint16_t lt_sum = pgm_read_word((uint16_t*)(addr + 8));
uint16_t i; for (i = 0; i < size; i++) uint16_t i;
sum += (uint16_t)pgm_read_byte((uint8_t*)(addr + i)) << ((i & 1)?0:8); for (i = 0; i < size; i++)
sum -= lt_sum; //subtract checksum sum += (uint16_t)pgm_read_byte((uint8_t*)(addr + i)) << ((i & 1)?0:8);
sum = (sum >> 8) | ((sum & 0xff) << 8); //swap bytes sum -= lt_sum; //subtract checksum
return (sum == lt_sum); sum = (sum >> 8) | ((sum & 0xff) << 8); //swap bytes
return (sum == lt_sum);
} }
uint8_t lang_get_count() uint8_t lang_get_count()
{ {
if (pgm_read_dword(((uint32_t*)(_PRI_LANG_SIGNATURE))) == 0xffffffff) if (pgm_read_dword(((uint32_t*)(_PRI_LANG_SIGNATURE))) == 0xffffffff)
return 1; //signature not set - only primary language will be available return 1; //signature not set - only primary language will be available
#ifdef W25X20CL #ifdef W25X20CL
W25X20CL_SPI_ENTER(); W25X20CL_SPI_ENTER();
uint8_t count = 2; //count = 1+n (primary + secondary + all in xflash) uint8_t count = 2; //count = 1+n (primary + secondary + all in xflash)
uint32_t addr = 0x00000; //start of xflash uint32_t addr = 0x00000; //start of xflash
lang_table_header_t header; //table header structure lang_table_header_t header; //table header structure
while (1) while (1)
{ {
w25x20cl_rd_data(addr, (uint8_t*)&header, sizeof(lang_table_header_t)); //read table header from xflash w25x20cl_rd_data(addr, (uint8_t*)&header, sizeof(lang_table_header_t)); //read table header from xflash
if (header.magic != LANG_MAGIC) break; //break if magic not valid if (header.magic != LANG_MAGIC) break; //break if magic not valid
addr += header.size; //calc address of next table addr += header.size; //calc address of next table
count++; //inc counter count++; //inc counter
} }
#else //W25X20CL #else //W25X20CL
uint16_t table = _SEC_LANG_TABLE; uint16_t table = _SEC_LANG_TABLE;
uint8_t count = 1; //count = 1 (primary) uint8_t count = 1; //count = 1 (primary)
while (pgm_read_dword(((uint32_t*)table)) == LANG_MAGIC) //magic valid while (pgm_read_dword(((uint32_t*)table)) == LANG_MAGIC) //magic valid
{ {
table += pgm_read_word((uint16_t*)(table + 4)); table += pgm_read_word((uint16_t*)(table + 4));
count++; count++;
} }
#endif //W25X20CL #endif //W25X20CL
return count; return count;
} }
uint8_t lang_get_header(uint8_t lang, lang_table_header_t* header, uint32_t* offset) uint8_t lang_get_header(uint8_t lang, lang_table_header_t* header, uint32_t* offset)
{ {
if (lang == LANG_ID_PRI) return 0; //primary lang not supported for this function if (lang == LANG_ID_PRI) return 0; //primary lang not supported for this function
#ifdef W25X20CL #ifdef W25X20CL
if (lang == LANG_ID_SEC) if (lang == LANG_ID_SEC)
{ {
uint16_t ui = _SEC_LANG_TABLE; //table pointer uint16_t ui = _SEC_LANG_TABLE; //table pointer
memcpy_P(header, (lang_table_t*)(_SEC_LANG_TABLE), sizeof(lang_table_header_t)); //read table header from progmem memcpy_P(header, (lang_table_t*)(_SEC_LANG_TABLE), sizeof(lang_table_header_t)); //read table header from progmem
if (offset) *offset = ui; if (offset) *offset = ui;
return (header->magic == LANG_MAGIC)?1:0; //return 1 if magic valid return (header->magic == LANG_MAGIC)?1:0; //return 1 if magic valid
} }
W25X20CL_SPI_ENTER(); W25X20CL_SPI_ENTER();
uint32_t addr = 0x00000; //start of xflash uint32_t addr = 0x00000; //start of xflash
lang--; lang--;
while (1) while (1)
{ {
w25x20cl_rd_data(addr, (uint8_t*)(header), sizeof(lang_table_header_t)); //read table header from xflash w25x20cl_rd_data(addr, (uint8_t*)(header), sizeof(lang_table_header_t)); //read table header from xflash
if (header->magic != LANG_MAGIC) break; //break if not valid if (header->magic != LANG_MAGIC) break; //break if not valid
if (offset) *offset = addr; if (offset) *offset = addr;
if (--lang == 0) return 1; if (--lang == 0) return 1;
addr += header->size; //calc address of next table addr += header->size; //calc address of next table
} }
#else //W25X20CL #else //W25X20CL
if (lang == LANG_ID_SEC) if (lang == LANG_ID_SEC)
{ {
uint16_t ui = _SEC_LANG_TABLE; //table pointer uint16_t ui = _SEC_LANG_TABLE; //table pointer
memcpy_P(header, ui, sizeof(lang_table_header_t)); //read table header from progmem memcpy_P(header, ui, sizeof(lang_table_header_t)); //read table header from progmem
if (offset) *offset = ui; if (offset) *offset = ui;
return (header->magic == LANG_MAGIC)?1:0; //return 1 if magic valid return (header->magic == LANG_MAGIC)?1:0; //return 1 if magic valid
} }
#endif //W25X20CL #endif //W25X20CL
return 0; return 0;
} }
uint16_t lang_get_code(uint8_t lang) uint16_t lang_get_code(uint8_t lang)
{ {
if (lang == LANG_ID_PRI) return LANG_CODE_EN; //primary lang = EN if (lang == LANG_ID_PRI) return LANG_CODE_EN; //primary lang = EN
#ifdef W25X20CL #ifdef W25X20CL
if (lang == LANG_ID_SEC) if (lang == LANG_ID_SEC)
{ {
uint16_t ui = _SEC_LANG_TABLE; //table pointer uint16_t ui = _SEC_LANG_TABLE; //table pointer
if (pgm_read_dword(((uint32_t*)(ui + 0))) != LANG_MAGIC) return LANG_CODE_XX; //magic not valid if (pgm_read_dword(((uint32_t*)(ui + 0))) != LANG_MAGIC) return LANG_CODE_XX; //magic not valid
return pgm_read_word(((uint32_t*)(ui + 10))); //return lang code from progmem return pgm_read_word(((uint32_t*)(ui + 10))); //return lang code from progmem
} }
W25X20CL_SPI_ENTER(); W25X20CL_SPI_ENTER();
uint32_t addr = 0x00000; //start of xflash uint32_t addr = 0x00000; //start of xflash
lang_table_header_t header; //table header structure lang_table_header_t header; //table header structure
lang--; lang--;
while (1) while (1)
{ {
w25x20cl_rd_data(addr, (uint8_t*)&header, sizeof(lang_table_header_t)); //read table header from xflash w25x20cl_rd_data(addr, (uint8_t*)&header, sizeof(lang_table_header_t)); //read table header from xflash
if (header.magic != LANG_MAGIC) break; //break if not valid if (header.magic != LANG_MAGIC) break; //break if not valid
if (--lang == 0) return header.code; if (--lang == 0) return header.code;
addr += header.size; //calc address of next table addr += header.size; //calc address of next table
} }
#else //W25X20CL #else //W25X20CL
uint16_t table = _SEC_LANG_TABLE; uint16_t table = _SEC_LANG_TABLE;
uint8_t count = 1; //count = 1 (primary) uint8_t count = 1; //count = 1 (primary)
while (pgm_read_dword((uint32_t*)table) == LANG_MAGIC) //magic valid while (pgm_read_dword((uint32_t*)table) == LANG_MAGIC) //magic valid
{ {
if (count == lang) return pgm_read_word(((uint16_t*)(table + 10))); //read language code if (count == lang) return pgm_read_word(((uint16_t*)(table + 10))); //read language code
table += pgm_read_word((uint16_t*)(table + 4)); table += pgm_read_word((uint16_t*)(table + 4));
count++; count++;
} }
#endif //W25X20CL #endif //W25X20CL
return LANG_CODE_XX; return LANG_CODE_XX;
} }
const char* lang_get_name_by_code(uint16_t code) const char* lang_get_name_by_code(uint16_t code)
{ {
switch (code) switch (code)
{ {
case LANG_CODE_EN: return _n("English"); case LANG_CODE_EN:
case LANG_CODE_CZ: return _n("Cestina"); return _n("English");
case LANG_CODE_DE: return _n("Deutsch"); case LANG_CODE_CZ:
case LANG_CODE_ES: return _n("Espanol"); return _n("Cestina");
case LANG_CODE_FR: return _n("Francais"); case LANG_CODE_DE:
case LANG_CODE_IT: return _n("Italiano"); return _n("Deutsch");
case LANG_CODE_PL: return _n("Polski"); case LANG_CODE_ES:
} return _n("Espanol");
return _n("??"); case LANG_CODE_FR:
return _n("Francais");
case LANG_CODE_IT:
return _n("Italiano");
case LANG_CODE_PL:
return _n("Polski");
}
return _n("??");
} }
void lang_reset(void) void lang_reset(void)
{ {
lang_selected = 0; lang_selected = 0;
eeprom_update_byte((unsigned char*)EEPROM_LANG, LANG_ID_FORCE_SELECTION); eeprom_update_byte((unsigned char*)EEPROM_LANG, LANG_ID_FORCE_SELECTION);
} }
uint8_t lang_is_selected(void) uint8_t lang_is_selected(void)
{ {
uint8_t lang_eeprom = eeprom_read_byte((unsigned char*)EEPROM_LANG); uint8_t lang_eeprom = eeprom_read_byte((unsigned char*)EEPROM_LANG);
return (lang_eeprom != LANG_ID_FORCE_SELECTION) && (lang_eeprom == lang_selected); return (lang_eeprom != LANG_ID_FORCE_SELECTION) && (lang_eeprom == lang_selected);
} }
#ifdef DEBUG_SEC_LANG #ifdef DEBUG_SEC_LANG
#include <stdio.h> #include <stdio.h>
const char* lang_get_sec_lang_str_by_id(uint16_t id) const char* lang_get_sec_lang_str_by_id(uint16_t id)
{ {
uint16_t ui = _SEC_LANG_TABLE; //table pointer uint16_t ui = _SEC_LANG_TABLE; //table pointer
return ui + pgm_read_word(((uint16_t*)(ui + 16 + id * 2))); //read relative offset and return calculated pointer return ui + pgm_read_word(((uint16_t*)(ui + 16 + id * 2))); //read relative offset and return calculated pointer
} }
uint16_t lang_print_sec_lang(FILE* out) uint16_t lang_print_sec_lang(FILE* out)
{ {
printf_P(_n("&_SEC_LANG = 0x%04x\n"), &_SEC_LANG); printf_P(_n("&_SEC_LANG = 0x%04x\n"), &_SEC_LANG);
printf_P(_n("sizeof(_SEC_LANG) = 0x%04x\n"), sizeof(_SEC_LANG)); printf_P(_n("sizeof(_SEC_LANG) = 0x%04x\n"), sizeof(_SEC_LANG));
uint16_t ptr_lang_table0 = ((uint16_t)(&_SEC_LANG) + 0xff) & 0xff00; uint16_t ptr_lang_table0 = ((uint16_t)(&_SEC_LANG) + 0xff) & 0xff00;
printf_P(_n("&_lang_table0 = 0x%04x\n"), ptr_lang_table0); printf_P(_n("&_lang_table0 = 0x%04x\n"), ptr_lang_table0);
uint32_t _lt_magic = pgm_read_dword(((uint32_t*)(ptr_lang_table0 + 0))); uint32_t _lt_magic = pgm_read_dword(((uint32_t*)(ptr_lang_table0 + 0)));
uint16_t _lt_size = pgm_read_word(((uint16_t*)(ptr_lang_table0 + 4))); uint16_t _lt_size = pgm_read_word(((uint16_t*)(ptr_lang_table0 + 4)));
uint16_t _lt_count = pgm_read_word(((uint16_t*)(ptr_lang_table0 + 6))); uint16_t _lt_count = pgm_read_word(((uint16_t*)(ptr_lang_table0 + 6)));
uint16_t _lt_chsum = pgm_read_word(((uint16_t*)(ptr_lang_table0 + 8))); uint16_t _lt_chsum = pgm_read_word(((uint16_t*)(ptr_lang_table0 + 8)));
uint16_t _lt_resv0 = pgm_read_word(((uint16_t*)(ptr_lang_table0 + 10))); uint16_t _lt_resv0 = pgm_read_word(((uint16_t*)(ptr_lang_table0 + 10)));
uint32_t _lt_resv1 = pgm_read_dword(((uint32_t*)(ptr_lang_table0 + 12))); uint32_t _lt_resv1 = pgm_read_dword(((uint32_t*)(ptr_lang_table0 + 12)));
printf_P(_n(" _lt_magic = 0x%08lx %S\n"), _lt_magic, (_lt_magic==LANG_MAGIC)?_n("OK"):_n("NA")); printf_P(_n(" _lt_magic = 0x%08lx %S\n"), _lt_magic, (_lt_magic==LANG_MAGIC)?_n("OK"):_n("NA"));
printf_P(_n(" _lt_size = 0x%04x (%d)\n"), _lt_size, _lt_size); printf_P(_n(" _lt_size = 0x%04x (%d)\n"), _lt_size, _lt_size);
printf_P(_n(" _lt_count = 0x%04x (%d)\n"), _lt_count, _lt_count); printf_P(_n(" _lt_count = 0x%04x (%d)\n"), _lt_count, _lt_count);
printf_P(_n(" _lt_chsum = 0x%04x\n"), _lt_chsum); printf_P(_n(" _lt_chsum = 0x%04x\n"), _lt_chsum);
printf_P(_n(" _lt_resv0 = 0x%04x\n"), _lt_resv0); printf_P(_n(" _lt_resv0 = 0x%04x\n"), _lt_resv0);
printf_P(_n(" _lt_resv1 = 0x%08lx\n"), _lt_resv1); printf_P(_n(" _lt_resv1 = 0x%08lx\n"), _lt_resv1);
if (_lt_magic != LANG_MAGIC) return 0; if (_lt_magic != LANG_MAGIC) return 0;
puts_P(_n(" strings:\n")); puts_P(_n(" strings:\n"));
uint16_t ui = _SEC_LANG_TABLE; //table pointer uint16_t ui = _SEC_LANG_TABLE; //table pointer
for (ui = 0; ui < _lt_count; ui++) for (ui = 0; ui < _lt_count; ui++)
fprintf_P(out, _n(" %3d %S\n"), ui, lang_get_sec_lang_str_by_id(ui)); fprintf_P(out, _n(" %3d %S\n"), ui, lang_get_sec_lang_str_by_id(ui));
return _lt_count; return _lt_count;
} }
#endif //DEBUG_SEC_LANG #endif //DEBUG_SEC_LANG
@ -266,7 +284,7 @@ uint16_t lang_print_sec_lang(FILE* out)
void lang_boot_update_start(uint8_t lang) void lang_boot_update_start(uint8_t lang)
{ {
uint8_t cnt = lang_get_count(); uint8_t cnt = lang_get_count();
if ((lang < 2) || (lang > cnt)) return; //only languages from xflash can be selected if ((lang < 2) || (lang > cnt)) return; //only languages from xflash can be selected
bootapp_reboot_user0(lang << 4); bootapp_reboot_user0(lang << 4);
} }

View File

@ -29,13 +29,14 @@ bool mmu_enabled = false;
bool mmu_ready = false; bool mmu_ready = false;
bool mmuFilamentMK3Moving = false;
bool mmuFSensorLoading = false; bool mmuFSensorLoading = false;
int lastLoadedFilament = -10; int lastLoadedFilament = -10;
int8_t mmu_state = 0; int8_t mmu_state = 0;
int8_t last_state = -10;
uint8_t mmu_cmd = 0; uint8_t mmu_cmd = 0;
bool ack_received = false;
uint8_t mmu_extruder = 0; uint8_t mmu_extruder = 0;
@ -78,6 +79,75 @@ int mmu_printf_P(const char* format, ...)
return r; return r;
} }
//check 'sensing Filament at Boot' response
int8_t mmu_rx_echo(void)
{
int8_t res = 0;
switch (mmu_cmd)
{
case MMU_CMD_T0: // T0
res = uart2_rx_str_P(PSTR("T0\n"));
break;
case MMU_CMD_T1: // T1
res = uart2_rx_str_P(PSTR("T1\n"));
break;
case MMU_CMD_T2: // T2
res = uart2_rx_str_P(PSTR("T2\n"));
break;
case MMU_CMD_T3: // T3
res = uart2_rx_str_P(PSTR("T3\n"));
break;
case MMU_CMD_T4: // T4
res = uart2_rx_str_P(PSTR("T4\n"));
break;
case MMU_CMD_L0: // L0
res = uart2_rx_str_P(PSTR("L0\n"));
break;
case MMU_CMD_L1: // L1
res = uart2_rx_str_P(PSTR("L1\n"));
break;
case MMU_CMD_L2: // L2
res = uart2_rx_str_P(PSTR("L2\n"));
break;
case MMU_CMD_L3: // L3
res = uart2_rx_str_P(PSTR("L3\n"));
break;
case MMU_CMD_L4: // L4
res = uart2_rx_str_P(PSTR("L4\n"));
break;
case MMU_CMD_C0: // C0
res = uart2_rx_str_P(PSTR("C0\n"));
break;
case MMU_CMD_U0: // U0
res = uart2_rx_str_P(PSTR("U0\n"));
break;
case MMU_CMD_E0: // E0
res = uart2_rx_str_P(PSTR("E0\n"));
break;
case MMU_CMD_E1: // E1
res = uart2_rx_str_P(PSTR("E1\n"));
break;
case MMU_CMD_E2: // E2
res = uart2_rx_str_P(PSTR("E2\n"));
break;
case MMU_CMD_E3: // E3
res = uart2_rx_str_P(PSTR("E3\n"));
break;
case MMU_CMD_E4: // E4
res = uart2_rx_str_P(PSTR("E4\n"));
break;
case MMU_CMD_R0: // R0
res = uart2_rx_str_P(PSTR("R0\n"));
break;
case MMU_CMD_FS: // FS
res = uart2_rx_str_P(PSTR("FS\n"));
break;
}
//if (res == 0) puts_P(PSTR("MMU Didn't see CMD and ECHO"));
if (res == 1) mmu_last_response = millis();
return res;
}
//check 'ok' response //check 'ok' response
int8_t mmu_rx_ok(void) int8_t mmu_rx_ok(void)
{ {
@ -86,18 +156,18 @@ int8_t mmu_rx_ok(void)
return res; return res;
} }
//check 'sensing Filament at Boot' response //check 'nk' response
int8_t mmu_rx_sensFilatBoot() int8_t mmu_rx_not_ok(void)
{ {
int8_t res = uart2_rx_str_P(PSTR("FB\n")); // FB stands for filament boot int8_t res = uart2_rx_str_P(PSTR("nk\n"));
if (res == 1) mmu_last_response = millis(); if (res == 1) mmu_last_response = millis();
return res; return res;
} }
//check ' not ok' response //check 'MK3 FSensor requested to look for load' response
int8_t mmu_rx_not_ok(void) int8_t mmu_rx_fsensorLook(void)
{ {
int8_t res = uart2_rx_str_P(PSTR("not_ok\n")); int8_t res = uart2_rx_str_P(PSTR("fl\n"));
if (res == 1) mmu_last_response = millis(); if (res == 1) mmu_last_response = millis();
return res; return res;
} }
@ -124,10 +194,28 @@ void mmu_init(void)
} }
//mmu main loop - state machine processing //mmu main loop - state machine processing
/**
* MMU States
* -1 >> -2 MMURX Start, respond with S1 (30s timeout to disabled state)
* -2 >> -3 MMURX ok, respond with S2
* -3 >> -4 MMURX ok, respond with P0(READ FINDA) if MK3 and goto -4
* -5 respond with M1(MODE STEALTH) if MK2.5 and goto -5
* -4 >> 1 MMURX ok, mmu_ready
* -5 >> 1 MMURX ok, mmu_ready
* 1 >> ? MMU CMD Request from MK3
* 2 >> 1 MMURX ok, Finda State
* 3 >> 1 MMURX ok, mmu commands response
* 10 >> 3 MMUECHO, confirm receipt of cmd (timeout 500ms to resend)
* 20 >> 1 not_ok
*/
void mmu_loop(void) void mmu_loop(void)
{ {
int filament = 0; int filament = 0;
// printf_P(PSTR("MMU loop, state=%d\n"), mmu_state); #ifdef MMU_DEBUG
if (last_state != mmu_state) printf_P(PSTR("MMU loop, state=%d\n"), mmu_state);
#endif //MMU_DEBUG
last_state = mmu_state;
switch (mmu_state) switch (mmu_state)
{ {
case 0: case 0:
@ -141,15 +229,7 @@ void mmu_loop(void)
#endif //MMU_DEBUG #endif //MMU_DEBUG
mmu_puts_P(PSTR("S1\n")); //send 'read version' request mmu_puts_P(PSTR("S1\n")); //send 'read version' request
mmu_state = -2; mmu_state = -2;
} /*else if (mmu_rx_sensFilatBoot() > 0) }
{
printf_P(PSTR("MMU => '%Sensed Filament at Boot'\n"), mmu_finda);
//enquecommand_front_P(PSTR("M104 S210"));
enquecommand_front_P(PSTR("M109 S210"));
delay(200);
extr_unload_at_boot();
mmu_puts_P(PSTR("FB\n")); //Advise unloaded to above bondtech for retraction
}*/
else if (millis() > 30000) //30sec after reset disable mmu else if (millis() > 30000) //30sec after reset disable mmu
{ {
puts_P(PSTR("MMU not responding - DISABLED")); puts_P(PSTR("MMU not responding - DISABLED"));
@ -216,83 +296,134 @@ void mmu_loop(void)
printf_P(PSTR("MMU => '%dok'\n"), mmu_finda); printf_P(PSTR("MMU => '%dok'\n"), mmu_finda);
#endif //MMU_DEBUG #endif //MMU_DEBUG
puts_P(PSTR("MMU - ENABLED")); puts_P(PSTR("MMU - ENABLED"));
fsensor_enable();
mmu_enabled = true; mmu_enabled = true;
mmu_state = 1; mmu_state = 1;
} }
return; return;
case 1: case 1:
if (mmu_cmd) //command request ? if (mmu_cmd && !ack_received) //command request ?
{ {
switch (mmu_cmd) {
case MMU_CMD_T0:
mmu_puts_P(PSTR("T0\n"));
break;
case MMU_CMD_T1:
mmu_puts_P(PSTR("T1\n"));
break;
case MMU_CMD_T2:
mmu_puts_P(PSTR("T2\n"));
break;
case MMU_CMD_T3:
mmu_puts_P(PSTR("T3\n"));
break;
case MMU_CMD_T4:
mmu_puts_P(PSTR("T4\n"));
break;
case MMU_CMD_L0:
mmu_puts_P(PSTR("L0\n"));
break;
case MMU_CMD_L1:
mmu_puts_P(PSTR("L1\n"));
break;
case MMU_CMD_L2:
mmu_puts_P(PSTR("L2\n"));
break;
case MMU_CMD_L3:
mmu_puts_P(PSTR("L3\n"));
break;
case MMU_CMD_L4:
mmu_puts_P(PSTR("L4\n"));
break;
case MMU_CMD_C0:
mmu_puts_P(PSTR("C0\n"));
break;
case MMU_CMD_U0:
mmu_puts_P(PSTR("U0\n"));
break;
case MMU_CMD_E0:
mmu_puts_P(PSTR("E0\n"));
break;
case MMU_CMD_E1:
mmu_puts_P(PSTR("E1\n"));
break;
case MMU_CMD_E2:
mmu_puts_P(PSTR("E2\n"));
break;
case MMU_CMD_E3:
mmu_puts_P(PSTR("E3\n"));
break;
case MMU_CMD_E4:
mmu_puts_P(PSTR("E4\n"));
break;
case MMU_CMD_R0:
mmu_puts_P(PSTR("R0\n"));
break;
case MMU_CMD_FS:
mmu_puts_P(PSTR("FS\n"));
break;
}
mmu_state = 10;
} else if (mmu_cmd && ack_received) {
ack_received = false;
if ((mmu_cmd >= MMU_CMD_T0) && (mmu_cmd <= MMU_CMD_T4)) if ((mmu_cmd >= MMU_CMD_T0) && (mmu_cmd <= MMU_CMD_T4))
{ {
filament = mmu_cmd - MMU_CMD_T0; filament = mmu_cmd - MMU_CMD_T0;
#ifdef MMU_DEBUG
printf_P(PSTR("MMU <= 'T%d'\n"), filament);
#endif //MMU_DEBUG
fsensor_enable();
delay(100);
mmu_printf_P(PSTR("T%d\n"), filament);
mmu_state = 3; // wait for response
if (lastLoadedFilament != filament) { if (lastLoadedFilament != filament) {
fsensor_autoload_check_start(); printf_P(PSTR("MMU <= 'T%d'\n"), filament);
mmuFSensorLoading = true; mmu_puts_P(PSTR("EE\n")); // Advise MMU CMD is correct, execute
//fsensor_enable(); mmu_state = 3; // wait for response
fsensor_autoload_enabled = true; } else {
mmuFilamentMK3Moving = false; mmu_puts_P(PSTR("EE\n")); // Advise MMU CMD is correct, execute
mmu_state = 3;
} }
lastLoadedFilament = filament; lastLoadedFilament = filament;
} }
else if ((mmu_cmd >= MMU_CMD_L0) && (mmu_cmd <= MMU_CMD_L4)) else if ((mmu_cmd >= MMU_CMD_L0) && (mmu_cmd <= MMU_CMD_L4))
{ {
filament = mmu_cmd - MMU_CMD_L0; filament = mmu_cmd - MMU_CMD_L0;
#ifdef MMU_DEBUG
printf_P(PSTR("MMU <= 'L%d'\n"), filament); printf_P(PSTR("MMU <= 'L%d'\n"), filament);
#endif //MMU_DEBUG mmu_puts_P(PSTR("EE\n")); // Advise MMU CMD is correct, execute
mmu_printf_P(PSTR("L%d\n"), filament);
mmu_state = 3; // wait for response mmu_state = 3; // wait for response
} }
else if (mmu_cmd == MMU_CMD_C0) else if (mmu_cmd == MMU_CMD_C0)
{ {
#ifdef MMU_DEBUG delay(100);
printf_P(PSTR("MMU <= 'C0'\n")); printf_P(PSTR("MMU <= 'C0'\n"));
#endif //MMU_DEBUG mmu_puts_P(PSTR("EE\n")); // Advise MMU CMD is correct, execute
delay(200);
mmu_puts_P(PSTR("C0\n")); //send 'continue loading'
mmu_state = 3; mmu_state = 3;
} }
else if (mmu_cmd == MMU_CMD_U0) else if (mmu_cmd == MMU_CMD_U0)
{ {
#ifdef MMU_DEBUG
printf_P(PSTR("MMU <= 'U0'\n")); printf_P(PSTR("MMU <= 'U0'\n"));
#endif //MMU_DEBUG mmu_puts_P(PSTR("EE\n")); // Advise MMU CMD is correct, execute
mmu_puts_P(PSTR("U0\n")); //send 'unload current filament'
lastLoadedFilament = -10; lastLoadedFilament = -10;
mmu_state = 3; mmu_state = 3;
} }
else if ((mmu_cmd >= MMU_CMD_E0) && (mmu_cmd <= MMU_CMD_E4)) else if ((mmu_cmd >= MMU_CMD_E0) && (mmu_cmd <= MMU_CMD_E4))
{ {
int filament = mmu_cmd - MMU_CMD_E0; int filament = mmu_cmd - MMU_CMD_E0;
#ifdef MMU_DEBUG
printf_P(PSTR("MMU <= 'E%d'\n"), filament); printf_P(PSTR("MMU <= 'E%d'\n"), filament);
#endif //MMU_DEBUG mmu_puts_P(PSTR("EE\n")); // Advise MMU CMD is correct, execute
mmu_printf_P(PSTR("E%d\n"), filament); //send eject filament
mmu_state = 3; // wait for response mmu_state = 3; // wait for response
} }
else if (mmu_cmd == MMU_CMD_R0) else if (mmu_cmd == MMU_CMD_R0)
{ {
#ifdef MMU_DEBUG
printf_P(PSTR("MMU <= 'R0'\n")); printf_P(PSTR("MMU <= 'R0'\n"));
#endif //MMU_DEBUG mmu_puts_P(PSTR("EE\n")); // Advise MMU CMD is correct, execute
mmu_puts_P(PSTR("R0\n")); //send recover after eject mmu_state = 3; // wait for response
}
else if (mmu_cmd == MMU_CMD_FS)
{
printf_P(PSTR("MMU <= 'Filament seen at extruder'\n"));
mmu_puts_P(PSTR("EE\n"));
//mmuFSensorLoading = false;
mmu_state = 3; // wait for response mmu_state = 3; // wait for response
} }
mmu_cmd = 0; mmu_cmd = 0;
} }
else if ((mmu_last_response + 300) < millis()) //request every 300ms else if ((mmu_last_response + 500) < millis()) //request every 500ms
{ {
#ifdef MMU_DEBUG
puts_P(PSTR("MMU <= 'P0'"));
#endif //MMU_DEBUG
mmu_puts_P(PSTR("P0\n")); //send 'read finda' request mmu_puts_P(PSTR("P0\n")); //send 'read finda' request
mmu_state = 2; mmu_state = 2;
} }
@ -301,9 +432,7 @@ void mmu_loop(void)
if (mmu_rx_ok() > 0) if (mmu_rx_ok() > 0)
{ {
fscanf_P(uart2io, PSTR("%hhu"), &mmu_finda); //scan finda from buffer fscanf_P(uart2io, PSTR("%hhu"), &mmu_finda); //scan finda from buffer
#ifdef MMU_DEBUG //printf_P(PSTR("MMU => '%dok'\n"), mmu_finda);
printf_P(PSTR("MMU => '%dok'\n"), mmu_finda);
#endif //MMU_DEBUG
if (!mmu_finda && CHECK_FINDA && fsensor_enabled) { if (!mmu_finda && CHECK_FINDA && fsensor_enabled) {
fsensor_stop_and_save_print(); fsensor_stop_and_save_print();
enquecommand_front_P(PSTR("FSENSOR_RECOVER")); //then recover enquecommand_front_P(PSTR("FSENSOR_RECOVER")); //then recover
@ -311,8 +440,8 @@ void mmu_loop(void)
else enquecommand_front_P(PSTR("M600")); //save print and run M600 command else enquecommand_front_P(PSTR("M600")); //save print and run M600 command
} }
mmu_state = 1; mmu_state = 1;
if (mmu_cmd == 0) //if (mmu_cmd == 0)
mmu_ready = true; //mmu_ready = true;
} }
else if ((mmu_last_request + MMU_P0_TIMEOUT) < millis()) else if ((mmu_last_request + MMU_P0_TIMEOUT) < millis())
{ //resend request after timeout (30s) { //resend request after timeout (30s)
@ -320,29 +449,56 @@ void mmu_loop(void)
} }
return; return;
case 3: //response to mmu commands case 3: //response to mmu commands
if(mmu_rx_fsensorLook() > 0)
{
printf_P(PSTR("MMU => 'waiting for filament @ MK3 Sensor'\n"));
if (!fsensor_enabled) fsensor_enable();
mmuFSensorLoading = true;
fsensor_autoload_enabled = true;
fsensor_autoload_check_stop();
mmu_state = 1;
} else if (mmu_rx_ok() > 0)
{
if (mmuFSensorLoading == true) {
mmuFSensorLoading = false;
printf_P(PSTR("MMU => 'ok :)'\n"));
}
printf_P(PSTR("MMU => 'ok'\n"));
mmu_ready = true;
mmu_state = 1;
} else if(mmu_rx_not_ok() > 0)
{
printf_P(PSTR("MMU => 'fixTheProblem!!'\n"));
mmu_ready = false;
mmu_state = 20;
}
else if ((mmu_last_request + MMU_CMD_TIMEOUT) < millis())
{ //resend request after timeout (5 min)
printf_P(PSTR("MMU => 'Erro 5m Timeout'\n"));
mmu_ready = false;
mmu_state = 20;
}
return;
case 10: //echo response, comms confirmation
if (mmu_rx_echo() > 0)
{
printf_P(PSTR("MMU => 'CMD ACK 0x%2X'\n"), mmu_cmd);
//mmu_puts_P(PSTR("EE\n")); // Advise MMU CMD is correct, execute
ack_received = true;
mmu_state = 1; // Do normal Await command completion confirmation
} else if ((mmu_last_request + 1000) < millis()) { // Timeout if echo doesn't match request, resend cmd
//printf_P(PSTR("MMU => 'CMD RETRY'\n"));
printf_P(PSTR("MMU => 'CMD RETRY 0x%2X'\n"), mmu_cmd);
mmu_state = 1;
}
return;
case 20: // MMU in fixTheProblem mode, we're waiting for an all good from it to continue.
if (mmu_rx_ok() > 0) if (mmu_rx_ok() > 0)
{ {
if (mmuFSensorLoading == false) { //if ok received then go back to ready
delay(100); mmu_state = 1;
printf_P(PSTR("MMU => 'ok'\n")); mmu_ready = true;
mmu_ready = true;
mmu_state = 1;
} else if (mmuFilamentMK3Moving == true) {
//mmu_puts_P(PSTR("FS\n"));
mmu_printf_P(PSTR("FS%d\n"), 1);
printf_P(PSTR("MMU => 'Advised of filament seen at extruder'\n"));
mmuFSensorLoading = false;
} else {
printf_P(PSTR("MMU => 'waiting for filament @ MK3 Sensor'\n"));
}
} else if (mmu_rx_not_ok() > 0) {
printf_P(PSTR("MMU => 'Waiting'\n"));
} }
/*else if ((mmu_last_request + MMU_CMD_TIMEOUT) < millis())
{ //resend request after timeout (5 min)
mmu_state = 1;
}*/
return;
} }
} }
@ -380,15 +536,15 @@ bool mmu_get_response(void)
KEEPALIVE_STATE(IN_PROCESS); KEEPALIVE_STATE(IN_PROCESS);
while (mmu_cmd != 0) while (mmu_cmd != 0)
{ {
// mmu_loop();
delay_keep_alive(100); delay_keep_alive(100);
} }
while (!mmu_ready) while (!mmu_ready)
{ {
// mmu_loop(); if ((mmu_state == 3) || (mmu_state == 10) || (mmuFSensorLoading)) {
if (mmu_state != 3) delay_keep_alive(100);
} else {
break; break;
delay_keep_alive(100); }
} }
bool ret = mmu_ready; bool ret = mmu_ready;
mmu_ready = false; mmu_ready = false;
@ -408,7 +564,7 @@ void manage_response(bool move_axes, bool turn_off_nozzle)
while(!response) while(!response)
{ {
response = mmu_get_response(); //wait for "ok" from mmu response = mmu_get_response(); //wait for "ok" from mmu
if (!response) { //no "ok" was received in reserved time frame, user will fix the issue on mmu unit if (!response) { //no "ok" or "echo" was received in reserved time frame, user will fix the issue on mmu unit
if (!mmu_print_saved) { //first occurence, we are saving current position, park print head in certain position and disable nozzle heater if (!mmu_print_saved) { //first occurence, we are saving current position, park print head in certain position and disable nozzle heater
if (lcd_update_enabled) { if (lcd_update_enabled) {
lcd_update_was_enabled = true; lcd_update_was_enabled = true;
@ -550,6 +706,7 @@ void mmu_M600_load_filament(bool automatic)
{ {
//load filament for mmu v2 //load filament for mmu v2
tmp_extruder = mmu_extruder; tmp_extruder = mmu_extruder;
lastLoadedFilament = -10;
if (!automatic) { if (!automatic) {
#ifdef MMU_M600_SWITCH_EXTRUDER #ifdef MMU_M600_SWITCH_EXTRUDER
bool yes = lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Do you want to switch extruder?"), false); bool yes = lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Do you want to switch extruder?"), false);
@ -572,9 +729,10 @@ void mmu_M600_load_filament(bool automatic)
mmu_command(MMU_CMD_T0 + tmp_extruder); mmu_command(MMU_CMD_T0 + tmp_extruder);
manage_response(false, true); manage_response(false, true);
delay(100);
mmu_command(MMU_CMD_C0); mmu_command(MMU_CMD_C0);
mmu_extruder = tmp_extruder; //filament change is finished mmu_extruder = tmp_extruder; //filament change is finished
delay(100);
mmu_load_to_nozzle(); mmu_load_to_nozzle();
@ -840,106 +998,6 @@ void extr_unload()
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 2500 / 60, active_extruder); plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 2500 / 60, active_extruder);
current_position[E_AXIS] += 4; current_position[E_AXIS] += 4;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3000 / 60, active_extruder); plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3000 / 60, active_extruder);
/*current_position[X_AXIS] += 23; //delay
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 600 / 60, active_extruder); //delay
current_position[X_AXIS] -= 23; //delay
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 600 / 60, active_extruder); //delay*/
delay_keep_alive(4700);
}
max_feedrate[E_AXIS] = 80;
current_position[E_AXIS] -= (bowden_length[mmu_extruder] + 60 + FIL_LOAD_LENGTH) / 2;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 500, active_extruder);
current_position[E_AXIS] -= (bowden_length[mmu_extruder] + 60 + FIL_LOAD_LENGTH) / 2;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 500, active_extruder);
st_synchronize();
//st_current_init();
if (SilentMode != SILENT_MODE_OFF) st_current_set(2, tmp_motor[2]); //set back to normal operation currents
else st_current_set(2, tmp_motor_loud[2]);
lcd_update_enable(true);
lcd_return_to_status();
max_feedrate[E_AXIS] = 50;
#endif //SNMM
}
else
{
lcd_clear();
lcd_set_cursor(0, 0);
lcd_puts_P(_T(MSG_ERROR));
lcd_set_cursor(0, 2);
lcd_puts_P(_T(MSG_PREHEAT_NOZZLE));
delay(2000);
lcd_clear();
}
//lcd_return_to_status();
}
void extr_unload_at_boot()
{ //unload just current filament for multimaterial printers
#ifdef SNMM
float tmp_motor[3] = DEFAULT_PWM_MOTOR_CURRENT;
float tmp_motor_loud[3] = DEFAULT_PWM_MOTOR_CURRENT_LOUD;
uint8_t SilentMode = eeprom_read_byte((uint8_t*)EEPROM_SILENT);
#endif
if (degHotend0() > EXTRUDE_MINTEMP)
{
#ifndef SNMM
st_synchronize();
//show which filament is currently unloaded
lcd_update_enable(false);
lcd_clear();
lcd_set_cursor(0, 1);
lcd_puts_P(_T(MSG_UNLOADING_FILAMENT));
lcd_print(" ");
lcd_print(mmu_extruder + 1);
filament_ramming();
//mmu_command(MMU_CMD_U0);
// get response
manage_response(false, true);
lcd_update_enable(true);
#else //SNMM
lcd_clear();
lcd_display_message_fullscreen_P(PSTR(""));
max_feedrate[E_AXIS] = 50;
lcd_set_cursor(0, 0);
lcd_puts_P(_T(MSG_UNLOADING_FILAMENT));
lcd_print(" ");
lcd_print(mmu_extruder + 1);
lcd_set_cursor(0, 2);
lcd_puts_P(_T(MSG_PLEASE_WAIT));
if (current_position[Z_AXIS] < 15) {
current_position[Z_AXIS] += 15; //lifting in Z direction to make space for extrusion
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 25, active_extruder);
}
current_position[E_AXIS] += 10; //extrusion
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 10, active_extruder);
st_current_set(2, E_MOTOR_HIGH_CURRENT);
if (current_temperature[0] < 230) { //PLA & all other filaments
current_position[E_AXIS] += 5.4;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 2800 / 60, active_extruder);
current_position[E_AXIS] += 3.2;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3000 / 60, active_extruder);
current_position[E_AXIS] += 3;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3400 / 60, active_extruder);
}
else { //ABS
current_position[E_AXIS] += 3.1;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 2000 / 60, active_extruder);
current_position[E_AXIS] += 3.1;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 2500 / 60, active_extruder);
current_position[E_AXIS] += 4;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3000 / 60, active_extruder);
/*current_position[X_AXIS] += 23; //delay
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 600 / 60, active_extruder); //delay
current_position[X_AXIS] -= 23; //delay
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 600 / 60, active_extruder); //delay*/
delay_keep_alive(4700); delay_keep_alive(4700);
} }

View File

@ -28,7 +28,6 @@ extern int16_t mmu_buildnr;
#define MMU_CMD_L3 0x23 #define MMU_CMD_L3 0x23
#define MMU_CMD_L4 0x24 #define MMU_CMD_L4 0x24
#define MMU_CMD_C0 0x30 #define MMU_CMD_C0 0x30
#define MMU_CMD_C1 0x31
#define MMU_CMD_U0 0x40 #define MMU_CMD_U0 0x40
#define MMU_CMD_E0 0x50 #define MMU_CMD_E0 0x50
#define MMU_CMD_E1 0x51 #define MMU_CMD_E1 0x51
@ -36,12 +35,15 @@ extern int16_t mmu_buildnr;
#define MMU_CMD_E3 0x53 #define MMU_CMD_E3 0x53
#define MMU_CMD_E4 0x54 #define MMU_CMD_E4 0x54
#define MMU_CMD_R0 0x60 #define MMU_CMD_R0 0x60
#define MMU_CMD_P0 0x70
#define MMU_CMD_FS 0x81
extern int mmu_puts_P(const char* str); extern int mmu_puts_P(const char* str);
extern int mmu_printf_P(const char* format, ...); extern int mmu_printf_P(const char* format, ...);
extern int8_t mmu_rx_echo(void);
extern int8_t mmu_rx_ok(void); extern int8_t mmu_rx_ok(void);
extern int8_t mmu_rx_not_ok(void); extern int8_t mmu_rx_not_ok(void);

View File

@ -46,9 +46,9 @@ uint8_t pat9125_s = 0;
// Init sequence, address & value. // Init sequence, address & value.
const PROGMEM uint8_t pat9125_init_seq1[] = { const PROGMEM uint8_t pat9125_init_seq1[] = {
// Disable write protect. // Disable write protect.
PAT9125_WP, 0x5a, PAT9125_WP, 0x5a,
// Set the X resolution to zero to let the sensor know that it could safely ignore movement in the X axis. // Set the X resolution to zero to let the sensor know that it could safely ignore movement in the X axis.
PAT9125_RES_X, PAT9125_XRES, PAT9125_RES_X, PAT9125_XRES,
// Set the Y resolution to a maximum (or nearly a maximum). // Set the Y resolution to a maximum (or nearly a maximum).
PAT9125_RES_Y, PAT9125_YRES, PAT9125_RES_Y, PAT9125_YRES,
@ -66,33 +66,33 @@ const PROGMEM uint8_t pat9125_init_seq1[] = {
// Init sequence, address & value. // Init sequence, address & value.
const PROGMEM uint8_t pat9125_init_seq2[] = { const PROGMEM uint8_t pat9125_init_seq2[] = {
// Magic sequence to enforce full frame rate of the sensor. // Magic sequence to enforce full frame rate of the sensor.
0x06, 0x028, 0x06, 0x028,
0x33, 0x0d0, 0x33, 0x0d0,
0x36, 0x0c2, 0x36, 0x0c2,
0x3e, 0x001, 0x3e, 0x001,
0x3f, 0x015, 0x3f, 0x015,
0x41, 0x032, 0x41, 0x032,
0x42, 0x03b, 0x42, 0x03b,
0x43, 0x0f2, 0x43, 0x0f2,
0x44, 0x03b, 0x44, 0x03b,
0x45, 0x0f2, 0x45, 0x0f2,
0x46, 0x022, 0x46, 0x022,
0x47, 0x03b, 0x47, 0x03b,
0x48, 0x0f2, 0x48, 0x0f2,
0x49, 0x03b, 0x49, 0x03b,
0x4a, 0x0f0, 0x4a, 0x0f0,
0x58, 0x098, 0x58, 0x098,
0x59, 0x00c, 0x59, 0x00c,
0x5a, 0x008, 0x5a, 0x008,
0x5b, 0x00c, 0x5b, 0x00c,
0x5c, 0x008, 0x5c, 0x008,
0x61, 0x010, 0x61, 0x010,
0x67, 0x09b, 0x67, 0x09b,
0x6e, 0x022, 0x6e, 0x022,
0x71, 0x007, 0x71, 0x007,
0x72, 0x008, 0x72, 0x008,
// stopper // stopper
0x0ff 0x0ff
}; };
@ -108,176 +108,176 @@ extern FILE _uartout;
uint8_t pat9125_init(void) uint8_t pat9125_init(void)
{ {
#ifdef PAT9125_SWSPI #ifdef PAT9125_SWSPI
swspi_init(); swspi_init();
#endif //PAT9125_SWSPI #endif //PAT9125_SWSPI
#ifdef PAT9125_SWI2C #ifdef PAT9125_SWI2C
swi2c_init(); swi2c_init();
#endif //PAT9125_SWI2C #endif //PAT9125_SWI2C
// Verify that the sensor responds with its correct product ID. // Verify that the sensor responds with its correct product ID.
pat9125_PID1 = pat9125_rd_reg(PAT9125_PID1); pat9125_PID1 = pat9125_rd_reg(PAT9125_PID1);
pat9125_PID2 = pat9125_rd_reg(PAT9125_PID2); pat9125_PID2 = pat9125_rd_reg(PAT9125_PID2);
if ((pat9125_PID1 != 0x31) || (pat9125_PID2 != 0x91)) if ((pat9125_PID1 != 0x31) || (pat9125_PID2 != 0x91))
{ {
pat9125_PID1 = pat9125_rd_reg(PAT9125_PID1); pat9125_PID1 = pat9125_rd_reg(PAT9125_PID1);
pat9125_PID2 = pat9125_rd_reg(PAT9125_PID2); pat9125_PID2 = pat9125_rd_reg(PAT9125_PID2);
if ((pat9125_PID1 != 0x31) || (pat9125_PID2 != 0x91)) if ((pat9125_PID1 != 0x31) || (pat9125_PID2 != 0x91))
return 0; return 0;
} }
#ifdef PAT9125_NEW_INIT #ifdef PAT9125_NEW_INIT
// Switch to bank0, not allowed to perform OTS_RegWriteRead. // Switch to bank0, not allowed to perform OTS_RegWriteRead.
pat9125_wr_reg(PAT9125_BANK_SELECTION, 0); pat9125_wr_reg(PAT9125_BANK_SELECTION, 0);
// Software reset (i.e. set bit7 to 1). It will reset to 0 automatically. // Software reset (i.e. set bit7 to 1). It will reset to 0 automatically.
// After the reset, OTS_RegWriteRead is not allowed. // After the reset, OTS_RegWriteRead is not allowed.
pat9125_wr_reg(PAT9125_CONFIG, 0x97); pat9125_wr_reg(PAT9125_CONFIG, 0x97);
// Wait until the sensor reboots. // Wait until the sensor reboots.
// Delay 1ms. // Delay 1ms.
_delay_us(1000); _delay_us(1000);
{ {
const uint8_t *ptr = pat9125_init_seq1; const uint8_t *ptr = pat9125_init_seq1;
for (;;) { for (;;) {
const uint8_t addr = pgm_read_byte_near(ptr ++); const uint8_t addr = pgm_read_byte_near(ptr ++);
if (addr == 0x0ff) if (addr == 0x0ff)
break; break;
if (! pat9125_wr_reg_verify(addr, pgm_read_byte_near(ptr ++))) if (! pat9125_wr_reg_verify(addr, pgm_read_byte_near(ptr ++)))
// Verification of the register write failed. // Verification of the register write failed.
return 0; return 0;
} }
} }
// Delay 10ms. // Delay 10ms.
_delay_ms(10); _delay_ms(10);
// Switch to bank1, not allowed to perform OTS_RegWrite. // Switch to bank1, not allowed to perform OTS_RegWrite.
pat9125_wr_reg(PAT9125_BANK_SELECTION, 0x01); pat9125_wr_reg(PAT9125_BANK_SELECTION, 0x01);
{ {
const uint8_t *ptr = pat9125_init_seq2; const uint8_t *ptr = pat9125_init_seq2;
for (;;) { for (;;) {
const uint8_t addr = pgm_read_byte_near(ptr ++); const uint8_t addr = pgm_read_byte_near(ptr ++);
if (addr == 0x0ff) if (addr == 0x0ff)
break; break;
if (! pat9125_wr_reg_verify(addr, pgm_read_byte_near(ptr ++))) if (! pat9125_wr_reg_verify(addr, pgm_read_byte_near(ptr ++)))
// Verification of the register write failed. // Verification of the register write failed.
return 0; return 0;
} }
} }
// Switch to bank0, not allowed to perform OTS_RegWriteRead. // Switch to bank0, not allowed to perform OTS_RegWriteRead.
pat9125_wr_reg(PAT9125_BANK_SELECTION, 0x00); pat9125_wr_reg(PAT9125_BANK_SELECTION, 0x00);
// Enable write protect. // Enable write protect.
pat9125_wr_reg(PAT9125_WP, 0x00); pat9125_wr_reg(PAT9125_WP, 0x00);
pat9125_PID1 = pat9125_rd_reg(PAT9125_PID1); pat9125_PID1 = pat9125_rd_reg(PAT9125_PID1);
pat9125_PID2 = pat9125_rd_reg(PAT9125_PID2); pat9125_PID2 = pat9125_rd_reg(PAT9125_PID2);
#endif //PAT9125_NEW_INIT #endif //PAT9125_NEW_INIT
pat9125_wr_reg(PAT9125_RES_X, PAT9125_XRES); pat9125_wr_reg(PAT9125_RES_X, PAT9125_XRES);
pat9125_wr_reg(PAT9125_RES_Y, PAT9125_YRES); pat9125_wr_reg(PAT9125_RES_Y, PAT9125_YRES);
fprintf_P(uartout, PSTR("PAT9125_RES_X=%hhu\n"), pat9125_rd_reg(PAT9125_RES_X)); fprintf_P(uartout, PSTR("PAT9125_RES_X=%hhu\n"), pat9125_rd_reg(PAT9125_RES_X));
fprintf_P(uartout, PSTR("PAT9125_RES_Y=%hhu\n"), pat9125_rd_reg(PAT9125_RES_Y)); fprintf_P(uartout, PSTR("PAT9125_RES_Y=%hhu\n"), pat9125_rd_reg(PAT9125_RES_Y));
return 1; return 1;
} }
uint8_t pat9125_update(void) uint8_t pat9125_update(void)
{ {
if ((pat9125_PID1 == 0x31) && (pat9125_PID2 == 0x91)) if ((pat9125_PID1 == 0x31) && (pat9125_PID2 == 0x91))
{ {
uint8_t ucMotion = pat9125_rd_reg(PAT9125_MOTION); uint8_t ucMotion = pat9125_rd_reg(PAT9125_MOTION);
pat9125_b = pat9125_rd_reg(PAT9125_FRAME); pat9125_b = pat9125_rd_reg(PAT9125_FRAME);
pat9125_s = pat9125_rd_reg(PAT9125_SHUTTER); pat9125_s = pat9125_rd_reg(PAT9125_SHUTTER);
if (pat9125_PID1 == 0xff) return 0; if (pat9125_PID1 == 0xff) return 0;
if (ucMotion & 0x80) if (ucMotion & 0x80)
{ {
uint8_t ucXL = pat9125_rd_reg(PAT9125_DELTA_XL); uint8_t ucXL = pat9125_rd_reg(PAT9125_DELTA_XL);
uint8_t ucYL = pat9125_rd_reg(PAT9125_DELTA_YL); uint8_t ucYL = pat9125_rd_reg(PAT9125_DELTA_YL);
uint8_t ucXYH = pat9125_rd_reg(PAT9125_DELTA_XYH); uint8_t ucXYH = pat9125_rd_reg(PAT9125_DELTA_XYH);
if (pat9125_PID1 == 0xff) return 0; if (pat9125_PID1 == 0xff) return 0;
int16_t iDX = ucXL | ((ucXYH << 4) & 0xf00); int16_t iDX = ucXL | ((ucXYH << 4) & 0xf00);
int16_t iDY = ucYL | ((ucXYH << 8) & 0xf00); int16_t iDY = ucYL | ((ucXYH << 8) & 0xf00);
if (iDX & 0x800) iDX -= 4096; if (iDX & 0x800) iDX -= 4096;
if (iDY & 0x800) iDY -= 4096; if (iDY & 0x800) iDY -= 4096;
pat9125_x += iDX; pat9125_x += iDX;
pat9125_y -= iDY; //negative number, because direction switching does not work pat9125_y -= iDY; //negative number, because direction switching does not work
} }
return 1; return 1;
} }
return 0; return 0;
} }
uint8_t pat9125_update_y(void) uint8_t pat9125_update_y(void)
{ {
if ((pat9125_PID1 == 0x31) && (pat9125_PID2 == 0x91)) if ((pat9125_PID1 == 0x31) && (pat9125_PID2 == 0x91))
{ {
uint8_t ucMotion = pat9125_rd_reg(PAT9125_MOTION); uint8_t ucMotion = pat9125_rd_reg(PAT9125_MOTION);
if (pat9125_PID1 == 0xff) return 0; if (pat9125_PID1 == 0xff) return 0;
if (ucMotion & 0x80) if (ucMotion & 0x80)
{ {
uint8_t ucYL = pat9125_rd_reg(PAT9125_DELTA_YL); uint8_t ucYL = pat9125_rd_reg(PAT9125_DELTA_YL);
uint8_t ucXYH = pat9125_rd_reg(PAT9125_DELTA_XYH); uint8_t ucXYH = pat9125_rd_reg(PAT9125_DELTA_XYH);
if (pat9125_PID1 == 0xff) return 0; if (pat9125_PID1 == 0xff) return 0;
int16_t iDY = ucYL | ((ucXYH << 8) & 0xf00); int16_t iDY = ucYL | ((ucXYH << 8) & 0xf00);
if (iDY & 0x800) iDY -= 4096; if (iDY & 0x800) iDY -= 4096;
pat9125_y -= iDY; //negative number, because direction switching does not work pat9125_y -= iDY; //negative number, because direction switching does not work
} }
return 1; return 1;
} }
return 0; return 0;
} }
uint8_t pat9125_update_y2(void) uint8_t pat9125_update_y2(void)
{ {
if ((pat9125_PID1 == 0x31) && (pat9125_PID2 == 0x91)) if ((pat9125_PID1 == 0x31) && (pat9125_PID2 == 0x91))
{ {
uint8_t ucMotion = pat9125_rd_reg(PAT9125_MOTION); uint8_t ucMotion = pat9125_rd_reg(PAT9125_MOTION);
if (pat9125_PID1 == 0xff) return 0; //NOACK error if (pat9125_PID1 == 0xff) return 0; //NOACK error
if (ucMotion & 0x80) if (ucMotion & 0x80)
{ {
int8_t dy = pat9125_rd_reg(PAT9125_DELTA_YL); int8_t dy = pat9125_rd_reg(PAT9125_DELTA_YL);
if (pat9125_PID1 == 0xff) return 0; //NOACK error if (pat9125_PID1 == 0xff) return 0; //NOACK error
pat9125_y -= dy; //negative number, because direction switching does not work pat9125_y -= dy; //negative number, because direction switching does not work
} }
return 1; return 1;
} }
return 0; return 0;
} }
uint8_t pat9125_rd_reg(uint8_t addr) uint8_t pat9125_rd_reg(uint8_t addr)
{ {
uint8_t data = 0; uint8_t data = 0;
#ifdef PAT9125_SWSPI #ifdef PAT9125_SWSPI
swspi_start(); swspi_start();
swspi_tx(addr & 0x7f); swspi_tx(addr & 0x7f);
data = swspi_rx(); data = swspi_rx();
swspi_stop(); swspi_stop();
#endif //PAT9125_SWSPI #endif //PAT9125_SWSPI
#ifdef PAT9125_SWI2C #ifdef PAT9125_SWI2C
if (!swi2c_readByte_A8(PAT9125_I2C_ADDR, addr, &data)) //NO ACK error if (!swi2c_readByte_A8(PAT9125_I2C_ADDR, addr, &data)) //NO ACK error
{ {
pat9125_PID1 = 0xff; pat9125_PID1 = 0xff;
pat9125_PID2 = 0xff; pat9125_PID2 = 0xff;
return 0; return 0;
} }
#endif //PAT9125_SWI2C #endif //PAT9125_SWI2C
return data; return data;
} }
void pat9125_wr_reg(uint8_t addr, uint8_t data) void pat9125_wr_reg(uint8_t addr, uint8_t data)
{ {
#ifdef PAT9125_SWSPI #ifdef PAT9125_SWSPI
swspi_start(); swspi_start();
swspi_tx(addr | 0x80); swspi_tx(addr | 0x80);
swspi_tx(data); swspi_tx(data);
swspi_stop(); swspi_stop();
#endif //PAT9125_SWSPI #endif //PAT9125_SWSPI
#ifdef PAT9125_SWI2C #ifdef PAT9125_SWI2C
if (!swi2c_writeByte_A8(PAT9125_I2C_ADDR, addr, &data)) //NO ACK error if (!swi2c_writeByte_A8(PAT9125_I2C_ADDR, addr, &data)) //NO ACK error
{ {
pat9125_PID1 = 0xff; pat9125_PID1 = 0xff;
pat9125_PID2 = 0xff; pat9125_PID2 = 0xff;
return; return;
} }
#endif //PAT9125_SWI2C #endif //PAT9125_SWI2C
} }
uint8_t pat9125_wr_reg_verify(uint8_t addr, uint8_t data) uint8_t pat9125_wr_reg_verify(uint8_t addr, uint8_t data)
{ {
pat9125_wr_reg(addr, data); pat9125_wr_reg(addr, data);
return pat9125_rd_reg(addr) == data; return pat9125_rd_reg(addr) == data;
} }

View File

@ -5,9 +5,9 @@
void rbuf_ini(uint8_t* ptr, uint8_t l) void rbuf_ini(uint8_t* ptr, uint8_t l)
{ {
ptr[0] = l; ptr[0] = l;
ptr[1] = 0; ptr[1] = 0;
ptr[2] = 0; ptr[2] = 0;
} }
//lock/unlock macros //lock/unlock macros
@ -20,17 +20,17 @@ void rbuf_ini(uint8_t* ptr, uint8_t l)
int rbuf_put(uint8_t* ptr, uint8_t b) int rbuf_put(uint8_t* ptr, uint8_t b)
{ {
//#ifdef _NO_ASM //#ifdef _NO_ASM
_lock(); //lock _lock(); //lock
uint8_t buf_w = ptr[1]; //get write index uint8_t buf_w = ptr[1]; //get write index
uint8_t buf_r = ptr[2]; //get read index uint8_t buf_r = ptr[2]; //get read index
_unlock(); //unlock _unlock(); //unlock
ptr[4 + buf_w] = b; //store byte to buffer ptr[4 + buf_w] = b; //store byte to buffer
buf_w++; //incerment write index buf_w++; //incerment write index
uint8_t buf_l = ptr[0]; //get length uint8_t buf_l = ptr[0]; //get length
if (buf_w >= buf_l) buf_w = 0; //rotate write index if (buf_w >= buf_l) buf_w = 0; //rotate write index
if (buf_w == buf_r) return -1; //return -1 to signal buffer full if (buf_w == buf_r) return -1; //return -1 to signal buffer full
ptr[1] = buf_w; //store write index ptr[1] = buf_w; //store write index
return 0; //return 0 to signal success return 0; //return 0 to signal success
//#else //_NO_ASM //#else //_NO_ASM
// TODO - optimized assembler version // TODO - optimized assembler version
// asm("movw r26, r24"); // asm("movw r26, r24");
@ -47,17 +47,17 @@ int rbuf_put(uint8_t* ptr, uint8_t b)
int rbuf_get(uint8_t* ptr) int rbuf_get(uint8_t* ptr)
{ {
//#ifdef _NO_ASM //#ifdef _NO_ASM
_lock(); //lock _lock(); //lock
uint8_t buf_w = ptr[1]; //get write index uint8_t buf_w = ptr[1]; //get write index
uint8_t buf_r = ptr[2]; //get read index uint8_t buf_r = ptr[2]; //get read index
_unlock(); //unlock _unlock(); //unlock
if (buf_r == buf_w) return -1; //return -1 to signal buffer empty if (buf_r == buf_w) return -1; //return -1 to signal buffer empty
int ret = ptr[4 + buf_r]; //get byte from buffer int ret = ptr[4 + buf_r]; //get byte from buffer
buf_r++; //increment read index buf_r++; //increment read index
uint8_t buf_l = ptr[0]; //get length uint8_t buf_l = ptr[0]; //get length
if (buf_r >= buf_l) buf_r = 0; //rotate read index if (buf_r >= buf_l) buf_r = 0; //rotate read index
ptr[2] = buf_r; //store read index ptr[2] = buf_r; //store read index
return ret; //return byte (0-255) return ret; //return byte (0-255)
// return 0; //return 0 to signal success // return 0; //return 0 to signal success
//#else //_NO_ASM //#else //_NO_ASM
// TODO - optimized assembler version // TODO - optimized assembler version

View File

@ -47,148 +47,180 @@ uint16_t sm4_cpu_time = 0;
uint8_t sm4_get_dir(uint8_t axis) uint8_t sm4_get_dir(uint8_t axis)
{ {
switch (axis) switch (axis)
{ {
#if ((MOTHERBOARD == BOARD_RAMBO_MINI_1_0) || (MOTHERBOARD == BOARD_RAMBO_MINI_1_3)) #if ((MOTHERBOARD == BOARD_RAMBO_MINI_1_0) || (MOTHERBOARD == BOARD_RAMBO_MINI_1_3))
case 0: return (PORTL & 2)?0:1; case 0:
case 1: return (PORTL & 1)?0:1; return (PORTL & 2)?0:1;
case 2: return (PORTL & 4)?0:1; case 1:
case 3: return (PORTL & 64)?1:0; return (PORTL & 1)?0:1;
case 2:
return (PORTL & 4)?0:1;
case 3:
return (PORTL & 64)?1:0;
#elif ((MOTHERBOARD == BOARD_EINSY_1_0a)) #elif ((MOTHERBOARD == BOARD_EINSY_1_0a))
case 0: return (PORTL & 1)?1:0; case 0:
case 1: return (PORTL & 2)?0:1; return (PORTL & 1)?1:0;
case 2: return (PORTL & 4)?1:0; case 1:
case 3: return (PORTL & 64)?0:1; return (PORTL & 2)?0:1;
case 2:
return (PORTL & 4)?1:0;
case 3:
return (PORTL & 64)?0:1;
#endif #endif
} }
return 0; return 0;
} }
void sm4_set_dir(uint8_t axis, uint8_t dir) void sm4_set_dir(uint8_t axis, uint8_t dir)
{ {
switch (axis) switch (axis)
{ {
#if ((MOTHERBOARD == BOARD_RAMBO_MINI_1_0) || (MOTHERBOARD == BOARD_RAMBO_MINI_1_3)) #if ((MOTHERBOARD == BOARD_RAMBO_MINI_1_0) || (MOTHERBOARD == BOARD_RAMBO_MINI_1_3))
case 0: if (!dir) PORTL |= 2; else PORTL &= ~2; break; case 0:
case 1: if (!dir) PORTL |= 1; else PORTL &= ~1; break; if (!dir) PORTL |= 2;
case 2: if (!dir) PORTL |= 4; else PORTL &= ~4; break; else PORTL &= ~2;
case 3: if (dir) PORTL |= 64; else PORTL &= ~64; break; break;
case 1:
if (!dir) PORTL |= 1;
else PORTL &= ~1;
break;
case 2:
if (!dir) PORTL |= 4;
else PORTL &= ~4;
break;
case 3:
if (dir) PORTL |= 64;
else PORTL &= ~64;
break;
#elif ((MOTHERBOARD == BOARD_EINSY_1_0a)) #elif ((MOTHERBOARD == BOARD_EINSY_1_0a))
case 0: if (dir) PORTL |= 1; else PORTL &= ~1; break; case 0:
case 1: if (!dir) PORTL |= 2; else PORTL &= ~2; break; if (dir) PORTL |= 1;
case 2: if (dir) PORTL |= 4; else PORTL &= ~4; break; else PORTL &= ~1;
case 3: if (!dir) PORTL |= 64; else PORTL &= ~64; break; break;
case 1:
if (!dir) PORTL |= 2;
else PORTL &= ~2;
break;
case 2:
if (dir) PORTL |= 4;
else PORTL &= ~4;
break;
case 3:
if (!dir) PORTL |= 64;
else PORTL &= ~64;
break;
#endif #endif
} }
asm("nop"); asm("nop");
} }
uint8_t sm4_get_dir_bits(void) uint8_t sm4_get_dir_bits(void)
{ {
register uint8_t dir_bits = 0; register uint8_t dir_bits = 0;
register uint8_t portL = PORTL; register uint8_t portL = PORTL;
//TODO -optimize in asm //TODO -optimize in asm
#if ((MOTHERBOARD == BOARD_RAMBO_MINI_1_0) || (MOTHERBOARD == BOARD_RAMBO_MINI_1_3)) #if ((MOTHERBOARD == BOARD_RAMBO_MINI_1_0) || (MOTHERBOARD == BOARD_RAMBO_MINI_1_3))
if (portL & 2) dir_bits |= 1; if (portL & 2) dir_bits |= 1;
if (portL & 1) dir_bits |= 2; if (portL & 1) dir_bits |= 2;
if (portL & 4) dir_bits |= 4; if (portL & 4) dir_bits |= 4;
if (portL & 64) dir_bits |= 8; if (portL & 64) dir_bits |= 8;
dir_bits ^= 0x07; //invert XYZ, do not invert E dir_bits ^= 0x07; //invert XYZ, do not invert E
#elif ((MOTHERBOARD == BOARD_EINSY_1_0a)) #elif ((MOTHERBOARD == BOARD_EINSY_1_0a))
if (portL & 1) dir_bits |= 1; if (portL & 1) dir_bits |= 1;
if (portL & 2) dir_bits |= 2; if (portL & 2) dir_bits |= 2;
if (portL & 4) dir_bits |= 4; if (portL & 4) dir_bits |= 4;
if (portL & 64) dir_bits |= 8; if (portL & 64) dir_bits |= 8;
dir_bits ^= 0x0a; //invert YE, do not invert XZ dir_bits ^= 0x0a; //invert YE, do not invert XZ
#endif #endif
return dir_bits; return dir_bits;
} }
void sm4_set_dir_bits(uint8_t dir_bits) void sm4_set_dir_bits(uint8_t dir_bits)
{ {
register uint8_t portL = PORTL; register uint8_t portL = PORTL;
portL &= 0xb8; //set direction bits to zero portL &= 0xb8; //set direction bits to zero
//TODO -optimize in asm //TODO -optimize in asm
#if ((MOTHERBOARD == BOARD_RAMBO_MINI_1_0) || (MOTHERBOARD == BOARD_RAMBO_MINI_1_3)) #if ((MOTHERBOARD == BOARD_RAMBO_MINI_1_0) || (MOTHERBOARD == BOARD_RAMBO_MINI_1_3))
dir_bits ^= 0x07; //invert XYZ, do not invert E dir_bits ^= 0x07; //invert XYZ, do not invert E
if (dir_bits & 1) portL |= 2; //set X direction bit if (dir_bits & 1) portL |= 2; //set X direction bit
if (dir_bits & 2) portL |= 1; //set Y direction bit if (dir_bits & 2) portL |= 1; //set Y direction bit
if (dir_bits & 4) portL |= 4; //set Z direction bit if (dir_bits & 4) portL |= 4; //set Z direction bit
if (dir_bits & 8) portL |= 64; //set E direction bit if (dir_bits & 8) portL |= 64; //set E direction bit
#elif ((MOTHERBOARD == BOARD_EINSY_1_0a)) #elif ((MOTHERBOARD == BOARD_EINSY_1_0a))
dir_bits ^= 0x0a; //invert YE, do not invert XZ dir_bits ^= 0x0a; //invert YE, do not invert XZ
if (dir_bits & 1) portL |= 1; //set X direction bit if (dir_bits & 1) portL |= 1; //set X direction bit
if (dir_bits & 2) portL |= 2; //set Y direction bit if (dir_bits & 2) portL |= 2; //set Y direction bit
if (dir_bits & 4) portL |= 4; //set Z direction bit if (dir_bits & 4) portL |= 4; //set Z direction bit
if (dir_bits & 8) portL |= 64; //set E direction bit if (dir_bits & 8) portL |= 64; //set E direction bit
#endif #endif
PORTL = portL; PORTL = portL;
asm("nop"); asm("nop");
} }
void sm4_do_step(uint8_t axes_mask) void sm4_do_step(uint8_t axes_mask)
{ {
#if ((MOTHERBOARD == BOARD_RAMBO_MINI_1_0) || (MOTHERBOARD == BOARD_RAMBO_MINI_1_3) || (MOTHERBOARD == BOARD_EINSY_1_0a)) #if ((MOTHERBOARD == BOARD_RAMBO_MINI_1_0) || (MOTHERBOARD == BOARD_RAMBO_MINI_1_3) || (MOTHERBOARD == BOARD_EINSY_1_0a))
register uint8_t portC = PORTC & 0xf0; register uint8_t portC = PORTC & 0xf0;
PORTC = portC | (axes_mask & 0x0f); //set step signals by mask PORTC = portC | (axes_mask & 0x0f); //set step signals by mask
asm("nop"); asm("nop");
PORTC = portC; //set step signals to zero PORTC = portC; //set step signals to zero
asm("nop"); asm("nop");
#endif //((MOTHERBOARD == BOARD_RAMBO_MINI_1_0) || (MOTHERBOARD == BOARD_RAMBO_MINI_1_3) || (MOTHERBOARD == BOARD_EINSY_1_0a)) #endif //((MOTHERBOARD == BOARD_RAMBO_MINI_1_0) || (MOTHERBOARD == BOARD_RAMBO_MINI_1_3) || (MOTHERBOARD == BOARD_EINSY_1_0a))
} }
uint16_t sm4_line_xyze_ui(uint16_t dx, uint16_t dy, uint16_t dz, uint16_t de) uint16_t sm4_line_xyze_ui(uint16_t dx, uint16_t dy, uint16_t dz, uint16_t de)
{ {
uint16_t dd = (uint16_t)(sqrt((float)(((uint32_t)dx)*dx + ((uint32_t)dy*dy) + ((uint32_t)dz*dz) + ((uint32_t)de*de))) + 0.5); uint16_t dd = (uint16_t)(sqrt((float)(((uint32_t)dx)*dx + ((uint32_t)dy*dy) + ((uint32_t)dz*dz) + ((uint32_t)de*de))) + 0.5);
uint16_t nd = dd; uint16_t nd = dd;
uint16_t cx = dd; uint16_t cx = dd;
uint16_t cy = dd; uint16_t cy = dd;
uint16_t cz = dd; uint16_t cz = dd;
uint16_t ce = dd; uint16_t ce = dd;
uint16_t x = 0; uint16_t x = 0;
uint16_t y = 0; uint16_t y = 0;
uint16_t z = 0; uint16_t z = 0;
uint16_t e = 0; uint16_t e = 0;
while (nd) while (nd)
{ {
if (sm4_stop_cb && (*sm4_stop_cb)()) break; if (sm4_stop_cb && (*sm4_stop_cb)()) break;
uint8_t sm = 0; //step mask uint8_t sm = 0; //step mask
if (cx <= dx) if (cx <= dx)
{ {
sm |= 1; sm |= 1;
cx += dd; cx += dd;
x++; x++;
} }
if (cy <= dy) if (cy <= dy)
{ {
sm |= 2; sm |= 2;
cy += dd; cy += dd;
y++; y++;
} }
if (cz <= dz) if (cz <= dz)
{ {
sm |= 4; sm |= 4;
cz += dd; cz += dd;
z++; z++;
} }
if (ce <= de) if (ce <= de)
{ {
sm |= 4; sm |= 4;
ce += dd; ce += dd;
e++; e++;
} }
cx -= dx; cx -= dx;
cy -= dy; cy -= dy;
cz -= dz; cz -= dz;
ce -= de; ce -= de;
sm4_do_step(sm); sm4_do_step(sm);
uint16_t delay = SM4_DEFDELAY; uint16_t delay = SM4_DEFDELAY;
if (sm4_calc_delay_cb) delay = (*sm4_calc_delay_cb)(nd, dd); if (sm4_calc_delay_cb) delay = (*sm4_calc_delay_cb)(nd, dd);
if (delay) delayMicroseconds(delay); if (delay) delayMicroseconds(delay);
nd--; nd--;
} }
if (sm4_update_pos_cb) (*sm4_update_pos_cb)(x, y, z, e); if (sm4_update_pos_cb) (*sm4_update_pos_cb)(x, y, z, e);
return nd; return nd;
} }

View File

@ -16,136 +16,148 @@
void __delay(void) void __delay(void)
{ {
_delay_us(1.5); _delay_us(1.5);
} }
void swi2c_init(void) void swi2c_init(void)
{ {
PIN_OUT(SWI2C_SDA); PIN_OUT(SWI2C_SDA);
PIN_OUT(SWI2C_SCL); PIN_OUT(SWI2C_SCL);
PIN_SET(SWI2C_SDA); PIN_SET(SWI2C_SDA);
PIN_SET(SWI2C_SCL); PIN_SET(SWI2C_SCL);
uint8_t i; for (i = 0; i < 100; i++) uint8_t i;
__delay(); for (i = 0; i < 100; i++)
__delay();
} }
void swi2c_start(void) void swi2c_start(void)
{ {
PIN_CLR(SWI2C_SDA); PIN_CLR(SWI2C_SDA);
__delay(); __delay();
PIN_CLR(SWI2C_SCL); PIN_CLR(SWI2C_SCL);
__delay(); __delay();
} }
void swi2c_stop(void) void swi2c_stop(void)
{ {
PIN_SET(SWI2C_SCL); PIN_SET(SWI2C_SCL);
__delay(); __delay();
PIN_SET(SWI2C_SDA); PIN_SET(SWI2C_SDA);
__delay(); __delay();
} }
void swi2c_ack(void) void swi2c_ack(void)
{ {
PIN_CLR(SWI2C_SDA); PIN_CLR(SWI2C_SDA);
__delay(); __delay();
PIN_SET(SWI2C_SCL); PIN_SET(SWI2C_SCL);
__delay(); __delay();
PIN_CLR(SWI2C_SCL); PIN_CLR(SWI2C_SCL);
__delay(); __delay();
} }
uint8_t swi2c_wait_ack() uint8_t swi2c_wait_ack()
{ {
PIN_INP(SWI2C_SDA); PIN_INP(SWI2C_SDA);
__delay(); __delay();
// PIN_SET(SWI2C_SDA); // PIN_SET(SWI2C_SDA);
__delay(); __delay();
PIN_SET(SWI2C_SCL); PIN_SET(SWI2C_SCL);
// __delay(); // __delay();
uint8_t ack = 0; uint8_t ack = 0;
uint16_t ackto = SWI2C_TMO; uint16_t ackto = SWI2C_TMO;
while (!(ack = (PIN_GET(SWI2C_SDA)?0:1)) && ackto--) __delay(); while (!(ack = (PIN_GET(SWI2C_SDA)?0:1)) && ackto--) __delay();
PIN_CLR(SWI2C_SCL); PIN_CLR(SWI2C_SCL);
__delay(); __delay();
PIN_OUT(SWI2C_SDA); PIN_OUT(SWI2C_SDA);
__delay(); __delay();
PIN_CLR(SWI2C_SDA); PIN_CLR(SWI2C_SDA);
__delay(); __delay();
return ack; return ack;
} }
uint8_t swi2c_read(void) uint8_t swi2c_read(void)
{ {
PIN_SET(SWI2C_SDA); PIN_SET(SWI2C_SDA);
__delay(); __delay();
PIN_INP(SWI2C_SDA); PIN_INP(SWI2C_SDA);
uint8_t data = 0; uint8_t data = 0;
int8_t bit; for (bit = 7; bit >= 0; bit--) int8_t bit;
{ for (bit = 7; bit >= 0; bit--)
PIN_SET(SWI2C_SCL); {
__delay(); PIN_SET(SWI2C_SCL);
data |= (PIN_GET(SWI2C_SDA)?1:0) << bit; __delay();
PIN_CLR(SWI2C_SCL); data |= (PIN_GET(SWI2C_SDA)?1:0) << bit;
__delay(); PIN_CLR(SWI2C_SCL);
} __delay();
PIN_OUT(SWI2C_SDA); }
return data; PIN_OUT(SWI2C_SDA);
return data;
} }
void swi2c_write(uint8_t data) void swi2c_write(uint8_t data)
{ {
int8_t bit; for (bit = 7; bit >= 0; bit--) int8_t bit;
{ for (bit = 7; bit >= 0; bit--)
if (data & (1 << bit)) PIN_SET(SWI2C_SDA); {
else PIN_CLR(SWI2C_SDA); if (data & (1 << bit)) PIN_SET(SWI2C_SDA);
__delay(); else PIN_CLR(SWI2C_SDA);
PIN_SET(SWI2C_SCL); __delay();
__delay(); PIN_SET(SWI2C_SCL);
PIN_CLR(SWI2C_SCL); __delay();
__delay(); PIN_CLR(SWI2C_SCL);
} __delay();
}
} }
uint8_t swi2c_check(uint8_t dev_addr) uint8_t swi2c_check(uint8_t dev_addr)
{ {
swi2c_start(); swi2c_start();
swi2c_write((dev_addr & SWI2C_DMSK) << SWI2C_ASHF); swi2c_write((dev_addr & SWI2C_DMSK) << SWI2C_ASHF);
if (!swi2c_wait_ack()) { swi2c_stop(); return 0; } if (!swi2c_wait_ack()) {
swi2c_stop(); swi2c_stop();
return 1; return 0;
}
swi2c_stop();
return 1;
} }
#ifdef SWI2C_A8 //8bit address #ifdef SWI2C_A8 //8bit address
uint8_t swi2c_readByte_A8(uint8_t dev_addr, uint8_t addr, uint8_t* pbyte) uint8_t swi2c_readByte_A8(uint8_t dev_addr, uint8_t addr, uint8_t* pbyte)
{ {
swi2c_start(); swi2c_start();
swi2c_write(SWI2C_WMSK | ((dev_addr & SWI2C_DMSK) << SWI2C_ASHF)); swi2c_write(SWI2C_WMSK | ((dev_addr & SWI2C_DMSK) << SWI2C_ASHF));
if (!swi2c_wait_ack()) { swi2c_stop(); return 0; } if (!swi2c_wait_ack()) {
swi2c_write(addr & 0xff); swi2c_stop();
if (!swi2c_wait_ack()) return 0; return 0;
swi2c_stop(); }
swi2c_start(); swi2c_write(addr & 0xff);
swi2c_write(SWI2C_RMSK | ((dev_addr & SWI2C_DMSK) << SWI2C_ASHF)); if (!swi2c_wait_ack()) return 0;
if (!swi2c_wait_ack()) return 0; swi2c_stop();
uint8_t byte = swi2c_read(); swi2c_start();
swi2c_stop(); swi2c_write(SWI2C_RMSK | ((dev_addr & SWI2C_DMSK) << SWI2C_ASHF));
if (pbyte) *pbyte = byte; if (!swi2c_wait_ack()) return 0;
return 1; uint8_t byte = swi2c_read();
swi2c_stop();
if (pbyte) *pbyte = byte;
return 1;
} }
uint8_t swi2c_writeByte_A8(uint8_t dev_addr, uint8_t addr, uint8_t* pbyte) uint8_t swi2c_writeByte_A8(uint8_t dev_addr, uint8_t addr, uint8_t* pbyte)
{ {
swi2c_start(); swi2c_start();
swi2c_write(SWI2C_WMSK | ((dev_addr & SWI2C_DMSK) << SWI2C_ASHF)); swi2c_write(SWI2C_WMSK | ((dev_addr & SWI2C_DMSK) << SWI2C_ASHF));
if (!swi2c_wait_ack()) { swi2c_stop(); return 0; } if (!swi2c_wait_ack()) {
swi2c_write(addr & 0xff); swi2c_stop();
if (!swi2c_wait_ack()) return 0; return 0;
swi2c_write(*pbyte); }
if (!swi2c_wait_ack()) return 0; swi2c_write(addr & 0xff);
swi2c_stop(); if (!swi2c_wait_ack()) return 0;
return 1; swi2c_write(*pbyte);
if (!swi2c_wait_ack()) return 0;
swi2c_stop();
return 1;
} }
#endif //SWI2C_A8 #endif //SWI2C_A8
@ -154,36 +166,42 @@ uint8_t swi2c_writeByte_A8(uint8_t dev_addr, uint8_t addr, uint8_t* pbyte)
uint8_t swi2c_readByte_A16(uint8_t dev_addr, unsigned short addr, uint8_t* pbyte) uint8_t swi2c_readByte_A16(uint8_t dev_addr, unsigned short addr, uint8_t* pbyte)
{ {
swi2c_start(); swi2c_start();
swi2c_write(SWI2C_WMSK | ((dev_addr & SWI2C_DMSK) << SWI2C_ASHF)); swi2c_write(SWI2C_WMSK | ((dev_addr & SWI2C_DMSK) << SWI2C_ASHF));
if (!swi2c_wait_ack()) { swi2c_stop(); return 0; } if (!swi2c_wait_ack()) {
swi2c_write(addr >> 8); swi2c_stop();
if (!swi2c_wait_ack()) return 0; return 0;
swi2c_write(addr & 0xff); }
if (!swi2c_wait_ack()) return 0; swi2c_write(addr >> 8);
swi2c_stop(); if (!swi2c_wait_ack()) return 0;
swi2c_start(); swi2c_write(addr & 0xff);
swi2c_write(SWI2C_RMSK | ((dev_addr & SWI2C_DMSK) << SWI2C_ASHF)); if (!swi2c_wait_ack()) return 0;
if (!swi2c_wait_ack()) return 0; swi2c_stop();
uint8_t byte = swi2c_read(); swi2c_start();
swi2c_stop(); swi2c_write(SWI2C_RMSK | ((dev_addr & SWI2C_DMSK) << SWI2C_ASHF));
if (pbyte) *pbyte = byte; if (!swi2c_wait_ack()) return 0;
return 1; uint8_t byte = swi2c_read();
swi2c_stop();
if (pbyte) *pbyte = byte;
return 1;
} }
uint8_t swi2c_writeByte_A16(uint8_t dev_addr, unsigned short addr, uint8_t* pbyte) uint8_t swi2c_writeByte_A16(uint8_t dev_addr, unsigned short addr, uint8_t* pbyte)
{ {
swi2c_start(); swi2c_start();
swi2c_write(SWI2C_WMSK | ((dev_addr & SWI2C_DMSK) << SWI2C_ASHF)); swi2c_write(SWI2C_WMSK | ((dev_addr & SWI2C_DMSK) << SWI2C_ASHF));
if (!swi2c_wait_ack()) { swi2c_stop(); return 0; } if (!swi2c_wait_ack()) {
swi2c_write(addr >> 8); swi2c_stop();
if (!swi2c_wait_ack()) return 0; return 0;
swi2c_write(addr & 0xff); }
if (!swi2c_wait_ack()) return 0; swi2c_write(addr >> 8);
swi2c_write(*pbyte); if (!swi2c_wait_ack()) return 0;
if (!swi2c_wait_ack()) return 0; swi2c_write(addr & 0xff);
swi2c_stop(); if (!swi2c_wait_ack()) return 0;
return 1; swi2c_write(*pbyte);
if (!swi2c_wait_ack()) return 0;
swi2c_stop();
return 1;
} }
#endif //SWI2C_A16 #endif //SWI2C_A16

View File

@ -18,67 +18,67 @@ FILE _uart2io = {0};
int uart2_putchar(char c, FILE *stream __attribute__((unused))) int uart2_putchar(char c, FILE *stream __attribute__((unused)))
{ {
while (!uart2_txready); while (!uart2_txready);
UDR2 = c; // transmit byte UDR2 = c; // transmit byte
// while (!uart2_txcomplete); // wait until byte sent // while (!uart2_txcomplete); // wait until byte sent
// UCSR2A |= (1 << TXC2); // delete TXCflag // UCSR2A |= (1 << TXC2); // delete TXCflag
return 0; return 0;
} }
int uart2_getchar(FILE *stream __attribute__((unused))) int uart2_getchar(FILE *stream __attribute__((unused)))
{ {
if (rbuf_empty(uart2_ibuf)) return -1; if (rbuf_empty(uart2_ibuf)) return -1;
return rbuf_get(uart2_ibuf); return rbuf_get(uart2_ibuf);
} }
//uart init (io + FILE stream) //uart init (io + FILE stream)
void uart2_init(void) void uart2_init(void)
{ {
DDRH &= ~0x01; DDRH &= ~0x01;
PORTH |= 0x01; PORTH |= 0x01;
rbuf_ini(uart2_ibuf, sizeof(uart2_ibuf) - 4); rbuf_ini(uart2_ibuf, sizeof(uart2_ibuf) - 4);
UCSR2A |= (1 << U2X2); // baudrate multiplier UCSR2A |= (1 << U2X2); // baudrate multiplier
UBRR2L = UART_BAUD_SELECT(UART2_BAUD, F_CPU); // select baudrate UBRR2L = UART_BAUD_SELECT(UART2_BAUD, F_CPU); // select baudrate
UCSR2B = (1 << RXEN2) | (1 << TXEN2); // enable receiver and transmitter UCSR2B = (1 << RXEN2) | (1 << TXEN2); // enable receiver and transmitter
UCSR2B |= (1 << RXCIE2); // enable rx interrupt UCSR2B |= (1 << RXCIE2); // enable rx interrupt
fdev_setup_stream(uart2io, uart2_putchar, uart2_getchar, _FDEV_SETUP_WRITE | _FDEV_SETUP_READ); //setup uart2 i/o stream fdev_setup_stream(uart2io, uart2_putchar, uart2_getchar, _FDEV_SETUP_WRITE | _FDEV_SETUP_READ); //setup uart2 i/o stream
} }
//returns 1 if chars in input buffer match to str //returns 1 if chars in input buffer match to str
//returns -1 if chars does not match and 0 for empty buffer //returns -1 if chars does not match and 0 for empty buffer
int8_t uart2_rx_str_P(const char* str) int8_t uart2_rx_str_P(const char* str)
{ {
uint8_t r = rbuf_r(uart2_ibuf); //get read index uint8_t r = rbuf_r(uart2_ibuf); //get read index
uint8_t w = rbuf_w(uart2_ibuf); //get write index uint8_t w = rbuf_w(uart2_ibuf); //get write index
// printf_P(PSTR("uart2_rx_str_P r=%d w=%d\n"), r, w); // printf_P(PSTR("uart2_rx_str_P r=%d w=%d\n"), r, w);
uint8_t e = rbuf_l(uart2_ibuf) - 1; //get end index uint8_t e = rbuf_l(uart2_ibuf) - 1; //get end index
uint8_t len = strlen_P(str); //get string length uint8_t len = strlen_P(str); //get string length
str += len; //last char will be compared first str += len; //last char will be compared first
// printf_P(PSTR(" len=%d\n"), len); // printf_P(PSTR(" len=%d\n"), len);
while (len--) //loop over all chars while (len--) //loop over all chars
{ {
if (w == r) return 0; //empty buffer - return 0 if (w == r) return 0; //empty buffer - return 0
if ((--w) == 255) w = e; //decrement index if ((--w) == 255) w = e; //decrement index
char c0 = pgm_read_byte(--str); //read char from str char c0 = pgm_read_byte(--str); //read char from str
char c1 = uart2_ibuf[4 + w]; //read char from input buffer char c1 = uart2_ibuf[4 + w]; //read char from input buffer
// printf_P(PSTR(" uart2_rx_str_P w=%d l=%d c0=%02x c1=%02x\n"), w, len, c0, c1); // printf_P(PSTR(" uart2_rx_str_P w=%d l=%d c0=%02x c1=%02x\n"), w, len, c0, c1);
if (c0 == c1) continue; //if match, continue with next char if (c0 == c1) continue; //if match, continue with next char
if ((c0 == '\r') && (c1 == '\n')) //match cr as lf if ((c0 == '\r') && (c1 == '\n')) //match cr as lf
continue; continue;
if ((c0 == '\n') && (c1 == '\r')) //match lf as cr if ((c0 == '\n') && (c1 == '\r')) //match lf as cr
continue; continue;
return -1; //no match - return -1 return -1; //no match - return -1
} }
return 1; //all characters match - return 1 return 1; //all characters match - return 1
} }
ISR(USART2_RX_vect) ISR(USART2_RX_vect)
{ {
//printf_P(PSTR("USART2_RX_vect \n") ); //printf_P(PSTR("USART2_RX_vect \n") );
if (rbuf_put(uart2_ibuf, UDR2) < 0) // put received byte to buffer if (rbuf_put(uart2_ibuf, UDR2) < 0) // put received byte to buffer
{ //rx buffer full { //rx buffer full
//uart2_rx_clr(); //for sure, clear input buffer //uart2_rx_clr(); //for sure, clear input buffer
printf_P(PSTR("USART2 rx Full!!!\n")); printf_P(PSTR("USART2 rx Full!!!\n"));
} }
} }

View File

@ -45,140 +45,140 @@ int w25x20cl_mfrid_devid(void);
int8_t w25x20cl_init(void) int8_t w25x20cl_init(void)
{ {
PIN_OUT(W25X20CL_PIN_CS); PIN_OUT(W25X20CL_PIN_CS);
_CS_HIGH(); _CS_HIGH();
W25X20CL_SPI_ENTER(); W25X20CL_SPI_ENTER();
if (!w25x20cl_mfrid_devid()) return 0; if (!w25x20cl_mfrid_devid()) return 0;
return 1; return 1;
} }
void w25x20cl_enable_wr(void) void w25x20cl_enable_wr(void)
{ {
_CS_LOW(); _CS_LOW();
_SPI_TX(_CMD_ENABLE_WR); // send command 0x06 _SPI_TX(_CMD_ENABLE_WR); // send command 0x06
_CS_HIGH(); _CS_HIGH();
} }
void w25x20cl_disable_wr(void) void w25x20cl_disable_wr(void)
{ {
_CS_LOW(); _CS_LOW();
_SPI_TX(_CMD_DISABLE_WR); // send command 0x04 _SPI_TX(_CMD_DISABLE_WR); // send command 0x04
_CS_HIGH(); _CS_HIGH();
} }
uint8_t w25x20cl_rd_status_reg(void) uint8_t w25x20cl_rd_status_reg(void)
{ {
_CS_LOW(); _CS_LOW();
_SPI_TX(_CMD_RD_STATUS_REG); // send command 0x90 _SPI_TX(_CMD_RD_STATUS_REG); // send command 0x90
uint8_t val = _SPI_RX(); // receive value uint8_t val = _SPI_RX(); // receive value
_CS_HIGH(); _CS_HIGH();
return val; return val;
} }
void w25x20cl_wr_status_reg(uint8_t val) void w25x20cl_wr_status_reg(uint8_t val)
{ {
_CS_LOW(); _CS_LOW();
_SPI_TX(_CMD_WR_STATUS_REG); // send command 0x90 _SPI_TX(_CMD_WR_STATUS_REG); // send command 0x90
_SPI_TX(val); // send value _SPI_TX(val); // send value
_CS_HIGH(); _CS_HIGH();
} }
void w25x20cl_rd_data(uint32_t addr, uint8_t* data, uint16_t cnt) void w25x20cl_rd_data(uint32_t addr, uint8_t* data, uint16_t cnt)
{ {
_CS_LOW(); _CS_LOW();
_SPI_TX(_CMD_RD_DATA); // send command 0x03 _SPI_TX(_CMD_RD_DATA); // send command 0x03
_SPI_TX(((uint8_t*)&addr)[2]); // send addr bits 16..23 _SPI_TX(((uint8_t*)&addr)[2]); // send addr bits 16..23
_SPI_TX(((uint8_t*)&addr)[1]); // send addr bits 8..15 _SPI_TX(((uint8_t*)&addr)[1]); // send addr bits 8..15
_SPI_TX(((uint8_t*)&addr)[0]); // send addr bits 0..7 _SPI_TX(((uint8_t*)&addr)[0]); // send addr bits 0..7
while (cnt--) // receive data while (cnt--) // receive data
*(data++) = _SPI_RX(); *(data++) = _SPI_RX();
_CS_HIGH(); _CS_HIGH();
} }
void w25x20cl_page_program(uint32_t addr, uint8_t* data, uint16_t cnt) void w25x20cl_page_program(uint32_t addr, uint8_t* data, uint16_t cnt)
{ {
_CS_LOW(); _CS_LOW();
_SPI_TX(_CMD_PAGE_PROGRAM); // send command 0x02 _SPI_TX(_CMD_PAGE_PROGRAM); // send command 0x02
_SPI_TX(((uint8_t*)&addr)[2]); // send addr bits 16..23 _SPI_TX(((uint8_t*)&addr)[2]); // send addr bits 16..23
_SPI_TX(((uint8_t*)&addr)[1]); // send addr bits 8..15 _SPI_TX(((uint8_t*)&addr)[1]); // send addr bits 8..15
_SPI_TX(((uint8_t*)&addr)[0]); // send addr bits 0..7 _SPI_TX(((uint8_t*)&addr)[0]); // send addr bits 0..7
while (cnt--) // send data while (cnt--) // send data
_SPI_TX(*(data++)); _SPI_TX(*(data++));
_CS_HIGH(); _CS_HIGH();
} }
void w25x20cl_page_program_P(uint32_t addr, uint8_t* data, uint16_t cnt) void w25x20cl_page_program_P(uint32_t addr, uint8_t* data, uint16_t cnt)
{ {
_CS_LOW(); _CS_LOW();
_SPI_TX(_CMD_PAGE_PROGRAM); // send command 0x02 _SPI_TX(_CMD_PAGE_PROGRAM); // send command 0x02
_SPI_TX(((uint8_t*)&addr)[2]); // send addr bits 16..23 _SPI_TX(((uint8_t*)&addr)[2]); // send addr bits 16..23
_SPI_TX(((uint8_t*)&addr)[1]); // send addr bits 8..15 _SPI_TX(((uint8_t*)&addr)[1]); // send addr bits 8..15
_SPI_TX(((uint8_t*)&addr)[0]); // send addr bits 0..7 _SPI_TX(((uint8_t*)&addr)[0]); // send addr bits 0..7
while (cnt--) // send data while (cnt--) // send data
_SPI_TX(pgm_read_byte(data++)); _SPI_TX(pgm_read_byte(data++));
_CS_HIGH(); _CS_HIGH();
} }
void w25x20cl_erase(uint8_t cmd, uint32_t addr) void w25x20cl_erase(uint8_t cmd, uint32_t addr)
{ {
_CS_LOW(); _CS_LOW();
_SPI_TX(cmd); // send command 0x20 _SPI_TX(cmd); // send command 0x20
_SPI_TX(((uint8_t*)&addr)[2]); // send addr bits 16..23 _SPI_TX(((uint8_t*)&addr)[2]); // send addr bits 16..23
_SPI_TX(((uint8_t*)&addr)[1]); // send addr bits 8..15 _SPI_TX(((uint8_t*)&addr)[1]); // send addr bits 8..15
_SPI_TX(((uint8_t*)&addr)[0]); // send addr bits 0..7 _SPI_TX(((uint8_t*)&addr)[0]); // send addr bits 0..7
_CS_HIGH(); _CS_HIGH();
} }
void w25x20cl_sector_erase(uint32_t addr) void w25x20cl_sector_erase(uint32_t addr)
{ {
return w25x20cl_erase(_CMD_SECTOR_ERASE, addr); return w25x20cl_erase(_CMD_SECTOR_ERASE, addr);
} }
void w25x20cl_block32_erase(uint32_t addr) void w25x20cl_block32_erase(uint32_t addr)
{ {
return w25x20cl_erase(_CMD_BLOCK32_ERASE, addr); return w25x20cl_erase(_CMD_BLOCK32_ERASE, addr);
} }
void w25x20cl_block64_erase(uint32_t addr) void w25x20cl_block64_erase(uint32_t addr)
{ {
return w25x20cl_erase(_CMD_BLOCK64_ERASE, addr); return w25x20cl_erase(_CMD_BLOCK64_ERASE, addr);
} }
void w25x20cl_chip_erase(void) void w25x20cl_chip_erase(void)
{ {
_CS_LOW(); _CS_LOW();
_SPI_TX(_CMD_CHIP_ERASE); // send command 0xc7 _SPI_TX(_CMD_CHIP_ERASE); // send command 0xc7
_CS_HIGH(); _CS_HIGH();
} }
void w25x20cl_rd_uid(uint8_t* uid) void w25x20cl_rd_uid(uint8_t* uid)
{ {
_CS_LOW(); _CS_LOW();
_SPI_TX(_CMD_RD_UID); // send command 0x4b _SPI_TX(_CMD_RD_UID); // send command 0x4b
uint8_t cnt = 4; // 4 dummy bytes uint8_t cnt = 4; // 4 dummy bytes
while (cnt--) // receive dummy bytes while (cnt--) // receive dummy bytes
_SPI_RX(); _SPI_RX();
cnt = 8; // 8 bytes UID cnt = 8; // 8 bytes UID
while (cnt--) // receive UID while (cnt--) // receive UID
uid[7 - cnt] = _SPI_RX(); uid[7 - cnt] = _SPI_RX();
_CS_HIGH(); _CS_HIGH();
} }
int w25x20cl_mfrid_devid(void) int w25x20cl_mfrid_devid(void)
{ {
_CS_LOW(); _CS_LOW();
_SPI_TX(_CMD_MFRID_DEVID); // send command 0x90 _SPI_TX(_CMD_MFRID_DEVID); // send command 0x90
uint8_t cnt = 3; // 3 address bytes uint8_t cnt = 3; // 3 address bytes
while (cnt--) // send address bytes while (cnt--) // send address bytes
_SPI_TX(0x00); _SPI_TX(0x00);
uint8_t w25x20cl_mfrid = _SPI_RX(); // receive mfrid uint8_t w25x20cl_mfrid = _SPI_RX(); // receive mfrid
uint8_t w25x20cl_devid = _SPI_RX(); // receive devid uint8_t w25x20cl_devid = _SPI_RX(); // receive devid
_CS_HIGH(); _CS_HIGH();
return ((w25x20cl_mfrid == _MFRID) && (w25x20cl_devid == _DEVID)); return ((w25x20cl_mfrid == _MFRID) && (w25x20cl_devid == _DEVID));
} }
void w25x20cl_wait_busy(void) void w25x20cl_wait_busy(void)
{ {
while (w25x20cl_rd_status_reg() & W25X20CL_STATUS_BUSY) ; while (w25x20cl_rd_status_reg() & W25X20CL_STATUS_BUSY) ;
} }