;
;    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 ? Do we have new incoming data ?
  cmp.b #0, &Datapacketbuffer ; Ist die Pufferlänge größer als Null ? Buffer length greater than zero ?
  je PacketGenerator ; Wenn es nichts Neues gibt, schaue nach, ob ich noch Pakete zum Senden vorbereiten kann.
  
  ; Es ist ein neues Paket zum Bearbeiten gekommen: We have mail !
  ; Prüfe, was das für eins ist !                   Check, what it is.
  cmp.b #usb_pid_setup, &Datapacketbuffer+15 ; Ganz am Ende wird vermerkt, was für einen PID das Token davor hatte.
  je Protocol_Setuppacket                    ; At the end of the buffer is the PID of the token packet before.
  
; ---------------------------------------------------------------------------   
  ; Es ist ein Out-Paket: It is an Out packet
  ;; write "o"
  clr.b &Datapacketbuffer ; Vergiss es ! Forget it. Handler should go here.
  jmp PacketGenerator ; Vielleicht liegt noch etwas Ausgehendes bereit... Perhaps something left to be transmitted ?
  
; ---------------------------------------------------------------------------   
Protocol_Setuppacket:
  ; Handle every sort of Setup packet.
  
  bit.b #00100000b, &Datapacketbuffer+2 ; Class-Requests aussortieren ! Sort out Class Requests.
  jc Protocol_Class_Requests
                
  cmp.b #0, &Datapacketbuffer+3 ; Get Status
  jne +
    mov #usb_paket_get_status, &ReadyforTransmit    
    clr.b &Datapacketbuffer ; Fertig abgearbeitet ! Finished handling.
    ret ; Es muss nichts zum Senden vorbereitet werden !  No need to prepare packets for transmission
            
            
+ cmp.b #5, &Datapacketbuffer+3 ; Set Address
  jne +
    mov.b &Datapacketbuffer+4, &New_Address
    
    mov #usb_paket_data1_leer_status, &ReadyforTransmit ; Brav Status Stage beantworten.  Answer Status stage
    clr.b &Datapacketbuffer ; Fertig abgearbeitet ! Finished handling.
    ret ; Es muss nichts zum Senden vorbereitet werden !  No need to prepare packets for transmission
                        
                        
+ cmp.b #9, &Datapacketbuffer+3 ; Set Configuration
  jne +
    mov #usb_paket_data1_leer_status, &ReadyforTransmit ; Brav Status Stage beantworten.  Answer Status stage  
    clr.b &Datapacketbuffer ; Fertig abgearbeitet ! Finished handling.
    ret ; Es muss nichts zum Senden vorbereitet werden ! No need to prepare packets for transmission
        
        
+ cmp.b #11, &Datapacketbuffer+3 ; Set Interface
  jne Protocol_Get_Descriptor
    mov #usb_paket_data1_leer_status, &ReadyforTransmit ; Brav Status Stage beantworten.  Answer Status stage
    ; Reset data toggling for interrupt endpoint !    
    clr &ReadyforTransmit_Irq_In ; Keine Daten für den Interrupt-In-Endpoint der Maus
    mov #usb_pid_data1, &Data_PID_Toggle_Irq_In ; Reset des Data Togglings für den Interrupt Endpoint        
    clr.b &Datapacketbuffer ; Fertig abgearbeitet ! Finished handling.
    ret ; Es muss nichts zum Senden vorbereitet werden ! No need to prepare packets for transmission
        
  
; ---------------------------------------------------------------------------   
Protocol_Get_Descriptor:  
  cmp.b #6, &Datapacketbuffer+3 ; Get Descriptor. Which one ? Welchen ?
  jne Disconnect_and_Debug ; Stop on unknown Request.
  
    mov #usb_pid_data0, &Data_PID_Toggle     ; Data-PID-Toggling korrekt setzen
    clr &DatatoTransmitOffset                ; Offset Null    
    clr.b &Datapacketbuffer                  ; Fertig abgearbeitet ! Finished handling.
    
    cmp.b #1, &Datapacketbuffer+5 ; Wünsche den Device Descriptor.
    jne +
      mov #Device_Descriptor, &DatatoTransmit
      jmp PacketGenerator
      
      
+   cmp.b #2, &Datapacketbuffer+5 ; Wünsche den Configuration Descriptor.
    jne ++
    
      cmp.b #9, &Datapacketbuffer+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...
        ; Short Configuration Descriptor, only the first nine bytes
        mov #Configuration_Descriptor_first9, &DatatoTransmit
        jmp PacketGenerator

+       ; Langer Configuration Descriptor wird gewünscht
        ; Complete Configuration Descriptor
        mov #Configuration_Descriptor_complete, &DatatoTransmit
        jmp PacketGenerator      
      
      
+   cmp.b #022h, &Datapacketbuffer+5 ; Wünsche den HID Descriptor
    jne +
      mov #HID_Descriptor, &DatatoTransmit
      jmp PacketGenerator      
      
            
+   cmp.b #3, &Datapacketbuffer+5 ; Wünsche einen String.
    jne Disconnect_and_Debug ; ENDE ! (bzw. andere Beschreibungen angefordert) Stop on unknown Request.
           
      cmp.b #0, &Datapacketbuffer+4
      jne +
      mov #String_Descriptor_0, &DatatoTransmit
+     ; Language-IDs mit String Index 0 zurückliefern

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

      cmp.b #2, &Datapacketbuffer+4
      jne +
      mov #String_Descriptor_2, &DatatoTransmit
+     ; String Index 2 zurückliefern
      
      jmp PacketGenerator
                 
; ---------------------------------------------------------------------------             
Protocol_Class_Requests: ; Klassen-Anfragen
     
    cmp.b #00Ah, &Datapacketbuffer+3 ; Set Idle
    jne +
       mov #usb_paket_data1_leer_status, &ReadyforTransmit ; Brav Status Stage beantworten.  Answer Status stage 
       clr.b &Datapacketbuffer ; Fertig abgearbeitet !
       ret ; Es muss nichts zum Senden vorbereitet werden ! No need to prepare packets for transmission
          
+ ifdef debug_messages 
    write "n" ; Exit point for unknown Class Requests
  endif
    
; ---------------------------------------------------------------------------     
Disconnect_and_Debug: ; Place to break if unknown pakets come in or strange errors occour.
 ; Andere Setup-Pakete: Stop !

  dint  
  bic.b #usbpullup, &P2DIR  ; Disconnect
  
  ; Ein bisschen warten ! Wait a bit !
  mov #10000, r5
- dec r5
  jnz -
  
  ; Ausbrechen aus dem Interrupt  Break out of interrupt frame on stack
  mov #0240h, sp              ; Init Stackpointer
  mov #0210h, r4              ; Init Datastackpointer, only used for messages...
  
  jmp Breakout
  
  