Author Topic: Dspic33ep16gs202  (Read 2452 times)

0 Members and 1 Guest are viewing this topic.

Offline blindelectronicsTopic starter

  • Newbie
  • Posts: 8
  • Country: it
Dspic33ep16gs202
« on: October 27, 2022, 08:19:02 am »
I'm having problems with SPI bus with CS pin. It does not work as it supposed to. Chip is Dspic33ep16gs202
Can you check my code? Green is CS, purple MOSI, blue SCK.
Is there anything incorrect?
I ll be very grateful for your views.
Thank you very much.

int main(void)
{
  HAL_SPI_Enable();
  //LATBbits.LATB=0;
  HAL_SPI_Write(0x44);       
  HAL_SPI_Write(0x00); // This second byte is set to 0 but if there is need for fancy, never used setups, then rewrite. 
  HAL_SPI_Write(0x00); 
  HAL_SPI_Disable();
  //LATBbits.LATB=1;

  return 0;
}

void HAL_SPI_Write(uint8_t data)
{
  spi1_writeByte(data);

  return 0; 
}

void SPI_INIT(void)
{
  // PRVNI SPI CONFIG
  IFS0bits.SPI1IF = 0; // Clear the Interrupt flag
  IEC0bits.SPI1IE = 0; // Disable the interrupt

  // SPI1CON1 Register Settings
  SPI1CON1bits.DISSCK = 0; // Internal serial clock is enabled
  SPI1CON1bits.DISSDO = 0; // SDOx pin is controlled by the module
  SPI1CON1bits.MODE16 = 0; // Communication is 0: byte-wide, 1: word-wide (16 bits)
  SPI1CON1bits.MSTEN = 1;  // Master mode enabled
   
  //SPI1CON1bits.SPRE = 0b000; // secondary Prescale
  //SPI1CON1bits.PPRE = 0b00;  // Primary Prescale
  SPI1CON1bits.SMP = 0; // Input data is sampled at the middle of data output time
   
  //  SPI1CON2bits.FRMEN=1;
   
  SPI1CON1bits.CKE = 0; // Serial output data changes on transition from Idle clock state to active clock state
  SPI1CON1bits.CKP = 0; // Idle state for clock is a low level;
   
  SPI1STATbits.SPIEN = 1; // Enable SPI module
  //SPI1BUF = 0x00; // Write data to be transmitted
  IFS0bits.SPI1IF = 0; // Clear the Interrupt flag
  IEC0bits.SPI1IE = 1; // Enable the interrupt
}
 

Offline blindelectronicsTopic starter

  • Newbie
  • Posts: 8
  • Country: it
Re: Dspic33ep16gs202
« Reply #1 on: October 27, 2022, 08:21:23 am »
scope screen
 

Offline Kean

  • Supporter
  • ****
  • Posts: 3545
  • Country: au
    • Kean Electronics
Re: Dspic33ep16gs202
« Reply #2 on: October 27, 2022, 08:32:59 am »
You don’t mention what HAL you are using. There is a good chance it expects you to control the CS pin in your code as it doesn’t know what bytes comprise a compete SPI transaction. You also don’t seem to call SPI_INIT() anywhere.
 

Offline blindelectronicsTopic starter

  • Newbie
  • Posts: 8
  • Country: it
