Beispiel #1
0
void i2c_reset(i2c_t *obj) {
    i2c_stop(obj);
}
Beispiel #2
0
//Write 8bit data to register with 8 bit address
void Magnetometer::hmc_write(byte address, byte data) {
  i2c_start_wait( (ADDR << 1) | I2C_WRITE ); // Start / Device address and Write (0)
  i2c_write(address); // 8bit register address 
  i2c_write(data); // 8 bit data
  i2c_stop(); // End condition
}
Beispiel #3
0
void i2c_writeReg(uint8_t add, uint8_t reg, uint8_t val) {
  i2c_rep_start(add<<1); // I2C write direction
  i2c_write(reg);        // register selection
  i2c_write(val);        // value to write in register
  i2c_stop();
}
Beispiel #4
0
/*
**********************************************************************************************************************
*                                               i2c_init
*
* Description:
*
* Arguments  :
*
* Returns    :    none
*
* Notes      :    none
*
**********************************************************************************************************************
*/
void i2c_exit(void)
{
#ifndef  CONFIG_CPUS_I2C
	int reg_value = 0;
	reg_value = readl(CCMU_BUS_CLK_GATING_REG3);
	reg_value &= ~(1<<bus_num);
	writel(reg_value,CCMU_BUS_CLK_GATING_REG3);
#else
	int reg_value = 0;
	reg_value = *((unsigned int *)(R_PRCE_APB0_RESET));
	reg_value &= ~(0x01 << 6);
	*((unsigned int *)(R_PRCE_APB0_RESET)) = reg_value;
	__msdelay(1);
	reg_value = *((unsigned int *)(R_PRCM_APB0_GATING));
	reg_value &= ~(0x01 << 6);
	*((unsigned int *)(R_PRCM_APB0_GATING)) = reg_value;
	__msdelay(1);

#endif

 return ;
}/*
****************************************************************************************************
*
*                                       i2c_read
*
*  Description:
*
*
*  Parameters:
*
*  Return value:
*
*  Read/Write interface:
*    chip:    I2C slave chip address, range 0..127
*    addr:    Memory (register) address within the chip
*    alen:    Number of bytes to use for addr (
*             0, 1: addr len = 8bit
*			  2: addr len = 16bit
*			  3, 4: addr len = 32bit
*
*    buffer:  Where to read/write the data
*    len:     How many bytes to read/write
*
*    Returns: 0 on success, not 0 on failure
*
****************************************************************************************************
*/
int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
{
    int   i, ret, ret0, addrlen;
    char  *slave_reg;

	ret0 = -1;
    ret = i2c_sendstart();
    if(ret)
	{
		goto i2c_read_err_occur;
	}

    ret = i2c_sendslaveaddr(chip, I2C_WRITE);
    if(ret)
    {
	    goto i2c_read_err_occur;
	}
    //send byte address
    if(alen >= 3)
    {
	addrlen = 2;
    }
    else if(alen <= 1)
    {
	addrlen = 0;
    }
    else
    {
	addrlen = 1;
    }
    slave_reg = (char *)&addr;
    for (i = addrlen; i>=0; i--)
    {
    	ret = i2c_sendbyteaddr(slave_reg[i] & 0xff);
    	if(ret)
    	{
    		goto i2c_read_err_occur;
    	}
    }
    ret = i2c_sendRestart();
    if(ret)
	{
		goto i2c_read_err_occur;
	}
    ret = i2c_sendslaveaddr(chip, I2C_READ);
    if(ret)
    {
        goto i2c_read_err_occur;
	}
    //get data
	ret = i2c_getdata(buffer, len);
	if(ret)
	{
		goto i2c_read_err_occur;
	}
    ret0 = 0;

i2c_read_err_occur:
	i2c_stop();

	return ret0;
}
int main()
{

  _delay_ms(1000);
  _delay_ms(1000);
  _delay_ms(1000);

  
  pinMode(BUTTON,INPUT);
  pinMode(LED,OUTPUT);
  digitalWrite(LED,LOW);
  
  // -- set up lines for I2C --
  
  i2cpin(SDA,HIGH);
  i2cpin(SDA,HIGH);
 
  _delay_ms(100);
  
  // check if I2C pullup resistors are doing their job
  if ((bit_is_set(PINB,SDA)) && (bit_is_set(PINB,SDA)))
  {
    i2c_available=1;
  } else {
    i2c_available=0;
  }
  
  
 
  // -- set up control lines for HV parallel programming --
  pinMode(VCC, OUTPUT);
  pinMode(RST, OUTPUT);
  pinMode(DATAOUT, OUTPUT);
  pinMode(INSTOUT, OUTPUT);
  pinMode(CLKOUT, OUTPUT);
  pinMode(DATAIN, OUTPUT);  // configured as input when in programming mode
  
  // Initialize output pins as needed
  digitalWrite(RST, HIGH);  // Level shifter is inverting, this shuts off 12V


  // show welcome message on LCD if attached
  if(i2c_available)
  {
    
    show_title_msg();
    _delay_ms(100);
    show_version_msg();
    _delay_ms(1000);
    show_instructions_msg();
  }
   
  while (1)
  {
  
    // indicate with LED that we are ready
    digitalWrite(LED,HIGH);
    _delay_ms(2000);
    digitalWrite(LED,LOW);
	
    if(i2c_available)
    {
      show_title_msg();
    }
	
    while (bit_is_clear(PINA,BUTTON)) {  }  // wait until keypress is detected     

	if(i2c_available)
    {
      i2c_start(LCD_I2C_DEVICE_ID);
      i2c_tx(12);  // clear lcd
      i2c_stop(); 
    }
	  
	  
    
   
   
    _delay_ms(100);

    int btcounter=0;

    while (bit_is_set(PINA,BUTTON))
    {
      btcounter++;
      _delay_ms(10);
     
    }

    // button has been released

    if (btcounter < 200)
    {
      // short button press detected
   
      if(readFuses())
      {
	    // successfully communicated with target device, blink three times briefly

        digitalWrite(LED,HIGH);
        _delay_ms(50);
        digitalWrite(LED,LOW);
        _delay_ms(300);
		
	    digitalWrite(LED,HIGH);
        _delay_ms(50);
        digitalWrite(LED,LOW);
        _delay_ms(300);

        digitalWrite(LED,HIGH);
        _delay_ms(50);
        digitalWrite(LED,LOW);
   
	  } else {

		// target programming device not found, blink 20x briefly
        blink_nodev_err();
	  
	  }
		
		
	 
    } else {

	  // long button press detected
	
      if(writeFuses())
	  {
	    // successfully communicated with target device, blink three times long
		
		digitalWrite(LED,HIGH);
        _delay_ms(1000);
        digitalWrite(LED,LOW);
        _delay_ms(500);
	  
	    digitalWrite(LED,HIGH);
        _delay_ms(1000);
        digitalWrite(LED,LOW);
        _delay_ms(500);
		
		digitalWrite(LED,HIGH);
        _delay_ms(1000);
        digitalWrite(LED,LOW);
      
		
	  } else {
	  
	    // target programming device not found, blink 20x briefly
	    blink_nodev_err();
	  
	  }

  
    
    }

    _delay_ms(1000);
    _delay_ms(1000);
    _delay_ms(1000);
    _delay_ms(1000);
   

  }

  return 0;

}
Beispiel #6
0
static int i2c_transfer(uint8_t addr, void *buf, size_t len)
{
    if (addr & 0x01) {
        // Set up master-receiver DMA
        //
        DMA1_Stream0->CR  &= ~DMA_SxCR_EN;
        while (DMA1_Stream0->CR  & DMA_SxCR_EN);

        DMA1->LIFCR = DMA_LIFCR_CTCIF0 | DMA_LIFCR_CHTIF0  |
                      DMA_LIFCR_CTEIF0 | DMA_LIFCR_CDMEIF0 |
                      DMA_LIFCR_CFEIF0;

        DMA1_Stream0->PAR  = (uint32_t)&I2C1->DR;
        DMA1_Stream0->M0AR = (uint32_t)buf;
        DMA1_Stream0->NDTR = len;
        DMA1_Stream0->CR   = DMA_Channel_1 | DMA_SxCR_MINC | DMA_SxCR_TCIE;
        DMA1_Stream0->CR  |= DMA_SxCR_EN;

        if (len > 1)
            I2C1->CR1 |=  I2C_CR1_ACK;
        else
            I2C1->CR1 &= ~I2C_CR1_ACK;
    }
    else {
        // Set up master-transmitter DMA
        //
        DMA1_Stream7->CR  &= ~DMA_SxCR_EN;
        while (DMA1_Stream7->CR  & DMA_SxCR_EN);

        DMA1->HIFCR = DMA_HIFCR_CTCIF7 | DMA_HIFCR_CHTIF7  |
                      DMA_HIFCR_CTEIF7 | DMA_HIFCR_CDMEIF7 |
                      DMA_HIFCR_CFEIF7;

        DMA1_Stream7->PAR  = (uint32_t)&I2C1->DR;
        DMA1_Stream7->M0AR = (uint32_t)buf;
        DMA1_Stream7->NDTR = len;
        DMA1_Stream7->CR   = DMA_Channel_1 | DMA_SxCR_MINC | DMA_SxCR_DIR_0;
        DMA1_Stream7->CR  |= DMA_SxCR_EN;
    }

    // Send START condition
    //
    s_addr = addr;
    I2C1->CR2 |= I2C_CR2_LAST | I2C_CR2_DMAEN;
    I2C1->CR2 |= I2C_CR2_ITEVTEN | I2C_CR2_ITERREN;
    I2C1->CR1 |= I2C_CR1_START;

    // Wait for the transfer to finish
    //
    TickType_t  timeout = 2 * (len * 9 * configTICK_RATE_HZ / I2C_SPEED + 1);
    TickType_t  t0 = xTaskGetTickCount();

    int res = xSemaphoreTake(i2c_irq_sem, timeout);

    while (I2C1->SR2 & I2C_SR2_BUSY) {
        if (xTaskGetTickCount() - t0 > timeout) {
            res = pdFAIL;
            break;
        }
    }

    uint16_t sr1 = I2C1->SR1;

    if (res != pdPASS)          i2c_stats.timeouts++;
    if (sr1 & I2C_SR1_ARLO)     i2c_stats.arlo++;
    if (sr1 & I2C_SR1_BERR)     i2c_stats.berr++;
    if (I2C1->SR1 & I2C_SR1_AF) i2c_stats.naks++;

    if (res != pdPASS || sr1 & I2C_SR1_ARLO || sr1 & I2C_SR1_BERR) {
        // Something went wrong on the bus.. try to reinitialize.
        //
        i2c_stop();
        i2c_init();
        errno = EBUSY;
        return -1;
    }

    if (I2C1->SR1 & I2C_SR1_AF) {
        // Slave address not acknowledged
        //
        I2C1->SR1 = 0;
        errno = ENXIO;
        return -1;
    }

    if (addr & 1)
        i2c_stats.rx_bytes += len;
    else
        i2c_stats.tx_bytes += len;

    return len;
}
Beispiel #7
0
/*
 * display the I2C status and error message and release the I2C bus
 */
void i2c_error(const char * message, uint8_t cr, uint8_t status)
{
  i2c_stop();
  printf_P(message);
  printf_P(s_fmt_i2c_error, cr, status);
}
Beispiel #8
0
/*#---------------------------------------------------------------------------
*#
*# FUNCTION NAME: i2c_writereg
*#
*# DESCRIPTION  : Writes a value to an I2C device
*#
*#--------------------------------------------------------------------------*/
int
i2c_writereg(unsigned char theSlave, unsigned char theReg, 
	     unsigned char theValue)
{
	int error, cntr = 3;
	unsigned long flags;

	spin_lock(&i2c_lock);

	do {
		error = 0;
		/*
		 * we don't like to be interrupted
		 */
		local_irq_save(flags);

		i2c_start();
		/*
		 * send slave address
		 */
		i2c_outbyte((theSlave & 0xfe));
		/*
		 * wait for ack
		 */
		if(!i2c_getack())
			error = 1;
		/*
		 * now select register
		 */
		i2c_dir_out();
		i2c_outbyte(theReg);
		/*
		 * now it's time to wait for ack
		 */
		if(!i2c_getack())
			error |= 2;
		/*
		 * send register register data
		 */
		i2c_outbyte(theValue);
		/*
		 * now it's time to wait for ack
		 */
		if(!i2c_getack())
			error |= 4;
		/*
		 * end byte stream
		 */
		i2c_stop();
		/*
		 * enable interrupt again
		 */
		local_irq_restore(flags);
		
	} while(error && cntr--);

	i2c_delay(CLOCK_LOW_TIME);

	spin_unlock(&i2c_lock);

	return -error;
}
void evalOpcode(unsigned char opcode) {

    int i;
    int16 opr1, opr2, opr3;
    unsigned int16 genPurpose = 0;

    if (opcode & 0b10000000) {
        genPurpose = gblMemPtr + 2;
        gblMemPtr = ((((unsigned int16)opcode & 0b00111111) << 8) + 2*fetchNextOpcode());
        opr1 = fetchNextOpcode();
        if (opcode & 0b01000000) {
            for (i = 0; i < (opr1 + 3); i++) {
                inputPop();
            }
        }
        for (i = 0; i < opr1; i++) {
            inputPush (stkPop());
        }
        inputPush (gblStkPtr);
        inputPush (genPurpose);
        inputPush(gblInputStkPtr - (opr1 + 2));
        return;
    }
    switch (opcode) {
    case CODE_END:
        gblLogoIsRunning = 0;
        output_low (RUN_LED);
        // clear thes variables just in case.
        gblLoopAddress = 0;
        gblRepeatCount = 0;
        break;
    case NUM8:
        int8 Hi3 = fetchNextOpcode();
        stkPush(Hi3);
        break;
    case NUM16:
        int8 Hi2 = fetchNextOpcode();
        int8 Lo2 = fetchNextOpcode();
        unsigned int16 teste4 = Hi2 << 8;
        teste4 += Lo2;
        stkPush (teste4);
        break;
    case LIST:
        stkPush(gblMemPtr + 2); //incremento de 2 em 2
        gblMemPtr += (2 * fetchNextOpcode());
        break;
    case EOL:
        genPurpose = stkPop();
        if (genPurpose > gblMemPtr) {
            //printf(usb_cdc_putc,"genPurpose >>>> gblMemPtr");
            gblMemPtr = genPurpose;
        } else {
            //printf(usb_cdc_putc,"genPurpose <<<< gblMemPtr");
            gblMemPtr = genPurpose;
            gblRepeatCount = stkPop();   // repeat count
            //printf(usb_cdc_putc," gblRepeatCount %Lu \n",genPurpose);
            if (gblRepeatCount > 1)
                gblRepeatCount--;
            if (gblRepeatCount != 1) {
                stkPush (gblRepeatCount);
                stkPush (gblMemPtr);
            }
        }
        break;
    case EOLR:
        if (stkPop()) {   // if condition is true
            stkPop();        // throw away the loop address
            gblMemPtr = stkPop(); // fetch the next command address
        } else { // if condition if false -> keep on looping.
            gblMemPtr = stkPop();
            stkPush (gblMemPtr);
            delay_ms(5); // this prevents the waituntil loop to execute too rapidly
            // which has proven to cause some problems when reading sensor values.
        }
        break;
    case LTHING:
        genPurpose = 2 * fetchNextOpcode();  // index of the input variable
        opr1 = inputPop();  // base address in the input stack
        inputPush(opr1);    // push the base address back to the stack.
        stkPush (gblInputStack[opr1 + genPurpose]);
        break;
    case STOP:
    case OUTPUT:
        if (opcode == OUTPUT){
            genPurpose = stkPop(); // this is the output value
        }
        opr1 = inputPop();  // this is the proc-input stack base address
        gblMemPtr = inputPop(); // this is the return address
        opr2 = inputPop();  // this is the data stack index;
        // remove any remaining data that belongs to the current procedure from the data stack
        // Usually this is important for the STOP opcode.
        while (gblStkPtr > opr2){
            stkPop();
        }
        // remove the procedure inputs from the input stack
        while (gblInputStkPtr > opr1){
            inputPop();
        }
        // Output will push the output to the stack
        if (opcode == OUTPUT){
            stkPush (genPurpose);
        }
        break;
    case REPEAT:
        gblLoopAddress = stkPop();
        gblRepeatCount = stkPop();
        // these will be poped by EOL
        stkPush (gblMemPtr);  // address after repeat is complete

        if (gblRepeatCount > 1) {
            stkPush (gblRepeatCount);
            stkPush (gblLoopAddress); // address while still repeating
            gblMemPtr = gblLoopAddress;
        } else if (gblRepeatCount == 1) {
            gblMemPtr = gblLoopAddress;
        } else {  // if loop count = 0
            gblMemPtr = stkPop();
        }
        break;
    case COND_IF:
        opr1 = stkPop();  // if true pointer address
        opr2 = stkPop();  // condition
        if (opr2) {
            stkPush(gblMemPtr);
            gblMemPtr = opr1;
        }
        break;
    case COND_IFELSE:
        opr1 = stkPop(); // if false pointer address
        opr2 = stkPop(); // if true pointer address
        opr3 = stkPop(); // condition
        stkPush(gblMemPtr);
        if (opr3) {
            gblMemPtr = opr2;
        } else {
            gblMemPtr = opr1;
        }
        break;
    case BEEP:
        beep();
        break;
    case WAITUNTIL:
        gblLoopAddress = stkPop();
        // these will be poped by EOLR
        stkPush(gblMemPtr);  // address after repeat is complete
        stkPush (gblLoopAddress); // address while still repeating
        gblMemPtr = gblLoopAddress;
        break;
    case LOOP:
        gblLoopAddress = stkPop(); // the begining of loop
        gblRepeatCount = 0; // disable this counter (loop forever)
        stkPush(0);   // this distinguishes LOOP from Repeat. (see EOL)
        stkPush(gblLoopAddress); // push loop address back into the stack
        // so that EOL will loop
        gblMemPtr = gblLoopAddress;
        break;
    case WAIT:
        gblWaitCounter = stkPop() * 4;
        break;
    case TIMER:
        stkPush(gblTimer); // gblTimer increases every 1ms. See in RTCC interrupt
        break;
    case RESETT:
        gblTimer = 0;
        break;
    case SEND:
        genPurpose = stkPop();
        break;
    case IR:
        stkPush (gblMostRecentlyReceivedByte);
        gblNewByteHasArrivedFlag = 0;
        break;
    case NEWIR:
        stkPush (gblNewByteHasArrivedFlag);
        break;
    case RANDOM:
        stkPush (rand());
        break;
    case OP_PLUS:
    case OP_MINUS:
    case OP_MULTIPLY:
    case OP_DIVISION:
    case OP_REMAINDER:
    case OP_EQUAL:
    case OP_GREATER:
    case OP_LESS:
    case OP_AND:
    case OP_OR:
    case OP_XOR:
        opr2=stkPop();  // second operand
        opr1=stkPop();// first operand
        switch (opcode) {
            case OP_PLUS:
                opr1+=opr2;
                break;
            case OP_MINUS:
                opr1-=opr2;
                break;
            case OP_MULTIPLY:
                opr1*=opr2;
                break;
            case OP_DIVISION:
                opr1/=opr2;
                break;
            case OP_REMAINDER:
                opr1%=opr2;
                break;
            case OP_EQUAL:
                opr1=(opr1==opr2);
                break;
            case OP_GREATER:
                opr1=(opr1>opr2);
                break;
            case OP_LESS:
                opr1=(opr1<opr2);
                break;
            case OP_AND:
                opr1=(opr1&&opr2);
                break;
            case OP_OR:
                opr1=(opr1||opr2);
                break;
            case OP_XOR:
                opr1=(opr1^opr2);
                break;
        };
        stkPush(opr1);
        break;
    case OP_NOT:
        stkPush(!stkPop());
        break;
    case SETGLOBAL:
        genPurpose = stkPop();// this is the value
        globalVariables[stkPop()] = genPurpose;
        break;
    case GETGLOBAL:
        stkPush(globalVariables[stkPop()]);
        break;
    case ASET:
        opr2 = stkPop();// this is the value to be stored
        opr1 = stkPop() * 2;// this is the array index. Each entry is two bytes wide.
        genPurpose = ARRAY_BASE_ADDRESS + stkPop();// this is the base address of the array.
        flashSetWordAddress(genPurpose + opr1);
        flashWrite(opr2);
        break;
    case AGET:
        opr1 = stkPop() * 2;// this is the array index. Each entry is two bytes wide.
        genPurpose = ARRAY_BASE_ADDRESS + stkPop();// this is the base address of the array.
        opr2 = read_program_eeprom(genPurpose + opr1);
        stkPush(opr2);
        break;
    case RECORD:
        genPurpose = stkPop();
        // PCM parts (14 bit PICs like the 16F877) uses an external EEPROM for data Logging storage
        flashSetWordAddress(RECORD_BASE_ADDRESS + gblRecordPtr++);
        flashWrite(genPurpose);
        // save current record pointer location
        flashSetWordAddress(MEM_PTR_LOG_BASE_ADDRESS);
        flashWrite(gblRecordPtr);
        break;
    case RECALL:
        genPurpose = read_program_eeprom(RECORD_BASE_ADDRESS + gblRecordPtr++);
        stkPush(genPurpose);
        break;
    case RESETDP:
        gblRecordPtr = 0;
        break;
    case SETDP:
        gblRecordPtr = stkPop() * 2;
        break;
    case ERASE:
        opr1 = stkPop() * 2;
        for (genPurpose=0; genPurpose<opr1; genPurpose++) {
            flashSetWordAddress(RECORD_BASE_ADDRESS + genPurpose);
            flashWrite(0);
        }
        gblRecordPtr = 0;
        break;
    case OPC_MOTORS_OFF:
        motors_off();
        break;
    case OPC_MOTORS_THATWAY:
        motors_that_way();
        break;
    case OPC_MOTORS_THISWAY:
        motors_this_way();
        break;
    case OPC_MOTORS_REVERT:
        motors_reverse();
        break;
    case OPC_MOTORS_ON_FOR:
    case OPC_MOTORS_ON:
        motors_on();
        if (opcode == OPC_MOTORS_ON_FOR) {
            set_on_for(stkPop()*4);
        }
        break;
    case OPC_MOTORS_POWER:
        motors_power(stkPop());
        break;
    case OPC_MOTORS_ANGLE:
        motors_angle(stkPop());
        break;
    case OPC_ACTIVATE_MOTORS:
        mtrsActive = stkPop();
        break;
    case REALLY_STOP:
        start_stop_logo_machine = 1;
        break;
    case EB:
        stkPush(read_program_eeprom(stkPop()));
        break;
    case DB:
        opr1 = stkPop();
        opr2 = stkPop();
        flashSetWordAddress(opr2);
        flashWrite(opr1);
        break;
    case LOW_BYTE:
        stkPush(stkPop() & 0xff);
        break;
    case HIGH_BYTE:
        stkPush(stkPop() >> 8);
        break;
    case SENSOR1:
    case SENSOR2:
    case SENSOR3:
    case SENSOR4:
    case SENSOR5:
    case SENSOR6:
    case SENSOR7:
    case SENSOR8:
        if (opcode < SENSOR3) {
            i = opcode - SENSOR1;
        } else {
            i = opcode - SENSOR3 + 2;
        }
        stkPush(readSensor(i));
        break;
    case SWITCH1:
    case SWITCH2:
    case SWITCH3:
    case SWITCH4:
    case SWITCH5:
    case SWITCH6:
    case SWITCH7:
    case SWITCH8:
        if (opcode < SWITCH3) {
            i = opcode - SWITCH1;
        } else {
            i = opcode - SWITCH3 + 2;
        }
        stkPush(readSensor(i)>>9);
        break;
    case ULED_ON:
        output_high(USER_LED);
        break;
    case ULED_OFF:
        output_low(USER_LED);
        break;

    case CL_I2C_START:
        i2c_start();
        break;
    case CL_I2C_STOP:
        i2c_stop();
        break;
    case CL_I2C_WRITE:
        i2c_write(stkPop());
        break;
    case CL_I2C_READ:
        stkPush(i2c_read(stkPop()));
        break;
    default:
        start_stop_logo_machine = 1;
        break;
    };
}
Beispiel #10
0
void I2C::stop(void)
{
    lock();
    i2c_stop(&_i2c);
    unlock();
}
Beispiel #11
0
void I2CSlave::stop(void)
{
    i2c_stop(&_i2c);
}
Beispiel #12
0
/*#---------------------------------------------------------------------------
*#
*# FUNCTION NAME: i2c_readreg
*#
*# DESCRIPTION  : Reads a value from the decoder registers.
*#
*#--------------------------------------------------------------------------*/
unsigned char
i2c_readreg(unsigned char theSlave, unsigned char theReg)
{
	unsigned char b = 0;
	int error, cntr = 3;
	unsigned long flags;
		
	do {
		error = 0;
		/*
		 * we don't like to be interrupted
		 */
		save_flags(flags);
		cli();
		/*
		 * generate start condition
		 */
		i2c_start();
		/*
		 * dummy preamble
		 */
		i2c_outbyte(0x01);
		i2c_data(I2C_DATA_HIGH);
		i2c_clk(I2C_CLOCK_HIGH);
		i2c_delay(CLOCK_HIGH_TIME); /* Dummy Acknowledge */
		i2c_clk(I2C_CLOCK_LOW);
		i2c_delay(CLOCK_LOW_TIME);
		i2c_clk(I2C_CLOCK_HIGH);
		i2c_delay(CLOCK_LOW_TIME); /* Repeated Start Condition */
		i2c_data(I2C_DATA_LOW);
		i2c_delay(CLOCK_HIGH_TIME);
		i2c_clk(I2C_CLOCK_LOW);
		i2c_delay(CLOCK_LOW_TIME);
    
		i2c_start();
    
		/*
		 * send slave address
		 */
		i2c_outbyte(theSlave);
		/*
		 * wait for ack
		 */
		if(!i2c_getack())
			error = 1;
		/*
		 * now select register
		 */
		i2c_dir_out();
		i2c_outbyte(theReg);
		/*
		 * now it's time to wait for ack
		 */
		if(!i2c_getack())
			error = 1;
		/*
		 * repeat start condition
		 */
		i2c_delay(CLOCK_LOW_TIME);
		i2c_start();
		/*
		 * send slave address
		 */
		i2c_outbyte(theSlave | 0x01);
		/*
		 * wait for ack
		 */
		if(!i2c_getack())
			error = 1;
		/*
		 * fetch register
		 */
		b = i2c_inbyte();
		/*
		 * send Ack
		 */
		i2c_sendack();
		/*
		 * end sequence
		 */
		i2c_stop();
		/*
		 * enable interrupt again
		 */
		restore_flags(flags);
		
	} while(error && cntr--);

	return b;
}
Beispiel #13
0
/*#---------------------------------------------------------------------------
*#
*# FUNCTION NAME: i2c_writereg
*#
*# DESCRIPTION  : Writes a value to an I2C device
*#
*#--------------------------------------------------------------------------*/
int
i2c_writereg(unsigned char theSlave, unsigned char theReg,
	     unsigned char theValue)
{
	int error, cntr = 3;
	unsigned long flags;
		
	do {
		error = 0;
		/*
		 * we don't like to be interrupted
		 */
		save_flags(flags);
		cli();
		/*
		 * generate start condition
		 */
		i2c_start();
		/*
		 * dummy preamble
		 */
		i2c_outbyte(0x01);
		i2c_data(I2C_DATA_HIGH);
		i2c_clk(I2C_CLOCK_HIGH);
		i2c_delay(CLOCK_HIGH_TIME); /* Dummy Acknowledge */
		i2c_clk(I2C_CLOCK_LOW);
		i2c_delay(CLOCK_LOW_TIME);
		i2c_clk(I2C_CLOCK_HIGH);
		i2c_delay(CLOCK_LOW_TIME); /* Repeated Start Condition */
		i2c_data(I2C_DATA_LOW);
		i2c_delay(CLOCK_HIGH_TIME);
		i2c_clk(I2C_CLOCK_LOW);
		i2c_delay(CLOCK_LOW_TIME);

		i2c_start();
		/*
		 * send slave address
		 */
		i2c_outbyte(theSlave);
		/*
		 * wait for ack
		 */
		if(!i2c_getack())
			error = 1;
		/*
		 * now select register
		 */
		i2c_dir_out();
		i2c_outbyte(theReg);
		/*
		 * now it's time to wait for ack
		 */
		if(!i2c_getack())
			error |= 2;
		/*
		 * send register register data
		 */
		i2c_outbyte(theValue);
		/*
		 * now it's time to wait for ack
		 */
		if(!i2c_getack())
			error |= 4;
		/*
		 * end byte stream
		 */
		i2c_stop();
		/*
		 * enable interrupt again
		 */
		restore_flags(flags);
		
	} while(error && cntr--);
	
	i2c_delay(CLOCK_LOW_TIME);
	
	return -error;
}
Beispiel #14
0
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
    int count = 0;
    int status;
    int value;
    volatile uint32_t work_reg = 0;

    if(length <= 0) {
        return 0;
    }
    i2c_set_MR3_ACK(obj);
    /* There is a STOP condition for last processing */
    if (obj->last_stop_flag != 0) {
        status = i2c_start(obj);
        if (status != 0) {
            i2c_set_err_noslave(obj, stop);
            return I2C_ERROR_BUS_BUSY;
        }
    }
    obj->last_stop_flag = stop;
    /*  Send Slave address */
    status = i2c_read_address_write(obj, (address | 0x01));
    if (status != 0) {
        i2c_set_err_noslave(obj, stop);
        return I2C_ERROR_NO_SLAVE;
    }
    /* wait RDRF */
    status = i2c_wait_RDRF(obj);
    /* check ACK/NACK */
    if ((status != 0) || (REG(SR2.UINT32) & SR2_NACKF == 1)) {
        /* Slave sends NACK */
        /* If not repeated start, send stop. */
        if (stop) {
            i2c_stop(obj);
            /* dummy read */
            value = REG(DRR.UINT32);
            (void)i2c_wait_STOP(obj);
            i2c_set_SR2_NACKF_STOP(obj);
        } else {
            (void)i2c_restart(obj);
            /* dummy read */
            value = REG(DRR.UINT32);
            (void)i2c_wait_START(obj);
            /* SR2.START = 0 */
            REG(SR2.UINT32) &= ~SR2_START;
        }
        return I2C_ERROR_NO_SLAVE;
    }
    /* Read in all except last byte */
    if (length > 2) {
        /* dummy read */
        value = REG(DRR.UINT32);
        for (count = 0; count < (length - 1); count++) {
            /* wait for it to arrive */
            status = i2c_wait_RDRF(obj);
            if (status != 0) {
                i2c_set_err_noslave(obj, stop);
                return I2C_ERROR_NO_SLAVE;
            }
            /* Recieve the data */
            if (count == (length - 2)) {
                value = i2c_do_read(obj, 1);
            } else if ((length >= 3) && (count == (length - 3))) {
                value = i2c_do_read(obj, 2);
            } else {
                value = i2c_do_read(obj, 0);
            }
            data[count] = (char)value;
        }
    } else if (length == 2) {
        /* Set MR3 WATI bit is 1 */
        REG(MR3.UINT32) |= MR3_WAIT;
        /* dummy read */
        value = REG(DRR.UINT32);
        /* wait for it to arrive */
        status = i2c_wait_RDRF(obj);
        if (status != 0) {
            i2c_set_err_noslave(obj, stop);
            return I2C_ERROR_NO_SLAVE;
        }
        i2c_set_MR3_NACK(obj);
        data[count] = (char)REG(DRR.UINT32);
        count++;
    } else {
        /* length == 1 */
        /* Set MR3 WATI bit is 1 */;
        REG(MR3.UINT32) |=  MR3_WAIT;
        i2c_set_MR3_NACK(obj);
        /* dummy read */
        value = REG(DRR.UINT32);
    }
    /* wait for it to arrive */
    status = i2c_wait_RDRF(obj);
    if (status != 0) {
        i2c_set_err_noslave(obj, stop);
        return I2C_ERROR_NO_SLAVE;
    }

    /* If not repeated start, send stop. */
    if (stop) {
        (void)i2c_stop(obj);
        /* RIICnDRR read */
        value = REG(DRR.UINT32) & 0xFF;
        data[count] = (char)value;
        /* RIICnMR3.WAIT = 0 */
        REG(MR3.UINT32) &= ~MR3_WAIT;
        (void)i2c_wait_STOP(obj);
        i2c_set_SR2_NACKF_STOP(obj);
    } else {
        (void)i2c_restart(obj);
        /* RIICnDRR read */
        value = REG(DRR.UINT32) & 0xFF;
        data[count] = (char)value;
        /* RIICnMR3.WAIT = 0 */
        REG(MR3.UINT32) &= ~MR3_WAIT;
        (void)i2c_wait_START(obj);
        /* SR2.START = 0 */
        REG(SR2.UINT32) &= ~SR2_START;
    }

    return length;
}
Beispiel #15
0
void DMA1_Stream0_IRQHandler(void)
{
    i2c_log_event(I2C_LOG_RXTC, I2C1->SR1, I2C1->SR2);
    i2c_stop();
}
Beispiel #16
0
void i2c_reset(i2c_t *obj) {
    i2c_stop(obj);
    (void)i2c_wait_STOP(obj);
    i2c_set_SR2_NACKF_STOP(obj);
}
Beispiel #17
0
void I2C1_ER_IRQHandler(void)
{
    i2c_log_event(I2C_LOG_ERR, I2C1->SR1, I2C1->SR2);
    i2c_stop();
}
Beispiel #18
0
/*#---------------------------------------------------------------------------
*#
*# FUNCTION NAME: i2c_readreg
*#
*# DESCRIPTION  : Reads a value from the decoder registers.
*#
*#--------------------------------------------------------------------------*/
unsigned char
i2c_readreg(unsigned char theSlave, unsigned char theReg)
{
	unsigned char b = 0;
	int error, cntr = 3;
	unsigned long flags;

	spin_lock(&i2c_lock);

	do {
		error = 0;
		/*
		 * we don't like to be interrupted
		 */
		local_irq_save(flags);
		/*
		 * generate start condition
		 */
		i2c_start();
    
		/*
		 * send slave address
		 */
		i2c_outbyte((theSlave & 0xfe));
		/*
		 * wait for ack
		 */
		if(!i2c_getack())
			error = 1;
		/*
		 * now select register
		 */
		i2c_dir_out();
		i2c_outbyte(theReg);
		/*
		 * now it's time to wait for ack
		 */
		if(!i2c_getack())
			error = 1;
		/*
		 * repeat start condition
		 */
		i2c_delay(CLOCK_LOW_TIME);
		i2c_start();
		/*
		 * send slave address
		 */
		i2c_outbyte(theSlave | 0x01);
		/*
		 * wait for ack
		 */
		if(!i2c_getack())
			error = 1;
		/*
		 * fetch register
		 */
		b = i2c_inbyte();
		/*
		 * last received byte needs to be nacked
		 * instead of acked
		 */
		i2c_sendack();
		/*
		 * end sequence
		 */
		i2c_stop();
		/*
		 * enable interrupt again
		 */
		local_irq_restore(flags);
		
	} while(error && cntr--);

	spin_unlock(&i2c_lock);

	return b;
}
int readFuses()
{

    // was 0xE1 0xDF 0xFF
	  
    target_device=0;
	
	if (enableProgramming())
	{
	
		// successfully found target programming device
		target_device=1;
	  
	    if(i2c_available)
        {
		  i2c_start(LCD_I2C_DEVICE_ID);
		  i2c_tx(12);
		  i=0;
		  while (pgm_read_byte(&reading[i]) != '\0')
		  i2c_tx(pgm_read_byte(&reading[i++])); 
		  i2c_stop();   
		}
		
		_delay_ms(500);

		if(i2c_available)
        {
		  i2c_start(LCD_I2C_DEVICE_ID);
		  i2c_tx(12);  // clear lcd
		  i=0;
		  while (pgm_read_byte(&heading[i]) != '\0')
		  i2c_tx(pgm_read_byte(&heading[i++])); 
		  i2c_tx(10); // jump to row 2
		  i2c_tx(2);
		  i2c_tx(1);
        }

		//Read lfuse
		shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x04, 0x4C);
		shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x00, 0x68);
		inData = shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x00, 0x6C);
		
		if(i2c_available)
        {
		  i=0;
		  while (pgm_read_byte(&nulx[i]) != '\0')
		  i2c_tx(pgm_read_byte(&nulx[i++])); 
		  i2c_lcd_hex(inData);
		  i2c_tx(32);
		  i2c_tx(32);   
        }
		  
		//Read hfuse
		shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x04, 0x4C);
		shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x00, 0x7A);
		inData = shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x00, 0x7E);
		
		if(i2c_available)
        {
		  i=0;
		  while (pgm_read_byte(&nulx[i]) != '\0')
		  i2c_tx(pgm_read_byte(&nulx[i++]));
		  i2c_lcd_hex(inData);
		  i2c_tx(32);
		  i2c_tx(32);    
        }
		
		//Read efuse
		shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x04, 0x4C);
		shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x00, 0x6A);
		inData = shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x00, 0x6E);
		
		if(i2c_available)
        {
		  i=0;
		  while (pgm_read_byte(&nulx[i]) != '\0')
		  i2c_tx(pgm_read_byte(&nulx[i++]));
		  i2c_lcd_hex(inData);

		  i2c_stop();  
        }
		
	} else {
	
	  // show no device found
	  if(i2c_available)
      {
	    show_nodev_msg();
	  }
	  
	}
	
    disableProgramming();

	return target_device;
	
}