stm32f4 discovery cs43l22 mp3 player

Başlatan DaRt, 01 Haziran 2015, 22:34:34

DaRt

Merhaba Arkadaşlar;
Nisan ayı ortalarında arm mcuları öğrenmeye başlamak için bir stm32f4 discovery kit alarak keil ile c ve arm dünyasına daldım.  İlk başladığım andan itibaren aklımda kit üzerindeki cs43l22 ses çipinden ses almak vardı. Bu amaçla bulduğum az sayıdaki örnekte karşılaştığım en büyük sorun, içerisinde sdcard, usb otg, lis302dl, ses kaydı vs gibi binlerce satır kod arasından işime yarayacak kodları çıkarıp almaktı. Bu zorluğu güç bela aşarak bir şekilde tüm donanımların kodlarını sadeleştirerek ve internette bulduğum hazır kütüphaneleri kullanarak  min kod sayısında bir mp3/wav player kodladım. Forumda da pek çok kişide bulunan discovery kitinin üzerindeki ses çipinden ses alma uygulaması konusunda forumdaki eksikliği kapatmak için bu başlığı açtım ve biraz da blog tadından 5~6 bölüm halinde sıfırdan başlayarak mp3 player kodlaması hakkında bir şeyler karalayım istedim.

Öncelikle şunu söylemeliyim ki elektronik/programcılıkla hobi seviyesinde ilgileniyorum. Dolayısı ile amacım ortaya ticari yada günlük kullanıma uygun bir ürün çıkarmak değil, neyin nasıl yapıldığını öğrenmek. Dolayısı ile yazdığım kodlar verimlilikten uzak, belkide çok daha az işlemci gücü ve hafıza alanı kullanarak yazılabilir, bu konuda iddialı değilim. Son olarak şunu eklemeliyim ki c ile tanışmam henüz çok yeni (2 ay bile olmadı). Bu nedenle konuyu takip eden arkadaşlar olursa ve yaptığım hatalar yada hantal işlemler konusunda uyarırlarsa hem ben hemde forumdaki arkadaşlarımız için çok daha yararlı olur diye düşünmekteyim. Diğer taraftan bu başlıkta wav ve mp3 dosyalarının sistematiği, header bölümleri hakkında dilim döndüğünce bir şeyler yazacağım ancak mp3 decoderi konusunda (nasıl çalıştığı, hangi matematiksel modelleri kullandığı vs.) bilgim olmadığından ve öğrenmek için yeterli zamanım olmadığından bu konuya girmeyeceğim. Dolayısı ile sadece hazır fonksiyonları kullanarak mp3 dosyasından pcm dataları elde edeceğim.

Gelelim neleri kullanacağımıza. Öncelikle stm32f407 çipi ile registry seviyesinde ilgilenmeyeceğiz. Bunun yerine aşağıda yazdığım kütüphaneleri kullanacağız.

derleyici keil 5
spi, i2c, i2s, dma, irq, gpio, dac vs için st kütüphaneleri
sdcard, tft fontları tilen majerle
fatfs chan
mp3 decoder helix
xpt2046, ili9341, cs43l22, mp3 oynatma rutinleri sağdan soldan bulduklarım biz sadece bunların hepsini tek projede birleştirip senkronize bir şekilde çalışmalarını sağlayacağız.

Toplamda 6 bölüm olacak ve her bölümü kod şeklinde açıklamaları ile beraber foruma yazacağım. Ayrıca derlenmiş dosya olarak dropboxa yükleyeceğim. İsteyen arkadaşlar kodları kendi projesine ekler, isteyenler dropboxtan indirir.

+ i2c, i2s kurulumu cs43l22 init ve ilk ses üretme (8kHz mono modda 4khz sabit frekanslı ses)
+ hafızadan wav çalma (8kHz mono)
+ dahili dac kullanarak cs43l22 analog girişleri ile wav çalma (8khz mono)
+ dma kurulumu double buffer modda hafızadan wav çalma (8kHz mono)
+ sdcard fatfs ile wav çalma (44.1 kHz stereo)
+ mp3 çalma

Bunları tamamladıktan sonra katılım durumuna göre usb otg, touch, tft lcd, ses kaydı gibi konulara da girebiliriz.

Son olarak aklında soru işareti olan arkadaşlar için youtube videosundan ortaya nasıl birşey çıkacağını görebilir. Cep  telefonu kaydı olduğu için ses kaydı çok kötü. Normalde ses çipinin oldukça kaliteli bir ses çıkışı var. İsteyenler aşağıdaki linklerden videoda koşturan kodları alabilirler 2 adet kütüphane dosyası ve 1 adet kod dosyasını aynı klasöre çıakrdığınızda sorunsuz derlenmesi gerekir. (xpt2046 touch ve ili9341 lcdsi olanlar yada kendine göre modifiye edecek olanlar tft için fsmc pinlerini, touch ve sd card için spi3 c7 c10 c12 pinlerini, reset pinleri için kodları inceleyebilir)  Şunu da eklemeliyim ki videodaki kodlar yarımdır çok fazla bug vardır. Bu kadarı yeter dediğim için daha fazla geliştirmek istemedim. Şimdilik bu kadar. Birazdan ilk bölümü yazmaya başlayacağım.


https://www.dropbox.com/s/770b7ro5po5j4xb/wavplayer.rar?dl=0
https://www.dropbox.com/s/9ka0x7b1ynj4u4b/00-STM32F429_LIBRARIES.rar?dl=0
https://www.dropbox.com/s/jztrpl11dyosege/00-STM32F4xx_STANDARD_PERIPHERAL_DRIVERS.rar?dl=0

https://www.youtube.com/watch?v=upjw8j0TUDw

muhittin_kaplan


DaRt

#2
Sağolasın Hocam.


mesaj birleştirme:: 02 Haziran 2015, 08:22:50

cs43l22 çipi cirrus logic firmasının ürettiği ve i2s yöntemiyle gönderilen pcm formatındaki dataları kendi içerisindeki dacta analog sinyale çevirim d sınıfı yükselteç ile yükselterek hoparlor yada kulaklık çıkışına veren ses çipidir. Ses datası için 1 adet i2s bağlantısı, registry kontrolleri için 1 adet i2c bağlantısı, 4 adet analog stereo giriş, 1 adet streo hoperlor çıkışı ve 1 adet stereo kulaklık çıkışı bulunur. çip 8 kHz ile 96kHz arası ses verisini çıkışa aktarabilir. Registrylerle ayarlanarak 12, 24 yada 27MHz clock kaynağı kullanılabilir. Çip stereodur eğer mono çalıanacaksa ya aynı veri iki kez gönderilemelidir. (belki registryleri ile oynanarak buna gerek kalmayabilir) Discovery kitin PD4 pinine bağlı reset piniyle aktif hale getirilir ve i2c üzeriden komut almaya başlar. Registiry kurulumlarından ve kullanılacak giriş çıkış kaynağı seçildikten sonra i2s ile datalar gönderilmeye başlandığında ses vermeye başlar. cirrus sitesinde bulunan datasheetinde geniş bilgi mevcut.

İlk olarak boş bir proje üzerine cs43l22.c olarak bir kod doyası oluşturdum ve i2c, i2s, ve cs43l22 init işlemlerini bu doyas üzerinde yaptım. kodları aşağıda. Kodların yanlarına dilim döndüğünce açıklama yazdım. Tam bu noktada çip hakkında kısa bir bilgi ekleyim. Anlayabildiğim kadarıyla stm32f407 i2s modunda standart olarak 256xsamplerate şeklinde clock çıkışı veriyor. Clokc girişi ise cs43l22de zorunlu ve cs43l22 datasheeti sayfa 29da belirtildiği üzere 8KHz için en az 12,28MHz clock sinyali uygulamak gerekiyor. Ancak stm32f4 8KHz için 8000*256=2,048MHz clock çıkışı verebiliyor. Bu durum nedense sorun çıkarmıyor ve çip 8khz sesi 2MHz clock ile çalabiliyor. Aşağıda i2c, i2s ve cs43l22 init fonksiyonları içeren kod grubu var.

// Header:
// File Name: cs43l22.c
// Author:
// Date:

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_i2c.h"


//----------Degiskenler-----------------
I2C_InitTypeDef i2c;
I2S_InitTypeDef i2s;
GPIO_InitTypeDef gpio;

//----------Fonksiyonlar-----------------
void writeI2CData(uint8_t bytesToSend[], uint8_t numOfBytesToSend); // ses çipine i2c verisi göndermek için
uint8_t readI2CData(uint8_t bytesToregs); // ses çipinden i2s verisi almak için
void init_I2C(void); // i2c kurulumu
void init_I2S(void); // i2s kurulumu
void init_cs43l22(void); // ses çipi registry ayarlamalar1

void init_I2S(void)
{ 
	// i2s potu ayarlamalari gpio ve spi iletisim için
		// SPI3 CLOCK ENABLE 
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE); //spi3 clock aktif

    RCC_PLLI2SCmd(ENABLE); 
 
  	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //gpioc clock aktif
	
		// I2S  MISO MOSI CLK PIN
	  gpio.GPIO_Mode = GPIO_Mode_AF; // spi3 pinleri af
    gpio.GPIO_OType = GPIO_OType_PP; // spi3 pinleripp
    gpio.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_10 | GPIO_Pin_12; // spi3 pinleri
    GPIO_Init(GPIOC, &gpio); // pinleri kur
 
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // gpioa clock aktif
	
    // I2S L/R PIN
    gpio.GPIO_Pin = GPIO_Pin_4; // giden ses datasinin sag mi yoksa sol mu oldugunu belirten spi3 port pini
    GPIO_Init(GPIOA, &gpio); // pini kur
 
		// I2S PIN AF
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_SPI3); // gpioa pin4 af spi3 ayarla
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_SPI3); // gpioa pin7 af spi3 ayarla
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_SPI3); // gpioa pin10 af spi3 ayarla
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_SPI3); // gpioa pin12 af spi3 ayarla
	
    SPI_I2S_DeInit(SPI3); // spi3 kurulumunu iptal et
    i2s.I2S_AudioFreq = I2S_AudioFreq_8k ; // sample rate 8000Hz olacak
    i2s.I2S_MCLKOutput = I2S_MCLKOutput_Enable; // cs43l22 için gerekli clock kaynagi aktif (8000*256=2.048MHz) 256 sabit deger
    i2s.I2S_DataFormat = I2S_DataFormat_16b; // 16bit data
    i2s.I2S_Mode = I2S_Mode_MasterTx; // i2s master mod olacak
    i2s.I2S_Standard = I2S_Standard_Phillips; // çipin destekledigi standart
    i2s.I2S_CPOL = I2S_CPOL_Low; //???
    I2S_Init(SPI3, &i2s); // spi3 kur

		I2S_Cmd(SPI3, ENABLE); // spi3 aktif
}


 void init_I2C(void)
{	
	// i2c potu ayarlamalari gpio ve spi iletisim için
	  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); // gpiob clock aktif
	
	  // I2C CLOCK ENABLE 
	  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); // i2c clock aktif
	
	  // I2C SDA SCK PIN
    gpio.GPIO_Mode = GPIO_Mode_AF; // i2c pinleri af
    gpio.GPIO_OType = GPIO_OType_OD; // i2c pinleri open drain
    gpio.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_9; // i2c pinleri
    gpio.GPIO_PuPd = GPIO_PuPd_UP; // dahili pull uplar aktif
    gpio.GPIO_Speed = GPIO_Speed_50MHz; // port hizi 50MHz olsun 
    GPIO_Init(GPIOB, &gpio); // gpiob kur
 
		// I2C PIN AF
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1); // gpioa pin4 af i2c ayarla
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1); // gpioa pin4 af i2c ayarla
	
    I2C_DeInit(I2C1); // i2c kurulumunu iptal et
	
    i2c.I2C_ClockSpeed = 100000; // i2c 100KHz olsun
    i2c.I2C_Mode = I2C_Mode_I2C; //
    i2c.I2C_OwnAddress1 = 0x33; //
    i2c.I2C_Ack = I2C_Ack_Enable; //
    i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //
    i2c.I2C_DutyCycle = I2C_DutyCycle_2; //
 
    I2C_Init(I2C1, &i2c); // i2c kur
	  I2C_Cmd(I2C1, ENABLE); //i2c aktif
}


 uint8_t readI2CData(uint8_t bytesToregs) // çipten i2c okuma rutini detaya girmeye gerek yok 
{
  uint8_t tmp=0;

  I2C_GenerateSTART(I2C1, ENABLE);

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

  I2C_Send7bitAddress(I2C1, 0x94, I2C_Direction_Transmitter); // 0x94 cihaz i2c adresi

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

  I2C_SendData(I2C1, bytesToregs);

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  I2C_GenerateSTART(I2C1, ENABLE);
  
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

  I2C_Send7bitAddress(I2C1, 0x94, I2C_Direction_Receiver);
  
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

  I2C_GenerateSTOP(I2C1, ENABLE);
  
	while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)){};

  tmp = I2C_ReceiveData(I2C1);

  return (tmp);
}


 void writeI2CData(uint8_t bytesToSend[], uint8_t numOfBytesToSend) // çipe i2c yazma rutini detaya girmeye gerek yok 
{
    uint8_t currentBytesValue = 0;
 

    while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));

    I2C_GenerateSTART(I2C1, ENABLE);
    while (!I2C_GetFlagStatus(I2C1, I2C_FLAG_SB));

    I2C_Send7bitAddress(I2C1, 0x94, I2C_Direction_Transmitter); // 0x94 cihaz i2c adresi
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
 

    while (currentBytesValue < numOfBytesToSend)
    {
	    I2C_SendData(I2C1, bytesToSend[currentBytesValue]);
    	currentBytesValue++;
	    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING));
    }
 
    while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF));
 
    I2C_GenerateSTOP(I2C1, ENABLE);
}


void init_cs43l22(void)
{
	uint8_t sendBuffer[2];
	int i;
	GPIO_ResetBits(GPIOD, GPIO_Pin_4); // çip resetle
	for(i=0;i<0xfffff;i++){}; // çip oturana kadar bekle
	GPIO_SetBits(GPIOD, GPIO_Pin_4); // çip rest kaldir
	for(i=0;i<0xfffff;i++){}; // çip oturana kadar bekle
 
    sendBuffer[0] = 0x0D;
    sendBuffer[1] = 0x03;
    writeI2CData(sendBuffer, 2); //master çikislar sessiz modda
 
    sendBuffer[0] = 0x00;
    sendBuffer[1] = 0x99;
    writeI2CData(sendBuffer, 2); // gerekli kurulum ayari datasheet s:32-31
 
    sendBuffer[0] = 0x47;
    sendBuffer[1] = 0x80;
    writeI2CData(sendBuffer, 2); // gerekli kurulum ayari datasheet s:32-31
 
    sendBuffer[0] = 0x32;
    sendBuffer[1] = 0xFF;
    writeI2CData(sendBuffer, 2); // gerekli kurulum ayari datasheet s:32-31
 
    sendBuffer[0] = 0x32;
    sendBuffer[1] = 0x7F;
    writeI2CData(sendBuffer, 2); // gerekli kurulum ayari datasheet s:32-31
 
    sendBuffer[0] = 0x00;
    sendBuffer[1] = 0x00;
    writeI2CData(sendBuffer, 2); // gerekli kurulum ayari datasheet s:32-31
 
    sendBuffer[0] = 0x04;
    sendBuffer[1] = 0xAF;
    writeI2CData(sendBuffer, 2); // hoperlor ç1k1_1 pasif kulakl1k ç1k1_1 aktif
 
    sendBuffer[0] = 0x0D;
    sendBuffer[1] = 0x70;
    writeI2CData(sendBuffer, 2); // sessiz mod iptal ve kulakl1k gain ayar1
 
    sendBuffer[0] = 0x05;
    sendBuffer[1] = 0x80;
    writeI2CData(sendBuffer, 2); // otomatik clock mod aktif
 
    sendBuffer[0] = 0x06;
    sendBuffer[1] = 0x07;
    writeI2CData(sendBuffer, 2); // arayüz ayarlamalar1, 16 bit sola yanas1k, slave
 
    sendBuffer[0] = 0x0A;
    sendBuffer[1] = 0x00;
    writeI2CData(sendBuffer, 2); // analog zero cross kullanm1yoruz
 
    sendBuffer[0] = 0x27;
    sendBuffer[1] = 0x00;
    writeI2CData(sendBuffer, 2); // ses limit ayarlar1 kullanm1yoruz
 
    sendBuffer[0] = 0x1A;
    sendBuffer[1] = 0x0A;
    writeI2CData(sendBuffer, 2); // PCM data volume ayari kanal 1
 
    sendBuffer[0] = 0x1B;
    sendBuffer[1] = 0x0A;
    writeI2CData(sendBuffer, 2); // PCM data volume ayari kanal 2
 
    sendBuffer[0] = 0x1F;
    sendBuffer[1] = 0x0F;
    writeI2CData(sendBuffer, 2); // equaliser
		
		sendBuffer[0] = 0x22;
    sendBuffer[1] = 0xC0;
    writeI2CData(sendBuffer, 2); // kulakl1k ses yükseklik ayar1 kanal 1
 
    sendBuffer[0] = 0x23;
    sendBuffer[1] = 0xC0;
    writeI2CData(sendBuffer, 2); // kulakl1k ses yükseklik ayar1 kanal 2
 
    sendBuffer[0] = 0x02;
    sendBuffer[1] = 0x9E;
    writeI2CData(sendBuffer, 2); // gerekli kurulum ayari datasheet s:32-31
}


Bu kurulumlardan sonra main.c system init, gpio, i2c ve i2s (8KHz, 16 bit) kurulumlarından sonra çip kontrolü yapmakta fayda var. Çipin i2c adresi 0x94tür. 0x01 adresli registryden 8 bitlik çip id okuyup yüksek 5 biti 0x1c (datasheet sayfa 37) ise mavi ledi yakıp yolumuza devam edelim. Eğer 0x1c okuyamazsak çipte kurulumda vs sorun var deyip kırmızı ledi yakalım. Ardından 0xfff, ve 0x000 verilerini arka arkaya 2şer kez göndererek 4kHz sabit frekanslı ses elde edelim. Çip stereo olduğundan arka arkaya gönderdiğimiz 2 datadan biri sol biri sağ kulaklıktan çıkacağından mono modda aynı datayı iki kez göndermek gerekiyor. Kodlar aşağıda.

// Header:
// File Name: 
// Author:
// Date:


#include "stm32f4xx.h"
#include "defines.h"


//----------Fonksiyonlar-----------------
void init_I2C(void);
uint8_t readI2CData(uint8_t bytesToregs);
void init_I2S(void);
void init_cs43l22(void);

void GpioInit(void) {
	GPIO_InitTypeDef GPIO_InitStruct;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
	
  GPIO_InitStruct.GPIO_Pin =  GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; // led pinleri
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; // pinler çıkış
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; // push pull çıkış
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz; // port hızı 100 mhz
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN; // pull down aktif
  GPIO_Init(GPIOD, &GPIO_InitStruct);  // pinleri kur
	
	 // RESET PIN CS43L22 
   GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4; // reset pini
   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; // çıkış
   GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN; // pull down aktif
   GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; // push pull
   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // port 50mhz
   GPIO_Init(GPIOD, &GPIO_InitStruct); // pinleri kur
}


int main(void) {
	uint8_t cs43l22id=0;
	uint8_t state=0;
	SystemInit();

	GpioInit(); //cs43l22 reset pini ve led pinleri gpio ayarlamalar1
	
	init_I2C(); // i2c kur
	
	init_I2S(); // i2s kur
	
	init_cs43l22(); // çipi ayarla
	
	cs43l22id=(readI2CData(0x01))>>3; // çip id oku ve 3 bit sola kaydir.
	
	if(cs43l22id==0x1C){
			GPIO_SetBits(GPIOD, GPIO_Pin_15); // çip id dogru okunduysa mavi led yans1n
	}
	else{
			GPIO_SetBits(GPIOD, GPIO_Pin_14); // çip id dogru okunmadiysa k1rm1z1 led yans1n
	}

	while (1) {
		 	while(!SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)){} // i2s ile gönderilmekte olan data varsa bekle
	    if (state == 0x00) // en son 0x000 gönderildiyse 0xfff gönder 
	    {			
		    SPI_I2S_SendData(SPI3, 0xFFF); // i2s ile 0xfff gönder kanal 1
				state = 0x01;
				while(!SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)){} // data gönderilene kadar bekle
				SPI_I2S_SendData(SPI3, 0xFFF); // i2s ile 0xfff gönder kanal 2
	    }
	    else // en son 0xfff gönderildiyse 0x000 gönder 
	    {
		    SPI_I2S_SendData(SPI3, 0x000); // i2s ile 0xfff gönder kanal 1
				state = 0x00;
				while(!SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)){} // data gönderilene kadar bekle
				SPI_I2S_SendData(SPI3, 0x000); // i2s ile 0xfff gönder kanal 2
	    }

	}
}


Yukarıdaki kodları kendi projenize ekleyip, stnin  i2s, i2c ve gpio  standart kütüphanelerini eklerseniz sorunsuz derlenerek çalışacaktır. Aşağıdaki linkte hazır proje olarak bulunmaktadır.
https://www.dropbox.com/s/p4yln3fwh6njsjb/mp3player.rar?dl=0

Bir sonraki bölümde hafızadan 8KHz 8bit mono ses çalacağız.









f15eagle

DaRt, güzel bir paylaşım yapmışsın tebrik ederim. Ses konusu pek ilgimi çekmese de kod örneklerini inceliyorum.

Çalışmaların devamını gelir umarım

justice_for_all

#4
I2C okuma kısmı yalnışmı yoksa ben mi yalnış yorumluyorum  :o

Alıntı yapılan: DaRt - 02 Haziran 2015, 08:18:15
uint8_t readI2CData(uint8_t bytesToregs) // çipten i2c okuma rutini detaya girmeye gerek yok 
{
  uint8_t tmp=0;

  I2C_GenerateSTART(I2C1, ENABLE);

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

  I2C_Send7bitAddress(I2C1, 0x94, I2C_Direction_Transmitter); // 0x94 cihaz i2c adresi

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

  I2C_SendData(I2C1, bytesToregs);

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  I2C_GenerateSTART(I2C1, ENABLE);
  
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

  I2C_Send7bitAddress(I2C1, 0x94, I2C_Direction_Receiver);
  
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

  I2C_GenerateSTOP(I2C1, ENABLE);
  
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)){};

  tmp = I2C_ReceiveData(I2C1);

  return (tmp);
}



Alıntı Yap

Send start condition.
Send 10010100 (chip address & write operation).
Receive acknowledge bit.
Send MAP byte, auto-increment off.
Receive acknowledge bit.
Send stop condition, aborting write.
Send start condition.
Send 10010101 (chip address & read operation).
Receive acknowledge bit.
Receive byte, contents of selected register.
Send acknowledge bit.
Send stop condition.

doğruymus stm32f4 örneklerindede aynı ama burada tek stop verilmeden start verilmiş burası neden boyle olmuş?
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

DaRt

Okunacak adres verisinden sonra stop verilse de çalışıyor verilmese de. Datasheette i2c timing diagramında stop biti verilmiş. İlginç gerçekten. Bu şekilde de çalıştığından genelde kullanılmıyor demek ki.

justice_for_all

sanırım iki kez arka arkaya start verilince stop verilmiş oluyor buyüzden verilmemiş olabilir.Şimdi biraz daha mantıklı olmaya başladı.
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

Fnisher

@DaRt stm32f4 discovery kartı ile yeni yeni ilgilenmeye başladım. 10 günlük tecrübemin ardından CS43L22 entegresini çalıştırmak istedim. Başarılı oldum ancak sinüs sinyalinden ses alabildim. Herhangi bir wav uzantılı dosyayı oynatamadım.
Tecrübelerinizden faydalanmak adına yazmış olduğunuz kodları incelemek istedim. Ancak dropbox üzerinden linklerin boş olduğunu gördüm. Muhtemelen çok eski olduğundan dolayı :)
Rica etsem projeyi incelemem adına tekrar paylaşabilir misiniz?



fdemirci916

Başlık üzerinden biraz zaman geçmiş ama beep generator ile nasıl ses üretebiliriz yardım edebilir misin? @DaRt