Re: Dspic33ep16gs202
« Reply #3 on: October 27, 2022, 09:35:11 am »
It is just function like this.
SPI_INIT is called I just forgot to put it here  :(

void HAL_SPI_Enable(void)
{
   LATBbits.LATB11=0;                      //Set CS pin LOW
}


void HAL_SPI_Disable(void)
{ 
   LATBbits.LATB11=1;             //Set CS pin HIGH   
}
 

Offline Kean

  • Supporter
  • ****
  • Posts: 3545
  • Country: au
    • Kean Electronics
Re: Dspic33ep16gs202
« Reply #4 on: October 27, 2022, 10:14:45 am »
OK, that helps.  Always good to include all the code you can.

Are you setting TRISB bit 11 to 0 anywhere to enable the CS pin as an output?
 

Offline JPortici

  • Super Contributor
  • ***
  • Posts: 3914
  • Country: it
Re: Dspic33ep16gs202
« Reply #5 on: October 27, 2022, 01:53:52 pm »
I'm having problems with SPI bus with CS pin. It does not work as it supposed to. Chip is Dspic33ep16gs202
Can you check my code? Green is CS, purple MOSI, blue SCK.
Is there anything incorrect?
I ll be very grateful for your views.
Thank you very much.

Code: [Select]
int main(void)
{
  HAL_SPI_Enable();
  //LATBbits.LATB=0;
  HAL_SPI_Write(0x44);       
  HAL_SPI_Write(0x00); // This second byte is set to 0 but if there is need for fancy, never used setups, then rewrite. 
  HAL_SPI_Write(0x00); 
  HAL_SPI_Disable();
  //LATBbits.LATB=1;

  return 0;
}

void HAL_SPI_Write(uint8_t data)
{
  spi1_writeByte(data);

  return 0; 
}

void SPI_INIT(void)
{
  // PRVNI SPI CONFIG
  IFS0bits.SPI1IF = 0; // Clear the Interrupt flag
  IEC0bits.SPI1IE = 0; // Disable the interrupt

  // SPI1CON1 Register Settings
  SPI1CON1bits.DISSCK = 0; // Internal serial clock is enabled
  SPI1CON1bits.DISSDO = 0; // SDOx pin is controlled by the module
  SPI1CON1bits.MODE16 = 0; // Communication is 0: byte-wide, 1: word-wide (16 bits)
  SPI1CON1bits.MSTEN = 1;  // Master mode enabled
   
  //SPI1CON1bits.SPRE = 0b000; // secondary Prescale
  //SPI1CON1bits.PPRE = 0b00;  // Primary Prescale
  SPI1CON1bits.SMP = 0; // Input data is sampled at the middle of data output time
   
  //  SPI1CON2bits.FRMEN=1;
   
  SPI1CON1bits.CKE = 0; // Serial output data changes on transition from Idle clock state to active clock state
  SPI1CON1bits.CKP = 0; // Idle state for clock is a low level;
   
  SPI1STATbits.SPIEN = 1; // Enable SPI module
  //SPI1BUF = 0x00; // Write data to be transmitted
  IFS0bits.SPI1IF = 0; // Clear the Interrupt flag
  IEC0bits.SPI1IE = 1; // Enable the interrupt
}

use code tags please (see how i did it?)
Is that your real code? i don't think so. you don't call SPI_INIT for example.
Then you don't show how you set up the pins.
Try and make a small example that shows the problem and post it.
 
The following users thanked this post: Kean

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3566
  • Country: ca
Re: Dspic33ep16gs202
« Reply #6 on: October 27, 2022, 08:07:36 pm »
Also post the code of spi1_writeByte().
 

Offline blindelectronicsTopic starter

  • Newbie
  • Posts: 8
  • Country: it
Re: Dspic33ep16gs202
« Reply #7 on: October 27, 2022, 08:15:16 pm »
Hi, I tried code, which works for stm32.
 Problem has to be somewhere in SPI_INIT or SPI functions.
I need to write code for spi for dspic, which would behave same as the one from STM32.

I do not know how to make those functions work for dspic

void HAL_SPI_WriteBuffer(uint8_t *Buffer, uint32_t Length)
void HAL_SPI_ReadBuffer(uint8_t *Buffer, uint32_t Length)
uint8_t HAL_SPI_Write(uint8_t data)

Do you have any ideas, how can i do that?
There is no example spi write in datasheet...
https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/dsPIC33EPXXGS202-Family-Data-Sheet-DS70005208E.pdf
Thank you very much
 

Offline blindelectronicsTopic starter

  • Newbie
  • Posts: 8
  • Country: it
Re: Dspic33ep16gs202
« Reply #8 on: October 27, 2022, 08:17:01 pm »
I used this early today:

uint8_t HAL_SPI_Write(uint8_t data)
{
    SPI1BUF = data;
   return 0;
}
 

Offline Kean

  • Supporter
  • ****
  • Posts: 3545
  • Country: au
    • Kean Electronics
Re: Dspic33ep16gs202
« Reply #9 on: October 27, 2022, 08:28:20 pm »
I used this early today:

Code: [Select]
uint8_t HAL_SPI_Write(uint8_t data)
{
    SPI1BUF = data;
return 0;
}

1. In HAL_SPI_Write() you should check the transmit buffer full status bit before writing another byte into the buffer.  You can use a busy-wait loop to keep things simple.
2. For HAL_SPI_WriteBuffer() you just need to loop through the bytes in the buffer, calling HAL_SPI_Write() for each one (wrapped in CS enable/disable).
3. Implementing HAL_SPI_ReadBuffer() is a bit more complex as you generally have to clock out data one byte ahead of the data you read in.
4. Your scope screenshot shows that you successfully clocked out one byte (0x44), but failed to clock the additional bytes because of #1 above.
5. As I mentioned above, your CS signal is probably not working because you don't configure the pin as an output.
 

Offline blindelectronicsTopic starter

  • Newbie
  • Posts: 8
  • Country: it
Re: Dspic33ep16gs202
« Reply #10 on: October 27, 2022, 08:38:00 pm »
Thank you for your reply Kean.
Port functions are configured like this:
    TRISBbits.TRISB14=0;    //SCK
    TRISBbits.TRISB13=1;    //MISO
    TRISBbits.TRISB12=0;    //MOSI

    TRISBbits.TRISB11=0;    //CS
    TRISBbits.TRISB15=0;    //PDN

    RPINR20bits.SDI1R=45;         //SDI input pin RP45      0b101101
    RPOR6bits.RP44R=0b000101;     //SDO OUTPUT pin RP44     0b000101
    RPOR7bits.RP46R=0b000110;     //SCK OUTPUT pin RP46     0b000110
 

Offline blindelectronicsTopic starter

  • Newbie
  • Posts: 8
  • Country: it
Re: Dspic33ep16gs202
« Reply #11 on: October 27, 2022, 08:41:33 pm »
I found something like this... When I tried to implement this it did not work :(
 

Offline Kean

  • Supporter
  • ****
  • Posts: 3545
  • Country: au
    • Kean Electronics
Re: Dspic33ep16gs202
« Reply #12 on: October 27, 2022, 08:44:29 pm »
Thanks for wasting our time.  :palm:

You were asked multiple time to show all of your code, and also asked to include any code in CODE tags.
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3566
  • Country: ca
Re: Dspic33ep16gs202
« Reply #13 on: October 27, 2022, 11:47:42 pm »
I used this early today:

uint8_t HAL_SPI_Write(uint8_t data)
{
    SPI1BUF = data;
   return 0;
}

Then everything is simple. The events happen in this order:

1. You drive CS down. You can see this on your scope (green trace I would guess)
2. You write to SPIBUF multiple times - the first write succeeds, others fail
3. You drive CS up. You can see that too. Double pulse for whatever reason.
4. SPI module transmits the first byte which you have transmitted on step 2. You can see this on your scope too.
5. Nothing else happens because the SPI buffer is now empty

You probably should wait for a byte to be transmitted before writing the next one. Also, you should wait until everything is transmitted before driving CS up.



 
The following users thanked this post: Kean

Offline Ground_Loop

  • Frequent Contributor
  • **
  • Posts: 711
  • Country: us
Re: Dspic33ep16gs202
« Reply #14 on: October 30, 2022, 10:39:41 pm »
You likely need to hold CS low for the entire transmission.
There's no point getting old if you don't have stories.
 

Offline Kean

  • Supporter
  • ****
  • Posts: 3545
  • Country: au
    • Kean Electronics
Re: Dspic33ep16gs202
« Reply #15 on: October 31, 2022, 02:34:41 am »
You likely need to hold CS low for the entire transmission.

Yes.

HAL_SPI_Write() should check the transmit buffer full status bit before writing another byte into the buffer
Code: [Select]
uint8_t HAL_SPI_Write(uint8_t data)
{
    while (SPI1STATbits.SPITBF) ;
    SPI1BUF = data;
    return 0;
}

HAL_SPI_Disable() should check the transmit shift register empty status bit before disabling CS
Code: [Select]
void HAL_SPI_Disable(void)
{
    while (!SPI1STATbits.SRMPT) ;
    LATBbits.LATB11=1;             //Set CS pin HIGH   
}

You apparently need to initialize SPI1CON2bits.SPIBEN to 1 so as to enable Enhanced Buffer mode for the SRMPT bit to work as expected.

Another (possibly easier) way to do it is monitor SPI1STATbits.SPIRBF flag, as while you clock data out of the transmit buffer you also clock data into the receive buffer.  The receive buffer will only be full once the transmit buffer and shitf register are also empty, thus handling both cases in one.  And you mentioned wanting to receive data.  For an example, see writeSPI1() in https://github.com/muradqasaimeh/PIC24-SPI-Communication/blob/master/SPI_Master.c
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf

 

- - -
-->