Skip to content

drivers/adxl345: cleanup/enhancements#6799

Merged
aabadie merged 1 commit intoRIOT-OS:masterfrom
dylad:adxl345_cleanup
Apr 11, 2017
Merged

drivers/adxl345: cleanup/enhancements#6799
aabadie merged 1 commit intoRIOT-OS:masterfrom
dylad:adxl345_cleanup

Conversation

@dylad
Copy link
Copy Markdown
Member

@dylad dylad commented Mar 27, 2017

@haukepetersen If you have some time, could you take a look at it please ?
I need some advises about the set state functions. I have to add a clear_state function for each mode. But I don't know how could I put it into one clear and efficient function.


int adxl345_init(adxl345_t *dev, const adxl345_params_t* params)
int adxl345_init(adxl345_t *dev, const adxl345_params_t* params, uint8_t range,
uint8_t rate, uint8_t full_res, float scale_factor)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

As stated in https://github.com/RIOT-OS/RIOT/wiki/Guide:-Writing-a-device-driver-in-RIOT, the init function should have the dev and params struct as only parameters...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Sorry I didn't remember that part ... I'll change that but I saw others drivers with more than dev and params as arguments like drivers/isl29020

uint8_t range; /**< Sensitivity configuration */
uint8_t rate; /**< Configured sample rate for accel */
uint8_t full_res; /**< Resolution bit */
uint8_t scale_factor; /**< Scale factor for converting value to mg */
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't know the device in detail, but it seems to me, like some of these fields are static configuration values, while others can be deducted from them, right?
interrupt -> dynamic param set at runtime -> belongs into adx1345_t
offset -> static params, part of adx1345_params_t
range -> static param, part of adx1345_params_t
rate -> static param, part of adx1345_params_t
full_res -> deducted from range?! -> goes into device descriptor
scale_factor -> deducted from range -> goes into device descriptor

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

full_res is not deducted from range so it will belong to adxl345_params_t
I will move each part to right struct

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

perfect.

@@ -43,6 +44,12 @@ int adxl345_init(adxl345_t *dev, const adxl345_params_t* params)
/* get device descriptor */
dev->params= *params;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this seems wrong, assigment of adx1345_params_t ** to adx1345_params_t? If you do it like this, I think what you want to do is

memcpy(&dev->params, params, sizeof(adx1345_params_t));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

But under further consideration, think of only copying the 'often used' fields (e.g. i2c, addr) into RAM and leave the 'use once' fields (e.g. offset) in ROM...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

memcpy(&dev->params, params, sizeof(adx1345_params_t)); was the initial implementation in the previous PR but @aabadie made me change this line. I think copying all parameters with memcpy is more clear.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

actually using dev->params = *params also works and it's also used in other places.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ture, didn't notice the * instead of &, so never mind...

But still the second consideration holds: IMHO we don't need to copy all config params into RAM...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@haukepetersen How am I suppose to put some members in RAM and others in ROM ? Should I remove them from the struct and call the #define params in adxl345_init function ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

noo, actually what I meant is quite simple: instead of having the device descriptor look like

typedef struct {
    adx1345_params_t params;
    ...
} adx1345_t;

you could do something like

typedef struct {
    i2c_t bus,
    uint8_t addr,
    adx1345_params_t *p,
    ....
} adx1345_t;

In this case, you would only copy the 'often/periodically' used values into RAM for faster access, while you access the rest of the config params indirectly from ROM (we assume the configuration to be placed in ROM...).

.scale_factor = ADXL345_PARAM_SCALE_FACTOR}
#define ADXL345_PARAMS { .i2c = ADXL345_PARAM_I2C, \
.addr = ADXL345_PARAM_ADDR, \
.offset = ADXL345_PARAM_OFFSET }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why don't you write the offset here inline as in .offset = { 0, 0, 0 } } here? Saves some of the verbose lines below...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Because I copy/paste this from another driver without even thinking ! I'll change it.

@dylad
Copy link
Copy Markdown
Member Author

dylad commented Mar 28, 2017

@haukepetersen I add some commits
I didn't change the line dev->params= *params; yet. Should I switch to memcpy or leave it 'as is' ?

I will squash when we're done.

@haukepetersen
Copy link
Copy Markdown
Contributor

I didn't change the line dev->params= *params; yet. Should I switch to memcpy or leave it 'as is' ?

nope, no need. But see my comment above about only copying some params into the dev descriptor, then you would have to change this line anyhow...

@dylad
Copy link
Copy Markdown
Member Author

dylad commented Mar 30, 2017

Thanks for your help @haukepetersen . I really tought you wanted something far more complicated...
I pushed lastest changes. I hope it is fine !

@dylad
Copy link
Copy Markdown
Member Author

dylad commented Mar 31, 2017

@haukepetersen
I'm facing a weird issue
I did some tests and notice some output data error when result is negative
I tested :

    data->x = (int16_t)(dev->scale_factor * ((float)((result[3] << 8)+result[2])));
    data->y = (int16_t)((float)((result[3] << 8)+result[2])* 3.9);
    data->z = (((result[3] << 8)+result[2]) );

data->x and data->y are supposed to be equals
and data->z * 3.9 should be equals to data->x in that case
The output result is :
X axis:-6558 Y axis:-6558 Z axis:-1

dev->scale_factor is a float equals to 3.9
data->x,y,z are all int16_t variables.
Why multiple -1 by 3.9 give me -6558 ?
I'm pretty sure the reason is obvious...

@dylad
Copy link
Copy Markdown
Member Author

dylad commented Apr 3, 2017

I fixed my problem. It works now.
What do you think ?

Copy link
Copy Markdown
Contributor

@aabadie aabadie left a comment

Choose a reason for hiding this comment

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

A few nitpicks. Otherwise looks good.

adxl345_params_t params; /**< Device configuration */
i2c_t i2c; /**< I2C device which is used */
uint8_t addr; /**< I2C address */
adxl345_params_t *params; /**< Device configuration */
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

please align

adxl345_read(&dev, &data);
printf("Acceleration [in mg]: X axis:%d Y axis:%d Z axis:%d\n",
data.x, data.y, data.z);
(int)data.x, (int)data.y, (int)data.z);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

align

#define ADXL345_PARAM_FULL_RES (1)
#endif
#ifndef ADXL345_PARAM_OFFSET
#define ADXL345_PARAM_OFFSET { 0, 0, 0 }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

please align defines in this file

#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

is this really needed ?

@dylad
Copy link
Copy Markdown
Member Author

dylad commented Apr 6, 2017

@aabadie thanks for your review, I'll fix it.
Regarding #include <math.h> I have a question :

data->x = (((result[1] << 8)+result[0]) * dev->scale_factor);
data->y = (((result[3] << 8)+result[2]) * dev->scale_factor);
data->z = (((result[5] << 8)+result[4]) * dev->scale_factor);

Here I multiply a integer by a real number so the result is a float and I store it into a int16_t
Is it better to use the floor function to retrieve the integer or should I leave as it ?
Any thought ?

@aabadie
Copy link
Copy Markdown
Contributor

aabadie commented Apr 6, 2017

Is it better to use the floor function to retrieve the integer or should I leave as it ?

I would say leave it as it is without the #include <math.h>.

Copy link
Copy Markdown
Contributor

@aabadie aabadie left a comment

Choose a reason for hiding this comment

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

ACK, please squash

@dylad dylad force-pushed the adxl345_cleanup branch from 1ed0eed to 530a2ef Compare April 10, 2017 18:17
@dylad
Copy link
Copy Markdown
Member Author

dylad commented Apr 10, 2017

Squashed.

