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.
Fork of mbed-RtosI2cDriver by
Revision 11:8c1d44595620, committed 2013-05-09
- Comitter:
- humlet
- Date:
- Thu May 09 20:52:07 2013 +0000
- Parent:
- 10:e3d6c92ff222
- Child:
- 12:6ddadcbbdca2
- Commit message:
- seem to work without tweaked mbed lib
Changed in this revision
--- a/I2CDriver.cpp Wed May 08 19:22:45 2013 +0000
+++ b/I2CDriver.cpp Thu May 09 20:52:07 2013 +0000
@@ -24,7 +24,7 @@
else error("I2CDriver: Invalid I2C pins selected\n");
if(s_channels[channel]==0) {
- new Thread(threadFun,(void *)channel,osPriorityRealtime,512); // evillive
+ new Thread(threadFun,(void *)channel,osPriorityRealtime,1024); // evillive
}
m_channel = s_channels[channel];
}
@@ -79,12 +79,9 @@
tr.ret = i2cRtos_read(&i2c, tr.adr, tr.dta, tr.len, (tr.rep?0:1));
break;
case READ_MST_REG:
- //printf("drv00\n");
tr.ret = i2cRtos_write(&i2c, tr.adr,(const char*)&(tr.reg), 1, 0);
- //printf("drv01\n");
if(tr.ret)break; // error => bail out
tr.ret = i2cRtos_read(&i2c, tr.adr, tr.dta, tr.len, (tr.rep?0:1));
- //printf("drv02\n");
break;
case READ_SLV:
tr.ret = i2cRtos_slave_read(&i2c, tr.dta, tr.len);
@@ -119,7 +116,7 @@
m_callerID = osThreadGetId();
m_callerPrio = osThreadGetPriority(m_callerID);
m_channel->mutex.lock(osWaitForever);
- osThreadSetPriority(m_callerID, c_drvPrio); // hopefully not interrupted since the lock
+ osThreadSetPriority(m_callerID, c_drvPrio); // evillive hopefully not interrupted since the lock
}
void I2CDriver::unlock()
--- a/I2CDriverTest02.h Wed May 08 19:22:45 2013 +0000
+++ b/I2CDriverTest02.h Thu May 09 20:52:07 2013 +0000
@@ -4,10 +4,10 @@
#include "I2CSlaveRtos.h"
const int freq = 400000;
-const int adr = 42;
-const int len=42;
-const char* mstMsg="We are mbed, resistance is futile";
-const char* slvMsg="Fine with me, let's get addicted";
+const int adr = 42<<1;
+const int len=34;
+const char mstMsg[len]="We are mbed, resistance is futile";
+const char slvMsg[len]="Fine with me, let's get addicted ";
static void slvRxMsg(I2CSlaveRtos& slv)
{
--- a/I2CDriverTest04.h Wed May 08 19:22:45 2013 +0000
+++ b/I2CDriverTest04.h Thu May 09 20:52:07 2013 +0000
@@ -3,7 +3,7 @@
#include "I2CMasterRtos.h"
#include "stdint.h"
-DigitalOut osci(p16);
+//DigitalOut osci(p16);
volatile int g_disco=0;
volatile int g_len=0;
@@ -27,7 +27,7 @@
config(i2c);
while(true) {
- osci.write(0);
+ //osci.write(0);
i2c.frequency(g_freq);
Thread::signal_wait(1<<5,osWaitForever);
// read back srf08 echo times (1+16 words)
@@ -38,7 +38,7 @@
uint32_t dt=us_ticker_read()-t1;
if(stat!=0) {
- osci.write(1);
+ //osci.write(1);
printf("\n%x %d %d %d\n",stat,g_freq,g_len,dt);
exit(0);
}
--- a/i2cRtos_api.c Wed May 08 19:22:45 2013 +0000
+++ b/i2cRtos_api.c Thu May 09 20:52:07 2013 +0000
@@ -11,7 +11,7 @@
#define I2C_DAT(x) (x->i2c->I2DAT)
#include "gpio_api.h"
-gpio_t gpio; // evillive
+static gpio_t gpio[2]; // evillive
enum I2cIsrCmd {
readMst,
@@ -23,7 +23,6 @@
struct I2cIsrTransfer {
i2c_t* obj;
enum I2cIsrCmd cmd;
- int adr;
int len;
int cnt;
int stat;
@@ -35,7 +34,6 @@
struct IsrIrqSem {
IRQn_Type irq;
- //uint32_t isr;
osSemaphoreId sem;
};
static struct IsrIrqSem isrIrqSem[2];
@@ -65,111 +63,85 @@
return I2C_STAT(obj);
}
-
// ISR stuff
static void i2cRtos_isr(uint32_t ch)
{
- //printf("isr01\n");
- volatile struct I2cIsrTransfer* tr=&(i2c_transfer[ch]);
-
- if(tr->cmd==waitSI) {
+ struct I2cIsrTransfer* tr=&(i2c_transfer[ch]);
+ if(tr->cmd==waitSI){
osSemaphoreRelease(isrIrqSem[ch].sem);
NVIC_DisableIRQ(isrIrqSem[ch].irq);
return;
}
-
int stat=i2c_status(tr->obj);
int stay = 0;
-
switch(tr->cmd) {
- case readMst: {
- int cnt = (tr->cnt)++;
- if(cnt==-1) {
- if(stat==0x40) {
- if(cnt != tr->len-2) {
+ case readMst:
+ switch(stat) {
+ case 0x50:
+ (tr->rData)[tr->cnt] = (char)(I2C_DAT(tr->obj) & 0xff);
+ case 0x40:
+ ++(tr->cnt);
+ if(tr->cnt != tr->len-1)
i2c_conset(tr->obj, 0, 0, 0, 1);
- } else {
+ else
i2c_conclr(tr->obj, 0, 0, 0, 1);
- }
stay = 1;
- }
- } else if(cnt < tr->len-1) {
- if(stat==0x50) {
- (tr->rData)[cnt] = (char)(I2C_DAT(tr->obj) & 0xff);
- if(cnt != tr->len-2) {
- i2c_conset(tr->obj, 0, 0, 0, 1);
- } else {
- i2c_conclr(tr->obj, 0, 0, 0, 1);
- }
- stay = 1;
- }
- } else {
- if(stat==0x58) {
- (tr->rData)[cnt] = (char)(I2C_DAT(tr->obj) & 0xff);
- stat = 0;
- }
+ break;
+ case 0x58:
+ (tr->rData)[tr->cnt] = (char)(I2C_DAT(tr->obj) & 0xff);
+ stat=0;
+ break;
}
break;
- }
- case writeMst: {
- int cnt = ++(tr->cnt);
- if(cnt==0) {
- if(stat==0x18) {
- I2C_DAT(tr->obj) = (tr->wData)[cnt];
- stay = 1;
- }
- } else if(cnt < tr->len) {
- if(stat==0x28) {
- I2C_DAT(tr->obj) = (tr->wData)[cnt];
- stay = 1;
- }
- } else {
- if(stat==0x28) {
- stat = 0;
- }
+ case writeMst:
+ switch(stat) {
+ case 0x18:
+ case 0x28:
+ if(++(tr->cnt)!=tr->len) { // evillive
+ I2C_DAT(tr->obj) = (tr->wData)[tr->cnt];
+ stay=1;
+ } else {
+ stat=0;
+ }
}
break;
- }
- case readSlv: {
- int cnt = ++(tr->cnt);
+ case readSlv:
+ ++(tr->cnt);
if(stat==0x80 || stat==0x90)
- (tr->rData)[cnt] = I2C_DAT(tr->obj) & 0xFF;
- stay = (stat==0x80 || stat==0x90 || stat==0x060 || stat==0x70) && (cnt < tr->len-1);
+ (tr->rData)[tr->cnt] = I2C_DAT(tr->obj) & 0xFF;
+ stay = (stat==0x80 || stat==0x90 || stat==0x060 || stat==0x70) && (tr->cnt < tr->len-1);
break;
- }
- case writeSlv: {
- int cnt = ++(tr->cnt);
- stay = cnt<tr->len && stat==0xb8;
+ case writeSlv:
+ ++(tr->cnt);
+ stay = tr->cnt<tr->len && stat==0xb8;
if(stay)
- I2C_DAT(tr->obj) = tr->wData[cnt];
+ I2C_DAT(tr->obj) = tr->wData[tr->cnt];
break;
- }
- default:
- error("Dial911 i2cRtos_isr\n");
}
if(stay) {
i2c_clear_SI(tr->obj);
} else {
- //i2c_clear_SI(tr->obj);
tr->stat = stat;
osSemaphoreRelease(isrIrqSem[ch].sem);
NVIC_DisableIRQ(isrIrqSem[ch].irq);
}
}
-void static i2cRtos_isr_ch0() // evillive
+static void i2cRtos_isr_ch0()
{
+ //gpio_write(&gpio[0], 1);
i2cRtos_isr(0);
+ //gpio_write(&gpio[0], 0);
}
-void static i2cRtos_isr_ch1()
+static void i2cRtos_isr_ch1()
{
- gpio_write(&gpio, 1);
+ //gpio_write(&gpio[1], 1);
i2cRtos_isr(1);
- gpio_write(&gpio, 0);
+ //gpio_write(&gpio[1], 0);
}
// determine channel
-static inline uint32_t i2c_get_channel(i2c_t *obj)
+static inline uint32_t i2c_get_channel(const i2c_t *obj)
{
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
switch((I2CName)(obj->i2c)) {
@@ -180,117 +152,72 @@
default:
error("Dial911 i2c_get_channel: Invaid I2CName \n");
}
-#elif defined(TARGET_LPC11U24)
- return 1;
-#else
-#error "Dial911 i2c_get_channel: Unsupported HW"
#endif
return 1;
}
// wait for ISR finished
-static inline void i2cRtos_wait_and_see(i2c_t *obj, int channel, uint32_t tmOut)
+static void i2cRtos_wait_and_see(i2c_t *obj, int ch, uint32_t tmOut) //evillive
{
- struct IsrIrqSem* iis = &(isrIrqSem[channel]);
- gpio_write(&gpio, 1);
+ struct IsrIrqSem* iis = &(isrIrqSem[ch]);
__disable_irq();
i2c_clear_SI(obj);
- NVIC_ClearPendingIRQ(iis->irq); // evillive
+ NVIC_ClearPendingIRQ(iis->irq);
NVIC_EnableIRQ(iis->irq);
__enable_irq();
- gpio_write(&gpio, 0);
- if(osSemaphoreWait(iis->sem, tmOut)!=1) {
- NVIC_DisableIRQ(iis->irq);
- printf("Ouch!\n");
- }
+ if(osSemaphoreWait(iis->sem, tmOut)!=1) NVIC_DisableIRQ(iis->irq);
+}
+
+static inline void i2cRtos_waitSI(i2c_t *obj, uint32_t tmOut){
+ int ch = i2c_get_channel(obj);
+ i2c_transfer[ch].cmd = waitSI;
+ i2cRtos_wait_and_see(obj, ch, tmOut);
}
-// setup semaphores and hook in ISRs
-void i2cRtos_init(i2c_t *obj, PinName sda, PinName scl)
-{
- gpio_init(&gpio, p15, PIN_OUTPUT);
-
- i2c_init(obj,sda,scl);
- uint32_t ch = i2c_get_channel(obj);
-#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
- static osSemaphoreDef(i2cIsrDrvSem_ch0);
- static osSemaphoreDef(i2cIsrDrvSem_ch1);
- switch(ch) {
- case 0:
- isrIrqSem[ch].irq = I2C1_IRQn;
- //isrIrqSem[ch].isr = (uint32_t)i2cRtos_isr_ch0;
- NVIC_SetVector(I2C1_IRQn, (uint32_t)i2cRtos_isr_ch0);
- isrIrqSem[ch].sem = osSemaphoreCreate(osSemaphore(i2cIsrDrvSem_ch0), 1);
- osSemaphoreWait(isrIrqSem[ch].sem, osWaitForever);
- break;
- case 1:
- //printf("apicfg\n");
- isrIrqSem[ch].irq = I2C2_IRQn;
- //isrIrqSem[ch].isr = (uint32_t)i2cRtos_isr_ch1;
- NVIC_SetVector(I2C2_IRQn, (uint32_t)i2cRtos_isr_ch1);
- //NVIC_DisableIRQ(I2C2_IRQn);
- isrIrqSem[ch].sem = osSemaphoreCreate(osSemaphore(i2cIsrDrvSem_ch1), 1);
- osSemaphoreWait(isrIrqSem[ch].sem, osWaitForever);
- break;
- }
-#elif defined(TARGET_LPC11U24)
- static osSemaphoreDef(i2cIsrDrvSem_ch1);
- isrIrqSem[ch].irq = I2C_IRQn;
- //isrIrqSem[ch].isr = (uint32_t)i2cRtos_isr_ch1;
- NVIC_SetVector(I2C_IRQn, (uint32_t)i2cRtos_isr_ch1);
- isrIrqSem[ch].sem = osSemaphoreCreate(osSemaphore(i2cIsrDrvSem_ch1), 1);
- osSemaphoreWait(isrIrqSem[ch].sem, osWaitForever);
-#else
-#error "Dial911 i2cRtos_init: Unsupported HW"
-#endif
-}
-
int i2cRtos_read(i2c_t *obj, int address, char *data, int length, int stop)
{
- gpio_write(&gpio, 1);
- int status = i2c_start(obj);
- if ((status != 0x10) && (status != 0x08)) {
+ gpio_write(&gpio[1], 1);
+ int stat = i2c_start(obj);
+ if ((stat != 0x10) && (stat != 0x08)) {
i2c_stop(obj);
- //printf("start Ouch read\n");
- return status;
+ return stat;
}
- gpio_write(&gpio, 0);
+ gpio_write(&gpio[1], 0);
int ch = i2c_get_channel(obj);
- volatile struct I2cIsrTransfer* tr = &(i2c_transfer[ch]); // evilive fill it locally and then copy it in one go to (volatile) mem?
+ struct I2cIsrTransfer* tr = &(i2c_transfer[ch]); // evilive fill it locally and then copy it in one go to (volatile) mem?
tr->obj=obj;
tr->cmd=readMst;
tr->len=length;
tr->cnt=-1;
tr->rData=data;
I2C_DAT(obj) = address | 0x01;
- i2cRtos_wait_and_see(obj, ch,2);// 1+(length>>2)); // timeout (1+len/4)ms
- status = tr->stat;
- if(status || stop) i2c_stop(obj);
- return status;
+ i2cRtos_wait_and_see(obj, ch,2+(length>>2)); // timeout (2+len/4)ms
+ stat = tr->stat;
+ if(stat || stop) i2c_stop(obj);
+ return stat;
}
int i2cRtos_write(i2c_t *obj, int address, const char *data, int length, int stop)
{
+ gpio_write(&gpio[1], 1);
int status = i2c_start(obj);
if ((status != 0x10) && (status != 0x08)) {
i2c_stop(obj);
- printf("start Ouch write\n");
return status;
}
+ gpio_write(&gpio[1], 0);
int ch = i2c_get_channel(obj);
- volatile struct I2cIsrTransfer* tr = &(i2c_transfer[ch]); // evilive fill it locally and then copy it in one go to (volatile) mem?
+ struct I2cIsrTransfer* tr = &(i2c_transfer[ch]); // evilive fill it locally and then copy it in one go to (volatile) mem?
tr->obj=obj;
tr->cmd=writeMst;
tr->len=length;
tr->cnt=-1;
tr->wData=data;
I2C_DAT(obj) = address & 0xfe;
- //printf("api01\n");
- i2cRtos_wait_and_see(obj, ch,2);// 2+(length>>2)); // timeout (1+len/4)ms
- //printf("api02\n");
- //i2c_clear_SI(obj); // ... why? Also in official lib
+ i2cRtos_wait_and_see(obj, ch, 2+(length>>2)); // timeout (2+len/4)ms
+ i2c_clear_SI(obj); // ... why? Also in official lib ... I guess this is the "write instead of start" bug
status = tr->stat;
if(status || stop) i2c_stop(obj);
return status;
@@ -303,19 +230,14 @@
} else {
i2c_conset(obj, 0, 0, 0, 1); // send a ACK
}
- int ch = i2c_get_channel(obj);
- i2c_transfer[ch].cmd = waitSI;
- i2cRtos_wait_and_see(obj, ch, 2);
+ i2cRtos_waitSI(obj, 2);
return (I2C_DAT(obj) & 0xff);
-
}
int i2cRtos_byte_write(i2c_t *obj, int data)
{
I2C_DAT(obj) = (data & 0xff);
- int ch = i2c_get_channel(obj);
- i2c_transfer[ch].cmd = waitSI;
- i2cRtos_wait_and_see(obj, ch, 2);
+ i2cRtos_waitSI(obj, 2);
int stat=i2c_status(obj);
return (stat==0x18 || stat==0x28 || stat==0x40 || stat==0xb8);
}
@@ -329,11 +251,8 @@
int retval = i2c_slave_receive(obj);
//check for pending requests
if(retval)return retval; // there is one => bail out
-
// No request? Wait for it!
- int ch = i2c_get_channel(obj);
- i2c_transfer[ch].cmd = waitSI;
- i2cRtos_wait_and_see(obj, ch, tmOut);
+ i2cRtos_waitSI(obj, tmOut);
// check again for pending requests
return i2c_slave_receive(obj);
}
@@ -341,7 +260,7 @@
int i2cRtos_slave_read(i2c_t *obj, char *data, int length)
{
int ch = i2c_get_channel(obj);
- volatile struct I2cIsrTransfer* tr = &(i2c_transfer[ch]); // evilive fill it locally and then copy it in one go to (volatile) mem?
+ struct I2cIsrTransfer* tr = &(i2c_transfer[ch]); // evilive fill it locally and then copy it in one go to (volatile) mem?
tr->obj=obj;
tr->cmd=readSlv;
tr->len=length;
@@ -351,7 +270,7 @@
if(tr->stat != 0xa0) {
i2c_stop(obj);
}
- i2c_clear_SI(obj); // ... why? Also in official lib
+ i2c_clear_SI(obj); // ... why? Also in official lib ... stops keeping scl low
return tr->cnt; // same weird return as in official lib
}
@@ -361,21 +280,62 @@
return(0);
}
int ch = i2c_get_channel(obj);
- volatile struct I2cIsrTransfer* tr = &(i2c_transfer[ch]); // evilive fill it locally and then copy it in one go to (volatile) mem?
+ struct I2cIsrTransfer* tr = &(i2c_transfer[ch]); // evilive fill it locally and then copy it in one go to (volatile) mem?
tr->obj=obj;
tr->cmd=writeSlv;
tr->len=length;
tr->cnt=0;
tr->wData=data;
I2C_DAT(obj) = data[0];
- i2cRtos_wait_and_see(obj, ch, 1+(length>>2)); // timeout (1+len/4)ms
+ i2cRtos_wait_and_see(obj, ch, 2+(length>>2)); // timeout (1+len/4)ms
int status = tr->stat;
if(status!=0xC0 && status!=0xC8) {
i2c_stop(obj);
}
- i2c_clear_SI(obj); // ... why? Also in official lib
+ i2c_clear_SI(obj); // ... why? Also in official lib ... stops keeping scl low
return tr->cnt;
}
+
+// setup semaphores and hook in ISRs
+void i2cRtos_init(i2c_t *obj, PinName sda, PinName scl)
+{
+ static int called=0;
+ if(!called) {
+ gpio_init(&gpio[0], p15, PIN_OUTPUT);
+ gpio_init(&gpio[1], p16, PIN_OUTPUT);
+ }
+ called = 1;
+ gpio_write(&gpio[0], 0);
+ gpio_write(&gpio[1], 0);
+
+ i2c_init(obj,sda,scl);
+ uint32_t ch = i2c_get_channel(obj);
+#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
+ static osSemaphoreDef(i2cIsrDrvSem_ch0);
+ static osSemaphoreDef(i2cIsrDrvSem_ch1);
+ switch(ch) {
+ case 0:
+ isrIrqSem[ch].irq = I2C1_IRQn;
+ NVIC_SetVector(I2C1_IRQn, (uint32_t)i2cRtos_isr_ch0);
+ isrIrqSem[ch].sem = osSemaphoreCreate(osSemaphore(i2cIsrDrvSem_ch0), 1);
+ break;
+ case 1:
+ isrIrqSem[ch].irq = I2C2_IRQn;
+ NVIC_SetVector(I2C2_IRQn, (uint32_t)i2cRtos_isr_ch1);
+ isrIrqSem[ch].sem = osSemaphoreCreate(osSemaphore(i2cIsrDrvSem_ch1), 1);
+ break;
+ }
+ osSemaphoreWait(isrIrqSem[ch].sem, osWaitForever);
+#elif defined(TARGET_LPC11U24)
+ static osSemaphoreDef(i2cIsrDrvSem_ch1);
+ isrIrqSem[ch].irq = I2C_IRQn;
+ NVIC_SetVector(I2C_IRQn, (uint32_t)i2cRtos_isr_ch1);
+ isrIrqSem[ch].sem = osSemaphoreCreate(osSemaphore(i2cIsrDrvSem_ch1), 1);
+ osSemaphoreWait(isrIrqSem[ch].sem, osWaitForever);
+#else
+#error "Dial911 i2cRtos_init: Unsupported HW"
+#endif
+}
#endif
#endif
--- a/mbed-NXP.lib Wed May 08 19:22:45 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/humlet/code/mbed-NXP/#692b566d83bf
--- a/mbed-src.lib Wed May 08 19:22:45 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/humlet/code/mbed-src/#49923059ddc8
