Subversion Repositories freemyipod

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
85 theseven 1
//
2
//
3
//    Copyright 2010 TheSeven
4
//
5
//
6
//    This file is part of emBIOS.
7
//
8
//    emBIOS is free software: you can redistribute it and/or
9
//    modify it under the terms of the GNU General Public License as
10
//    published by the Free Software Foundation, either version 2 of the
11
//    License, or (at your option) any later version.
12
//
13
//    emBIOS is distributed in the hope that it will be useful,
14
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
//    See the GNU General Public License for more details.
17
//
18
//    You should have received a copy of the GNU General Public License along
19
//    with emBIOS.  If not, see <http://www.gnu.org/licenses/>.
20
//
21
//
22
 
23
 
24
#include "global.h"
25
#include "i2c.h"
26
#include "thread.h"
27
#include "s5l8720.h"
28
 
29
 
30
static struct mutex i2cmutex;
31
 
32
 
33
void i2c_init()
34
{
35
    mutex_init(&i2cmutex);
36
}
37
 
38
void i2c_send(uint32_t bus, uint32_t device, uint32_t address, const uint8_t* data, uint32_t length)
39
{
40
    mutex_lock(&i2cmutex, TIMEOUT_BLOCK);
87 theseven 41
    IICDS(bus) = device & ~1;
42
    IICSTAT(bus) = 0xF0;
43
    IICCON(bus) = 0xB7;
44
    while ((IICCON(bus) & 0x10) == 0) yield();
45
    if (address >= 0)
46
    {
47
        /* write address */
48
        IICDS(bus) = address;
49
        IICCON(bus) = 0xB7;
50
        while ((IICCON(bus) & 0x10) == 0) yield();
51
    }
52
    /* write data */
53
    while (length--)
54
    {
55
        IICDS(bus) = *data++;
56
        IICCON(bus) = 0xB7;
57
        while ((IICCON(bus) & 0x10) == 0) yield();
58
    }
59
    /* STOP */
60
    IICSTAT(bus) = 0xD0;
61
    IICCON(bus) = 0xB7;
62
    while ((IICSTAT(bus) & (1 << 5)) != 0) yield();
85 theseven 63
    mutex_unlock(&i2cmutex);
64
}
65
 
66
void i2c_recv(uint32_t bus, uint32_t device, uint32_t address, uint8_t* data, uint32_t length)
67
{
68
    mutex_lock(&i2cmutex, TIMEOUT_BLOCK);
87 theseven 69
    if (address >= 0)
70
    {
71
        /* START */
72
        IICDS(bus) = device & ~1;
73
        IICSTAT(bus) = 0xF0;
74
        IICCON(bus) = 0xB7;
75
        while ((IICCON(bus) & 0x10) == 0) yield();
76
        /* write address */
77
        IICDS(bus) = address;
78
        IICCON(bus) = 0xB7;
79
        while ((IICCON(bus) & 0x10) == 0) yield();
80
    }
81
    /* (repeated) START */
82
    IICDS(bus) = device | 1;
83
    IICSTAT(bus) = 0xB0;
84
    IICCON(bus) = 0xB7;
85
    while ((IICCON(bus) & 0x10) == 0) yield();
86
    while (length--)
87
    {
88
        IICCON(bus) = (length == 0) ? 0x37 : 0xB7; /* NACK or ACK */
89
        while ((IICCON(bus) & 0x10) == 0) yield();
90
        *data++ = IICDS(bus);
91
    }
92
    /* STOP */
93
    IICSTAT(bus) = 0x90;
94
    IICCON(bus) = 0xB7;
95
    while ((IICSTAT(bus) & (1 << 5)) != 0) yield();
85 theseven 96
    mutex_unlock(&i2cmutex);
97
}
98
 
99
void i2c_sendbyte(uint32_t bus, uint32_t device, uint32_t address, uint32_t data)
100
{
101
    uint8_t buf[1];
102
    buf[0] = data;
103
    i2c_send(bus, device, address, buf, 1);
104
}
105
 
106
uint8_t i2c_recvbyte(uint32_t bus, uint32_t device, uint32_t address)
107
{
108
    uint8_t buf[1];
109
    i2c_recv(bus, device, address, buf, 1);
110
    return buf[0];
111
}