summaryrefslogtreecommitdiff
path: root/firmware/drivers/i2s.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/i2s.c')
-rw-r--r--firmware/drivers/i2s.c61
1 files changed, 49 insertions, 12 deletions
diff --git a/firmware/drivers/i2s.c b/firmware/drivers/i2s.c
index df32801..2d900be 100644
--- a/firmware/drivers/i2s.c
+++ b/firmware/drivers/i2s.c
@@ -32,7 +32,7 @@ void i2s_set_power(int power)
// Remark: On reset, the I²S interface is disabled (PCI2S = 0).
uint32_t *pconp = (uint32_t *)0x400FC0C4;
*pconp &= ~(0b1 << 27); // Clear bit
- *pconp |= ~( ((power != 0) & 0b1) << 27); // Set bit
+ *pconp |= ((power != 0) & 0b1) << 27; // Set bit
}
void i2s_set_clksel(i2s_clksel_t sel)
@@ -91,7 +91,7 @@ void i2s_set_pinsel()
;
}
-void i2s_set_dao_register(wordwidth_t ww, channels_t ch)
+void i2s_set_dao_register(i2s_wordwidth_t ww, i2s_channels_t ch)
{
// See table 405, pg. 476
uint32_t *i2sdao = (uint32_t*)0x400A8000;
@@ -106,7 +106,7 @@ void i2s_set_dao_register(wordwidth_t ww, channels_t ch)
;
}
-void i2s_set_dai_register(wordwidth_t ww, channels_t ch)
+void i2s_set_dai_register(i2s_wordwidth_t ww, i2s_channels_t ch)
{
// See table 406, pg. 477
uint32_t *i2sdai = (uint32_t*)0x400A8004;
@@ -149,7 +149,7 @@ void i2s_set_rx_clock_bitrate(uint8_t bitrate)
*i2srxbitrate = (bitrate & 0b111111);
}
-void i2s_set_tx_mode_control(clksel_t c, int _4pin, int mcena)
+void i2s_set_tx_mode_control(i2s_tx_clksel_t c, int _4pin, int mcena)
{
// See table 417, pg 482
uint32_t *i2stxmode = (uint32_t*)0x400A8030;
@@ -159,7 +159,7 @@ void i2s_set_tx_mode_control(clksel_t c, int _4pin, int mcena)
;
}
-void i2s_set_rx_mode_control(clksel_t c, int _4pin, int mcena)
+void i2s_set_rx_mode_control(i2s_rx_clksel_t c, int _4pin, int mcena)
{
// See table 418, pg 483
uint32_t *i2srxmode = (uint32_t*)0x400A8034;
@@ -280,19 +280,54 @@ int i2s_get_state_tx_level()
return (*i2sstate >> 16) & 0b1111; // bit 16-19
}
-void i2s_init()
+int i2s_init(int pclkdiv, int bitrate, int x, int y,
+ int bitwidth, int channels)
{
i2s_set_power(1);
- i2s_set_clksel(I2S_CCLK_2);
+
+ i2s_clksel_t clk = I2S_CCLK;
+ switch(pclkdiv) {
+ case 1: clk = I2S_CCLK; break;
+ case 2: clk = I2S_CCLK_2; break;
+ case 4: clk = I2S_CCLK_4; break;
+ case 8: clk = I2S_CCLK_8; break;
+ default:
+ return 1;
+ }
+ i2s_set_clksel(clk);
+
i2s_set_pinsel();
- i2s_set_dao_register(WW_16_BIT, CH_STEREO);
- i2s_set_tx_rate(1, 1);
- i2s_set_tx_clock_bitrate(7);
+
+ i2s_wordwidth_t ww = I2S_WW_16_BIT;
+ switch(bitwidth) {
+ case 8: ww = I2S_WW_8_BIT; break;
+ case 16: ww = I2S_WW_16_BIT; break;
+ case 32: ww = I2S_WW_32_BIT; break;
+ default:
+ return 1;
+ }
+
+ i2s_channels_t ch = I2S_CH_MONO;
+ switch(channels) {
+ case 1: ch = I2S_CH_MONO; break;
+ case 2: ch = I2S_CH_STEREO; break;
+ default:
+ return 1;
+ }
+
+ i2s_set_dao_register(ww, ch);
+
+ if((x & 0xff) != x || (y & 0xff) != y) return 1;
+ i2s_set_tx_rate(x, y);
+
+ if((bitrate & 0b111111) != bitrate) return 1;
+ i2s_set_tx_clock_bitrate(bitrate);
+
i2s_set_tx_mode_control(CLK_TX_SRC, 1, 1);
- i2s_tx_reset();
+ //i2s_tx_reset();
i2s_tx_stop();
-
+ /*
int i;
i = i2s_get_state_irq();
i = i2s_get_state_dmareq1();
@@ -300,6 +335,8 @@ void i2s_init()
i = i2s_get_state_rx_level();
i = i2s_get_state_tx_level();
(void)i;
+ */
+ return 0;
}
#if 0