Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  i2c_.fuc   Sprache: unbekannt

 
/*
 * Copyright 2013 Red Hat Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: Ben Skeggs
 */

#define T_TIMEOUT  2200000
#define T_RISEFALL 1000
#define T_HOLD     5000

#ifdef INCLUDE_PROC
process(PROC_I2C_, #i2c_init, #i2c_recv)
#endif

/******************************************************************************
 * I2C_ data segment
 *****************************************************************************/
#ifdef INCLUDE_DATA
i2c_scl_map:
.b32 NV_PPWR_OUTPUT_I2C_0_SCL
.b32 NV_PPWR_OUTPUT_I2C_1_SCL
.b32 NV_PPWR_OUTPUT_I2C_2_SCL
.b32 NV_PPWR_OUTPUT_I2C_3_SCL
.b32 NV_PPWR_OUTPUT_I2C_4_SCL
.b32 NV_PPWR_OUTPUT_I2C_5_SCL
.b32 NV_PPWR_OUTPUT_I2C_6_SCL
.b32 NV_PPWR_OUTPUT_I2C_7_SCL
.b32 NV_PPWR_OUTPUT_I2C_8_SCL
.b32 NV_PPWR_OUTPUT_I2C_9_SCL
i2c_sda_map:
.b32 NV_PPWR_OUTPUT_I2C_0_SDA
.b32 NV_PPWR_OUTPUT_I2C_1_SDA
.b32 NV_PPWR_OUTPUT_I2C_2_SDA
.b32 NV_PPWR_OUTPUT_I2C_3_SDA
.b32 NV_PPWR_OUTPUT_I2C_4_SDA
.b32 NV_PPWR_OUTPUT_I2C_5_SDA
.b32 NV_PPWR_OUTPUT_I2C_6_SDA
.b32 NV_PPWR_OUTPUT_I2C_7_SDA
.b32 NV_PPWR_OUTPUT_I2C_8_SDA
.b32 NV_PPWR_OUTPUT_I2C_9_SDA
#if NVKM_PPWR_CHIPSET < GF119
i2c_ctrl:
.b32 0x00e138
.b32 0x00e150
.b32 0x00e168
.b32 0x00e180
.b32 0x00e254
.b32 0x00e274
.b32 0x00e764
.b32 0x00e780
.b32 0x00e79c
.b32 0x00e7b8
#endif
#endif

/******************************************************************************
 * I2C_ code segment
 *****************************************************************************/
#ifdef INCLUDE_CODE

// $r3  - value
// $r2  - sda line
// $r1  - scl line
// $r0  - zero
i2c_drive_scl:
 cmp b32 $r3 0
 bra e #i2c_drive_scl_lo
 nv_iowr(NV_PPWR_OUTPUT_SET, $r1)
 ret
 i2c_drive_scl_lo:
 nv_iowr(NV_PPWR_OUTPUT_CLR, $r1)
 ret

i2c_drive_sda:
 cmp b32 $r3 0
 bra e #i2c_drive_sda_lo
 nv_iowr(NV_PPWR_OUTPUT_SET, $r2)
 ret
 i2c_drive_sda_lo:
 nv_iowr(NV_PPWR_OUTPUT_CLR, $r2)
 ret

i2c_sense_scl:
 bclr $flags $p1
 nv_iord($r3, NV_PPWR_INPUT)
 and $r3 $r1
 bra z #i2c_sense_scl_done
  bset $flags $p1
 i2c_sense_scl_done:
 ret

i2c_sense_sda:
 bclr $flags $p1
 nv_iord($r3, NV_PPWR_INPUT)
 and $r3 $r2
 bra z #i2c_sense_sda_done
  bset $flags $p1
 i2c_sense_sda_done:
 ret

#define i2c_drive_scl(v) /*
*/ mov $r3 (v) /*
*/ call(i2c_drive_scl)
#define i2c_drive_sda(v) /*
*/ mov $r3 (v) /*
*/ call(i2c_drive_sda)
#define i2c_sense_scl() /*
*/ call(i2c_sense_scl)
#define i2c_sense_sda() /*
*/ call(i2c_sense_sda)
#define i2c_delay(v) /*
*/ mov $r14 (v) /*
*/ call(nsec)

#define i2c_trace_init() /*
*/ imm32($r6, 0x10000000) /*
*/ sub b32 $r7 $r6 1 /*
*/
#define i2c_trace_down() /*
*/ shr b32 $r6 4 /*
*/ push $r5 /*
*/ shl b32 $r5 $r6 4 /*
*/ sub b32 $r5 $r6 /*
*/ not b32 $r5 /*
*/ and $r7 $r5 /*
*/ pop $r5 /*
*/
#define i2c_trace_exit() /*
*/ shl b32 $r6 4 /*
*/
#define i2c_trace_next() /*
*/ add b32 $r7 $r6 /*
*/
#define i2c_trace_call(func) /*
*/ i2c_trace_next() /*
*/ i2c_trace_down() /*
*/ call(func) /*
*/ i2c_trace_exit() /*
*/

i2c_raise_scl:
 push $r4
 mov $r4 (T_TIMEOUT / T_RISEFALL)
 i2c_drive_scl(1)
 i2c_raise_scl_wait:
  i2c_delay(T_RISEFALL)
  i2c_sense_scl()
  bra $p1 #i2c_raise_scl_done
  sub b32 $r4 1
  bra nz #i2c_raise_scl_wait
 i2c_raise_scl_done:
 pop $r4
 ret

i2c_start:
 i2c_sense_scl()
 bra not $p1 #i2c_start_rep
 i2c_sense_sda()
 bra not $p1 #i2c_start_rep
 bra #i2c_start_send
 i2c_start_rep:
  i2c_drive_scl(0)
  i2c_drive_sda(1)
  i2c_trace_call(i2c_raise_scl)
  bra not $p1 #i2c_start_out
 i2c_start_send:
 i2c_drive_sda(0)
 i2c_delay(T_HOLD)
 i2c_drive_scl(0)
 i2c_delay(T_HOLD)
 i2c_start_out:
 ret

i2c_stop:
 i2c_drive_scl(0)
 i2c_drive_sda(0)
 i2c_delay(T_RISEFALL)
 i2c_drive_scl(1)
 i2c_delay(T_HOLD)
 i2c_drive_sda(1)
 i2c_delay(T_HOLD)
 ret

// $r3  - value
// $r2  - sda line
// $r1  - scl line
// $r0  - zero
i2c_bitw:
 call(i2c_drive_sda)
 i2c_delay(T_RISEFALL)
 i2c_trace_call(i2c_raise_scl)
 bra not $p1 #i2c_bitw_out
 i2c_delay(T_HOLD)
 i2c_drive_scl(0)
 i2c_delay(T_HOLD)
 i2c_bitw_out:
 ret

// $r3  - value (out)
// $r2  - sda line
// $r1  - scl line
// $r0  - zero
i2c_bitr:
 i2c_drive_sda(1)
 i2c_delay(T_RISEFALL)
 i2c_trace_call(i2c_raise_scl)
 bra not $p1 #i2c_bitr_done
 i2c_sense_sda()
 i2c_drive_scl(0)
 i2c_delay(T_HOLD)
 xbit $r3 $flags $p1
 bset $flags $p1
 i2c_bitr_done:
 ret

i2c_get_byte:
 mov $r5 0
 mov $r4 8
 i2c_get_byte_next:
  shl b32 $r5 1
  i2c_trace_call(i2c_bitr)
  bra not $p1 #i2c_get_byte_done
  or $r5 $r3
  sub b32 $r4 1
  bra nz #i2c_get_byte_next
 mov $r3 1
 i2c_trace_call(i2c_bitw)
 i2c_get_byte_done:
 ret

i2c_put_byte:
 mov $r4 8
 i2c_put_byte_next:
  sub b32 $r4 1
  xbit $r3 $r5 $r4
  i2c_trace_call(i2c_bitw)
  bra not $p1 #i2c_put_byte_done
  cmp b32 $r4 0
  bra ne #i2c_put_byte_next
 i2c_trace_call(i2c_bitr)
 bra not $p1 #i2c_put_byte_done
 i2c_trace_next()
 cmp b32 $r3 1
 bra ne #i2c_put_byte_done
 bclr $flags $p1 // nack
 i2c_put_byte_done:
 ret

i2c_addr:
 i2c_trace_call(i2c_start)
 bra not $p1 #i2c_addr_done
 extr $r3 $r12 I2C__MSG_DATA0_ADDR
 shl b32 $r3 1
 or $r5 $r3
 i2c_trace_call(i2c_put_byte)
 i2c_addr_done:
 ret

i2c_acquire_addr:
 extr $r14 $r12 I2C__MSG_DATA0_PORT
#if NVKM_PPWR_CHIPSET < GF119
 shl b32 $r14 2
 add b32 $r14 #i2c_ctrl
 ld b32 $r14 D[$r14]
#else
 shl b32 $r14 5
 add b32 $r14 0x00d014
#endif
 ret

i2c_acquire:
 call(i2c_acquire_addr)
 call(rd32)
 bset $r13 3
 call(wr32)
 ret

i2c_release:
 call(i2c_acquire_addr)
 call(rd32)
 bclr $r13 3
 call(wr32)
 ret

// description
//
// $r15 - current (i2c)
// $r14 - sender process name
// $r13 - message
// $r12 - data0
// $r11 - data1
// $r0  - zero
i2c_recv:
 bclr $flags $p1
 extr $r1 $r12 I2C__MSG_DATA0_PORT
 shl b32 $r1 2
 cmp b32 $r1 (#i2c_sda_map - #i2c_scl_map)
 bra ge #i2c_recv_done
 add b32 $r3 $r1 #i2c_sda_map
 ld b32 $r2 D[$r3]
 add b32 $r3 $r1 #i2c_scl_map
 ld b32 $r1 D[$r3]

 bset $flags $p2
 push $r13
 push $r14

 push $r13
 i2c_trace_init()
 i2c_trace_call(i2c_acquire)
 pop $r13

 cmp b32 $r13 I2C__MSG_RD08
 bra ne #i2c_recv_not_rd08
  mov $r5 0
  i2c_trace_call(i2c_addr)
  bra not $p1 #i2c_recv_done
  extr $r5 $r12 I2C__MSG_DATA0_RD08_REG
  i2c_trace_call(i2c_put_byte)
  bra not $p1 #i2c_recv_done
  mov $r5 1
  i2c_trace_call(i2c_addr)
  bra not $p1 #i2c_recv_done
  i2c_trace_call(i2c_get_byte)
  bra not $p1 #i2c_recv_done
  ins $r11 $r5 I2C__MSG_DATA1_RD08_VAL
  i2c_trace_call(i2c_stop)
  mov b32 $r11 $r5
  clear b32 $r7
  bra #i2c_recv_done

 i2c_recv_not_rd08:
 cmp b32 $r13 I2C__MSG_WR08
 bra ne #i2c_recv_not_wr08
  mov $r5 0
  call(i2c_addr)
  bra not $p1 #i2c_recv_done
  extr $r5 $r12 I2C__MSG_DATA0_WR08_REG
  call(i2c_put_byte)
  bra not $p1 #i2c_recv_done
  mov $r5 0
  call(i2c_addr)
  bra not $p1 #i2c_recv_done
  extr $r5 $r11 I2C__MSG_DATA1_WR08_VAL
  call(i2c_put_byte)
  bra not $p1 #i2c_recv_done
  call(i2c_stop)
  clear b32 $r7
  extr $r5 $r12 I2C__MSG_DATA0_WR08_SYNC
  bra nz #i2c_recv_done
  bclr $flags $p2
  bra #i2c_recv_done

 i2c_recv_not_wr08:

 i2c_recv_done:
 extr $r14 $r12 I2C__MSG_DATA0_PORT
 call(i2c_release)

 pop $r14
 pop $r13
 bra not $p2 #i2c_recv_exit
 mov b32 $r12 $r7
 call(send)

 i2c_recv_exit:
 ret

// description
//
// $r15 - current (i2c)
// $r0  - zero
i2c_init:
 ret
#endif

[ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge