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

View File

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

View File

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

View File

@ -171,12 +171,13 @@ bool fsensor_enable(void)
else
fsensor_not_responding = true;
fsensor_enabled = true;
fsensor_autoload_enabled = true;
fsensor_autoload_set(true);
fsensor_autoload_enabled = false;
fsensor_oq_meassure = false;
fsensor_err_cnt = 0;
fsensor_dy_old = 0;
eeprom_update_byte((uint8_t*)EEPROM_FSENSOR, fsensor_enabled ? 0x01 : 0x00);
FSensorStateMenu = fsensor_enabled ? 1 : 0;
eeprom_update_byte((uint8_t*)EEPROM_FSENSOR, 0x01);
FSensorStateMenu = 1;
}
return fsensor_enabled;
}
@ -215,7 +216,7 @@ void fsensor_autoload_check_start(void)
printf_P(ERRMSG_PAT9125_NOT_RESP, 3);
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_c = 0; //reset number of changes counter
fsensor_autoload_sum = 0;
@ -233,7 +234,7 @@ void fsensor_autoload_check_stop(void)
if (!fsensor_autoload_enabled) return;
// puts_P(_N("fsensor_autoload_check_stop 2\n"));
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_watch_autoload = false;
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 >= 12) && (fsensor_autoload_sum > 20))
{
puts_P(_N("fsensor_check_autoload = true !!!\n"));
//if (mmu_enabled) {
mmuFilamentMK3Moving = true;
//puts_P(_N("fsensor_check_autoload = true !!!\n"));
if (mmu_enabled) mmu_command(MMU_CMD_FS);
fsensor_autoload_check_stop();
//}
fsensor_autoload_enabled = false;
return true;
}
return false;

View File

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

View File

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

View File

