もっと今更、SC-88ProにS/PDIFを付けよう

Dependencies:   mbed

もっと今更、SC-88ProにS/PDIFを付けよう

STM32F103C8T6 ARM STM32 (blue pill)

  • モデル:STM32F103C8T6
  • コア:ARM 32 Cortex-M3 CPU
  • 72MHz頻度を作動させる
  • 64Kフラッシュメモリ、20K SRAM
  • 2.0-3.6Vパワー、I/O

というやつ。

/media/uploads/peu605/frontview.jpg

詳細はwikiの説明に

https://developer.mbed.org/users/peu605/code/DIT88proSTM32F1/wiki/説明

しまったなぁ、wikiのタイトル、漢字にしてしまったよ…

STM32F103C8T6, Roland, SC-88pro, S/PDIF, SPIDF, デジタル出力

Revision:
3:bdac1803f0fd
Parent:
2:62c8aa0c38c7
Child:
4:c7c69c9b3cac
--- a/main.cpp	Mon Sep 04 16:54:24 2017 +0000
+++ b/main.cpp	Tue Sep 05 11:06:55 2017 +0000
@@ -71,11 +71,12 @@
 
 int main()
 {
+    // change to 72MHz
     SystemClock_Config();
-    
+
     setupPeripherals();
     setChannelStatus();
-    
+
     HAL_Delay(1000);
 
     // enable SPI and deselect
@@ -95,10 +96,11 @@
     // wait for interrupt
     while (true) {
 
+        __WFI();
+
 #ifdef _DEBUG_CONSOLE
         debugOut();
 #endif
-        __WFI();
 
     }
 }
@@ -106,16 +108,16 @@
 
 void transferFrames()
 {
-    
-    // measured load is 20.8%
+
+    // measured load is 18.6% at 72MHz
     _LED_OFF(); // PC_13 to HIGH
-    
+
     for (uint32_t i = 0; i < BUFFER_NUM_FRAMES / 2; ++i) {
         transferFrame();
     }
-    
+
     _LED_ON();  // PC_13 to LOW
-    
+
 }
 
 
@@ -152,11 +154,11 @@
 
     static bool lastCellZero = true;
 //    static uint32_t spiDelay = 0;
-    
+
     // ======================================
     // Read rx buffer and make raw SPIDF data
     // ======================================
-    
+
     // Roland SC-88pro, 256fs, 18bit right justified, MSB first
     // SC-88pro's output format seems to be 2's complement 18 bit audio data in 20 bit data frame.
     //
@@ -180,15 +182,17 @@
     // 1111 ... 0000000  1111110000000000  1111110000000000
     // 5432     6543210  5432109876543210  5432109876543210
     //
-    // bit[127:20] is all 0 or all 1.
+    // bit[127:20] is all 0 or all 1. SDO keeps last LSB state.
     //
     // bit[31:20] should be 000...00 or 111...11
     // bit[19:0] MSB to LSB, 2's complement 18 bit audio data in 20 bit data frame
-    
+    //
+    // measured spiDelay is 2 to 4
+
     // arithmetic right shift
     int32_t val = (*(rxBuffPtr + 6) << 16) | *(rxBuffPtr + 7);
     val >>= spiDelay;
-    
+
     // determine spiDelay
     while(true) {
         int32_t test = val & MASK31_20;
@@ -205,15 +209,15 @@
             }
         }
     }
-    
-    // left shift to fit 24 bit width
+
+    // left shift to fit 24 bit width, adding zero
     val <<= (24 - SDATA_LENGH);
 
     // 4-27 data, 28 V, 29 U, 30 C, 31 P
     // U = 0
     // 'val' here does not have preamble.
     // So, V position is (28 - 4), C pos is (30 - 4), and P pos is (31 - 4).
-    
+
     // mask with 24 bit to clear VUCP bits
     val &= MASK23_0;
 
@@ -249,13 +253,17 @@
     // First, 0 ~ 4 bit is Preamble. Not BMC!
     uint16_t bmc;
     if (!aCh) {
+        // b channel
         bmc = lastCellZero ? PREAMBLE_Y : ~PREAMBLE_Y;
     } else if (frameIndex == 0) {
+        // a channel, frame 0
         bmc = lastCellZero ? PREAMBLE_Z : ~PREAMBLE_Z;
     } else {
+        // a channel, frame != 0
         bmc = lastCellZero ? PREAMBLE_X : ~PREAMBLE_X;
     }
-    lastCellZero = !(bmc & 1);  //lastCellZero = (bmc & 1) == 0;
+//    lastCellZero = !(bmc & 1);
+    lastCellZero = (bmc & 1) == 0;
     *txBuffPtr++ = bmc;
 
     // Next, 5 ~ 31 bit, audio data and VUCP bits. 28/4 = 7 loops
@@ -263,7 +271,8 @@
     for (uint32_t i = 0; i < 7 ; ++i) {
         bmc = lastCellZero
               ? bmcTable[val & 0x0f] : ~bmcTable[val & 0x0f];
-        lastCellZero = !(bmc & 1);
+//        lastCellZero = !(bmc & 1);
+        lastCellZero = (bmc & 1) == 0;
         *txBuffPtr++ = bmc;
         val >>= 4;
     }
@@ -344,29 +353,55 @@
     *str = '\0';
 }
 
+
 #ifdef _DEBUG_CONSOLE
-uint16_t tmpData[8];
-char str[17];
-Serial pc(PA_2, PA_3);
-
 void debugOut()
 {
+    static char str[17];
+    static Serial pc(PA_2, PA_3);
+
 //    pc.printf("SystemCoreClock =%d\n", SystemCoreClock);
 
-    for (uint8_t i = 6; i < 8; ++i) {
-        tmpData[i] = spiRxBuff[0].ltCh[i];
+/*
+    // dump raw data
+    uint16_t tmp = spiRxBuff[0].ltCh[6];
+    toBinary(&tmp, (char*) &str);
+    pc.printf("Delay:%02d %s ", spiDelay, str);
+    tmp = spiRxBuff[0].ltCh[7];
+    toBinary(&tmp, (char*) &str);
+    pc.printf("%s\n", str);
+    HAL_Delay(200);
+*/
+
+    // dump shifted data
+    int32_t val = (spiRxBuff[0].ltCh[6] << 16) | (spiRxBuff[0].ltCh[7]);
+    val >>= spiDelay;
+    uint16_t tmp = (val & 0xffff0000) >> 16;
+    toBinary(&tmp, (char*) &str);
+    pc.printf("Delay:%02d %s ", spiDelay, str);
+    tmp = val & 0xffff;
+    toBinary(&tmp, (char*) &str);
+    pc.printf("%s\n", str);
+    HAL_Delay(200);
+
+/*
+    // find loud 18bit data
+    int32_t val = (spiRxBuff[0].ltCh[6] << 16) | (spiRxBuff[0].ltCh[7]);
+    val >>= spiDelay;
+    uint16_t tmp = (val & 0xffff0000) >> 16;
+    if ((tmp & 0b1111) == 0b1110 || (tmp & 0b1111) == 0b0001) {
+        toBinary(&tmp, (char*) &str);
+        pc.printf("Delay:%02d %s ", spiDelay, str);
+        tmp = val & 0xffff;
+        toBinary(&tmp, (char*) &str);
+        pc.printf("%s\n", str);
     }
-    pc.printf("Delay:%02d", spiDelay);
-    for (uint8_t i = 6; i < 8; ++i) {
-        pc.printf(" ");
-        toBinary(&tmpData[i], (char*) &str);
-        pc.printf(str);
-    }
-    pc.printf("\n");
-    HAL_Delay(200);
+*/
+
 }
 #endif
 
+
 /**
   * @brief  System Clock Configuration
   *         The system Clock is configured as follow :
@@ -384,12 +419,14 @@
   */
 void SystemClock_Config(void)
 {
+    HAL_RCC_DeInit();
+    // not implemented yet?
+//    LL_RCC_DeInit();
 
     /* Set FLASH latency */
     LL_FLASH_SetLatency(LL_FLASH_LATENCY_2);
 
     /* Enable HSE oscillator */
-//    LL_RCC_HSE_EnableBypass();
     LL_RCC_HSE_Enable();
     while(LL_RCC_HSE_IsReady() != 1) {
     };
@@ -416,15 +453,15 @@
 
     /* Update CMSIS variable (which can be updated also through SystemCoreClockUpdate function) */
     LL_SetSystemCoreClock(72000000);
-    
-    // 本当に72MHzかなぁ…
 
+    // re-set baud rate.
+//    pc.baud(9600);
 }
 
 
 void setupPeripherals()
 {
-    
+
     // enable GPIOB/C clock
     LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOB);
     LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOC);