⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 finalproject.c

📁 ipod 车载控制源码和协议
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ECE 476 Final Project
* Austin S. Lu & Albert Ren
* asl45 awr8
*/

#include <mega32.h>
#include <stdio.h>
#include <stdlib.h> //for ltoa
#include <delay.h>
#asm
    .equ __lcd_port=0x15
#endasm
#include <lcd.h>

//Bruce's definitions
#define begin {
#define end   }

//Define the states for the state machine
#define Command 0
#define DecodeCommand 1
#define Send 2
#define button_release 3
#define hold 4
#define Receive 5
int state = 0;

//Define the commands we support
//MODE 2 iPod Remote Functions
#define play 0x01
#define volup 0x02
#define voldown 0x04
#define skipfwd 0x08
#define skipback 0x10
#define menu 0x40
#define select 0x80

//MODE 4 Advanced Remote
#define type 0x12
#define name 0x14
#define current 0x1e
#define title 0x20
#define artist 0x22
#define album 0x24

//MODE 4 Send Commands
#define Switch 0
#define GetTrack 1
#define UseTrack 2
#define SwitchtoMode2 3
#define SendPlay 4

//Information on the Apple Accessory Protocol can be found at
// http://ipodlinux.org/Apple_Accessory_Protocol

//Here are some variables that we'll need
char mstime = 0;
char header1 = 0xff;
char header2 = 0x55;
char length;
char mode=0x02;
char command[2];
int checksum;
int index = 0;
int debouncecounter = 0;
char lastpress = 0;
char press = 0;
int timeout = 0;
unsigned long currentsong;
int param_length = 0;

//Here are the flags we're using
char validcommand = 0;
char commandtype = 0;
char stopflag = 0;
char releaseflag = 0;
char transmitdone_flag = 0;
char mode4flag = 0;
unsigned char switchmode[16] = {0xff, 0x55, 0x03, 0x00, 0x01, 0x04, 0xF8, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char switchback[16] = {0xff, 0x55, 0x03, 0x00, 0x01, 0x02, 0xFA, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char currenttrackcommand[16] = {0xff, 0x55, 0x03, 0x04, 0x00, 0x1E, 0xDB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
int tempchecksum;
unsigned char t_buffer_temp[16];


//For LCD displays
unsigned char lcdbuffer[50];
unsigned int lcdbufferlength = 16;
unsigned int lcdstart = 0;
int lcdtime = 0;

char hold_timer = 0;
int timeoutcounter = 0;
int failurecount = 0;
int mode4sequence = 0;

//variables we use for transmitting
unsigned char t_index;  //current string index
unsigned char t_buffer[16];	//output string
unsigned char t_ready;  //flag for transmit done
unsigned char t_char;  //current character

//RXC ISR variables
unsigned char r_index=0;  //current string index
unsigned char r_buffer[128];	//input string
unsigned char r_ready;  //flag for receive done
unsigned char r_char;  //current character
unsigned char r_checksum; //received checksum
unsigned char prev_char = 0;
unsigned char start_checksum = 0;
unsigned char r_length = 0xF5;

//Functions we use
void initialize(void);
void puts_int(void);
void buttons (void);
void gets_int(void);
void lcd_scroll(void);

//timer 0 overflow ISR
interrupt [TIM0_COMP] void timer0_overflow(void)
begin
    mstime++;
    lcdtime ++;
end

//UART xmit-empty ISR
//TRANSMITS LSB FIRST (Little Endian is stupid!)
//http://en.wikipedia.org/wiki/Serial_port
interrupt [USART_DRE] void uart_send(void)
{
	t_index++;
    t_char = t_buffer[t_index];
    if(t_char == (char)checksum){//at this point, we know what the end is
        UDR = t_char;
        stopflag = 1;
        stopflag = 0;
        UCSRB.5=0; //kill isr
		t_ready=1; //transmit done
		checksum = 0;
    }
    else	{UDR = t_char;}     //send the char
}

//UART character-ready ISR
interrupt [USART_RXC] void uart_rec(void)
begin
		r_char=UDR;    //get a char
		//build the input string
		//iPod takes the form of 0xFF 0x55 Data Checksum
		//We are assuming idle high, so we should check for 0x55 instead
	if((r_char == (char)(r_checksum & 0xff)) && ((r_index-3)==r_length)) {
		r_ready=1;				   	//signal cmd processor
		UCSRB.7=0;   				//stop rec ISR
        start_checksum = 0;
    }

    if(start_checksum == 1) {
    	r_checksum = r_checksum - r_char;
    }

    if(r_char == 0x55 && prev_char == 0xff) {
    	start_checksum = 1;
        r_checksum = 0x100;
    }

    r_buffer[r_index]=r_char;
    if(r_index == 2) //Make the length so!
    	r_length = r_buffer[r_index];

    r_index++;
	prev_char = r_char;

end

void main(void)
begin
    int k, temp, ReturnToSender;
    unsigned char songnumber;
//State machine updates every ms for now
    initialize();

    while(1)
    begin
        if(lcdtime >= 300)
        {
            lcdtime = 0;
            lcd_scroll();
        }
        if(mstime)
        begin

            buttons();
            mstime = 0;
            switch (state)
            begin
                case(Command):

                //check if there's a command. If so, we will decode it
                mode4sequence = Switch;
                timeoutcounter = 0;
                failurecount = 0;
                if(validcommand == 1)
                begin
                    validcommand = 0;
                    state = DecodeCommand;
                end
                if((releaseflag == 1) && (validcommand == 0) && (mode == 0x02)) //the button was released
                begin
                	releaseflag = 0;
                    state = button_release;
                end
                break;

                case(DecodeCommand):
	                //We must decode the command! If statements galore!
	                t_buffer[0] = header1; //0xff
	                t_buffer[1] = header2; //0x55
                    if((mode == 0x02) || (commandtype == current))
                    {
                       length = 0x03;
                    }
                    else
                    begin
                        length = 7; //Otherwise length is 7 bytes, cause it's a mode 4 command
                    end
	                t_buffer[2] = length;
	                t_buffer[3] = mode;
                    if(mode == 0x04)
                    {
                       mode4flag = 1;
                    }
	                t_buffer[4] = 0x00; //Beginning of command
	                if(commandtype == play)
	                    t_buffer[5] = play;
	                if(commandtype == volup)
	                    t_buffer[5] = volup;
	                if(commandtype == voldown)
	                    t_buffer[5] = voldown;
	                if(commandtype == skipfwd)
	                    t_buffer[5] = skipfwd;
	                if(commandtype == skipback)
	                    t_buffer[5] = skipback;
	                if(commandtype == album)
	                   t_buffer[5] = album;
	                if(commandtype == title)
	                   t_buffer[5] = title;
                    if (commandtype == artist)
	                   t_buffer[5] = artist;

	               if((mode == 0x04) && (commandtype != current)) //We need to send ipod the current song
	               begin
	                   t_buffer[6] = (currentsong >> 24) & 0xff ; //& with 0xFF cause we're cautious people!
	                   t_buffer[7] = (currentsong >> 16) & 0xff;
	                   t_buffer[8] = (currentsong >> 8) & 0xff;
	                   t_buffer[9] = currentsong & 0xff;
	                   param_length = 4; //Mode 4 and Mode 2 have different lengths
	               end
	                for (index = 2; index < 6 + param_length; index ++) { //for checksum
	                    checksum = checksum + t_buffer[index];

	                }

	                checksum = (0x100 - checksum & 0xff);
	                t_buffer[6+param_length] = (char) checksum & 0xff; //as a char */
	                param_length = 0; //We always reset to Mode 2 commands
	                state = Send;
                break;

                case(Send):
	                stopflag = 0;
	                timeoutcounter = 0;

	                if (mode == 0x02)
	                begin
						puts_int();
						commandtype = 0;
						state = Command;
	                end

                    //Otherwise, the command is going to depend on
                    //switching the iPod into Mode 4 zone
                    //So, first we switch
                    else
                    begin
                    	//Switch to Mode 4
                        if((mode4sequence == Switch))
                        begin
                           for(k=0; k<16; k++)
                           begin
                                //t_buffer_temp holds original mode4 command
                                t_buffer_temp[k] = t_buffer[k];
                                t_buffer[k] = switchmode[k];
                           end
                           tempchecksum = checksum;
                           checksum = 0xF8; //Mode switching checksum
                           //Now send the sucker
                           stopflag = 0;
                           puts_int();
                           state = Receive; //Now we receive a response
                        end

                        //Now we gotta get the current song
                        if(mode4sequence == GetTrack)
                        begin
                           for(k = 0; k<16; k++)
                           begin
                               //Put in the current command!
                               t_buffer[k] = currenttrackcommand[k];
                           end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -