¡Y directo al grano!
El protocolo Maple BUS es simétrico, es decir, que tiene una buena implementación, por ejemplo, HOST, la misma implementación se puede utilizar como DEVICE. Más fácil: puede leer el joystick o puede fingir que lo es.
Descripción de protocolo (hardware)
La interfaz Maple BUS es de dos cables. SDCKA / SDCKB, cada una de las líneas en determinadas etapas desempeña el papel tanto de "transmisión de datos" como de "retención de datos".
La comunicación en Maple BUS se realiza en paquetes. Cada paquete de datos consta de un patrón de encabezado, datos, una suma de comprobación y un patrón de seguimiento. La longitud máxima del paquete de datos es de 1024 bytes.
Hay 5 tipos de patrones en total:
INICIO: indica el inicio de la transmisión de datos (4-reklok SDCKB mientras SDCKA está en un nivel bajo).
El paquete siempre debe terminar con el patrón END (2 relojes de SDCKA mientras SDCKB está en un nivel bajo):
Occupancy - (8- SDCKB SDCKA ). HI->LO SDCKA , LO->HI . (Light GUN - Func. FT7):
RESET - (14- SDCKB SDCKA , DEVICE).
.
. - SDCKB, - SDCKA, ( :) ).
1:
, VMU, , ...
Maple BUS Device, Device Expansion Device, Device Expansion Device LM-Bus. Expansion 5-, , ( 315-6211-AB) " " 2- ( EXP-DEV , , VMU LCD , Exp. ).
LM-BUS Maple BUS, DEVICE Maple BUS Exp. DEVICE HOST'.
LM-BUS , , .
, :
COMMAND - , 0x01 0xFE (. "maplebus.h").
maplebus commands
//HOST
#define DeviceRequest 0x01
#define AllStatusRequest 0x02
#define DeviceReset 0x03
#define DeviceKill 0x04
#define GetCondition 0x09
#define GetMediaInfo 0x0A
#define BlockRead 0x0B
#define BlockWrite 0x0C
#define GetLastError 0x0D
#define SetCondition 0x0E
#define FT4Control 0x0F
#define ARControl 0x10
#define TransmitAgain 0xFC
//Device
#define DeviceStatus 0x05
#define DeviceAllStatus 0x06
#define DeviceReply 0x07
#define DataTransfer 0x08
#define ARError 0xF9
#define LCDError 0xFA
#define FileError 0xFB
#define TransmitAgain 0xFC
#define CommandUnknown 0xFD
#define FunctionTypeUnknown 0xFE
DEST. AP - ( ).
ORIG. AP - .
AP :
PO[1:0] - (A - 00, B - 01, C - 10, D - 11).
D/E - (1 - Device, 0 - Expansion Device PORT).
LM[4:0] - (1 - Exp. DEVICE , 0 - Exp. ).
DATA SIZE - 32- .
DATA - .
CRC - XOR COMMAND, AP, DATA SIZE, DATA.
"" HOST DEVICE DeviceRequest, , , "" (A/B/C/D).
(DeviceStatus answer):
Device ID - (Device ID FT, FD - ).
Device Functions
/*Device functions*/
#define CONTROLLER MAKE_DWORD(0x00000001) //FT0 : Controller Function
#define STORAGE MAKE_DWORD(0x00000002) //FT1 : Storage Function
#define LCD MAKE_DWORD(0x00000004) //FT2 : B/W LCD Function
#define TIMER MAKE_DWORD(0x00000008) //FT3 : Timer Function
#define AUDIO_INPUT MAKE_DWORD(0x00000010) //FT4 : Audio input device Function
#define AR_GUN MAKE_DWORD(0x00000020) //FT5 : AR-Gun Function
#define KEYBOARD MAKE_DWORD(0x00000040) //FT6 : Keyboard
#define GUN MAKE_DWORD((unsigned int)0x00000080) //FT7 : Light-Gun Function
#define VIBRATION MAKE_DWORD((unsigned int)0x00000100) //FT8 : Vibration Function
#define MOUSE MAKE_DWORD((unsigned int)0x00000200) //FT9 : Pointing Function
#define EXMEDIA MAKE_DWORD((unsigned int)0x00000400) //FT10 : Exchange Media Function
#define CAMERA MAKE_DWORD((unsigned int)0x00000800) //FT11 : Camera Device Functio
Destination code - .
Product name - ( {'D','r','e','a','m','c','a','s','t',' ','C','o','n','t','r','o','l','l','e','r', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' '} - 30 ).
License - ( {'P','r','o','d','u','c','e','d',' ','B','y',' ','o','r',' ','U','n','d','e','r',' ','L','i','c','e','n','s','e',' ','F','r','o','m',' ','S','E','G','A',' ','E','N','T','E','R','P','R','I','S','E','S',',','L','T','D','.',' ',' ',' ',' ',' ',} -60 ).
Min./Max. current - . (1 = 10 , 43 => 0x1AE).
" " ( , ), : 40 "Version 1.000,1998/05/11,315-6125-AB Analog Module: The 4th Edition. 05/08".
, Device ID.
FT0, CONTROLLER, GetCondition - / . Device ID. , Device ID :
GetCondition, , :
Ra/La/Da/Ua - /// ( "").
Start/A/B/X/Y - .
A1, A2 -
A3 A4 - "".
.
( )
SDCKA SDCKB , , , , " " , , " " , , .
CPLD (EPM3032) xMAPLE:
SDCKA/SDCKB - Maple BUS.
GCLK - CLK 16-48MHz.
INHTxD - , 1 - , 0 - .
RxD - .
nSTRCV- (Rising Edge).
nDLatch - " " ( Q[7..0] ).
Q[7..0] - .
EOP - END ( ).
FERR - .
nRST - - RESET , - 0.
:
' (3 , ):
SMAPLE.v
module SMAPLE(
input GCLK, //MCU Generated 16MHz clock input
input INHTxD, //Inhibit Input Data (User Can disable XMAPLE Detect Signals While MCU Transmit DATA)
input SDCKAi, //Data/Clock A Line
input SDCKBi, //Data/Clock B Line
output RxD, //Receive on progress (While receive is 1)
output [7:0]Q // Output data bus (MCU can read valid data on this
//port in time 200uS after data latch Negative Pulse received)
, output nSTRCV, //Receive start, negative pulse - Output
output OCPYi, //Occupancy packet received - Output
output nRST, //Reset packet received - Output
output FERR, //Frame error - Output
output EOPi, //End Of Packed received - Output
output nDLatch //New Data latched on BUS (Negative Pulse)
);
/*Control Register*/
reg rRxD = 0;
assign RxD = rRxD;
reg rFERR = 0;
assign FERR = rFERR;
wire nWE;
assign nDLatch = (EOPi & nWE);
wire iFERR;
/* Align Data Packet */
reg rENA = 1'b0;
reg rENB = 1'b0;
always @(posedge GCLK or negedge nRST) begin
if(!nRST) begin
rENA <= 1'b0;
rENB <= 1'b0;
end else begin
rENA <= SDCKAi;
rENB <= SDCKBi;
end
end
always @(posedge GCLK or negedge nRST) begin
if(!nRST) begin
rFERR <= 0;
rRxD <= 0;
end else begin
if(!EOPi)// && !INHTxD)
rRxD <=0 ;
else begin
if(!iFERR) rFERR <= 1;
if(!nSTRCV) begin
rFERR <= 0;
rRxD <= ~INHTxD;
end
end
end
end
line_monitor line_monitor
(
.GCLK(GCLK), //Global Clock - Input
.SDCKA(SDCKAi|INHTxD), //CLOCK/DATA Line A disabled by data transmit - Input
.SDCKB(SDCKBi|INHTxD), //CLOCK/DATA Line B disabled by data transmit - Input
.RxDr(RxD), //Data Receive in progress - Input
.RxD(nSTRCV), //Receive start, negative pulse - Output
.OCPY(OCPYi), //Occupancy packet received - Output
.RESET(nRST), //Reset packet received - Output
.FERR(iFERR), //Frame error - Output
.EOP(EOPi), //End Of Packed received - Output
.ENA(rENA), //CLOCK For Line B
.ENB(rENB) //CLOCK For Line A
);
/*Receive Maple Frame*/
maple_receive maple_receive
(
.SDCKA(SDCKAi), //CLOCK/DATA Line A disabled by data transmit - Input
.SDCKB(SDCKBi), //CLOCK/DATA Line B disabled by data transmit - Input
.ENA(rENA), //CLOCK For Line B
.ENB(rENB), //CLOCK For Line A
.RCV(RxD), //Receive in progress, 1 - receive - Input
.Dout(Q[7:0]), //Received data byte - Output
.nWE(nWE), //Write Latch - Output
.RxDi(nSTRCV), //Receive start, negative pulse - Input
.INHTxD(INHTxD) //Inhibit Input Data (User Can disable XMAPLE Detect Signals While MCU Transmit DATA)
);
endmodule
line_monitor.v
module line_monitor
(
input GCLK,
input SDCKA,
input SDCKB,
input RxDr, //Data Receive in progress - Input
output RxD,
output OCPY,
output RESET,
output FERR,
output EOP,
input ENA,
input ENB
);
reg [3:0] countA = 0;
reg [2:0] countB = 0;
reg [3:0] pcount = 0;
reg rEOP = 1'b1;
assign EOP = rEOP;
assign RxD = (pcount == 4'h4) ? 1'b0 : 1'b1;
assign OCPY = (pcount == 4'h8) ? 1'b0 : 1'b1;
assign RESET = (pcount == 4'hE)? 1'b0 : 1'b1; //Output reset signal does not need to check for FERR
assign FERR = (!((RxD & OCPY & RESET) && pcount[3:1])) | (!RxDr & !rEOP);
//assign EOP = (eopcount == 3'h2) ? 1'b0 : 1'b1;
always @(posedge SDCKA) pcount <= countA;
always @(posedge SDCKB) rEOP <= !(countB == 3'h2);
//Patterns
//PATTERN Counter Managing
always @(posedge ENA or negedge ENB) begin
if (ENA) begin
countA <= 0;
end
else begin
countA <= countA + 4'h1;
end
end
//EOP Counter Managing
always @(posedge ENB or negedge ENA) begin
if (ENB) begin
countB <= 0;
end
else begin
countB <= countB + 3'h1;
end
end
//synopsys translate_off
//synopsys translate_on
endmodule
maple_receive.v
module maple_receive
(
input SDCKA, //CLOCK/DATA Line A
input SDCKB, //CLOCK/DATA Line B
input ENA, //CLOCK
input ENB, //CLOCK
input RCV, //Receive in progress, 1 - valid
output [7:0]Dout, //received data output
output nWE,
input RxDi,
input INHTxD //Inhibit Input Data (User Can disable XMAPLE Detect Signals While MCU Transmit DATA)
);
reg [3:0] dataA = 4'h0;
reg [3:0] dataB = 4'h0;
reg [1:0]countB = 2'b00;
reg rLastBitCounted = 1'b1;
//B LINE
//Dout[1] = SDCKA Means Major version 1.
//Dout[0] = SDCKB Means Minor version .0
//And version result = 1.0
assign Dout[1] = !INHTxD ? dataB[0] : SDCKA;
assign Dout[3] = dataB[1];
assign Dout[5] = dataB[2];
assign Dout[7] = dataB[3];
//A LINE
assign Dout[0] = !INHTxD ? dataA[0] : SDCKB;
assign Dout[2] = dataA[1];
assign Dout[4] = dataA[2];
assign Dout[6] = dataA[3];
assign nWE = (dtaLock);
always @(negedge ENA)begin
dataB[3:1] <= dataB[2:0];
dataB[0] <= SDCKB;
if(RCV) begin
countB <= countB + 2'b1;
end else begin
countB <= 2'b11;
end
end
always @(negedge ENB)begin
dataA[3:1] <= dataA[2:0];
dataA[0] <= SDCKA;
rLastBitCounted <= !countB[0] | !countB[1];
end
wire dtaLock = rLastBitCounted;
endmodule
" " Eval Board.
:
:
Eval...
:
, , .
Dreamcast XBOX360 ( " " XBOX360, ).
, , :
, "".
SD - :
... USB HID, MAPLE.
:
USE_STDPERIPH_DRIVER - ST.
STM32F10X_MD - Medium Density.
MAPLE_HOST - MAPLE HOST.
USB_HID - HID .
, :
… ( Microsoft Xbox 360 Accessories, XInput... , ):
xMAPLE ...
DREAMCAST.
, - FT9 : Pointing Function.
, DeviceID GetCondition, .
Mouse DeviceID:
Dreamcast 3 : A,B,W, X/Y: AC1,AC2 (ball) "": AC3 (wheel).
AC1,AC2,AC3 - - .
:
AOV2, AOV1, AOV0 - AC3, AC2, AC1 .
PS/2 :
..., gerber'...
:
, , , .
"" :
( ) :
USE_STDPERIPH_DRIVER - ST.
STM32F10X_MD - Medium Density.
MAPLE_DEVICE - MAPLE DEVICE.
EN_MOUSE - HID .
MOUSE_CALLBACK - HOST.
EXTI9_5_CALLBACK - EXTI5-EXTI9 MAPLE_BUS.
(, HEX).
, EN_MOUSE EN_CONTROLLER, , PS/2 DREAMCAST, , DREAMCAST . "HALF LIFE " EN_CONTROLLER PS/2.
, DREAMCAST !!!
De hecho, eso es todo lo que quería contar. Sin embargo, no hablé de (espero contarte más :)):
Cómo trabajar con VibroPAK.
Cómo implementar una unidad de memoria (aunque puede instalar y trabajar con memoria en la placa de expansión PS / 2 SPI EEPROM).
Y todavía tengo juegos de placas de circuito impreso y puedo enviar juegos de placas de circuito impreso por el costo del correo a tres personas que quieran "probar suerte".
¡Tenga un buen día! Buen humor y entendimiento mutuo !!!