summaryrefslogtreecommitdiff
path: root/libs/dolphin/src/vi/i2c.c
blob: af048c61e3c9a35cf81fc2ad32247a98fdb1cdc7 (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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <dolphin/vi.h>

#include "__vi.h"

static int lastError;

static int wait4ClkHigh(void) {
    int n;

    for (n = 0; n < 1000; n++) {
        if (__VIGetSCL() != 0) {
            return 1;
        }
    }

    lastError = 2;
    return 0;
}

static int sendSlaveAddr(u8 slaveAddr) {
    int i;

    __VISetSDA(0);
    __VISetSCL(0);

    for (i = 0; i < 8; i++) {
        if (slaveAddr & 0x80) {
            __VISetSDA(1);
        } else {
            __VISetSDA(0);
        }

        __VISetSCL(1);
        if (wait4ClkHigh() == 0) {
            return 0;
        }

        __VISetSCL(0);
        slaveAddr <<= 1;
    }

    __VISetSDA(1);
    __VISetSCL(1);

    if (wait4ClkHigh() == 0) {
        return 0;
    }

    if (__VIGetSDA() != 0) {
        lastError = 1;
        return 0;
    }

    __VISetSCL(0);
    return 1;
}

int __VISendI2CData(u8 slaveAddr, u8* pData, int nBytes) {
    s32 i;
    u8 data;

    if (sendSlaveAddr(slaveAddr) == 0) {
        return 0;
    }

    while (nBytes != 0) {
        data = *pData++;
        for (i = 0; i < 8; i++) {
            if (data & 0x80) {
                __VISetSDA(1);
            } else {
                __VISetSDA(0);
            }

            __VISetSCL(1);

            if (wait4ClkHigh() == 0) {
                return 0;
            }

            __VISetSCL(0);
            data <<= 1;
        }

        __VISetSDA(1);
        __VISetSCL(1);

        if (wait4ClkHigh() == 0) {
            return 0;
        }

        if (nBytes != 1 && __VIGetSDA() != 0) {
            lastError = 1;
            return 0;
        }

        __VISetSCL(0);
        nBytes--;
    }

    __VISetSDA(0);
    __VISetSCL(1);
    __VISetSDA(1);
    return 1;
}