⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.s

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 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 + -