Question

Je travaille avec le microcontrôleur NXP LPC1788 pour le moment, et j'essaie de la configurer pour communiquer avec un PC Windows 7 à l'aide de USB. J'ai une expérience limitée avec USB (j'ai commencé à apprendre le protocole au début de cette semaine), mais j'ai travaillé avec le LPC1788 depuis un certain temps et avez l'expérience d'autres protocoles de communication (Can, I2C, SSP).

Je veux configurer mon microcontrôleur pour agir en tant que périphérique et pour que le PC agisse comme hôte. Je soupçonne que je devrai configurer le microcontrôleur pour communiquer à l'aide de transferts d'interruption complète. De plus, j'aurai probablement besoin de créer mon propre pilote USB spécifique au fournisseur pour le PC ultérieurement - je ne l'ai pas encore fait, et mes descripteurs ne sont pas correctement configurés.

Mon problème spécifique est que lorsque j'exécute mon programme et initialiser / activer le périphérique USB du microcontroller, je ne reçois que deux interruptions USB. Les valeurs d'état d'interruption de périphérique (DevinTRT) dans chaque cas sont les suivantes:

0x19 - (FRAME, DEVSTAT, and CCEMPTY interrupts)
0x1  - (FRAME interrupt)

Dans le cas de la réception de l'interruption DEVSTAT, j'ai lu la valeur suivante à partir du moteur d'interface série à l'aide d'une commande d'état de périphérique GET:

0x19 - (CON (connected), SUS_CH (suspend state change), and RST (bus reset))

Utilisation de USBYZER, je n'obtient que les quatre paquets suivants: http://i.imgur.com/wrk7rbv .png .

Je m'attends à ce que même sans descripteurs correctement configurés ou un pilote correspondant sur la partie PC, je devrais toujours recevoir plus que cela. J'aurais censé recevoir une demande d'obtention d'une descripteur dans le point final 0.

Ma fonction principale n'initialise que mon appareil USB et boucles indéfiniment.

Le code d'initialisation USB est indiqué ci-dessous:

void USBInit()
{
  // Turn on power and clock
  CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCUSB, ENABLE);

  // PLL0 clock is 96 MHz, usbclk should be 48 MHz.
  LPC_SC->USBCLKSEL = 0x102;

  // Configure USB pins.
  PINSEL_ConfigPin(0, 29, 1); // USB_D+1
  PINSEL_ConfigPin(0, 30, 1); // USB_D-1
  PINSEL_ConfigPin(1, 18, 1); // USB_UP_LED1
  PINSEL_ConfigPin(2,  9, 1); // USB_CONNECT1
  PINSEL_ConfigPin(1, 30, 2); // USB_VBUS 
  //PINSEL_ConfigPin(1, 19, 2); // USB_PPWR1

  PINSEL_SetPinMode(1, 30, PINSEL_BASICMODE_PLAINOUT);

  // Set DEV_CLK_EN and AHB_CLK_EN.
  LPC_USB->USBClkCtrl |= 0x12;

  // Wait until change is reflected in clock status register.
  while((LPC_USB->USBClkSt & 0x12) != 0x12);

  // Select USB port 1.
  LPC_USB->USBClkCtrl |= 0x8;
  while((LPC_USB->USBClkSt & 0x8) == 0);
  LPC_USB->StCtrl &= ~0x3;
  LPC_USB->USBClkCtrl &= ~0x8;

  // Reset the USB.
  USBReset();

  // Configure interrupt mode.
  writeSIECommandData(CMD_SET_MODE, 0);

  // Enable NVIC USB interrupts.
  NVIC_EnableIRQ(USB_IRQn);

  // Set device address to 0x0 and enable device & connection.
  USBSetAddress(0);
  USBSetConnection(TRUE);

  //printf("USB initialised\n");
  //printf("EpIntEn: 0x%x\n", LPC_USB->EpIntEn);

  // No errors here (SIE Error code: 0x0).
  USBPrintErrCode();

  // Packet sequence violation here (SIE Error code: 0x11).
  USBPrintErrCode();
}

