Skip to content

Instantly share code, notes, and snippets.

@benjcal
Created October 15, 2025 20:45
Show Gist options
  • Save benjcal/96245e499e456cf1dc1b79560dad6b29 to your computer and use it in GitHub Desktop.
Save benjcal/96245e499e456cf1dc1b79560dad6b29 to your computer and use it in GitHub Desktop.
audio experiment
#include <string.h>
#include <libopencm3/stm32/rcc.h>
#include "arm_sin_f32.h"
#include "gpio.h"
#include "i2s.h"
#include "usb.h"
static void setup_clocks(void)
{
rcc_clock_setup_pll(&rcc_hse_12mhz_3v3[RCC_CLOCK_3V3_168MHZ]);
}
const gpio_pin led_status = {
.gp_port = GPIOA,
.gp_pin = GPIO15,
.gp_mode = GPIO_MODE_OUTPUT,
.gp_level = 0
};
const i2s_config i2s3 = {
.i2s_instance = SPI3,
.i2s_pll_n = 369,
.i2s_pll_r = 2,
.i2s_div = 7,
.i2s_mode = I2S_MODE_MASTER_TX,
.i2s_std = I2S_STD_PHILIPS,
.i2s_mclk_mode = I2S_MCLK_ENABLED,
.i2s_data_format = I2S_FORMAT_16,
.i2s_pins = {
{
.gp_port = GPIOA,
.gp_pin = GPIO4,
.gp_mode = GPIO_MODE_AF,
.gp_af = GPIO_AF6,
},
{
.gp_port = GPIOB,
.gp_pin = GPIO3,
.gp_mode = GPIO_MODE_AF,
.gp_af = GPIO_AF6,
},
{
.gp_port = GPIOB,
.gp_pin = GPIO5,
.gp_mode = GPIO_MODE_AF,
.gp_af = GPIO_AF6,
},
{
.gp_port = GPIOC,
.gp_pin = GPIO7,
.gp_mode = GPIO_MODE_AF,
.gp_af = GPIO_AF6,
},
},
};
int main(void)
{
setup_clocks();
i2s_init(&i2s3);
gpio_init_pin(&led_status);
gpio_pin_set(&led_status);
setup_usb();
#define SAMPLE_RATE 48000
float f = 1000; // sine frequency
int amplitude = 0x7FFF;
int n = 0;
while (1) {
if (i2s_is_ready(&i2s3)) {
int16_t sample = i2s_next_is_right(&i2s3) ? 0xCAFE : (int)(amplitude * arm_sin_f32(2.0 * PI * f * n++ / SAMPLE_RATE));
i2s_send_sample(&i2s3, sample);
}
/* USB echo */
if (usb_data_available()) {
char buf[64] = { 0 };
usb_read_data(buf, 64);
switch (buf[0]) {
case '\r':
strncpy(buf, "\n\r", 64);
break;
case 0x7f:
strncpy(buf, "\b \b", 64);
break;
default:
break;
}
usb_send(buf, strlen(buf));
}
usb_poll();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment