2016年1月15日金曜日

PSoC 5LPでI2Sのテスト TDA1543編(メモ)

I2SのDACのTDA1543を仕入れてテストしてみた。

I2SのDACはPCM5102Aでテストしようと思っていたが、電源電圧が3.3V(絶対定格3.9V)なので間違えて壊してしまいそうなので5Vが定格のTDA1543 をつかうことにした。なかなか売ってなくてデジットで1000円ぐらいだった。

I2SのマスターはPSoC 5LP Prototyping Kitを使った。

配線

電流出力だがRでIV変換できるらしいので、Webに上がっていた作例を参考にした。VDDは5Vだ。

PSoC Creator TopDesign


16bit/48kHzだとClockに3.072MHz与えればいいが分周の関係で実際はちょっとずれる。データ転送にはDMAを使った。

ソースコード

 /* ========================================  
  *  
  * Copyright YOUR COMPANY, THE YEAR  
  * All Rights Reserved  
  * UNPUBLISHED, LICENSED SOFTWARE.  
  *  
  * CONFIDENTIAL AND PROPRIETARY INFORMATION  
  * WHICH IS THE PROPERTY OF your company.  
  *  
  * ========================================  
 */  
 #include <project.h>  
 #define TABLE_LENGTH 256  
 /* Defines for DMA_1 */  
 #define DMA_1_BYTES_PER_BURST 2  
 #define DMA_1_REQUEST_PER_BURST 1  
 #define DMA_1_SRC_BASE (CYDEV_SRAM_BASE)  
 #define DMA_1_DST_BASE (CYDEV_PERIPH_BASE)  
 /* Variable declarations for DMA_1 */  
 /* Move these variable declarations to the top of the function */  
 uint8 DMA_1_Chan;  
 uint8 DMA_1_TD[1];  
 uint16 sawTable[TABLE_LENGTH];  
 int main()  
 {  
   int i, v;  
   // sawTableの生成  
   for (i = 0; i < TABLE_LENGTH; i += 2) {  
     v = i * (0x10000 / TABLE_LENGTH);  
     sawTable[i]  = v;  
     sawTable[i+1] = v;  
   }  
   CyGlobalIntEnable; /* Enable global interrupts. */  
   /* Place your initialization/startup code here (e.g. MyInst_Start()) */  
   I2S_1_Start();  
   /* DMA Configuration for DMA_1 */  
   DMA_1_Chan = DMA_1_DmaInitialize(DMA_1_BYTES_PER_BURST, DMA_1_REQUEST_PER_BURST,   
     HI16(DMA_1_SRC_BASE), HI16(DMA_1_DST_BASE));  
   DMA_1_TD[0] = CyDmaTdAllocate();  
   CyDmaTdSetConfiguration(DMA_1_TD[0], TABLE_LENGTH, DMA_1_TD[0], TD_INC_SRC_ADR);  
   CyDmaTdSetAddress(DMA_1_TD[0], LO16((uint32)sawTable), LO16((uint32)I2S_1_TX_CH0_F0_PTR));  
   CyDmaChSetInitialTd(DMA_1_Chan, DMA_1_TD[0]);  
   CyDmaChEnable(DMA_1_Chan, 1);  
   while(0u != (I2S_1_ReadTxStatus() & I2S_1_TX_FIFO_0_NOT_FULL))  
   {  
     /* Wait for TxDMA to fill Tx FIFO */  
   }  
   CyDelayUs(1);  
   I2S_1_EnableTx();  
   for(;;)  
   {  
     /* Place your application code here. */  
   }  
 }  
 /* [] END OF FILE */  

やっていることは16bitのStereo Interleaveのノコギリ波の配列を作ってDMAでI2Sコンポーネントに送っている。

DMAを使っているのでコードがかなりややこしくなっていて自分でもよくわからない。

PSoC CreatorにDMA Wizardというツールがあるので一応使ってコードを生成した。

出力波形

ch1:TDA1543のLOUT ch2:I2SのWS

ノコギリ波が出力された!

が正負が逆。

TDA1543のデータシートのBlock Diagram

出力を反転電流-電圧変換回路を通しているので反転出力なのかな?

あと、WSと出力波形を見ると
0.687ms / 21.486us ≒ 32
なので数が合わない。(プログラムは1周期128個出力するつもりで書いている)

DMA転送が怪しい感じだ。

Github
https://github.com/ryood/TDA1543