New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
I2C/SPI slave #565
Comments
@MaBecker: I2C Slave support has just been added to nRF52 builds with 77a60d9 Use as follows: Add this to the
Then on the device:
So there's a 64 byte Uint8Array called On the I2C master it's like every other I2C device:
|
Try now - the lack of response and and re-initialisation should be fixed |
Any idea how to nail this down?
|
Just digging into it with some jsiConsolePrintf() in work...... case TWIS_EVT_READ_REQ:
if (p_event->data.buf_req) {
JsVar *i2c = jsvObjectGetChild(execInfo.root,"I2C1",0);
if (i2c) {
JsVar *buf = jsvObjectGetChild(i2c,"buffer",0);
size_t bufLen;
char *bufPtr = jsvGetDataPointer(buf, &bufLen);
jsiConsolePrintf("Case TWIS_EVT_READ_REQ %d, %d\n",twisAddr, bufLen - twisAddr);
if (bufPtr && bufLen>twisAddr)
nrf_drv_twis_tx_prepare(&TWIS1, bufPtr + twisAddr, bufLen - twisAddr);
jsvUnLock2(i2c,buf);
}
}
break; >Case TWIS_EVT_READ_REQ 63, 1
read { "addr": 63, "length": 1 } 3f
>Case TWIS_EVT_READ_REQ 64, 0 |
Oh right - well there's only a 64 byte buffer, so that's all you get.
should fix it |
The larger buffer is not fixing it. adding case TWIS_EVT_READ_REQ:
if (p_event->data.buf_req) {
JsVar *i2c = jsvObjectGetChild(execInfo.root,"I2C1",0);
if (i2c) {
JsVar *buf = jsvObjectGetChild(i2c,"buffer",0);
size_t bufLen;
char *bufPtr = jsvGetDataPointer(buf, &bufLen);
twisAddr %= bufLen; // <--wrap around
if (bufPtr && bufLen>twisAddr)
nrf_drv_twis_tx_prepare(&TWIS1, bufPtr + twisAddr, bufLen - twisAddr);
jsvUnLock2(i2c,buf);
}
}
break; What do you think about this wrap around solution? |
Hmm, that's an odd one. It's hard to see why the larger buffer wouldn't fix it :( The problem with the wrap-around solution is... why? I mean, it's almost certainly not what you'd want. I find it very hard to think of a point where you'd want your read to wrap. It's probably better that it errors and then you figure out why your software is trying to read past the end of the buffer. Also, I'm not sure it will read - what if twisAddr is 60, bufLen is 64, but then you want to read 10? What does |
Even with a larger buffer like 256, nrf_drv_twis_tx_prepare() is not called because of the if condition and that is causing a i2c-bus-blocking situation. if (bufPtr && bufLen>twisAddr)
nrf_drv_twis_tx_prepare(&TWIS1, bufPtr + twisAddr, bufLen - twisAddr); Possible ways to fix this could be:
First of all: This case is buffer size independent. |
That's not the case though - the first byte you write sets the address. If you look at pretty much any I2C device it works the same way: http://www.espruino.com/modules/INA226.js
You write a one byte address, then read the data you want. You never issue a read on its own without writing first, so I'm not sure this is something we should really be trying to handle. I feel like a lot of other I2C devices would behave exactly the same way in this case. I don't think it's a bug. |
just updated the text - we came over cross .. |
I do not think it's a bug, it's just something that needs to be handled. |
Sorry - not my intention at all... Does it need to be handled though? I mean, if you're doing repeated reads with no write then it's probably a software bug. Espruino shouldn't really have to work in that case - in fact if it keeps working and is used like that it's probably going to lead to errors down the line. Or are you saying that in this case the nRF52 actually blocks the I2C bus and it can no longer be used for communicating with any other devices? |
Yes, this is exactly what happens |
Ok, lets fix this then... What happens if you do:
Failing that, we can do:
|
You mean using the first option? |
yes, this one if (bufPtr && bufLen>twisAddr)
nrf_drv_twis_tx_prepare(&TWIS1, bufPtr + twisAddr, bufLen - twisAddr);
else
nrf_drv_twis_tx_prepare(&TWIS1, twisRxBuf, 0); |
Great! Thanks for testing - just done! |
|
Great! we can close this then? |
Yes - what a great function - again many thanks! |
Hello! Just wanted to mention that since I was working on the hdc1080 sensor ( https://www.ti.com/lit/ds/symlink/hdc1080.pdf ) on page 14 section 8.6 Register map, it notes that the power on reset pointer is 0x00 Which means that although most sensors would do the "write to I2C address to set the pointer then read" protocol, TI also was expecting use cases where the sensor would have a "default" mode so it can be immediately read without setting the pointer. Thanks for this! :) |
Just working on a NRF52840 (SDK15) custom board with i2c slave targets/nrf5x/jshardware.c: In function 'jshKill':
targets/nrf5x/jshardware.c:861:7: error: implicit declaration of function 'nrf_drv_twis_is_enabled'; did you mean 'nrf_drv_usbd_is_enabled'? [-Werror=implicit-function-declaration]
if (nrf_drv_twis_is_enabled(TWIS1_INSTANCE_INDEX)) {
^~~~~~~~~~~~~~~~~~~~~~~
nrf_drv_usbd_is_enabled
CC src/jswrap_arraybuffer.o
targets/nrf5x/jshardware.c:861:31: error: 'TWIS1_INSTANCE_INDEX' undeclared (first use in this function); did you mean 'TWIS1_ENABLED'?
if (nrf_drv_twis_is_enabled(TWIS1_INSTANCE_INDEX)) {
^~~~~~~~~~~~~~~~~~~~
TWIS1_ENABLED
.....
targets/nrf5x/jshardware.c: In function 'jshI2CSetup':
targets/nrf5x/jshardware.c:1973:54: error: 'TWIS1_INSTANCE_INDEX' undeclared (first use in this function); did you mean 'TWIS1_ENABLED'?
if ((device == EV_I2C1) && nrf_drv_twis_is_enabled(TWIS1_INSTANCE_INDEX)) {
^~~~~~~~~~~~~~~~~~~~
TWIS1_ENABLED OK, twis_slave is missing for SKD15, for first tests took a copy of SDK12 and of cause now the linker is complaining because the missing libs. uino/targets/nrf5x/jshardware.c:1930: undefined reference to `nrf_drv_twis_rx_prepare'
collect2: error: ld returned 1 exit status
make: *** [espruino_2v08.82_nrf52840_custom.elf] Error 1 |
I think you just need to edit the Maybe check the twis file gets built: 77a60d9#diff-600fbc2b88437b719bd2062e306061338736300b6e7560a36e96fda185185436R168 As far as I can see though the TWIS stuff is designed for SDK15, so it should work fine. I guess the obvious question is: You had this working ok - so what changed? Can you still build it for the 52832 ok? |
Hmm, isn't that what those define do? # i2c slave
'DEFINES +=-DI2C_SLAVE -DTWIS_ENABLED=1 -DTWIS1_ENABLED=1', # enable I2C slave support
Yes 52832 still build without err eg for PUCKJS_CUTOM.py ( SKD12 ) # i2c slave
'DEFINES +=-DI2C_SLAVE -DTWIS_ENABLED=1 -DTWIS1_ENABLED=1', # enable I2C slave support |
Just remove nrf5x_15/componentes and other stuff and callled Same error, just check the zip file, it contains not twis_slave folder .... Note: nrf5x_15 is not part of the repository, but nrf5x_12, is that why twis_slave folder and libs are not missing? |
It's pretty standard for Nordic to randomly rename everything for no reason between literally every bloody SDK version. I'd be pretty sure this will still be fine when you figure out the correct files to add though. Usually I just see what the linker complains about not having, then grep through the SDK to find out where those functions are defined. |
JS execution speed is really too slow to properly do something via an IRQ, but there could be an array of data that can be read out...
http://forum.espruino.com/conversations/273112/
The text was updated successfully, but these errors were encountered: