;
;    Mecrimus-B - A firmware-only USB implementation for MSP430 microcontrollers
;    Copyright (C) 2012  Matthias Koch
;
;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;    (at your option) any later version.
;
;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.
;
;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.
;  

; Loop for handling USB protocol requests.
; Can be called in the main loop or at the end of the transmitter with reenabled interrupts.

; --------------------------------------------------------------------------- 
Protokollhelferlein: ; Dies wird am Ende des Transmitters außer Konkurrenz und
                     ; mit bereits wieder aktivierten Interruptsaufgerufen und 
                     ; arbeitet die ankommenden und ausgehenden Pakete ab.
; --------------------------------------------------------------------------- 

  ; Sind neue Daten da ?
  cmp.b #0, &Datenpaketpuffer ; Ist die Pufferlänge größer als Null ?
  je Paketverteiler ; Wenn es nichts Neues gibt, schaue nach, ob ich noch Pakete zum Senden vorbereiten kann.
  
  ; Es ist ein neues Paket zum Bearbeiten gekommen:
  ; Prüfe, was das für eins ist !
  cmp.b #usb_pid_setup, &Datenpaketpuffer+15 ; Ganz am Ende wird vermerkt, was für einen PID das Token davor hatte.
  je Protokoll_Setuppaket
  
  ; Es ist ein Out-Paket:
  clr.b &Datenpaketpuffer ; Vergiss es !
  ifdef debug_messages_protocol_loop
  write "o"
  endif
 ; writebyte &Datenpaketpuffer+14
  jmp Paketverteiler ; Vielleicht liegt noch etwas Ausgehendes bereit...
  
  
Protokoll_Setuppaket:
  ; Müsste noch im ersten Byte nach der passenden Signatur forschen ! Es gibt unterschiedliche Setup-Pakettypen ! 
  ; Jetzt aber erstmal einfach.
    
  cmp.b #9, &Datenpaketpuffer+3 ; Set Configuration
  jne +
    mov #usb_paket_data1_leer_status, &ReadyforTransmit ; Brav Status Stage beantworten.    
    clr.b &Datenpaketpuffer ; Fertig abgearbeitet !
    ifdef debug_messages_protocol_loop
    write "s" 
    endif
    ret ; Es muss nichts zum Senden vorbereitet werden !
    
    
    ;; ifdef 0 ; Für einen Ausbruch mit lsusb -v
    
+ cmp.b #0, &Datenpaketpuffer+3 ; Get Status
  jne +
    ;mov #usb_pid_data0, &Data_PID_Toggle     ; Data-PID-Toggling korrekt setzen
    ;clr &DatatoTransmitOffset                ; Offset Null    
    ;mov #usb_get_status_reply, &DatatoTransmit  ; Passende Antwort zurechtlegen    
    
    mov #usb_paket_get_status, &ReadyforTransmit
    
    clr.b &Datenpaketpuffer ; Fertig abgearbeitet !
    ifdef debug_messages_protocol_loop
    write "g" 
    endif
    ret ; Es muss nichts zum Senden vorbereitet werden !    
    
    ;;endif 
    
+ cmp.b #5, &Datenpaketpuffer+3 ; Set Address
  jne Protokoll_Descriptor    
    mov.b &Datenpaketpuffer+4, &Neue_Adresse
    mov #usb_paket_data1_leer_status, &ReadyforTransmit ; Brav Status Stage beantworten.    
    clr.b &Datenpaketpuffer ; Fertig abgearbeitet !
    ifdef debug_messages_protocol_loop
    write "a"     
    endif
    ret ; Es muss nichts zum Senden vorbereitet werden !
  
  
  
  
Protokoll_Descriptor:  
  cmp.b #6, &Datenpaketpuffer+3 ; Get Descriptor. Welchen ?
  jne Anhaltestelle
  
    cmp.b #1, &Datenpaketpuffer+5 ; Wünsche den Device Descriptor.
    jne + ; ENDE ! (bzw. andere Beschreibungen angefordert)
     
      mov #usb_pid_data0, &Data_PID_Toggle     ; Data-PID-Toggling korrekt setzen
      clr &DatatoTransmitOffset                ; Offset Null    
      mov #Device_Descriptor, &DatatoTransmit  ; Passende Antwort zurechtlegen
      ifdef debug_messages_protocol_loop
      write "d"   
      endif
      clr.b &Datenpaketpuffer ; Fertig abgearbeitet !
      jmp Paketverteiler
      
+   cmp.b #3, &Datenpaketpuffer+5 ; Wünsche einen String.
    jne Protokoll_Configuration_Descriptor ; ENDE ! (bzw. andere Beschreibungen angefordert)
     
      mov #usb_pid_data0, &Data_PID_Toggle     ; Data-PID-Toggling korrekt setzen
      clr &DatatoTransmitOffset                ; Offset Null    

      cmp.b #0, &Datenpaketpuffer+4
      jne +
      mov #String_Descriptor_0, &DatatoTransmit
+     ; Language-IDs mit String Index 0 zurückliefern

      cmp.b #1, &Datenpaketpuffer+4
      jne +
      mov #String_Descriptor_1, &DatatoTransmit
+     ; String Index 1 zurückliefern

      cmp.b #2, &Datenpaketpuffer+4
      jne +
      mov #String_Descriptor_2, &DatatoTransmit
+     ; String Index 2 zurückliefern

      ifdef debug_messages_protocol_loop
      write "l"   
      endif
      clr.b &Datenpaketpuffer ; Fertig abgearbeitet !
      jmp Paketverteiler

 
Protokoll_Configuration_Descriptor:     
    cmp.b #2, &Datenpaketpuffer+5 ; Wünsche den Configuration Descriptor.
    jne Anhaltestelle ; ENDE ! (bzw. andere Beschreibungen angefordert)         
    
      mov #usb_pid_data0, &Data_PID_Toggle     ; Data-PID-Toggling korrekt setzen
      clr &DatatoTransmitOffset                ; Offset Null    
      
      cmp.b #9, &Datenpaketpuffer+8  ; 0B C3 80 06 00 02 00 00 --> 09 <-- 00 AE 04 
      jne +
      ; Kurzer Configuration Descriptor wird gewünscht, nur die ersten neun Bytes...
      mov #Configuration_Descriptor_neun, &DatatoTransmit  ; Passende Antwort zurechtlegen
      ifdef debug_messages_protocol_loop
      write "9"   
      endif
      jmp ++
+     ; Langer Configuration Descriptor wird gewünscht      
      mov #Configuration_Descriptor_achtzehn, &DatatoTransmit  ; Passende Antwort zurechtlegen
+     ; Fertig. Abschicken !      
      clr.b &Datenpaketpuffer ; Fertig abgearbeitet !
      ifdef debug_messages_protocol_loop
      write "c"   
      endif
      jmp Paketverteiler
      
    
Anhaltestelle: ; Place to break if unknown pakets come in or strange errors occour.
 ; Andere Setup-Pakete: Stop !

  dint  
  bic.b #usbpullup, &P2DIR  
  
  ; Ein bisschen warten !
  mov #10000, r5
- dec r5
  jnz -
  
  ; Ausbrechen aus dem Interrupt
  mov #0240h, sp              ; Init Stackpointer
  mov #0210h, r4              ; Init Datastackpointer, only used for messages...
  
  jmp Ausbrechen
  
  