/** * Address slave register and read one byte of data. * @param byte place to write received data to. * @param end Whether to signalise the slave to stop transmission. * @returns If the process of addressing the slave and the register were successful. */ bool i2c_register_read(i2cport *port, uint8_t device_address, uint8_t register_address , uint8_t *byte, bool end) { if (! i2c_restart(port, device_address, I2CWRITE) || ! i2c_write(port, register_address) || ! i2c_restart(port, device_address, I2CREAD)) return false; *byte = i2c_read(port, end); return true; }
int eeprom_load(void) { printf("Loading EEPROM data by 16 bytes pages...\n"); // load eeprom by pages of 16 bytes each int counter = 0x00; for (int i = 0; i < CONFIG_EEPROM_SIZE / 16; i++) { // set address i2c_start(I2C_Direction_Transmitter, CONFIG_EEPROM_ADDRESS); i2c_send(counter >> 8); i2c_send(counter & 0xFF); // read data i2c_restart(I2C_Direction_Receiver, CONFIG_EEPROM_ADDRESS); for (int j = 0; j < 15; j++) { eeprom_map[counter++] = i2c_recv_ack(); } // stop condition eeprom_map[counter++] = i2c_recv_nack(); early_putc('*'); } printf("\nDone.\n"); return 0; }
static void i2c_tx_irq(IRQn_Type irq_num, uint32_t index) { i2c_t *obj = i2c_data[index].async_obj; if ((REG(SR2.UINT32) & SR2_NACKF)) { /* Slave sends NACK */ i2c_set_err_noslave(obj); i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_TRANSFER_EARLY_NACK; i2c_abort_asynch(obj); ((void (*)())i2c_data[index].async_callback)(); return; } if (obj->tx_buff.pos == obj->tx_buff.length) { /* All datas have tranferred */ /* Clear TEND */ REG(SR2.UINT32) &= ~(SR2_TEND); /* If not repeated start, send stop. */ if (i2c_data[index].shouldStop && obj->rx_buff.length == 0) { (void)i2c_set_STOP(obj); (void)i2c_wait_STOP(obj); i2c_set_SR2_NACKF_STOP(obj); i2c_transfer_finished(obj); } else { (void)i2c_restart(obj); (void)i2c_wait_START(obj); /* SR2.START = 0 */ REG(SR2.UINT32) &= ~SR2_START; if (obj->rx_buff.length) { /* Ready to read */ i2c_set_MR3_ACK(obj); /* Disable INTRIICTEI */ REG(IER.UINT8[0]) &= ~(1 << 6); /* Send Slave address */ if (i2c_read_address_write(obj, (i2c_data[index].address | 0x01)) != 0) { i2c_set_err_noslave(obj); i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_ERROR_NO_SLAVE; i2c_abort_asynch(obj); ((void (*)())i2c_data[index].async_callback)(); return; } } else { i2c_transfer_finished(obj); } } } else { /* Send next 1 byte */ if (i2c_do_write(obj, *(uint8_t *)obj->tx_buff.buffer) != 0) { i2c_set_err_noslave(obj); i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_ERROR_NO_SLAVE; i2c_abort_asynch(obj); ((void (*)())i2c_data[index].async_callback)(); return; } obj->tx_buff.buffer = (uint8_t *)obj->tx_buff.buffer + 1; ++obj->tx_buff.pos; } }
unsigned char I2C_GPIO_Write_iM205 (unsigned char addr, unsigned char reg, unsigned char val ) { unsigned char state, data; #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0u; #endif APP_TRACE_INFO(("\r\nI2C_GPIO_Write_iM205(0x%0X,0x%0X, 0x%0X)", addr, reg, val)); OS_ENTER_CRITICAL(); i2c_start(); //起始条件,开始数据通信 //发送地址和数据读写方向 data = (addr << 1) | 0; //低位为0,表示写数据 state = i2c_write_byte(data); if(state != 0) { i2c_stop(); OS_EXIT_CRITICAL(); //APP_TRACE_INFO(("\r\n write byte err1!")); return 1; } //写入数据 state = i2c_write_byte( reg ); if(state != 0) { i2c_stop(); OS_EXIT_CRITICAL(); //APP_TRACE_INFO(("\r\n write byte err2!")); return 1; } i2c_restart(); //发送地址和数据读写方向 data = (addr << 1) | 0; //低位为0,表示写数据 state = i2c_write_byte(data); if(state != 0) { i2c_stop(); OS_EXIT_CRITICAL(); //APP_TRACE_INFO(("\r\n write byte err3!")); return 1; } //写入数据 state = i2c_write_byte( val ); if(state != 0) { i2c_stop(); OS_EXIT_CRITICAL(); //APP_TRACE_INFO(("\r\n write byte err4!")); return 1; } i2c_stop(); //终止条件,结束数据通信 OS_EXIT_CRITICAL(); return 0; }
int i2c_read_block(const uint8_t devaddr, const uint8_t regaddr, uint8_t *data, const int length) { if(!length) return 0; i2c_start(); int res = i2c_send_byte(devaddr); if(res) { printf("NACK on address %02x (%d)\n", devaddr, res); i2c_stop(); return -1; } res = i2c_send_byte(regaddr); if(res) { printf("NACK on register address %02x (%d)\n", regaddr, res); i2c_stop(); return -1; } i2c_restart(); res = i2c_send_byte(devaddr | 1); if(res) { printf("NACK on address %02x (%d)\n", devaddr | 1, res); i2c_stop(); return -2; } for(int i=0;i<length;i++) { *(data++) = i2c_receive_byte((i == length-1)? 0 : 1); } i2c_stop(); return 0; }
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { int cnt; int status; /* 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); return I2C_ERROR_BUS_BUSY; } } obj->last_stop_flag = stop; /* Send Slave address */ status = i2c_do_write(obj, address); if (status != 0) { i2c_set_err_noslave(obj); return I2C_ERROR_NO_SLAVE; } /* Wait send end */ status = i2c_wait_TEND(obj); if ((status != 0) || ((REG(SR2.UINT32) & SR2_NACKF) != 0)) { /* Slave sends NACK */ i2c_set_err_noslave(obj); return I2C_ERROR_NO_SLAVE; } /* Send Write data */ for (cnt=0; cnt<length; cnt++) { status = i2c_do_write(obj, data[cnt]); if(status != 0) { i2c_set_err_noslave(obj); return cnt; } else { /* Wait send end */ status = i2c_wait_TEND(obj); if ((status != 0) || ((REG(SR2.UINT32) & SR2_NACKF) != 0)) { /* Slave sends NACK */ i2c_set_err_noslave(obj); return I2C_ERROR_NO_SLAVE; } } } /* If not repeated start, send stop. */ if (stop) { (void)i2c_set_STOP(obj); (void)i2c_wait_STOP(obj); i2c_set_SR2_NACKF_STOP(obj); } else { (void)i2c_restart(obj); (void)i2c_wait_START(obj); /* SR2.START = 0 */ REG(SR2.UINT32) &= ~SR2_START; } return length; }
uint8_t i2c_read_reg(uint8_t slave, uint8_t reg) { uint8_t data; i2c_start(); i2c_write(slave << 1); i2c_write(reg); i2c_restart(); i2c_write((slave << 1) | 0x1); data = i2c_read(I2C_STATUS_NACK); i2c_stop(); return data; }
short i2c_get_byte(char slaveAddr, char dataAddr) { i2c_start(); // ST i2c_address(slaveAddr, 0); // SAD + W i2c_write(dataAddr); // SUB i2c_restart(); // SR? i2c_address(slaveAddr, 1); // SAD + R char data1 = i2c_read(0); // DATA i2c_stop(); // STOP return data1; }
static void i2c_set_err_noslave(i2c_t *obj, int stop) { if (stop) { (void)i2c_stop(obj); (void)i2c_wait_STOP(obj); i2c_set_SR2_NACKF_STOP(obj); } else { (void)i2c_restart(obj); (void)i2c_wait_START(obj); /* SR2.START = 0 */ REG(SR2.UINT32) &= ~SR2_START; } }
unsigned short i2c_get_udata(char mAddr, char addr) { i2c_start(); i2c_address(mAddr, 0); i2c_write(addr); i2c_restart(); i2c_address(mAddr, 1); unsigned char data1 = i2c_read(1); unsigned char data0 = i2c_read(0); i2c_stop(); return data0 + (data1 << 8); }
char DS1621_lire1octets(char adresse) { char data; i2c_start(); // Start I2C i2c_ecrire(ADD_W_DS1621); // Envoie de l'adresse RTC pour écriture i2c_ecrire(adresse); // Envoie de l'adresse du registre à lire i2c_restart(); // Repeat Start I2C i2c_ecrire(ADD_R_DS1621); // Envoie de l'adresse RTC pour lecture data=i2c_lire(1); // Lecture du registre souhaité + NOack (fin de communication) i2c_stop(); // Stop I2C return(data); }
//read from an address char I2Cread(char addr, char subaddr) { char temp; i2c_start(); send_i2c_byte(addr); send_i2c_byte(subaddr); microcontroller_delay_us(10); i2c_restart(); send_i2c_byte(addr | 0x01); temp = i2c_read_byte(); reset_i2c_bus(); return temp; }
void DS1621_init(char data, char TH, char TL) { //Config i2c_start(); // Start I2C i2c_ecrire(ADD_W_DS1621); // Envoie de l'adresse DS1621 pour écriture i2c_ecrire(Acces_Config); // Envoie de l'adresse du registre à écrire i2c_ecrire(data); // Envoie de la donnée //TH i2c_restart(); i2c_ecrire(ADD_W_DS1621); // Envoie de l'adresse DS1621 pour écriture i2c_ecrire(Acces_TH); // Envoie de l'adresse du registre à écrire i2c_ecrire(TH); // Envoie de la donnée //TL i2c_restart(); i2c_ecrire(ADD_W_DS1621); // Envoie de l'adresse DS1621 pour écriture i2c_ecrire(Acces_TL); // Envoie de l'adresse du registre à écrire i2c_ecrire(TL); // Envoie de la donnée i2c_stop(); DS1621_conv(); //Lancement conversion }
// Fonctions lecture pour DS1621 char DS1621_lire2octets(char adresse) { char tempH,tempL; i2c_start(); // Start I2C i2c_ecrire(ADD_W_DS1621); // Envoie de l'adresse RTC pour écriture i2c_ecrire(adresse); // Envoie de l'adresse du registre à lire i2c_restart(); // Repeat Start I2C i2c_ecrire(ADD_R_DS1621); // Envoie de l'adresse RTC pour lecture // Lecture de l'octet haut tempH=i2c_lire(0); // Lecture de l'octet bas, 1 pour envoyer un acknoledge (donc fin de la trame) tempL=i2c_lire(1); i2c_stop(); return(tempH); }
uint8_t i2c_read_byte(const uint8_t devaddr, const uint8_t regaddr) { i2c_start(); int res; res = i2c_send_byte(devaddr); if(res) { printf("Error sending write address (%d)\n", res); } res = i2c_send_byte(regaddr); if(res) { printf("Error sending register address (%d)\n", res); } i2c_restart(); res = i2c_send_byte(devaddr | 1); if(res) { printf("Error sending read address (%d)\n", res); } uint8_t result = i2c_receive_byte(0); i2c_stop(); return result; }
uint16_t i2c_read_word(const uint8_t devaddr, const uint16_t regaddr) { i2c_start(); int res; res = i2c_send_byte(devaddr); if(res) { printf("Error sending write address (%d)\n", res); } res = i2c_send_byte(regaddr >> 8); res += i2c_send_byte(regaddr & 0xFF); if(res) { printf("Error sending register address (%d)\n", res); } i2c_restart(); res = i2c_send_byte(devaddr | 1); if(res) { printf("Error sending read address (%d)\n", res); } uint16_t result = ((uint16_t)i2c_receive_byte(1)) << 8; result |= i2c_receive_byte(0); i2c_stop(); return result; }
int main(int argc, char** argv) { unsigned char right_direction = 'S'; //S- stop, F - Forwards, B - Backwards unsigned char left_direction = 'S'; unsigned char user_right_direction = 'S'; //S- stop, F - Forwards, B - Backwards unsigned char user_left_direction = 'S'; //char motor_direction = ' '; //TEMP unsigned int left_speed = 0; //the speed of the left motor unsigned int right_speed = 0; //the speed of the right motor unsigned int user_left_speed = 0; //the speed of the left motor unsigned int user_right_speed = 0; //the speed of the right motor unsigned char battery_percentage = 100; //int right_distance = 0;//the distance that the right motor has traveled in cm //int left_distance = 0; //the distance that the left motor has traveled in cm unsigned char tempC = 0 ; //temporary char unsigned char tempC1, tempC2; unsigned char tempBuffC = 0; //setup port B as digital output TRISE = 0; TRISB = 0x0FFF; TRISD = 0xF00; //enable port D pins (encoders) as inputs //initialize peripherals initADC(); initPWM(); initTimer(); initUART(); initInputCapture(); i2c_init(); //set up transmit data buffer TX_DATA_BUFFER.head = 0; TX_DATA_BUFFER.tail = 0; //set up recieve data buffer RX_DATA_BUFFER.head = 0; RX_DATA_BUFFER.tail = 0; //initialize the control packet controlpacket.bytesRecieved = 0; //enable interrupts for the required molules IEC1bits.MI2C1IE = 1; IEC1bits.T4IE = 1; //enable timer 3 interrupts IEC0bits.T3IE = 1; IEC0bits.U1RXIE = 1; //enable UART Rx interrupts IFS0bits.U1RXIF = 0; IEC0bits.U1TXIE = 1; //enable UART Tx interrupts IEC0bits.AD1IE = 1; //enable ADC interrupts IEC0bits.IC1IE = 1; //enable input capture interrupts IEC0bits.IC2IE = 1; //^ IEC2bits.IC3IE = 1; //^ IEC2bits.IC4IE = 1; //^ // ===================================================================== // ========================= MAIN LOOP ============================= //====================================================================== while(1) { U1STAbits.UTXEN = 1; //------------------------- ATD ------------------------------- //If the SENSORs have recieved new values update the variables if (SENSORS_READY == 1) { AD1CON1bits.ASAM = 0; //turn off sampling temporarily SENSOR4 = ADC1BUF0; SENSOR3 = ADC1BUF1; SENSOR2 = ADC1BUF2; SENSOR1 = ADC1BUF3; SENSOR5 = ADC1BUF4; AD1CON1bits.ASAM = 1; //turn sampling back on SENSORS_READY = 0; } //------------------------- UART ---------------------------- //TEMP -- TEST THE UART BY SENDING A MESSAGE WHEN TIMER INTERRUPTS if (PRINT == 1) { //printString("Right ticks:"); //printInt(RIGHT_TICKS); //printString("\n\r"); //printString("Left ticks:"); //printInt(LEFT_TICKS); //printString("\n\r"); printString("1: "); printInt(SENSOR1); printString("\n\r"); printString("2: "); printInt(SENSOR2); printString("\n\r"); printString("3: "); printInt(SENSOR3); printString("\n\r"); printString("4: "); printInt(SENSOR4); printString("\n\r"); printString("5: "); printInt(SENSOR5); printString("\n\r"); PRINT = 0; //LATB ^= 0x8000; } //If the UART module is ready to send a character, place the //next character in the TX buffer in the send register if (READY_TO_SEND == 1) { if (BUFF_status(&TX_DATA_BUFFER) != BUFF_EMPTY) { U1TXREG = BUFF_pop(&TX_DATA_BUFFER); READY_TO_SEND = 0; } } //If the UART module is ready to receive a character, place the char //in the receive buffer for later use if (READY_TO_REC == 1) { if (BUFF_status(&RX_DATA_BUFFER) != BUFF_FULL) { tempC = U1RXREG; BUFF_push(&RX_DATA_BUFFER, tempC); READY_TO_REC = 0; //BUFF_push(&TX_DATA_BUFFER, tempC); //TEMP --echo back char } } //if there is a character available, pop it off and add it to the //control packet if (BUFF_status(&RX_DATA_BUFFER) != BUFF_EMPTY) { tempC = BUFF_pop(&RX_DATA_BUFFER); BUFF_push(&TX_DATA_BUFFER, tempC); ///TEMP switch(controlpacket.bytesRecieved) { case 0: if (tempC == 0xAA) { controlpacket.bytesRecieved = 1; } break; case 1: controlpacket.sequence = tempC; controlpacket.bytesRecieved += 1; break; case 2: controlpacket.command = tempC; controlpacket.bytesRecieved += 1; break; case 3: controlpacket.data1 = tempC; controlpacket.bytesRecieved += 1; break; case 4: controlpacket.data2 = tempC; controlpacket.bytesRecieved += 1; break; default: break; } } //(to read a byte from UART just use this... /* if (BUFF_status(&RX_DATA_BUFFER) != BUFF_EMPTY) { <BYTE> = BUFF_pop(&RX_DATA_BUFFER); } */ //to write a byte to UART just use this... /* if (BUFF_status(&TX_DATA_BUFFER) != BUFF_FULL) { BUFF_push(&TX_DATA_BUFFER, <BYTE HERE>); } */ //----------------------- I2C ------------------------------- // //if( /*READY TO READ FUEL VAL*/) //{ //I2C_START = 0; // //(to read a byte from i2c just use this... /* if (BUFF_status(&I2C_RX_BUFFER) != BUFF_EMPTY) { <BYTE> = BUFF_pop(&I2C_RX_BUFFER); } */ if(GET_BATT == 1) { I2C_START = i2c_start(); } if( I2C_ISR == 1) { LATB ^= 0x8000; if( I2C_START == 1) { I2C_START = 0; I2C_SEND_BYTE += send_byte_i2c( 0xAA ); //send first byte: fuel gauge address in write mode } else if(I2C_SEND_BYTE == 1) { I2C_SEND_BYTE += send_byte_i2c( 0x02 ); //send first command byte StateOfCharge() command -- returns an unsigned int value 0-100% } else if(I2C_SEND_BYTE == 2) { I2C_SEND_BYTE += send_byte_i2c( 0x03 ); //send second command byte } else if(I2C_SEND_BYTE == 3) { I2C_SEND_BYTE = 0; I2C_RESTART += i2c_restart(); //after they ack second command byte send restart } else if(I2C_RESTART == 1) //send 0xAB to designate read mode { I2C_RESTART = 0; I2C_SEND_BYTE += send_byte_i2c( 0xAB ); if(I2C_SEND_BYTE == 1) { I2C_SEND_BYTE = 4; } } else if(I2C_SEND_BYTE == 4) //recieve 1 byte - unsigned int from 0 to 100 % { I2C_SEND_BYTE = 0; battery_percentage = read_i2c_byte_nack(); I2C_RECV_BYTE = 1; BATT_READY = 1; GET_BATT = 0; } else if(I2C_RECV_BYTE == 1) //send stop condition { I2C_RECV_BYTE = 0; //I2C_STOP += i2c_stop(); error } else if(I2C_STOP == 1) { I2C_STOP = 0; //stop condition has completed clear stop i2c_stop flag } else { I2C_ERROR = 1; } } //--------------------- PROCESS CMD --------------------- if (controlpacket.bytesRecieved == 5) { //if done receiving packet if (controlpacket.command == CMD_GET_SENSOR_DATA) { //Send all sensor data back //send IR data - 1 bit for each sensor (1 if tripped) if (BUFF_status(&TX_DATA_BUFFER) != BUFF_FULL) { BUFF_push(&TX_DATA_BUFFER, 0xAA); BUFF_push(&TX_DATA_BUFFER, controlpacket.sequence); BUFF_push(&TX_DATA_BUFFER, CMD_SENSOR); tempBuffC = 0; if (SENSOR1 > SEN_MAX) tempBuffC |= 1; if ((SENSOR2 > SEN_MAX) || (SENSOR4 < SEN_MIN)) tempBuffC |= 0x2; if (SENSOR3 > SEN_MAX) tempBuffC |= 0x4; if ((SENSOR4 > SEN_MAX) || (SENSOR4 < SEN_MIN)) tempBuffC |= 0x8; if ((SENSOR5 > SEN_MAX) || (SENSOR5 < SEN_MIN)) tempBuffC |= 0x10; BUFF_push(&TX_DATA_BUFFER, tempBuffC); BUFF_push(&TX_DATA_BUFFER, 0x00); } /* //first SENSOR1 if (BUFF_status(&TX_DATA_BUFFER) != BUFF_FULL) { BUFF_push(&TX_DATA_BUFFER, 0xAA); BUFF_push(&TX_DATA_BUFFER, controlpacket.sequence); BUFF_push(&TX_DATA_BUFFER, CMD_SENSOR1); BUFF_push(&TX_DATA_BUFFER, (char)(SENSOR1 >> 8)); BUFF_push(&TX_DATA_BUFFER, (char)SENSOR1); } // SENSOR2 if (BUFF_status(&TX_DATA_BUFFER) != BUFF_FULL) { BUFF_push(&TX_DATA_BUFFER, 0xAA); BUFF_push(&TX_DATA_BUFFER, controlpacket.sequence); BUFF_push(&TX_DATA_BUFFER, CMD_SENSOR2); BUFF_push(&TX_DATA_BUFFER, (char)(SENSOR2 >> 8)); BUFF_push(&TX_DATA_BUFFER, (char)SENSOR2); } // SENSOR3 if (BUFF_status(&TX_DATA_BUFFER) != BUFF_FULL) { BUFF_push(&TX_DATA_BUFFER, 0xAA); BUFF_push(&TX_DATA_BUFFER, controlpacket.sequence); BUFF_push(&TX_DATA_BUFFER, CMD_SENSOR3); BUFF_push(&TX_DATA_BUFFER, (char)(SENSOR3 >> 8)); BUFF_push(&TX_DATA_BUFFER, (char)SENSOR3); } // SENSOR4 if (BUFF_status(&TX_DATA_BUFFER) != BUFF_FULL) { BUFF_push(&TX_DATA_BUFFER, 0xAA); BUFF_push(&TX_DATA_BUFFER, controlpacket.sequence); BUFF_push(&TX_DATA_BUFFER, CMD_SENSOR4); BUFF_push(&TX_DATA_BUFFER, (char)(SENSOR4 >> 8)); BUFF_push(&TX_DATA_BUFFER, (char)SENSOR4); } // SENSOR5 if (BUFF_status(&TX_DATA_BUFFER) != BUFF_FULL) { BUFF_push(&TX_DATA_BUFFER, 0xAA); BUFF_push(&TX_DATA_BUFFER, controlpacket.sequence); BUFF_push(&TX_DATA_BUFFER, CMD_SENSOR5); BUFF_push(&TX_DATA_BUFFER, (char)(SENSOR5 >> 8)); BUFF_push(&TX_DATA_BUFFER, (char)SENSOR5); } */ // LEFT ENCODER if (BUFF_status(&TX_DATA_BUFFER) != BUFF_FULL) { BUFF_push(&TX_DATA_BUFFER, 0xAA); BUFF_push(&TX_DATA_BUFFER, controlpacket.sequence); BUFF_push(&TX_DATA_BUFFER, CMD_LEFT_ENCODER); BUFF_push(&TX_DATA_BUFFER, (char)(LEFT_TICKS >> 8)); BUFF_push(&TX_DATA_BUFFER, (char)LEFT_TICKS); } // RIGHT_ENCODER if (BUFF_status(&TX_DATA_BUFFER) != BUFF_FULL) { BUFF_push(&TX_DATA_BUFFER, 0xAA); BUFF_push(&TX_DATA_BUFFER, controlpacket.sequence); BUFF_push(&TX_DATA_BUFFER, CMD_RIGHT_ENCODER); BUFF_push(&TX_DATA_BUFFER, (char)(RIGHT_TICKS >> 8)); BUFF_push(&TX_DATA_BUFFER, (char)RIGHT_TICKS); } controlpacket.bytesRecieved = 0; } if (controlpacket.command == CMD_RIGHT_ENCODER) { BUFF_push(&TX_DATA_BUFFER, 0xAA); BUFF_push(&TX_DATA_BUFFER, controlpacket.sequence); BUFF_push(&TX_DATA_BUFFER, CMD_RIGHT_ENCODER); BUFF_push(&TX_DATA_BUFFER, (char)(RIGHT_TICKS >> 8)); BUFF_push(&TX_DATA_BUFFER, (char)RIGHT_TICKS); controlpacket.bytesRecieved = 0; }
/** * Generates a re-/start condition and sends the device address * and then register address and one byte of data. * There is no stop condition generated. * @returns If the receiver sent the ACK bit. */ bool i2c_register_write(i2cport *port, uint8_t deviceaddr, uint8_t regaddr, uint8_t byte) { return i2c_restart(port, deviceaddr, I2CWRITE) && i2c_write(port, regaddr) && i2c_write(port, byte); }
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); 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); return I2C_ERROR_NO_SLAVE; } /* wait RDRF */ status = i2c_wait_RDRF(obj); /* check ACK/NACK */ if ((status != 0) || ((REG(SR2.UINT32) & SR2_NACKF) != 0)) { /* Slave sends NACK */ (void)i2c_set_STOP(obj); /* dummy read */ value = REG(DRR.UINT32); (void)i2c_wait_STOP(obj); i2c_set_SR2_NACKF_STOP(obj); obj->last_stop_flag = 1; 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); 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); 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); return I2C_ERROR_NO_SLAVE; } /* If not repeated start, send stop. */ if (stop) { (void)i2c_set_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; }
static void i2c_rx_irq(IRQn_Type irq_num, uint32_t index) { i2c_t *obj = i2c_data[index].async_obj; if (obj->rx_buff.pos == SIZE_MAX) { if ((REG(SR2.UINT32) & SR2_NACKF) != 0) { /* Slave sends NACK */ (void)i2c_set_STOP(obj); /* dummy read */ if (REG(DRR.UINT32)) {} (void)i2c_wait_STOP(obj); i2c_set_SR2_NACKF_STOP(obj); obj->i2c.last_stop_flag = 1; i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_TRANSFER_EARLY_NACK; i2c_abort_asynch(obj); ((void (*)())i2c_data[index].async_callback)(); return; } if (obj->rx_buff.length == 1) { /* length == 1 */ /* Set MR3 WAIT bit is 1 */; REG(MR3.UINT32) |= MR3_WAIT; i2c_set_MR3_NACK(obj); } else if (obj->rx_buff.length == 2) { /* Set MR3 WAIT bit is 1 */ REG(MR3.UINT32) |= MR3_WAIT; } /* dummy read */ if (REG(DRR.UINT32)) {} obj->rx_buff.pos = 0; return; } if ((REG(SR2.UINT32) & SR2_NACKF) != 0) { /* Slave sends NACK */ i2c_set_err_noslave(obj); i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_TRANSFER_EARLY_NACK; i2c_abort_asynch(obj); ((void (*)())i2c_data[index].async_callback)(); return; } else { switch (obj->rx_buff.length - obj->rx_buff.pos) { case 1: /* Finished */ /* If not repeated start, send stop. */ if (i2c_data[index].shouldStop) { (void)i2c_set_STOP(obj); /* RIICnDRR read */ *(uint8_t *)obj->rx_buff.buffer = REG(DRR.UINT32) & 0xFF; /* 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 */ *(uint8_t *)obj->rx_buff.buffer = REG(DRR.UINT32) & 0xFF; /* RIICnMR3.WAIT = 0 */ REG(MR3.UINT32) &= ~MR3_WAIT; (void)i2c_wait_START(obj); /* SR2.START = 0 */ REG(SR2.UINT32) &= ~SR2_START; } i2c_transfer_finished(obj); return; case 2: i2c_set_MR3_NACK(obj); break; case 3: /* this time is befor last byte read */ /* Set MR3 WAIT bit is 1 */ REG(MR3.UINT32) |= MR3_WAIT; break; default: i2c_set_MR3_ACK(obj); break; } *(uint8_t *)obj->rx_buff.buffer = REG(DRR.UINT32) & 0xFF; obj->rx_buff.buffer = (uint8_t *)obj->rx_buff.buffer + 1; ++obj->rx_buff.pos; } }
/** * Address slave register for reading. Does not read any data. * Do reading yourself, so you can have error codes of this initialization as * return value. */ uint8_t i2c_register_read_init(i2cport *port, uint8_t device_address, uint8_t register_address) { return i2c_restart(port, device_address, I2CWRITE) && i2c_write(port, register_address) && i2c_restart(port, device_address, I2CREAD); }
/** * Generates a restart condition and sends the device address * and then the register address. * There is no stop condition generated. * @returns If the receiver sent the ACK bit. */ bool i2c_register_addr(i2cport *port, uint8_t device_address, uint8_t register_address) { return i2c_restart(port, device_address, I2CWRITE) && i2c_write(port, register_address); }