Signed-off-by: dylad <dylan.laduranty@mesotic.com>
@aabadie aabadie added Type: cleanup The issue proposes a clean-up / The PR cleans-up parts of the codebase / documentation Area: drivers Area: Device drivers CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Apr 10, 2017
@aabadie aabadie added this to the Release 2017.04 milestone Apr 10, 2017
@aabadie aabadie changed the title drivers/adxl345: cleanup/enhancements [WIP] drivers/adxl345: cleanup/enhancements Apr 10, 2017
@aabadie
Copy link
Copy Markdown
Contributor

aabadie commented Apr 11, 2017

Murdock approves, go !

@aabadie aabadie merged commit dffbc70 into RIOT-OS:master Apr 11, 2017
@dylad
Copy link
Copy Markdown
Member Author

dylad commented Apr 11, 2017

many thanks to both of you @aabadie @haukepetersen !

@haukepetersen
Copy link
Copy Markdown
Contributor

@aabadie: there were still un-addressed comments (see my comments above...). The state you merged is broken by design: what if you want to configure two of these devices? Now it won't work... Please make sure you look for open comments before you merge things...

@aabadie
Copy link
Copy Markdown
Contributor

aabadie commented Apr 11, 2017

there were still un-addressed comments (see my comments above...)

I'm sorry, I don't which one you are talking about. But apologizes, I should have for your confirmation first.

The state you merged is broken by design: what if you want to configure two of these devices? Now it won't work

Can you be more explicit ?

@dylad
Copy link
Copy Markdown
Member Author

dylad commented Apr 11, 2017

@haukepetersen I really thought all your comments were addressed. Which one did I miss ?

dev.i2c);

if (adxl345_init(&dev, adxl345_params) == ADXL345_OK) {
if (adxl345_init(&dev, (adxl345_params_t*)adxl345_params) == ADXL345_OK) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@haukepetersen, were you mentioning this regarding the fact only one sensor can be initialized at a time ? Then yes, I admit the line should be:

adxl345_init(&dev, &adxl345_params[0]) == ADXL345_OK

Copy link
Copy Markdown
Contributor

@haukepetersen haukepetersen left a comment

Choose a reason for hiding this comment

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

my fault, seems like my browser did not complete the connection to github when i submitted this review...

#define ADDR (dev->addr)

int adxl345_init(adxl345_t *dev, const adxl345_params_t* params)
int adxl345_init(adxl345_t *dev, adxl345_params_t* params)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

the const should stay here...


/* get device descriptor */
dev->params= *params;
dev->params = (adxl345_params_t*)params;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

but what happened to the i2c bus and the addr?

ADXL345_STANDBY_MODE,
ADXL345_SLEEP_MODE,
ADXL345_AUTOSLEEP_MODE,
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

documentation missing

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

(even though obvious what the enum members mean, doxygen will certainly complain about it...)

adxl345_data_t data;

dev.i2c = ADXL345_PARAM_I2C;
dev.addr = ADXL345_PARAM_ADDR;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

remove these two...

uint8_t range; /**< Sensitivity configuration */
uint8_t rate; /**< Configured sample rate for accel */
uint8_t full_res; /**< Resolution bit */
} adxl345_params_t;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

i2c and addr must stay in the params struct...

@haukepetersen
Copy link
Copy Markdown
Contributor

@aabadie, @dylad: sorry for my comments about open review comments, something went wrong on my side when I tried to send my review comments... Hope they help to shed some light on the open points that I had in mind...

@dylad
Copy link
Copy Markdown
Member Author

dylad commented Apr 25, 2017

@haukepetersen
Thanks for your review. Since this one is merged, I'll submit another PR soon (in May).

@haukepetersen
Copy link
Copy Markdown
Contributor

perfect, thanks!

@dylad dylad deleted the adxl345_cleanup branch May 7, 2017 09:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: drivers Area: Device drivers CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Type: cleanup The issue proposes a clean-up / The PR cleans-up parts of the codebase / documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants