Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

STM32F411 port #189

Open
Wurstnase opened this Issue Nov 5, 2015 · 223 comments

Comments

Projects
None yet
5 participants
@Wurstnase
Copy link
Collaborator

Wurstnase commented Nov 5, 2015

Hi all,

I think it's better to make a new issue for that port. Currently I stopped with the Due-port.

Anyhow, the first progress is done. Serial works and I start to simplify it.

I delete the mbed-hal_tick_stm32 parts. https://github.com/Traumflug/Teacup_Firmware/blob/e04833b431589072091d41701179fed0c491dfda/mbed-hal_tick_stm32.c
But with that, the STM starts "start\nok\n" but after additional 4 or 5 chars it stops. I don't understand this part completely. It reconfigure the Systick? Any hints?

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Nov 5, 2015

I found some ideas. I will test them and report.

@Traumflug

This comment has been minimized.

Copy link
Owner

Traumflug commented Nov 5, 2015

  • Does delay_us() work? It's based on NOPs and more advanced CPUs might optimize this away internally, even if the compiler doesn't.
  • Is the maximum string length about the same as the buffer size? If yes, characters might be written into the already filled buffer.
  • Systick should be independent from serial workings. Especially with the baud rate being right.
@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Nov 5, 2015

delay.c isn't ported.
This one

// Reconfigure the HAL tick using a standard timer instead of systick.
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)

reconfigure it. That is called in the mbed-system_stm32.c.

After deleting the mbed-hal_tick_stm32.c the __weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) is called.

The baud-rate works perfectly (the divisior of my last pull was wrong, but correct on my local version). But without the ticker I can only see the first 16? chars.

@Traumflug

This comment has been minimized.

Copy link
Owner

Traumflug commented Nov 5, 2015

16 bytes might well be the size of the UART send buffer. If you write more in one chunk, the remaining bytes are lost. You have to wait until some of the bytes are sent. serial_writechar() in serial-arm.c on master/experimental shows how it can be done. Well, either you find other tasks to spend time or you have to port delay.c before sending larger amounts.

delay-arm.c should work without changes. For testing delays without a scope simply use delay_ms(10000), send a character before and after, and if these two characters are sent with 10 seconds in between, you're fine for both, delay_ms() and delay_us(). Precision isn't crucial, stepper motors are timed by other mechanisms.

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Nov 6, 2015

To precise it. I also add

for (;;) {
  if (serial_rxchars() != 0) {
    serial_writechar(serial_popchar());
  }
}

But it doesn't show chars anymore after deleting the ticker. I hope I have more time this afternoon.

@triffid

This comment has been minimized.

Copy link
Collaborator

triffid commented Nov 6, 2015

@Traumflug

This comment has been minimized.

Copy link
Owner

Traumflug commented Nov 6, 2015

Perhaps you simply expect a bit too much from the first few commits. If serial out works, fine, time to move on to the next commit.

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Nov 6, 2015

Git is not my best friend... Or... Learning git the hard way :)

I start a new branch with cherrypicked commits and a clean rebase. I made some big mistakes at the beginning.

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Nov 6, 2015

Or @Traumflug what is the best practise for rebase? Should I push after any rebase?

My first issue was to manipulate the corrupted files wrong. I've took 'ours' not 'theirs'. Or reverse?!?

@Traumflug

This comment has been minimized.

Copy link
Owner

Traumflug commented Nov 7, 2015

I've took 'ours' not 'theirs'. Or reverse?!?

I sometimes wonder where people learn such stuff. "It doesn't work! It doesn't work!" ... and if one manages to catch such people before they rush away one hears about attempts which can't be found in any tutorial and only in a small corner of the manual. Happens not too rarely.

OK, this little story aside, one uses neither 'ours' nor 'theirs'. At least not until it's 100% sure it does the right things. Without them, conflicts can happen, that's the normal behaviour. Editing conflicts is no rocket science, one searches the conflicting file for ====, which will find two versions of the same code section. These two versions are joined to one by plain text editing. What to keep and what to delete depends on what the result should be. Along the way these three marker lines are removed as well. After editing a conflict one saves the file, then adds it with git add.

All files done, one continues the rebase with git rebase --continue. Until the rebase is completed. If it's unclear wether it's completed, simply try another --continue; it never hurts.

