;
;    Mecrisp - A native code Forth implementation for MSP430 microcontrollers
;    Copyright (C) 2011  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/>.
;

; Terminalroutinen für die serielle Schnittstelle im MSP430F2774

terminal_qkey_schnippsel macro
;------------------------------------------------------------------------------
; ( -- Flag ) Prüft, ob eine Taste gedrückt wurde
; terminal_qkey:
;------------------------------------------------------------------------------
  pushda #0
  bit.b #UCA0RXIFG, &IFG2
  jz +
  mov #-1, @r4
+ ret
  endm

terminal_key_schnippsel macro     
;------------------------------------------------------------------------------
; ( -- c ) Holt den Tastendruck
; terminal_key:
;------------------------------------------------------------------------------
- bit.b #UCA0RXIFG, &IFG2
  jz -
        
  decd r4
  clr @r4
  mov.b &UCA0RXBUF, @r4        
  ret    
  endm
      
terminal_emit_schnippsel macro
;------------------------------------------------------------------------------
; ( c -- ) Gibt ein Zeichen aus
; terminal_emit:
;------------------------------------------------------------------------------
- bit.b #UCA0TXIFG, &IFG2       ; USCI_A0 TX buffer ready?
  jz -                          ; Jump if TX buffer not ready
  mov.b @r4, &UCA0TXBUF         ; TX -> RXed character
  drop
  ret
  endm

terminal_init_schnippsel macro
;------------------------------------------------------------------------------
; terminal_init: ; ( -- ) Wird am Anfang einmal aufgerufen, für Hardware-Initialisierungen ! 
;------------------------------------------------------------------------------
  ; Umgestellt auf 8 MHz ! Achtung: Flash-Timing muss bei Änderungen auch angepasst werden ! Siehe flash.asm
  ; Momentaner Teiler 19+1 --> 400kHz. Muss im Bereich 257 kHz bis 476 kHz liegen.

  mov.b &CALBC1_8MHZ, &BCSCTL1   ; Set DCO
  mov.b &CALDCO_8MHZ, &DCOCTL    ;   to 8 MHz.

  ifdef msp430f2274
            bis.b   #030h, &P3SEL            ; Use P3.4/P3.5 for USCI_A0
  endif
  ifdef msp430g2553
            mov.b   #006h, &P1SEL            ; Use P1.1/P1.2 for USCI_A0
            mov.b   #006h, &P1SEL2           ; Use P1.1/P1.2 for USCI_A0
  endif

  ifndef irda  
          ;------------------------------------------------------------------------------
          ; Initialisierung für normale serielle Schnittstelle
            bis.b   #UCSSEL_2,&UCA0CTL1     ; SMCLK
            mov.b   #65,&UCA0BR0            ; 8MHz 9600 Insgesamt 833
            mov.b   #3,&UCA0BR1             ; 8MHz 9600
            mov.b   #UCBRS_2,&UCA0MCTL      ; Modulation UCBRSx = 2
            bic.b   #UCSWRST,&UCA0CTL1      ; **Initialize USCI state machine**
  else
          ;------------------------------------------------------------------------------
          ; Initialisierung für IrDA, ungetestet
            bis.b   #UCSWRST,&UCA0CTL1          ; Set SW Reset
            mov.b   #UCSSEL_2+UCSWRST,&UCA0CTL1 ; Use SMCLK, keep SW reset                                            
            mov.b   #52,&UCA0BR0                ; 8MHz/52=153.8KHz
            mov.b   #0,&UCA0BR1
            mov.b   #UCBRF_1+UCOS16,&UCA0MCTL   ; Set 1st stage modulator to 1
                                                ; 16-times oversampling mode
            mov.b   #UCIRTXPL2+UCIRTXPL0+UCIRTXCLK+UCIREN,&UCA0IRTCTL
                                                ; Pulse length = 6 half clock cyc
                                                ; Enable BITCLK16, IrDA enc/dec
            mov.b   #UCIRRXPL,&UCA0IRRCTL       ; Light = low pulse
            bic.b   #UCSWRST,&UCA0CTL1          ; Resume operation
          ;------------------------------------------------------------------------------ 
  endif

  ifdef flashdictionaryeinbinden
    clr.b &IE1 ; Lösche die Interrupt-Flags von Oscillator Fault, NMI, Flash-Violation.
    mov.w #FWKEY, &FCTL1           ; Schreib- & Löschzugriffe ausgeschaltet.
    mov.w #FWKEY|FSSEL_1|19, &FCTL2 ; MCLK/20 for Flash Timing Generator   Bei meinen Konstantendefinitionen ist das hier MCLK ! 
    
    ifndef msp430g2553
      mov.w #FWKEY+LOCK, &FCTL3      ; Lock Flash memory against writing
    endif
  endif
  ; ret Jetzt nicht mehr, weil es als Makro eingefügt wird.


  endm


        ; Flash Memory Controller
        ; Flash Timing Generator frequency must be 257-476 kHz.
        ; 8 MHZ/17 = 470.59 kHz.   tFTG=2.125 msec.
        ; At 470 kHz, byte/word program time is 35*tFTG = 75 usec.
        ; Cumulative program time to any 64-byte block (between erasures)
        ; must not exceed 4 msec, thus 53 writes at 250 kHz.  Therefore,
        ; do not use exclusively byte writes in a 64-byte block.
        ; Also, "a flash word (low + high byte) must not
        ; be written more than twice between erasures."
        ; Program/Erase endurance is 10,000 cycles minimum.
        ;MOV #FWKEY+0,&FCTL1             ; write & erase modes OFF
        ;MOV #FWKEY+FSSEL1+16,&FCTL2     ; SMCLK/17 = 471 kHz.
        ;MOV #FWKEY+LOCK,&FCTL3          ; lock flash memory against writing
  
; In meinem Fall 400kHz --> 2,5 us tFTG --> 35*tFTG = 87,5 us.
; Darf 10ms lang schreiben... --> Habe 10ms/87.5us = 114 Schreibzugriffe pro 64-Byte-Block.
; Alles paletti. Kann also im reinen Bytemodus brennen. Die Routinen achten darauf,
; dass nichts zweimal geschrieben wird.
