USB Host, what solution?

Post here first, or if you can't find a relevant section!
User avatar
Bakisha
Posts: 139
Joined: Fri Dec 20, 2019 6:50 pm
Answers: 5
Contact:

Re: USB Host, what solution?

Post by Bakisha »

If you have logic analyzer, you could toggle pin before and after MX_USB_HOST_Process() function and see timing of it. I don't know if USBH_HID_EventCallback is interrupt driven.
I tried to mess around with sketch from viewtopic.php?f=7&t=197 , by adding HID support, but no luck (it would compile, but i have no idea why it isn't working)
I don't know how Amiga is reading mouse. Dedicated chip (CIA or something) or some other 1MHz counter TTL logic chip?
feluga
Posts: 64
Joined: Wed Mar 18, 2020 2:50 am

Re: USB Host, what solution?

Post by feluga »

BennehBoy wrote: Mon Apr 19, 2021 9:00 pm To get the quadrature signal output to emulate the amiga mouse requires a 150us duration for each pulse, I've tried to implement this with a timer ...
Does anyone have any tips?
About the 150us duration, I understood that this is the minimum time necessary for Amiga to pick up changes on the quadrature.
I think you could use a "timestamp" design such as this (just a general idea):

Code: Select all

uint32_t lastTimeStamp = 0;
loop:
  if (getMicros() > lastTimeStamp) {
    lastTimeStamp = getMicros() + 150;
    read_and_treat_USB_Report();
    setAmigaPins_basedOnUSBReport();
  }
This way you will comply to the 150us just using a loop.
BennehBoy
Posts: 135
Joined: Sat Jan 04, 2020 2:38 am
Answers: 1

Re: USB Host, what solution?

Post by BennehBoy »

Hi yeah, there is no micros in cube, that's an Arduino thing, which is why I'm using the timer - I would much have preferred to use a state machine approach as it's non blocking unlike the current code which just waits for a timer to hit 150. Code link here -> https://github.com/BennehBoy/F401_AMIGA_HID

But anyhow, I've been messing with the debugger and the MC isn't locked up, it's happily running the main loop. Just the eventhandler ceases to work when the timer is enabled.
feluga
Posts: 64
Joined: Wed Mar 18, 2020 2:50 am

Re: USB Host, what solution?

Post by feluga »

It shoud use HAL in Cube.

Try this, as it works with STM32F4, but not for the STM32F103:

Code: Select all

const uint32_t cyclesPerMicroSecond = HAL_RCC_GetHCLKFreq() / 1000000;
uint32_t micros = DWT->CYCCNT / cyclesPerMicroSecond;
This code provides a delay in microseconds using HAL:

Code: Select all

/**
 * @brief This function provides a delay (in microseconds)
 * @param microseconds: delay in microseconds
 */
__STATIC_INLINE void DWT_Delay_us(volatile uint32_t microseconds) {
 uint32_t clk_cycle_start = DWT->CYCCNT;
 /* Go to number of cycles for system */
 microseconds *= (HAL_RCC_GetHCLKFreq() / 1000000);
 /* Delay till end */
 while ((DWT->CYCCNT - clk_cycle_start) < microseconds);
}
Reference: https://community.st.com/s/question/0D5 ... elay-in-us
BennehBoy
Posts: 135
Joined: Sat Jan 04, 2020 2:38 am
Answers: 1

Re: USB Host, what solution?

Post by BennehBoy »

Thanks, I'll give that a try.
mlundin
Posts: 94
Joined: Wed Nov 04, 2020 1:20 pm
Answers: 6
Location: Sweden

Re: USB Host, what solution?

Post by mlundin »

I would try something like a single shot pwm pulse with 150us width, then you can set the interrupts at the end of this pulse if needed
feluga
Posts: 64
Joined: Wed Mar 18, 2020 2:50 am

Re: USB Host, what solution?

Post by feluga »

I think that running the USB Host processing may take something close to 150us ... 150us in a 84MHz-100Mhz MCU means only 12,600-15,000 CPU cycles.

Using Timer/PWM IRQ may compete with USB Host processing, causing some issues for the data it gets or for USB Host timing.
That must be correctly managed in the code.
BennehBoy
Posts: 135
Joined: Sat Jan 04, 2020 2:38 am
Answers: 1

Re: USB Host, what solution?

Post by BennehBoy »

I'm not so sure the timer was the problem now, I've just worked backwards and can no longer get my code to display the mouse input - something is amiss.... I must've done something stupid somewhere.

Programmed blinky on with CDC, connecting to USB port on computer, there's no life from the board - so it looks like some magic smoke has been emitted somewhere. Powers fine from the SWD pins. No wonder USB isn't working :lol: :lol:
BennehBoy
Posts: 135
Joined: Sat Jan 04, 2020 2:38 am
Answers: 1

Re: USB Host, what solution?

Post by BennehBoy »

Luckily I always buy these in multiples, so have another board up and running now.

Unfortunately the DWT code also results in no USB processing. It doesn't matter how short the delay is. The debugger seems to show the MC stuck in the while loop of the delay function. I'll double check my implementation as I'm not convinced I've done it right.

EDIT, figured this out now, the function you pasted relies on some init work having been done against DWT. I'll come back to it tomorrow.
feluga
Posts: 64
Joined: Wed Mar 18, 2020 2:50 am

Re: USB Host, what solution?

Post by feluga »

Yes, there is an initialization function uint32_t DWT_Delay_Init(void).
The whole code suggested is as follow:

dwt_stm32_delay.h

Code: Select all

#ifndef DWT_STM32_DELAY_H
#define DWT_STM32_DELAY_H
#ifdef __cplusplus
extern 'C' {
#endif
 
#include 'stm32f4xx_hal.h'
/**
 * @brief Initializes DWT_Cycle_Count for DWT_Delay_us function
 * @return Error DWT counter
 * 1: DWT counter Error
 * 0: DWT counter works
 */
uint32_t DWT_Delay_Init(void);
 
/**
 * @brief This function provides a delay (in microseconds)
 * @param microseconds: delay in microseconds
 */
__STATIC_INLINE void DWT_Delay_us(volatile uint32_t microseconds)
{
 uint32_t clk_cycle_start = DWT->CYCCNT;
 /* Go to number of cycles for system */
 microseconds *= (HAL_RCC_GetHCLKFreq() / 1000000);
 /* Delay till end */
 while ((DWT->CYCCNT - clk_cycle_start) < microseconds);
}
 
#ifdef __cplusplus
}
#endif
#endif
dwt_stm32_delay.c

Code: Select all

    #include 'dwt_stm32_delay.h'
     
    /**
     * @brief Initializes DWT_Clock_Cycle_Count for DWT_Delay_us function
     * @return Error DWT counter
     * 1: clock cycle counter not started
     * 0: clock cycle counter works
     */
    uint32_t DWT_Delay_Init(void) {
     /* Disable TRC */
     CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk; // ~0x01000000;
     /* Enable TRC */
     CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; // 0x01000000;
     /* Disable clock cycle counter */
     DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk; //~0x00000001;
     /* Enable clock cycle counter */
     DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; //0x00000001;
     /* Reset the clock cycle counter value */
     DWT->CYCCNT = 0;
    /* 3 NO OPERATION instructions */
    __ASM volatile ('NOP');
    __ASM volatile ('NOP');
     __ASM volatile ('NOP');
     /* Check if clock cycle counter has started */
    if(DWT->CYCCNT)
    {
     return 0; /*clock cycle counter started*/
    }
    else
     {
     return 1; /*clock cycle counter not started*/
     }
    }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
main.c

Code: Select all

    /* Includes ------------------------------------------------------------------*/
    #include 'stm32f4xx_hal.h'
    #include 'dwt_stm32_delay.h'
    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();
     /* Configure the system clock */
     SystemClock_Config();
     /* Initialize all configured peripherals */
     MX_GPIO_Init();
     /* USER CODE BEGIN 2 */
     if(DWT_Delay_Init())
     {
     Error_Handler(); /* Call Error Handler */
     }
     while(1)
     {
     /* 10s Delay */
     DWT_Delay_us(10000000);
     HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
     }
    }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
Post Reply

Return to “General discussion”