mcci-catena / arduino-lmic

LoraWAN-MAC-in-C library, adapted to run under the Arduino environment
https://forum.mcci.io/c/device-software/arduino-lmic/
MIT License
633 stars 209 forks source link

Arduino_Core_STM32 - Support #538

Open ricaun opened 4 years ago

ricaun commented 4 years ago

Is your feature request related to a problem? Please describe.

I'm trying to use lmic with Arduino_Core_STM32 and sometimes the board stop working and I figure out whats the problem.

The main problem is how noInterrupt() works. https://github.com/stm32duino/Arduino_Core_STM32/issues/934

If the interrupt is disabled the delay and micros do not work as it should be. This behavior breaks the hal_waitUntil function.

https://github.com/mcci-catena/arduino-lmic/blob/f67121c931c591b88602b024b289f6d4ec7159b7/src/hal/hal.cpp#L288

This assumption does not apply to the Arduino_Core_STM32 platform, without interrupt the tick turns off.

Describe the solution you'd like

The best solution should be using the rtc of the stm32, but I don't know to do that, need to study...

Describe alternatives you've considered A kind of solution if removing the noInterrupt to and the code works without block the board.

https://github.com/mcci-catena/arduino-lmic/blob/f67121c931c591b88602b024b289f6d4ec7159b7/src/hal/hal.cpp#L314

This should make the code works.


Arduino_Core_STM32 version 1.8.0 arduino-lmic version 3.1.0

terrillmoore commented 4 years ago

Please see #523 and related bugs. Removing noInterrupts() is not a solution in this case; the problem is that the radio driver uses noInterrupts(). [The MCCI version of the STM32 BSP works correctly, but as you point out, this is not generally true. When we fixed this in our version, we observed that the LMIC needed this but didn't understand that the root cause is the os_radio() routine. Now that I understand this, the solution is to adopt normal RTOS design so that we avoid or eliminate interrupt system manipulation.]

ricaun commented 4 years ago

Hello,

I was looking at you Arduino_Core_STM32 repo and the original Arduino_Core_STM32 and trying to understand why your repo works with the stm32. I found this: override_hal_gettick.c

If I add this code on the example the code does not break.

uint32_t HAL_GetTick(void)
{
  extern __IO uint32_t uwTick;

  /* Read PRIMASK register, check interrupt status before disable them */
  /* Returns 0 if they are enabled, or non-zero if disabled */
  if (__get_PRIMASK())
  {
    if (SCB->ICSR & SCB_ICSR_PENDSTSET_Msk)
    {
      SCB->ICSR = SCB_ICSR_PENDSTCLR_Msk;
      HAL_IncTick();
    }
  }

  return uwTick;
}

This is a better solution than removing the noInterrupts();.

Another thing I noticed is your delayMicroseconds function does is really different. The original uses the dwt_getCycles() to create a great delayMicroseconds.

Another thing I noticed is your delayMicroseconds function does is really different. The original uses the dwt_getCycles() to create a great delayMicroseconds.

  int32_t start  = dwt_getCycles();
  int32_t cycles = us * (SystemCoreClock / 1000000);
  while ((int32_t)dwt_getCycles() - start < cycles);

Maybe that's why are you using this.

https://github.com/mcci-catena/arduino-lmic/blob/4eb195edd82db6968ae4dd66a814421e6a6d93aa/src/hal/hal.cpp#L286-L298

See yaa!

(I close the issue by mistake)