audio commit
This commit is contained in:
@@ -14,7 +14,8 @@ board = blackpill_f411ce
|
|||||||
framework = arduino
|
framework = arduino
|
||||||
upload_protocol = stlink
|
upload_protocol = stlink
|
||||||
debug_tool = stlink
|
debug_tool = stlink
|
||||||
lib_deps = stm32duino/STM32duino STM32SD@^1.2.3
|
lib_deps =
|
||||||
|
;stm32duino/STM32duino STM32SD@^1.2.3
|
||||||
build_flags =
|
build_flags =
|
||||||
-D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC
|
-D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC
|
||||||
-D PIO_FRAMEWORK_ARDUINO_USB_FULLSPEED_FULLMODE
|
-D PIO_FRAMEWORK_ARDUINO_USB_FULLSPEED_FULLMODE
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ This example uses the SPI3 port tested on STM32F407VET "black" board. On other b
|
|||||||
I2S_HandleTypeDef hi2s3;
|
I2S_HandleTypeDef hi2s3;
|
||||||
DMA_HandleTypeDef hdma_spi3_tx;
|
DMA_HandleTypeDef hdma_spi3_tx;
|
||||||
uint32_t dma_buffer[I2S_BUFFER_SIZE];
|
uint32_t dma_buffer[I2S_BUFFER_SIZE];
|
||||||
|
//int16_t sine[WAV_SIZE] = {0};
|
||||||
// sinus oszillator
|
// sinus oszillator
|
||||||
float osc_phi = 0;
|
float osc_phi = 0;
|
||||||
float osc_phi_inc = 440.0f / 44100.0f; // generating 440HZ
|
float osc_phi_inc = 440.0f / 44100.0f; // generating 440HZ
|
||||||
@@ -37,6 +38,16 @@ void Error_Handler2(byte errorcode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void generateSine(int32_t amplitude, int16_t *buffer, uint16_t length)
|
||||||
|
{
|
||||||
|
// Generate a sine wave signal with the provided amplitude and store it in
|
||||||
|
// the provided buffer of size length.
|
||||||
|
for (int i = 0; i < length; ++i)
|
||||||
|
{
|
||||||
|
buffer[i] = int16_t(float(amplitude) * sin(2.0 * PI * (1.0 / length) * i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FillBuffer(uint32_t *buffer, uint16_t len)
|
void FillBuffer(uint32_t *buffer, uint16_t len)
|
||||||
{
|
{
|
||||||
float a;
|
float a;
|
||||||
@@ -62,11 +73,13 @@ void StartAudioBuffers(I2S_HandleTypeDef *hi2s)
|
|||||||
// start circular dma
|
// start circular dma
|
||||||
HAL_I2S_Transmit_DMA(hi2s, (uint16_t *)dma_buffer, I2S_BUFFER_SIZE << 1);
|
HAL_I2S_Transmit_DMA(hi2s, (uint16_t *)dma_buffer, I2S_BUFFER_SIZE << 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
|
extern "C" void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
|
||||||
{
|
{
|
||||||
// second half finished, filling it up again while first half is playing
|
// second half finished, filling it up again while first half is playing
|
||||||
FillBuffer(&(dma_buffer[I2S_BUFFER_SIZE >> 1]), I2S_BUFFER_SIZE >> 1);
|
FillBuffer(&(dma_buffer[I2S_BUFFER_SIZE >> 1]), I2S_BUFFER_SIZE >> 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
|
extern "C" void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
|
||||||
{
|
{
|
||||||
// first half finished, filling it up again while second half is playing
|
// first half finished, filling it up again while second half is playing
|
||||||
@@ -180,15 +193,10 @@ extern "C" void HAL_MspInit(void) // maybe useful, not included in this example
|
|||||||
/* SysTick_IRQn interrupt configuration */
|
/* SysTick_IRQn interrupt configuration */
|
||||||
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
|
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
|
||||||
}
|
}
|
||||||
// void initAudio(void)
|
|
||||||
// {
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void handleAudio(void)
|
|
||||||
// {
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
void initAudio()
|
void initAudio()
|
||||||
{
|
{
|
||||||
@@ -197,15 +205,43 @@ void initAudio()
|
|||||||
MX_DMA_Init();
|
MX_DMA_Init();
|
||||||
MX_I2S3_Init();
|
MX_I2S3_Init();
|
||||||
pinMode(LED_BUILTIN, OUTPUT);
|
pinMode(LED_BUILTIN, OUTPUT);
|
||||||
|
pinMode(PIN_I2S_SDMODE, OUTPUT);
|
||||||
|
digitalWrite(PIN_I2S_SDMODE, HIGH);
|
||||||
digitalWrite(LED_BUILTIN, 0);
|
digitalWrite(LED_BUILTIN, 0);
|
||||||
StartAudioBuffers(&hi2s3);
|
StartAudioBuffers(&hi2s3);
|
||||||
digitalWrite(LED_BUILTIN, 1);
|
digitalWrite(LED_BUILTIN, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#define PI 3.14159265358979323846
|
||||||
|
#define TAU (2.0 * PI)
|
||||||
|
|
||||||
void handleAudio()
|
void handleAudio()
|
||||||
{
|
{
|
||||||
// just a dummy code in loop, audio out is generated by ISR
|
// just a dummy code in loop, audio out is generated by ISR
|
||||||
digitalWrite(LED_BUILTIN, 1);
|
digitalWrite(LED_BUILTIN, 1);
|
||||||
delay(250);
|
delay(250);
|
||||||
|
//HAL_I2S_Transmit(&hi2s3,&sine,WAV_SIZE,1000);
|
||||||
|
HAL_StatusTypeDef res;
|
||||||
|
int16_t signal[46876];
|
||||||
|
int nsamples = sizeof(signal) / sizeof(signal[0]);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while(i < nsamples) {
|
||||||
|
double t = ((double)i/2.0)/((double)nsamples);
|
||||||
|
signal[i] = 32767*sin(100.0 * TAU * t); // left
|
||||||
|
signal[i+1] = signal[i]; // right
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
res = HAL_I2S_Transmit(&hi2s3, (uint16_t*)signal, nsamples, HAL_MAX_DELAY);
|
||||||
|
if(res != HAL_OK) {
|
||||||
|
Serial.printf("I2S - ERROR, res = %d!\r\n", res);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
digitalWrite(LED_BUILTIN, 0);
|
digitalWrite(LED_BUILTIN, 0);
|
||||||
delay(250);
|
delay(250);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3,5 +3,31 @@
|
|||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
|
|
||||||
|
#define SAMPLERATE_HZ 44100 // The sample rate of the audio. Higher sample rates have better fidelity,
|
||||||
|
// but these tones are so simple it won't make a difference. 44.1khz is
|
||||||
|
// standard CD quality sound.
|
||||||
|
|
||||||
|
#define AMPLITUDE ((1<<29)-1) // Set the amplitude of generated waveforms. This controls how loud
|
||||||
|
// the signals are, and can be any value from 0 to 2**31 - 1. Start with
|
||||||
|
// a low value to prevent damaging speakers!
|
||||||
|
|
||||||
|
#define WAV_SIZE 256 // The size of each generated waveform. The larger the size the higher
|
||||||
|
// quality the signal. A size of 256 is more than enough for these simple
|
||||||
|
// waveforms.
|
||||||
|
|
||||||
|
|
||||||
|
// Define the frequency of music notes (from http://www.phy.mtu.edu/~suits/notefreqs.html):
|
||||||
|
#define C4_HZ 261.63
|
||||||
|
#define D4_HZ 293.66
|
||||||
|
#define E4_HZ 329.63
|
||||||
|
#define F4_HZ 349.23
|
||||||
|
#define G4_HZ 392.00
|
||||||
|
#define A4_HZ 440.00
|
||||||
|
#define B4_HZ 493.88
|
||||||
|
|
||||||
|
// Define a C-major scale to play all the notes up and down.
|
||||||
|
float scale[] = { C4_HZ, D4_HZ, E4_HZ, F4_HZ, G4_HZ, A4_HZ, B4_HZ, A4_HZ, G4_HZ, F4_HZ, E4_HZ, D4_HZ, C4_HZ };
|
||||||
|
|
||||||
|
|
||||||
void initAudio(void);
|
void initAudio(void);
|
||||||
void handleAudio(void);
|
void handleAudio(void);
|
||||||
|
|||||||
@@ -4,4 +4,5 @@
|
|||||||
// #define PIN_I2S_FS PB12 /* I2S4_WS, Frame Sync (LRclock)
|
// #define PIN_I2S_FS PB12 /* I2S4_WS, Frame Sync (LRclock)
|
||||||
// #define PIN_I2S_SCK PB13 /* I2S4_CLK, serial Clock */
|
// #define PIN_I2S_SCK PB13 /* I2S4_CLK, serial Clock */
|
||||||
// #define PIN_I2S_SD PA1 /* I2S4_SD, Serial Data */
|
// #define PIN_I2S_SD PA1 /* I2S4_SD, Serial Data */
|
||||||
// #define PIN_I2S_SDMODE PA13 /* DAC_SDMODE, SDmode HIGH = enabled (left channel), LOW = shutdown */
|
#define PIN_I2S_SDMODE PA13 /* DAC_SDMODE, SDmode HIGH = enabled (left channel), LOW = shutdown */
|
||||||
|
|
||||||
|
|||||||
@@ -1,73 +1,73 @@
|
|||||||
#include "storage.h"
|
#include "storage.h"
|
||||||
|
|
||||||
Sd2Card card;
|
// Sd2Card card;
|
||||||
SdFatFs fatFs;
|
// SdFatFs fatFs;
|
||||||
|
|
||||||
void initStorage(void)
|
void initStorage(void)
|
||||||
{
|
{
|
||||||
bool disp = false;
|
// bool disp = false;
|
||||||
// Open serial communications and wait for port to open:
|
// // Open serial communications and wait for port to open:
|
||||||
Serial.begin(9600);
|
// Serial.begin(9600);
|
||||||
|
|
||||||
while (!Serial);
|
// while (!Serial);
|
||||||
Serial.print("\nInitializing SD card...");
|
// Serial.print("\nInitializing SD card...");
|
||||||
while(!card.init(SD_DETECT_PIN)) {
|
// while(!card.init(SD_DETECT_PIN)) {
|
||||||
if (!disp) {
|
// if (!disp) {
|
||||||
Serial.println("initialization failed. Is a card inserted?");
|
// Serial.println("initialization failed. Is a card inserted?");
|
||||||
disp = true;
|
// disp = true;
|
||||||
}
|
// }
|
||||||
delay(10);
|
// delay(10);
|
||||||
}
|
// }
|
||||||
|
|
||||||
Serial.println("A card is present.");
|
// Serial.println("A card is present.");
|
||||||
|
|
||||||
// print the type of card
|
// // print the type of card
|
||||||
Serial.print("\nCard type: ");
|
// Serial.print("\nCard type: ");
|
||||||
switch (card.type()) {
|
// switch (card.type()) {
|
||||||
case SD_CARD_TYPE_SD1:
|
// case SD_CARD_TYPE_SD1:
|
||||||
Serial.println("SD1");
|
// Serial.println("SD1");
|
||||||
break;
|
// break;
|
||||||
case SD_CARD_TYPE_SD2:
|
// case SD_CARD_TYPE_SD2:
|
||||||
Serial.println("SD2");
|
// Serial.println("SD2");
|
||||||
break;
|
// break;
|
||||||
case SD_CARD_TYPE_SDHC:
|
// case SD_CARD_TYPE_SDHC:
|
||||||
Serial.println("SDHC");
|
// Serial.println("SDHC");
|
||||||
break;
|
// break;
|
||||||
default:
|
// default:
|
||||||
Serial.println("Unknown");
|
// Serial.println("Unknown");
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
|
// // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
|
||||||
if (!fatFs.init()) {
|
// if (!fatFs.init()) {
|
||||||
Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
|
// Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// print the type and size of the first FAT-type volume
|
// // print the type and size of the first FAT-type volume
|
||||||
uint64_t volumesize;
|
// uint64_t volumesize;
|
||||||
Serial.print("\nVolume type is FAT");
|
// Serial.print("\nVolume type is FAT");
|
||||||
Serial.println(fatFs.fatType(), DEC);
|
// Serial.println(fatFs.fatType(), DEC);
|
||||||
Serial.println();
|
// Serial.println();
|
||||||
|
|
||||||
volumesize = fatFs.blocksPerCluster(); // clusters are collections of blocks
|
// volumesize = fatFs.blocksPerCluster(); // clusters are collections of blocks
|
||||||
volumesize *= fatFs.clusterCount(); // we'll have a lot of clusters
|
// volumesize *= fatFs.clusterCount(); // we'll have a lot of clusters
|
||||||
volumesize *= 512; // SD card blocks are always 512 bytes
|
// volumesize *= 512; // SD card blocks are always 512 bytes
|
||||||
Serial.print("Volume size (bytes): ");
|
// Serial.print("Volume size (bytes): ");
|
||||||
Serial.println(volumesize);
|
// Serial.println(volumesize);
|
||||||
Serial.print("Volume size (Kbytes): ");
|
// Serial.print("Volume size (Kbytes): ");
|
||||||
volumesize /= 1024;
|
// volumesize /= 1024;
|
||||||
Serial.println(volumesize);
|
// Serial.println(volumesize);
|
||||||
Serial.print("Volume size (Mbytes): ");
|
// Serial.print("Volume size (Mbytes): ");
|
||||||
volumesize /= 1024;
|
// volumesize /= 1024;
|
||||||
Serial.println(volumesize);
|
// Serial.println(volumesize);
|
||||||
|
|
||||||
|
|
||||||
Serial.println("\nFiles found on the card (name, date and size in bytes): ");
|
// Serial.println("\nFiles found on the card (name, date and size in bytes): ");
|
||||||
File root = SD.openRoot();
|
// File root = SD.openRoot();
|
||||||
|
|
||||||
// list all files in the card with date and size
|
// // list all files in the card with date and size
|
||||||
root.ls(LS_R | LS_DATE | LS_SIZE);
|
// root.ls(LS_R | LS_DATE | LS_SIZE);
|
||||||
Serial.println("###### End of the SD tests ######");
|
// Serial.println("###### End of the SD tests ######");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleStorage(void) {
|
void handleStorage(void) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// include the SD library:
|
// include the SD library:
|
||||||
#include <STM32SD.h>
|
//#include <STM32SD.h>
|
||||||
|
|
||||||
// If SD card slot has no detect pin then define it as SD_DETECT_NONE
|
// If SD card slot has no detect pin then define it as SD_DETECT_NONE
|
||||||
// to ignore it. One other option is to call 'card.init()' without parameter.
|
// to ignore it. One other option is to call 'card.init()' without parameter.
|
||||||
|
|||||||
Reference in New Issue
Block a user