Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed-rtos mbed-src
Revision 1:90455d5bdd8c, committed 2013-04-14
- Comitter:
- humlet
- Date:
- Sun Apr 14 06:39:04 2013 +0000
- Parent:
- 0:13c962fecb13
- Child:
- 2:514105beb343
- Commit message:
- no more smoke
Changed in this revision
--- a/I2CDriver.cpp Sat Apr 13 13:37:29 2013 +0000
+++ b/I2CDriver.cpp Sun Apr 14 06:39:04 2013 +0000
@@ -1,102 +1,197 @@
#include "I2CDriver.h"
#include "error.h"
-#define ISR2DRV_SIG (1<<0);
-#define DRV_USR_SIG (1<<1);
+using namespace mbed;
+using namespace rtos;
-Channel I2CDriver::channels[2]= {0,0};
+#define ISR2DRV_SIG (1<<7)
+#define DRV_USR_SIG (1<<6)
+
+const PinName I2CDriver::c_sdas[] = {p9,p28};
+const PinName I2CDriver::c_scls[] = {p10,p27};
+
+I2CDriver::Channel* I2CDriver::s_channels[2] = {0,0};
void I2CDriver::channel_0_ISR()
{
- osSignalSet( channels[0].driver, ISR2DRV_SIG);
- NVIC_DisableIRQ(I2C1_IRQn); //I2C_IRQn
+ osSignalSet( s_channels[0]->driver, ISR2DRV_SIG);
+ NVIC_DisableIRQ(I2C1_IRQn);
}
void I2CDriver::channel_1_ISR()
{
- osSignalSet( channels[1].driver, ISR2DRV_SIG);
- NVIC_DisableIRQ(I2C2_IRQn); //I2C_IRQn
+ osSignalSet( s_channels[1]->driver, ISR2DRV_SIG);
+#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
+ NVIC_DisableIRQ(I2C2_IRQn);
+#elif defined(TARGET_LPC11U24)
+ NVIC_DisableIRQ(I2C_IRQn);
+#endif
}
-void I2CDriver::threadFun(void* const args)
+void I2CDriver::threadFun(void const *args)
{
int channelIdx = (int)args;
Channel channel;
s_channels[channelIdx] = &channel;
channel.driver = Thread::gettid();
-
+#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
if(channelIdx==0)NVIC_SetVector(I2C1_IRQn, (uint32_t)I2CDriver::channel_0_ISR);
if(channelIdx==1)NVIC_SetVector(I2C2_IRQn, (uint32_t)I2CDriver::channel_1_ISR);
-
- I2C i2c(c_sda[channelIdx], c_scl[channelIdx]);
-
+#elif defined(TARGET_LPC11U24)
+ NVIC_SetVector(I2C_IRQn, (uint32_t)I2CDriver::channel_1_ISR);
+#endif
+ I2C i2c(c_sdas[channelIdx], c_scls[channelIdx]);
+ volatile Transfer& tr = channel.transfer;
while(1) {
- osSignalWait(DRV_USR_SIG,0);
- switch(channels[channel].transfer.cmd) {
+ // wait for requests
+ osSignalWait(DRV_USR_SIG,osWaitForever);
+ // check and adapt frequency
+ if(channel.freq != tr.freq) {
+ channel.freq = tr.freq;
+ i2c.frequency(tr.freq);
+ }
+ // just doit
+ switch(tr.cmd) {
case START:
- if(channel.freq!=channel.transfer.freq) i2c.frequency
i2c.start();
break;
case STOP:
i2c.stop();
break;
+ case READ:
+ tr.ret = i2c.read(tr.adr, tr.dta, tr.len, tr.rep);
+ break;
+ case READ_FROM_REGISTER:
+ tr.ret = i2c.write(tr.adr,(const char*)&(tr.reg), 1, true);
+ if(tr.ret)break; // error => bail out
+ tr.ret = i2c.read(tr.adr, tr.dta, tr.len, tr.rep);
+ break;
+ case READ_BYTE:
+ tr.ret = i2c.read(tr.ack);
+ break;
+ case WRITE:
+ tr.ret = i2c.write(tr.adr, tr.wdta, tr.len, tr.rep);
+ break;
+ case WRITE_BYTE:
+ tr.ret = i2c.write(tr.ack);
+ break;
+ default:
+ error("call 911");
}
- s_threads[2]
+ // inform the caller
+ osSignalSet( channel.transfer.caller, DRV_USR_SIG);
}
}
-I2CDriver::I2CDriver(PinName sda, PinName scl)
+I2CDriver::I2CDriver(PinName sda, PinName scl):I2C(sda,scl)
{
// check pins and determine i2c channel
int channel=0;
- if(sda==sdas[0] && scl==scls[0]) channel=0; // I2C_1
- else if (sda==sdas[1] && scl==scls[1]) channel=1; //I2C_2
- else error("I2CDriver: Invalid I2C pinns selected");
-
+#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
+ if(sda==c_sdas[0] && scl==c_scls[0]) channel=0; // I2C_1
+ else
+#endif
+ if (sda==c_sdas[1] && scl==c_scls[1]) channel=1; //I2C_2 or I2C
+ else error("I2CDriver: Invalid I2C pinns selected");
if(s_channels[channel]==0)
new Thread(threadFun,(void *)channel,osPriorityRealtime);
-
- m_channel = *(s_channel[channel]);
+ m_channel = s_channels[channel];
}
-void I2CDriver::sendNwait(){
- osSignalSet( m_channel.driver, DRV_USR_SIG);
+
+void I2CDriver::sendNwait()
+{
+ m_channel->transfer.freq = _hz;
+ m_channel->transfer.caller = Thread::gettid();
+ osSignalSet( m_channel->driver, DRV_USR_SIG);
osSignalWait(DRV_USR_SIG,osWaitForever);
}
-void I2CDriver::frequency(int hz);
-
-int I2CDriver::read(int address, char *data, int length, bool repeated = false);
-
-
-int I2CDriver::read(int ack);
-
-
-int I2CDriver::write(int address, const char *data, int length, bool repeated = false);
-
-
-int I2CDriver::write(int data);
-
-
-void I2CDriver::start(void){
+int I2CDriver::read(int address, char *data, int length, bool repeated)
+{
lock();
- m_channel.transfer.freq = _hz;
- m_channel.transfer.cmd = START;
+ m_channel->transfer.cmd = READ;
+ m_channel->transfer.adr = address;
+ m_channel->transfer.dta = data;
+ m_channel->transfer.len = length;
+ m_channel->transfer.rep = repeated;
sendNwait();
- unlock();
+ int ret = m_channel->transfer.ret;
+ unlock();
+ return ret;
}
-void I2CDriver::stop(void){
+int I2CDriver::read(int address, uint8_t regist, char *data, int length, bool repeated)
+{
+ lock();
+ m_channel->transfer.cmd = READ_FROM_REGISTER;
+ m_channel->transfer.adr = address;
+ m_channel->transfer.reg = regist;
+ m_channel->transfer.dta = data;
+ m_channel->transfer.len = length;
+ m_channel->transfer.rep = repeated;
+ sendNwait();
+ int ret = m_channel->transfer.ret;
+ unlock();
+ return ret;
+}
+
+int I2CDriver::read(int ack)
+{
+ lock();
+ m_channel->transfer.cmd = READ_BYTE;
+ m_channel->transfer.ack = ack;
+ sendNwait();
+ int ret = m_channel->transfer.ret;
+ unlock();
+ return ret;
+}
+
+int I2CDriver::write(int address, const char *data, int length, bool repeated)
+{
lock();
- m_channel.transfer.freq = _hz;
- m_channel.transfer.cmd = STOP;
+ m_channel->transfer.cmd = WRITE;
+ m_channel->transfer.adr = address;
+ m_channel->transfer.wdta = data;
+ m_channel->transfer.len = length;
+ m_channel->transfer.rep = repeated;
+ sendNwait();
+ int ret = m_channel->transfer.ret;
+ unlock();
+ return ret;
+}
+
+int I2CDriver::write(int data)
+{
+ lock();
+ m_channel->transfer.cmd = WRITE_BYTE;
+ m_channel->transfer.ack = data;
sendNwait();
- unlock();
+ int ret = m_channel->transfer.ret;
+ unlock();
+ return ret;
}
+
+void I2CDriver::start(void)
+{
+ lock();
+ m_channel->transfer.cmd = START;
+ sendNwait();
+ unlock();
+}
+
+
+void I2CDriver::stop(void)
+{
+ lock();
+ m_channel->transfer.cmd = STOP;
+ sendNwait();
+ unlock();
+}
--- a/I2CDriver.h Sat Apr 13 13:37:29 2013 +0000
+++ b/I2CDriver.h Sun Apr 14 06:39:04 2013 +0000
@@ -26,12 +26,6 @@
*/
I2CDriver(PinName sda, PinName scl);
- /** Set the frequency of the I2C interface
- *
- * @param hz The bus frequency in hertz
- */
- void frequency(int hz);
-
/** Read from an I2C slave
*
* Performs a complete read transaction. The bottom bit of
@@ -48,6 +42,8 @@
*/
int read(int address, char *data, int length, bool repeated = false);
+ int read(int address, uint8_t regist, char *data, int length, bool repeated = false);
+
/** Read a single byte from the I2C bus
*
* @param ack indicates if the byte is to be acknowledged (1 = acknowledge)
@@ -90,15 +86,15 @@
void stop(void);
/// Wait until the i2c driver becomes available.
- void lock() {
+ void lock() {
// if one and the same thread can lock twice, but then it needs also to unlock twice.
// exactly what we need here
- m_channel.mutex.lock(osWaitForever);
+ m_channel->mutex.lock(osWaitForever);
}
/// Unlock the driver that has previously been locked by the same thread
- void osStatus unlock() {
- m_channel.mutex.unlock(osWaitForever);
+ void unlock() {
+ m_channel->mutex.unlock();
}
@@ -112,41 +108,43 @@
READ_BYTE,
READ,
READ_FROM_REGISTER
- }
+ };
struct Transfer {
+ osThreadId caller;
Command cmd;
int freq;
int adr;
- int reg;
+ uint8_t reg;
char* dta;
+ const char* wdta;
int len;
+ int ack;
bool rep;
- int res;
- }
+ int ret;
+ };
struct Channel {
- osThreadId caller;
- osThreadId driver;
- Mutex mutex;
- Transfer transfer;
- int freq;
- }
+ volatile osThreadId driver;
+ rtos::Mutex mutex;
+ volatile Transfer transfer;
+ volatile int freq;
+ };
- static const PinName c_sda[]= {p9,p28};
- static const PinName c_scl[]= {p10,p27};
+ static const PinName c_sdas[2];
+ static const PinName c_scls[2];
- static Channel* s_channels[2];
+ static Channel* s_channels[2];
- Channel& m_channel;
+ Channel* m_channel;
static void channel_0_ISR();
static void channel_1_ISR();
- static void threadFun(void* const args);
+ static void threadFun(void const *args);
void sendNwait();
-}
+};
}
#endif
--- a/mbed-NXP.lib Sat Apr 13 13:37:29 2013 +0000 +++ b/mbed-NXP.lib Sun Apr 14 06:39:04 2013 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed-NXP/#c9f4bde8b624 +http://mbed.org/users/mbed_official/code/mbed-NXP/#102159096554