Unfortunately, Git is a bit unclear on which the conflicting files are. Lots of messages, sometimes with, sometimes without the file names. The easiest way to find the file(s) is to simply try to continue with git rebase --continue, then it's simply lists the not yet solved ones (it uses the word 'merged', which is a bit misleading).

Wether to push or not to push is entirely independent from all this. Pushing after a rebase obviously makes most sense. You can push before, too, especially if the rebase doesn't work the way you like it.

Not to forget: one can always abort a rebase with git rebase --abort. This will restore the repo to the point before the rebase attempt, without any clutter or half-done tasks dangling around.

@Traumflug

This comment has been minimized.

Copy link
Owner

Traumflug commented Nov 7, 2015

P.S.: for playing with another branch to not mess up the original (good idea!) I'd simply duplicate the existing one: git branch <oldname> <newname> Then you can rebase and rebase -i as much as you like without destroying anything.

@triffid

This comment has been minimized.

Copy link
Collaborator

triffid commented Nov 7, 2015

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Nov 7, 2015

My way of learning is doing it. Anyhow, I rebase it exactly the way you discribed, the only thing I was wrong, I thought the rebase I made were more in the front than it is.

I start a rebase. Saw that something is wrong. Abort a rebase. Start again...
However...

One thing to keep in mind with rebase is that if you rebase a pushed branch it won't push again unless you force

Ok, a new point I've didn't know. Maybe this is also something which get me crashed?!?

@Traumflug

This comment has been minimized.

Copy link
Owner

Traumflug commented Nov 7, 2015

Traumflug seems to have created his own workflow

This workflow certainly isn't an invention of me, it's well documented as "topic branches". Git comes with quite a number of tools to support this workflow, after all. Even the Git folks them selfs use this strategy.

Maybe this is also something which get me crashed?!?

Again: no, can't happen, rebasing and pushing are two entirely independent tasks.

I start a rebase. Saw that something is wrong. Abort a rebase. Start again...
However...

... however you don't tell us what went wrong.

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Nov 7, 2015

It just something I made wrong in one of the first commits. I made a rebase, vote the wrong 'ours'/'theirs' and the problems began. I had a lot of broken commits. And it was getting worse and worse with each commit. Just something I have to learn. I think I was right, but now I know I wasn't.

Hopefully this new one works better. The first rebases works pretty fine and I think I'm on the right way now.

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Nov 7, 2015

git_rebase_issues
What I am doing wrong? I pull my last push. Rebase to experimental~73 (fastio). Repair, commit.

@Traumflug

This comment has been minimized.

Copy link
Owner

Traumflug commented Nov 7, 2015

Repair, commit.

Repair, add, rebase --continue

Other than that, what's the problem? You have 6 commits locally on top of the remote branch. Looks perfectly fine.

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Nov 8, 2015

Repair, add, rebase --continue until nothing is to do anymore. Right.
I didn't rebase the experimental, sorry for confusion.

So what I was doing exactly.

  • ~~rebase experimental ~74~~
  • add, rebase --continue
  • git push

until this anything fine

  • git pull

and here I need to repair my just pushed branch. I don't rebase anything.
I will take a coffee and write my statement again. In think this is also wrong...

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Nov 8, 2015

Forgot what I've been written. I have a tool called Smartgit. But it's too "smart".
It makes a
git fetch --progress --prune origin
when I normally want to pull.

Pure git works perfect.

@Traumflug

This comment has been minimized.

Copy link
Owner

Traumflug commented Nov 8, 2015

rebase experimental~74

Looking at what's in the public repo, branch arm-stm32f411-port is based on experimental~74 already, so it's no surprise another rebase attempt does nothing. To move up the ladder you'd have to rebase to experimental~73.

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Nov 8, 2015

Anyhow, the main-issue was Smartgit.
Fastio works now :) with 18,5MHz.

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Nov 8, 2015

It couldn't be so complicated.
Git pull
Git rebase experimental~68 (or 67 or whatelse)
Repair, add, rebase --continue...
Whatever I made, an old commit is duplicated in front.

@Traumflug

This comment has been minimized.

Copy link
Owner

Traumflug commented Nov 8, 2015

Whatever I made, an old commit is duplicated in front.

