Skip to content
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

cpu/cc2538: add periph/i2c driver #3765

Merged
merged 1 commit into from
Mar 7, 2016
Merged

Conversation

hexluthor
Copy link
Contributor

Tested on cc2538dk.

@OlegHahm OlegHahm added Platform: ARM Platform: This PR/issue effects ARM-based platforms Type: new feature The issue requests / The PR implemements a new feature for RIOT labels Sep 2, 2015
@OlegHahm
Copy link
Member

OlegHahm commented Sep 2, 2015

@hexluthor, good to see that you're still interested in RIOT and keep contributing. As you may have seen on the mailing list we're currently in feature freeze, so we will probably not be able to merge this within the next two weeks, but getting all the cc2538 stuff you have proposed is definitely a top priority right after the release.

@hexluthor
Copy link
Contributor Author

Thanks @OlegHahm. No rush. I saw the periph/i2c API and wanted to get this out there.

@thomaseichinger
Copy link
Member

@hexluthor I am sorry I didn't respond to this PR recently. I currently can't flash the OpenMote, but I am in contact with the OpenMote people to fix this again. I will test this as soon as I can.

@thomaseichinger thomaseichinger added this to the Release 2015.12 milestone Nov 17, 2015
@A-Paul
Copy link
Member

A-Paul commented Nov 25, 2015

Hi @hexluthor, I got a CC2838DK here and going to perform HW tests on that platform. For now I'm trying to get used to the components.
I tried to flash a example, following your description in the wiki, but somehow this step:

Hold down the SELECT pushbutton while pressing RESET to activate the MCU's internal bootloader...
has not the desired effect. Invoking make flash gives me this error:

ERROR: Can't connect to target. Ensure boot loader is started. (no answer to synch sequence)

Both /dev/ttyUSB{0,1} are up. Do you have any hints?

@hexluthor
Copy link
Contributor Author

@A-Paul, you're using a SmartRF06 baseboard with CC2538EM daughter board attached, correct? Make sure these jumpers are populated:

  • VDD TO EM
  • Enable UART over XDS100v3
  • VDD -> EB power

Confirm that the power switch in the on position and the USB power source is selected. Try both UARTs:

make PORT=/dev/ttyUSB0 flash term
make PORT=/dev/ttyUSB1 flash term

If you send me a photo of your board, I may be able to identify an issue. Good luck!

@OlegHahm OlegHahm modified the milestones: Release 2015.12, Release 2016.03 Dec 8, 2015
@kYc0o
Copy link
Contributor

kYc0o commented Jan 25, 2016

hello! I was wondering if I can ACK this PR using a ReMote http://zolertia.io/product/hardware/re-mote ?

@PeterKietzmann
Copy link
Member

@kYc0o thanks for the offer! AFAIK @A-Paul already started to do hardware testing. But if you are faster ;-) ?! Generally it should be possible to test the diver on a re-mote but note that you need a logic analyser/scope and an i2c slave device to do so

@kYc0o
Copy link
Contributor

kYc0o commented Jan 26, 2016

@PeterKietzmann Yes I have the instruments, I'll try to test it in the following hours

@PeterKietzmann
Copy link
Member

Nice! While you're at it how about #3842 :-) ?

@kYc0o
Copy link
Contributor

kYc0o commented Jan 26, 2016

Yeah sure, I already asked the people on that PR :-)

@kYc0o
Copy link
Contributor

kYc0o commented Jan 26, 2016

I wrote a small example to test the functionality.

The configuration is:
A cc2538dk attached to the SmartRF06 board is configured as a master i2c device and an Arduino DUE as slave. The goal is to send the message "This is the i2c working" from the master to the slave.

The cc2538dk example :

#include <stdio.h>
#include <string.h>
#include "periph/i2c.h"

int main(void)
{
    char *i2c_message = "This is the i2c working";
    uint8_t charLength = strlen(i2c_message);

    puts("Hello World!");

    printf("You are running RIOT on a(n) %s board.\n", RIOT_BOARD);
    printf("This board features a(n) %s MCU.\n", RIOT_MCU);

    if (i2c_init_master(I2C_0, I2C_SPEED_NORMAL) == 0) {
        printf("Trying to send message \"%s\" with length %d\n", i2c_message, charLength);
        if (i2c_write_bytes(I2C_0, 8, i2c_message, charLength) == charLength) {
            printf("I2C message successfully sent!\n");
        } else {
            printf("I2C message not sent!\n");
        }
    } else {
        printf("Error while initializing I2C interface\n");
    }

    return 0;
}

The arduino sketch:

#include <Wire.h>

void setup() {
  Wire.begin(8);                // join i2c bus with address #8
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output
  Serial.println("Starting I2C tests sketch!");
}

void loop() {
  delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
  while (Wire.available()) { // loop through all available bytes
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
}

This is working if I plug the SmartRF06 board for the first time, then if I push the reset button to resend the message it is not sent showing the error I2C message not sent!. If I re-plug the board it works again. The Arduino DUE is never reset.

Any thoughts?

@PeterKietzmann
Copy link
Member

Could you put a logic analyser in parallel to the bus to see the check the signals? I don't know how the Arduino slave implementation behaves. Maybe something with the ACK/NACK synchronization goes wrong after resetting the cc2538 board? E.g. some default configurations of the hardware pins lead to signal toggles on the SCK or SDA pins which the slave device tries to interpret as I2C command?
I usually connect to "simple" I2C hardware when testing this kind of drivers.

@PeterKietzmann
Copy link
Member

One question: Is 8 the bus address on which the Arduino listens?

@hexluthor
Copy link
Contributor Author

Hi all. Here's a bunch of new commits that make the I2C driver more robust. I cherry-picked them so hopefully nothing got lost. It now depends on the xtimer module, but I don't know how to express this in the Makefile rules. For now, I just add USEMODULE += xtimer if needed.

@kYc0o
Copy link
Contributor

kYc0o commented Jan 26, 2016

Ok I'll try to analyze with the oscilloscope. As I receive the message correctly on the Arduino side, I think it should behave as expected.
The address 8 is on the line:

Wire.begin(8);                // join i2c bus with address #8

I'll try to get a simpler slave i2c device too.

@kYc0o
Copy link
Contributor

kYc0o commented Jan 26, 2016

hi @hexluthor thanks for your commits, I'll test with and give feedback.

@PeterKietzmann
Copy link
Member

@kYc0o any progress?

@kYc0o
Copy link
Contributor

kYc0o commented Jan 29, 2016

I'm waiting for an i2c hardware for more tests. I'll put the analyser output but everything seems to be ok...

@kYc0o
Copy link
Contributor

kYc0o commented Feb 1, 2016

@hexluthor have you tested this using tests/periph_i2c on some i2c device? I'm currently testing on cc2538dk but it freezes when I initialize the i2c

@kYc0o
Copy link
Contributor

kYc0o commented Feb 24, 2016

If necessary I can do a final check tomorrow, I can test at least in a cc2538dk, but possibly on the other two boards

@OlegHahm OlegHahm added the Community: Hack'n'ACK candidate This PR is a candidate for review and discussion during one of RIOT's monthly Hack'n'ACK parties label Feb 27, 2016
@kYc0o
Copy link
Contributor

kYc0o commented Mar 1, 2016

I just checked with a cc2538dk and an mpu9150 with a great success! we need to test it in another board?

edit: of course, it needs #4878 merged before

@kYc0o kYc0o added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Mar 1, 2016
@kYc0o
Copy link
Contributor

kYc0o commented Mar 1, 2016

can you change this commit name: Fix i2c_write_regs() ?

Just to make travis happy :)

@kYc0o
Copy link
Contributor

kYc0o commented Mar 3, 2016

As #4878 was merged, @hexluthor can you rebase and change the commit message so we can merge this asap? Thanks!

@hexluthor
Copy link
Contributor Author

Rebased and squashed. Thanks!


assert_scl();

#ifdef MODULE_XTIMER
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still necessary?

@hexluthor
Copy link
Contributor Author

@A-Paul, it depends if we want xtimer to be a hard dependency of cpu/cc2538/periph/i2c. How would this dependency be expressed within RIOT's make system?

With a perfect I2C bus xtimer probably isn't needed. On an ugly bus, it may be critical.

@A-Paul
Copy link
Member

A-Paul commented Mar 3, 2016

@hexluthor, at first, sorry for the "last minute" intervention.
I stumbled upon a -now squashed- previous commit with a topic like "avoid xtimer (for now)". So i thought that might be temporary changes as long as (x)timer is making problems. And that they can be reverted when timer is fixed.

@kYc0o
Copy link
Contributor

kYc0o commented Mar 5, 2016

AFAIK timer is working ok, I just merged xtimers several days ago, so we can say that xtimer is no more an obstacle. However, if @hexluthor wants a perfect bus, we should avoid it's use.

IMO this is a very good and useful implementation, but as @A-Paul said, the ifdef for xtimer it's not needed anymore. So, if you guys agree, we can try to merge this without those ifdefs and try to improve this in the future without any xtimers?

@A-Paul
Copy link
Member

A-Paul commented Mar 6, 2016

@kYc0o, @hexluthor I just wanted to prevent a temporary workaround being forgotten.
I understand that the ifdefs are sensible for now. I also prefer to not having hard dependencies.

From my side, ACK for this PR in the current state. @kYc0o, do you join?

@kYc0o
Copy link
Contributor

kYc0o commented Mar 6, 2016

I agree, although I'd prefer to remove the ifdefs I think this is mergeable as is. ACK from me too.

@OlegHahm OlegHahm removed the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Mar 6, 2016
@hexluthor
Copy link
Contributor Author

The I2C driver will work without the xtimer module. With the xtimer module, it becomes more robust and fault-tolerant. The ifdefs make both scenarios possible, and hence I vote to keep them.

@kYc0o
Copy link
Contributor

kYc0o commented Mar 7, 2016

OK great, then ACK and merge!

kYc0o added a commit that referenced this pull request Mar 7, 2016
cpu/cc2538: add periph/i2c driver
@kYc0o kYc0o merged commit 740635d into RIOT-OS:master Mar 7, 2016
@LudwigKnuepfer
Copy link
Member

Merged without CI?

@kYc0o
Copy link
Contributor

kYc0o commented Mar 7, 2016

CI was green when merged, since several days ago...

@kYc0o
Copy link
Contributor

kYc0o commented Mar 7, 2016

@LudwigKnuepfer
Copy link
Member

ah sorry

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Community: Hack'n'ACK candidate This PR is a candidate for review and discussion during one of RIOT's monthly Hack'n'ACK parties Platform: ARM Platform: This PR/issue effects ARM-based platforms Type: new feature The issue requests / The PR implemements a new feature for RIOT
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants