Ejemplo n.º 1
0
/*************************************************************************
  Issues a start condition and sends address and transfer direction.
  return 0 = device accessible, 1= failed to access device
 *************************************************************************/
unsigned char i2c_start(unsigned char address)
{
    uint8_t   twst;

    // send START condition
    TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);

    // wait until transmission completed
    CHECK_TIMEOUT_PRE();
    while(!(TWCR & (1<<TWINT))) { CHECK_TIMEOUT(2); };

    // check value of TWI Status Register. Mask prescaler bits.
    twst = TW_STATUS & 0xF8;
    if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;

    // send device address
    TWDR = address;
    TWCR = (1<<TWINT) | (1<<TWEN);

    // wail until transmission completed and ACK/NACK has been received
    CHECK_TIMEOUT_PRE2();
    while(!(TWCR & (1<<TWINT))) { CHECK_TIMEOUT(2); };

    // check value of TWI Status Register. Mask prescaler bits.
    twst = TW_STATUS & 0xF8;
    if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;

    return 0;

}/* i2c_start */
Ejemplo n.º 2
0
/*************************************************************************
  Send one byte to I2C device

Input:    byte to be transfered
Return:   0 write successful
1 write failed
 *************************************************************************/
unsigned char i2c_write( unsigned char data )
{
    uint8_t   twst;

    // send data to the previously addressed device
    TWDR = data;
    TWCR = (1<<TWINT) | (1<<TWEN);

    // wait until transmission completed
    CHECK_TIMEOUT_PRE();
    while(!(TWCR & (1<<TWINT))) { CHECK_TIMEOUT(2) };

    // check value of TWI Status Register. Mask prescaler bits
    twst = TW_STATUS & 0xF8;
    if( twst != TW_MT_DATA_ACK) return 1;
    return 0;

}/* i2c_write */


/*************************************************************************
  Read one byte from the I2C device, request more data from device

Return:  byte read from I2C device
 *************************************************************************/
unsigned char i2c_readAck(void)
{
    TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
    CHECK_TIMEOUT_PRE();
    while(!(TWCR & (1<<TWINT))) { CHECK_TIMEOUT(2); };

    return TWDR;

}/* i2c_readAck */
Ejemplo n.º 3
0
/*************************************************************************
  Read one byte from the I2C device, read is followed by a stop condition

Return:  byte read from I2C device
 *************************************************************************/
unsigned char i2c_readNak(void)
{
    TWCR = (1<<TWINT) | (1<<TWEN);
    CHECK_TIMEOUT_PRE();
    while(!(TWCR & (1<<TWINT))) { CHECK_TIMEOUT(2); };

    return TWDR;

}/* i2c_readNak */
Ejemplo n.º 4
0
/*************************************************************************
  Terminates the data transfer and releases the I2C bus
 *************************************************************************/
void i2c_stop(void)
{
    /* send stop condition */
    TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);

    // wait until stop condition is executed and bus released
    CHECK_TIMEOUT_PRE();
    while(TWCR & (1<<TWSTO)) { CHECK_TIMEOUT(); };

}/* i2c_stop */
Ejemplo n.º 5
0
/*************************************************************************
  Issues a start condition and sends address and transfer direction.
  If device is busy, use ack polling to wait until device is ready

Input:   address and transfer direction of I2C device
 *************************************************************************/
void i2c_start_wait(unsigned char address)
{
    uint8_t   twst;


    while ( 1 )
    {
        // send START condition
        TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);

        // wait until transmission completed
        while(!(TWCR & (1<<TWINT)));

        // check value of TWI Status Register. Mask prescaler bits.
        twst = TW_STATUS & 0xF8;
        if ( (twst != TW_START) && (twst != TW_REP_START)) continue;

        // send device address
        TWDR = address;
        TWCR = (1<<TWINT) | (1<<TWEN);

        // wail until transmission completed
        while(!(TWCR & (1<<TWINT)));

        // check value of TWI Status Register. Mask prescaler bits.
        twst = TW_STATUS & 0xF8;
        if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) )
        {
            /* device busy, send stop condition to terminate write operation */
            TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);

            // wait until stop condition is executed and bus released
            CHECK_TIMEOUT_PRE();
            while(TWCR & (1<<TWSTO)) { CHECK_TIMEOUT(); };

            continue;
        }
        //if( twst != TW_MT_SLA_ACK) return 1;
        break;
    }

}/* i2c_start_wait */
/*****************************************************************************
 函 数 名  : hi_bbp_ccpu_reset_and_wait_idle
 功能描述  : c核复位后关闭并等bbp进入空闲态
 输入参数  : 无
 输出参数  : 无
 返 回 值  : int
 调用函数  : ccpu_reset_bbp_and_wait_idle
 被调函数  :

 修改历史      :
  1.日    期   : 2014年3月12日
    修改内容   : 新生成函数

*****************************************************************************/
int hi_bbp_ccpu_reset_and_wait_idle(void)
{
    unsigned int regvalue = 0;
    unsigned int u32slicebegin = 0;
    u32 bbp_dma_base = g_bbpinfo.part[BBP_DMA].reg_base;
    u32 wbbp_base = g_bbpinfo.part[BBP_WBBP].reg_base;
    u32 abb_base = g_bbpinfo.part[BBP_ABB].reg_base;
    u32 sysapcrg_base = 0;
    u32 i = 0;

    bsp_reset_timestamp(0xaa, STAMP_RESET_BBP_DEBUG);

    /*查询BBPHY桥PLL时钟的状态*/
    sysapcrg_base = (u32)bsp_sysctrl_addr_byindex(sysctrl_ap_pericrg);
    /*查询是否来源于DSPPLL 0xfff350dc[bit 4\5] == 2*/
    regvalue = readl(sysapcrg_base + 0xdc);
    regvalue &= (unsigned int)(0x3 << 4);
    if(regvalue == 0x20){
        bsp_reset_timestamp(0xbb, STAMP_RESET_BBP_DEBUG);
        /*dsp pll是否关闭 0xe020020c bit26*/
        regvalue = readl(sysreg_base + 0x20c);
        regvalue &= (unsigned int)(0x1 << 26);
        if(regvalue != (unsigned int)(0x1 << 26)){
            bsp_reset_timestamp(0x1, STAMP_RESET_WBBP_MSTER_STOP);
            return BBP_OK;
        }
    }

    /*查询BBPHY桥门控参考时钟的状态*/
    regvalue = readl(sysreg_base + 0x20);
    regvalue &= (unsigned int)(0x1 << 24);
    if(regvalue != (unsigned int)(0x1 << 24)){
        bsp_reset_timestamp(0x2, STAMP_RESET_WBBP_MSTER_STOP);
        return BBP_OK;
    }

    /*查询BBP crg解复位的状态*/
    regvalue = readl(sysreg_base + 0x80);
    regvalue &= (unsigned int)0x1;
    if(regvalue != 0x0){
        bsp_reset_timestamp(0x3, STAMP_RESET_WBBP_MSTER_STOP);
        return BBP_OK;
    }
    /*查询COMM的cmos状态*/
    regvalue = readl(sysreg_base + 0xe04);
    regvalue &= (unsigned int)0x200;
    if(regvalue != 0x200){
        bsp_reset_timestamp(0x4, STAMP_RESET_WBBP_MSTER_STOP);
        return BBP_OK;
    }
    /*查询COMM的iso状态*/
    regvalue = readl(sysreg_base + 0xe0c);
    regvalue &= (unsigned int)0x200;
    if(regvalue != 0x0){
        bsp_reset_timestamp(0x5, STAMP_RESET_WBBP_MSTER_STOP);
        return BBP_OK;
    }
    /*查询COMM的clk状态*/
    regvalue = readl(sysreg_base + 0x38);
    regvalue &= (unsigned int)0x2;
    if(regvalue != 0x2){
        bsp_reset_timestamp(0x6, STAMP_RESET_WBBP_MSTER_STOP);
        return BBP_OK;
    }
    /*查询COMM的reset状态*/
    regvalue = readl(sysreg_base + 0x80);
    regvalue &= (unsigned int)0x2;
    if(regvalue != 0x0){
        bsp_reset_timestamp(0x7, STAMP_RESET_WBBP_MSTER_STOP);
        return BBP_OK;
    }

    bsp_reset_timestamp(0x1, STAMP_RESET_BBP_DEBUG);

    /*disable dma*/
    writel(0x0, bbp_dma_base + 0x0294);/*data*/
    writel(0x0, bbp_dma_base + 0x02A8);/*channel_0*/
    writel(0x0, bbp_dma_base + 0x02B4);/*channel_1*/
    writel(0x0, bbp_dma_base + 0x02B8);/*log*/
    bsp_reset_timestamp(0x2, STAMP_RESET_BBP_DEBUG);
    /*comm*/
    for (i = 0; i < 96; i++)
    {
        writel(0x0, bbp_dma_base + 0x0308 + 0x10 *i);
    }
    bsp_reset_timestamp(0x3, STAMP_RESET_BBP_DEBUG);
    /*fast*/
    for (i = 0; i < 32; i++)
    {
        regvalue = readl(bbp_dma_base + 0x0A0C + 0x10 *i);
        regvalue &= ~(1 << 28);
        writel(regvalue, bbp_dma_base + 0x0A0C + 0x10 *i);
    }
    bsp_reset_timestamp(0x4, STAMP_RESET_BBP_DEBUG);

    /*delay 50ms*/
    u32slicebegin = bsp_get_slice_value();
    do{
    }while(CHECK_TIMEOUT_50MS(u32slicebegin));
    bsp_reset_timestamp(0x5, STAMP_RESET_BBP_DEBUG);
    /*reset bbpdma*/
    writel(0x7, bbp_dma_base);
    bsp_reset_timestamp(0x6, STAMP_RESET_BBP_DEBUG);
    /*delay 50ms*/
    u32slicebegin = bsp_get_slice_value();
    do{
    }while(CHECK_TIMEOUT_50MS(u32slicebegin));
    bsp_reset_timestamp(0x7, STAMP_RESET_BBP_DEBUG);

    /*查询BBP DMA 8/9/10bit 3类通道(包含所有)是否空闲*/
    u32slicebegin = bsp_get_slice_value();
    do{
        regvalue = readl(bbp_dma_base+ 0x10);
        regvalue &= (unsigned int)0x700;
    }while((0x0 != regvalue) && CHECK_TIMEOUT(u32slicebegin));
    if(0x0 != regvalue){
        *(u32 *)STAMP_RESET_IDLE_FAIL_COUNT |= (u32)0x1 << ENUM_RESET_BBP_DMA;
        goto wbbp_idle;
    }

    bsp_reset_timestamp(bsp_get_slice_value(), STAMP_RESET_BBP_DMA_ENTER_IDLE);

wbbp_idle:
    /*查询ABB的解复位状态*/
    regvalue = readl(sysreg_base + 0x80);
    regvalue &= (unsigned int)0x80000000;
    if(regvalue != 0x0){
        bsp_reset_timestamp(0x1, STAMP_RESET_WBBP_ENTER_IDLE);
        goto comm_rst;
    }

    /*查询ABB PLL的状态*/
    regvalue = readl(abb_base + (0xa5 << 2));
    regvalue &= (unsigned int)0x22;
    if(regvalue != 0x22){
        bsp_reset_timestamp(0x2, STAMP_RESET_WBBP_ENTER_IDLE);
        goto comm_rst;
    }

    /*查询WBBP(wps)的clk状态*/
    regvalue = readl(sysreg_base + 0x38);
    regvalue &= (unsigned int)0x40;
    if(regvalue != 0x40){
        bsp_reset_timestamp(0x3, STAMP_RESET_WBBP_ENTER_IDLE);
        goto comm_rst;
    }

    /*查询WBBP的reset状态*/
    regvalue = readl(sysreg_base + 0x80);
    regvalue &= (unsigned int)0x40;
    if(regvalue != 0x0){
        bsp_reset_timestamp(0x4, STAMP_RESET_WBBP_ENTER_IDLE);
        goto comm_rst;
    }

    /*查询WBBP的ISO状态*/
    regvalue = readl(sysreg_base + 0xe0c);
    regvalue &= (unsigned int)0x100;
    if(regvalue != 0x0){
        bsp_reset_timestamp(0x5, STAMP_RESET_WBBP_ENTER_IDLE);
        goto comm_rst;
    }

    /*查询WBBP的MTCOMS状态*/
    regvalue = readl(sysreg_base + 0xe04);
    regvalue &= (unsigned int)0x100;
    if(regvalue != 0x100){
        bsp_reset_timestamp(0x6, STAMP_RESET_WBBP_ENTER_IDLE);
        goto comm_rst;
    }

    /*配置WBBP*/
    bsp_reset_timestamp(bsp_get_slice_value(), STAMP_RESET_WBBP_MSTER_STOP);
    writel(0x0, wbbp_base + 0x9070);

    bsp_reset_timestamp(bsp_get_slice_value(), STAMP_RESET_WBBP_SLAVE_STOP);
    writel(0x0, wbbp_base + 0x29070);

    bsp_reset_timestamp(0x8, STAMP_RESET_BBP_DEBUG);

    /*查询WBBP 0/16/17/18/19是否空闲*/
    u32slicebegin = bsp_get_slice_value();
    do{
        regvalue = readl(wbbp_base + 0x949c);
        regvalue &= (unsigned int)0xF0001;
    }while((0x0 != regvalue) && CHECK_TIMEOUT(u32slicebegin));
    if(0x0 != regvalue){
        bsp_reset_timestamp((0x1U << ENUM_RESET_WBBP)|*(u32 *)STAMP_RESET_IDLE_FAIL_COUNT, STAMP_RESET_IDLE_FAIL_COUNT);
        goto comm_rst;
    }
    bsp_reset_timestamp(bsp_get_slice_value(), STAMP_RESET_WBBP_ENTER_IDLE);

comm_rst:
    bsp_reset_timestamp(0x9, STAMP_RESET_BBP_DEBUG);
    /*reset bbpcomm*/
    writel(0x2, sysreg_base + 0x78);
    bsp_reset_timestamp(0xa, STAMP_RESET_BBP_DEBUG);

    return BBP_OK;
}