mirror of
https://github.com/halleysfifthinc/AVCLAN-Mockingboard.git
synced 2026-08-07 01:13:18 +00:00
Move source files into src dir
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
Copyright (C) 2006 Marcin Slonicki <marcin@softservice.com.pl>.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
this file is a part of the TOYOTA Corolla MP3 Player Project
|
||||
-----------------------------------------------------------------------
|
||||
http://www.softservice.com.pl/corolla/avc
|
||||
|
||||
May 28 / 2009 - version 2
|
||||
|
||||
*/
|
||||
|
||||
#include "GlobalDef.h"
|
||||
|
||||
// max 10 events in fifo
|
||||
// uint8_t EventCount;
|
||||
// uint8_t EventCmd[10];
|
||||
uint8_t Event;
|
||||
|
||||
uint8_t showLog;
|
||||
uint8_t showLog2;
|
||||
@@ -0,0 +1,50 @@
|
||||
/*--------------------------------------------------------------------------------------------------
|
||||
|
||||
Name : GlobalDef.h
|
||||
|
||||
Description : Global definitions.
|
||||
|
||||
History : 2004/04/06 - Created by Louis Frigon.
|
||||
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
#ifndef _GLOBALDEF_H_
|
||||
#define _GLOBALDEF_H_
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE (!FALSE)
|
||||
|
||||
// AVC LAN bus on AC2 (PA6/7)
|
||||
// PA6 AINP0 +
|
||||
// PA7 AINN1 -
|
||||
#define INPUT_IS_SET (bit_is_set(AC2_STATUS, AC_STATE_bp))
|
||||
#define INPUT_IS_CLEAR (bit_is_clear(AC2_STATUS, AC_STATE_bp))
|
||||
|
||||
#define sbi(port, bit) (port) |= (1 << (bit)) // Set bit (i.e. to 1)
|
||||
#define cbi(port, bit) (port) &= ~(1 << (bit)) // Clear bit (i.e. set bit to 0)
|
||||
|
||||
// // max 10 events in fifo
|
||||
// extern uint8_t EventCount;
|
||||
// extern uint8_t EventCmd[10];
|
||||
extern uint8_t Event;
|
||||
|
||||
#define EV_NOTHING 0
|
||||
#define EV_DISPLAY 1
|
||||
#define EV_STATUS 4
|
||||
|
||||
// // const
|
||||
// #define smYear 1
|
||||
// #define smMonth 2
|
||||
// #define smDay 3
|
||||
// #define smHour 4
|
||||
// #define smMin 5
|
||||
// #define smWDay 6
|
||||
|
||||
// #define STOPEvent cbi(TIMSK, TOIE1); cbi(UCSRB, RXCIE);
|
||||
// #define STARTEvent sbi(TIMSK, TOIE1); sbi(UCSRB, RXCIE);
|
||||
|
||||
extern uint8_t showLog;
|
||||
extern uint8_t showLog2;
|
||||
|
||||
#endif // _GLOBALDEF_H_
|
||||
+996
@@ -0,0 +1,996 @@
|
||||
/*
|
||||
Copyright (C) 2015 Allen Hill <allenofthehills@gmail.com>.
|
||||
|
||||
Portions of the following source code are:
|
||||
Copyright (C) 2006 Marcin Slonicki <marcin@softservice.com.pl>.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
this file is a part of the TOYOTA Corolla MP3 Player Project
|
||||
-----------------------------------------------------------------------
|
||||
http://www.softservice.com.pl/corolla/avc
|
||||
|
||||
May 28 / 2009 - version 2
|
||||
|
||||
*/
|
||||
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "GlobalDef.h"
|
||||
#include "avclandrv.h"
|
||||
#include "com232.h"
|
||||
|
||||
#define AVC_OUT_EN() \
|
||||
cbi(AC2_CTRLA, AC_ENABLE_bp); \
|
||||
sbi(VPORTA_DIR, 6); // Write mode
|
||||
#define AVC_OUT_DIS() \
|
||||
cbi(VPORTA_DIR, 6); \
|
||||
sbi(AC2_CTRLA, AC_ENABLE_bp); // Read mode
|
||||
#define AVC_SET_LOGICAL_1() \
|
||||
__asm__ __volatile__( \
|
||||
"sbi %[vporta_out], 6;" ::[vporta_out] "I"(_SFR_IO_ADDR(VPORTA_OUT)));
|
||||
#define AVC_SET_LOGICAL_0() \
|
||||
__asm__ __volatile__( \
|
||||
"cbi %[vporta_out], 6;" ::[vporta_out] "I"(_SFR_IO_ADDR(VPORTA_OUT)));
|
||||
|
||||
uint8_t CD_ID_1;
|
||||
uint8_t CD_ID_2;
|
||||
|
||||
uint8_t HU_ID_1;
|
||||
uint8_t HU_ID_2;
|
||||
|
||||
uint8_t parity_bit;
|
||||
|
||||
uint8_t repeatMode;
|
||||
uint8_t randomMode;
|
||||
|
||||
uint8_t playMode;
|
||||
|
||||
uint8_t cd_Disc;
|
||||
uint8_t cd_Track;
|
||||
uint8_t cd_Time_Min;
|
||||
uint8_t cd_Time_Sec;
|
||||
|
||||
uint8_t answerReq;
|
||||
|
||||
cd_modes CD_Mode;
|
||||
|
||||
uint8_t broadcast;
|
||||
uint8_t master1;
|
||||
uint8_t master2;
|
||||
uint8_t slave1;
|
||||
uint8_t slave2;
|
||||
uint8_t message_len;
|
||||
uint8_t message[MAXMSGLEN];
|
||||
|
||||
uint8_t data_control;
|
||||
uint8_t data_len;
|
||||
uint8_t data[MAXMSGLEN];
|
||||
|
||||
// we need check answer (to avclan check) timeout
|
||||
// when is more then 1 min, FORCE answer.
|
||||
uint8_t check_timeout;
|
||||
|
||||
#define SW_ID 0x11 // 11 For my stereo
|
||||
|
||||
// commands
|
||||
const uint8_t stat1[] = {0x4, 0x00, 0x00, 0x01, 0x0A};
|
||||
const uint8_t stat2[] = {0x4, 0x00, 0x00, 0x01, 0x08};
|
||||
const uint8_t stat3[] = {0x4, 0x00, 0x00, 0x01, 0x0D};
|
||||
const uint8_t stat4[] = {0x4, 0x00, 0x00, 0x01, 0x0C};
|
||||
|
||||
// broadcast
|
||||
const uint8_t lan_stat1[] = {0x3, 0x00, 0x01, 0x0A};
|
||||
const uint8_t lan_reg[] = {0x3, SW_ID, 0x01, 0x00};
|
||||
const uint8_t lan_init[] = {0x3, SW_ID, 0x01, 0x01};
|
||||
const uint8_t lan_check[] = {0x3, SW_ID, 0x01, 0x20};
|
||||
const uint8_t lan_playit[] = {0x4, SW_ID, 0x01, 0x45, 0x63};
|
||||
|
||||
const uint8_t play_req1[] = {0x4, 0x00, 0x25, 0x63, 0x80};
|
||||
|
||||
#ifdef __AVENSIS__
|
||||
const uint8_t play_req2[] = {0x6, 0x00, SW_ID, 0x63, 0x42};
|
||||
#else
|
||||
const uint8_t play_req2[] = {0x6, 0x00, SW_ID, 0x63, 0x42, 0x01, 0x00};
|
||||
#endif
|
||||
|
||||
const uint8_t play_req3[] = {0x5, 0x00, SW_ID, 0x63, 0x42, 0x41};
|
||||
const uint8_t stop_req[] = {0x5, 0x00, SW_ID, 0x63, 0x43, 0x01};
|
||||
const uint8_t stop_req2[] = {0x5, 0x00, SW_ID, 0x63, 0x43, 0x41};
|
||||
|
||||
// answers
|
||||
const uint8_t CMD_REGISTER[] = {0x1, 0x05, 0x00, 0x01, SW_ID, 0x10, 0x63};
|
||||
const uint8_t CMD_STATUS1[] = {0x1, 0x04, 0x00, 0x01, 0x00, 0x1A};
|
||||
const uint8_t CMD_STATUS2[] = {0x1, 0x04, 0x00, 0x01, 0x00, 0x18};
|
||||
const uint8_t CMD_STATUS3[] = {0x1, 0x04, 0x00, 0x01, 0x00, 0x1D};
|
||||
const uint8_t CMD_STATUS4[] = {0x1, 0x05, 0x00, 0x01, 0x00, 0x1C, 0x00};
|
||||
uint8_t CMD_CHECK[] = {0x1, 0x06, 0x00, 0x01, SW_ID, 0x30, 0x00, 0x00};
|
||||
|
||||
const uint8_t CMD_STATUS5[] = {0x1, 0x05, 0x00, 0x5C, 0x12, 0x53, 0x02};
|
||||
const uint8_t CMD_STATUS5A[] = {0x0, 0x05, 0x5C, 0x31, 0xF1, 0x00, 0x00};
|
||||
|
||||
const uint8_t CMD_STATUS6[] = {0x1, 0x06, 0x00, 0x5C, 0x32, 0xF0, 0x02, 0x00};
|
||||
|
||||
const uint8_t CMD_PLAY_OK1[] = {0x1, 0x05, 0x00, 0x63, SW_ID, 0x50, 0x01};
|
||||
const uint8_t CMD_PLAY_OK2[] = {0x1, 0x05, 0x00, 0x63, SW_ID, 0x52, 0x01};
|
||||
const uint8_t CMD_PLAY_OK3[] = {0x0, 0x0B, 0x63, 0x31, 0xF1, 0x01, 0x00,
|
||||
0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x80};
|
||||
uint8_t CMD_PLAY_OK4[] = {0x0, 0x0B, 0x63, 0x31, 0xF1, 0x01, 0x28,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x80};
|
||||
|
||||
const uint8_t CMD_STOP1[] = {0x1, 0x05, 0x00, 0x63, SW_ID, 0x53, 0x01};
|
||||
uint8_t CMD_STOP2[] = {0x0, 0x0B, 0x63, 0x31, 0xF1, 0x00, 0x30,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x80};
|
||||
|
||||
const uint8_t CMD_BEEP[] = {0x1, 0x05, 0x00, 0x63, 0x29, 0x60, 0x02};
|
||||
|
||||
void AVC_HoldLine() {
|
||||
STOPEvent;
|
||||
|
||||
// wait for free line
|
||||
uint8_t line_busy = 1;
|
||||
|
||||
TCB1.CNT = 0;
|
||||
do {
|
||||
while (INPUT_IS_CLEAR) {
|
||||
/* The comparison value was originally 25 with CK64 (tick period
|
||||
of 4.34 us) at a clock frequency 14.7456MHz. For a more accurate tick
|
||||
period of .5 us at 16MHz, the value should be approximately 225*/
|
||||
if (TCB1.CNT >= 900)
|
||||
break;
|
||||
}
|
||||
if (TCB1.CNT > 864)
|
||||
line_busy = 0;
|
||||
} while (line_busy);
|
||||
|
||||
// switch to out mode
|
||||
AVC_OUT_EN();
|
||||
AVC_SET_LOGICAL_1();
|
||||
|
||||
STARTEvent;
|
||||
}
|
||||
|
||||
void AVC_ReleaseLine() {
|
||||
AVC_SET_LOGICAL_0();
|
||||
AVC_OUT_DIS();
|
||||
}
|
||||
|
||||
void AVCLan_Init() {
|
||||
PORTA.PIN6CTRL = PORT_ISC_INPUT_DISABLE_gc; // Disable input buffer;
|
||||
PORTA.PIN7CTRL = PORT_ISC_INPUT_DISABLE_gc; // recommended when using AC
|
||||
|
||||
// Pull-ups are disabled by default
|
||||
VPORTA.DIR &= ~(PIN6_bm | PIN7_bm); // Zero pin 6 and 7 to set as input
|
||||
|
||||
// Analog comparator
|
||||
AC2.CTRLA = AC_OUTEN_bm | AC_HYSMODE_25mV_gc | AC_ENABLE_bm;
|
||||
|
||||
TCB1.CTRLB = TCB_ASYNC_bm | TCB_CNTMODE_SINGLE_gc;
|
||||
TCB1.EVCTRL = TCB_CAPTEI_bm;
|
||||
TCB1.INTCTRL = TCB_CAPT_bm;
|
||||
EVSYS.ASYNCUSER0 = EVSYS_ASYNCUSER0_ASYNCCH0_gc;
|
||||
TCB1.CTRLA = TCB_CLKSEL_CLKDIV2_gc | TCB_ENABLE_bm;
|
||||
|
||||
message_len = 0;
|
||||
answerReq = cmNull;
|
||||
check_timeout = 0;
|
||||
|
||||
cd_Disc = 1;
|
||||
cd_Track = 1;
|
||||
cd_Time_Min = 0;
|
||||
cd_Time_Sec = 0;
|
||||
repeatMode = 0;
|
||||
randomMode = 0;
|
||||
playMode = 0;
|
||||
CD_Mode = stStop;
|
||||
}
|
||||
|
||||
uint8_t AVCLan_Read_uint8_t(uint8_t length) {
|
||||
uint8_t bite = 0;
|
||||
|
||||
while (1) {
|
||||
while (INPUT_IS_CLEAR) {}
|
||||
TCB1.CNT = 0;
|
||||
while (INPUT_IS_SET) {} // If input was set for less than 26 us
|
||||
if (TCB1.CNT < 208) { // (a generous half period), bit was a 1
|
||||
bite++;
|
||||
parity_bit++;
|
||||
}
|
||||
length--;
|
||||
if (!length)
|
||||
return bite;
|
||||
bite = bite << 1;
|
||||
}
|
||||
}
|
||||
|
||||
void set_AVC_logic_for(uint8_t val, uint16_t period) {
|
||||
if (val == 1) {
|
||||
AVC_SET_LOGICAL_1();
|
||||
} else {
|
||||
AVC_SET_LOGICAL_0();
|
||||
}
|
||||
TCB1.CCMP = period;
|
||||
EVSYS.ASYNCSTROBE = EVSYS_ASYNCCH00_bm;
|
||||
loop_until_bit_is_set(TCB1_INTFLAGS, 0);
|
||||
TCB1_INTFLAGS = 1;
|
||||
}
|
||||
|
||||
uint8_t AVCLan_Send_StartBit() {
|
||||
set_AVC_logic_for(1, 1328); // 166 us @ 125 ns tick (for F_CPU = 16MHz)
|
||||
set_AVC_logic_for(0, 152); // 19 us @ 125 ns tick (for F_CPU = 16MHz)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void AVCLan_Send_Bit1() {
|
||||
set_AVC_logic_for(1, 164); // 20.5 us @ 125 ns tick (for F_CPU = 16MHz)
|
||||
set_AVC_logic_for(0, 152); // 19 us @ 125 ns tick (for F_CPU = 16MHz)
|
||||
}
|
||||
|
||||
void AVCLan_Send_Bit0() {
|
||||
set_AVC_logic_for(1, 272); // 34 us @ 125 ns tick (for F_CPU = 16MHz)
|
||||
set_AVC_logic_for(0, 44); // 5.5 us @ 125 ns tick (for F_CPU = 16MHz)
|
||||
}
|
||||
|
||||
uint8_t AVCLan_Read_ACK() {
|
||||
set_AVC_logic_for(1, 152); // 34 us @ 125 ns tick (for F_CPU = 16MHz)
|
||||
AVC_SET_LOGICAL_0(); // Replace with AVC_ReleaseLine?
|
||||
AVC_OUT_DIS(); // switch to read mode
|
||||
|
||||
TCB1.CNT = 0;
|
||||
while (1) {
|
||||
if (INPUT_IS_SET && (TCB1.CNT > 208))
|
||||
break; // Make sure INPUT is not still set from us
|
||||
// Line of experimentation: Try changing TCNT0 comparison value or remove
|
||||
// check entirely
|
||||
if (TCB1.CNT > 300)
|
||||
return 1; // Not sure if this fix is intent correct
|
||||
}
|
||||
|
||||
while (INPUT_IS_SET) {}
|
||||
AVC_OUT_EN(); // back to write mode
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t AVCLan_Send_ACK() {
|
||||
TCB1.CNT = 0;
|
||||
while (INPUT_IS_CLEAR) {
|
||||
if (TCB1.CNT >= 900)
|
||||
return 0; // max wait time
|
||||
}
|
||||
|
||||
AVC_OUT_EN();
|
||||
|
||||
set_AVC_logic_for(1, 272); // 34 us @ 125 ns tick (for F_CPU = 16MHz)
|
||||
set_AVC_logic_for(0, 44); // 5.5 us @ 125 ns tick (for F_CPU = 16MHz)
|
||||
|
||||
AVC_OUT_DIS();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t AVCLan_Send_uint8_t(uint8_t bite, uint8_t len) {
|
||||
uint8_t b;
|
||||
if (len == 8) {
|
||||
b = bite;
|
||||
} else {
|
||||
b = bite << (8 - len);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if ((b & 128) != 0) {
|
||||
AVCLan_Send_Bit1();
|
||||
parity_bit++;
|
||||
} else {
|
||||
AVCLan_Send_Bit0();
|
||||
}
|
||||
len--;
|
||||
if (!len) {
|
||||
// if (INPUT_IS_SET) RS232_Print("SBER\n"); // Send Bit ERror
|
||||
return 1;
|
||||
}
|
||||
b = b << 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t AVCLan_Send_ParityBit() {
|
||||
if ((parity_bit & 1) != 0) {
|
||||
AVCLan_Send_Bit1();
|
||||
// parity_bit++;
|
||||
} else {
|
||||
AVCLan_Send_Bit0();
|
||||
}
|
||||
parity_bit = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t CheckCmd(uint8_t *cmd) {
|
||||
uint8_t i;
|
||||
uint8_t *c;
|
||||
uint8_t l;
|
||||
|
||||
c = cmd;
|
||||
l = *c++;
|
||||
|
||||
for (i = 0; i < l; i++) {
|
||||
if (message[i] != *c)
|
||||
return 0;
|
||||
c++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t AVCLan_Read_Message() {
|
||||
STOPEvent; // disable timer1 interrupt
|
||||
|
||||
uint8_t i;
|
||||
uint8_t for_me = 0;
|
||||
|
||||
// RS232_Print("$ ");
|
||||
// TCCR1B |= (1 << CS11)|(1 << CS10); // Timer1 prescaler at 64
|
||||
// TCNT1 = 0;
|
||||
// TCNT0 = 0;
|
||||
// while (INPUT_IS_SET) {
|
||||
// if ( TCNT0 > 255 ) { // 170 us
|
||||
// // TCCR1B = 0;
|
||||
// // TCCR1B |= (1 << WGM12)|(1 << CS12); // Set CTC, prescaler at 256
|
||||
// STARTEvent;
|
||||
// RS232_Print("LAN>T1\n");
|
||||
// return 0;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if ( TCNT0 < 20 ) { // 20 us
|
||||
// // TCCR1B = 0;
|
||||
// // TCCR1B |= (1 << WGM12)|(1 << CS12);
|
||||
// STARTEvent;
|
||||
// RS232_Print("LAN>T2\n");
|
||||
// return 0;
|
||||
// }
|
||||
AVCLan_Read_uint8_t(1);
|
||||
|
||||
broadcast = AVCLan_Read_uint8_t(1);
|
||||
|
||||
parity_bit = 0;
|
||||
master1 = AVCLan_Read_uint8_t(4);
|
||||
master2 = AVCLan_Read_uint8_t(8);
|
||||
if ((parity_bit & 1) != AVCLan_Read_uint8_t(1)) {
|
||||
STARTEvent;
|
||||
return 0;
|
||||
}
|
||||
|
||||
parity_bit = 0;
|
||||
slave1 = AVCLan_Read_uint8_t(4);
|
||||
slave2 = AVCLan_Read_uint8_t(8);
|
||||
if ((parity_bit & 1) != AVCLan_Read_uint8_t(1)) {
|
||||
STARTEvent;
|
||||
return 0;
|
||||
}
|
||||
// is this command for me ?
|
||||
if ((slave1 == CD_ID_1) && (slave2 == CD_ID_2)) {
|
||||
for_me = 1;
|
||||
}
|
||||
|
||||
if (for_me)
|
||||
AVCLan_Send_ACK();
|
||||
else
|
||||
AVCLan_Read_uint8_t(1);
|
||||
|
||||
parity_bit = 0;
|
||||
AVCLan_Read_uint8_t(4); // control - always 0xF
|
||||
if ((parity_bit & 1) != AVCLan_Read_uint8_t(1)) {
|
||||
STARTEvent;
|
||||
return 0;
|
||||
}
|
||||
if (for_me)
|
||||
AVCLan_Send_ACK();
|
||||
else
|
||||
AVCLan_Read_uint8_t(1);
|
||||
|
||||
parity_bit = 0;
|
||||
message_len = AVCLan_Read_uint8_t(8);
|
||||
if ((parity_bit & 1) != AVCLan_Read_uint8_t(1)) {
|
||||
STARTEvent;
|
||||
return 0;
|
||||
}
|
||||
if (for_me)
|
||||
AVCLan_Send_ACK();
|
||||
else
|
||||
AVCLan_Read_uint8_t(1);
|
||||
|
||||
if (message_len > MAXMSGLEN) {
|
||||
// RS232_Print("LAN> Command error");
|
||||
STARTEvent;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < message_len; i++) {
|
||||
parity_bit = 0;
|
||||
message[i] = AVCLan_Read_uint8_t(8);
|
||||
if ((parity_bit & 1) != AVCLan_Read_uint8_t(1)) {
|
||||
STARTEvent;
|
||||
return 0;
|
||||
}
|
||||
if (for_me) {
|
||||
AVCLan_Send_ACK();
|
||||
} else {
|
||||
AVCLan_Read_uint8_t(1);
|
||||
}
|
||||
}
|
||||
|
||||
STARTEvent;
|
||||
|
||||
if (showLog)
|
||||
ShowInMessage();
|
||||
|
||||
if (for_me) {
|
||||
|
||||
if (CheckCmd((uint8_t *)stat1)) {
|
||||
answerReq = cmStatus1;
|
||||
return 1;
|
||||
}
|
||||
if (CheckCmd((uint8_t *)stat2)) {
|
||||
answerReq = cmStatus2;
|
||||
return 1;
|
||||
}
|
||||
if (CheckCmd((uint8_t *)stat3)) {
|
||||
answerReq = cmStatus3;
|
||||
return 1;
|
||||
}
|
||||
if (CheckCmd((uint8_t *)stat4)) {
|
||||
answerReq = cmStatus4;
|
||||
return 1;
|
||||
}
|
||||
// if (CheckCmd((uint8_t*)stat5)) { answerReq = cmStatus5; return 1; }
|
||||
|
||||
if (CheckCmd((uint8_t *)play_req1)) {
|
||||
answerReq = cmPlayReq1;
|
||||
return 1;
|
||||
}
|
||||
if (CheckCmd((uint8_t *)play_req2)) {
|
||||
answerReq = cmPlayReq2;
|
||||
return 1;
|
||||
}
|
||||
if (CheckCmd((uint8_t *)play_req3)) {
|
||||
answerReq = cmPlayReq3;
|
||||
return 1;
|
||||
}
|
||||
if (CheckCmd((uint8_t *)stop_req)) {
|
||||
answerReq = cmStopReq;
|
||||
return 1;
|
||||
}
|
||||
if (CheckCmd((uint8_t *)stop_req2)) {
|
||||
answerReq = cmStopReq2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
} else { // broadcast check
|
||||
|
||||
if (CheckCmd((uint8_t *)lan_playit)) {
|
||||
answerReq = cmPlayIt;
|
||||
return 1;
|
||||
}
|
||||
if (CheckCmd((uint8_t *)lan_check)) {
|
||||
answerReq = cmCheck;
|
||||
CMD_CHECK[6] = message[3];
|
||||
return 1;
|
||||
}
|
||||
if (CheckCmd((uint8_t *)lan_reg)) {
|
||||
answerReq = cmRegister;
|
||||
return 1;
|
||||
}
|
||||
if (CheckCmd((uint8_t *)lan_init)) {
|
||||
answerReq = cmInit;
|
||||
return 1;
|
||||
}
|
||||
if (CheckCmd((uint8_t *)lan_stat1)) {
|
||||
answerReq = cmStatus1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
answerReq = cmNull;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t AVCLan_SendData() {
|
||||
uint8_t i;
|
||||
|
||||
STOPEvent;
|
||||
|
||||
// wait for free line
|
||||
uint8_t line_busy = 1;
|
||||
|
||||
TCB1.CNT = 0;
|
||||
do {
|
||||
while (INPUT_IS_CLEAR) {
|
||||
if (TCB1.CNT >= 900)
|
||||
break;
|
||||
}
|
||||
if (TCB1.CNT > 864)
|
||||
line_busy = 0;
|
||||
} while (line_busy);
|
||||
|
||||
// switch to output mode
|
||||
AVC_OUT_EN();
|
||||
|
||||
AVCLan_Send_StartBit();
|
||||
AVCLan_Send_uint8_t(0x1, 1); // regular communication
|
||||
|
||||
parity_bit = 0;
|
||||
AVCLan_Send_uint8_t(CD_ID_1, 4); // CD Changer ID as master
|
||||
AVCLan_Send_uint8_t(CD_ID_2, 8);
|
||||
AVCLan_Send_ParityBit();
|
||||
|
||||
AVCLan_Send_uint8_t(HU_ID_1, 4); // HeadUnit ID as slave
|
||||
AVCLan_Send_uint8_t(HU_ID_2, 8);
|
||||
|
||||
AVCLan_Send_ParityBit();
|
||||
|
||||
if (AVCLan_Read_ACK()) {
|
||||
AVC_OUT_DIS();
|
||||
STARTEvent;
|
||||
RS232_Print("Error ACK 1 (Transmission ACK)\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
AVCLan_Send_uint8_t(0xF, 4); // 0xf - control -> COMMAND WRITE
|
||||
AVCLan_Send_ParityBit();
|
||||
if (AVCLan_Read_ACK()) {
|
||||
AVC_OUT_DIS();
|
||||
STARTEvent;
|
||||
RS232_Print("Error ACK 2 (COMMMAND WRITE)\n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
AVCLan_Send_uint8_t(data_len, 8); // data length
|
||||
AVCLan_Send_ParityBit();
|
||||
if (AVCLan_Read_ACK()) {
|
||||
AVC_OUT_DIS();
|
||||
STARTEvent;
|
||||
RS232_Print("Error ACK 3 (Data Length)\n");
|
||||
return 3;
|
||||
}
|
||||
|
||||
for (i = 0; i < data_len; i++) {
|
||||
AVCLan_Send_uint8_t(data[i], 8); // data uint8_t
|
||||
AVCLan_Send_ParityBit();
|
||||
if (AVCLan_Read_ACK()) {
|
||||
AVC_OUT_DIS();
|
||||
STARTEvent;
|
||||
RS232_Print("Error ACK 4 (Data uint8_t: ");
|
||||
RS232_PrintDec(i);
|
||||
RS232_Print(")\n");
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
// back to read mode
|
||||
AVC_OUT_DIS();
|
||||
|
||||
STARTEvent;
|
||||
if (showLog)
|
||||
ShowOutMessage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t AVCLan_SendDataBroadcast() {
|
||||
uint8_t i;
|
||||
|
||||
STOPEvent;
|
||||
|
||||
// wait for free line
|
||||
uint8_t line_busy = 1;
|
||||
|
||||
TCB1.CNT = 0;
|
||||
do {
|
||||
while (INPUT_IS_CLEAR) {
|
||||
if (TCB1.CNT >= 900)
|
||||
break;
|
||||
}
|
||||
if (TCB1.CNT > 864)
|
||||
line_busy = 0;
|
||||
} while (line_busy);
|
||||
|
||||
AVC_OUT_EN();
|
||||
|
||||
AVCLan_Send_StartBit();
|
||||
AVCLan_Send_uint8_t(0x0, 1); // broadcast
|
||||
|
||||
parity_bit = 0;
|
||||
AVCLan_Send_uint8_t(CD_ID_1, 4); // CD Changer ID as master
|
||||
AVCLan_Send_uint8_t(CD_ID_2, 8);
|
||||
AVCLan_Send_ParityBit();
|
||||
|
||||
AVCLan_Send_uint8_t(0x1, 4); // all audio devices
|
||||
AVCLan_Send_uint8_t(0xFF, 8);
|
||||
AVCLan_Send_ParityBit();
|
||||
AVCLan_Send_Bit1();
|
||||
|
||||
AVCLan_Send_uint8_t(0xF, 4); // 0xf - control -> COMMAND WRITE
|
||||
AVCLan_Send_ParityBit();
|
||||
AVCLan_Send_Bit1();
|
||||
|
||||
AVCLan_Send_uint8_t(data_len, 8); // data lenght
|
||||
AVCLan_Send_ParityBit();
|
||||
AVCLan_Send_Bit1();
|
||||
|
||||
for (i = 0; i < data_len; i++) {
|
||||
AVCLan_Send_uint8_t(data[i], 8); // data uint8_t
|
||||
AVCLan_Send_ParityBit();
|
||||
AVCLan_Send_Bit1();
|
||||
}
|
||||
|
||||
AVC_OUT_DIS();
|
||||
STARTEvent;
|
||||
if (showLog)
|
||||
ShowOutMessage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t AVCLan_SendAnswerFrame(uint8_t *cmd) {
|
||||
uint8_t i;
|
||||
uint8_t *c;
|
||||
uint8_t b;
|
||||
|
||||
c = cmd;
|
||||
|
||||
b = *c++;
|
||||
data_control = 0xF;
|
||||
data_len = *c++;
|
||||
for (i = 0; i < data_len; i++) {
|
||||
data[i] = *c++;
|
||||
}
|
||||
if (b)
|
||||
return AVCLan_SendData();
|
||||
else
|
||||
return AVCLan_SendDataBroadcast();
|
||||
}
|
||||
|
||||
uint8_t AVCLan_SendMyData(uint8_t *data_tmp, uint8_t s_len) {
|
||||
uint8_t i;
|
||||
uint8_t *c;
|
||||
|
||||
c = data_tmp;
|
||||
|
||||
data_control = 0xF;
|
||||
data_len = s_len;
|
||||
for (i = 0; i < data_len; i++) {
|
||||
data[i] = *c++;
|
||||
}
|
||||
return AVCLan_SendData();
|
||||
}
|
||||
|
||||
uint8_t AVCLan_SendMyDataBroadcast(uint8_t *data_tmp, uint8_t s_len) {
|
||||
uint8_t i;
|
||||
uint8_t *c;
|
||||
|
||||
c = data_tmp;
|
||||
|
||||
data_control = 0xF;
|
||||
data_len = s_len;
|
||||
for (i = 0; i < data_len; i++) {
|
||||
data[i] = *c++;
|
||||
}
|
||||
return AVCLan_SendDataBroadcast();
|
||||
}
|
||||
|
||||
uint8_t AVCLan_SendInitCommands() {
|
||||
uint8_t r;
|
||||
|
||||
const uint8_t c1[] = {0x0, 0x0B, 0x63, 0x31, 0xF1, 0x00, 0x80,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x80};
|
||||
const uint8_t c2[] = {0x0, 0x0A, 0x63, 0x31, 0xF3, 0x00,
|
||||
0x3F, 0x00, 0x00, 0x00, 0x00, 0x02};
|
||||
const uint8_t c3[] = {0x0, 0x0A, 0x63, 0x31, 0xF3, 0x00,
|
||||
0x3F, 0x00, 0x01, 0x00, 0x01, 0x02};
|
||||
const uint8_t c4[] = {0x0, 0x0A, 0x63, 0x31, 0xF3, 0x00,
|
||||
0x3D, 0x00, 0x01, 0x00, 0x01, 0x02};
|
||||
const uint8_t c5[] = {0x0, 0x0A, 0x63, 0x31, 0xF3, 0x00,
|
||||
0x39, 0x00, 0x01, 0x00, 0x01, 0x02};
|
||||
const uint8_t c6[] = {0x0, 0x0A, 0x63, 0x31, 0xF3, 0x00,
|
||||
0x31, 0x00, 0x01, 0x00, 0x01, 0x02};
|
||||
const uint8_t c7[] = {0x0, 0x0A, 0x63, 0x31, 0xF3, 0x00,
|
||||
0x21, 0x00, 0x01, 0x00, 0x01, 0x02};
|
||||
const uint8_t c8[] = {0x0, 0x0B, 0x63, 0x31, 0xF1, 0x00, 0x90,
|
||||
0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x80};
|
||||
const uint8_t c9[] = {0x0, 0x0A, 0x63, 0x31, 0xF3, 0x00,
|
||||
0x01, 0x00, 0x01, 0x00, 0x01, 0x02};
|
||||
const uint8_t cA[] = {0x0, 0x0B, 0x63, 0x31, 0xF1, 0x00, 0x30,
|
||||
0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x80};
|
||||
|
||||
r = AVCLan_SendAnswerFrame((uint8_t *)c1);
|
||||
if (!r)
|
||||
r = AVCLan_SendAnswerFrame((uint8_t *)c2);
|
||||
if (!r)
|
||||
r = AVCLan_SendAnswerFrame((uint8_t *)c3);
|
||||
if (!r)
|
||||
r = AVCLan_SendAnswerFrame((uint8_t *)c4);
|
||||
if (!r)
|
||||
r = AVCLan_SendAnswerFrame((uint8_t *)c5);
|
||||
if (!r)
|
||||
r = AVCLan_SendAnswerFrame((uint8_t *)c6);
|
||||
if (!r)
|
||||
r = AVCLan_SendAnswerFrame((uint8_t *)c7);
|
||||
if (!r)
|
||||
r = AVCLan_SendAnswerFrame((uint8_t *)c8);
|
||||
if (!r)
|
||||
r = AVCLan_SendAnswerFrame((uint8_t *)c9);
|
||||
if (!r)
|
||||
r = AVCLan_SendAnswerFrame((uint8_t *)cA);
|
||||
|
||||
// const uint8_t c1[] = { 0x0, 0x0B, 0x63, 0x31, 0xF1, 0x00, 0x80,
|
||||
// 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x80 }; r =
|
||||
// AVCLan_SendAnswerFrame((uint8_t*)c1);
|
||||
return r;
|
||||
}
|
||||
|
||||
void AVCLan_Send_Status() {
|
||||
// disc track t_min
|
||||
// t_sec
|
||||
uint8_t STATUS[] = {0x0, 0x0B, 0x63, 0x31, 0xF1, 0x01, 0x10,
|
||||
0x01, 0x01, 0x00, 0x00, 0x00, 0x80};
|
||||
|
||||
STATUS[7] = cd_Disc;
|
||||
STATUS[8] = cd_Track;
|
||||
STATUS[9] = cd_Time_Min;
|
||||
STATUS[10] = cd_Time_Sec;
|
||||
|
||||
STATUS[11] = 0;
|
||||
|
||||
AVCLan_SendAnswerFrame((uint8_t *)STATUS);
|
||||
}
|
||||
|
||||
uint8_t AVCLan_SendAnswer() {
|
||||
uint8_t r = 0;
|
||||
|
||||
switch (answerReq) {
|
||||
case cmStatus1:
|
||||
r = AVCLan_SendAnswerFrame((uint8_t *)CMD_STATUS1);
|
||||
break;
|
||||
case cmStatus2:
|
||||
r = AVCLan_SendAnswerFrame((uint8_t *)CMD_STATUS2);
|
||||
break;
|
||||
case cmStatus3:
|
||||
r = AVCLan_SendAnswerFrame((uint8_t *)CMD_STATUS3);
|
||||
break;
|
||||
case cmStatus4:
|
||||
r = AVCLan_SendAnswerFrame((uint8_t *)CMD_STATUS4);
|
||||
break;
|
||||
case cmRegister:
|
||||
r = AVCLan_SendAnswerFrame((uint8_t *)CMD_REGISTER);
|
||||
break;
|
||||
case cmInit: // RS232_Print("INIT\n");
|
||||
r = AVCLan_SendInitCommands();
|
||||
break;
|
||||
case cmCheck:
|
||||
r = AVCLan_SendAnswerFrame((uint8_t *)CMD_CHECK);
|
||||
check_timeout = 0;
|
||||
CMD_CHECK[6]++;
|
||||
RS232_Print("AVCCHK\n");
|
||||
break;
|
||||
case cmPlayReq1:
|
||||
playMode = 0;
|
||||
r = AVCLan_SendAnswerFrame((uint8_t *)CMD_PLAY_OK1);
|
||||
break;
|
||||
case cmPlayReq2:
|
||||
case cmPlayReq3:
|
||||
playMode = 0;
|
||||
r = AVCLan_SendAnswerFrame((uint8_t *)CMD_PLAY_OK2);
|
||||
if (!r)
|
||||
r = AVCLan_SendAnswerFrame((uint8_t *)CMD_PLAY_OK3);
|
||||
CD_Mode = stPlay;
|
||||
break;
|
||||
case cmPlayIt:
|
||||
playMode = 1;
|
||||
RS232_Print("PLAY\n");
|
||||
CMD_PLAY_OK4[7] = cd_Disc;
|
||||
CMD_PLAY_OK4[8] = cd_Track;
|
||||
CMD_PLAY_OK4[9] = cd_Time_Min;
|
||||
CMD_PLAY_OK4[10] = cd_Time_Sec;
|
||||
r = AVCLan_SendAnswerFrame((uint8_t *)CMD_PLAY_OK4);
|
||||
if (!r)
|
||||
AVCLan_Send_Status();
|
||||
CD_Mode = stPlay;
|
||||
break;
|
||||
case cmStopReq:
|
||||
case cmStopReq2:
|
||||
CD_Mode = stStop;
|
||||
playMode = 0;
|
||||
|
||||
r = AVCLan_SendAnswerFrame((uint8_t *)CMD_STOP1);
|
||||
CMD_STOP2[7] = cd_Disc;
|
||||
CMD_STOP2[8] = cd_Track;
|
||||
CMD_STOP2[9] = cd_Time_Min;
|
||||
CMD_STOP2[10] = cd_Time_Sec;
|
||||
r = AVCLan_SendAnswerFrame((uint8_t *)CMD_STOP2);
|
||||
break;
|
||||
case cmBeep:
|
||||
AVCLan_SendAnswerFrame((uint8_t *)CMD_BEEP);
|
||||
break;
|
||||
}
|
||||
|
||||
answerReq = cmNull;
|
||||
return r;
|
||||
}
|
||||
|
||||
void AVCLan_Register() {
|
||||
RS232_Print("REG_ST\n");
|
||||
AVCLan_SendAnswerFrame((uint8_t *)CMD_REGISTER);
|
||||
RS232_Print("REG_END\n");
|
||||
// AVCLan_Command( cmRegister );
|
||||
AVCLan_Command(cmInit);
|
||||
}
|
||||
|
||||
uint8_t AVCLan_Command(uint8_t command) {
|
||||
uint8_t r;
|
||||
|
||||
answerReq = command;
|
||||
r = AVCLan_SendAnswer();
|
||||
/*
|
||||
RS232_Print("ret=");
|
||||
RS232_PrintHex8(r);
|
||||
RS232_Print("\n");
|
||||
*/
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Increment packed 2-digit BCD number.
|
||||
WARNING: Overflow behavior is incorrect (e.g. `incBCD(0x99) != 0x00`) */
|
||||
uint8_t incBCD(uint8_t data) {
|
||||
if ((data & 0x9) == 0x9)
|
||||
return (data + 7);
|
||||
|
||||
return (data + 1);
|
||||
}
|
||||
|
||||
void ShowInMessage() {
|
||||
if (message_len == 0)
|
||||
return;
|
||||
|
||||
AVC_HoldLine();
|
||||
|
||||
RS232_Print("HU < (");
|
||||
|
||||
if (broadcast == 0)
|
||||
RS232_Print("bro) ");
|
||||
else
|
||||
RS232_Print("dir) ");
|
||||
|
||||
RS232_PrintHex4(master1);
|
||||
RS232_PrintHex8(master2);
|
||||
RS232_Print("| ");
|
||||
RS232_PrintHex4(slave1);
|
||||
RS232_PrintHex8(slave2);
|
||||
RS232_Print("| ");
|
||||
|
||||
uint8_t i;
|
||||
for (i = 0; i < message_len; i++) {
|
||||
RS232_PrintHex8(message[i]);
|
||||
RS232_Print(" ");
|
||||
}
|
||||
RS232_Print("\n");
|
||||
|
||||
AVC_ReleaseLine();
|
||||
}
|
||||
|
||||
void ShowOutMessage() {
|
||||
uint8_t i;
|
||||
|
||||
AVC_HoldLine();
|
||||
|
||||
RS232_Print(" out > ");
|
||||
for (i = 0; i < data_len; i++) {
|
||||
RS232_PrintHex8(data[i]);
|
||||
RS232_SendByte(' ');
|
||||
}
|
||||
RS232_Print("\n");
|
||||
|
||||
AVC_ReleaseLine();
|
||||
}
|
||||
|
||||
#ifdef SOFTWARE_DEBUG
|
||||
uint16_t temp_b[100];
|
||||
|
||||
void AVCLan_Measure() {
|
||||
STOPEvent;
|
||||
|
||||
// uint16_t tmp, tmp1, tmp2, bit0, bit1;
|
||||
uint8_t n = 0;
|
||||
|
||||
cbi(TCCR1B, CS12);
|
||||
TCCR1B = _BV(CS10);
|
||||
TCNT1 = 0;
|
||||
|
||||
char str[5];
|
||||
|
||||
while (n < 100) {
|
||||
temp_b[n] = TCNT1;
|
||||
while (INPUT_IS_CLEAR) {}
|
||||
temp_b[n + 1] = TCNT1;
|
||||
while (INPUT_IS_SET) {}
|
||||
temp_b[n + 2] = TCNT1;
|
||||
while (INPUT_IS_CLEAR) {}
|
||||
temp_b[n + 3] = TCNT1;
|
||||
while (INPUT_IS_SET) {}
|
||||
temp_b[n + 4] = TCNT1;
|
||||
while (INPUT_IS_CLEAR) {}
|
||||
temp_b[n + 5] = TCNT1;
|
||||
while (INPUT_IS_SET) {}
|
||||
temp_b[n + 6] = TCNT1;
|
||||
while (INPUT_IS_CLEAR) {}
|
||||
temp_b[n + 7] = TCNT1;
|
||||
while (INPUT_IS_SET) {}
|
||||
temp_b[n + 8] = TCNT1;
|
||||
while (INPUT_IS_CLEAR) {}
|
||||
temp_b[n + 9] = TCNT1;
|
||||
while (INPUT_IS_SET) {}
|
||||
//
|
||||
// while (INPUT_IS_CLEAR) {}
|
||||
//
|
||||
// tmp1 = TCNT1;
|
||||
//
|
||||
// while (INPUT_IS_SET) {}
|
||||
//
|
||||
// tmp2 = TCNT1;
|
||||
//
|
||||
// bit0 = tmp1-tmp;
|
||||
// bit1 = tmp2-tmp1;
|
||||
//
|
||||
// RS232_Print("1,");
|
||||
// RS232_PrintDec(bit1);
|
||||
// RS232_Print("\n");
|
||||
//
|
||||
// RS232_Print("0,");
|
||||
// RS232_PrintDec(bit0);
|
||||
// RS232_Print("\n");
|
||||
n += 10;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 100; i++) {
|
||||
itoa(temp_b[i], str);
|
||||
if (i & 1) {
|
||||
RS232_Print("High,");
|
||||
} else {
|
||||
RS232_Print("Low,");
|
||||
}
|
||||
RS232_Print(str);
|
||||
RS232_Print("\n");
|
||||
}
|
||||
RS232_Print("\nDone.\n");
|
||||
|
||||
cbi(TCCR1B, CS10);
|
||||
TCCR1B = _BV(CS12);
|
||||
|
||||
STARTEvent;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HARDWARE_DEBUG
|
||||
void SetHighLow() {
|
||||
AVC_OUT_EN();
|
||||
sbi(TCCR1B, CS10);
|
||||
uint16_t n = 60000;
|
||||
TCNT1 = 0;
|
||||
AVC_SET_LOGICAL_1();
|
||||
while (TCNT1 < n) {}
|
||||
TCNT1 = 0;
|
||||
AVC_SET_LOGICAL_0();
|
||||
while (TCNT1 < n) {}
|
||||
cbi(TCCR1B, CS10);
|
||||
AVC_OUT_DIS();
|
||||
}
|
||||
#endif
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
Copyright (C) 2015 Allen Hill <allenofthehills@gmail.com>.
|
||||
|
||||
Portions of the following source code are:
|
||||
Copyright (C) 2006 Marcin Slonicki <marcin@softservice.com.pl>.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
this file is a part of the TOYOTA Corolla MP3 Player Project
|
||||
-----------------------------------------------------------------------
|
||||
http://www.softservice.com.pl/corolla/avc
|
||||
|
||||
May 28 / 2009 - version 2
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __AVCLANDRV_H
|
||||
#define __AVCLANDRV_H
|
||||
|
||||
#include "GlobalDef.h"
|
||||
|
||||
#define STOPEvent \
|
||||
cbi(RTC.PITINTCTRL, RTC_PI_bp); \
|
||||
cbi(USART0.CTRLA, USART_RXCIE_bp);
|
||||
#define STARTEvent \
|
||||
sbi(RTC.PITINTCTRL, RTC_PI_bp); \
|
||||
sbi(USART0.CTRLA, USART_RXCIE_bp);
|
||||
|
||||
#define CHECK_AVC_LINE \
|
||||
if (INPUT_IS_SET) \
|
||||
AVCLan_Read_Message();
|
||||
|
||||
void AVC_HoldLine();
|
||||
void AVC_ReleaseLine();
|
||||
|
||||
#define MAXMSGLEN 32
|
||||
|
||||
// Head Unid ID
|
||||
extern uint8_t HU_ID_1; // 0x01
|
||||
extern uint8_t HU_ID_2; // 0x40
|
||||
|
||||
extern uint8_t CD_ID_1; // 0x03
|
||||
extern uint8_t CD_ID_2; // 0x60
|
||||
|
||||
// DVD CHANGER
|
||||
// #define CD_ID_1 0x02
|
||||
// #define CD_ID_2 0x50
|
||||
|
||||
#define cmNull 0
|
||||
#define cmStatus1 1
|
||||
#define cmStatus2 2
|
||||
#define cmStatus3 3
|
||||
#define cmStatus4 4
|
||||
|
||||
#define cmRegister 100
|
||||
#define cmInit 101
|
||||
#define cmCheck 102
|
||||
#define cmPlayIt 103
|
||||
#define cmBeep 110
|
||||
|
||||
#define cmNextTrack 120
|
||||
#define cmPrevTrack 121
|
||||
#define cmNextDisc 122
|
||||
#define cmPrevDisc 123
|
||||
|
||||
#define cmScanModeOn 130
|
||||
#define cmScanModeOff 131
|
||||
|
||||
#define cmPlayReq1 5
|
||||
#define cmPlayReq2 6
|
||||
#define cmPlayReq3 7
|
||||
#define cmStopReq 8
|
||||
#define cmStopReq2 9
|
||||
|
||||
typedef enum { stStop = 0, stPlay = 1 } cd_modes;
|
||||
extern cd_modes CD_Mode;
|
||||
|
||||
extern uint8_t broadcast;
|
||||
extern uint8_t master1;
|
||||
extern uint8_t master2;
|
||||
extern uint8_t slave1;
|
||||
extern uint8_t slave2;
|
||||
extern uint8_t message_len;
|
||||
extern uint8_t message[MAXMSGLEN];
|
||||
|
||||
extern uint8_t data_control;
|
||||
extern uint8_t data_len;
|
||||
extern uint8_t data[MAXMSGLEN];
|
||||
|
||||
uint8_t AVCLan_Read_Message();
|
||||
void AVCLan_Send_Status();
|
||||
|
||||
void AVCLan_Init();
|
||||
void AVCLan_Register();
|
||||
uint8_t AVCLan_SendData();
|
||||
uint8_t AVCLan_SendAnswer();
|
||||
uint8_t AVCLan_SendDataBroadcast();
|
||||
uint8_t AVCLan_Command(uint8_t command);
|
||||
|
||||
uint8_t incBCD(uint8_t data);
|
||||
|
||||
extern uint8_t check_timeout;
|
||||
|
||||
extern uint8_t cd_Disc;
|
||||
extern uint8_t cd_Track;
|
||||
extern uint8_t cd_Time_Min;
|
||||
extern uint8_t cd_Time_Sec;
|
||||
|
||||
extern uint8_t playMode;
|
||||
|
||||
uint8_t AVCLan_SendMyData(uint8_t *data_tmp, uint8_t s_len);
|
||||
uint8_t AVCLan_SendMyDataBroadcast(uint8_t *data_tmp, uint8_t s_len);
|
||||
|
||||
void ShowInMessage();
|
||||
void ShowOutMessage();
|
||||
|
||||
#ifdef SOFTWARE_DEBUG
|
||||
void AVCLan_Measure();
|
||||
#endif
|
||||
#ifdef HARDWARE_DEBUG
|
||||
void SetHighLow();
|
||||
#endif
|
||||
|
||||
extern uint8_t answerReq;
|
||||
|
||||
#endif // __AVCLANDRV_H
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
Copyright (C) 2006 Marcin Slonicki <marcin@softservice.com.pl>.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
this file is a part of the TOYOTA Corolla MP3 Player Project
|
||||
-----------------------------------------------------------------------
|
||||
http://www.softservice.com.pl/corolla/avc
|
||||
|
||||
May 28 / 2009 - version 2
|
||||
|
||||
*/
|
||||
|
||||
#include "com232.h"
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/io.h>
|
||||
|
||||
uint8_t RS232_RxCharBuffer[25], RS232_RxCharBegin, RS232_RxCharEnd;
|
||||
uint8_t readkey;
|
||||
|
||||
void RS232_Init(void) {
|
||||
RS232_RxCharBegin = RS232_RxCharEnd = 0;
|
||||
|
||||
PORTMUX.CTRLB = PORTMUX_USART0_ALTERNATE_gc; // Use PA1/PA2 for TxD/RxD
|
||||
|
||||
USART0.CTRLA = USART_RXCIE_bm; // Enable receive interrupts
|
||||
USART0.CTRLB = USART_RXEN_bm | USART_TXEN_bm |
|
||||
USART_RXMODE_NORMAL_gc; // Enable Rx/Tx and set receive mode
|
||||
// normal
|
||||
USART0.CTRLC = USART_CMODE_ASYNCHRONOUS_gc | USART_PMODE_DISABLED_gc |
|
||||
USART_CHSIZE_8BIT_gc |
|
||||
USART_SBMODE_1BIT_gc; // Async UART with 8N1 config
|
||||
USART0.BAUD = 256; // 250k baud rate (64*F_CPU/(16*250k)) for F_CPU = 16MHz
|
||||
}
|
||||
|
||||
ISR(USART0_RXC_vect) {
|
||||
RS232_RxCharBuffer[RS232_RxCharEnd] = USART0_RXDATAL; // Store received
|
||||
// character to the End
|
||||
// of Buffer
|
||||
RS232_RxCharEnd++;
|
||||
}
|
||||
|
||||
void RS232_SendByte(uint8_t Data) {
|
||||
loop_until_bit_is_set(USART0_STATUS,
|
||||
USART_DREIF_bp); // wait for UART to become available
|
||||
USART0_TXDATAL = Data; // send character
|
||||
}
|
||||
|
||||
void RS232_Print(const char *pBuf) {
|
||||
register uint8_t c;
|
||||
while ((c = *pBuf++)) {
|
||||
if (c == '\n')
|
||||
RS232_SendByte('\r');
|
||||
RS232_SendByte(c);
|
||||
}
|
||||
}
|
||||
|
||||
void RS232_PrintHex4(uint8_t Data) {
|
||||
uint8_t Character = Data & 0x0f;
|
||||
Character += '0';
|
||||
if (Character > '9')
|
||||
Character += 'A' - '0' - 10;
|
||||
RS232_SendByte(Character);
|
||||
}
|
||||
|
||||
void RS232_PrintHex8(uint8_t Data) {
|
||||
RS232_PrintHex4(Data >> 4);
|
||||
RS232_PrintHex4(Data);
|
||||
}
|
||||
|
||||
void RS232_PrintDec(uint8_t Data) {
|
||||
if (Data > 99) {
|
||||
RS232_SendByte('*');
|
||||
return;
|
||||
}
|
||||
if (Data < 10) {
|
||||
RS232_SendByte('0' + Data);
|
||||
return;
|
||||
}
|
||||
uint8_t c;
|
||||
unsigned short v, v1;
|
||||
v = Data;
|
||||
v1 = v / 10;
|
||||
c = '0' + (v - v1 * 10);
|
||||
RS232_SendByte('0' + v1);
|
||||
RS232_SendByte(c);
|
||||
}
|
||||
|
||||
void RS232_PrintDec2(uint8_t Data) {
|
||||
if (Data < 10)
|
||||
RS232_SendByte('0');
|
||||
RS232_PrintDec(Data);
|
||||
}
|
||||
|
||||
char *itoa(int i, char b[]) {
|
||||
char const digit[] = "0123456789";
|
||||
char *p = b;
|
||||
if (i < 0) {
|
||||
*p++ = '-';
|
||||
i *= -1;
|
||||
}
|
||||
int shifter = i;
|
||||
do { // Move to where representation ends
|
||||
++p;
|
||||
shifter = shifter / 10;
|
||||
} while (shifter);
|
||||
*p = '\0';
|
||||
do { // Move back, inserting digits as u go
|
||||
*--p = digit[i % 10];
|
||||
i = i / 10;
|
||||
} while (i);
|
||||
return b;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright (C) 2006 Marcin Slonicki <marcin@softservice.com.pl>.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
this file is a part of the TOYOTA Corolla MP3 Player Project
|
||||
-----------------------------------------------------------------------
|
||||
http://www.softservice.com.pl/corolla/avc
|
||||
|
||||
May 28 / 2009 - version 2
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __COM232_H
|
||||
#define __COM232_H
|
||||
|
||||
#include "GlobalDef.h"
|
||||
|
||||
extern uint8_t RS232_RxCharBuffer[25], RS232_RxCharBegin, RS232_RxCharEnd;
|
||||
extern uint8_t readkey;
|
||||
|
||||
void RS232_Init(void);
|
||||
extern void RS232_Print_P(const char *str_addr);
|
||||
extern void RS232_SendByte(uint8_t Data);
|
||||
extern void RS232_Print(const char *pBuf);
|
||||
extern void RS232_PrintHex4(uint8_t Data);
|
||||
extern void RS232_PrintHex8(uint8_t Data);
|
||||
extern void RS232_PrintDec(uint8_t Data);
|
||||
extern void RS232_PrintDec2(uint8_t Data);
|
||||
extern char *itoa(int i, char b[]);
|
||||
|
||||
#endif // __COM232_H
|
||||
+241
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
Copyright (C) 2006 Marcin Slonicki <marcin@softservice.com.pl>.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
this file is a part of the TOYOTA Corolla MP3 Player Project
|
||||
-----------------------------------------------------------------------
|
||||
http://www.softservice.com.pl/corolla/avc
|
||||
|
||||
May 28 / 2009 - version 2
|
||||
|
||||
*/
|
||||
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "GlobalDef.h"
|
||||
#include "avclandrv.h"
|
||||
#include "com232.h"
|
||||
|
||||
void Setup();
|
||||
|
||||
uint8_t rcv_command[5];
|
||||
uint8_t rcv_pos = 0;
|
||||
uint8_t rcv_time_clr = 0;
|
||||
|
||||
int main() {
|
||||
uint8_t readSeq = 0;
|
||||
uint8_t s_len = 0;
|
||||
uint8_t s_dig = 0;
|
||||
uint8_t s_c[2];
|
||||
uint8_t i;
|
||||
uint8_t data_tmp[32];
|
||||
|
||||
Setup();
|
||||
|
||||
RS232_Print("AVCLan reader 1.00\nReady\n\n");
|
||||
RS232_Print("\nS - read sequence\nW - send command\nQ - send "
|
||||
"broadcast\nL/l - log on/off\nK/k - seq. echo on/off\n");
|
||||
RS232_Print("R/r - register device\nB - Beep\n");
|
||||
#ifdef HARDWARE_DEBUG
|
||||
RS232_Print("1 - Hold High/low\nE - Print line status\n");
|
||||
#endif
|
||||
#ifdef SOFTWARE_DEBUG
|
||||
RS232_Print("M - Measure high and low lengths\n");
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
|
||||
if (INPUT_IS_SET) { // if message from some device on AVCLan begin
|
||||
AVCLan_Read_Message();
|
||||
// show message
|
||||
} else {
|
||||
// check command from HU
|
||||
if (answerReq != 0)
|
||||
AVCLan_SendAnswer();
|
||||
}
|
||||
|
||||
// HandleEvent
|
||||
switch (Event) {
|
||||
case EV_STATUS:
|
||||
Event &= ~EV_STATUS;
|
||||
AVCLan_Send_Status();
|
||||
break;
|
||||
}
|
||||
|
||||
// Key handler
|
||||
if (RS232_RxCharEnd) {
|
||||
cbi(USART0.CTRLA, USART_RXCIE_bp); // disable RX complete interrupt
|
||||
readkey = RS232_RxCharBuffer[RS232_RxCharBegin]; // read begin of received
|
||||
// Buffer
|
||||
RS232_RxCharBegin++;
|
||||
if (RS232_RxCharBegin == RS232_RxCharEnd) // if Buffer is empty
|
||||
RS232_RxCharBegin = RS232_RxCharEnd = 0; // reset Buffer
|
||||
sbi(USART0.CTRLA, USART_RXCIE_bp); // enable RX complete interrupt
|
||||
switch (readkey) {
|
||||
case 'S':
|
||||
showLog = 0;
|
||||
RS232_Print("READ SEQUENCE > \n");
|
||||
readSeq = 1;
|
||||
s_len = 0;
|
||||
s_dig = 0;
|
||||
s_c[0] = s_c[1] = 0;
|
||||
break;
|
||||
case 'W':
|
||||
showLog = 1;
|
||||
readSeq = 0;
|
||||
AVCLan_SendMyData(data_tmp, s_len);
|
||||
break;
|
||||
case 'Q':
|
||||
showLog = 1;
|
||||
readSeq = 0;
|
||||
AVCLan_SendMyDataBroadcast(data_tmp, s_len);
|
||||
break;
|
||||
case 'R':
|
||||
RS232_Print("REGIST:\n");
|
||||
AVCLan_Command(cmRegister);
|
||||
TCB1.CNT = 0;
|
||||
while (TCB1.CNT < 540) {}
|
||||
CHECK_AVC_LINE;
|
||||
break;
|
||||
case 'r':
|
||||
AVCLan_Register();
|
||||
break;
|
||||
case 'l':
|
||||
RS232_Print("Log OFF\n");
|
||||
showLog = 0;
|
||||
break;
|
||||
case 'L':
|
||||
RS232_Print("Log ON\n");
|
||||
showLog = 1;
|
||||
break;
|
||||
case 'k':
|
||||
RS232_Print("str OFF\n");
|
||||
showLog2 = 0;
|
||||
break;
|
||||
case 'K':
|
||||
RS232_Print("str ON\n");
|
||||
showLog2 = 1;
|
||||
break;
|
||||
case 'B':
|
||||
data_tmp[0] = 0x00;
|
||||
data_tmp[1] = 0x5E;
|
||||
data_tmp[2] = 0x29;
|
||||
data_tmp[3] = 0x60;
|
||||
data_tmp[4] = 0x01;
|
||||
s_len = 5;
|
||||
AVCLan_SendMyData(data_tmp, s_len);
|
||||
break;
|
||||
|
||||
#ifdef HARDWARE_DEBUG
|
||||
case '1':
|
||||
SetHighLow();
|
||||
break;
|
||||
case 'E':
|
||||
if (INPUT_IS_SET) {
|
||||
RS232_Print("Set/High/1\n");
|
||||
} else if (INPUT_IS_CLEAR) {
|
||||
RS232_Print("Unset/Low/0\n");
|
||||
} else {
|
||||
RS232_Print("WTF?\n");
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef SOFTWARE_DEBUG
|
||||
case 'M':
|
||||
AVCLan_Measure();
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
if (readSeq == 1) {
|
||||
s_c[s_dig] = readkey;
|
||||
|
||||
s_dig++;
|
||||
if (s_dig == 2) {
|
||||
if (s_c[0] < ':')
|
||||
s_c[0] -= 48;
|
||||
else
|
||||
s_c[0] -= 55;
|
||||
data_tmp[s_len] = 16 * s_c[0];
|
||||
if (s_c[1] < ':')
|
||||
s_c[1] -= 48;
|
||||
else
|
||||
s_c[1] -= 55;
|
||||
data_tmp[s_len] += s_c[1];
|
||||
s_len++;
|
||||
s_dig = 0;
|
||||
s_c[0] = s_c[1] = 0;
|
||||
}
|
||||
if (showLog2) {
|
||||
RS232_Print("CURRENT SEQUENCE > ");
|
||||
for (i = 0; i < s_len; i++) {
|
||||
RS232_PrintHex8(data_tmp[i]);
|
||||
RS232_SendByte(' ');
|
||||
}
|
||||
RS232_Print("\n");
|
||||
}
|
||||
}
|
||||
} // switch (readkey)
|
||||
} // if (RS232_RxCharEnd)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Setup() {
|
||||
CD_ID_1 = 0x03;
|
||||
CD_ID_2 = 0x60;
|
||||
|
||||
HU_ID_1 = 0x01;
|
||||
HU_ID_2 = 0x90;
|
||||
|
||||
showLog = 1;
|
||||
showLog2 = 1;
|
||||
|
||||
// Default is zero; resetting/zeroing unnecessary
|
||||
// MCUCR = 0;
|
||||
|
||||
loop_until_bit_is_clear(RTC_STATUS, RTC_CTRLABUSY_bp);
|
||||
RTC.CTRLA = RTC_PRESCALER_DIV1_gc;
|
||||
RTC.CLKSEL = RTC_CLKSEL_INT32K_gc;
|
||||
RTC.PITINTCTRL = RTC_PI_bm;
|
||||
loop_until_bit_is_clear(RTC_PITSTATUS, RTC_CTRLBUSY_bp);
|
||||
RTC.PITCTRLA = RTC_PERIOD_CYC32768_gc | RTC_PITEN_bm;
|
||||
|
||||
RS232_Init();
|
||||
|
||||
AVCLan_Init();
|
||||
|
||||
Event = EV_NOTHING;
|
||||
sei();
|
||||
}
|
||||
|
||||
// Periodic interrupt with a 1 sec period
|
||||
ISR(RTC_PIT_vect) {
|
||||
if (CD_Mode == stPlay) {
|
||||
cd_Time_Sec = incBCD(cd_Time_Sec);
|
||||
if (cd_Time_Sec == 0x60) {
|
||||
cd_Time_Sec = 0;
|
||||
cd_Time_Min = incBCD(cd_Time_Min);
|
||||
if (cd_Time_Min == 0xA0) {
|
||||
cd_Time_Min = 0x0;
|
||||
}
|
||||
}
|
||||
}
|
||||
Event |= EV_STATUS;
|
||||
RTC.PITINTFLAGS |= RTC_PI_bm;
|
||||
}
|
||||
Reference in New Issue
Block a user