program for I2C master device

Dependencies:   mbed

Fork of I2C_HelloWorld_Mbed by mbed official

main.cpp

Committer:
marcus255
Date:
2016-01-08
Revision:
11:eff597e2366e
Parent:
10:39dd1d3508c3

File content as of revision 11:eff597e2366e:

/*
* Project: I2C to UART converter
* File:    main.cpp
* Utility: simulating I2C Master devices
* Author:  Marek Trojan
*/

#include "main.h"

int main()
{
    init();
    wait_ms(1000);
    while (1) {}
}

void write_and_read()
{
    //led = !led;
    if (routine == MEMORY_ROUTINE) {
        read_data(&memory_cell_addr);
        wait_ms(20);
        write_data();
        memory_cell_addr+=0x10;
    } else if (routine == TIME_ROUTINE) {
        rtc_time();
    } else if (routine == SENSOR_ROUTINE) {
        rtc_sensor();
    }
}

void rtc_sensor()
{
    char temperature[2];
    if(get_temperature_raw(temperature)) {
        float result = proceed_temperature(temperature);
        pc.printf("> Temperature: %1.2f\n\r",result);
        wait_ms(1);
    } else {
        pc.printf("> I2C Error\n\r");
    }
}

void rtc_time()
{
    char time[3];
    if(get_time_raw(time)) {
        uint8_t t[6];
        proceed_time(time, t);
        pc.printf("> Time: %x%x:%x%x:%x%x\n\r", t[0], t[1], t[2], t[3], t[4], t[5]);
        wait_ms(1);
    } else {
        pc.printf("> I2C Error\n\r");
    }
}

int get_temperature_raw(char* temperature)
{
    char reg_addr = TEMPERATURE_REGISTER;
    if(i2c.write(RTC_ADDR, &reg_addr, 1)) {
        //pc.printf("Writing: Error\n\r");
        return 0;
    }
    wait_ms(20);
    if(i2c.read(RTC_ADDR, temperature, 2)) {
        //pc.printf("Reading: Error\n\r");
        return 0;
    }
    return 1;
}

int get_time_raw(char* time)
{
    char reg_addr = TIME_REGISTER;
    if(i2c.write(RTC_ADDR, &reg_addr, 1)) {
        return 0;
    }
    wait_ms(20);
    if(i2c.read(RTC_ADDR, time, 3)) {
        return 0;
    }
    return 1;
}

float proceed_temperature(char * temperature)
{
    char MSB = temperature[0]; // MSB is a signed int8 and carries temperature in accuracy of 1 Celsius degree
    char LSB = temperature[1]; // LSB carries fraction part of temperature. Possible values are 0, 0.25, 0.5, 0.75
    float high = (float)MSB;
    float low = ((float)((uint8_t)LSB >> 6) * 0.25f);
    return high + low;
}

void proceed_time(char * time, uint8_t * tiny_time)
{
    char secs = time[0];
    char mins = time[1];
    char hrs  = time[2];

    *(tiny_time + 0) = ((hrs  >> 4) & 0x01);
    *(tiny_time + 1) = (hrs  & 0x0F);
    *(tiny_time + 2) = ((mins >> 4) & 0x0F);
    *(tiny_time + 3) = (mins & 0x0F);
    *(tiny_time + 4) = ((secs >> 4) & 0x0F);
    *(tiny_time + 5) = (secs & 0x0F);
}


void write_data()
{
    srand(time(NULL));
    for (uint8_t i = 0; i < DATA_SIZE; i++) {
        data[i+1] = (char) (rnd() % 90 + 33);
    }
    data[0] = memory_cell_addr;
    if (i2c.write(EEPROM_ADDRESS, data, DATA_SIZE + 1)) {
        pc.printf("> Writing: Error\n\r");
    } else {
        pc.printf("> Writing: OK\n\r");
    }

}

void read_data(char* cell_addr)
{
    int success = 1;
    char fromSlave[DATA_SIZE + 1];
    fromSlave[DATA_SIZE] = '\0';
    if(i2c.write(EEPROM_ADDRESS, cell_addr, 1)) {
        success = 0;
    }
    wait_ms(20);
    if (success) {
        if(i2c.read(EEPROM_ADDRESS, fromSlave, DATA_SIZE)) {
            //pc.printf("Reading: Error\n\r");
            success = 0;
        }
    }
    if (success) {
        pc.printf("> Reading: OK, data at 0x%x is: %s\n\r", *cell_addr, fromSlave);
    } else {
        pc.printf("> Reading: Error\n\r");
    }
}

void init(void)
{
    i2c.frequency(I2C_FREQ_STANDARD / 2);
    i2c_ticker.attach(&write_and_read, 1.0f);
    pc.baud(PC_BAUD);
    pc.attach(&select_routine);
    routine = MEMORY_ROUTINE;
    memory_cell_addr = 0x00;
    m_z=12434,m_w=33254;
}

void select_routine()
{
    char cmd = pc.getc();
    switch (cmd) {
        case 'm':
        routine = MEMORY_ROUTINE;
        break;
        case 't':
        routine = SENSOR_ROUTINE;
        break;
        default:
        routine = TIME_ROUTINE; 
    }    
}

unsigned int rnd()
{
    m_z = 36969 * (m_z & 65535) + (m_z >>16);
    m_w = 18000 * (m_w & 65535) + (m_w >>16);
    return ((m_z <<16) + m_w);
}