/** * rtc_read_register() - read a register of realt time clock * * @address: address of realt time clock register * @byte: pointer to address where the read byte will be stored in * * Return: TWI_OK on success, TWI_ERR on error */ uint8_t rtc_read_register(uint8_t address, uint8_t* byte) { rtc_disable_avr_interrupt(); uint8_t ret = 0; ret |= twi_start(); if (ret != TWI_OK) goto rtc_read_register_exit; ret |= twi_send_slave_address(TWI_WRITE, RTC_ADDRESS); if (ret != TWI_OK) goto rtc_read_register_exit; ret |= twi_send_byte(address); if (ret != TWI_OK) goto rtc_read_register_exit; ret |= twi_start(); if (ret != TWI_OK) goto rtc_read_register_exit; ret |= twi_send_slave_address(TWI_READ, RTC_ADDRESS); if (ret != TWI_OK) goto rtc_read_register_exit; ret |= twi_read_byte(TWI_NACK, byte); twi_stop(); rtc_read_register_exit: if (during_bitmask == FALSE) { rtc_enable_avr_interrupt(); } return ret; }
i2c_info_e i2cWriteData(const uint8_t address, const uint8_t data[], const size_t size, const bool stop) { // Si pas de données a envoyer. if(size == 0) return I2C_INFO_NO_ERROR; twi_generate_start(); // Pour générai la condition de start. while(!twi_is_raising_falg()); // Attend que le drapeau ce lève. if(twi_get_statu() != TW_START && twi_get_statu() != TW_REP_START) // Si le statu n'est pas TW_START ou TW_REP_START, s'est qu'il ses produit une erreur. { twi_generate_stop(); return I2C_INFO_NO_START; } //Envois de l'adresse et du mode écriture. twi_send_byte((address<<1)|TW_WRITE); // Envoi du premier octet, qui contient l'adresse et le mode écriture. while(!twi_is_raising_falg()); // Attend que le drapeau ce lève. if(twi_get_statu() != TW_MT_SLA_ACK) // Si le statu n'est pas TW_MT_SLA_ACK, s'est qu'il ses produit une erreur. { twi_generate_stop(); return I2C_INFO_NO_ADDRESSED; } //Envoi autan de données que demander. for(size_t i=0; i < size; i++) { twi_send_byte(data[i]); // Envoi d'une données. while(!twi_is_raising_falg()); // Attend que le drapeau ce lève. if(twi_get_statu() != TW_MT_DATA_ACK) // Si le statu n'est pas TW_MT_DATA_ACK, s'est qu'il ses produit une erreur. { twi_generate_stop(); return I2C_INFO_DATA_NO_WRITE; } } // Pour générai la condition de stop, si souhaiter. if(stop) twi_generate_stop(); return I2C_INFO_NO_ERROR; }
i2c_info_e i2cReadData(const uint8_t address, uint8_t data[], const size_t size, const bool stop) { // Si pas de données a envoyer. if(size == 0) return I2C_INFO_NO_ERROR; twi_generate_start(); // Pour générai la condition de start. while(!twi_is_raising_falg()); // Attend que le drapeau ce lève. if(twi_get_statu() != TW_START && twi_get_statu() != TW_REP_START) // Si le statu n'est pas TW_START ou TW_REP_START, s'est qu'il ses produit une erreur. { twi_generate_stop(); return I2C_INFO_NO_START; } //Envois de l'adresse et du mode lecture. twi_send_byte((address<<1)|TW_READ); // Envoi du premier octet, qui contient l'adresse et le mode écriture. while(!twi_is_raising_falg()); // Attend que le drapeau ce lève. if(twi_get_statu() != TW_MR_SLA_ACK) // Si le statu n'est pas TW_MR_SLA_ACK, s'est qu'il ses produit une erreur. { twi_generate_stop(); return I2C_INFO_NO_ADDRESSED; } const size_t iteratorTop = size-1; // Itération maximum du tableau des données. //Reçoit autan de données -1 que demander. for(size_t i=0; i < iteratorTop; i++) { twi_receive_byte_ack(); // Prépare le composent à resevoire un octet inci qu'a transmettre le bit ack. while(!twi_is_raising_falg()); // Attend que le drapeau ce lève. if(twi_get_statu() != TW_MR_DATA_ACK) // Si le statu n'est pas TW_MR_DATA_ACK, s'est qu'il ses produit une erreur. { twi_generate_stop(); return I2C_INFO_DATA_NO_READ; } data[i] = twi_get_received_byte(); // Récupère l'octet qui viens d'être reçus. } // Resoi le dernier octet twi_receive_byte_nack(); // Prépare le composent à resevoire un octet inci qu'a transmettre le bit nack. while(!twi_is_raising_falg()); // Attend que le drapeau ce lève. if(twi_get_statu() != TW_MR_DATA_NACK) // Si le statu n'est pas TW_MR_DATA_NACK, s'est qu'il ses produit une erreur. { twi_generate_stop(); return I2C_INFO_DATA_NO_READ; } data[iteratorTop] = twi_get_received_byte(); // Récupère l'octet qui viens d'être reçus. // Pour générai la condition de stop, si souhaiter. if(stop) twi_generate_stop(); return I2C_INFO_NO_ERROR; }
int main() { //... //Un buffer pour récupérer les données. uint8_t buf[2]; //Sélectionne la fréquence du bus à 400KHz (cpu à 16MHz). twi_bit_rate_generator(12, TWI_PRESCALER_1); //Active le twi. twi_enable(); //... twi_generate_start(); // Pour générai la condition de start. while(!twi_is_raising_falg()); // Attend que le drapeau ce lève. if(twi_get_statu() != TW_START) // Si le statu n'est pas TW_START, s'est qu'il ses produit une erreur. TWI_ERREUR(); //Envoi l'adresse. twi_send_byte((TWI_ADD<<1)|TW_READ); // Envoi du premier octet, qui contient l'adresse et le mode lecture. while(!twi_is_raising_falg()); // Attend que le drapeau ce lève. if(twi_get_statu() != TW_MR_SLA_ACK) // Si le statu n'est pas TW_MR_SLA_ACK, s'est que le composent de cette adresse n'a pas répondu pressent. TWI_ERREUR(); //Reçoit les données. twi_receive_byte_ack(); // Permet de préparer la réception d'une donnée et de générai le bit ack à la fin de la résection, pour indiquer que l'on veut accérire d'autre donnée. while(!twi_is_raising_falg()); // Attend que le drapeau ce lève. if(twi_get_statu() != TW_MR_DATA_ACK) // Si le statu n'est pas TW_MR_DATA_ACK, s'est qu'il ses produit une erreur. TWI_ERREUR(); buf[0] = twi_get_received_byte(); // Récupère de la donnée ressue. twi_receive_byte_nack(); // Permet de préparer la réception d'une donnée et de générai le bit nack à la fin de la résection, pour indiquer que l'on ne veut plus accérire d'autre donnée. while(!twi_is_raising_falg()); // Attend que le drapeau ce lève. if(twi_get_statu() != TW_MR_DATA_NACK) // Si le statu n'est pas TW_MR_DATA_NACK, s'est qu'il ses produit une erreur. TWI_ERREUR(); buf[1] = twi_get_received_byte(); // Récupère de la donnée ressue. twi_generate_stop(); // Pour générai la condition de stop. //.. while(1) { //... } return 0; }
// must be called in: // slave tx event callback // or after beginTransmission(address) void twi_send(uint8_t* data, uint8_t quantity) { if(transmitting){ // in master transmitter mode for(uint8_t i = 0; i < quantity; ++i){ twi_send_byte(data[i]); } }else{ // in slave send mode // reply to master twi_transmit(data, quantity); } }