prusa firmware code snippet -> what the heck is going on there ?
 
Notifications
Clear all

prusa firmware code snippet -> what the heck is going on there ?  

  RSS
JeffJordan
(@jeffjordan)
Member Moderator
prusa firmware code snippet -> what the heck is going on there ?

hi guys,
actually I'm trying to modify the 3.0.12 firmware for my MK2 (and my clone) a little bit, so that I can use PJR's hyperfine bed levelling amendment (using the G80 command) and a modified bed level correction sub-menu (with eight values for "a" - "h") inside the calibration menu.

ok, I'm not very familiar with C / C++, so I often have to use the arduino sites or two books I bought about C and C++.

now I stumbled over a part of the firmware (inside Marlin_main.cpp) where a routine reads one of four values, stored inside the eeprom.
but I can't figure out how this works:

unsigned char *addr = (i < 2) ?
((i == 0) ? (unsigned char*)EEPROM_BED_CORRECTION_LEFT : (unsigned char*)EEPROM_BED_CORRECTION_RIGHT) :
((i == 2) ? (unsigned char*)EEPROM_BED_CORRECTION_FRONT : (unsigned char*)EEPROM_BED_CORRECTION_REAR);
correction = eeprom_read_int8(addr);

this part is inside a loop where i runs from 0 to 3.
correction is assigned as long int.
the EEPROM_BED_CORRECTION_... are EEPROM locations (defined inside Configuration.h), where the corresponding value is stored.
the value itself requires only one byte inside the EEPROM, so that we have four EEPROM_BED_CORRECTION locations, where a single byte is stored.

ok, *addr seems to be a pointer, but how is its value determined ?
and what the heck does "(unsigned char*)" attached to the EEPROM locations do ?

anyone here who could explain what's going on inside the first three lines posted in the code section ?
or somebody who can show me a simple way to read out a single parameter, stored at EEPROM_BED_CORRECTION_LEFT for example ?

dem inscheniör is' nix zu schwör...

Napsal : 19/07/2017 1:53 pm
PJR
 PJR
(@pjr)
Antient Member Moderator
Re: prusa firmware code snippet -> what the heck is going on there ?

Yeah.

If i is equal to 0 carry out the next part else carry out the last part.

sorry, had to look again, there's another conditional:

unsigned char *addr = (i < 2) ?
((i == 0) ? (unsigned char*)EEPROM_BED_CORRECTION_LEFT : (unsigned char*)EEPROM_BED_CORRECTION_RIGHT) :
((i == 2) ? (unsigned char*)EEPROM_BED_CORRECTION_FRONT : (unsigned char*)EEPROM_BED_CORRECTION_REAR);
correction = eeprom_read_int8(addr);

Se we are defining an unsigned char pointer )addr) which becomes equal to the eeprom memory address according to the value of i.

If i < 2 it assigns either LEFT or RIGHT; if i = 0 it assigns LEFT else RIGHT
If i >=2 it assigns either FRONT or REAR; if i = 2 it assigns FRONT else REAR

so addr ends up containing the pointer to the L/R/F/B value within EEprom

Peter

Please note: I do not have any affiliation with Prusa Research. Any advices given are offered in good faith. It is your responsibility to ensure that by following my advice you do not suffer or cause injury, damage…

Napsal : 19/07/2017 4:33 pm
3DBastler
(@3dbastler)
Eminent Member
Re: prusa firmware code snippet -> what the heck is going on there ?

To make it easier to understand I would write it like below (symbolic meant):
for (i = 0; i < 3; i++)
{
if (i < 2) then
// i = 0 or 1
{
if (i == 0) then
{
return_value = (unsigned char*)EEPROM_BED_CORRECTION_LEFT;
}
else
{
return_value = (unsigned char*)EEPROM_BED_CORRECTION_RIGHT;
}
}
else
// i = 2 or 3
{
if (i == 2) then
{
return_value = (unsigned char*)EEPROM_BED_CORRECTION_FRONT;
}
else
// i= 3
{
return_value = (unsigned char*)EEPROM_BED_CORRECTION_REAR;
}
}

return (return_value);

}// end for i = 0 to 3

Napsal : 19/07/2017 4:39 pm
JeffJordan
(@jeffjordan)
Member Moderator
Topic starter answered:
Re: prusa firmware code snippet -> what the heck is going on there ?

meanwhile I found a more structured way with using the switch & case commands.
and I figured out that (unsigned char*) allows you to convert the integer value of the EEPROM-address to a vector.
so my cases look like this one:switch (i) {
case 0:
{unsigned char *addr = (unsigned char*)EEPROM_BED_CORRECTION_PJR_A;
correction = eeprom_read_int8(addr);
}
break;
...
}

now I finally managed to compile the 3.0.12 firmware with a "Bed level correct" submenu, where I can set manually all the eight correction values from -99 to +99 µm. and the lower case parsing of the G80 command should work as well. combinations are valid as well, so if I only send a "G80 b50" to the printer, it takes value a, and c to h out of the eeprom and uses the parsed 50 for value b.

in theory it should work, but until now, I haven't tested it with a print.
if somebody's willing to test as well, just sent me a pm. -> but without any warranty and at your own risk.

dem inscheniör is' nix zu schwör...

Napsal : 19/07/2017 5:55 pm
Share: