//Same as the previous function, except that it reads multiple registers and stores them in data //The code must ensure that *data is large enough to contain all read data void DS1307RegisterRMult(uint8_t FirstReg, uint8_t NumReg, uint8_t *data){//Read from arbitrary number of registers TWIStart(); TWIWrite(DS1307ADDRESS | (0 << 0)); TWIWrite(FirstReg); TWIStart(); TWIWrite(DS1307ADDRESS | (1 << 0)); for(uint8_t i = 0; i < (NumReg - 1); i++){ data[i] = TWIReadACK(); } data[NumReg] = TWIReadNACK(); }
//Reads from a single register //Again, speed is generally not an issue, so this is adequate for most applications uint8_t DS1307RegisterR(uint8_t reg){//Read from a single register uint8_t data = 0; TWIStart(); TWIWrite(DS1307ADDRESS | (0 << 0)); TWIWrite(reg); TWIStart(); TWIWrite(DS1307ADDRESS | (1 << 0)); data = TWIReadNACK(); TWIStop(); return data; }
// Stops the CLK output void stopRTC(void){ TWIStart(); TWIWrite(0xA2); TWIWrite(0x0D); TWIWrite(0x00); TWIStop(); }
// RTC 1Hz clk output void initTimer(void){ TWIStart(); TWIWrite(0xA2); TWIWrite(0x0D); TWIWrite(0b10000011); TWIStop(); }
void DS1307Init(){//Initialize the DS1307; enable clock. TWIStart(); TWIWrite(DS1307ADDRESS | (0 << 0));//Write to the DS1307 TWIWrite(0x00);//I want to write to register 0x00, so that is the first byte TWIWrite(0x00);//I want all bits in register 0x00 to be 0, so 0x00 is my second byte. In particular, I want bit 7, the clock enable bit, to be 0, so that the oscillator boots up. TWIStop(); }
//This function takes two arguements, which register and what byte you want that register to be written //The interface with the DS1307 is not critical, so this function is all I really need void DS1307RegisterW(uint8_t reg, uint8_t data){//Write to a single register TWIStart(); TWIWrite(DS1307ADDRESS | (0 << 0)); TWIWrite(reg); TWIWrite(data); TWIStop(); }
// Gets the current percentage of the battery void getBatteryPercentage(void){ TWIStart(); TWIWrite(DS2782EAddress); // Average current TWIWrite(0x10); // Current accumulation TWIStart(); //Check status TWIWrite(DS2782EAddress|0b00000001); vcc = TWIReadACK() << 8;//} vcc += TWIReadNACK(); vcc = vcc*(0.3125); // 6.25uVh/Rsns = 6.25u/20mOhm = 0.0003125Ah = 0.3125mAh = 1/3.2 = 312uA vcc = (vcc * 100) / 300; // Converting to % (assumming 373mAh = 100% from experiment TWIStop(); }
//If I do need to write multiple registers a bit faster, I can use this //It takes several arguements *reg is an array of bytes, where each byte is a register, NumReg is the length of this array and the number of registers you want to write //I have it taking NumReg because I assume the code will know how many elements it assigned to *reg, so this saves finding out the length //NumReg is also the number of elements in *data //*data is an array where each element is the data you want written to the corresponding register //data[i] is written to reg[i[] void DS1307RegisterWMult(uint8_t *reg, uint8_t NumReg, uint8_t *data){//Write to arbitrary number of registers for(uint8_t i = 0; i < NumReg; i++){ TWIStart(); TWIWrite(DS1307ADDRESS | (0 << 0)); TWIWrite(reg[i]); TWIWrite(data[i]); } TWIStop(); }
uint16_t ReadTemp(uint8_t var){ uint8_t addr = 0x90; uint8_t regPtr = 0x00; addr = addr & 0xFE; TWIStart(); TWIWrite(addr); TWIWrite(regPtr); TWIStart(); TWIWrite(addr | 0x01); uint8_t data1 = TWIReadACK(); uint8_t data2 = TWIReadNACK(); TWIStop(); uint8_t val = (data1 & 0x7F )<<1; uint8_t add = (data2 & 0x80)>>7; uint8_t sign = (data1 & 0x80)>>7; uint16_t res = val | add; res = res | ((uint16_t)sign) << 8; return res; }
void TWIRead(uint8_t address, uint8_t *data, uint8_t length) { //Start comms TWIStart(); //Address slave for reading TWIAddress(address, 0x01); //Do not read last byte with ack for(unsigned int ii = 0; ii < length; ++ii) { *data++ = TWIReadACK(); } //Read last bit with nack *data = TWIReadNACK(); //Generate stop TWIStop(); }
void TWIWrite(uint8_t address, uint8_t *data, uint8_t length) { TWIStart(); TWIAddress(address, 0x00); //For each byte for(unsigned int ii = 0; ii < length; ii++) { /* Load DATA into TWDR Register. Clear TWINT bit in TWCR to start transmission of data */ TWDR = *data++; TWCR = (1<<TWINT) | (1<<TWEN); /* Wait for TWINT Flag set. This indicates that the DATA has been transmitted, and ACK/NACK has been received. */ while (!(TWCR & (1<<TWINT))); /* Check value of TWI Status Register. Mask prescaler bits. If status different from MT_DATA_ACK go to ERROR */ //if ((TWSR & 0xF8) != TWI_MT_DATA_ACK) // ERROR(LED_GREEN | LED_RED); } TWIStop(); }
uint8_t WriteWord(uint8_t deviceAddr, uint8_t regPtr, uint16_t data) { uint8_t datal = *((uint8_t*)&data); uint8_t datah = *(((uint8_t*)&data)+1); // Step a bit forward, just like using an array uint8_t reply; TWIStart(); if (TWIGetStatus() != 0x08) return ERROR; // Write Device Addr // Device addr is built according to the scheme: // 0011,A2,A1,A0,RW // 0011 = 0x30 // A2,A1,A0 Mask = 0x0E uint8_t addr = 0; addr = 0x30 | ( deviceAddr & 0x0E ); // Clear RW Bit for Writing, this is actually not needed. Just in case addr = addr & 0xFE; TWIWrite(addr); if ((reply = TWIGetStatus()) != 0x18) // READ an ACK return ERROR; TWIWrite(regPtr); if ((reply = TWIGetStatus()) != 0x18) // READ an ACK return ERROR; TWIWrite(datah); if ((reply = TWIGetStatus()) != 0x18) // READ an ACK return ERROR; TWIWrite(datal); if ((reply = TWIGetStatus()) != 0x18) // READ an ACK return ERROR; TWIStop(); return SUCCESS; }
uint16_t ReadWord( uint8_t deviceAddr, uint8_t regPtr ){ uint16_t data = 0; uint8_t * datal = ((uint8_t*)&data); uint8_t * datah = (((uint8_t*)&data)+1); // Step a bit forward, just like using an array uint8_t reply; int i = 0; // Write Device Addr // Device addr is built according to the scheme: // 0011,A2,A1,A0,RW // 0011 = 0x30 // A2,A1,A0 Mask = 0x0E uint8_t addr = 0; addr = 0x90 | ( deviceAddr & 0x0E ); // Set RW Bit for Reading // addr = addr | 0x0C; // addr = addr | 0x80; // Write Device Addr, WRITING i = 0; for( ; i < RETRIES; i++ ){ TWIStart(); if ((reply = TWIGetStatus()) != TW_START){ TWIStop(); return ERROR; } TWIWrite(addr & 0xFE); reply = TWIGetStatus(); if (reply == TW_MT_SLA_ACK){ // READ an ACK break; }else if (reply == TW_MT_SLA_NACK || reply == TW_MT_ARB_LOST ){ continue; }else{ TWIStop(); return ERROR; } if( i == RETRIES -1 ){ TWIStop(); return ERROR; } } // Write Register Addr TWIWrite(regPtr); reply = TWIGetStatus(); if (reply != TW_MT_DATA_ACK){ // READ an ACK TWIStop(); return ERROR; } TWIStart(); TWIWrite(addr | 0x01); //*datah = TWIReadACK(); uint8_t data1 = TWIReadACK(); if ((reply = TWIGetStatus()) != TW_MR_DATA_ACK){ // READ an ACK TWIStop(); return ERROR; } //*datal = TWIReadNACK(); uint8_t data2 = TWIReadNACK(); if ((reply = TWIGetStatus()) != TW_MR_DATA_NACK){ // READ an ACK TWIStop(); return ERROR; } TWIStop(); return data; }
int main(void) { init(); //****** //TEST 1 //****** #if _TEST == 1 bool toggle = false; uint8_t packet_pos = 0; char c; DDRD |= (1 << PD6); init(); while(true) { c = uart0_getchar(); if (c == 'y') { toggle = false; uart0_putchar('y'); } if (c == 'n') { toggle = true; uart0_putchar('n'); } if (toggle) PORTD |= (1 << PD6); else PORTD &= ~(1 << PD6); } //****** //TEST 2 //****** #elif _TEST == 2 char c; DDRD |= (1 << PD6) // set outputs in PORTD | (1 << PD5) | (1 << PD4); TCCR1A = 0x00; // clear all current timer 1 settings TCCR1B = 0x00; TCCR1B |= (1 << WGM12); // turn on CTC mode: // Clear Timer on Compare Match TIMSK1 = (1 << TOIE1); // enable global and timer overflow interrupt TCCR1B |= (1 << CS10); while(true) { c = uart0_getchar(); if (c != EOF) { if (c == 'f') servoTurn(0); if (c == 'g') servoTurn(90); if (c == 'h') servoTurn(180); } } //****** v //TEST 3 //****** #elif _TEST == 3 Packet host_packet; PacketInit(&host_packet); int len = 0; char c; DDRD |= (1 << PD6); while(1) { c = uart0_getchar(); if (c != EOF) len = PacketProcessChar(&host_packet, c); if (len > 0) uart0_printstr("got a packet!\r\n"); } //****** //TEST 4 //****** #elif _TEST == 4 uint8_t messageBuf[4]; uint8_t TWI_slaveAddress = 0x10; DDRD |= (1 << PD5) | (1 << PD6); TWIInit(); sei(); while(1) { PORTD ^= (1 << PD5) | (1 << PD6); TWIStart(); //TWIStop(); _delay_ms(500); } #elif _TEST == 5 Packet host_packet; PacketInit(&host_packet); int len = 0; char c; DDRD |= (1 << PD5); uint8_t message_buf[] = {0xFE, 0xFE, 0x01, 0x04, 0x02, 0x2B, 0x01, 0xCC}; int i; while(1) { c = uart0_getchar(); if (c != EOF) { len = PacketProcessChar(&host_packet, c); } if (len > 0) { PORTD ^= (1 << PD5); len = 0; } //for (i = 0; i < 8; i++) // uart0_putchar(message_buf[i]); //uart0_putchar(0xFD); //uart0_putchar(0xFF); //c = uart0_getchar(); //if (c != EOF) { // len = PacketProcessChar(&host_packet, c); //PORTD ^= (1 << PD5); //} //if (len > 0) //PORTD ^= (1 << PD5); //_delay_ms(1000); } /* DDRD |= (1 << PD5); char c; while(1) { c = uart0_getchar(); if (c != EOF) { uart0_putchar(c); PORTD ^= (1 << PD5); //_delay_ms(500); } }*/ #endif // _TEST return 0; }