Почему мой драйвер HAL_SPI TransmitReceive-function вытягивает старший SS один байт слишком рано (иногда) - PullRequest
0 голосов
/ 11 февраля 2020

У меня есть два вопроса относительно драйвера HAL_SPI.

  1. Я установил относительно простое приложение, в котором мне нужно отправить блок байтов в полнодуплексном режиме от мастера (ST Nucleo L452RE-P) на экран NF C. (ST NF05A1). Я использовал функцию HAL_SPI_TransmitReceive_IT, чтобы отправлять и получать в одно и то же время с набором SS, основанным на прерываниях, когда передача Tx выполнена. Это прекрасно работает большую часть времени, но когда я хочу отправить 14 байтов (отправить один, и pu sh из 13 от ведомого), Tx-прерывание, кажется, срабатывает по крайней мере на один байт слишком рано, так как показано здесь: 13/14 байтов, отправленных с TxRx-fun c

Когда мне нужно только отправить 6 байтов, или даже если я форсирую 14-й байт, отправив 15 байт, работает нормально: 6/6 байт отправлено с TxRx-fun c 15/15 байт отправлено с TxRx-fun c

Когда я попробуйте отправить 14 байтов с помощью функции HAL_SPI_Transmit_IT, она работает нормально, но тогда я не получаю MISO-пакет c: 14/14 байтов, отправленный с Tx-fun c

Как вы можете видеть на первом рисунке, между отдельными байтами SPI-tx, кажется, есть некоторые паузы - короткий перерыв на полбайта после 4-го байта и более длинный перерыв на 2 байта после 6-го байта , Это кажется довольно постоянным, когда я использую комбинированную функцию TransmitReceive, но не с функцией Transmit, как вы можете видеть на последнем изображении.

Надеюсь, вы поможете мне понять.

main. c

uint8_t spiTxData = 0xFF;

uint8_t *spiTxDataPtr = &spiTxData;

uint8_t spiRxData[64];

uint8_t *spiRxDataPtr = &spiRxData[0];



int main(void){
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */


  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  MX_SPI2_Init();
  /* USER CODE BEGIN 2 */
  intFlags = 0;
  step = 0;
  /* USER CODE END 2 */



  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  printLog("Application loop started. ");

  while (1)
  {

      if ( (intFlags & 0x01 ) == 0x01 )
      {
          HAL_GPIO_TogglePin(NFC_LD1_GPIO_Port, NFC_LD1_Pin);

          HAL_GPIO_WritePin(SPI2_NSS_GPIO_Port, SPI2_NSS_Pin, GPIO_PIN_RESET);  // pull NSS low


          switch (step)
          {
              case 0:
                  spiTxDataPtr = &nfcRead[0];
                  HAL_SPI_TransmitReceive_IT(&hspi2, spiTxDataPtr, spiRxDataPtr, 15);   // SPI_TX | read from regs
                  step += 1;        // inc step for next SPI tx
                  break;
              case 1:
                  spiTxDataPtr = &nfcInit1[0];
                  HAL_SPI_TransmitReceive_IT(&hspi2, spiTxDataPtr, spiRxDataPtr, 6);        // SPI_TX | write to regs
                  step += 1;        // inc step for next SPI tx
                  break;
              case 2:
                  spiTxDataPtr = &nfcRead[0];
                  HAL_SPI_TransmitReceive_IT(&hspi2, spiTxDataPtr, spiRxDataPtr, 14);   // SPI_TX | read from regs
                  step += 1;        // inc step for next SPI tx
                  break;
              case 3:
                  spiTxDataPtr = &nfcInit2;
                  HAL_SPI_TransmitReceive_IT(&hspi2, spiTxDataPtr, spiRxDataPtr, 1);        // SPI_TX | direct command - analog preset
                  step += 1;        // inc step for next SPI tx
                  break;
              case 4:
                  spiTxDataPtr = &nfcRead[0];
                  HAL_SPI_TransmitReceive_IT(&hspi2, spiTxDataPtr, spiRxDataPtr, 14);   // SPI_TX | read from regs
                  step = 0;         // inc step for next SPI tx
                  break;
          }

////////////////////////////////  Working SPI with Tx-func only /////////////////////////////////
//        switch (step)
//                {
//                    case 0:
//                        spiTxDataPtr = &nfcRead[0];
//                        HAL_SPI_Transmit_IT(&hspi2, spiTxDataPtr, 14);    // SPI_TX | read from regs
//                        step += 1;        // inc step for next SPI tx
//                        break;
//                    case 1:
//                        spiTxDataPtr = &nfcInit1[0];
//                        HAL_SPI_Transmit_IT(&hspi2, spiTxDataPtr, 6);     // SPI_TX | write to regs
//                        step += 1;        // inc step for next SPI tx
//                        break;
//                    case 2:
//                        spiTxDataPtr = &nfcRead[0];
//                        HAL_SPI_Transmit_IT(&hspi2, spiTxDataPtr, 14);    // SPI_TX | read from regs
//                        step += 1;        // inc step for next SPI tx
//                        break;
//                    case 3:
//                        spiTxDataPtr = &nfcInit2;
//                        HAL_SPI_Transmit_IT(&hspi2, spiTxDataPtr, 1);     // SPI_TX | direct command - analog preset
//                        step += 1;        // inc step for next SPI tx
//                        break;
//                    case 4:
//                        spiTxDataPtr = &nfcRead[0];
//                        HAL_SPI_Transmit_IT(&hspi2, spiTxDataPtr, 14);    // SPI_TX | read from regs
//                        step = 0;         // inc step for next SPI tx
//                        break;
//                }
//////////////////////////////////////////////////////////////////////////////////////////////////


          intFlags &= ~(1UL << 0);                                              // reset BlueBtn int flag

      } else if ( (intFlags & 0x02) == 0x02 )
      {
          HAL_GPIO_WritePin(SPI2_NSS_GPIO_Port, SPI2_NSS_Pin, GPIO_PIN_SET);    // pull NSS high
          intFlags &= ~(1UL << 1);                                              // reset SPI2 TXE int flag
      }


    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

    static void MX_SPI2_Init(void)
{

  /* USER CODE BEGIN SPI2_Init 0 */

  /* USER CODE END SPI2_Init 0 */

  /* USER CODE BEGIN SPI2_Init 1 */

  /* USER CODE END SPI2_Init 1 */
  /* SPI2 parameter configuration*/
  hspi2.Instance = SPI2;
  hspi2.Init.Mode = SPI_MODE_MASTER;
  hspi2.Init.Direction = SPI_DIRECTION_2LINES;
  hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi2.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi2.Init.NSS = SPI_NSS_SOFT;
  hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
  hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi2.Init.CRCPolynomial = 7;
  hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  hspi2.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
  if (HAL_SPI_Init(&hspi2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SPI2_Init 2 */

  /* USER CODE END SPI2_Init 2 */

}

main.h

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.h
  * @brief          : Header for main.c file.
  *                   This file contains the common defines of the application.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "stm32l4xx_hal.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */

/* USER CODE END ET */

/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
extern volatile int intFlags;
/* USER CODE END EC */

/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */

/* USER CODE END EM */

/* Exported functions prototypes ---------------------------------------------*/
void Error_Handler(void);

/* USER CODE BEGIN EFP */
extern void testFunc(void);
/* USER CODE END EFP */

/* Private defines -----------------------------------------------------------*/
#define B1_Pin GPIO_PIN_13
#define B1_GPIO_Port GPIOC
#define B1_EXTI_IRQn EXTI15_10_IRQn
#define MCO_Pin GPIO_PIN_0
#define MCO_GPIO_Port GPIOH
#define NFC_LD1_Pin GPIO_PIN_1
#define NFC_LD1_GPIO_Port GPIOA
#define USART_TX_Pin GPIO_PIN_2
#define USART_TX_GPIO_Port GPIOA
#define USART_RX_Pin GPIO_PIN_3
#define USART_RX_GPIO_Port GPIOA
#define SMPS_EN_Pin GPIO_PIN_4
#define SMPS_EN_GPIO_Port GPIOA
#define SMPS_V1_Pin GPIO_PIN_5
#define SMPS_V1_GPIO_Port GPIOA
#define SMPS_PG_Pin GPIO_PIN_6
#define SMPS_PG_GPIO_Port GPIOA
#define SMPS_SW_Pin GPIO_PIN_7
#define SMPS_SW_GPIO_Port GPIOA
#define SPI2_NSS_Pin GPIO_PIN_11
#define SPI2_NSS_GPIO_Port GPIOA
#define TMS_Pin GPIO_PIN_13
#define TMS_GPIO_Port GPIOA
#define TCK_Pin GPIO_PIN_14
#define TCK_GPIO_Port GPIOA
#define SWO_Pin GPIO_PIN_3
#define SWO_GPIO_Port GPIOB
/* USER CODE BEGIN Private defines */

/* USER CODE END Private defines */

#ifdef __cplusplus
}
#endif

#endif /* __MAIN_H */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

st25r3911b. h - SPI-массивы

/*
 * st25r3911b.h
 *
 *  Created on: 10. feb. 2020
 *      Author: pwn
 */

#ifndef ST25R3911B_H_
#define ST25R3911B_H_

// Constants for initialization of the NFC-chip
uint8_t nfcInit1[] =
{
        0x00 ,  // write to multiple regs, starting from reg 00
        0x08 ,  // reg 0x00 = 0x08 (default)
        0x80 ,  // reg 0x01 = 0x80 (3,3V supply)
        0x00 ,  // reg 0x02 = 0x00 (default)
        0x00 ,  // reg 0x03 = 0x00 (NFC initiatior & NFCIP-1 active communication)
        0x22    // reg 0x04 = 0x22 (bit rate 424 kbit/s)
};


uint8_t nfcInit2 = 0xCC; // Direct command - analog preset

// Constants for initialization of the NFC-chip
uint8_t nfcAnalogPreset[] =
{
        0x00 ,  // write to multiple regs, starting from reg 00
        0x08 ,  // reg 0x00 = 0x08 (default)
        0x80 ,  // reg 0x01 = 0x80 (3,3V supply)
        0x20 ,  // reg 0x02 = 0x20 (Analog preset vals)
        0x00 ,  // reg 0x03 = 0x00 (NFC initiatior & NFCIP-1 active communication)
        0x22 ,  // reg 0x04 = 0x20 (bit rate 424 kbit/s)
        0x20 ,  // reg 0x05 = 0x20 (Analog preset vals)
        0x00 ,  // reg 0x06 = 0x00 (default)
        0x00 ,  // reg 0x07 = 0x00 (default)
        0x00 ,  // reg 0x08 = 0x00 (default)
        0x34 ,  // reg 0x09 = 0x30 (Analog preset vals)
        0x05 ,  // reg 0x0A = 0x05 (Analog preset vals w. lp = 1200 kHz & FSZ = 12 kHz & TSZ = 200 kHz)
        0x1A ,  // reg 0x0B = 0x1A (default)
        0xDB ,  // reg 0x0C = 0xDB (Analog preset vals)
};


uint8_t nfcRead[64] =
{
        0x40 ,  // read multiple regs, starting from reg 00 (st25r3911b chip contains 0x3F registers in total)
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
        0xFF, 0xFF, 0xFF
};

#endif /* ST25R3911B_H_ */

stm32l4xx_it. c

void SPI2_IRQHandler(void)
{
  /* USER CODE BEGIN SPI2_IRQn 0 */

  /* Check if SPI in mode Transmitter -------------------------------------------------*/
  if (__HAL_SPI_GET_FLAG(&hspi2, SPI_FLAG_TXE))
  {
      intFlags |= 0x02;
  }

  /* USER CODE END SPI2_IRQn 0 */
  HAL_SPI_IRQHandler(&hspi2);
  /* USER CODE BEGIN SPI2_IRQn 1 */

  /* USER CODE END SPI2_IRQn 1 */
}
...