Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make

And straight to the point!





The Maple BUS protocol is symmetric, that is, having one good implementation, for example HOST, the same implementation can be used as DEVICE. Easier - you can read the joystick, or you can pretend to be it.





Protocol description (hardware)

The Maple BUS interface is two-wire. SDCKA / SDCKB, each of the lines at certain stages plays the role of both "transmitting data" and "latching data".





Communication on the Maple BUS is carried out in packages. Each data packet consists of a header pattern, data, checksum, and a trailing pattern. The maximum data packet length is 1024 bytes.





There are 5 types of patterns in total:





START - indicates the start of data transmission (4-reklok SDCKB while SDCKA is at a low level).





The package should always end with the END pattern (2 clocks of SDCKA while SDCKB is at a low level):





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.





:





.





Gerber .





:





Eval...





Gerber .





:





, , .





Dreamcast XBOX360 ( " " XBOX360, ).





, , :





(GERBER), (GERBER).





, "".





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'...





:





, , , .





"" 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 !!!





That's actually all I wanted to tell. However, I did not talk about (I hope I will tell you more :)):





  • How to work with VibroPAK.





  • How to implement a Memory Unit (although you can install and work with memory on the PS / 2 SPI EEPROM expansion board).





  • And I still have sets of printed circuit boards, and I can send three sets of printed circuit boards for the cost of mail to three who want to "try my hand".





Have a good day! Great mood and mutual understanding !!!








All Articles