CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug Reports on this forum. Send them to support@ccsinfo.com

Can't read data with SPI using PIC16f18346
Goto page Previous  1, 2, 3, 4, 5, 6, 7  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
L.T.



Joined: 24 Jul 2020
Posts: 50

View user's profile Send private message

PostPosted: Thu Aug 13, 2020 3:04 am     Reply with quote

Thank for your time and sorry for my ignorance. I need your help. I tried everything but I failed. :(
Ttelmah



Joined: 11 Mar 2010
Posts: 16429

View user's profile Send private message

PostPosted: Thu Aug 13, 2020 3:04 am     Reply with quote

OK. No guarantees on this, but this covers most of the problems with
what has been posted:
Code:

#include <16F18346.h>
#device ADC=10
#use delay(internal=16000000)

//setup softwarew SPI so bit order can be reversed.
#use spi(DI=PIN_B4, DO=PIN_C7, CLK=PIN_B6, LSB_FIRST, baud=1000000, MODE=2, stream=PGA)
#PIN_SELECT U1TX=PIN_A1
#PIN_SELECT U1RX=PIN_A0 //basic UART setup for diagnostics
#use RS232(UART1, baud=9600, ERRORS)


// Define commands by name
#define P1BL  0x00
#define P2BL  0x01
#define P1LO  0x02
#define P2LO  0x03
#define TNLM  0x04
#define UMR  0x05
#define TNLR  0x06
#define TEDD  0x07
#define SD  0x08
#define SRR  0x09
#define SRW  0x0A
#define EEBR  0x0B
#define EEBW  0x0C
#define TVGBR  0x0D
#define TVGBW  0x0E
#define THRBR  0x0F
#define THRBW  0x10
#define syncByte 0x55
int numObj=1;
unsigned int objTime[8];
byte ultraMeasResult[36]; //buffer for results

/*------------------------------------------------- calcChecksum -----
| Function calcChecksum
|
| Purpose: Calculates the UART checksum value for n bytes in the buffer
|
| Parameters:
| Number of bytes
|
| Returns: byte representation of calculated checksum value
*-------------------------------------------------------------------*/
int checksum(char * buffer, int number)
{
   unsigned int16 sum=0;
   unsigned int8 ctr=1; //ignore 0x55
   do {
      sum+=buffer[ctr++];
   } while (ctr<number);
   sum &= 0xff; //low 8 bits only
   sum ^= 0xFF; //inverted
   return sum;
}
   
/*------------------------------------------------- ultrasonicCmd -----
| Function sendCommand
|
| Purpose: Issues a burst-and-listen or listenonly
command based on the number of objects to be detected.
|
| Parameters:
| cmd (IN) -- determines which preset command is run
| • 0 = Preset 1 Burst + Listen command
| • 1 = Preset 2 Burst + Listen command
| • 2 = Preset 1 Listen Only command
| • 3 = Preset 2 Listen Only command
| number (IN) -- PGA460 can capture time-offlight,
width, and amplitude for 1 to 8 objects.
| TCI is limited to time-of-flight measurement data only.
|
| Returns: none
*-------------------------------------------------------------------*/
void sendCommand(int cmd, int number)
{
   //send a command packet to the device
   int ctr;
   byte bufCmd[4]; // prepare bufCmd
   bufCmd[0]=syncByte;
   bufCmd[2]=number;
   numObj=number; //update number of objects to detect
   memset(objTime, 0xFF, 8); // reset buffer
   switch (cmd)
   {
   case 0: // Send Preset 1 Burst + Listen command
   {
   bufCmd[1] = P1BL;
   bufCmd[3] = Checksum(bufCmd,3);
   break;
   }
   case 1: // Send Preset 2 Burst + Listen command
   {
   bufCmd[1] = P2BL;
   bufCmd[3] = Checksum(bufCmd,3);
   break;
   }
   case 3: // Send Preset 1 Listen Only command
   {
   bufCmd[1] = P1LO;
   bufCmd[3] = Checksum(bufCmd,3);
   break;
   }
   case 4: // Send Preset 2 Listen Only command
   {
   bufCmd[1] = P2LO;
   bufCmd[3] = Checksum(bufCmd,3);
   break;
   }
   default: return;
   }
   //Now write buffer
   for (ctr=0;ctr<4;ctr++)
      spi_xfer(PGA,bufCmd[ctr],8);   
}

void pullResult(void)
{
   //Now data sheet disagrees with itself on whether a checksum is required for
   //the read command. Code shows it, but data sheet says it is not needed.
   //Including anyway....
   byte buf[3]; //temporary TX buffer
   int ctr;
   buf[0]=syncByte;
   buf[1]=UMR;
   buf[2]=checksum(buf,2);
   //Now write buffer
   for (ctr=0;ctr<3;ctr++)
      spi_xfer(PGA,buf[ctr],8);
   //clear incoming buffer
   memset(ultraMeasResult,0,sizeof(ultraMeasResult));
   
   //Now need to read reply
   delay_us(125); //worst case command processing dead time
   for(ctr=0; ctr<((2+(numObj*4))); ctr++)
   {
      //read max 'numObj replies
      ultraMeasResult[ctr]=spi_xfer(PGA,0xFF,8);
   }
}

float convertResult(byte source)
{
   int16 speedSound = 343;
   int index;
   int16 objDist;
   index=(source/3)*3;
   switch(source%3)
   {
      case 0: //Objn Distance (m)
         objDist = make16(ultraMeasResult[index+1],ultraMeasResult[index+2]);
         return (objDist/2*0.000001)*speedSound;
         break;
      case 1: //Objn Width (us)
         return (ultraMeasResult[index+3])*16.0;
         break;
      case 2: //Objn Peak Amplitude
         return ultraMeasResult[index+4];
         break;
   }
}

void main()
{
   //Now, comms requires 300uSec active data before starting
   //Clock out 0xFF's to generate this
   int ctr;
   float distance;
   for (ctr=0;ctr<8;ctr++)
      spi_xfer(PGA,0x55,8);
   //Now need to issue a preset 1 command, then pause for 100uSec
   //and read response
   while (TRUE)
   {
      sendCommand(P1BL, 1); //one channel only
      delay_ms(70); //worst case command delay is 65mSec
      pullResult();
      //Now need to convert these values
      for (ctr=0; ctr<numObj; ctr++)
      {
         distance=convertResult(0+(ctr*3));
         printf("Distance %f/n", distance);
      }
      delay_ms(500); //slow things down
   }   
}


Uses a com port for output (move this somewhere to suit your hardware.
L.T.



Joined: 24 Jul 2020
Posts: 50

View user's profile Send private message

PostPosted: Thu Aug 13, 2020 3:14 am     Reply with quote

Thanks, I'll try it now.


-------------------------------------------------------------------------
I tried but PGA didn't answer.
L.T.



Joined: 24 Jul 2020
Posts: 50

View user's profile Send private message

PostPosted: Fri Aug 14, 2020 12:45 am     Reply with quote

Hey there,

I found a problem in the code. memset function doesnt work perfectly. It isn't erasing all data in misoBuf array. misoBuf is the array of slave device's answers.
Code:
BYTE misoBuf[131];

memset's description in 16F18346.h file is:
Code:
_bif void memset(unsigned int8* destination, unsigned int8 value, unsigned int16 num);


And I used memset function in this part for clean the buffer:
Code:
void pga460_spiTransfer(BYTE* mosi, BYTE size )
{
   uint16 temp2;
   memset(misoBuf[0], 0x00, sizeof(misoBuf)); // idle-low receive buffer data
   
   for (int i = 0; i<size; i++)
   {
      //digitalWrite(SPI_CS, LOW);
      misoBuf[i] = usscSPI_transfer(mosi[i]);
      //digitalWrite(SPI_CS, HIGH);
   }
   return;
   
}


When I used memset as you can see in the code above, I get misoBuf array as follows:

misoBuf before memset:

Code:
"\x e9\x ea\x eb\x ec\x ed\x ee\x ef\x 0\x 88\x 88\x 88\x 88\x 88\x 88\x 0\x 20\x 21\x ff\x 84\x 21\x 8\x 42\x 0\x 0\x 0\x 75\x 1b\x 81\x 20\x 0\x 0\x 5\x e9\x 0\x 1\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 1\x 0\x 0\x 0\x a0\x 1\x 90\x a6\x 8\x f0\x f1\x f2\x f3\x f4\x f5\x f6\x f7\x f8\x f9\x fa\x fb\x fc\x fd\x fe\x ff\x 0\x 1\x 2\x 3\x 4\x 5\x 6\x 7\x 8\x 9\x a\x b\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0"


misoBuf after memset:
Code:
"\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 88\x 88\x 88\x 88\x 88\x 88\x 0\x e9\x 20\x ff\x 84\x 21\x 8\x 42\x 0\x 0\x 0\x 75\x 1b\x 6b\x 21\x 0\x 0\x 5\x 20\x 0\x 1\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 1\x 0\x 0\x 0\x a0\x 1\x 90\x a6\x 8\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0"


I tried a lot of version of using memset as below:
memset(misoBuf[0], 0x00, sizeof(misoBuf));
memset(&misoBuf[0], 0x00, sizeof(misoBuf));
memset(*misoBuf[0], 0x00, sizeof(misoBuf));
*memset(misoBuf[0], 0x00, sizeof(misoBuf));
*memset(&misoBuf[0], 0x00, sizeof(misoBuf));
*memset(&misoBuf[0], 0x00, sizeof(misoBuf));
.
.
.
.
etc.

Even, I wrote memset function myself. You can see below.
Code:
void *tmemset8( uint8 * adrest, uint8 datat, uint8 sizet){
   while(sizet-->0){
      *adrest=data;
      adrest++;}
void pga460_spiTransfer(BYTE* mosi, BYTE size )
{

    tmemset8(misoBuf, 0x00, sizeof(misoBuf)); // idle-low receive buffer data

   for (int i = 0; i<size; i++)
   {
      //digitalWrite(SPI_CS, LOW);
      misoBuf[i] = usscSPI_transfer(mosi[i]);
      //digitalWrite(SPI_CS, HIGH);
   }
   return;
   
}
}



And I get same result. It never erase all data. I tried a lot of version of writing new memset function as below:
Code:
void *tmemset8( uint8 * adrest, uint8 datat, uint8 sizet){
   for(int index=0;index<sizet;index++)
   {
      adrest[index] = datat;
   }
   return(adrest);
   
}


Code:
void tmemset8( uint8 * adrest, uint8 datat, uint8 sizet){

   for(int index=0;index<sizet;index++)
   {
      adrest[index] = datat;
   }
   return(adrest);
   
}

.
.
.
.
etc.

What is the problem guys?
PCM programmer



Joined: 06 Sep 2003
Posts: 21232

View user's profile Send private message

PostPosted: Fri Aug 14, 2020 1:54 am     Reply with quote

This is not how you pass the address of an array in C.
You are giving memset the value of the 1st element in the array.
Quote:
void pga460_spiTransfer(BYTE* mosi, BYTE size )
{
uint16 temp2;
memset(misoBuf[0], 0x00, sizeof(misoBuf)); // idle-low receive buffer data

Ttelmah



Joined: 11 Mar 2010
Posts: 16429

View user's profile Send private message

PostPosted: Fri Aug 14, 2020 2:00 am     Reply with quote

So you are actually erasing loads of stuff in the wrong part of the
processor's memory. The code I posted use the correct syntax for memset.
L.T.



Joined: 24 Jul 2020
Posts: 50

View user's profile Send private message

PostPosted: Fri Aug 14, 2020 2:50 am     Reply with quote

PCM programmer wrote:
This is not how you pass the address of an array in C.
You are giving memset the value of the 1st element in the array.
Quote:
void pga460_spiTransfer(BYTE* mosi, BYTE size )
{
uint16 temp2;
memset(misoBuf[0], 0x00, sizeof(misoBuf)); // idle-low receive buffer data



When I did like you told, I get the result as follows:

Code:
"\x e9\x ea\x eb\x ec\x ed\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x f6\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 75\x 1f\x 3\x 1\x 0\x 0\x 0\x 0\x 0\x 1\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 1\x 0\x 0\x 0\x a0\x 1\x 90\x a6\x 8\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0"
L.T.



Joined: 24 Jul 2020
Posts: 50

View user's profile Send private message

PostPosted: Fri Aug 14, 2020 2:55 am     Reply with quote

Ttelmah wrote:
So you are actually erasing loads of stuff in the wrong part of the
processor's memory. The code I posted use the correct syntax for memset.


I can't see any difference between yours and mine. I used memset for objTime or ultraMeasResult. It does not work for them too, some of them are reset and some remain stable.
PCM programmer



Joined: 06 Sep 2003
Posts: 21232

View user's profile Send private message

PostPosted: Fri Aug 14, 2020 3:39 am     Reply with quote

Do you think I am telling you to do this ?
Quote:
memset(misoBuf[0], 0x00, sizeof(misoBuf)); // idle-low receive buffer data

I am not telling you to do that. I was quoting your code.


This is what you should do:
Code:
memset(misoBuf, 0x00, sizeof(misoBuf));


If it doesn't work, then post your compiler version.
L.T.



Joined: 24 Jul 2020
Posts: 50

View user's profile Send private message

PostPosted: Fri Aug 14, 2020 4:50 am     Reply with quote

PCM programmer wrote:
Do you think I am telling you to do this ?
Quote:
memset(misoBuf[0], 0x00, sizeof(misoBuf)); // idle-low receive buffer data

I am not telling you to do that. I was quoting your code.


This is what you should do:
Code:
memset(misoBuf, 0x00, sizeof(misoBuf));


If it doesn't work, then post your compiler version.


I tried it too.. Doesnt work. MPLABX IDE V5.05 and CCS C Compiler v5.076
PCM programmer



Joined: 06 Sep 2003
Posts: 21232

View user's profile Send private message

PostPosted: Fri Aug 14, 2020 5:06 am     Reply with quote

See the test program posted below.

Here are the results. First it prints the array contents to show that
it holds all these numbers.
Quote:

0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
128,129,130,

Then it prints the array again, after running memset on it. It works.
This was tested with vs. 5.094. If it doesn't work with your version,
then I'll install your version and test it.
Quote:

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,


Test program:
Code:
#include <18F46K22.h>
#fuses NOWDT
#use delay (internal=4M)
#use rs232(baud=9600, UART1, ERRORS)

BYTE misoBuf[131] = 
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
96,97,98,99,100,101,102,103,104,105,106,107,108,
109,110,111,112,113,114,115,116,117,118,119,120,
121,122,123,124,125,126,127,128,129,130
};

//======================================
void main()
{         
int8 i;

for(i=0; i<sizeof(misoBuf); i++)
   {
    if(i%16 == 0)
       putc('\r');

    printf("%u,", misoBuf[i]);
   }


memset(misoBuf, 0x00, sizeof(misoBuf)); 

putc('\r');
putc('\r');

for(i=0; i<sizeof(misoBuf); i++)
   {
    if(i%16 == 0)
       putc('\r');

    printf("%u,", misoBuf[i]);
   }



while(TRUE);
}
L.T.



Joined: 24 Jul 2020
Posts: 50

View user's profile Send private message

PostPosted: Fri Aug 14, 2020 6:08 am     Reply with quote

I cant run the program, it gave an error about RS232.Then I erased RS232 part, because it is not necessary. I did debug, but when it came memset line, program has closed.
temtronic



Joined: 01 Jul 2010
Posts: 7687
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Aug 14, 2020 6:24 am     Reply with quote

what was the RS232 error ??
L.T.



Joined: 24 Jul 2020
Posts: 50

View user's profile Send private message

PostPosted: Fri Aug 14, 2020 6:51 am     Reply with quote

temtronic wrote:
what was the RS232 error ??


I had to choose a pin (#select_pin), but I have no idea which pin is correct to read from the computer.
PCM programmer



Joined: 06 Sep 2003
Posts: 21232

View user's profile Send private message

PostPosted: Mon Aug 17, 2020 3:01 am     Reply with quote

Working with Ttelmah, I was able to get MPLAB X vs. 5.30 to display printf
statements in the UART1 tab of the MPLAB X Simulator.

I installed CCS vs. 5.076 (same as your version). I compiled the
test program shown below and it worked fine. It displayed this output.
This shows that memset() did zero the array correctly.
Code:
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
128,129,130,


0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,

Test program:
Code:

#include <16F18346.h>
#fuses NOWDT
#use delay (internal=4M)
#pin_select U1TX = PIN_C6
#pin_select U1RX = PIN_C7
#use rs232(baud=9600, UART1, ERRORS)


BYTE misoBuf[131] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
96,97,98,99,100,101,102,103,104,105,106,107,108,
109,110,111,112,113,114,115,116,117,118,119,120,
121,122,123,124,125,126,127,128,129,130
};

//======================================
void main()
{         
int8 i;

for(i=0; i<sizeof(misoBuf); i++)
   {
    if(i%16 == 0)
       printf("\r\n");

    printf("%u,", misoBuf[i]);
   }


memset(misoBuf, 0x00, sizeof(misoBuf));

printf("\r\n");
printf("\r\n");

for(i=0; i<sizeof(misoBuf); i++)
   {
    if(i%16 == 0)
       printf("\r\n");


    printf("%u,", misoBuf[i]);
   }

while(TRUE);
}


Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2, 3, 4, 5, 6, 7  Next
Page 3 of 7

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group