|
//sta013.c #include <mega128.h> #include "mp3data.h" #ifndef begin #define begin { #define end } #endif //prototypes void STA013_Write(unsigned char address, unsigned char data);//writes via I2C void STA013_Audio_Stop(void);//sends stop playing comand void STA013_Show_Info(void);//displays contents of the registers void STA013_Test_Serial_Interface(void) begin //test the SCKR, SDI and DATA_REQ lines unsigned char c,sdi,sckr,data_req; unsigned char tmpstr[BUF_SIZE],tmpinstr[BUF_SIZE]; c=0; sdi=0; sckr=0; while(c!='q') begin sdi=sdi^0x01; sckr=sckr^0x01; SDI=sdi; SCKR=sckr; data_req = DATA_REQ; if (sdi==0x01) begin while(OUT_RDY==0);S_Printf("Setting sdi to 1\n\r"); end if (sckr==0x01) begin while(OUT_RDY==0);S_Printf("Setting sckr to 1\n\r"); end if (data_req==0x01) begin while(OUT_RDY==0);S_Printf("data_req = 1\n\r"); end else begin if (data_req==0x00) begin while(OUT_RDY==0);S_Printf("data_req = 0\n\r"); end else begin sprintf(tmpstr,"data_req %x\n\r",data_req); while(OUT_RDY==0);S_Print(tmpstr); end end while(OUT_RDY==0); S_Printf("Press q <enter> to quit"); while(OUT_RDY==0); S_Printf(",<enter> to continue\n\r"); while(!IN_RDY); S_In(tmpinstr); c = tmpinstr[0]; end end void STA013_Audio_Send(unsigned char data) begin unsigned char i; //using a for loop now, might be faster to use 7 copies for (i=0;i<8;i++) begin if ((data & 0x80)==0x80) begin//send 1 SDI = 1; SCKR = 1; end else begin//send 0 SDI = 0; SCKR = 1; end data = data << 1; //now send a negative edge and STA013 will sample SDI SCKR = 0;//negative edge /* #asm//slow things down a bit nop nop #endasm */ end//for i end void STA013_Audio_Stop(void) begin STA013_Write(PLAY,0x00); delay_us(5); STA013_Write(RUN,0x00);//not sure whether this is needed yet S_Printf("Stopped play\n\r"); end void STA013_Play_MP3(void) begin unsigned int i = 0; //need to tell STA013 to start playing via I2C //send RUN(0x72) = 0x01, STA013 goes into decode state //send PLAY(0x13) = 0x01 and MUTE(0x14) = 0x00; //S_Printf("Writing run\n\r"); STA013_Write(0x72,0x01); //S_Printf("Writing play\n\r"); STA013_Write(0x13,0x01); //S_Printf("Writing mute\n\r"); STA013_Write(0x14,0x00); //DATA_REQ should go high while(1) begin if (DATA_REQ) begin//send the next byte of mp3 data //S_Printf("DATA_REQ\n\r"); STA013_Audio_Send(mp3data[i++]); end /* else //debug, see if DATA_REQ ever goes low begin while(!OUT_RDY); S_Printf("data req low\n\r"); end */ if (i==MP3_Data_Size) //out of data begin STA013_Audio_Stop(); while(OUT_RDY==0); S_Printf("Beacuse out of data\n\r"); //STA013_Show_Info();//for debug break; end; end end //play from the serial input buffer void STA013_Play_Buffer(void) begin //S_Printf("Writing run\n\r"); STA013_Write(0x72,0x01); //S_Printf("Writing play\n\r"); STA013_Write(0x13,0x01); //S_Printf("Writing mute\n\r"); STA013_Write(0x14,0x00); //DATA_REQ should go high while(dataheadptr!=BUF_END_ADD -1);//let buffer fill up lcd_gotoxy(0,0); lcd_putsf("MP3 Playback st "); while(SERIAL_MODE=Xmode) begin if (DATA_REQ)//STA requests data begin STA013_Audio_Send(*mp3ptr); if (mp3ptr+1<BUF_END_ADD) begin while(mp3ptr+1 == dataheadptr)PORTE = ~(0x05);//PORTE = PORTE&0xfe;//buffer under-run, wait for more data mp3ptr++; end else begin//need to wrap around to the start while(dataheadptr==BUF_START_ADD)PORTE=~(0x06); //PORTE = PORTE&0xfe;//under-run,led0 on mp3ptr=BUF_START_ADD; end //debug //PORTE=PORTE|0x01;//turn off led 0 end end STA013_Audio_Stop(); lcd_gotoxy(0,0);lcd_putsf("MP3 End "); end void STA013_HW_Reset(void) begin //Setup PORTD for the data transmission DDRD = DDRD | (1<<7) | (1<<6);//7,6 used for output, SDI, SCKR PORTD = 0x00;//set all to zero, as well as turn off pull up for PORTD.5 DATA_REQ //don't think I need to use the pull up, need to check this though //set !reset output DDRF = DDRF | 0x80; #ifdef showerror if ((DDRF&0x80)!=0x80) begin S_Printf("Err setting DDRF\n\r"); end #endif PORTF = PORTF & 0x7f;//reset delay_ms(500U); PORTF = PORTF | 0x80;//reset off #ifdef showerror if ((PORTF&0x80)!=0x80) begin S_Printf("Err setting PORTF\n\r"); end #endif delay_ms(1000U); end void STA013_Current_Add_Read(void) begin unsigned char data = 0, status, tmpstr[BUF_SIZE]; #ifdef verbose S_Printf("Cur_Add_R Send start cond\n\r"); #endif I2C_START;//send start condition I2C_WAIT;//wait until start conditition transmitted status = TWSR&0xf8; if (status!=TWI_START) begin #ifdef verbose S_Printf("Start failed\n\r"); sprintf(tmpstr,"Status=%x\n\r",status); S_Print(tmpstr); #endif end S_Printf("Start condition transmitted\n\r"); TWDR = STA_WRITE;//I2C slave address I2C_TRANSMIT;//TWCR = (1<<TWINT)|(1<<TWEN);//start transmission of address I2C_WAIT;//wait until STA_READ has been transmitted and ACK recieved status = TWSR&0xf8; if (status != MR_ADD_ACK) begin S_Printf("I2C no ack write\n\r"); sprintf(tmpstr,"Status=%x\n\r",status); S_Print(tmpstr); end //respond with TWINT TWEA return an acknowledge, table 88 status = TWSR&0xf8; sprintf(tmpstr,"Status=%x\n\r",status); S_Print(tmpstr); S_Printf("rdy to ack data\n\r"); //TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN);//must remember to always set TWEN when I want to do I2C //recieve and not ack TWCR = (1<<TWINT)|(1<<TWEN); I2C_WAIT;//is this neccesary? think so status = TWSR&0xf8; sprintf(tmpstr,"Status=%x\n\r",status); S_Print(tmpstr); while(OUT_RDY==0); S_Outf("transmit complete\n\r"); //I2C_READ;//clear TWINT flag /* status = TWSR&0xf8; while(status!=MR_DATA_ACK){status = TWSR&0xf8;};//see whether status can become MR_DATA_ACK while(OUT_RDY==0); S_Outf("DATA ACK!\n\r"); */ I2C_WAIT; if (status != MR_DATA_ACK) begin S_Printf("I2C no data recieved\n\r"); sprintf(tmpstr,"Status=%x\n\r",status); S_Print(tmpstr); end data = TWDR; sprintf(tmpstr,"Data = %x\n\r",data); S_Print(tmpstr); S_Printf("Send stop\n\r"); I2C_STOP; S_Printf("Send stop successful\n\r"); end /* Start Condition Send A Byte The value is 0x86 (134). The seven most significant bits instruct the STA013 to listen (because there may be other chips connected to SDA and SCL). The LSB is clear, telling the STA013 that will will be writing an address. Send A Byte The value is the address where we need to read data. The main program will pass the address to our sta013_read function. Stop Condition Start Condition Send A Byte The value is 0x87 (135). Again, the upper bits select the STA013, and the LSB sets up the next access to read. Receive A Byte Read the byte from the STA013. This will be returned to the main program. Stop Condition */ unsigned char STA013_Read(unsigned char address) begin unsigned char data, tmpstr[BUF_SIZE]; data = 0; I2C_START; I2C_WAIT; if ((TWSR&0xf8)!=TWI_START) begin if (SERIAL_MODE==Nmode) S_Printf("read fail start 1\n\r"); end TWDR = STA_READ; I2C_TRANSMIT; I2C_WAIT; if ((TWSR&0xf8)!=MT_ADD_ACK) begin if (SERIAL_MODE==Nmode) S_Printf("STA013 not on I2C bus\n\r"); end TWDR = address; I2C_TRANSMIT; I2C_WAIT; if ((TWSR&0xf8)!=MT_DATA_ACK) begin if (SERIAL_MODE==Nmode) S_Printf("data not ack\n\r"); end I2C_STOP; delay_us(100); I2C_START; I2C_WAIT; if ((TWSR&0xf8)!=TWI_START) begin if (SERIAL_MODE==Nmode) S_Printf("fail start 2\n\r"); end TWDR = STA_WRITE; I2C_TRANSMIT; I2C_WAIT; //sprintf(tmpstr,"1.status = %x\n\r", TWSR&0xf8); //S_Print(tmpstr); if ((TWSR&0xf8)!=MR_ADD_ACK) begin if (SERIAL_MODE==Nmode) S_Printf("STA013 not on I2C bus\n\r"); end TWCR = (1<<TWINT)|(1<<TWEN); I2C_WAIT; //sprintf(tmpstr,"2.status = %x\n\r",TWSR&0xf8); //S_Print(tmpstr); if ((TWSR&0xf8)!=MR_DATA_NO_ACK) begin if (SERIAL_MODE==Nmode) S_Printf("err data not rcved!\n\r"); end data = TWDR; I2C_STOP; delay_us(4);//must have some interval between I2C cmds //sprintf(tmpstr, "data read %x\n\r", data); //S_Print(tmpstr); return data; end void STA013_Write(unsigned char address, unsigned char data) begin unsigned char tmpstr[BUF_SIZE]; I2C_START; I2C_WAIT; if ((TWSR&0xf8)!=TWI_START) begin if (SERIAL_MODE==Nmode) S_Printf("unable to start write\n\r"); end TWDR = STA_READ; I2C_TRANSMIT; I2C_WAIT; if ((TWSR&0xf8)!=MT_ADD_ACK) begin if (SERIAL_MODE==Nmode) S_Printf("STA013 not on I2C bus\n\r"); end TWDR = address; I2C_TRANSMIT; I2C_WAIT; if ((TWSR&0xf8)!=MT_DATA_ACK) begin if (SERIAL_MODE==Nmode) S_Printf("data not ack 1\n\r"); end TWDR = data; I2C_TRANSMIT; I2C_WAIT; if ((TWSR&0xf8)!=MT_DATA_ACK) begin if (SERIAL_MODE==Nmode) S_Printf("data not ack 2\n\r"); end I2C_STOP; delay_us(4); end //reads the STA013 configuration data from eeprom void Read_Eeprom(void) begin unsigned char eeprom *conf_data_ptr = STA_CONFIG_ADDR; unsigned char address,//stores the address of the reg to write to data;//stores the value to write unsigned int i; i=0; address = conf_data_ptr[i++]; data = conf_data_ptr[i++]; while((address!=0)|(data!=0))//the last item is 0,0 begin #asm nop nop nop nop #endasm//delay between writes STA013_Write(address,data); address = conf_data_ptr[i++]; data = conf_data_ptr[i++]; end end void STA013_Init(void) begin unsigned char data; //I2C initialization //set clock rate for I2C //SCL freq = CPU CLK/(16 + 2(TWBR)*4^TWPS) //TWPS - prescalar set to 0 //for SCL = 100kHz, TWBR = 72 TWBR = 72; STA013_HW_Reset(); data = STA013_Read(0x01); if (data==0xac) begin S_Printf("STA013 found\n\r"); end else begin S_Printf("STA013 not found\n\r"); end Read_Eeprom(); end void Display_Reg(unsigned char address, unsigned char flash regname[]) begin unsigned char data, tmpstr[BUF_SIZE]; data = STA013_Read(address); sprintf(tmpstr," [%d] = %d\n\r",address,data); while(!OUT_RDY); S_Printf(regname); while(!OUT_RDY); S_Print(tmpstr); end void STA013_Show_Info(void) begin while(!OUT_RDY);S_Printf("Volume settings\n\r"); Display_Reg(DLA,"DLA"); Display_Reg(DLB,"DLB"); Display_Reg(DRA,"DRA"); Display_Reg(DRB,"DRB"); Display_Reg(MFSFDF_411,"MFSFDF"); Display_Reg(PLLFRAC_411_L,"PLLFRAC_411_L"); Display_Reg(PLLFRAC_411_R,"PLLFRAC_411_R"); Display_Reg(PCMCONF,"PCMCONF"); Display_Reg(MSFDF_X,"MSFDF_X"); Display_Reg(DAC_CLK_MODE,"DAC_CLK_MODE"); Display_Reg(PLLFRAC_L,"PLLFRAC_L"); Display_Reg(PLLFRAC_H,"PLLFRAC_H"); Display_Reg(PLLCTRL,"PLLCTRL"); Display_Reg(ERROR_CODE,"ERROR_CODE"); Display_Reg(7,"Reg 7");//should be 0 by ConfigPLL from STmicro Display_Reg(6,"Reg 6");//should be 12 Display_Reg(PLAY,"PLAY"); Display_Reg(MUTE,"MUTE"); Display_Reg(84,"PCMDIVIDER"); Display_Reg(DATA_REQ_ENABLE,"DATA_REQ_ENABLE"); Display_Reg(0x0c,"REQ_POL"); Display_Reg(RUN,"RUN"); pause(); end |
|