analogdevicesinc / TMC-API

TRINAMIC's IC API
MIT License
200 stars 88 forks source link

Assumed datatype in CAST_Sn_TO_S32 in Macros.h #3

Closed PMTaylor closed 4 years ago

PMTaylor commented 4 years ago

Hi there, using Arduino, and the datatype the compiler assumes is too short (int?) for the operation if the shift is bigger than 16.

Seems to work as intended as "#define CAST_Sn_TO_S32(value, n) ((value) | (((value) & (1L<<((n)-1)))? ~((0x1L<<(n))-1) : 0 ))" but i'm far from a good C programmer.

trinamic-LH commented 4 years ago

Hello,

yes, the Arduino's int datatype has only 16 bits.

Am i understanding you correctly, that the CAST_Sn_TO_S32 macro is showing the bigger-than-16 shift warning?

PMTaylor commented 4 years ago

Yes a warning is show. More importantly, the shifts fail to produce the correct result with the macro as written. Explicitly defining the type of the "1" and "0x1" constants as "uint32", or "unsigned long" here seems appropriate.

trinamic-LH commented 4 years ago

So something like this should work then: #define CAST_Sn_TO_S32(value, n) ((value) | (((value) & ((uint32_t)1<<((n)-1)))? ~(((uint32_t)1<<(n))-1) : 0 ))

Once we've tested everything on our end we will integrate that fix. Thanks for the report πŸ‘

PMTaylor commented 4 years ago

Yep, that works for me, hopefully it doesn't break anyone else's use cases. I think we know the shift will never be more than 32 bits, so uint32 is the right choice.

On Tue, Feb 18, 2020 at 12:59 AM Lenard Heß notifications@github.com wrote:

So something like this should work then:

define CAST_Sn_TO_S32(value, n) ((value) | (((value) &

((uint32_t)1<<((n)-1)))? ~(((uint32_t)1<<(n))-1) : 0 ))

Once we've tested everything on our end we will integrate that fix. Thanks for the report πŸ‘

β€” You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/trinamic/TMC-API/issues/3?email_source=notifications&email_token=AD5XQTPWTMBINVSMYXM5BY3RDOPQXA5CNFSM4KV6UFGKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEMBEEQA#issuecomment-587350592, or unsubscribe https://github.com/notifications/unsubscribe-auth/AD5XQTL5HBFT6LAPB6FNXMDRDOPQXANCNFSM4KV6UFGA .

greyltc commented 4 years ago

This issue looks like its similar to the compiler warning I'm getting today:

Compiling src/TMC5130/TMC5130.c.o
src/TMC5130/TMC5130.c: In function 'tmc5130_writeDatagram':
src/TMC5130/TMC5130.c:22:22: warning: left shift count >= width of type [-Wshift-count-overflow]
  int32_t value = (x1 << 24) | (x2 << 16) | (x3 << 8) | x4;
                      ^
src/TMC5130/TMC5130.c:22:35: warning: left shift count >= width of type [-Wshift-count-overflow]
  int32_t value = (x1 << 24) | (x2 << 16) | (x3 << 8) | x4;

Would you agree?

I've done this to fix it:

// Writes (x1 << 24) | (x2 << 16) | (x3 << 8) | x4 to the given address
void tmc5130_writeDatagram(TMC5130TypeDef *tmc5130, uint8_t address, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4)
{
    uint8_t data[5] = { address | TMC5130_WRITE_BIT, x1, x2, x3, x4 };
    tmc5130_readWriteArray(tmc5130->config->channel, &data[0], 5);

    int32_t value = ((uint32_t)x1 << 24) | ((uint32_t)x2 << 16) | (x3 << 8) | x4;

    // Write to the shadow register and mark the register dirty
    address = TMC_ADDRESS(address);
    tmc5130->config->shadowRegister[address] = value;
    tmc5130->registerAccess[address] |= TMC_ACCESS_DIRTY;
}

and this:

int32_t tmc5130_readInt(TMC5130TypeDef *tmc5130, uint8_t address)
{
    address = TMC_ADDRESS(address);

    // register not readable -> shadow register copy
    if(!TMC_IS_READABLE(tmc5130->registerAccess[address]))
        return tmc5130->config->shadowRegister[address];

    uint8_t data[5] = { 0, 0, 0, 0, 0 };

    data[0] = address;
    tmc5130_readWriteArray(tmc5130->config->channel, &data[0], 5);

    data[0] = address;
    tmc5130_readWriteArray(tmc5130->config->channel, &data[0], 5);

    return ((uint32_t)data[1] << 24) | ((uint32_t)data[2] << 16) | (data[3] << 8) | data[4];
}
trinamic-LH commented 4 years ago

Fixed in commit b17de70de73c691f3cf71c5ff52a85527f5e3a7c