; Copyright 2010 Castle Technology Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
;     http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
        GET     Hdr:ListOpts
        GET     Hdr:Macros
        GET     Hdr:System
        GET     Hdr:Machine.<Machine>
        GET     Hdr:ImageSize.<ImageSize>
        $GetIO

        AREA    |Asm$$Code|, CODE, READONLY, PIC

        EXPORT  TPSRead
        EXPORT  TPSWrite

; A couple of utility functions for reading/writing registers from the TWL4030/TPS65950 IC (although the protocol is probably generic enough to work with many other IIC devices)

; For the majority of uses, v1 simply needs to be initialised as follows:
; LDR  v1, OSentries+4*OS_IICOpV
; i.e. the IIC transfer will be performed on IIC bus 0, via RISCOS_IICOpV. This means that 0 will be returned on success, or an OS error block pointer on failure!
; When using OS_IICOpV, v2 can be left uninitialised.
; TODO - Tidy this up - TPSRead/TPSWrite can simply choose for themselves whether to use OS_IICOpV or IIC_DoOp_Poll

TPSRead
        ; a1 = IIC address(*2)
        ; a2 = buffer
        ; a3 = count
        ; a4 = start register
        ; v1 = IIC func
        ; v2 = IIC param
        ; out:
        ; a1 = return code
        ; ip corrupted
        ; buffer updated
        ORR     a1, a1, #1 ; read
        Push    "a1-a4,lr" ; Push regs and second iic_transfer block
        EOR     a1, a1, #1+(1:SHL:29) ; write with retry
        ADD     a2, sp, #12
        MOV     a3, #1
        Push    "a1-a3" ; push first iic_transfer block
        MOV     a1, sp
        MOV     a2, #2
        MOV     a3, v2
        BLX     v1
        ADD     sp, sp, #16
        Pull    "a2-a4,pc"

TPSWrite
        ; a1 = IIC address(*2)
        ; a2 = buffer
        ; a3 = count
        ; a4 = start register
        ; v1 = IIC func
        ; v2 = IIC param
        ; out:
        ; a1 = return code
        ; ip corrupted
        ORR     a1, a1, #1:SHL:31 ; Write (no start bit)
        Push    "a1-a4,lr" ; Push regs and second iic_transfer block
        EOR     a1, a1, #(1:SHL:29)+(1:SHL:31) ; Write (retries)
        ADD     a2, sp, #12
        MOV     a3, #1
        Push    "a1-a3" ; push first iic_transfer block
        MOV     a1, sp
        MOV     a2, #2
        MOV     a3, v2
        BLX     v1
        ADD     sp, sp, #16
        Pull    "a2-a4,pc"

        END