Subversion Repositories freemyipod

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
273 theseven 1
//
2
//
3
//    Copyright 2010 TheSeven
4
//
5
//
427 farthen 6
//    This file is part of emCORE.
273 theseven 7
//
427 farthen 8
//    emCORE is free software: you can redistribute it and/or
273 theseven 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
//
427 farthen 13
//    emCORE is distributed in the hope that it will be useful,
273 theseven 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
427 farthen 19
//    with emCORE.  If not, see <http://www.gnu.org/licenses/>.
273 theseven 20
//
21
//
22
 
23
 
24
#include "global.h"
25
#include "i2c.h"
26
#include "thread.h"
27
#include "s5l8702.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);
386 theseven 41
    while (IIC10(bus));
273 theseven 42
    IICDS(bus) = device & ~1;
386 theseven 43
    while (IIC10(bus));
273 theseven 44
    IICSTAT(bus) = 0xF0;
386 theseven 45
    while (IIC10(bus));
273 theseven 46
    IICCON(bus) = 0xB7;
47
    while ((IICCON(bus) & 0x10) == 0) yield();
48
    if (address >= 0)
49
    {
50
        /* write address */
386 theseven 51
        while (IIC10(bus));
273 theseven 52
        IICDS(bus) = address;
386 theseven 53
        while (IIC10(bus));
273 theseven 54
        IICCON(bus) = 0xB7;
55
        while ((IICCON(bus) & 0x10) == 0) yield();
56
    }
57
    /* write data */
58
    while (length--)
59
    {
386 theseven 60
        while (IIC10(bus));
273 theseven 61
        IICDS(bus) = *data++;
386 theseven 62
        while (IIC10(bus));
273 theseven 63
        IICCON(bus) = 0xB7;
64
        while ((IICCON(bus) & 0x10) == 0) yield();
65
    }
66
    /* STOP */
386 theseven 67
    while (IIC10(bus));
273 theseven 68
    IICSTAT(bus) = 0xD0;
386 theseven 69
    while (IIC10(bus));
273 theseven 70
    IICCON(bus) = 0xB7;
71
    while ((IICSTAT(bus) & (1 << 5)) != 0) yield();
72
    mutex_unlock(&i2cmutex);
73
}
74
 
75
void i2c_recv(uint32_t bus, uint32_t device, uint32_t address, uint8_t* data, uint32_t length)
76
{
77
    mutex_lock(&i2cmutex, TIMEOUT_BLOCK);
78
    if (address >= 0)
79
    {
80
        /* START */
386 theseven 81
        while (IIC10(bus));
273 theseven 82
        IICDS(bus) = device & ~1;
386 theseven 83
        while (IIC10(bus));
273 theseven 84
        IICSTAT(bus) = 0xF0;
386 theseven 85
        while (IIC10(bus));
273 theseven 86
        IICCON(bus) = 0xB7;
87
        while ((IICCON(bus) & 0x10) == 0) yield();
88
        /* write address */
386 theseven 89
        while (IIC10(bus));
273 theseven 90
        IICDS(bus) = address;
386 theseven 91
        while (IIC10(bus));
273 theseven 92
        IICCON(bus) = 0xB7;
93
        while ((IICCON(bus) & 0x10) == 0) yield();
94
    }
95
    /* (repeated) START */
386 theseven 96
    while (IIC10(bus));
273 theseven 97
    IICDS(bus) = device | 1;
386 theseven 98
    while (IIC10(bus));
273 theseven 99
    IICSTAT(bus) = 0xB0;
386 theseven 100
    while (IIC10(bus));
273 theseven 101
    IICCON(bus) = 0xB7;
102
    while ((IICCON(bus) & 0x10) == 0) yield();
103
    while (length--)
104
    {
386 theseven 105
        while (IIC10(bus));
273 theseven 106
        IICCON(bus) = (length == 0) ? 0x37 : 0xB7; /* NACK or ACK */
107
        while ((IICCON(bus) & 0x10) == 0) yield();
108
        *data++ = IICDS(bus);
109
    }
110
    /* STOP */
386 theseven 111
    while (IIC10(bus));
273 theseven 112
    IICSTAT(bus) = 0x90;
386 theseven 113
    while (IIC10(bus));
273 theseven 114
    IICCON(bus) = 0xB7;
115
    while ((IICSTAT(bus) & (1 << 5)) != 0) yield();
116
    mutex_unlock(&i2cmutex);
117
}
118
 
119
void i2c_sendbyte(uint32_t bus, uint32_t device, uint32_t address, uint32_t data)
120
{
121
    uint8_t buf[1];
122
    buf[0] = data;
123
    i2c_send(bus, device, address, buf, 1);
124
}
125
 
126
uint8_t i2c_recvbyte(uint32_t bus, uint32_t device, uint32_t address)
127
{
128
    uint8_t buf[1];
129
    i2c_recv(bus, device, address, buf, 1);
130
    return buf[0];
131
}