La fonction de réinitialisation USB:

void USBReset()
{
  LPC_USB->EpInd = 0;
  LPC_USB->MaxPSize = USB_MAX_PACKET_SIZE;
  LPC_USB->EpInd = 1;
  LPC_USB->MaxPSize = USB_MAX_PACKET_SIZE;
  while ((LPC_USB->DevIntSt & EP_RLZED_INT) == 0);

  LPC_USB->EpIntClr  = 0xFFFFFFFF;
  LPC_USB->EpIntEn   = 0xFFFFFFFF;
  LPC_USB->DevIntClr = 0xFFFFFFFF;
  LPC_USB->DevIntEn  = DEV_STAT_INT | EP_SLOW_INT | EP_FAST_INT;
}

La fonction d'adresse de réglage USB:

void USBSetAddress(uint32_t addr)
{
  writeSIECommandData(CMD_SET_ADDR, DAT_WR_BYTE(DEV_EN | addr));
  writeSIECommandData(CMD_SET_ADDR, DAT_WR_BYTE(DEV_EN | addr));
}

La fonction de connexion USB Set:

void USBSetConnection(uint32_t connect)
{
  writeSIECommandData(CMD_SET_DEV_STAT, DAT_WR_BYTE(connect ? DEV_CON : 0));
}

La routine de service d'interruption USB:

void USB_IRQHandler(void)
{
  uint32_t data;
  uint32_t interruptData = LPC_USB->DevIntSt;

  printf("InterruptData: 0x%x\n", interruptData);

  // Handle device status interrupt (reset, connection change, suspend/resume).
  if(interruptData & DEV_STAT_INT)
  {
    LPC_USB->DevIntClr = DEV_STAT_INT;
    writeSIECommand(CMD_GET_DEV_STAT);
    data = readSIECommandData(DAT_GET_DEV_STAT);
    printf("Data: 0x%x\n", data);

    // Device reset.
    if(data & DEV_RST)
    {
      USBReset();
      USBResetCore();
      printf("USB Reset\n");
    }

    // Connection change.
    if(data & DEV_CON_CH)
    {
      printf("Connection change\n");
      /* Pass */
    }

    // Suspend/resume.
    if(data & DEV_SUS_CH)
    {
      if(data & DEV_SUS)
      {
        printf("USB Suspend\n");
        USBSuspend();
      }
      else
      {
        printf("USB Resume\n");
        USBResume();
      }
    }

    return;
  }

  // Handle endpoint interrupt.
  if(interruptData & EP_SLOW_INT)
  {
    printf("Endpoint interrupt\n");
  }

  if(interruptData & EP_FAST_INT)
  {
    printf("Endpoint interrupt\n");
  }
}

La sortie du terminal:

InterruptData: 0x19
Data: 0x19
USB Reset
USB Resume
InterruptData: 0x1

Edit: Utilisation de la commande de code d'erreur d'erreur SIE, j'ai trouvé que je vous retrouve avec une erreur "Packet inattendu" d'ici la fin de la fonction d'initialisation USB. Cependant, si je lisais le registre de test, je récupère 0xA50F comme prévu, ce qui signifie que ma communication avec le SIE fonctionne et que mes horloges USB / AHB sont probablement configurées correctement et fonctionnant.

Était-ce utile?

La solution

J'ai réussi à obtenir un exemple de projet USB travaillant dans Workbench Embedded iar.Sur la base de cela, j'ai fait deux changements qui ont principalement corrigé mon programme:

  • J'ai changé la configuration de mon projet de "Semihosted" à "SWO" qui a rendu mon impression beaucoup plus rapidement.

  • J'ai supprimé la ligne suivante.Apparemment mal configuré le taux d'horloge USB.

    LPC_SC->USBCLKSEL = 0x102;
    

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top