@ -29,13 +29,14 @@ bool mmu_enabled = false;
bool mmu_ready = false;
bool mmuFilamentMK3Moving = false;
bool mmuFSensorLoading = false;
int lastLoadedFilament = -10;
int8_t mmu_state = 0;
int8_t last_state = -10;
uint8_t mmu_cmd = 0;
bool ack_received = false;
uint8_t mmu_extruder = 0;
@ -78,6 +79,75 @@ int mmu_printf_P(const char* format, ...)
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
int8_t mmu_rx_ok(void)
{
@ -86,18 +156,18 @@ int8_t mmu_rx_ok(void)
return res;
}
//check 'sensing Filament at Boot' response
int8_t mmu_rx_sensFilatBoot()
//check 'nk' response
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();
return res;
}
//check ' not ok' response
int8_t mmu_rx_not_ok(void)
//check 'MK3 FSensor requested to look for load' response
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();
return res;
}
@ -124,10 +194,28 @@ void mmu_init(void)
}
//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)
{
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)
{
case 0:
@ -141,15 +229,7 @@ void mmu_loop(void)
#endif //MMU_DEBUG
mmu_puts_P(PSTR("S1\n")); //send 'read version' request
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
{
puts_P(PSTR("MMU not responding - DISABLED"));
@ -216,83 +296,134 @@ void mmu_loop(void)
printf_P(PSTR("MMU => '%dok'\n"), mmu_finda);
#endif //MMU_DEBUG
puts_P(PSTR("MMU - ENABLED"));
fsensor_enable();
mmu_enabled = true;
mmu_state = 1;
}
return;
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))
{
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) {
fsensor_autoload_check_start();
mmuFSensorLoading = true;
//fsensor_enable();
fsensor_autoload_enabled = true;
mmuFilamentMK3Moving = false;
printf_P(PSTR("MMU <= 'T%d'\n"), filament);
mmu_puts_P(PSTR("EE\n")); // Advise MMU CMD is correct, execute
mmu_state = 3; // wait for response
} else {
mmu_puts_P(PSTR("EE\n")); // Advise MMU CMD is correct, execute
mmu_state = 3;
}
lastLoadedFilament = filament;
}
else if ((mmu_cmd >= MMU_CMD_L0) && (mmu_cmd <= MMU_CMD_L4))
{
filament = mmu_cmd - MMU_CMD_L0;
#ifdef MMU_DEBUG
printf_P(PSTR("MMU <= 'L%d'\n"), filament);
#endif //MMU_DEBUG
mmu_printf_P(PSTR("L%d\n"), filament);
mmu_puts_P(PSTR("EE\n")); // Advise MMU CMD is correct, execute
mmu_state = 3; // wait for response
}
else if (mmu_cmd == MMU_CMD_C0)
{
#ifdef MMU_DEBUG
delay(100);
printf_P(PSTR("MMU <= 'C0'\n"));
#endif //MMU_DEBUG
delay(200);
mmu_puts_P(PSTR("C0\n")); //send 'continue loading'
mmu_puts_P(PSTR("EE\n")); // Advise MMU CMD is correct, execute
mmu_state = 3;
}
else if (mmu_cmd == MMU_CMD_U0)
{
#ifdef MMU_DEBUG
printf_P(PSTR("MMU <= 'U0'\n"));
#endif //MMU_DEBUG
mmu_puts_P(PSTR("U0\n")); //send 'unload current filament'
mmu_puts_P(PSTR("EE\n")); // Advise MMU CMD is correct, execute
lastLoadedFilament = -10;
mmu_state = 3;
}
else if ((mmu_cmd >= MMU_CMD_E0) && (mmu_cmd <= MMU_CMD_E4))
{
int filament = mmu_cmd - MMU_CMD_E0;
#ifdef MMU_DEBUG
printf_P(PSTR("MMU <= 'E%d'\n"), filament);
#endif //MMU_DEBUG
mmu_printf_P(PSTR("E%d\n"), filament); //send eject filament
mmu_puts_P(PSTR("EE\n")); // Advise MMU CMD is correct, execute
mmu_state = 3; // wait for response
}
else if (mmu_cmd == MMU_CMD_R0)
{
#ifdef MMU_DEBUG
printf_P(PSTR("MMU <= 'R0'\n"));
#endif //MMU_DEBUG
mmu_puts_P(PSTR("R0\n")); //send recover after eject
mmu_puts_P(PSTR("EE\n")); // Advise MMU CMD is correct, execute
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_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_state = 2;
}
@ -301,9 +432,7 @@ void mmu_loop(void)
if (mmu_rx_ok() > 0)
{
fscanf_P(uart2io, PSTR("%hhu"), &mmu_finda); //scan finda from buffer
#ifdef MMU_DEBUG
printf_P(PSTR("MMU => '%dok'\n"), mmu_finda);
#endif //MMU_DEBUG
//printf_P(PSTR("MMU => '%dok'\n"), mmu_finda);
if (!mmu_finda && CHECK_FINDA && fsensor_enabled) {
fsensor_stop_and_save_print();
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
}
mmu_state = 1;
if (mmu_cmd == 0)
mmu_ready = true;
//if (mmu_cmd == 0)
//mmu_ready = true;
}
else if ((mmu_last_request + MMU_P0_TIMEOUT) < millis())
{ //resend request after timeout (30s)
@ -320,29 +449,56 @@ void mmu_loop(void)
}
return;
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 (mmuFSensorLoading == false) {
delay(100);
printf_P(PSTR("MMU => 'ok'\n"));
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"));
//if ok received then go back to ready
mmu_state = 1;
mmu_ready = true;
}
/*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);
while (mmu_cmd != 0)
{
// mmu_loop();
delay_keep_alive(100);
}
while (!mmu_ready)
{
// mmu_loop();
if (mmu_state != 3)
if ((mmu_state == 3) || (mmu_state == 10) || (mmuFSensorLoading)) {
delay_keep_alive(100);
} else {
break;
delay_keep_alive(100);
}
}
bool ret = mmu_ready;
mmu_ready = false;
@ -408,7 +564,7 @@ void manage_response(bool move_axes, bool turn_off_nozzle)
while(!response)
{
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 (lcd_update_enabled) {
lcd_update_was_enabled = true;
@ -550,6 +706,7 @@ void mmu_M600_load_filament(bool automatic)
{
//load filament for mmu v2
tmp_extruder = mmu_extruder;
lastLoadedFilament = -10;
if (!automatic) {
#ifdef MMU_M600_SWITCH_EXTRUDER
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);
manage_response(false, true);
delay(100);
mmu_command(MMU_CMD_C0);
mmu_extruder = tmp_extruder; //filament change is finished
delay(100);
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);
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);
}
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);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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