I2CRTOS Driver by Helmut Schmücker. Removed included mbed-rtos library to prevent multiple definition. Make sure to include mbed-rtos library in your program!

Fork of I2cRtosDriver by Helmut Schmücker

Committer:
humlet
Date:
Sun Apr 14 06:39:04 2013 +0000
Revision:
1:90455d5bdd8c
Parent:
0:13c962fecb13
Child:
2:514105beb343
no more smoke

Who changed what in which revision?

UserRevisionLine numberNew contents of line
humlet 0:13c962fecb13 1 #include "I2CDriver.h"
humlet 0:13c962fecb13 2 #include "error.h"
humlet 0:13c962fecb13 3
humlet 1:90455d5bdd8c 4 using namespace mbed;
humlet 1:90455d5bdd8c 5 using namespace rtos;
humlet 0:13c962fecb13 6
humlet 1:90455d5bdd8c 7 #define ISR2DRV_SIG (1<<7)
humlet 1:90455d5bdd8c 8 #define DRV_USR_SIG (1<<6)
humlet 1:90455d5bdd8c 9
humlet 1:90455d5bdd8c 10 const PinName I2CDriver::c_sdas[] = {p9,p28};
humlet 1:90455d5bdd8c 11 const PinName I2CDriver::c_scls[] = {p10,p27};
humlet 1:90455d5bdd8c 12
humlet 1:90455d5bdd8c 13 I2CDriver::Channel* I2CDriver::s_channels[2] = {0,0};
humlet 0:13c962fecb13 14
humlet 0:13c962fecb13 15
humlet 0:13c962fecb13 16 void I2CDriver::channel_0_ISR()
humlet 0:13c962fecb13 17 {
humlet 1:90455d5bdd8c 18 osSignalSet( s_channels[0]->driver, ISR2DRV_SIG);
humlet 1:90455d5bdd8c 19 NVIC_DisableIRQ(I2C1_IRQn);
humlet 0:13c962fecb13 20 }
humlet 0:13c962fecb13 21
humlet 0:13c962fecb13 22
humlet 0:13c962fecb13 23 void I2CDriver::channel_1_ISR()
humlet 0:13c962fecb13 24 {
humlet 1:90455d5bdd8c 25 osSignalSet( s_channels[1]->driver, ISR2DRV_SIG);
humlet 1:90455d5bdd8c 26 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
humlet 1:90455d5bdd8c 27 NVIC_DisableIRQ(I2C2_IRQn);
humlet 1:90455d5bdd8c 28 #elif defined(TARGET_LPC11U24)
humlet 1:90455d5bdd8c 29 NVIC_DisableIRQ(I2C_IRQn);
humlet 1:90455d5bdd8c 30 #endif
humlet 0:13c962fecb13 31 }
humlet 0:13c962fecb13 32
humlet 0:13c962fecb13 33
humlet 1:90455d5bdd8c 34 void I2CDriver::threadFun(void const *args)
humlet 0:13c962fecb13 35 {
humlet 0:13c962fecb13 36 int channelIdx = (int)args;
humlet 0:13c962fecb13 37 Channel channel;
humlet 0:13c962fecb13 38 s_channels[channelIdx] = &channel;
humlet 0:13c962fecb13 39
humlet 0:13c962fecb13 40 channel.driver = Thread::gettid();
humlet 1:90455d5bdd8c 41 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
humlet 0:13c962fecb13 42 if(channelIdx==0)NVIC_SetVector(I2C1_IRQn, (uint32_t)I2CDriver::channel_0_ISR);
humlet 0:13c962fecb13 43 if(channelIdx==1)NVIC_SetVector(I2C2_IRQn, (uint32_t)I2CDriver::channel_1_ISR);
humlet 1:90455d5bdd8c 44 #elif defined(TARGET_LPC11U24)
humlet 1:90455d5bdd8c 45 NVIC_SetVector(I2C_IRQn, (uint32_t)I2CDriver::channel_1_ISR);
humlet 1:90455d5bdd8c 46 #endif
humlet 1:90455d5bdd8c 47 I2C i2c(c_sdas[channelIdx], c_scls[channelIdx]);
humlet 1:90455d5bdd8c 48 volatile Transfer& tr = channel.transfer;
humlet 0:13c962fecb13 49 while(1) {
humlet 1:90455d5bdd8c 50 // wait for requests
humlet 1:90455d5bdd8c 51 osSignalWait(DRV_USR_SIG,osWaitForever);
humlet 1:90455d5bdd8c 52 // check and adapt frequency
humlet 1:90455d5bdd8c 53 if(channel.freq != tr.freq) {
humlet 1:90455d5bdd8c 54 channel.freq = tr.freq;
humlet 1:90455d5bdd8c 55 i2c.frequency(tr.freq);
humlet 1:90455d5bdd8c 56 }
humlet 1:90455d5bdd8c 57 // just doit
humlet 1:90455d5bdd8c 58 switch(tr.cmd) {
humlet 0:13c962fecb13 59 case START:
humlet 0:13c962fecb13 60 i2c.start();
humlet 0:13c962fecb13 61 break;
humlet 0:13c962fecb13 62 case STOP:
humlet 0:13c962fecb13 63 i2c.stop();
humlet 0:13c962fecb13 64 break;
humlet 1:90455d5bdd8c 65 case READ:
humlet 1:90455d5bdd8c 66 tr.ret = i2c.read(tr.adr, tr.dta, tr.len, tr.rep);
humlet 1:90455d5bdd8c 67 break;
humlet 1:90455d5bdd8c 68 case READ_FROM_REGISTER:
humlet 1:90455d5bdd8c 69 tr.ret = i2c.write(tr.adr,(const char*)&(tr.reg), 1, true);
humlet 1:90455d5bdd8c 70 if(tr.ret)break; // error => bail out
humlet 1:90455d5bdd8c 71 tr.ret = i2c.read(tr.adr, tr.dta, tr.len, tr.rep);
humlet 1:90455d5bdd8c 72 break;
humlet 1:90455d5bdd8c 73 case READ_BYTE:
humlet 1:90455d5bdd8c 74 tr.ret = i2c.read(tr.ack);
humlet 1:90455d5bdd8c 75 break;
humlet 1:90455d5bdd8c 76 case WRITE:
humlet 1:90455d5bdd8c 77 tr.ret = i2c.write(tr.adr, tr.wdta, tr.len, tr.rep);
humlet 1:90455d5bdd8c 78 break;
humlet 1:90455d5bdd8c 79 case WRITE_BYTE:
humlet 1:90455d5bdd8c 80 tr.ret = i2c.write(tr.ack);
humlet 1:90455d5bdd8c 81 break;
humlet 1:90455d5bdd8c 82 default:
humlet 1:90455d5bdd8c 83 error("call 911");
humlet 0:13c962fecb13 84 }
humlet 1:90455d5bdd8c 85 // inform the caller
humlet 1:90455d5bdd8c 86 osSignalSet( channel.transfer.caller, DRV_USR_SIG);
humlet 0:13c962fecb13 87 }
humlet 0:13c962fecb13 88 }
humlet 0:13c962fecb13 89
humlet 0:13c962fecb13 90
humlet 1:90455d5bdd8c 91 I2CDriver::I2CDriver(PinName sda, PinName scl):I2C(sda,scl)
humlet 0:13c962fecb13 92 {
humlet 0:13c962fecb13 93 // check pins and determine i2c channel
humlet 0:13c962fecb13 94 int channel=0;
humlet 1:90455d5bdd8c 95 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
humlet 1:90455d5bdd8c 96 if(sda==c_sdas[0] && scl==c_scls[0]) channel=0; // I2C_1
humlet 1:90455d5bdd8c 97 else
humlet 1:90455d5bdd8c 98 #endif
humlet 1:90455d5bdd8c 99 if (sda==c_sdas[1] && scl==c_scls[1]) channel=1; //I2C_2 or I2C
humlet 1:90455d5bdd8c 100 else error("I2CDriver: Invalid I2C pinns selected");
humlet 0:13c962fecb13 101 if(s_channels[channel]==0)
humlet 0:13c962fecb13 102 new Thread(threadFun,(void *)channel,osPriorityRealtime);
humlet 1:90455d5bdd8c 103 m_channel = s_channels[channel];
humlet 0:13c962fecb13 104 }
humlet 0:13c962fecb13 105
humlet 1:90455d5bdd8c 106
humlet 1:90455d5bdd8c 107 void I2CDriver::sendNwait()
humlet 1:90455d5bdd8c 108 {
humlet 1:90455d5bdd8c 109 m_channel->transfer.freq = _hz;
humlet 1:90455d5bdd8c 110 m_channel->transfer.caller = Thread::gettid();
humlet 1:90455d5bdd8c 111 osSignalSet( m_channel->driver, DRV_USR_SIG);
humlet 0:13c962fecb13 112 osSignalWait(DRV_USR_SIG,osWaitForever);
humlet 0:13c962fecb13 113 }
humlet 0:13c962fecb13 114
humlet 0:13c962fecb13 115
humlet 1:90455d5bdd8c 116 int I2CDriver::read(int address, char *data, int length, bool repeated)
humlet 1:90455d5bdd8c 117 {
humlet 0:13c962fecb13 118 lock();
humlet 1:90455d5bdd8c 119 m_channel->transfer.cmd = READ;
humlet 1:90455d5bdd8c 120 m_channel->transfer.adr = address;
humlet 1:90455d5bdd8c 121 m_channel->transfer.dta = data;
humlet 1:90455d5bdd8c 122 m_channel->transfer.len = length;
humlet 1:90455d5bdd8c 123 m_channel->transfer.rep = repeated;
humlet 0:13c962fecb13 124 sendNwait();
humlet 1:90455d5bdd8c 125 int ret = m_channel->transfer.ret;
humlet 1:90455d5bdd8c 126 unlock();
humlet 1:90455d5bdd8c 127 return ret;
humlet 0:13c962fecb13 128 }
humlet 0:13c962fecb13 129
humlet 0:13c962fecb13 130
humlet 1:90455d5bdd8c 131 int I2CDriver::read(int address, uint8_t regist, char *data, int length, bool repeated)
humlet 1:90455d5bdd8c 132 {
humlet 1:90455d5bdd8c 133 lock();
humlet 1:90455d5bdd8c 134 m_channel->transfer.cmd = READ_FROM_REGISTER;
humlet 1:90455d5bdd8c 135 m_channel->transfer.adr = address;
humlet 1:90455d5bdd8c 136 m_channel->transfer.reg = regist;
humlet 1:90455d5bdd8c 137 m_channel->transfer.dta = data;
humlet 1:90455d5bdd8c 138 m_channel->transfer.len = length;
humlet 1:90455d5bdd8c 139 m_channel->transfer.rep = repeated;
humlet 1:90455d5bdd8c 140 sendNwait();
humlet 1:90455d5bdd8c 141 int ret = m_channel->transfer.ret;
humlet 1:90455d5bdd8c 142 unlock();
humlet 1:90455d5bdd8c 143 return ret;
humlet 1:90455d5bdd8c 144 }
humlet 1:90455d5bdd8c 145
humlet 1:90455d5bdd8c 146 int I2CDriver::read(int ack)
humlet 1:90455d5bdd8c 147 {
humlet 1:90455d5bdd8c 148 lock();
humlet 1:90455d5bdd8c 149 m_channel->transfer.cmd = READ_BYTE;
humlet 1:90455d5bdd8c 150 m_channel->transfer.ack = ack;
humlet 1:90455d5bdd8c 151 sendNwait();
humlet 1:90455d5bdd8c 152 int ret = m_channel->transfer.ret;
humlet 1:90455d5bdd8c 153 unlock();
humlet 1:90455d5bdd8c 154 return ret;
humlet 1:90455d5bdd8c 155 }
humlet 1:90455d5bdd8c 156
humlet 1:90455d5bdd8c 157 int I2CDriver::write(int address, const char *data, int length, bool repeated)
humlet 1:90455d5bdd8c 158 {
humlet 0:13c962fecb13 159 lock();
humlet 1:90455d5bdd8c 160 m_channel->transfer.cmd = WRITE;
humlet 1:90455d5bdd8c 161 m_channel->transfer.adr = address;
humlet 1:90455d5bdd8c 162 m_channel->transfer.wdta = data;
humlet 1:90455d5bdd8c 163 m_channel->transfer.len = length;
humlet 1:90455d5bdd8c 164 m_channel->transfer.rep = repeated;
humlet 1:90455d5bdd8c 165 sendNwait();
humlet 1:90455d5bdd8c 166 int ret = m_channel->transfer.ret;
humlet 1:90455d5bdd8c 167 unlock();
humlet 1:90455d5bdd8c 168 return ret;
humlet 1:90455d5bdd8c 169 }
humlet 1:90455d5bdd8c 170
humlet 1:90455d5bdd8c 171 int I2CDriver::write(int data)
humlet 1:90455d5bdd8c 172 {
humlet 1:90455d5bdd8c 173 lock();
humlet 1:90455d5bdd8c 174 m_channel->transfer.cmd = WRITE_BYTE;
humlet 1:90455d5bdd8c 175 m_channel->transfer.ack = data;
humlet 0:13c962fecb13 176 sendNwait();
humlet 1:90455d5bdd8c 177 int ret = m_channel->transfer.ret;
humlet 1:90455d5bdd8c 178 unlock();
humlet 1:90455d5bdd8c 179 return ret;
humlet 0:13c962fecb13 180 }
humlet 1:90455d5bdd8c 181
humlet 1:90455d5bdd8c 182 void I2CDriver::start(void)
humlet 1:90455d5bdd8c 183 {
humlet 1:90455d5bdd8c 184 lock();
humlet 1:90455d5bdd8c 185 m_channel->transfer.cmd = START;
humlet 1:90455d5bdd8c 186 sendNwait();
humlet 1:90455d5bdd8c 187 unlock();
humlet 1:90455d5bdd8c 188 }
humlet 1:90455d5bdd8c 189
humlet 1:90455d5bdd8c 190
humlet 1:90455d5bdd8c 191 void I2CDriver::stop(void)
humlet 1:90455d5bdd8c 192 {
humlet 1:90455d5bdd8c 193 lock();
humlet 1:90455d5bdd8c 194 m_channel->transfer.cmd = STOP;
humlet 1:90455d5bdd8c 195 sendNwait();
humlet 1:90455d5bdd8c 196 unlock();
humlet 1:90455d5bdd8c 197 }