0

I am using STM32F407 Discovery Board for interfacing USB OTG FS. I am using CubeMx and Keil for development.

First thing first, I have enabled PC0 - USB_Power(for Discovery Board) and the state is RESET for proper USB running.
I have enabled PA9 - VBUS as GPIO Input.
My System is running at 168MHz.
Have used MAX_SS(Max Sector size) - 4096(This option is available in Cube Mx).
Enabled USB as Host and used FATFS provided by CubeMX.
Enbaled MSC(Mass Storage Class).

CODE:

#include "main.h"
#include "stm32f4xx_hal.h"
#include "fatfs.h"
#include "usb_host.h"

#define GREEN_High          HAL_GPIO_WritePin(GREEN_GPIO_Port,GREEN_Pin,GPIO_PIN_SET)
#define GREEN_Low               HAL_GPIO_WritePin(GREEN_GPIO_Port,GREEN_Pin,GPIO_PIN_RESET)

#define ORANGE_High         HAL_GPIO_WritePin(ORANGE_GPIO_Port,ORANGE_Pin,GPIO_PIN_SET)
#define ORANGE_Low          HAL_GPIO_WritePin(ORANGE_GPIO_Port,ORANGE_Pin,GPIO_PIN_RESET)

extern USBH_HandleTypeDef hUsbHostFS;
extern ApplicationTypeDef Appli_state;
FATFS USBDISKFatFs;
FIL MyFile;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
void MX_USB_HOST_Process(void);

void Green_Blink(uint16_t ms);
void Orange_Blink(uint16_t ms);
void USB_Write_Demo(char* fileName);

int main(void)
{
  HAL_Init();
    SystemClock_Config();
  MX_GPIO_Init();
  MX_USB_HOST_Init();
  MX_FATFS_Init();
    Green_Blink(100);
    Orange_Blink(100);
  while (1)
  {
    MX_USB_HOST_Process();
        if (Appli_state == APPLICATION_START)
        {
            USB_Write_Demo("myCSV.csv");

        }
 *THIS IS THE AREA OF PROBLEM*
//      else if (Appli_state == APPLICATION_IDLE)
//      {
//          GREEN_High;
//          ORANGE_High;
//          HAL_Delay(100);
//          GREEN_Low;
//          ORANGE_Low;
//          HAL_Delay(100);
//      }
  }
}

void USB_Write_Demo(char *fileName)
{
    FRESULT fres;
    uint32_t bytesWritten;
    uint8_t w_text[] = {"Hello, I, AM, STM32, Discovery\r\n"};
    if (f_mount(&USBDISKFatFs,(TCHAR const*)USBHPath,0) != FR_OK)
    {
        Orange_Blink(1000);
        Error_Handler();
    }
    else
    {
        Green_Blink(100);
        if (open_append(&MyFile,fileName) != FR_OK)
        {
            Orange_Blink(100);
            Error_Handler();
        }
        else
        {
            Green_Blink(100);
            fres = f_write(&MyFile,w_text,sizeof(w_text),(void*)bytesWritten);
            if (bytesWritten == 0 || fres != FR_OK)
            {
                Orange_Blink(100);
                Error_Handler();
            }
            else
            {
                f_close(&MyFile);
                Green_Blink(100);
            }
        }
    }
}

void Green_Blink(uint16_t ms)
{
    GREEN_High;
    HAL_Delay(ms);
    GREEN_Low;
    HAL_Delay(ms);
}

void Orange_Blink(uint16_t ms)
{
    ORANGE_High;
    HAL_Delay(ms);
    ORANGE_Low;
    HAL_Delay(ms);
}

So what is happening here is i am creating a CSV file and with every loop i am appending the new data in it. And i am really succesffull in doing so. I have created a really long(500KB not so long) csv file using this particular code.

But i have found an abnormality here which i am not able to understand.

When i add this part to the code, there is no file created and every iteration the control reaches this function.

    else if (Appli_state == APPLICATION_IDLE)
    {
        GREEN_High;
        ORANGE_High;
        HAL_Delay(100);
        GREEN_Low;
        ORANGE_Low;
        HAL_Delay(100);
    }

I am not able to understand how this function is affecting the working code. I am sure that APPLICATION_START and APPLICATION_IDLE are two diffrent things. When i comment this portion of the code, Everything is just fine i can make files as long as my storage doesn't end.

It took me several hours(like 2days) to figure out this is the problem.
I tried to increase Minimum heap size - 0x2000 and Minimum Stack size - 0x4000 (This option is available on linker setting in cubeMx. While generating file the place where you give the project name,location and all there only)

Any suggestions will be helpful as i am out of ideas.

Ehsan Habib
  • 135
  • 1
  • 5
  • 12
  • 1
    Can you remove `HAL_Delay()`s from this snippet and check if the issue persists? – KamilCuk Aug 21 '18 at 12:02
  • yes it's working. but i have to do more work in that section so there will be lot of code and delays. – Ehsan Habib Aug 21 '18 at 12:05
  • and what's the logic behind removing `HAL_Delay()` and the code works but if i place `HAL_Delay()` the code doesn't work?? – Ehsan Habib Aug 21 '18 at 12:08
  • Read about concurrency, parallel programming and all other stuff concerning running two jobs on a single cpu. You cpu needs to service USB request, but at the same time you request it to be stuck for 100 miliseconds. You need to create two threads, one that will service the USB and the other for your task. The function `MX_USB_HOST_Process()` must be called way often than each 100ms. `HAL_Delay` function is just a loop stuck checking systick counter, each 1ms interrupted by systick interrupt to increment the counter – KamilCuk Aug 21 '18 at 12:13
  • okay so what i did now was placing an `HAL_Dealy()` after this call `USB_Write_Demo("myCSV.csv")` and i blinked anothe LED `BLUE` inside else if part and i found that for certain time the `Appli_state equals to APPLICATION_IDLE` and then everything is back to nowmal. – Ehsan Habib Aug 21 '18 at 12:15
  • one last thing. Is there any other way except RTOS.????? – Ehsan Habib Aug 21 '18 at 12:20

2 Answers2

0

I found a way to deal with this problem without using RTOS. As i have never tried RTOS before It was difficult to complete the project in few days.

The idea is simple. It is we need to wait till MX_USB_HOST_Process() doesn't returns Appli_state as Idle.

I dont take the credit.

You can check this LINK

so i added a new function in usb_host.c which retuns Appli_state

uint8_t IsUSB_Busy(void)
{
    return Appli_state;
}

And in main.c i waited till it returns anything but 0. As APPLICATION_IDLE=0

typedef enum {
  APPLICATION_IDLE = 0,
  APPLICATION_START,
  APPLICATION_READY,
  APPLICATION_DISCONNECT
}ApplicationTypeDef;

Added this bit of code in main file and everything is working as expected

while (!IsUSB_Busy())
{
    MX_USB_HOST_Process();
}

I hope someone finds it helpful.

And Thanks for your help.

Ehsan Habib
  • 135
  • 1
  • 5
  • 12
-1

You can create two Tasks (FreeRTOS) with CubeMX, separate the USB stuff from the LED stuff. taskLED() and taskUSB()

duchonic
  • 8
  • 5