pixma / stm8s-projects

Repo where i play with STM8
7 stars 7 forks source link

SPI Read is not working #1

Closed Rahul5214 closed 6 years ago

Rahul5214 commented 6 years ago

I'm using this library for STM8S103F3to read LIS3DHaccelerometer. I wrote a spi read function in stdafx.c file as pasted below.

uint8_t spi_read_data_1_byte(uint8_t ReadAddr){
    uint8_t data;
    // PA3 = SS pin on STM8S103F3
    GPIO_WriteHigh(GPIOA, GPIO_PIN_3);  // SS pin Low
        //Send Address
        SPI_SendData(ReadAddr | 0x80); // MSB bit high for read mode
    data = SPI_ReceiveData();
    GPIO_WriteLow(GPIOA, GPIO_PIN_3);  // SS pin High
    return data;
}

But spi_read_data_1_byte always returns 255 value for all registers addresses.

I am using IAR and printf for debugging. I have cross checked SPI connections also and I can't figure the problem.

pixma commented 6 years ago

Some steps to diagnose -

You can share your SPI Init code here for further investigation. And, SPI related functions and codes should not be in stdafx.c, it should be inside spi-related src files. "stdafx" is usually used for standard application framework purpose to include the basic framework or say header files into the project.

Keep me posted!

Rahul5214 commented 6 years ago

I have tried all 4 SPI modes. Connection are as follows: full duplex mode STM -> LIS3DH PC7 -> SDO PC6 -> SDA, SDI PC5 -> SCL, SCK PA3 -> CS

SPI_Init(SPI_FIRSTBIT_MSB, SPI_BAUDRATEPRESCALER_8, SPI_MODE_MASTER, SPI_CLOCKPOLARITY_HIGH, SPI_CLOCKPHASE_2EDGE,SPI_DATADIRECTION_2LINES_FULLDUPLEX, SPI_NSS_SOFT,0x07);

GPIO_Init(GPIOA, GPIO_PIN_3, GPIO_MODE_OUT_PP_HIGH_SLOW); // SS pin = PA3 in STM8S103F3
void spi_read_data_1_byte( uint8_t ReadAddr){     // in stdafx.c file
    uint8_t data;
    GPIO_WriteLow(GPIOA, GPIO_PIN_3);

    /*!< Wait until the transmit buffer is empty */
    while (SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET){}

    //Send Address
    SPI_SendData(ReadAddr | 0x80);   // MSB 1 for reading
    data = SPI_ReceiveData();
    printf("f- %d\n", data);
    SPI_SendData(0);
    data = SPI_ReceiveData();
    printf("s- %d\n", data);
    GPIO_WriteHigh(GPIOA, GPIO_PIN_3);
}

Code in main.c file


#include "stdafx.h"

void delay(uint16_t time){
    uint16_t i;
        uint16_t j;
    for (i=0; i<200; i++){
          for(j=0; j<time;j++){
            nop();
          }

    }
}
int main( void ){
    //GPIO_DeInit(GPIOB);
   // SPI_DeInit();

    //GPIO_Init(GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_FAST);
    init_spi();

    // The main loop
    while( 1 ){
        delay(80);
      //  GPIO_WriteReverse(GPIOB, GPIO_PIN_5);
        spi_read_data_1_byte(0x0f);//Random Address 0x40 for now.
    }
}

I have just edited stdafx.h and stdafx.c. All other files are untouched. Output in Terminal I\O

f- 0
s- 255
f- 51
s- 255
f- 51
s- 255
f- 51
s- 255

SPI register values after executing SPI_Init() function. screenshot 18

Reset value of SPI_DRis 0x00 but I don't know why it is showing blank in register window.

Rahul5214 commented 6 years ago

Finally it worked with these changes.

SPI_Init(SPI_FIRSTBIT_MSB, SPI_BAUDRATEPRESCALER_8, SPI_MODE_MASTER, SPI_CLOCKPOLARITY_HIGH, SPI_CLOCKPHASE_2EDGE,SPI_DATADIRECTION_2LINES_FULLDUPLEX, SPI_NSS_SOFT,0x07); // in stafx.c

uint8_t SPI_read(uint8_t ReadAddr){
   uint8_t value;
   GPIO_WriteLow(GPIOA, GPIO_PIN_3);
   SPI_Transfer(ReadAddr | 0x80);
   value = SPI_Transfer(0);
   GPIO_WriteHigh(GPIOA, GPIO_PIN_3);
   return value;
}

void SPI_write(uint8_t WriteAddr, uint8_t value){
  GPIO_WriteLow(GPIOA, GPIO_PIN_3);
  SPI_Transfer(WriteAddr & ~0x80); // MSB 0 for writing
  SPI_Transfer(value);
  GPIO_WriteHigh(GPIOA, GPIO_PIN_3);
}

// in stm8s_spi.c

uint8_t SPI_Transfer(uint8_t Data){
    while (SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET){}
    SPI->DR = Data;

    while (SPI_GetFlagStatus(SPI_FLAG_RXNE) == RESET){}
    return ((uint8_t)SPI->DR); /* Return the data in the DR register*/
}