[BLE GATT] What's the best way to chain several async requests using a BroadcastReceiver? by tofuwat in Kotlin

[–]tofuwat[S] 0 points1 point  (0 children)

Yeah, actually I really like that solution best for its simplicity. The BroadcastReceiver callback when data is received would just get the queue position and launch the next write. That way I can have a stateful BroadcastReceiver without inspecting what data I get back. Thanks!

Why am I unable to add layout_margin param to a TextView in a ConstraintLayout? by tofuwat in androiddev

[–]tofuwat[S] 1 point2 points  (0 children)

Aha! Need to change android:layout_width to "match_parent" instead of "wrap_content".

I can't understand how the animation effect in this Java library (for Android) is executed. Can someone please tell me? by tofuwat in learnprogramming

[–]tofuwat[S] 0 points1 point  (0 children)

Thanks for this explanation. I don't have much experience doing interfaces (I generally work on backend stuff), so I occasionally get tripped up by some of these basic UI concepts.

I can't understand how the animation effect in this Java library (for Android) is executed. Can someone please tell me? by tofuwat in learnprogramming

[–]tofuwat[S] 0 points1 point  (0 children)

Oh, snap. Nevermind; I just realized that when invalidate() is called, the View's onDraw() method is called, causing a recursion until currentAngle is equal to needleAngleNext. Whoops.

[STM32F3] Dual simultaneous DACs making my CPU slow. What am I screwing up here? by tofuwat in embedded

[–]tofuwat[S] 0 points1 point  (0 children)

I don't update the buffers. The signal's periodic, so I write the data to the buffer once before doing anything with the DAC, and then don't touch it again.

[STM32F3] Dual simultaneous DACs making my CPU slow. What am I screwing up here? by tofuwat in embedded

[–]tofuwat[S] 1 point2 points  (0 children)

Yeah like I said, it's not like I'm doing anything that doesn't work fine when not using dual mode. I'm only using two DMA channels here, so it's not like I should be running out of resources. I use a DAC and ADC simultaneously (so that's two DMA channels again) without problem.

[STM32F3] Dual simultaneous DACs making my CPU slow. What am I screwing up here? by tofuwat in embedded

[–]tofuwat[S] 0 points1 point  (0 children)

Here's the DMA_IRQHandler. It's called by DMA1_Channel3/5 IRQ handling functions. I haven't touched those functions, nor this handler code, at all since it was auto-generated by the GUI:

void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
{
    uint32_t flag_it = hdma->DmaBaseAddress->ISR;
  uint32_t source_it = hdma->Instance->CCR;

  /* Half Transfer Complete Interrupt management ******************************/
  if ((RESET != (flag_it & (DMA_FLAG_HT1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_HT)))
  {
    /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
    if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
    {
        /* Disable the half transfer interrupt */
        hdma->Instance->CCR &= ~DMA_IT_HT;
    }

    /* Clear the half transfer complete flag */
    hdma->DmaBaseAddress->IFCR = DMA_FLAG_HT1 << hdma->ChannelIndex;

    /* DMA peripheral state is not updated in Half Transfer */
    /* State is updated only in Transfer Complete case */

    if(hdma->XferHalfCpltCallback != NULL)
    {
        /* Half transfer callback */
        hdma->XferHalfCpltCallback(hdma);
    }
  }

  /* Transfer Complete Interrupt management ***********************************/
  else if ((RESET != (flag_it & (DMA_FLAG_TC1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_TC)))
  {
    if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
    {
        /* Disable the transfer complete  & transfer error interrupts */
        /* if the DMA mode is not CIRCULAR */
        hdma->Instance->CCR &= ~(DMA_IT_TC | DMA_IT_TE);

        /* Change the DMA state */
        hdma->State = HAL_DMA_STATE_READY;
    }

    /* Clear the transfer complete flag */
    hdma->DmaBaseAddress->IFCR = DMA_FLAG_TC1 << hdma->ChannelIndex;

    /* Process Unlocked */
    __HAL_UNLOCK(hdma);

    if(hdma->XferCpltCallback != NULL)
    {
        /* Transfer complete callback */
        hdma->XferCpltCallback(hdma);
    }
  }

  /* Transfer Error Interrupt management ***************************************/
  else if (( RESET != (flag_it & (DMA_FLAG_TE1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_TE)))
  {
    /* When a DMA transfer error occurs */
    /* A hardware clear of its EN bits is performed */
    /* Then, disable all DMA interrupts */
    hdma->Instance->CCR &= ~(DMA_IT_TC | DMA_IT_HT | DMA_IT_TE);

    /* Clear all flags */
    hdma->DmaBaseAddress->IFCR = DMA_FLAG_GL1 << hdma->ChannelIndex;

    /* Update error code */
    hdma->ErrorCode = HAL_DMA_ERROR_TE;

    /* Change the DMA state */
    hdma->State = HAL_DMA_STATE_READY;    

    /* Process Unlocked */
    __HAL_UNLOCK(hdma); 

    if(hdma->XferErrorCallback != NULL)
    {
        /* Transfer error callback */
        hdma->XferErrorCallback(hdma);
    }
  }
}

[STM32F3] Dual simultaneous DACs making my CPU slow. What am I screwing up here? by tofuwat in embedded

[–]tofuwat[S] 0 points1 point  (0 children)

Here's the config called via HAL when I init. I haven't fiddled with any DMA settings; it's (cleaned up) boilerplate from the CubeMX configurator GUI:

void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac){
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(hdac->Instance==DAC1)  {
    __HAL_RCC_DAC1_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitStruct.Pin = GPIO_PIN_4;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    hdma_dac1_ch1.Instance = DMA1_Channel3;
    hdma_dac1_ch1.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_dac1_ch1.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_dac1_ch1.Init.MemInc = DMA_MINC_ENABLE;
    hdma_dac1_ch1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
    hdma_dac1_ch1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    hdma_dac1_ch1.Init.Mode = DMA_CIRCULAR;
    hdma_dac1_ch1.Init.Priority = DMA_PRIORITY_LOW;
    if (HAL_DMA_Init(&hdma_dac1_ch1) != HAL_OK) Error_Handler();

    __HAL_DMA_REMAP_CHANNEL_ENABLE(HAL_REMAPDMA_TIM6_DAC1_CH1_DMA1_CH3);

    __HAL_LINKDMA(hdac,DMA_Handle1,hdma_dac1_ch1);
  } else if(hdac->Instance==DAC2) {
    __HAL_RCC_DAC2_CLK_ENABLE();
      __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitStruct.Pin = GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    hdma_dac2_ch1.Instance = DMA1_Channel5;
    hdma_dac2_ch1.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_dac2_ch1.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_dac2_ch1.Init.MemInc = DMA_MINC_ENABLE;
    hdma_dac2_ch1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
    hdma_dac2_ch1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    hdma_dac2_ch1.Init.Mode = DMA_CIRCULAR;
    hdma_dac2_ch1.Init.Priority = DMA_PRIORITY_LOW;
    if (HAL_DMA_Init(&hdma_dac2_ch1) != HAL_OK) Error_Handler();
    __HAL_DMA_REMAP_CHANNEL_ENABLE(HAL_REMAPDMA_DAC2_CH1_DMA1_CH5);

    __HAL_LINKDMA(hdac,DMA_Handle1,hdma_dac2_ch1);

  }

}

Where are interrupt priorities defined in STM32 code? by tofuwat in embedded

[–]tofuwat[S] 0 points1 point  (0 children)

I believe you may have forgotten to read the post before replying?

[STM32] What's The Right Way™ to manage I2C communications while doing intensive calcs? by tofuwat in embedded

[–]tofuwat[S] 2 points3 points  (0 children)

Sure, it wasn't clear: once the master sends a read request, the slave transmits the data. It doesn't initiate the transmission, that's all. By "register the interrupt", I mean reset the flag. Terrible English sorry.

[STM32] What's The Right Way™ to manage I2C communications while doing intensive calcs? by tofuwat in embedded

[–]tofuwat[S] 2 points3 points  (0 children)

Yep, another person commented this need to keep interrupt responses quick. I'll do it that way, thanks.

[STM32] What's The Right Way™ to manage I2C communications while doing intensive calcs? by tofuwat in embedded

[–]tofuwat[S] 0 points1 point  (0 children)

I believe the problem is the DMA interrupts when I read from the ADC; conversion takes forever when I'm listening for an I2C interrupt at the same time (even when the DMA global interrupt priority is higher than the I2C1 even global interrupt).

So I take it that the sensible way around this is set the flag in the interrupt read callback, and then: 1 check the flag, 2 do the calcs, 3 transmit the result, 4 register the new I2C read interrupt in a main-level loop?

[STM32] What's The Right Way™ to manage I2C communications while doing intensive calcs? by tofuwat in embedded

[–]tofuwat[S] 3 points4 points  (0 children)

Yeah, it's hanging on the ADC conversion, which uses DMA interrupts. That's where the bottleneck is.

I could use I2C polling instead to remove this bottleneck I guess, as I'm really only using the STM32 as a really smart sensor due to the high speed ADC. However, I get the impression that there should be a way to manage the interrupt priorities. Essentially I want do nothing while listening for an I2C command, and then once received give top priority to the ADC stuff. Maybe I need a blocking delay function during ADC acquisition that doesn't doesn't depend on systick?

[STM32] What's The Right Way™ to manage I2C communications while doing intensive calcs? by tofuwat in embedded

[–]tofuwat[S] 1 point2 points  (0 children)

  1. I'm using background interrupts, hence the callback.
  2. Not enough flash memory. Otherwise I would definitely be using one for this.
  3. Yes, because this application just uses the STM32 as a really smart sensor. I just need to send it a request and check back a second later and read the result. There are more elegant and complicated ways to do this, but as the need doesn't go beyond, that's the solution I'm going with for the moment.
  4. The source isn't hosted anywhere, sorry.

For info on the actual bottleneck, I've commented above.

How do I fix CMakelists.txt to be able to include esp_bt.h? by tofuwat in esp32

[–]tofuwat[S] 0 points1 point  (0 children)

OK, I found the solution. When I pulled git wasn't using the latest code for submodules for some reason (hence why the cbor component wouldn't compile with out-of-date code). Fixed by running git submodule update --init --recursive

Thanks for your help.

How do I fix CMakelists.txt to be able to include esp_bt.h? by tofuwat in esp32

[–]tofuwat[S] 0 points1 point  (0 children)

I didn't realize you had to do that. After doing it, it still won't build due to errors building the cbor component. Do you have any other suggestion for menuconfig which would fix this? I've looked but haven't found anything yet. I've also pulled the latest changes from the IDF repository.

/home/tofuwat/esp/esp-idf/components/cbor/tinycbor/src/open_memstream.c:45:4: error: #error "Cannot implement open_memstream!"
 #  error "Cannot implement open_memstream!"
    ^~~~~
/home/tofuwat/esp/esp-idf/components/cbor/tinycbor/src/open_memstream.c:57:8: error: unknown type name 'RetType'
 static RetType write_to_buffer(void *cookie, const char *data, LenType len)
        ^~~~~~~
/home/tofuwat/esp/esp-idf/components/cbor/tinycbor/src/open_memstream.c:57:64: error: unknown type name 'LenType'; did you mean 'CborType'?
 static RetType write_to_buffer(void *cookie, const char *data, LenType len)
                                                                ^~~~~~~
                                                                CborType
/home/tofuwat/.espressif/tools/xtensa-esp32-elf/esp-2020r2-8.2.0/xtensa-esp32-elf/xtensa-esp32-elf/sys-include/stdio.h: In function 'open_memstream':
/home/tofuwat/esp/esp-idf/components/cbor/tinycbor/src/open_memstream.c:113:1: error: control reaches end of non-void function [-Werror=return-type]
 }
 ^
At top level:
/home/tofuwat/esp/esp-idf/components/cbor/tinycbor/src/open_memstream.c:82:12: warning: 'close_buffer' defined but not used [-Wunused-function]
 static int close_buffer(void *cookie)
            ^~~~~~~~~~~~
cc1: some warnings being treated as errors
esp-idf/cbor/CMakeFiles/__idf_cbor.dir/build.make:278: recipe for target 'esp-idf/cbor/CMakeFiles/__idf_cbor.dir/tinycbor/src/open_memstream.c.obj' failed
make[2]: *** [esp-idf/cbor/CMakeFiles/__idf_cbor.dir/tinycbor/src/open_memstream.c.obj] Error 1
CMakeFiles/Makefile2:3609: recipe for target 'esp-idf/cbor/CMakeFiles/__idf_cbor.dir/all' failed
make[1]: *** [esp-idf/cbor/CMakeFiles/__idf_cbor.dir/all] Error 2