Dspic33ep16gs202 - Page 1
Forum section: electronics / general

author: blindelectronics
author_rank: Newbie
timestamp: October 27, 2022, 08:19:02 am
content: I'm having problems with SPI bus with CS pin. It does not work as it supposed to. Chip is Dspic33ep16gs202Can 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 CONFIGIFS0bits.SPI1IF = 0; // Clear the Interrupt flagIEC0bits.SPI1IE = 0; // Disable the interrupt// SPI1CON1 Register SettingsSPI1CON1bits.DISSCK = 0; // Internal serial clock is enabledSPI1CON1bits.DISSDO = 0; // SDOx pin is controlled by the moduleSPI1CON1bits.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 PrescaleSPI1CON1bits.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 stateSPI1CON1bits.CKP = 0; // Idle state for clock is a low level;SPI1STATbits.SPIEN = 1; // Enable SPI module//SPI1BUF = 0x00; // Write data to be transmittedIFS0bits.SPI1IF = 0; // Clear the Interrupt flagIEC0bits.SPI1IE = 1; // Enable the interrupt}

author: blindelectronics
author_rank: Newbie
timestamp: October 27, 2022, 08:21:23 am
content: scope screen

author: Kean
author_rank: Unknown
timestamp: October 27, 2022, 08:32:59 am
content: 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.

author: blindelectronics
author_rank: Newbie
timestamp: October 27, 2022, 09:35:11 am
content: It is just function like this.SPI_INIT is called I just forgot to put it herevoid HAL_SPI_Enable(void){LATBbits.LATB11=0; //Set CS pin LOW}void HAL_SPI_Disable(void){LATBbits.LATB11=1; //Set CS pin HIGH}

author: Kean
author_rank: Unknown
timestamp: October 27, 2022, 10:14:45 am
content: 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?

author: JPortici
author_rank: Super Contributor
timestamp: October 27, 2022, 01:53:52 pm
content: Quote from: blindelectronics on October 27, 2022, 08:19:02 amuse 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.

author: NorthGuy
author_rank: Super Contributor
timestamp: October 27, 2022, 08:07:36 pm
content: Also post the code of spi1_writeByte().

author: blindelectronics
author_rank: Newbie
timestamp: October 27, 2022, 08:15:16 pm
content: 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 dspicvoid 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.pdfThank you very much

author: blindelectronics
author_rank: Newbie
timestamp: October 27, 2022, 08:17:01 pm
content: I used this early today:uint8_t HAL_SPI_Write(uint8_t data){SPI1BUF = data;return 0;}

author: Kean
author_rank: Unknown
timestamp: October 27, 2022, 08:28:20 pm
content: Quote from: blindelectronics on October 27, 2022, 08:17:01 pm1. 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.

author: blindelectronics
author_rank: Newbie
timestamp: October 27, 2022, 08:38:00 pm
content: Thank you for your reply Kean.Port functions are configured like this:TRISBbits.TRISB14=0; //SCKTRISBbits.TRISB13=1; //MISOTRISBbits.TRISB12=0; //MOSITRISBbits.TRISB11=0; //CSTRISBbits.TRISB15=0; //PDNRPINR20bits.SDI1R=45; //SDI input pin RP45 0b101101RPOR6bits.RP44R=0b000101; //SDO OUTPUT pin RP44 0b000101RPOR7bits.RP46R=0b000110; //SCK OUTPUT pin RP46 0b000110

author: blindelectronics
author_rank: Newbie
timestamp: October 27, 2022, 08:41:33 pm
content: I found something like this... When I tried to implement this it did not work

author: Kean
author_rank: Unknown
timestamp: October 27, 2022, 08:44:29 pm
content: Thanks for wasting our time.You were asked multiple time to showallof your code, and also asked to include any code in CODE tags.

author: NorthGuy
author_rank: Super Contributor
timestamp: October 27, 2022, 11:47:42 pm
content: Quote from: blindelectronics on October 27, 2022, 08:17:01 pmThen 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 fail3. 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 emptyYou 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.

author: Ground_Loop
author_rank: Frequent Contributor
timestamp: October 30, 2022, 10:39:41 pm
content: You likely need to hold CS low for the entire transmission.

author: Kean
author_rank: Unknown
timestamp: October 31, 2022, 02:34:41 am
content: Quote from: Ground_Loop on October 30, 2022, 10:39:41 pmYes.HAL_SPI_Write() should check the transmit buffer full status bit before writing another byte into the bufferCode: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 CSCode: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() inhttps://github.com/muradqasaimeh/PIC24-SPI-Communication/blob/master/SPI_Master.c