Stm32f0 SPI2 Master Sorunsalı

Başlatan yldzelektronik, 12 Temmuz 2016, 11:57:18

yldzelektronik

Merhaba,

Spi kullanarak bir slave device sürmek istiyorum.Ancak bir türlü spi 2 ile yıldızımız barışmıyor.

Mcu: Stm32f070CB

SPI2 ve SPI1 için aynı ayarları kullanıyorum.Init rutini şöle;

#define SPIx                           SPI1//SPI2
#define SPIx_CLK                       RCC_APB2Periph_SPI1//RCC_APB1Periph_SPI2
//#define SPIx_CLK_INIT                  RCC_APB2PeriphClockCmd
//#define SPIx_IRQn                      SPI2_IRQn
//#define SPIx_IRQHANDLER                SPI2_IRQHandler

#define SPIx_SCK_PIN                   GPIO_Pin_5//GPIO_Pin_13
#define SPIx_SCK_GPIO_PORT             GPIOA//GPIOB
#define SPIx_SCK_GPIO_CLK              RCC_AHBPeriph_GPIOA//RCC_AHBPeriph_GPIOB
#define SPIx_SCK_SOURCE                GPIO_PinSource5//GPIO_PinSource13
#define SPIx_SCK_AF                    GPIO_AF_0

#define SPIx_MISO_PIN                  GPIO_Pin_6//GPIO_Pin_14
#define SPIx_MISO_GPIO_PORT            GPIOA//GPIOB
#define SPIx_MISO_GPIO_CLK             RCC_AHBPeriph_GPIOA//RCC_AHBPeriph_GPIOB
#define SPIx_MISO_SOURCE               GPIO_PinSource6//GPIO_PinSource14
#define SPIx_MISO_AF                   GPIO_AF_0

#define SPIx_MOSI_PIN                  GPIO_Pin_7//GPIO_Pin_15
#define SPIx_MOSI_GPIO_PORT            GPIOA//GPIOB
#define SPIx_MOSI_GPIO_CLK             RCC_AHBPeriph_GPIOA//RCC_AHBPeriph_GPIOB
#define SPIx_MOSI_SOURCE               GPIO_PinSource7//GPIO_PinSource15
#define SPIx_MOSI_AF                   GPIO_AF_0

HardwareSPI::HardwareSPI(uint32_t spiPortNumber) :
    _spiPortNumber(spiPortNumber)
{
}

void HardwareSPI::begin(SPIFrequency frequency, uint32_t bitOrder, uint32_t mode)
{
  GPIO_InitTypeDef GPIO_InitStructure;
//  NVIC_InitTypeDef NVIC_InitStructure;
  SPI_InitTypeDef  SPI_InitStructure;

  /* Peripheral Clock Enable -------------------------------------------------*/
  /* Enable the SPI clock */
  RCC_APB2PeriphClockCmd(SPIx_CLK, ENABLE);//RCC_APB1PeriphClockCmd(SPIx_CLK, ENABLE);
  
  /* Enable GPIO clocks */
  RCC_AHBPeriphClockCmd(SPIx_SCK_GPIO_CLK | SPIx_MISO_GPIO_CLK | SPIx_MOSI_GPIO_CLK, ENABLE);

  /* SPI GPIO Configuration --------------------------------------------------*/
  /* GPIO Deinitialisation */
//  GPIO_DeInit(SPIx_SCK_GPIO_PORT);
//  GPIO_DeInit(SPIx_MISO_GPIO_PORT);
//  GPIO_DeInit(SPIx_MOSI_GPIO_PORT);
  
  /* Connect SPI pins to AF5 */  
  GPIO_PinAFConfig(SPIx_SCK_GPIO_PORT, SPIx_SCK_SOURCE, SPIx_SCK_AF);
  GPIO_PinAFConfig(SPIx_MISO_GPIO_PORT, SPIx_MISO_SOURCE, SPIx_MISO_AF);    
  GPIO_PinAFConfig(SPIx_MOSI_GPIO_PORT, SPIx_MOSI_SOURCE, SPIx_MOSI_AF);

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;

  /* SPI SCK pin configuration */
  GPIO_InitStructure.GPIO_Pin = SPIx_SCK_PIN;
  GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStructure);
  
  /* SPI  MISO pin configuration */
  GPIO_InitStructure.GPIO_Pin =  SPIx_MISO_PIN;
  GPIO_Init(SPIx_MISO_GPIO_PORT, &GPIO_InitStructure);  

  /* SPI  MOSI pin configuration */
  GPIO_InitStructure.GPIO_Pin =  SPIx_MOSI_PIN;
  GPIO_Init(SPIx_MOSI_GPIO_PORT, &GPIO_InitStructure);
 
  /* SPI configuration -------------------------------------------------------*/
  SPI_I2S_DeInit(SPIx);
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  if (mode == SPI_MODE0)
  {
      SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
      SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
  }
  else if (mode == SPI_MODE1)
  {
      SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
      SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  }
  else if (mode == SPI_MODE2)
  {
      SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
      SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
  }
  else if (mode == SPI_MODE3)
  {
      SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
      SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  }

  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  // Prescaler is divided into PCLK2 (84MHz) to get SPI baud rate/clock speed
  // 256 => 328.125kHz
  // 128 => 656.25kHz
  // 64 => 1.3125MHz
  // 32 => 2.625MHz
  // 16 => 5.25MHz
  // 8  => 10.5MHz
  // 4  => 21.0MHz
  switch (frequency)
  {
      case SPI_21_0MHZ:
				SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
			break;
      case SPI_10_5MHZ:
				SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
			break;
      case SPI_5_25MHZ:
				SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
			break;
      case SPI_2_625MHZ:
      default:
				SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
			break;
      case SPI_1_3125MHZ:
				SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
			break;
      case SPI_656_25KHZ:
				SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
			break;
      case SPI_328_125KHZ:
				SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
			break;
  }

  if (bitOrder == LSBFIRST)
      SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB;
  else
      SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

  /* Initializes the SPI communication */
  SPI_Init(SPIx, &SPI_InitStructure);
  /* Enable SPI1  */
  SPI_Cmd(SPIx, ENABLE);
}


Olay şu;

Spi 1 kullanarak yukarıdaki ayarlar ile hiç sorun yaşamadan slave ile iletişim kurabiliyorum.Ancak aynı ayarları spi2 için yapmaya kalktığımda slave cihaza veri yazabilirken veri okuyamıyorum.Ne yazsam 0 dönüyor.Hangi registerini okusam slave in 0 dönüyor.

Her iki durumda da spi master olarak çalışıyor mcu.

Spi2 için bu ayarları yaptığımda skop ile bakıyorum ve clock görüyorum.Aynı şekilde mosi ucunda da veriyi görüyorum.Ancak slave veri dönmüyor.

Aklıma gelen bir tek şu sorun var.Ekte Spi2 ile olan skop görüntüsü ve spi1 skop görüntüsü var.

Spi2 ile olan sinyalde  sanki slave giden sinyaldeki veriyi okuyamıyor mu acaba.Yani lojik 1 de 0 da kalma süreleri yeterli gelmiyor da veriyi mi algılayamıyor acaba?

Spi1 Clock, MISO:



Spi2 Clock, MOSI:



Spi2 MISO hep 0.Hiç veri yok. Sebebi ne olabilir?

Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

Klein

SPI MISO Pinini remap yapman gerekiyor olabilir. Hangi pini kullandın?

yldzelektronik

GPIOB Pin 14 miso
GPIOB Pin 13 SCK
GPIOB Pin 15 mosi

Stm32f0 da pin remap nasıl yapılıyor ki?

Alternate function kastediyorsanız yaptım zaten ve aynı ayarlar ile spi1 çok güzel çalışıyor.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

Klein

Yok alternatif fonksiyon değil.
JTAG, SWD, OSC gibi bazı pinler varsayılan olarak bu tip özel işler için atanmıştır. Bu pinleri IO veya AF fonksiyonlu pinler olarak kullanmak için önce pin remapping yapılmalıdır.
Fakat senin kullandığın pinlere  ST-CUBE ile kabaca baktım, remapping gerekmiyor gibi.


yldzelektronik

Alıntı yapılan: Klein - 12 Temmuz 2016, 14:06:27
Yok alternatif fonksiyon değil.
JTAG, SWD, OSC gibi bazı pinler varsayılan olarak bu tip özel işler için atanmıştır. Bu pinleri IO veya AF fonksiyonlu pinler olarak kullanmak için önce pin remapping yapılmalıdır.
Fakat senin kullandığın pinlere  ST-CUBE ile kabaca baktım, remapping gerekmiyor gibi.



Abi bir tek pb15 awake pin gibi?Onda remap gerekir mi?Ama ben zaten data çıkışı görüyorum.Yani sorunum data girişi
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

Klein

Remapping sorunu değil.
Datasheet'i yeterince okumama sorunu

3. This feature is available on STM32F030x8 devices only.
5. For STM32F030xC devices only.

yldzelektronik

#6
Alıntı yapılan: Klein - 12 Temmuz 2016, 14:23:33
Remapping sorunu değil.
Datasheet'i yeterince okumama sorunu

3. This feature is available on STM32F030x8 devices only.
5. For STM32F030xC devices only.


