IIS
Signal frequency setting
IIS (Inter-IC Sound) was developed by Philips and is a commonly used audio device interface, mainly used for CD, MD, MP3 and other devices.
S3C2440 has a total of 5 pins for IIS: IISDO, IISDI, IISSCLK, IISLRCK and CDCLK. The first two pins are used for the output and input of digital audio signals, and the other three pins are related to the frequency of the audio signal. It can be seen that to use IIS well, the signal frequency must be set correctly.
IISSCLK is a serial clock, and each clock signal transmits one bit of audio signal. Therefore, the frequency of IISSCLK = number of channels × sampling frequency × number of sampling bits. For example, if the sampling frequency fs is 44.1kHz, the number of sampling bits is 16 bits, and the number of channels is 2 (left and right channels), then the frequency of IISSCLK = 32fs = 1411.2kHz.
1. Fs 2. Number of sampling bits 3. Number of channels
View using wav data extractor
Sampling frequency
Right click the music file --> Properties --> Details
PCLK (50,000,000) is processed by two prescalers to obtain IISSCLK, IISLRCK and CDCLK respectively. Register IISPSR is the IIS prescaler register, bits 5 to 9 are prescaler A, bits 0 to 4 are prescaler B. Generally speaking, the values N of these two prescalers are equal, that is, as long as one is known, the other is also known. Here we calculate the value N of prescaler B through CDCLK, that is, CDCLK = PCLK / (N + 1).
I set the main clock frequency to 384fs. From the table below, since fs=44.1kHZ, CDCLK=16.9344, we know that N=2.
//The prescaler is 2, so CDCLK=PCLK/(2+1)=16.66666kHz (the closer to 16.9344 in the table, the better)
rIISPSR = 2<<5|2;
IIS Configuration
//Configure IIS interface
rGPEUP = rGPEUP & ~(0x1f) | 0x1f; //Pull-up is invalid, GPE[4:0] 1 1111
rGPECON = rGPECON & ~(0x3ff) | 0x2aa;
//Configure IIS registers for s3c2440
//The prescaler is 2, so CDCLK=PCLK/(2+1)=16.66666kHz
rIISPSR = 2<<5|2;
//Invalid DMA, input idle, prescaler valid, turn on IIS
rIISCON = (0<<5)|(0<<4)|(0<<3)|(1<<2)|(1<<1);
//PCLK is the clock source, output mode, IIS mode, 16 bits per channel, CODECLK=384fs, SCLK=32fs
rIISMOD = (0<<9)|(0<<8)|(2<<6)|(0<<5)|(0<<4)|(1<<3)|(1<<2)|(1<<0);
rIISFCON = (0<<15)|(1<<13); //Output FIFO normal mode, output FIFO enable
UDA1341
In my opinion, IIS is to send audio (WAV) data of a certain size to FIFO or DMA at a certain frequency, and UDA1341 is to convert these audio data into electrical signals and send them out through the audio interface. The configuration of uda1341 is for reference.
//Simulate L3 bus to write data through io port
//mode: 1 is address mode, 0 is data mode
//Please refer to the data sheet for address mode, data mode and transmission timing
static void write_UA1341(U8 data, U8 address)
{
int i,j;
if(address == 1) {
rGPBDAT = rGPBDAT&(~(L3D | L3M | L3C)) | L3C; //Address mode, according to the manual, L3M is LOW, L3C is high
} else {
rGPBDAT = rGPBDAT & (~(L3D |L3M |L3C)) |(L3M|L3C); //Data mode L3M is high
}
Delay(1);
//transfer data
for(i=0;i<8;i++)
{
if(data & 0x1) // H
{
rGPBDAT &= ~L3C; //L3C=L
rGPBDAT |= L3D; //L3D=H
for(j=0;j<5;j++)
; //Wait for a while
rGPBDAT |= L3C; //L3C=H
rGPBDAT |= L3D; //L3D=H
for(j=0;j<5;j++)
; //Wait for a while
}
else // L
{
rGPBDAT &= ~L3C; //L3C=L
rGPBDAT &= ~L3D; //L3D=L
for(j=0;j<5;j++)
; //Wait for a while
rGPBDAT |= L3C; //L3C=H
rGPBDAT &= ~L3D; //L3D=L
for(j=0;j<5;j++)
; //Wait for a while
}
data >>= 1;
}
rGPBDAT = rGPBDAT & ~(L3D | L3M | L3C) | (L3C | L3M); //L3M=H,L3C=H
UDA1341 initialization
// UDA1341 initialization
//Configure L3 interface bus, GPB2:L3MODE, GPB3:L3DATA, GPB4:L3CLOCK
rGPBCON = 0x015550; //output
rGPBUP = 0x7ff; //Pull-up is invalid
rGPBDAT = 0x1e4;
rGPBDAT = rGPBDAT & (~(L3M |L3C |L3D)) |(L3M|L3C); //Set L3CLOCK and L3MODE high to prepare for transmission
////According to the operation sequence in page 14 of the UDA1341TS data sheet, first in address mode,
//Select operation address 000101xx +10(STATUS)=0X16
write_UA1341(0x16,1);
write_UA1341(0x60,0); // 0, 1, 10, 000, 0 reset
write_UA1341(0x16,1);
write_UA1341(0x10,0); //0,0,01, 000,0 : status 0, 384fs, IIS, no DC-filtering
write_UA1341(0x16,1);
write_UA1341(0xc1,0); //1,0,0,0, 0,0,01: status 1,
//Gain of DAC 6 dB,Gain of ADC 0dB,ADC non-inverting,
//DAC non-inverting, Single speed playback, ADC-Off DAC-On
Interface material
Production of WAV audio files
1. Download lossless music from the Internet (I downloaded WAV and APE formats)
2. Open Format Factory → Audio → WAV → Add File → Capture a clip (lossless music is too large, so you need to capture a small part, 20 seconds per song will be enough) → OK → Output Configuration (as shown below) → OK → Click Start.
3. Open the captured WAV folder
4. Use DataToHex to convert the WAV file into an audio data array file, and modify the array file name Array[].
5. Change the wav audio data file to a c file. Please do not change it to h, otherwise debugging will take a long time.
6. Production is complete!
Main logic blocks
buffer=music1; //Initialize buffer to point to music1 music array address
while(1){
if(flag==1){ rIISCON |= 0x1; //If you click play (flag==1) to turn on IIS song_num1 initial value is 1 to play the first song
//Process the display of music pictures when clicking to play (flag1=1 when clicking to play)
if(flag1==1 && song_num==1 ){flag1=0, Pait_Bmp( 70, 70, 100, 100, music1_bmp);}
if(flag1==1 && song_num==2 ){flag1=0, Pait_Bmp( 70, 70, 100, 100, music2_bmp);}
if(flag1==1 && song_num==3 ){flag1=0, Pait_Bmp( 70, 70, 100, 100, music3_bmp);}
// When the music flag song_num1 is not zero (song_num1 is assigned a value after the song is played or song_num1 is assigned a value through a key value (previous/next song))
// buffer music playback address is initialized length music length is reassigned and music picture is displayed next FIFO byte position count is initialized song_num1 is reset to zero
if(song_num1==1) { buffer=music1; length=3704572; count=0; Pait_Bmp( 70, 70, 100, 100, music1_bmp); song_num1=0;}
if(song_num1==2) { buffer=music2; length=3704552; count=0; Pait_Bmp( 70, 70, 100, 100, music2_bmp); song_num1=0;}
if(song_num1==3) { buffer=music3; length=5644880; count=0; Pait_Bmp( 70, 70, 100, 100, music3_bmp); song_num1=0;}
if((rIISCON & (1<<7))==0) //Check if the output FIFO is empty
{ //The data in FIFO is 16 bits and the depth is 32
//When the output FIFO is empty, write 32 16-bit data to the FIFO at one time
for(i=0;i<32;i++){
//rIISFIFO=(buffer[i+count]);
rIISFIFO=(buffer[2*i+count])+(buffer[2*i+1+count]<<8); // Store 16 bits of data in FIFO in one cycle
}
count+=64;
// 64 is 32 loops, each loop points to the sum of two different bytes
//After the music is finished playing, the music flag song_num1 points to the next song
if(count>length){
song_num2=song_num2+1;
if(song_num2==4){song_num2=1;}
song_num1=song_num2;
}
}
}
//Close IIS when paused to display the welcome picture
if(flag==0) { rIISCON |= 0x0; Pait_Bmp( 70, 70, 100, 100, hellomusic); } //Close IIS;
}
Main code
Main.c
#define GLOBAL_CLK 1
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h" //Function declaration
#include "2440slib.h"
#include "mmu.h"
#include "profile.h"
// Function declaration
extern void music_player(void);
void Main(void)
{
U32 mpll_val = 0,consoleNum;
Port_Init();
mpll_val = (92<<12)|(1<<4)|(1);
//init FCLK=400M,
ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);
ChangeClockDivider(14, 12); //the result of rCLKDIVN [0:1:0:1] 3-0 bit
cal_cpu_bus_clk(); //HCLK=100M PCLK=50M
consoleNum = 0; // Uart 0 select for debug.
Uart_Init( 0,115200 );
Uart_Select(consoleNum);
Port_Init();
MMU_Init(); //Address mapping initialization
Beep(2000, 100);
music_player();
}
music_player.c
/***********************************
Implementing the function music player
***************************************/
#include "2440lib.h"
#include "2440slib.h"
#include "LCD_init.h"
#include "2440addr.h"
#define L3C (1<<4) //gpb4:L3CLOCK
#define L3D (1<<3) //gpb3:L3DATA
#define L3M (1<<2) //gpb2:L3MODE
#define rIISFIFO (*(volatile unsigned long*)0x55000010)
extern unsigned char music_interface[];
extern unsigned char hellomusic[]; //hellomusic
extern unsigned char music1_bmp[];
extern unsigned char music2_bmp[];
extern unsigned char music3_bmp[];
extern unsigned char button1[]; //Pause
extern unsigned char button1_1[];
extern unsigned char button2[]; //Next song
extern unsigned char button2_2[];
extern unsigned char button3[]; //Previous song
extern unsigned char button3_3[];
Previous article:Mini2440 bare metal test - IIC controls EEPROM data transmission
Next article:Mini2440 bare metal test - Uart and PC to achieve file and character transmission
Recommended ReadingLatest update time:2024-11-23 19:18
- Popular Resources
- Popular amplifiers
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- The first! National Automotive Chip Quality Inspection Center established
- BYD releases self-developed automotive chip using 4nm process, with a running score of up to 1.15 million
- GEODNET launches GEO-PULSE, a car GPS navigation device
- Should Chinese car companies develop their own high-computing chips?
- Infineon and Siemens combine embedded automotive software platform with microcontrollers to provide the necessary functions for next-generation SDVs
- Continental launches invisible biometric sensor display to monitor passengers' vital signs
- SHT31 Evaluation + Temperature and Humidity Accuracy
- Netizens dismantle a 1968 US military computer
- pyboardCN V2 Issue 2
- 【GD32F350 LogicKids】Basic peripheral drivers
- [ST NUCLEO-H743ZI Review] + 5. CAN communication transceiver test
- Request resume
- MicroPython Hands-on (30) - Blynk for the Internet of Things
- Schematic resource help
- Is there a ESP8266 microPython library for dht20?
- EEWORLD University ---- DC / DC switching regulator packaging innovation