ЭсТиЭм HAL_ брыкается, не понятно почему

Волшебник
Онлайн
Зарегистрирован: 22.12.2016

 Есть хал-овский драйвер, допиливаю до дабл-буффер - эстиэм обленилась в конец , не дописала. Так вот:

HAL_StatusTypeDef dbuff_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint8_t *pData2, uint16_t Size)
{
  HAL_StatusTypeDef errorcode = HAL_OK;
  assert_param(IS_SPI_DMA_HANDLE(hspi->hdmarx));
  __HAL_LOCK(hspi);

  if (hspi->State != HAL_SPI_STATE_READY)
  {
    errorcode = HAL_BUSY;
    goto error;
  }

  if ((pData == NULL) || (Size == 0U))
  {
    errorcode = HAL_ERROR;
    goto error;
  }

  hspi->State       = HAL_SPI_STATE_BUSY_RX;
  hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
  hspi->pRxBuffPtr  = (uint8_t *)pData;
  hspi->RxXferSize  = Size;
  hspi->RxXferCount = Size;
  hspi->RxISR       = NULL;
  hspi->TxISR       = NULL;
  hspi->TxXferSize  = 0U;
  hspi->TxXferCount = 0U;

  CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_LDMARX);
  if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) {
    CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
    }
  else {
    SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
    if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD) {
      CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
      if ((hspi->RxXferCount & 0x1U) == 0x0U) {
        CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_LDMARX);
        hspi->RxXferCount = hspi->RxXferCount >> 1U;
        }
      else {
        SET_BIT(hspi->Instance->CR2, SPI_CR2_LDMARX);
        hspi->RxXferCount = (hspi->RxXferCount >> 1U) + 1U;
        }
      }
    }

    HAL_DMA_RegisterCallback(hspi4.hdmarx,   HAL_DMA_XFER_CPLT_CB_ID, SPI_RxCpltM0);
    HAL_DMA_RegisterCallback(hspi4.hdmarx, HAL_DMA_XFER_M1CPLT_CB_ID, SPI_RxCpltM1);

    __HAL_DMA_DISABLE_IT(hspi4.hdmarx, DMA_IT_HT);  
    __HAL_DMA_DISABLE_IT(hspi4.hdmarx, DMA_IT_TC);  

//  volatile  uint32_t tmpreg = 0U;
//  tmpreg = (uint32_t)&hspi->Instance->DR;

  if (HAL_OK != HAL_DMAEx_MultiBufferStart_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)pData, (uint32_t)pData2, Size))
  {
    SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
    errorcode = HAL_ERROR;

    hspi->State = HAL_SPI_STATE_READY;
    goto error;
  }

  if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) { __HAL_SPI_ENABLE(hspi); }
  __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_ERR));
  SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);

error:
  __HAL_UNLOCK(hspi);
  return errorcode;
}

Вот проблемная часть:
if (HAL_OK != HAL_DMAEx_MultiBufferStart_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)pData, (uint32_t)pData2, Size)) 

как верху написано -всё работает, но если оптимизирую

volatile uint32_t tmpreg = 0U;
tmpreg = (uint32_t)&hspi->Instance->DR;

if (HAL_OK != HAL_DMAEx_MultiBufferStart_IT(hspi->hdmarx, tmpreg, (uint32_t)pData, (uint32_t)pData2, Size))

 то сразу посылает на "гоу ту", стерва.   Чего я не догоняю?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Волшебник, может потому, что переменная tmpreg локальная, а в функцию можно только глобальные класть?

Волшебник
Онлайн
Зарегистрирован: 22.12.2016

Не-а. Вот функция для ЦАП-а:

HAL_StatusTypeDef dual_DAC_Start_DMA(DAC_HandleTypeDef* hdac, uint32_t* pData1,  uint32_t* pData2, uint32_t Length, uint32_t Alignment)
{
  uint32_t tmpreg = 0U;
      
  __HAL_LOCK(hdac);  
    hdac->State = HAL_DAC_STATE_BUSY;

//    hdac->DMA_Handle1->XferCpltCallback     = DAC_DMAConvCpltCh1;
  //  hdac->DMA_Handle1->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh1;
    //hdac->DMA_Handle1->XferErrorCallback    = DAC_DMAErrorCh1;

  //  htim1.hdma[TIM_DMA_ID_UPDATE]->XferCpltCallback     = TransferComplete;
  //  htim1.hdma[TIM_DMA_ID_UPDATE]->XferErrorCallback    = TransferError ;
  //  htim1.hdma[TIM_DMA_ID_UPDATE]->XferHalfCpltCallback = TransferHalfComplete;

    hdac->Instance->CR |= DAC_CR_DMAEN1;
    switch(Alignment)
    {
      case DAC_ALIGN_12B_R:
        tmpreg = (uint32_t)&hdac->Instance->DHR12RD;// DAC_DHR8RD
        break;
      case DAC_ALIGN_12B_L:
        tmpreg = (uint32_t)&hdac->Instance->DHR12LD;
        break;
      case DAC_ALIGN_8B_R:
        tmpreg = (uint32_t)&hdac->Instance->DHR8RD;
        break;
      default:
        break;
    }

    __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR1);
    
//    HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData1, tmpreg, Length);
    HAL_DMAEx_MultiBufferStart_IT(hdac->DMA_Handle1, (uint32_t)pData1, tmpreg, (uint32_t)pData2, Length);
  
  __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_1);  
  __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_2); 
   
  __HAL_UNLOCK(hdac);
  
  return HAL_OK;
}
tmpreg - локальная , и пасуется на ура. Что самое интересное, функция одна и та-же HAL_DMAEx_MultiBufferStart_IT, то есть это не её

ф. бизинес что ей впаривают, ну если тип совпадает 32-беззнак.

Чего то с лабелами и гоу ту, по стилю в эстиэм какие то лошары драйвер на бюйсике писали. Могу и не оптимизировать, или условия на гоу-ту послать и как в цап-е - без кондиционно вызвать и проверки от дурака самому послать на гоу-ту.

Мне просто любопытно, как этот бэйсик-стиль   нтегрирован в С++