SPI2 yalnızca STM32F030xC yada STM32F030x8 mı varmış?Hangi dokümanda okudunuz abi?

DocID027114 Rev 2 sayfa 23:





mesaj birleştirme:: 12 Temmuz 2016, 15:18:25

Bu soruna çözüm bulamıyorum bir türlü.PCB revizyon yapmam gerekecek.Yapmak istemiyorum.Hem uzun sürecek hem de para.Ayrıca zaman kaybettirecek.

Aklınıza gelen herhangi birşey var mı?
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

Klein

Haklısın, sen değil ben atlamışım.
Portu Init ettikten sonra , başka bir rutin DeInit ediyor olabilir mi?

Bir de kodun SPI2 Halini yayınla oradan bakalım.

yldzelektronik

#8
#define SPIx                           SPI1//SPI2
#define SPIx_CLK                       RCC_APB2Periph_SPI1//RCC_APB1Periph_SPI2
//#define SPIx_CLK_INIT                  RCC_APB2PeriphClockCmd
//#define SPIx_IRQn                      SPI2_IRQn
//#define SPIx_IRQHANDLER                SPI2_IRQHandler

#define SPIx_SCK_PIN                   GPIO_Pin_5//GPIO_Pin_13
#define SPIx_SCK_GPIO_PORT             GPIOA//GPIOB
#define SPIx_SCK_GPIO_CLK              RCC_AHBPeriph_GPIOA//RCC_AHBPeriph_GPIOB
#define SPIx_SCK_SOURCE                GPIO_PinSource5//GPIO_PinSource13
#define SPIx_SCK_AF                    GPIO_AF_0

#define SPIx_MISO_PIN                  GPIO_Pin_6//GPIO_Pin_14
#define SPIx_MISO_GPIO_PORT            GPIOA//GPIOB
#define SPIx_MISO_GPIO_CLK             RCC_AHBPeriph_GPIOA//RCC_AHBPeriph_GPIOB
#define SPIx_MISO_SOURCE               GPIO_PinSource6//GPIO_PinSource14
#define SPIx_MISO_AF                   GPIO_AF_0

#define SPIx_MOSI_PIN                  GPIO_Pin_7//GPIO_Pin_15
#define SPIx_MOSI_GPIO_PORT            GPIOA//GPIOB
#define SPIx_MOSI_GPIO_CLK             RCC_AHBPeriph_GPIOA//RCC_AHBPeriph_GPIOB
#define SPIx_MOSI_SOURCE               GPIO_PinSource7//GPIO_PinSource15
#define SPIx_MOSI_AF                   GPIO_AF_0

HardwareSPI::HardwareSPI(uint32_t spiPortNumber) :
    _spiPortNumber(spiPortNumber)
{
}

void HardwareSPI::begin(SPIFrequency frequency, uint32_t bitOrder, uint32_t mode)
{
  GPIO_InitTypeDef GPIO_InitStructure;
//  NVIC_InitTypeDef NVIC_InitStructure;
  SPI_InitTypeDef  SPI_InitStructure;

  /* Peripheral Clock Enable -------------------------------------------------*/
  /* Enable the SPI clock */
  RCC_APB2PeriphClockCmd(SPIx_CLK, ENABLE);//RCC_APB1PeriphClockCmd(SPIx_CLK, ENABLE);
  
  /* Enable GPIO clocks */
  RCC_AHBPeriphClockCmd(SPIx_SCK_GPIO_CLK | SPIx_MISO_GPIO_CLK | SPIx_MOSI_GPIO_CLK, ENABLE);

  /* SPI GPIO Configuration --------------------------------------------------*/
  /* GPIO Deinitialisation */
//  GPIO_DeInit(SPIx_SCK_GPIO_PORT);
//  GPIO_DeInit(SPIx_MISO_GPIO_PORT);
//  GPIO_DeInit(SPIx_MOSI_GPIO_PORT);
  
  /* Connect SPI pins to AF5 */  
  GPIO_PinAFConfig(SPIx_SCK_GPIO_PORT, SPIx_SCK_SOURCE, SPIx_SCK_AF);
  GPIO_PinAFConfig(SPIx_MISO_GPIO_PORT, SPIx_MISO_SOURCE, SPIx_MISO_AF);    
  GPIO_PinAFConfig(SPIx_MOSI_GPIO_PORT, SPIx_MOSI_SOURCE, SPIx_MOSI_AF);

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;

  /* SPI SCK pin configuration */
  GPIO_InitStructure.GPIO_Pin = SPIx_SCK_PIN;
  GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStructure);
  
  /* SPI  MISO pin configuration */
  GPIO_InitStructure.GPIO_Pin =  SPIx_MISO_PIN;
  GPIO_Init(SPIx_MISO_GPIO_PORT, &GPIO_InitStructure);  

  /* SPI  MOSI pin configuration */
  GPIO_InitStructure.GPIO_Pin =  SPIx_MOSI_PIN;
  GPIO_Init(SPIx_MOSI_GPIO_PORT, &GPIO_InitStructure);
 
  /* SPI configuration -------------------------------------------------------*/
  SPI_I2S_DeInit(SPIx);
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  if (mode == SPI_MODE0)
  {
      SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
      SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
  }
  else if (mode == SPI_MODE1)
  {
      SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
      SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  }
  else if (mode == SPI_MODE2)
  {
      SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
      SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
  }
  else if (mode == SPI_MODE3)
  {
      SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
      SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  }

  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  // Prescaler is divided into PCLK2 (84MHz) to get SPI baud rate/clock speed
  // 256 => 328.125kHz
  // 128 => 656.25kHz
  // 64 => 1.3125MHz
  // 32 => 2.625MHz
  // 16 => 5.25MHz
  // 8  => 10.5MHz
  // 4  => 21.0MHz
  switch (frequency)
  {
      case SPI_21_0MHZ:
				SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
			break;
      case SPI_10_5MHZ:
				SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
			break;
      case SPI_5_25MHZ:
				SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
			break;
      case SPI_2_625MHZ:
      default:
				SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
			break;
      case SPI_1_3125MHZ:
				SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
			break;
      case SPI_656_25KHZ:
				SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
			break;
      case SPI_328_125KHZ:
				SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
			break;
  }

  if (bitOrder == LSBFIRST)
      SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB;
  else
      SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

  /* Initializes the SPI communication */
  SPI_Init(SPIx, &SPI_InitStructure);
  /* Enable SPI1  */
  SPI_Cmd(SPIx, ENABLE);
}


