📄 i2c.s
字号:
/* $Id: i2c.S,v 1.1 2001/12/11 08:19:18 pefo Exp $ *//* * Copyright (c) 2001 Opsycon AB (www.opsycon.se) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Opsycon AB, Sweden. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *//* * I2C Functions used in early startup code to get SPD info from * SDRAM modules. This code must be entirely PIC and RAM independent. */#include "pmon/dev/gt64260reg.h"#include "target/ev64260.h"#include <machine/mpc_regs.h>#include <machine/psl.h>#define CTR 9#define HIADJ(x) (x)@ha#define HI(x) (x)@h#define LO(x) (x)@l/* * Use this macro to prevent reordering by as/ld and processor */#define IORDER eieio; sync/* Delay macro */#define DELAY(count) \ li 0, count; \ mtctr 0; \1: \ bdnz 1b \/************************************************************* *NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE* ************************************************************* * Throughout this code r25 is used to hold the GT-chip base * address. DON'T use r25 for any purpose whatsoever! *//* * Macros to simplify setting up the Galileo controller */#define GT_REGAD(offs) \ ori r5, r25, offs#define GT_REGWR(offs, value) \ ori r5, r25, offs; \ lis r6, HIADJ(value); \ addi r6, r6, LO(value); \ stwbrx r6, 0, (r5); \ eieio; sync#define GT_REGRD(offs) \ ori r5, r25, offs; \ lwbrx r6, 0, (r5); \ eieio; sync#define GT_REGSET(offs, value) \ ori r5, r25, offs; \ lwbrx r6, 0, (r5); \ oris r6, r6, HI(value); \ ori r6, r6, LO(value); \ stwbrx r6, 0, (r5); \ eieio; sync#define GT_REGCLR(offs, value) \ ori r5, r25, offs; \ lwbrx r6, 0, (r5); \ lis r5, HI(value); \ ori r5, r5, LO(value); \ andc r6, r6, r5; \ ori r5, r25, offs; \ stwbrx r6, 0, (r5); \ eieio; sync#define I2C_INT_ENABLE 0x80#define I2C_ENABLE 0x40#define I2C_ACK 0x04#define I2C_INT_FLAG 0x08#define I2C_STOP_BIT 0x10#define I2C_START_BIT 0x20#define I2C_AMOD_RD 0x01#define BUS_ERROR 0x00#define START_CONDITION_TRA 0x08#define RSTART_CONDITION_TRA 0x10#define ADDR_AND_WRITE_BIT_TRA_ACK_REC 0x18#define ADDR_AND_READ_BIT_TRA_ACK_REC 0x40#define SLAVE_REC_WRITE_DATA_ACK_TRA 0x28#define MAS_REC_READ_DATA_ACK_NOT_TRA 0x58boot_i2c_test: li r3, 0x600boot_i2c_test_call: or r7, r25, r25 mflr r8 lis r25, HI(GT_BASE_ADDR) bl boot_i2c_init bl boot_i2c_read mtlr r8 or r25, r7, r7 blr/* * Wait for interrupt, return status byte */wait_int: GT_REGRD(I2C_CONTROL) li r5, I2C_INT_FLAG and. r6, r6, r5 beq wait_int GT_REGRD(I2C_STATUS_BAUDE_RATE) blr/* * I2C Master init. */ .globl boot_i2c_initboot_i2c_init: GT_REGWR(I2C_SOFT_RESET, 0x0) GT_REGWR(I2C_STATUS_BAUDE_RATE, 0x24); GT_REGWR(I2C_CONTROL, I2C_ENABLE) blr/* * I2C Read byte from device. Use RANDOM READ protocol. */ .globl boot_i2c_readboot_i2c_read: mflr r4 /* Save return address */ GT_REGSET(I2C_CONTROL, I2C_START_BIT) bl wait_int cmpwi r6, START_CONDITION_TRA bne boot_i2c_read_bad /* Bad start, exit *//**/ rlwinm r6, r3, 25, 28, 30 /* Get device part of addr */ ori r6, r6, 0xa0 /* Device type + write(addr) */ GT_REGAD(I2C_DATA) /* Send device address */ stwbrx r6, 0, (r5) GT_REGCLR(I2C_CONTROL, I2C_INT_FLAG) /* Send it */ bl wait_int cmpwi r6, ADDR_AND_WRITE_BIT_TRA_ACK_REC bne boot_i2c_read_bad/**/ andi. r6, r3, 0xff GT_REGAD(I2C_DATA) /* Send address */ stwbrx r6, 0, (r5) GT_REGCLR(I2C_CONTROL, I2C_INT_FLAG) /* Send it */ bl wait_int cmpwi r6, SLAVE_REC_WRITE_DATA_ACK_TRA bne boot_i2c_read_bad/**/ GT_REGSET(I2C_CONTROL, I2C_START_BIT) /* Restart! */ GT_REGCLR(I2C_CONTROL, I2C_INT_FLAG) /* Send it */ bl wait_int cmpwi r6, RSTART_CONDITION_TRA bne boot_i2c_read_bad /* Bad start, exit *//**/ rlwinm r6, r3, 25, 28, 30 /* Get device part of addr */ ori r6, r6, 0xa1 /* Device type + read */ GT_REGAD(I2C_DATA) /* Send device address */ stwbrx r6, 0, (r5) GT_REGCLR(I2C_CONTROL, I2C_INT_FLAG) /* Send it */ bl wait_int cmpwi r6, ADDR_AND_READ_BIT_TRA_ACK_REC bne boot_i2c_read_bad/**/ GT_REGCLR(I2C_CONTROL, I2C_INT_FLAG | I2C_ACK) /* Get data *//**/ bl wait_int cmpwi r6, MAS_REC_READ_DATA_ACK_NOT_TRA bne boot_i2c_read_bad GT_REGRD(I2C_DATA) or r3, r6 ,r6 b boot_i2c_read_end/**/boot_i2c_read_bad: li r3, -1boot_i2c_read_end: GT_REGSET(I2C_CONTROL, I2C_STOP_BIT) GT_REGCLR(I2C_CONTROL, I2C_INT_FLAG) mtlr r4 blr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -