aboutsummaryrefslogtreecommitdiff
path: root/main/i2c.c
blob: 3ecc2ee6b2c178f2b9c0dc243994eff66de576f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include "i2c.h"

#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <pico/stdlib.h>
#include <hardware/i2c.h>

void init_i2c() {
    stdio_init_all();
	i2c_init(i2c_default, 100 * 1000); // currently at 100kHz

	// Initialize I2C pins - sda(16), scl(17)
    gpio_set_function(SDA_PIN, GPIO_FUNC_I2C);
    gpio_set_function(SCL_PIN, GPIO_FUNC_I2C);

    gpio_pull_up(SDA_PIN);
    gpio_pull_up(SCL_PIN);
}

int read_i2c(uint8_t addr, uint8_t *output, size_t len) {
    // false - finished with bus
    return i2c_read_blocking (i2c_default, addr, output, len, false);
}

int write_i2c(uint8_t addr, uint8_t *input, size_t len) {
    // true to keep master control of bus
    return i2c_write_blocking (i2c_default, addr, input, len, true);
}

bool reserved_addr(uint8_t addr) {
    return (addr & 0x78) == 0 || (addr & 0x78) == 0x78;
}

void init_addr_array(uint8_t array[]) {
    for(int i = 0; i < MAX_SLAVES; i++){
        array[i] = 0x00;
    }
}

uint8_t scan_bus(uint8_t array[]) {
    int ret;
    int i = 0;
    uint8_t rxdata;

    for(int addr = 0; addr < (1<<7); addr++) {
        // ignore reserved addresses
        // These are any addresses of the form 000 0xxx or 111 1xxx
        if( reserved_addr(addr) ){
            ret = PICO_ERROR_GENERIC;
        }else{
            ret = i2c_read_blocking(i2c_default, addr, &rxdata, 1, false);
        }

        // if acknowledged -> ret == number of bytes sent
        if(ret > 0){
            array[i] = addr;
            i++;
        }
    }

    return array;
}

void bus_task() {
    // scan bus for slaves
    // send updates at regular intervals

    int i = 0;
    uint8_t *found[MAX_SLAVES];
    init_addr_array(&found);

    while(1) {
        scan_bus(&found);

        for(int i = 0; i < MAX_SLAVES; i++){
            if( found[i] == 0x00 )
                break;
            
            // send data to found slave address
            write_i2c(found[i], 0x01, 1);

            write_i2c(found[i], 0x00, 1);
            // request update from slave addr at found[i]
            //write_i2c();
        }
    }

}