What is the content of this "duplicate"? If commits don't match 100%, the differing part is left in the rebased branch. Then you have two commits with the same description, but different content.

If this difference is just some whitespace or something neglibile, you can remove the commit with git rebase -i experimental~68. An editor will open, listing all commits. Removing the line with the commit in question will also remove the commit from the branch.

If the difference is bigger you have to decide wether it needs to be kept or what else to do with it.

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Nov 9, 2015

Ok, one hopefully last question about this.

git checkout arm-stm32f411-port
git pull
git rebase experimental~xx
git add xy
git rebase --continue
git add xz
git rebase --continue

Now I get a message like this:

git status
On branch arm-stm32f411-port
Your branch and 'origin/arm-stm32f411-port' have diverged,
and have 21 and 18 different commits each, respectively.
    (use "git pull" to merge the remote branch into yours)

nothing to commit, working directory clean

Everything is perfect, until I made a git pull where my problems start.
Is it necessary to git pull?

@Traumflug

This comment has been minimized.

Copy link
Owner

Traumflug commented Nov 9, 2015

git checkout arm-stm32f411-port
git pull

Again you mix rebasing with pushing/pulling. Please stop it! If you're the only contributor to this branch there's never a need to pull anything.

Your branch and 'origin/arm-stm32f411-port' have diverged,

This is an informational message and expected after a rebase. As the diverge appeared because your local branch changed, not because the remote one did, this advice to pull is wrong. A git push -f origin arm-stm32f411-port will upload your local branch to the remote repo, which will also make them equal, so the message will disappear.

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Nov 9, 2015

git checkout arm-stm32f411-port
git pull

Again you mix rebasing with pushing/pulling. Please stop it! If you're the only contributor to this branch there's never a need to pull anything.

I'm on a different computer acutally and want to be sure, that I have the latest version.

A git push -f origin arm-stm32f411-port will upload your local branch to the remote repo, which will also make them equal, so the message will disappear.

Ok, now I'm on the right way. That's the one I need. Thanks!

@Traumflug

This comment has been minimized.

Copy link
Owner

Traumflug commented Nov 9, 2015

I'm on a different computer

In this case you're technically two users. Do the rebase on the computer with the newer development, after having this done, push it to the public repo, then go to the other computer and pull there.

That said, using "pull" can cause trouble. A "fetch" always works, because it doesn't update local branches. I'd do it like this:

git fetch
git branch -d arm-stm32f411-port            # delete the local branch
git checkout -b origin/arm-stm32f411-port   # create a new local branch from the remote one

This is a strategy which never causes conflicts.

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Nov 10, 2015

Yeah, the most mystics are in my head now. 👍

I will made a reset to the last wrong git pull and will rebase/cherry-pick it as it should be.

I have some additional branches with minimized working serial. Btw. the Pin-Registers is a CortexM0 only thing?!? I don't find any similar at my M4. There are only port-register, but therefor a lot.

@Traumflug

This comment has been minimized.

Copy link
Owner

Traumflug commented Nov 10, 2015

Btw. the Pin-Registers is a CortexM0 only thing?!?

Pin I/O is considered to be a "peripheral", so yes, it might be different on your MCU. Likely less a "M0-only" thing, more a "NXP-only" thing.

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Nov 11, 2015

History is more clean now. git rebase -i HEAD~x is a nice way to repair some commits.

The SystemInit() needs a total rework. The RCC-part is hardly nested. I hope I can find a clean way.

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Dec 10, 2016

The int_inv_sqrt() algorithm is only good enough for stepping rates and accelerations were you need less then 2^16 steps for acceleration. At 2^16 this will anyway overflow.

But also the accuracy will go down a lot when you are close to 2^16 steps.

at 48MHz, 1280 steps/mm, acc 100 =>

int_inv_sqrt(58052) ~ 17
int_inv_sqrt(58053) ~ 16

dda_c = c0_P * int_inv_sqrt(x) >> 13 = 189736 * 17 >> 13 = 393
                                       189736 * 16 >> 13 = 370

393 = 95 mm/s
370 = 101 mm/s

This jump is very noticeable.

Wurstnase added a commit that referenced this issue Jan 2, 2017

Revert "DDA: use bitmask to track active axes [...]"
While this was an improvement of 9 clocks on AVRs, it had more
than the opposite effect on ARMs: 25 clocks slower on the slowest
step. Apparently ARMs aren't as efficient in reading and writing
single bits.

  #189 (comment)

Performance on AVR is back to what we had before:

  ATmega sizes               '168   '328(P)   '644(P)     '1280
  Program:  19610 bytes      137%       64%       31%       16%
     Data:   2175 bytes      213%      107%       54%       27%
   EEPROM:     32 bytes        4%        2%        2%        1%

  short-moves.gcode statistics:
  LED on occurences: 888.
  LED on time minimum: 280 clock cycles.
  LED on time maximum: 549 clock cycles.
  LED on time average: 286.273 clock cycles.

  smooth-curves.gcode statistics:
  LED on occurences: 23648.
  LED on time minimum: 272 clock cycles.
  LED on time maximum: 580 clock cycles.
  LED on time average: 307.439 clock cycles.

  triangle-odd.gcode statistics:
  LED on occurences: 1636.
  LED on time minimum: 272 clock cycles.
  LED on time maximum: 539 clock cycles.
  LED on time average: 297.732 clock cycles.
@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Jan 23, 2017

The ADC is kidding me.

One ADC is at GND. The other one at 3.3V.

Result:

0, 1023, 0, 1023, 0, 1023, 0, 1023
0, 1023, 0, 1023, 0, 1023, 0, 1023
1023, 0, 1023, 0, 1023, 0, 1023, 0
1023, 0, 1023, 0, 1023, 0, 1023, 0
1023, 0, 1023, 0, 1023, 0, 1023, 0

It's random which sensor is read first. Also sometimes the OVR-flag appears. 😩

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Jan 23, 2017

Hmm... How do I point to an array?

uint16_t adc_buffer[10];
DMA2_Stream4->M0AR = (uint32_t)&adc_buffer;
or
DMA2_Stream4->M0AR = (uint32_t)&adc_buffer[0];
or
DMA2_Stream4->M0AR = (uint32_t)adc_buffer;
@phord

This comment has been minimized.

Copy link
Collaborator

phord commented Jan 23, 2017

adc_buffer: uint16_t *
&adc_buffer: uint16_t **
&adc_buffer[0]: uint16_t * (same as adc_buffer)

But why are you casting them to uint32_t? I don't think that will work on the AVR.

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Jan 23, 2017

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Jan 23, 2017

Uff... Finally also this works also.

So when reading via DMA the ADC hicks up. First ADC reading was missing. But the DMA knows, that it must convert X ADCs. So it will start again at 0. So in one case we read ADC0, ADC1. Some other time we read ADC1 and then ADC0. With this, also an overrun could happen, which would make things more complicated. An overrun will happen, when an ADC is ready but there is no more space. This can be avoided by disabling a bit in a special register, which is/was disabled. But in this unique thing, it could also happen. 😶

To restart the ADC the STM needs to disable the ADC, unset/set the DMA-bit, enable ADC and start the ADC. Then we can use the start_adc()-function. 😑

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Jan 30, 2017

Disabling the ADC has some unwanted sideeffects. The ADC needs ~3µs to stabilize. So I figured out, that disabling the continuous conversion is sufficient for that.

So instead of disabling the ADC completely, the DMA_CR2_CONT-bit is cleared after the conversion (transfer complete interrupt of the DMA) and set afterwards in the start_adc().

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Mar 23, 2017

Pretty cool stuff you can do with a bare controller.

Put the new experimental code, a portion of temporal code with acceleration and ramps, three pwm-able pins, some magic and a DWT to count cycles. Shaking... -O3 -flto...

512000 steps (1280 steps/mm * 400mm; G1 X400) of a single axis in 39 million cycles (Acceleration at 10000, just bare controller, no motors). With 100MHz this means ~0,39s for 512k steps. Whooping 1.3MHz. Approx. 1025mm/s

With two axes need for the same distance (G1 X400 Y400) 77 million cycles. So we have 1.3MHz 665kHz. Approx. 519 mm/s
With three axes (G1 X400 Y400 Z400) 113mc -> 1.3MHz 453kHz. Approx. 307mm/s

Just happy that this works and want to share with you.

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Mar 31, 2017

Are there any caveats for Teacup to jump directly into main?
I've changed the startup file from bl _start to bl main and add also the LDFLAG += -nostartfiles. Program size is reduced dramatically:

SIZES with _start no _start
FLASH 14812 bytes 9896 bytes
RAM 1828 bytes 1084 bytes
EEPROM 0 bytes 0 bytes
@Traumflug

This comment has been minimized.

Copy link
Owner

Traumflug commented Mar 31, 2017

Huh, that's a lot. Good catch!

Does this startup code initializing interrupt vectors and CPU clock still run? If yes, I wonder a bit what's the point of these 5k of code. AFAIK, CMSIS claims to get away with "just a few bytes of RAM".

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Mar 31, 2017

What I've read about this, this is the cstdlib init stuff. Maybe...

Vectors etc. are started some lines before with the systeminit.

@Traumflug

This comment has been minimized.

Copy link
Owner

Traumflug commented Mar 31, 2017

Looking into cmsis-startup...s I see

    ldr    r0, =SystemInit
    blx    r0
    ldr    r0, =_start
    bx    r0

With my limited experience in assembly this looks like it's jumping to SystemInit() first, then running this _start() thing. Accordingly it's fine to drop _start().

Wow. Such a small change for such a large gain.

@triffid

This comment has been minimized.

Copy link
Collaborator

triffid commented Mar 31, 2017

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Mar 31, 2017

One of _start's jobs is to copy from flash to non zero
static variables and zero-fill the bss section.

Isn't this done in the startup-file?

Please make sure you understand precisely what's being skipped before
committing such a change!

Totally agree with you. 👍

@Traumflug

This comment has been minimized.

Copy link
Owner

Traumflug commented Mar 31, 2017

Valid points, @triffid. Certainly needs investigation.

Looking into cmsis-startup... I see such stuff:

  • stack initialisation,
  • heap initialisation,
  • interrupt vector initialisation,
  • an (empty) default IRQ handler,
  • a loop to copy the data section to RAM.

Stack, heap and IRQ stuff should be fine if the CPU runs at all. Data section can be tested with some code relying on a variable initialized to something non-zero.

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Mar 31, 2017

This is the resulting symbol list. I've deleted any weaks to shorten this.

~$ nm -Cg build/teacup.elf
200005d4 B __bss_end__
20000198 B __bss_start__
20000198 D __data_end__
20000198 D __data_start__
200005d4 N __end__
080026a8 T __etext
080026a8 T __exidx_end
080026a8 T __exidx_start
20020000 A __StackLimit
20020000 B __StackTop
200005d4 B _ebss
20000198 D _edata
20020000 A _estack
20000198 B _sbss
20000198 D _sdata
080026a8 T _sidata
200001e8 B adc_buffer.lto_priv.30
0800254c T axis_qr_P
08002668 T c0_P.lto_priv.26
080019d5 T clock
200005a0 B clock_flag_10ms.lto_priv.27
200005a4 B clock_flag_1s.lto_priv.29
200005a8 B clock_flag_250ms.lto_priv.28
08001159 T dda_new_startpoint
080010b9 T dda_start
08001f51 T decfloat_to_int.constprop.3
080023ec T Default_Handler
08001025 T delay_ms
08001d21 T DMA2_Stream4_IRQHandler
08000fd9 T do_heater.part.0
200005d4 N end
080011ed T enqueue_home
08000000 T g_pfnVectors
080011b1 T get_direction
20000214 B heaters_pid
20000224 B heaters_runtime
08001cc1 T home_x_negative
08001c5d T home_y_negative
08000199 T main
200005b0 B mb_head.lto_priv.20
200005b4 B mb_tail
200005b8 B mb_tail_dda
2000026c B move_state
20000294 B movebuffer
08001071 T muldivQR
200001b4 B next_target
0800229d T NVIC_EncodePriority.lto_priv.17.lto_priv.24
0800229d T NVIC_EncodePriority.lto_priv.18.lto_priv.25
080020ed T PendSV_Handler
08002385 T power_on
200005bc B ps_is_on.lto_priv.21
200005bd B psu_timeout
08001051 T queue_full
08001c49 T queue_wait
20000264 B read_digit
08001ded T sendf_P.constprop.4
08001d3d T serial_writechar
0800236d T serial_writestr_P
080022d5 T single_temp_print.lto_priv.23
20000198 B startpoint
0800254c T steps_per_m_P.7459.lto_priv.31
080018c9 T SystemInit
08002239 T SysTick_Handler
08002331 T temp_achieved
200005c0 B temp_sensors_runtime.lto_priv.22
08002351 T temp_wait
08001fa1 T TIM5_IRQHandler
200005d0 B wait_for_temp.lto_priv.19
@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Mar 31, 2017

