Lattice Mico32 GPIO Interrupt programmieren

OP #865903
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....
OP #867504
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...
OP #867567
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);
}
Gast #1858480
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?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren