1
\$\begingroup\$

I am very new to STM32s. I have been trying to interface a sensor using an STM32F401RE Nucleo board but failing to receive sensor data from the board. I generate 3 clock signals to drive the sensor. I have programmed the board via CubeIDE and the program flashes onto the board without any problems. I confirmed (using a logic analyzer) that the code is generating the correct signals. I have the following configuration regarding connectivity:

  • RCC -> HSE -> Crystal/Ceramic Resonator
  • Connectivity -> USB_OTG_FS -> Device_Only
  • Middleware -> USB_DEVICE -> Communication Device Class (Virtual Port Com)
  • Clock Configuration -> 84 MHz

This video tutorial that I have been following has the same configuration. In fact, I have replicated each and every setting to match what the video shows. Basically there is a master clock signal, and two other signals which are interdependent. One of the interdependent signals triggers the internal ADC to read the sensor output via DMA (4th internal signal). Then the output of the ADC is programmed to be sent over USB to the host computer. When the person in the video opens a serial port reader (CoolTerm), he begins to see data showing up in the console without configuring anything (just pushes start). When I tried doing the same thing, using the same serial port reader, I don't see anything showing up in the console. I confirmed that I am using the right port. I tried varying the Baud Rates as well but no luck, not even garbage values. On a hardware level (as I mentioned earlier) I know that the signals are being generated. I am also able to detect and measure the output of the sensor using the Logic Analyzer. The only issue is not being able to get that data onto my computer.

I have been at this for weeks and cannot figure out why I cannot receive any data. I have initialized the components in the right order (DMA before the ADC). I have the right code in place, but unable to receive the output over USB.

I am used to developing on Arduino and Espressif boards so I was expecting something like a serial monitor to debug the board but apparently things are not so simple on STM.

Here is how I have declared the Buffer variable for holding the ADC data:

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

#define CCDBuffer 6000
volatile uint16_t CCDPixelBuffer[CCDBuffer];

/* USER CODE END 0 */

Here is how I have initialized and configured the Timers and ADC:

/* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_TIM3_Init();
  MX_TIM4_Init();
  MX_TIM2_Init();
  MX_TIM5_Init();
  MX_ADC1_Init();
  MX_USB_DEVICE_Init();

  /* USER CODE BEGIN 2 */

  HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);     // ICG Signal   PA0
  __HAL_TIM_SET_COUNTER(&htim2, 66);
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);     // fM Signal    PA6
  HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_4);     // ADC Internal Signal
  HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_2);     // SH Signal    PA1

  /* USER CODE END 2 */

Here is how I am sending the ADC data over USB:

/* Infinite loop */
  /* USER CODE BEGIN WHILE */

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

      HAL_ADC_Start_DMA(&hadc1, (uint32_t*) CCDPixelBuffer, CCDBuffer);

  }
  /* USER CODE END 3 */

Here is the function definition for sending the ADC data over USB:

/* USER CODE BEGIN 4 */

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {
    CDC_Transmit_FS((uint8_t*) CCDPixelBuffer, CCDBuffer);
}

/* USER CODE END 4 */

Here is a screenshot of the Clock Configuration tab: enter image description here

Here is a screenshot of the Pinout & Configuration tab: enter image description here

I would be so grateful if anyone can please provide any insight as to why I am unable to receive data over USB from this Nucleo board. Thanks in advance for taking the time to read through.

\$\endgroup\$
10
  • 1
    \$\begingroup\$ Do you actually have a USB connection? The standard Mini-USB port on the Nucleo does not have a direct connection to the target controller. You can use it as a virtual COM port (you have to use a UART peripheral for that) but not as a OTG connection. And a link to the tutorial might be helpful to skim over it to see any obvious traps. \$\endgroup\$
    – Arsenal
    Aug 16, 2022 at 8:50
  • \$\begingroup\$ Thanks for your response @Arsenal. Here is the link to the author's blog: curiousscientist.tech/blog/tcd1304-linear-ccd-driving-the-ccd \$\endgroup\$
    – Harit
    Aug 16, 2022 at 9:10
  • 1
    \$\begingroup\$ Which uses a completely different board... \$\endgroup\$
    – Arsenal
    Aug 16, 2022 at 9:43
  • 1
    \$\begingroup\$ You can use the ST-Link portion of the Nucleo board to program and debug the BlackPill. There is a description in the Nucleo user manual on how to get that to work. \$\endgroup\$
    – Arsenal
    Aug 16, 2022 at 10:04
  • 1
    \$\begingroup\$ Using CubeIDE there is also a configuration for the Rx and Tx buffer: CDC Buffer Sizes. Not sure what about the default values for new projects... Does your setup fit with #define CCDBuffer 6000 ? \$\endgroup\$
    – Mo E
    Aug 16, 2022 at 22:33

1 Answer 1

1
\$\begingroup\$

You see to want to use USB protocol on the target F401 MCU. Currently you have no USB connection from the target F401 MCU to your PC, so none of the ports you can open is correct.

The USB connector is for the ST-Link programming interface and virtual COM port it provides to F401 UART. It is not connected to the USB pins on the target F401.

If you need to have USB connectivity to F401, you need to connect to the USB pins of F401 yourself.

If you just want to transfer data via the existing USB connector, use the F401 UART that is available through the on the VCP provided by the ST-Link USB interface.

\$\endgroup\$
10
  • \$\begingroup\$ Thanks for the insight! I have an FTDI external usb programmer. Would that be useful if I need to connect the pins myself? If so, do you have any idea how to determine which pins to use? I will modify my question to include a screenshot of the pinout window from CubeIDE as well. \$\endgroup\$
    – Harit
    Aug 16, 2022 at 9:12
  • \$\begingroup\$ No it is not useful because I don't know what you mean by "FTDI external usb programmer" and you need to connect PC USB pins directly to your target STM32 pins if it is even possible. You can of course look at CubeIDE to see which pins you configured for USB, but in the end you must read the board user manual to find the pins and see if they are free to use. \$\endgroup\$
    – Justme
    Aug 16, 2022 at 9:22
  • \$\begingroup\$ Here is what I mean by FTDI external usb programmer: eckstein-shop.de/media/image/product/364/lg/… \$\endgroup\$
    – Harit
    Aug 16, 2022 at 10:01
  • 1
    \$\begingroup\$ STM32 chips have a factory bootloader which supports UART so you can program it using FTDI UART. And I already said in my answer that the F401 has USB pins but there is no USB connector for it. If you want to use USB then connect those pins to your PC. If you just want to use USB UART then send over the ST-Link VCP or use your FTDI cable with UART. \$\endgroup\$
    – Justme
    Aug 17, 2022 at 4:18
  • 1
    \$\begingroup\$ Well the ST-Link onboard is connected by default in hardware to certain pins so those pins may be unusable for ADC unless you disconnect them, so configure your pins according to the already built Nucleo hardware. \$\endgroup\$
    – Justme
    Aug 23, 2022 at 15:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.