Author Topic: 40-bit values on a 32-bit microcontroller  (Read 6142 times)

0 Members and 1 Guest are viewing this topic.

Offline rill17Topic starter

  • Contributor
  • Posts: 15
  • Country: mt
40-bit values on a 32-bit microcontroller
« on: April 21, 2017, 06:17:23 pm »
Hi there, I am using a 32-bit microcontroller (PIC32MZ) and a device i am interfacing with will send me a 40-bit value over spi in a series of 5 bytes. How can i use this 40 bit value to, for instance, perform arithmetic operations with it such as multiply or divide it with another 40-bit value? thanks in advance
 

Offline mariush

  • Super Contributor
  • ***
  • Posts: 5018
  • Country: ro
  • .
Re: 40-bit values on a 32-bit microcontroller
« Reply #1 on: April 21, 2017, 06:32:37 pm »
Use 64 bit variables? Shift the bits into 64bit variables and then do the math with them.

See xc32 documentation, Chapter 8. Supported Data Types and Variables (page 145)

Use unsigned long long  ... make an alias for it, name it uint64 or something like that.
« Last Edit: April 21, 2017, 06:37:47 pm by mariush »
 
The following users thanked this post: rill17

Offline Bruce Abbott

  • Frequent Contributor
  • **
  • Posts: 627
  • Country: nz
    • Bruce Abbott's R/C Models and Electronics
Re: 40-bit values on a 32-bit microcontroller
« Reply #2 on: April 22, 2017, 12:44:25 am »
What type of 40 bit value is it (integer, fixed point, floating point?) and how is it stored in the 5 bytes?
 

Offline rill17Topic starter

  • Contributor
  • Posts: 15
  • Country: mt
Re: 40-bit values on a 32-bit microcontroller
« Reply #3 on: April 25, 2017, 12:34:13 am »
basically what is happening is im interfacing with an ic which is transmitting 40-bit and 32-bit values via spi. i managed the 40-bit data but have run into another issue if you guys can help. the 32 bit data is being received 1 byte at a time and i am storing the data into 32-bit integers on the microcontroller by shifting the data using the following bit of code:
for(i=0; i<64; i++)
{
      received = (uint32_t)(((myReadBuffer_SPI[j])<<24) | ((myReadBuffer_SPI[j+1])<<16) | ((myReadBuffer_SPI[j+2])<<8) |
      (myReadBuffer_SPI[j+3]));
      j += 4;
}
i need to transmit this 32 bit number using uart to a pc, i am using a uart to usb device and basically need to end up with a text file containing the integers in decimal format so i could copy in excel and graph the data. the conversion can be done on the pc and not necessarily on the microcontroller. any ideas??
 

Offline TNorthover

  • Contributor
  • Posts: 42
  • Country: us
Re: 40-bit values on a 32-bit microcontroller
« Reply #4 on: April 25, 2017, 01:46:40 am »
i need to transmit this 32 bit number using uart to a pc, i am using a uart to usb device and basically need to end up with a text file containing the integers in decimal format so i could copy in excel and graph the data. the conversion can be done on the pc and not necessarily on the microcontroller. any ideas??

I assume you can write bytes through the UART already, so you just reverse the unpacking shifts in your post and write those 4 bytes out sequentially. Then the PC end reassembles them exactly as you did with the SPI. Or is there something else we're missing?
 

Offline mariush

  • Super Contributor
  • ***
  • Posts: 5018
  • Country: ro
  • .
Re: 40-bit values on a 32-bit microcontroller
« Reply #5 on: April 25, 2017, 02:09:34 am »
To keep things simple you could use hexadecimal notation ( 0..9 A..F) to send the numbers over. Split the number in 4 bit chunks and convert each 0..15 value to the proper ascii character.

You could just shift take the last 4 bits and put the result in an 10 element array, shift 4 bits to the right, repeat n times, then do the 0..15 conversion to 0..f 10 times for your 40 bit value.

Have a look at  STRUCT and UNION .. you can make your own data types with them to make it easier to work with individual bytes if you don't want to use divisions and shifts a lot.