Maybe also important:

~$ nm -p build/teacup.elf
080023b0 t LoopCopyDataInit
080023a8 t CopyDataInit
080023c4 t LoopFillZerobss
080023be t FillZerobss
080023ec t Infinite_Loop
@triffid

This comment has been minimized.

Copy link
Collaborator

triffid commented Mar 31, 2017

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Apr 3, 2017

Wondering that GCC don't throw any error:

#define F_CPU 100000000
move_duration = distance * ((60UL * F_CPU / 1000UL) / dda->endpoint.F);
@triffid

This comment has been minimized.

Copy link
Collaborator

triffid commented Apr 3, 2017

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Apr 3, 2017

If it bugs you anyway, put F_CPU / 1000UL in parentheses so it gets
computed before the multiply by 60. That won't cause any problems unless
someone has a system where F_CPU is not a multiple of 1000, and even then
it would only give minor velocity errors...

Yes, this is what I'm doing. I just found this issue yesterday. GCC unfortunately don't show any overflow in that case and I was wondering on my ARM why the osci shows unpredictable values.

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Jul 24, 2017

While the STM32F411 code is already in the experimental branch, I've just started with the port for Nucleo Boards STM32F401 and STM32F446. Both should be able to build and test the serial connection.

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Jul 26, 2017

Teacup clock is running at expected speed.
Now I need to research some issues.

The stm32f446 can run up to 180MHz. While running with 100MHz the dda_step() needs approx. 135 cpu-cycles. At 180MHz it needs 200 cpu-cycles. Waitstates for flash increase from 3 to 5, but this shouldn't increase that number so huge?!?

Also the deceleration doesn't work at any speed. With 100 and 180MHz when I use 1280 steps/mm and want to travel with ~26000 mm/min the acceleration works. But it will nearly immediately stop at deceleration point. But any step is done. The interrupt will go into dda_step in any case. (Maybe the latency for calculating the next step while cruising is to high?!? But then it shouldn't be nearly the same at 100 and 180MHz.)

I know, this is not possible for normal 3d printer. But I want to find this issue. 😄

I will take my osci from work to measure the debug pin for better inspections.

@Traumflug

This comment has been minimized.

Copy link
Owner

Traumflug commented Jul 26, 2017

The stm32f446 can run up to 180MHz. While running with 100MHz the dda_step() needs approx. 135 cpu-cycles. At 180MHz it needs 200 cpu-cycles. Waitstates for flash increase from 3 to 5, but this shouldn't increase that number so huge?!?

Apparently reading from Flash is the bottleneck. 135 / 3 * 5 = 225.

You could look into running the entire thing from RAM. Zero waitstates, then, ~1.3 MHz step rate.

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Jul 26, 2017

Apparently reading from Flash is the bottleneck. 135 / 3 * 5 = 225.

Excellent hint, but little bit different you will expect. 👍

>>> g1 x1000 f27018

Current code:
min:202 max:205 avg:203 n:1280000
Function to RAM:
min:169 max:173 avg:170 n:1280000

Nice one. 20% faster... BUT!

min:112 max:155 avg:121 n:1280000

What is that? I was little bit surprised, that it's nearly 5/3, because the STM32 should have something called ART accelerator. But this wasn't active. So dig into the ref man, find the part, activate it.

Just for the facts:

min:159 max:173 avg:162 n:1280000

This is the code in RAM with ART.

@Wurstnase

This comment has been minimized.

Copy link
Collaborator Author

Wurstnase commented Jul 28, 2017

f446_16mhz

Now I will invest my time in more suitable stuff. Raw ADC heater management for example.

@Traumflug

This comment has been minimized.

Copy link
Owner

Traumflug commented Jul 28, 2017

1.6 MHz. Wow!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.