Bed Leveling on V1/V2

A project log for Monoprice Mini Marlin 2.0 Support

Getting Marlin to run on the Monoprice Mini/Malyan M200.

J.C. NelsonJ.C. Nelson 05/23/2019 at 04:120 Comments

One of the big features the V3/MP MIni Pro brings to the table is automatic bed leveling, but I've always been of the opinion there's no reason to restrict bed leveling to a new product. Marlin supports it, so why not the mini?  To do this required a couple of changes underlying everything else:

First, eeprom emulation wasn't working. The 103 in the V1 doesn't support SRAM and there's no I2C eeprom (and precious few pins available to wire one up). So EEPROM emulation it is. Here, I was led astray by some of the pre-existing code. the STM32F4 and F7 HAL support EEPROM emulation, and I first attempted to port it, but flash programming is very different between 103, F4 and F7. 

So, instead, I deleted all the existing code and wired together a simple one using the platform's EEPROM library. There's some overhead to this that's not good, but for now it works and lets us save settings using M500...a prereq for bed leveling.

After enabling bed leveling in a fake mode (linear, using z min pin, aka "pretend to level using the z endstop"), I recompiled and immediately failed, overflowing the ROM region by 2k bytes.

But it's actually much worse than that. 

The linker script doesn't (and shouldn't) take into account EEPROM emulation, which takes a full page. THis means that of the 128K available, 8k goes to the bootloader, 4k to the emulation, so we were overflowing by over 6k, and 6k is a LOT in the ARM world.

arm-none-eabi-nm -t d -S --size-sort

gave us the output for where the sizes were going.

Our biggest culprits? We expect dtoa and strtod (a couple of large functions we need and you don't expect to vary much - the whole subject of decimal conversion and representation is intricate and fasinating, and a lot of the value in these two is that they do things the same way everywhere, all the time).

34263024 00000940 T _ZN14MarlinSettings4saveEv
134309128 00000984 T HAL_RCC_OscConfig
134336292 00001104 T __gethex
134277628 00001128 T _Z8probe_ptRKfS0_12ProbePtRaisehb
134307920 00001156 T HAL_PCD_IRQHandler
134326604 00001182 W _printf_float
134252048 00001204 T _ZN10GcodeSuite22process_parsed_commandEv
134234936 00001296 T __aeabi_dmul
536873824 00001344 B _ZN7Planner12block_bufferE
134285852 00001368 T _ZN11Temperature12PID_autotuneERKfaab
134232892 00001516 T __aeabi_ddiv
134246040 00001524 T _ZN10GcodeSuite3G29Ev
134280316 00001552 T _ZN7Stepper23stepper_block_phase_isrEv
134264188 00001596 T _ZN14MarlinSettings6reportEb
134231120 00001772 T __aeabi_dadd
134236232 00001840 T __aeabi_dsub
536877664 00002048 b eeprom_buffer
134274192 00002312 T _ZN7Planner15_populate_blockEP7block_tbRA4_KlfhRKf
134265784 00002724 T _ZN14MarlinSettings5_loadEv
134333160 00002984 T _dtoa_r
134328968 00003132 T _strtod_l

The problem with this output is pretty much everything here, we need (there may be some optimizations available by removing PID autotune, but that's re-arranging deck chairs on the Titanic to slow the sinking. We need big savings, and the first thing we have to do is find out if it's using function sections.

Unfortunately, that flag is already on. 

However...a quick check shows that Link Time Optimization is NOT on. A quick change, and we get:

Sketch uses 100392 bytes (81%) of program storage space. Maximum is 122880 bytes.
Global variables use 9724 bytes (47%) of dynamic memory, leaving 10756 bytes for local variables. Maximum is 20480 bytes.

That is totally acceptable. A quick check, and G29 works flawlessly.

Next up, time to fix the Z homing speeds to be something normal. Right now it homes very slowly because I'm looking at how the ISR services pulses. I'll try something more rational soon, and then homing should behave normally, and hooking up leveling probes to the mini will be straightforward.