void i2c_reset(i2c_t *obj) { i2c_stop(obj); }
//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 }
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(); }
/* ********************************************************************************************************************** * 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; }
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; }
/* * 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); }
/*#--------------------------------------------------------------------------- *# *# 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; }; }
void I2C::stop(void) { lock(); i2c_stop(&_i2c); unlock(); }
void I2CSlave::stop(void) { i2c_stop(&_i2c); }
/*#--------------------------------------------------------------------------- *# *# 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; }
/*#--------------------------------------------------------------------------- *# *# 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; }
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; }
void DMA1_Stream0_IRQHandler(void) { i2c_log_event(I2C_LOG_RXTC, I2C1->SR1, I2C1->SR2); i2c_stop(); }
void i2c_reset(i2c_t *obj) { i2c_stop(obj); (void)i2c_wait_STOP(obj); i2c_set_SR2_NACKF_STOP(obj); }
void I2C1_ER_IRQHandler(void) { i2c_log_event(I2C_LOG_ERR, I2C1->SR1, I2C1->SR2); i2c_stop(); }
/*#--------------------------------------------------------------------------- *# *# 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; }