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

📄 twi.c

📁 IAR5.2下 AT91SAM9260 ARM 对 MCP2515 控制源化码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ----------------------------------------------------------------------------
 *         ATMEL Microcontroller Software Support 
 * ----------------------------------------------------------------------------
 * Copyright (c) 2008, Atmel Corporation
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the disclaimer below.
 *
 * Atmel's name may not be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
 * ----------------------------------------------------------------------------
 */

#ifndef trace_LEVEL
    #define trace_LEVEL  1
#endif

//------------------------------------------------------------------------------
//         Headers
//------------------------------------------------------------------------------

#include "twi.h"
#include <pio/pio.h>
#include <pmc/pmc.h>
#include <utility/math.h>
#include <utility/assert.h>
#include <utility/trace.h>

#define TWI_CLOCK 	100000
#define  ERROR 	(AT91C_TWI_NACK_SLAVE)		//状态寄存器的一位,如果置1表示从机未应答

//------------------------------------------------------------------------------
//         Global functions
//------------------------------------------------------------------------------


//*=============================================================================
//* \fn    AT91F_TWI_CfgPIO
//* \brief Configure PIO controllers to drive TWI signals
//*=============================================================================
void TWI_CfgPIO (void)
{
	// Configure PIO controllers to periph mode
	PIO_CfgPeriph(AT91C_BASE_PIOA,                      // PIO controller base address
		      ((unsigned int) AT91C_PA23_TWD     ) |
		      ((unsigned int) AT91C_PA24_TWCK    ), // Peripheral A
		      0); // Peripheral B
}


//*=============================================================================
//* 函数名称:TWI_Configure
//* 函数功能:配置 TWI 时钟及模式
//* 入口参数:1. twck: TWI 指针
//*           2. mck : 系统主频
//* 返回值  :无
//*=============================================================================
void TWI_Configure(AT91S_TWI *pTwi, unsigned int twck, unsigned int mck)
{
    unsigned int ckdiv = 0;
    unsigned int cldiv;
    unsigned char ok = 0;

    trace_LOG(trace_DEBUG, "-D- TWI_Configure()\r\n");
    SANITY_CHECK(pTwi);

    // Reset the TWI
    pTwi->TWI_CR = AT91C_TWI_SWRST;

    // Set master mode
    pTwi->TWI_CR = AT91C_TWI_MSEN;

    // Configure clock
    while (!ok) 
    { 
        cldiv = ((mck / (2 * twck)) - 3) / power(2, ckdiv);
        if (cldiv <= 255) 
            ok = 1;
        else 
            ckdiv++;
    }

    ASSERT(ckdiv < 8, "-F- Cannot find valid TWI clock parameters\r\n");
    //trace_LOG(trace_INFO, "-D- Using CKDIV = %u and CLDIV/CHDIV = %u\r\n", ckdiv, cldiv);
    
    pTwi->TWI_CWGR = (ckdiv << 16) | (cldiv << 8) | cldiv;
}



//*----------------------------------------------------------------------------
//* \fn    AT91F_TWI_Configure
//* \brief Configure TWI in master mode
//*----------------------------------------------------------------------------
void AT91F_TWI_Configure ( AT91PS_TWI pTWI )          // \arg pointer to a TWI controller
{
    //* Disable interrupts
    pTWI->TWI_IDR = (unsigned int) -1;

    //* Reset peripheral
    pTWI->TWI_CR = AT91C_TWI_SWRST;

    //* Set Master mode
    pTWI->TWI_CR = AT91C_TWI_MSEN;

}


//*============================================================================
//*		                 TWI初始化
//*============================================================================
//*============================================================================
//* 函数名称:AT91F_SetTwiClock
//* 函数功能:设置TWI时钟
//* 入口参数:无
//* 返回值  :无
//*============================================================================
void AT91F_SetTwiClock(const AT91PS_TWI pTwi)
{
	int sclock;

	/* Here, CKDIV = 1 and CHDIV=CLDIV  ==> CLDIV = CHDIV = 1/4*((Fmclk/FTWI) -6)*/

	sclock = (10*BOARD_MCK / TWI_CLOCK);
	if (sclock % 10 >= 5)
		sclock = (sclock /10) - 5;
	else
		sclock = (sclock /10)- 6;
	sclock = (sclock + (4 - sclock %4)) >> 2;	// div 4

        pTwi->TWI_CWGR	= 0x00010000 | sclock | (sclock << 8);
}


//*============================================================================
//* 函数名称: TWI_Open
//* 函数功能: 打开 TWI 
//*============================================================================
void TWI_Open(void)
{
	// 配制 PIO 为 TWI
	TWI_CfgPIO ();
                
	PIO_CfgOpendrain(AT91C_BASE_PIOA, AT91C_PA23_TWD | AT91C_PA24_TWCK);		//配制 PA23,PA24 为开漏

	// 使能 TWI 电源时钟
	PMC_EnablePeripheral(AT91C_ID_TWI );
	
	// 配制 TWI 为主模式
	TWI_Configure (AT91C_BASE_TWI, TWI_CLOCK, BOARD_MCK);
}


//*============================================================================
//* 函数名称: AT91F_TWI_Close
//* 函数功能: 关闭 TWI 
//*============================================================================
void TWI_Close(void)
{
    // 禁用 TWI 电源时钟
    PMC_DisablePeripheral( AT91C_ID_TWI );
}



//*=============================================================================
//* 函数名称:TWI_Stop
//* 函数功能:发送停止位
//* 入口参数:1. twck: TWI 指针
//* 返回值  :无
//*=============================================================================
void TWI_Stop(AT91S_TWI *pTwi)
{
    SANITY_CHECK(pTwi);

    pTwi->TWI_CR = AT91C_TWI_STOP;
}

//------------------------------------------------------------------------------
/// Starts a read operation on the TWI bus with the specified slave, and returns
/// immediately. Data must then be read using TWI_ReadByte() whenever a byte is
/// available (poll using TWI_ByteReceived()).
/// \param pTwi  Pointer to an AT91S_TWI instance.
/// \param address  Slave address on the bus.
/// \param iaddress  Optional internal address bytes.
/// \param isize  Number of internal address bytes.
//-----------------------------------------------------------------------------
void TWI_StartRead( AT91S_TWI *pTwi,
                    unsigned char address,
                    unsigned int iaddress,
                    unsigned char isize)
{
    trace_LOG(trace_DEBUG, "-D- TWI_StartRead()\n\r");
    SANITY_CHECK(pTwi);
    SANITY_CHECK((address & 0x80) == 0);
    SANITY_CHECK((iaddress & 0xFF000000) == 0);
    SANITY_CHECK(isize < 4);

    // Set slave address and number of internal address bytes
    pTwi->TWI_MMR = (isize << 8) | AT91C_TWI_MREAD | (address << 16);

    // Set internal address bytes
    pTwi->TWI_IADR = iaddress;

    // Send START condition
    pTwi->TWI_CR = AT91C_TWI_START;
}


//-----------------------------------------------------------------------------
/// Reads a byte from the TWI bus. The read operation must have been started
/// using TWI_StartRead() and a byte must be available (check with
/// TWI_ByteReceived()).
/// Returns the byte read.
/// \param pTwi  Pointer to an AT91S_TWI instance.
//-----------------------------------------------------------------------------
unsigned char TWI_ReadByte(AT91S_TWI *pTwi)
{
    SANITY_CHECK(pTwi);

    return pTwi->TWI_RHR;
}


//-----------------------------------------------------------------------------
/// Sends a byte of data to one of the TWI slaves on the bus. This function
/// must be called once before TWI_StartWrite() with the first byte of data
/// to send, then it shall be called repeatedly after that to send the
/// remaining bytes.
/// \param pTwi  Pointer to an AT91S_TWI instance.
/// \param byte  Byte to send.
//-----------------------------------------------------------------------------
void TWI_WriteByte(AT91S_TWI *pTwi, unsigned char byte)
{
    SANITY_CHECK(pTwi);

    pTwi->TWI_THR = byte;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -