/************************************************************************* 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 */
/************************************************************************* 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 */
/************************************************************************* 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 */
/************************************************************************* 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 */
/************************************************************************* 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; }