/*
* File: TempSensor.c
* Author: narayan
*
* Created on 15 de Março de 2019, 22:29
*/
#ifndef F_CPU
# define F_CPU 20000000UL / 8
#endif
#include <stdlib.h>
#include <inttypes.h>
#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
#include "usart.h"
/*
*
*/
#define WRITE_OP (0x00 << 0x00)
#define READ_OP (0x01 << 0x00)
//Statuses handling
#define STATUS_NACK 1
#define STATUS_ACK 0
#define STATUS_OK 0
#define ARBLOST -1
#define BUSRROR -2
void CPU_Init(void){
// Enable Protected registers write
CPU_CCP = CCP_IOREG_gc;
CLKCTRL_MCLKCTRLA = CLKCTRL_CLKSEL_OSC20M_gc;
// Eable Prescaler
CPU_CCP = CCP_IOREG_gc;
CLKCTRL_MCLKCTRLB = CLKCTRL_PDIV_8X_gc | CLKCTRL_PEN_bm;
CPU_SREG |= CPU_I_bm; // Global Interrupt Flag Enabled
}
void TWI_Init(void){
TWI0_CTRLA |= TWI_SDASETUP_4CYC_gc // SDASETUP time of 4 clock cycles
| TWI_SDAHOLD_500NS_gc; // SDA Hold time - Meets SMBus specifications across all corners (0x03) ???
TWI0_CTRLA &= ~TWI_FMPEN_bm; // Fast Mode Plus disabled
// Set MBAUD to get 100KHz for SCL from fSCL = CLK_PER / (10 + 2*BAUD + CLK_PER*tRise)
// fSCL = 104KHz, CLK_PER = 20MHz/8, tRise = 2.5ns (datasheet page 17)
TWI0_MBAUD = 0x07;
TWI0_MCTRLB |= TWI_FLUSH_bm; // Clear TWI state
TWI0_MSTATUS |= TWI_RIF_bm // Set RIF
| TWI_WIF_bm // Set WIF
| TWI_BUSSTATE_IDLE_gc; // Manually set BUS state to IDLE
TWI0_MCTRLA &= ~TWI_TIMEOUT_gm; // Disable Timeout for TWI operation
TWI0_MCTRLA |= TWI_SMEN_bm // Smart Mode Enable
| TWI_ENABLE_bm; // Enable Master Mode of operation
}
void Start_Bit(void){
// Wait until BUS is IDLE
while( (TWI0_MSTATUS & TWI_BUSSTATE_gm) != TWI_BUSSTATE_IDLE_gc)
/*wait*/;
// Send Start Bit
TWI0_MCTRLB = TWI_MCMD_REPSTART_gc;
}
void Stop_Bit(void){
// Wait until BUS is IDLE
while( (TWI0_MSTATUS & TWI_BUSSTATE_gm) != TWI_BUSSTATE_IDLE_gc)
/*wait*/;
TWI0_MCTRLB = TWI_MCMD_STOP_gc;
}
uint8_t TWI_Read(uint8_t sl_addr, uint8_t* packet, uint8_t* psumtemp, float* pavgtemp){
if( (TWI0_MSTATUS & TWI_BUSERR_bm) || (TWI0_MSTATUS & TWI_ARBLOST_bm) ){
TWI0_MCTRLA &= ~TWI_ENABLE_bm;
_delay_ms(1);
TWI0_MCTRLA |= TWI_ENABLE_bm;
TWI0_MCTRLA |= TWI_BUSSTATE_IDLE_gc;
}
// Send Slave address and R operation onto the bus
TWI0_MADDR = (sl_addr << 1) | READ_OP;
for(uint8_t i = 0; i < 5; i++){
// Data byte is stored into TWI0_DATA register and passed to *packet variable
*(packet + i) = TWI0_MDATA;
// Sum the read value
*psumtemp += *(packet + i);
// Average readed values
*pavgtemp = *psumtemp / 5.0;
if(i == 5){
// Stop reading more data bytes with a NACK
TWI0_MCTRLB = TWI_ACKACT_NACK_gc;
break;
}
// Send ACK from Master to signal Data packed readed
TWI0_MCTRLB = TWI_ACKACT_ACK_gc;
}
// Send Stop bit to terminate transaction
TWI0_MCTRLB = TWI_MCMD_STOP_gc;
return STATUS_OK;
}
int main(int argc, char** argv) {
uint8_t temperature[256] = {0};
uint8_t sumtemp = 0;
float avgtemp = 0.0;
char message[256];
CPU_Init();
USART2_Init();
TWI_Init();
while(0x01){
TWI_Read(0x18, temperature, &sumtemp, &avgtemp);
USART2_SendStr
(itoa(avgtemp
, message
, 10)); USART2_SendChar('\n');
_delay_ms(1000);
}
return (EXIT_SUCCESS);
}