Forum: FPGA, VHDL & Co. Lattice Mico32 GPIO Interrupt programmieren


von Simon D. (simon86)


Lesenswert?

Hallo!

Habe in meinen FPGA einen Lattice Mico32 Soft Core mit einer GPIO (1 
Bit) namens "INT" und einer GPIO (8 Bit) namens "LED". Beim 
Konfigurieren der GPIO INT habe ich "Interrupt INT0 bei positiver Flanke 
auslösen" gewählt.

Ich habe nun Probleme, die ISR zu programmieren. Ich möchte zuerst 
einmal alle Interrupts zulassen -> MicoEnableInterrupts(0xFFFF) und dann 
mit MicoRegisterISR die ISR_INT0(){} mit der GPIO INT verbinden...

kennt sich jemand damit aus? Leider findet man nirgendwo ein 
Beispielprogramm....

von Rick Dangerus (Gast)


Lesenswert?

Schau mal bei soc-lm32 rein. Da gibt es in spike_hw.h ein Beispiel für 
eine Timer-ISR, die bei mir funktioniert.

Rick

von Simon D. (simon86)


Lesenswert?

wo / was ist soc - lm32? Das soc Verzeichnis ist in jedem SoftCore 
Projektordner... oder meinst du ein Verzeichnis im MSB 
Installationsordner?

Ein Beispiel für den Timer Interrupt habe ich, ein Übertragen des Codes 
auf einen GPIO Interrupt hat jedoch nicht funktioniert. Deswegen 
bräuchte ich ein Beispiel speziell für eine GPIO...

von Simon D. (simon86)


Lesenswert?

Hallo! Habe die Lösung gerade vom Lattice Support bekommen

#include "DDStructs.h"
#include "LookupServices.h"
#include "stdio.h"
#include "MicoUtils.h"
#include "MicoGPIO.h"

static void myISR( int intrLevel, void * data )
{
  static int capValue ;
  MicoGPIOCtx_t * my_buttons   = (MicoGPIOCtx_t *) data ;
  MICO_GPIO_READ_EDGE_CAPTURE(my_buttons,capValue) ;
  //printf("printed by ISR, capValue=%x\r\n",capValue);
  MICO_GPIO_WRITE_IRQ_MASK(my_buttons,0x00000000);

  // ------------------

  MICO_GPIO_WRITE_IRQ_MASK(my_buttons,0xffffffff);
  return ;
}

int main(void)
{
  unsigned int iValue = 0x1, iKeyStatus;

  MicoGPIOCtx_t *leds   = (MicoGPIOCtx_t *)MicoGetDevice("LED");
  MicoGPIOCtx_t *buttons = (MicoGPIOCtx_t *)MicoGetDevice("Button");

    MicoRegisterISR(buttons->intrLevel, buttons, myISR);
  MICO_GPIO_WRITE_IRQ_MASK(buttons,0xffffffff);

  while(1){
    *((volatile unsigned int *)(leds->base)) = ~iValue;
    MicoSleepMilliSecs(200);
    iValue = iValue << 1;
    if(iValue == 0x100){
      iValue = 0x1;
    }
    MICO_GPIO_READ_DATA(buttons,iKeyStatus) ;
    //printf("printed by main look-up service, 
iKeyStatus=%x\r\n",iKeyStatus);
  }
  return(0);
}

von WpMD (Gast)


Lesenswert?

Hallo!

Ich greife dieses Thema nochmal auf da ich versuche im lm32 einen 
Interrupt über einen GPIO zu realisieren. Ich bin dabei erstmal nach der 
Vorlage von Simon vorgegangen.
Der Sprung in die Interruptfunktion funktioniert auch gut, danach stehe 
ich aber vor einem Problem. Die Interruptfunktion wird ständig 
ausgeführt. Er springt also nach Ablauf der Funktion nicht zurück ins 
main Programm.


static void USB_ISR(unsigned int intrLevel, void *data)
{
  int USB_Daten;
  MICO_GPIO_READ_DATA( USB_Data, USB_Daten);
  return;
}

int main( void )
{
  MicoGPIOCtx_t *USB_Data = (MicoGPIOCtx_t *)MicoGetDevice("USB_Data");
  MicoGPIOCtx_t *USB_Interrupt = (MicoGPIOCtx_t 
*)MicoGetDevice("USB_Interrupt");

  MicoRegisterISR(USB_Interrupt->intrLevel, USB_Interrupt, USB_ISR);
  MICO_GPIO_WRITE_IRQ_MASK(USB_Interrupt,0xffffffff);

  do{
    int Test_Daten;
    MICO_GPIO_READ_DATA( USB_Data, Test_Daten);
  }while(1);

   return 0;
}

Interruptsignal in VHDL:

set_USB_Interrupt: process (clk_i)
  begin
    USB_Interrupt <= USB_Data (7 downto 7);
  end process;

Zur Erzeugung des Interruptsignals habe ich erstmal das oberste bit des 
Datenstroms genommen. Im MSB ist für den GPIO "USB_Interrupt" der IRQ 
Mode aktiviert und auf Edge -> Positive Edge eingestellt.
Wenn ich nun nach dem Starten des Programms ein Datum sende in dem das 
höchstwertige Bit 1 ist, dann springt er in die Funktion USB_ISR. Danach 
durchläuft er aber immer wieder diese Funktion, auch wenn ich ein neues 
Datum senden in dem das bit auf 0 liegt.
Wenn ich das ganz Prinzip richtig verstanden habe, dann sollte der 
Interrupt doch nur bei der steigenden Flanke des entsprechenden Signals 
ausgeführt werden?!?
Kann mir einer sagen wo der Fehler in meinem Code liegt, bzw. wie es zu 
diesem Problem kommen kann?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.