;
;    Mecrimus - 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/>.
;  
  
  
  cpu msp430

  include "mspregister.asm"  ; Register definitions
  include "datastack.asm"    ; Defines a second stack in r4 used here only for printing messages
  
  org 0F800h                 ; Start somewhere... Target is msp430g2452 at the moment.

; Connections to Pins on Port 1:
  ; Simply the Anode of a LED on P1.0 for RS232 like transmissions.

; Connections to Pins on Port 2:

syncled  equ 1 ; P2.0  Anode of LED that shows syncinc including 100 Ohms
               ; P2.1  Cathode of this LED, soldered in this way with brighness measurements and Ledcomm in mind...
               ;       Always driven low here.

usbminus equ 4  ; P2.2 D- over 50 Ohms with 1.5 kOhm pullup, driven to simulate connect and disconnent by P2.5
usbplus  equ 8  ; P2.3 D+ over 50 Ohns

usbpullup equ 32 ; P2.5 


; Memory map:

; 200 - 20F Data Stack   Only used for Forth message printing routines
; 210 - 23F Return Stack
; 240 - 24F Space for Variables
; 250 - 27F Buffers. At the end of memory to not currupt stack and variables in case of buffer overflow.

Receivebufferpointer     equ 242h
Transmitbufferpointer    equ 244h

Buffer1  equ 0250h
Buffer2  equ 0260h
Buffer3  equ 0270h

 include "rs232-over-led.asm"
 include "messages.asm"
 include "Receiver-15MHz.asm"
 include "Transmitter-15MHz.asm"

Reset:
  mov #WDTPW+WDTHOLD, &WDTCTL ; Stop watchdog  
  mov #0240h, sp              ; Init Stackpointer
  mov #0210h, r4              ; Init Datastackpointer, only used for messages...

; Neue Speicherbelegung: 200-220 Datenstack, 220-240 Returnstack.
; Variablen bei 240-250, Puffer an 250.

  ; Prepare Port 1
  clr.b &P1OUT
  bis.b #255, &P1DIR

  ; Prepare Port 2
  clr.b &P2OUT
  mov.b #1+2, &P2DIR  ; Prepare Pins for the Sync-LED, Anode and Cathode driven low. USB lines inputs.

  mov.b &CALBC1_1MHZ, &BCSCTL1   ; Set DCO
  mov.b &CALDCO_1MHZ, &DCOCTL    ;   to 1 MHz. To see if external clock is properly used, as between 1 MHz and 15 MHz is a big difference.
  
  ; Select LFXT1 (HF external clock mode) for MCLK
  bic #OSCOFF, sr              ; Turn on osc.
  bis.b #XTS, &BCSCTL1         ; HF mode
  mov.b #LFXT1S_3, &BCSCTL3     ; External clock source
  
- bic.b #OFIFG, &IFG1          ; Clear OFIFG
  mov #0FFh,R15                ; Delay
- dec R15
  jnz -
  bit.b #OFIFG, &IFG1          ; Re-test OFIFG
  jnz --                       ; Repeat test if needed
  bis.b #SELM_3, &BCSCTL2 ; Select LFXT1CLK
 


    
    
Mainloop:           ; Print contents of buffer (empty RAM in first run als welcome message), then connect and try to catch packets.

  mov #Buffer1, r5  ; Address of Buffer
  mov #16, r6       ; Number of bytes to print
  
- mov.b @r5+, r7
  writebyte r7
  write " "
  dec r6
  jnz -

  write " | "
                
  mov #Buffer2, r5  
  mov #16, r6 
  
- mov.b @r5+, r7
  writebyte r7
  write " "
  dec r6
  jnz -

  write " | "
                        
  mov #Buffer3, r5  
  mov #16, r6 
  
- mov.b @r5+, r7
  writebyte r7
  write " "
  dec r6
  jnz -

  writeln " ."
  
  ; This will give you an output like this:
  ;  03 2D 00 10 FD FF FF FF FF FF FF FF FF FF FF FF  | 23 C3 80 06 00 01 10 00 20 80 6E CA FD FF FF FF  | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  .
  ;  03 2D 00 10 FD FF FF FF FF FF FF FF FF FF FF FF  | 41 C3 80 06 90 00 00 00 20 80 6E CA FD FF FF FF  | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  .
  ;  03 2D 00 10 FD FF FF FF FF FF FF FF FF FF FF FF  | 41 C3 80 06 90 00 00 00 20 80 6E CA FD FF FF FF  | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  .
  ;  03 2D 00 10 FD FF FF FF FF FF FF FF FF FF FF FF  | 41 C3 80 06 90 00 00 00 20 80 6E CA FD FF FF FF  | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  .
  ;  03 2D 00 10 FD FF FF FF FF FF FF FF FF FF FF FF  | 15 C3 00 05 05 00 00 00 00 00 F4 98 FD FF FF FF  | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  .
  ;  03 2D 00 10 FD FF FF FF FF FF FF FF FF FF FF FF  | 41 C3 00 05 15 00 10 00 00 00 F4 98 FD FF FF FF  | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  .
  ;  03 2D 00 10 FD FF FF FF FF FF FF FF FF FF FF FF  | 41 C3 00 05 16 00 10 00 00 00 74 81 FD FF FF FF  | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  .
  ;  03 2D 00 10 FD FF FF FF FF FF FF FF FF FF FF FF  | 41 C3 00 05 16 00 10 00 00 00 74 81 FD FF FF FF  | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  .
  ; I am still unsure why count is wrong in second packet.

          
   
  bis.b #usbpullup, &P2OUT  ; "Connect to USB" via enabling the D- pullup resistor.
  bis.b #usbpullup, &P2DIR
  
  
- mov #Buffer1, &Receivebufferpointer  ; Select first Buffer

- bit.b #usbminus, &P2IN  ; Wait for low in D- as first part of sync-pattern
  jc -  
  call #USB_Sync ; Catch !
  jnc --  ; If receiving of first packet fails, try to catch another.
  
     cmp.b #usb_pid_in, &Buffer1+1  ; I want definitely a setup packet !
     je --                          ; Catch next if it isn't one.
     
     ; Without this you will catch a lot of IN packets.
     ;  03 69 82 18 FD FF FF FF FF FF FF FF FF FF FF FF 
  
  ifdef 0 ; Deactivated in favor of experimental section in Receiver.
  
- mov #Buffer2, &Receivebufferpointer  ; Select second buffer

- bit.b #usbminus, &P2IN  ; Wait for low...
  jc -  
  call #USB_Sync
  jnc --  ; Repeat until successfully got something.
   
   
- mov #Buffer3, &Receivebufferpointer

- bit.b #usbminus, &P2IN  ; Warte auf Null in der Leitung
  jc -  
  call #USB_Sync ; Catch !
  jnc --  ; Solange, bis etwas da ist.   
  
  endif
  
  jmp Mainloop
  
  

  org 0FFFEh 
  .word Reset ; Reset Vektor 
 
