title: PIC 18F45K42: How to combine 4 bytes to Int?
body: <p>I am writing code for a PIC 18F45K42 to read .wav files from an HCSD card. I am using MPLAB X IDE v5.20 and XC v2.05. I am using FATFs library to read data off the card.</p>
  
  <p>I can read data off the card and get good results until it comes to combining the 4 bytes representing the .wav file size.</p>
  
  <pre><code>#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
  #define BYTE_TO_BINARY(byte)  \
  (byte &amp; 0x80 ? '1' : '0'), \
  (byte &amp; 0x40 ? '1' : '0'), \
  (byte &amp; 0x20 ? '1' : '0'), \
  (byte &amp; 0x10 ? '1' : '0'), \
  (byte &amp; 0x08 ? '1' : '0'), \
  (byte &amp; 0x04 ? '1' : '0'), \
  (byte &amp; 0x02 ? '1' : '0'), \
  (byte &amp; 0x01 ? '1' : '0') 
  
  UINT actualLength;
  UINT br;
  char contents[44]; // Buffer
  uint32_t file_size;
  char result;
  
  printf("Checking media\n\r");
  if( SD_SPI_IsMediaPresent() == false)
  {
      printf("No media\n\r");
      return;
  }
  
   if (f_mount(&amp;drive,"0:",1) == FR_OK)
      {
      if (f_open(&amp;file, "P.WAV", FA_READ) == FR_OK){
  
          result = f_read(&amp;file, contents, 44, &amp;br);
          if ( result == FR_OK){
              printf("%c%c%c%c", contents[0],contents[1],contents[2],contents[3]);
              printf("\n\r");
              printf("contents 4-7: %u %u %u %u", contents[4],contents[5],contents[6],contents[7]);
              printf("\n\r");
              printf(""BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(contents[7]));
              printf(""BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(contents[6]));
              printf(""BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(contents[5]));
              printf(""BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(contents[4]));
              file_size = (contents[7] &lt;&lt; 24) | (contents[6] &lt;&lt; 16) | (contents[5] &lt;&lt; 8) | contents[4];
              int kb = file_size/1024;
              printf("\n\r");
              printf("Size: %u kB: %u", file_size, kb);
              printf("\n\r");
  // . . . OMITTED . . .
  </code></pre>
  
  <p>I am am printing the binary to reassure myself that the data written from the card is correct. The output I get is</p>
  
  <pre><code>Checking media
  RIFF
  contents 4-7: 4 122 18 0
  00000000000100100111101000000100
  Size: 31254 kB: 0
  </code></pre>
  
  <p>That binary gives me the correct number for the file size, 1210884, so the size I am getting by trying to get by combining the bytes is wrong. I presume this is is because I get the following complier warnings:</p>
  
  <pre><code>main.c:108:42: warning: shift count &gt;= width of type [-Wshift-count-overflow]
              file_size = (contents[7] &lt;&lt; 24) | (contents[6] &lt;&lt; 16) | (contents[5] &lt;&lt; 8) | contents[4];
                                       ^  ~~
  main.c:108:64: warning: shift count &gt;= width of type [-Wshift-count-overflow]
              file_size = (contents[7] &lt;&lt; 24) | (contents[6] &lt;&lt; 16) | (contents[5] &lt;&lt; 8) | contents[4];
  </code></pre>
  
  <p>I have searched on these warnings and tried a number of recommended fixes, but so far I haven't found anything that works for this situation. I hasten to add that my C knowledge is limited, and I am not 100% sure what that bit shift expression is doing. My naive understanding is that the rightmost bit of <code>contents[7]</code> should be shifted to bit 24 of the 32bit integer, <code>contents[6]</code> rightmost bit to bit 16 etc. and somehow, probably because of some kind of data type issue, this is not happening properly. But of course I don't know, and I'm not sure what limitations there are in the Microchip XC compilier.</p>
  
  <p>Short of recommending that I finally take a good course in C, can someone suggest what's going wrong and how to get the right value by assembling the 4 file size bytes properly.</p>
  
  <p>Many thanks for looking.</p>