Datos de regulación de la conexión serie USB en el microcontrolador STM32 (control de flujo)

Acabo de integrar el código del ejemplo de puerto COM virtual USB STM32 de ST ( stm32_usb-fs-device_lib.zip desde aquí ) con mi proyecto para que el STM32 aparezca como un puerto serie virtual.

Sin embargo, el ejemplo de código limita los datos que recibe al tener la función de devolución de llamada EP3_OUT_Callback bloqueada (en una interrupción) hasta que se traten todos los datos. El comentario exacto en el código es "Los datos USB se procesarán de inmediato, esto permitirá que el próximo tráfico USB se desnude hasta el final de USART Xfer"

En mi proyecto, necesito procesar los datos que se han recibido en el bucle principal (fuera de una interrupción), por lo que necesito una forma de acelerar los datos que recibo de USB sin bloquear en EP3_OUT_Callback.

Lo que me gustaría es una función:

Do_Not_Call_EP3_OUT_Callback_Right_Now(bool yes_or_no);
Cuanto más miro esto, más creo que la respuesta podría ser llamar a SetEPRxStatus (ENDP3, EP_RX_?) y luego establecerlo en EP_RX_VALID en el bucle principal cuando se procesan todos los datos. Sin embargo, no puedo hacer que esto funcione, por lo que agradecería cualquier aporte (o ejemplos donde se haga esto).

Respuestas (2)

Parece que tengo esto funcionando:

void EP3_OUT_Callback(void) {
 ...
  //SetEPRxValid(ENDP3); //<-- Commented out
  SetEPRxStatus(ENDP3, Do_I_Have_Room_For_More_Data() ? EP_RX_VALID : EP_RX_NAK); //<-- Added this
}

void SOF_Callback(void) {
  if(bDeviceState == CONFIGURED) {
    SetEPRxStatus(ENDP3, Do_I_Have_Room_For_More_Data() ? EP_RX_VALID : EP_RX_NAK); //<-- Added this
    ...
    // Original TX code here
  }
}

Lo que sucede es que después de obtener los datos, y en la devolución de llamada de inicio del marco (cada 1 ms), establezco si el punto final acepta datos.

Nota: Los documentos nunca parecen decir cuántos datos leerá USB_SIL_Read, lo que podría conducir a una saturación del búfer. Sin embargo, creo que el máximo es lo que está en VIRTUAL_COM_PORT_DATA_SIZE, y esto parece funcionar muy bien para mí.

Esto parece funcionar; sin embargo, no tengo idea de si es la forma "correcta" de hacerlo. Por favor, avíseme si está mal y lo actualizaré.

Solo para agregar, parece que Windows desechará paquetes de datos después de algunos (¿5?) NAK consecutivos, lo que hace que esto funcione la mayor parte del tiempo, pero no cuando el micro está ocupado por un período de tiempo prolongado.

Debería poder hacer esto configurando un indicador atómico en el ISR de que los datos están disponibles, detectando eso en el bucle principal para tratarlo y luego enviando el acuse de recibo desde allí, o configurando un indicador para que sea acusado. la próxima oportunidad

¿Tienes algún ejemplo? El bucle principal sabe que los datos están ahí. El problema es que el ISR (o al menos EP3_OUT_Callback) no parece ACK explícitamente. Solo el hecho de que se llame a EP3_OUT_Callback es un ACK explícito, y para entonces ya es demasiado tarde.
que el último 'explícito' debería ser 'implícito'. Tengo la sensación de que el STM32 tiene algún hardware que maneja el USB, por lo que puede ser una cuestión de decir si enviar ACK o no, en lugar de enviarlos explícitamente desde el código.