;
;    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

; Register
UCA0TXBUF equ 067h
UCA0RXBUF equ 066h
UCA0STAT  equ 065h
UCA0MCTL  equ 064h
UCA0BR1   equ 063h
UCA0BR0   equ 062h
UCA0CTL1  equ 061h
UCA0CTL0  equ 060h

; Konstanten für Register IE1
UCA0RXIFG equ 1
UCA0TXIFG equ 2

; Konstanten für UCA0CTL1:
UCSWRST   equ 1
UCSSEL_0  equ 00000000b
UCSSEL_1  equ 01000000b
UCSSEL_2  equ 10000000b
UCSSEL_3  equ 11000000b

; Konstanten für UCA0MCTL

; UCBRF Bit 7-4 Nur wenn 16-fach-Oversampling für IRDA.
; USBRS Bit 1-3

UCBRS_0   equ 0000b
UCBRS_1   equ 0010b
UCBRS_2   equ 0100b
UCBRS_3   equ 0110b
UCBRS_4   equ 1000b
UCBRS_5   equ 1010b
UCBRS_6   equ 1100b
UCBRS_7   equ 1110b

UCOS16 equ 1

P1SEL2 equ 041h

;------------------------------------------------------------------------------
; ( -- Flag ) Prüft, ob eine Taste gedrückt wurde
terminal_qkey:
;------------------------------------------------------------------------------
  pushda #0
  bit.b #UCA0RXIFG,&IFG2
  jz +
  mov #-1, @r4
+ ret
     
;------------------------------------------------------------------------------
; ( -- c ) Holt den Tastendruck
terminal_key:
;------------------------------------------------------------------------------
- bit.b   #UCA0RXIFG,&IFG2
  jz -
        
  decd r4
  clr @r4
  mov.b  &UCA0RXBUF, @r4        
  ret    
       
;------------------------------------------------------------------------------
; ( 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

;------------------------------------------------------------------------------
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
            
            
            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**

  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




        ; 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.