SPI1 ve SPI2 hali bu.Yalnızca SPI2 için olanlar commentlenmiş halde.O kadar.

EK: Soft SPI ile denedim.SPI2 pinleriyle.Sorunsuz haberleşilebiliyor.En azından veri okuyabiliyorum.Yazmayı denemedim.Yanlışlık var.Soft spi ile de okunmuyor.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

Klein

Giriş pinini PullDown yapmışsın. Slave cihazın Source akımı sink akımına göre düşükse sıkıntı çıkarıyor olabilir. Gerçi SPI1'in çalışıp SPI2'nin çalışmamasını açıklamıyor ama yine de bir kontrol et.

yldzelektronik

#10
Alıntı yapılan: Klein - 12 Temmuz 2016, 16:06:01
Giriş pinini PullDown yapmışsın. Slave cihazın Source akımı sink akımına göre düşükse sıkıntı çıkarıyor olabilir. Gerçi SPI1'in çalışıp SPI2'nin çalışmamasını açıklamıyor ama yine de bir kontrol et.

Bir kaç saat evvel FxDev'in gönderidiği kodlarda görüp düzeltmiştim.

Ekleme: Sorun devam etmekte.Halen spi2 ile veri alamamaktayım.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

LukeSkywalker

Kodları kütüphane kullanmadan register seviyesinde yazıp dener misiniz?

Klein

Soft SPI ile de veri alamadığını söylemiştin. Bu durumda portu okuyamıyorsun demektir. SPI Slave aygıtı aradan çıkarıp portu elle yönlendirdiğinde okuyabiliyor musun?

yldzelektronik

Alıntı yapılan: LukeSkywalker - 12 Temmuz 2016, 17:56:07
Kodları kütüphane kullanmadan register seviyesinde yazıp dener misiniz?


Şuan başka bir sorun çıktığından onunla ilgilenemeyeceğim.Ama o yöntem ile de deneyeceğim.Teşekkürler.

Alıntı yapılan: Klein - 12 Temmuz 2016, 17:59:08
Soft SPI ile de veri alamadığını söylemiştin. Bu durumda portu okuyamıyorsun demektir. SPI Slave aygıtı aradan çıkarıp portu elle yönlendirdiğinde okuyabiliyor musun?

Deneyeceğim.İlginç bir durum ortaya çıktı.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

yldzelektronik

Selamlar,

Sorunun kaynağını buldum.

Sorun yeni yaptığım şematikte spi slave device bacak isimlerini yanlış yazmışım.Normalde device da miso olması gereken pine mosi demişim ve bütün mevzu bununla ilgili.Bu değişimi ne zaman yaptığımı veya yapıp yapmadığımı hatırlamadığımdan hiç aklıma gelmedi.

Logic analyzer ile bakarken fark ettim.

Yardımcı olanlara teşekkür ederim.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.