« Last Edit: April 25, 2017, 02:11:38 am by mariush »
 

Offline Bruce Abbott

  • Frequent Contributor
  • **
  • Posts: 627
  • Country: nz
    • Bruce Abbott's R/C Models and Electronics
Re: 40-bit values on a 32-bit microcontroller
« Reply #6 on: April 25, 2017, 02:19:53 am »
i need to transmit this 32 bit number using uart to a pc, i am using a uart to usb device and basically need to end up with a text file containing the integers in decimal format so i could copy in excel and graph the data. the conversion can be done on the pc and not necessarily on the microcontroller. any ideas??
It's often better to convert the numbers into text (in eg. comma delimited CSV format) before sending via UART, because binary values can be tricky to get through some serial protocols (NULLs get absorbed, control characters do weird stuff) and synchronization is harder (how do you tell when one number ends and another starts when any Byte can be 0-255?). Downsides are having to do more processing in the MCU (shouldn't be a problem for PIC32MZ), and having to transmit more Bytes per number.
 
Quote
im interfacing with an ic which is transmitting 40-bit and 32-bit values via spi
Can you tell us what the ic is, or is it a big secret?
 

Offline rill17Topic starter

  • Contributor
  • Posts: 15
  • Country: mt
Re: 40-bit values on a 32-bit microcontroller
« Reply #7 on: April 25, 2017, 12:21:43 pm »
No no secret, i just kept it vague on purpose as its not that relevant. The IC is the Xethru X2, i am actually transmitting through UART and receiving using Termite as seen in the screenshot (delimited by a carriage return). what i need to end up with is a list of decimal values in a text file as attached.
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4028
  • Country: nz
Re: 40-bit values on a 32-bit microcontroller
« Reply #8 on: April 25, 2017, 01:51:28 pm »
basically what is happening is im interfacing with an ic which is transmitting 40-bit and 32-bit values via spi. i managed the 40-bit data but have run into another issue if you guys can help. the 32 bit data is being received 1 byte at a time and i am storing the data into 32-bit integers on the microcontroller by shifting the data using the following bit of code:
for(i=0; i<64; i++)
{
      received = (uint32_t)(((myReadBuffer_SPI[j])<<24) | ((myReadBuffer_SPI[j+1])<<16) | ((myReadBuffer_SPI[j+2])<<8) |
      (myReadBuffer_SPI[j+3]));
      j += 4;
}
i need to transmit this 32 bit number using uart to a pc, i am using a uart to usb device and basically need to end up with a text file containing the integers in decimal format so i could copy in excel and graph the data. the conversion can be done on the pc and not necessarily on the microcontroller. any ideas??

Unless you absolutely need every bit of speed you can get (inconceivable if a UART is fast enough to absorb the data) it would be much easier to use an array of bytes to store the data!

Code: [Select]
unsigned char received[256];
for (i=0; i<256; i++)
{
    received[i] = myReadBuffer_SPI[i];
}

// ... time passes

char *hex = "0123456789ABCDEF";
for (i=0; i<256; i++)
{
    unsigned char ch = received[i];
    UART_out(hex[ch/16]);
    UART_out(hex[ch%16]);
}

Or maybe you can just do it from the SPI buffer in one hit, if you're not sorting out multiple interleaved message types or something.
« Last Edit: April 26, 2017, 01:23:34 pm by brucehoult »
 

Offline macboy

  • Super Contributor
  • ***
  • Posts: 2254
  • Country: ca
Re: 40-bit values on a 32-bit microcontroller
« Reply #9 on: April 25, 2017, 04:08:16 pm »
Why not pass along the 5 bytes directly, or even better IMHO, translate them into two-character ASCII encoded hex values (like "FF" for 0xFF). The benefit of the latter is that you only send printable ASCII characters, never control codes which might get eaten by the UART (like XON/XOFF chars) or by the receiving end software (like Null, EOF, CR/LF, Bell, etc.). It also allows you to insert end-of-line characters or spaces at will, to demarcate the 5-byte values. This also greatly simplifies the processing as plain text is scripting language friendly and human readable. Binary is neither.

The conversion on the PC side would be simple. I'm sure a perl guru could come up with a one-liner that would eat the hex-encoded ASCII text file and spit out another text file with decimal values. In fact, you could do it real time by using the serial port as the input file to such a script.

With that said, I have worked with data as large as 40 bits on a lowly 8-bit PIC (really lowly... a PIC16F55). Writing an efficient algorithm, in assembly, to convert a 40-bit integer into a 13-digit decimal on a chip without hardware multiply or divide, is interesting to say the least.
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4028
  • Country: nz
Re: 40-bit values on a 32-bit microcontroller
« Reply #10 on: April 26, 2017, 01:40:28 pm »
With that said, I have worked with data as large as 40 bits on a lowly 8-bit PIC (really lowly... a PIC16F55). Writing an efficient algorithm, in assembly, to convert a 40-bit integer into a 13-digit decimal on a chip without hardware multiply or divide, is interesting to say the least.

I'm not too familiar with PIC model numbers. I found that PIC16C55 has 24 *bytes* of RAM. Is that the same? Anyway, there's plenty of ROM.

Store a table of powers of 10 in ROM. 13 entries, 65 bytes. For each power of ten, count how many times you can subtract it from the number (can be zero). Output that digit. Maximum 13*9 = 117 loops. Should be plenty fast enough.

You could generate the powers of 10 at runtime (a loop with n = ((n<<2)+n)<<1), but it might use abuot as much code space as the table.

Storing [1..9] times each power of ten would be a waste as you'd still have to fetch and compare them. At most you could do a binary search, but that would gain very little.


 

Offline macboy

  • Super Contributor
  • ***
  • Posts: 2254
  • Country: ca
Re: 40-bit values on a 32-bit microcontroller
« Reply #11 on: April 26, 2017, 02:56:11 pm »
With that said, I have worked with data as large as 40 bits on a lowly 8-bit PIC (really lowly... a PIC16F55). Writing an efficient algorithm, in assembly, to convert a 40-bit integer into a 13-digit decimal on a chip without hardware multiply or divide, is interesting to say the least.

I'm not too familiar with PIC model numbers. I found that PIC16C55 has 24 *bytes* of RAM. Is that the same? Anyway, there's plenty of ROM.
Sorry, it was the PIC16F57 (I was replacing a PIC16C55). The 'F57 has 72 bytes of RAM and 2 kword of ROM.

Quote
Store a table of powers of 10 in ROM. 13 entries, 65 bytes. For each power of ten, count how many times you can subtract it from the number (can be zero). Output that digit. Maximum 13*9 = 117 loops. Should be plenty fast enough.

You could generate the powers of 10 at runtime (a loop with n = ((n<<2)+n)<<1), but it might use abuot as much code space as the table.

Storing [1..9] times each power of ten would be a waste as you'd still have to fetch and compare them. At most you could do a binary search, but that would gain very little.
You might find each loop iteration to be at least few dozen cycles, so you are into the many thousands of cycles to do the conversion. It would be more efficient to have 12 separate subroutines, one for each power of ten (the highest counting up to 10 instead of 9) using immediate values, rather than gathering values from a table. When I have ROM to spare, I tend toward inline code with as few loops and branches as possible.

I implemented a version of the "double dabble" algorithm. If you are not familiar, look it up. It's fascinating. I got it down to a fixed 2570 cycles for any 40-bit input. I was trying to do this within a single 2 ms timeslice of a main loop running at 1 MIPS, but couldn't fit it so I modified the algorithm to pause itself partway through and resume later.
 

Offline Bruce Abbott

  • Frequent Contributor
  • **
  • Posts: 627
  • Country: nz
    • Bruce Abbott's R/C Models and Electronics
Re: 40-bit values on a 32-bit microcontroller
« Reply #12 on: April 26, 2017, 08:42:50 pm »
No no secret, i just kept it vague on purpose as its not that relevant. The IC is the Xethru X2, i am actually transmitting through UART and receiving using Termite as seen in the screenshot (delimited by a carriage return). what i need to end up with is a list of decimal values in a text file as attached.
If I understand the X2 datasheet correctly,  it stores 32 bit ADC samples in a frame buffer. When reading the buffer you choose  MSB and LSB between 0 and 31. Presumably the values are unsigned, so depending on what bit range you choose the SPI output could be equivalent to 8, 16, 24 or 32 bit unsigned integers. Some control registers store 40 bit integers.

Your data appears to be 32 bit integers, which you want to convert to the equivalent ASCII decimal number (character string). This can be done using printf(). 

   
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4028
  • Country: nz
Re: 40-bit values on a 32-bit microcontroller
« Reply #13 on: April 26, 2017, 08:49:20 pm »
No no secret, i just kept it vague on purpose as its not that relevant. The IC is the Xethru X2, i am actually transmitting through UART and receiving using Termite as seen in the screenshot (delimited by a carriage return). what i need to end up with is a list of decimal values in a text file as attached.
If I understand the X2 datasheet correctly,  it stores 32 bit ADC samples in a frame buffer. When reading the buffer you choose  MSB and LSB between 0 and 31. Presumably the values are unsigned, so depending on what bit range you choose the SPI output could be equivalent to 8, 16, 24 or 32 bit unsigned integers. Some control registers store 40 bit integers.

Your data appears to be 32 bit integers, which you want to convert to the equivalent ASCII decimal number (character string). This can be done using printf(). 

Shirley you joke, sir?

printf() can drag in tens of KB of code. You want to print a simple integer, why drag in tons of code you don't need to to justify, pad, print in different bases, not to mention format floating point numbers in a all manner of ways?
 

Offline Bruce Abbott

  • Frequent Contributor
  • **
  • Posts: 627
  • Country: nz
    • Bruce Abbott's R/C Models and Electronics
Re: 40-bit values on a 32-bit microcontroller
« Reply #14 on: April 27, 2017, 05:22:31 pm »
Shirley you joke, sir?

printf() can drag in tens of KB of code. You want to print a simple integer, why drag in tons of code you don't need to to justify, pad, print in different bases, not to mention format floating point numbers in a all manner of ways?
The smallest PICMZ has 512k of Flash. XC32's printf uses less than 7k. If program memory is so tight that you can't afford another 1.4% to get nicely formatted printing then you are probably already in trouble.
 

Offline senso

  • Frequent Contributor
  • **
  • Posts: 951
  • Country: pt
    • My AVR tutorials
Re: 40-bit values on a 32-bit microcontroller
« Reply #15 on: April 27, 2017, 06:53:48 pm »
Printf with floats in an atmega are around 3-4k of flash, its so handy to be able to print nicelly formated strings, yes I could make it with a ton of buffers, xtoa's and gluing that all together, or just sprintf and be done with it.
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4028
  • Country: nz
Re: 40-bit values on a 32-bit microcontroller
« Reply #16 on: April 27, 2017, 08:22:27 pm »
Shirley you joke, sir?

printf() can drag in tens of KB of code. You want to print a simple integer, why drag in tons of code you don't need to to justify, pad, print in different bases, not to mention format floating point numbers in a all manner of ways?
The smallest PICMZ has 512k of Flash. XC32's printf uses less than 7k. If program memory is so tight that you can't afford another 1.4% to get nicely formatted printing then you are probably already in trouble.

We were just talking about, for example, PIC16F57 with 2 K words of ROM, and printing 40 bit integers on that. printf() ain't gunna fit.
 

Offline VEGETA

  • Super Contributor
  • ***
  • Posts: 1946
  • Country: jo
  • I am the cult of personality
    • Thundertronics
Re: 40-bit values on a 32-bit microcontroller
« Reply #17 on: May 01, 2017, 05:39:27 am »
I guess you can use 2 of 32 variables for storing data then use shifting bits technique to store them in one 64 variable. I guess the tool here is >> and <<.


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf