mikrocontroller.net

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


Autor: Simon D. (simon86)
Datum:

Bewertung
0 lesenswert
nicht 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....

Autor: Rick Dangerus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Simon D. (simon86)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Simon D. (simon86)
Datum:

Bewertung
0 lesenswert
nicht 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);
}

Autor: WpMD (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.