Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: main.cpp
- Revision:
- 0:cb6ecbfcf585
- Child:
- 1:f468352a5408
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Sun Mar 30 19:34:20 2014 +0000
@@ -0,0 +1,267 @@
+#include "mbed.h"
+
+// this program control CS8416 in software mode(SPI) with LPC1114FN2.
+
+// CS8416 : 192 kHz Digital Audio Interface Receiver
+// http://www.cirrus.com/jp/pubs/proDatasheet/CS8416_F3.pdf
+
+// FN1242A : 24bit/192KHz/2ch DAC
+// http://akizukidenshi.com/download/ds/niigataseimitsu/FN1242Ajspec.pdf
+
+
+// LPC1114FN28 connect to
+// 1 MISO cs8416 / CDOUT
+// 2 MOSI cs8416 / CDIN
+// 3 SWCLK LPC-Link
+// 4 PIO cs8416 / CS
+// 6 SCK cs8416 / CCLK
+// 7 AVIN 3.3V
+// 8 AGND
+// 9 PIO toggle switch : input source select.
+// 12 SWDIO LPC-Link
+// 14 PIO cs8416 / reset
+// 15 PIO led1 : left
+// 16 PIO led2
+// 17 PIO led3
+// 18 PIO led4 : right
+// 21 VIN 3.3V
+// 22 GND
+// 23 RESET LPC-Link
+// 24 PIO fn1242a / ML
+// 25 PIO fn1242a / MD
+// 26 PIO fn1242a / MC
+
+// CS8416
+// RXP0 : S/PDIF TOSLINK input
+// RXP1 : S/PDIF COAX input
+// OMCK : 11.2896 MHz
+
+SPI spi(dp2, dp1, dp6); // mosi, miso, sclk
+DigitalOut pin_cs (dp4);
+DigitalOut pin_rst (dp14);
+DigitalOut pin_led1(dp15);
+DigitalOut pin_led2(dp16);
+DigitalOut pin_led3(dp17);
+DigitalOut pin_led4(dp18);
+DigitalIn pin_tgl (dp9);
+DigitalOut pin_ML (dp24);
+DigitalOut pin_MD (dp25);
+DigitalOut pin_MC (dp26);
+
+
+const uint8_t DEF_REGVAL[10] = {
+ 0x00, // 0x00 : Control0
+ 0x00, // 0x01 : Control1
+ 0x48, // 0x02 : Control2 // EMPH_CNTL[2:0]=deemphasis filter auto select, GPO0SEL[3:0]=(96KHZ)
+ 0x00, // 0x03 : Control3
+ 0x80, // 0x04 : Control4 // RUN=normal part operation
+ 0x85, // 0x05 : Serial Audio Data Format // SOMS=master mode, SODEL=second OSCLK period, SOLRPOL=right channel when OLRCK is high.
+ 0x00, // 0x06 : Receiver Error Mask
+ 0x00, // 0x07 : Interrupt Mask
+ 0x00, // 0x08 : Interrupt Mode MSB
+ 0x00 // 0x09 : Interrupt Mode LSB
+};
+
+uint32_t g_freq = 0;
+uint8_t g_cur_frmt = 0;
+uint32_t g_cur_tgl = 0;
+
+
+void fn1242_write(uint16_t word) {
+
+ pin_ML = 1;
+
+ for (int iii = 0; iii < 16; iii++) {
+ pin_MC = 0;
+ pin_MD = (word & 0x8000) == 0 ? 0 : 1; // msb first
+ wait_us(10); // us
+
+ pin_MC = 1;
+ wait_us(10); // us
+
+ word = word << 1;
+ }
+
+ pin_MD = 0;
+ pin_MC = 0;
+ pin_ML = 0;
+ wait_us(10); // us
+
+ pin_ML = 1;
+ wait_us(10); // us
+}
+
+void fn1242_init() {
+
+ pin_ML = 1;
+ pin_MD = 0;
+ pin_MC = 0;
+ wait_us(10); // us
+
+ fn1242_write(
+ (2 << 11) // MODE2
+ | (0 << 9) // OM (default)
+ | (0 << 8) // RST (OFF/default)
+ | (2 << 6) // BIT (24bit)
+ | (0 << 4) // ZM (default)
+ | (0 << 3) // ATC (default)
+ | (0 << 2) // MUTE (OFF/default)
+ | (0 ) ); // EMPH (OFF/default)
+}
+
+void cs8416_write(uint8_t u8_addr, uint8_t u8_data) {
+ uint8_t u8_recv = 0;
+
+ pin_cs = 0;
+ wait_us(10); // us
+ u8_recv = spi.write(0x20);
+ u8_recv = spi.write(u8_addr);
+ u8_recv = spi.write(u8_data);
+ pin_cs = 1;
+ wait_us(10); // us
+}
+
+
+uint8_t cs8416_read(uint8_t u8_addr) {
+ uint8_t u8_recv = 0;
+
+ pin_cs = 0;
+ wait_us(10); // us
+ u8_recv = spi.write(0x20);
+ u8_recv = spi.write(u8_addr);
+ pin_cs = 1;
+ wait_us(10); // us
+
+ pin_cs = 0;
+ wait_us(10); // us
+ u8_recv = spi.write(0x21);
+ u8_recv = spi.write(0x00);
+ pin_cs = 1;
+ wait_us(10); // us
+
+ return u8_recv;
+}
+
+
+void cs8416_init() {
+
+ pin_rst = 0; // reset
+ wait_ms(100); // ms
+ pin_rst = 1;
+ wait_ms(1); // ms
+
+ // SPI Mode is selected if there is a high to low transition on the AD0/CS pin, after the RST pin has been brought high.
+ pin_cs = 1; wait_ms(1);
+ pin_cs = 0; wait_ms(1); // enter SPI mode
+ pin_cs = 1; wait_ms(1);
+
+ for (int iii = 0; iii < 10; iii++) {
+ uint8_t u8_addr = (uint8_t) iii;
+ uint8_t u8_data = DEF_REGVAL[iii];
+ cs8416_write(u8_addr, u8_data);
+ }
+}
+
+
+void decide_freq(uint8_t u8_addr18) {
+
+ switch (u8_addr18) {
+ case 0x59:
+ case 0x58:
+ case 0x57: g_freq = 32; break;
+
+ case 0x40:
+ case 0x3f: g_freq = 44; break;
+
+ case 0x3b:
+ case 0x3a: g_freq = 48; break;
+
+ case 0x20:
+ case 0x1f: g_freq = 88; break;
+
+ case 0x1d:
+ case 0x1c: g_freq = 96; break;
+
+ case 0x10:
+ case 0x0f: g_freq = 176; break;
+
+ case 0x0e: g_freq = 192; break;
+
+ default: g_freq = 0; break;
+ }
+}
+
+
+void set_led() {
+ uint32_t u32_val = 0;
+
+ switch (g_freq) {
+ case 32: u32_val = 0x01; break; // 0001
+ case 44: u32_val = 0x02; break; // 0010
+ case 48: u32_val = 0x03; break; // 0011
+ case 88: u32_val = 0x04; break; // 0100
+ case 96: u32_val = 0x05; break; // 0101
+ case 176: u32_val = 0x06; break; // 0110
+ case 192: u32_val = 0x07; break; // 0111
+ }
+
+ pin_led4 = (u32_val & 1); u32_val = u32_val >> 1;
+ pin_led3 = (u32_val & 1); u32_val = u32_val >> 1;
+ pin_led2 = (u32_val & 1); u32_val = u32_val >> 1;
+}
+
+
+void set_rmckf() {
+ uint8_t u8_data = 0;
+
+ if (g_cur_frmt & 1) { // (0Bh)[0] 96KHZ - If the input sample rate is <= 48 kHz, outputs a "0". Outputs a "1" if the sample rate is >= 88.1 kHz. Otherwise the output is indeterminate.
+ pin_led1 = 1;
+ u8_data = 0x02; // (01h)[1] RMCKF - Recovered Master Clock Frequency @ 1 : 128 Fs
+ } else {
+ pin_led1 = 0;
+ u8_data = 0x00; // (01h)[1] RMCKF - Recovered Master Clock Frequency @ 0 : 256 Fs
+ }
+ cs8416_write(0x01, DEF_REGVAL[1] + u8_data); // (01h) : Control1
+}
+
+
+void set_source() {
+ uint8_t u8_data = 0;
+
+ if (g_cur_tgl & 1) {
+ u8_data = 0x08; // (04h)[5:3] RXSEL2:0
+ } else {
+ u8_data = 0x00; // (04h)[5:3] RXSEL2:0
+ }
+ cs8416_write(0x04, DEF_REGVAL[4] + u8_data); // (04h) : Control4
+}
+
+
+int main() {
+
+ spi.format(8, 3); // 8bit, mode3
+ spi.frequency(1000000); // 1MHz : default
+
+ cs8416_init();
+ fn1242_init();
+
+ while (1) {
+ uint8_t u8_addr18 = cs8416_read(0x18); // (18h) : OMCK/RMCK Ratio
+ decide_freq(u8_addr18);
+ set_led();
+
+ uint8_t u8_addr0B = cs8416_read(0x0b); // (0Bh) : Format Detect Status
+ if (g_cur_frmt != u8_addr0B) {
+ g_cur_frmt = u8_addr0B;
+ set_rmckf();
+ }
+
+ uint32_t u32_tgl = pin_tgl;
+ if (g_cur_tgl != u32_tgl) {
+ g_cur_tgl = u32_tgl;
+ set_source();
+ }
+
+ wait_ms(200); // ms
+ }
+}