もっと今更、SC-88ProにS/PDIFを付けよう
もっと今更、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
というやつ。
詳細はwikiの説明に
https://developer.mbed.org/users/peu605/code/DIT88proSTM32F1/wiki/説明
しまったなぁ、wikiのタイトル、漢字にしてしまったよ…
STM32F103C8T6, Roland, SC-88pro, S/PDIF, SPIDF, デジタル出力
Diff: main.cpp
- 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);