Adjust sound volume with select+up/down & add DMG color palette
This commit is contained in:
+64
-9
@@ -24,6 +24,9 @@
|
||||
|
||||
#include "i2s.h"
|
||||
|
||||
/**
|
||||
* return the default i2s context used to store information about the setup
|
||||
*/
|
||||
i2s_config_t i2s_get_default_config(void) {
|
||||
i2s_config_t i2s_config = {
|
||||
.sample_freq = 44100,
|
||||
@@ -35,11 +38,16 @@ i2s_config_t i2s_get_default_config(void) {
|
||||
.dma_channel = 0,
|
||||
.dma_buf = NULL,
|
||||
.dma_trans_count = 0,
|
||||
.volume = 0,
|
||||
};
|
||||
|
||||
return i2s_config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the I2S driver. Must be called before calling i2s_write or i2s_dma_write
|
||||
* i2s_config: I2S context obtained by i2s_get_default_config()
|
||||
*/
|
||||
void i2s_init(i2s_config_t *i2s_config) {
|
||||
uint8_t func=GPIO_FUNC_PIO0; // TODO: GPIO_FUNC_PIO0 for pio0 or GPIO_FUNC_PIO1 for pio1
|
||||
gpio_set_function(i2s_config->data_pin, GPIO_FUNC_PIO0);
|
||||
@@ -52,17 +60,17 @@ void i2s_init(i2s_config_t *i2s_config) {
|
||||
|
||||
audio_i2s_program_init(i2s_config->pio, i2s_config->sm , offset, i2s_config->data_pin , i2s_config->clock_pin_base);
|
||||
|
||||
// Set PIO clock
|
||||
/* Set PIO clock */
|
||||
uint32_t system_clock_frequency = clock_get_hz(clk_sys);
|
||||
uint32_t divider = system_clock_frequency * 4 / i2s_config->sample_freq; // avoid arithmetic overflow
|
||||
pio_sm_set_clkdiv_int_frac(i2s_config->pio, i2s_config->sm , divider >> 8u, divider & 0xffu);
|
||||
|
||||
pio_sm_set_enabled(i2s_config->pio, i2s_config->sm, false);
|
||||
|
||||
// Allocate memory for the DMA buffer
|
||||
/* Allocate memory for the DMA buffer */
|
||||
i2s_config->dma_buf=malloc(i2s_config->dma_trans_count*sizeof(uint32_t));
|
||||
|
||||
// Direct Memory Access setup
|
||||
/* Direct Memory Access setup */
|
||||
i2s_config->dma_channel = dma_claim_unused_channel(true);
|
||||
|
||||
dma_channel_config dma_config = dma_channel_get_default_config(i2s_config->dma_channel);
|
||||
@@ -81,20 +89,67 @@ void i2s_init(i2s_config_t *i2s_config) {
|
||||
pio_sm_set_enabled(i2s_config->pio, i2s_config->sm , true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write samples to I2S directly and wait for completion (blocking)
|
||||
* i2s_config: I2S context obtained by i2s_get_default_config()
|
||||
* sample: pointer to an array of len x 32 bits samples
|
||||
* Each 32 bits sample contains 2x16 bits samples,
|
||||
* one for the left channel and one for the right channel
|
||||
* len: length of sample in 32 bits words
|
||||
*/
|
||||
void i2s_write(const i2s_config_t *i2s_config,const int16_t *samples,const size_t len) {
|
||||
for(size_t i=0;i<len;i++) {
|
||||
for(size_t i=0;i<len;i+=2) {
|
||||
pio_sm_put_blocking(i2s_config->pio, i2s_config->sm, (uint32_t)samples[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Write samples to DMA buffer and initiate DMA transfer (non blocking)
|
||||
/**
|
||||
* Write samples to DMA buffer and initiate DMA transfer (non blocking)
|
||||
* i2s_config: I2S context obtained by i2s_get_default_config()
|
||||
* sample: pointer to an array of dma_trans_count x 32 bits samples
|
||||
*/
|
||||
void i2s_dma_write(i2s_config_t *i2s_config,const int16_t *samples) {
|
||||
// Wait the completion of the previous DMA transfer
|
||||
/* Wait the completion of the previous DMA transfer */
|
||||
dma_channel_wait_for_finish_blocking(i2s_config->dma_channel);
|
||||
// Copy samples into the DMA buffer
|
||||
memcpy(i2s_config->dma_buf,samples,i2s_config->dma_trans_count*sizeof(int32_t));
|
||||
// Initiate the DMA transfer
|
||||
/* Copy samples into the DMA buffer */
|
||||
if(i2s_config->volume==0) {
|
||||
memcpy(i2s_config->dma_buf,samples,i2s_config->dma_trans_count*sizeof(int32_t));
|
||||
} else {
|
||||
for(uint16_t i=0;i<i2s_config->dma_trans_count*2;i++) {
|
||||
i2s_config->dma_buf[i] = samples[i]>>i2s_config->volume;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initiate the DMA transfer */
|
||||
dma_channel_transfer_from_buffer_now(i2s_config->dma_channel,
|
||||
i2s_config->dma_buf,
|
||||
i2s_config->dma_trans_count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust the output volume
|
||||
* i2s_config: I2S context obtained by i2s_get_default_config()
|
||||
* volume: desired volume between 0 (highest. volume) and 16 (lowest volume)
|
||||
*/
|
||||
void i2s_volume(i2s_config_t *i2s_config,uint8_t volume) {
|
||||
if(volume>16) volume=16;
|
||||
i2s_config->volume=volume;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increases the output volume
|
||||
*/
|
||||
void i2s_increase_volume(i2s_config_t *i2s_config) {
|
||||
if(i2s_config->volume>0) {
|
||||
i2s_config->volume--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decreases the output volume
|
||||
*/
|
||||
void i2s_decrease_volume(i2s_config_t *i2s_config) {
|
||||
if(i2s_config->volume<16) {
|
||||
i2s_config->volume++;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user