Permalink
Browse files

Added initial PSX bus bitbanging code

  • Loading branch information...
kcuzner committed Aug 3, 2013
1 parent f94e0e0 commit 7a4fef3a08cff20d1e7809010f511c3e9ed235e1
Showing with 143 additions and 1 deletion.
  1. +2 −1 include/psx.h
  2. +14 −0 src/main.c
  3. +127 −0 src/psx.c
View
@@ -15,6 +15,7 @@
#define _PSX_H_
#define PSX_PORT PORTD
+#define PSX_DDR DDRD
#define PSX_ATT_MASK 0x08
#define PSX_CLK_MASK 0x04
#define PSX_DATA_MASK 0x02
@@ -30,7 +31,7 @@ void psx_setup(void);
* Sends data via the PSX bus
* @param data Data character to send
*/
-void psx_send(unsigned char data);
+char psx_send(unsigned char data);
/**
* Called when the att pin is signaled low. This should be implemented wherever
View
@@ -11,7 +11,21 @@
* - left, down, and right buttons are pressed
*/
+#include "psx.h"
+
int main(void)
{
return 0;
}
+
+void psx_on_att(void)
+{
+ //send our greeting
+ psx_send(0xFF); //the impression of being idle
+ psx_send(0x41); //identifier as a digital pad
+ psx_send(0x5a); //ready to send data
+
+ //send button state
+ psx_send(0xff);
+ psx_send(0xff);
+}
View
127 src/psx.c
@@ -4,3 +4,130 @@
#include "psx.h"
+#include <avr/io.h>
+#include <avr/interrupt.h>
+
+#define PSX_DDR_IN_MASK ~(PSX_ATT_MASK | PSX_CLK_MASK | PSX_CMD_MASK)
+#define PSX_DDR_OUT_MASK PSX_DATA_MASK | PSX_ACK_MASK
+
+unsigned char buffer[5];
+/**
+ * Holds the send state for the psx bus
+ */
+struct
+{
+ /**
+ * Length of the buffer
+ */
+ unsigned size:3;
+ /**
+ * Current byte to send
+ */
+ unsigned index:3;
+ /**
+ * Mask for the current bit to send
+ */
+ unsigned char sendMask;
+} sendState;
+
+void psx_setup(void)
+{
+ sendState.size = sendState.index = 0;
+ sendState.sendMask = 0x01; //we send lsb first, shifting left
+
+ //set up the direction
+ PSX_DDR &= PSX_DDR_IN_MASK;
+ PSX_DDR |= PSX_DDR_OUT_MASK;
+
+ //set up the interrupts
+ //we listen for a high to low level transition on ATT (int1)
+ //we listen to both levels (falling, we change; rising, we read) (int0)
+ EICRA = ISC11 | ISC00;
+ EIMSK = INT1 | INT0;
+
+}
+
+/**
+ * Sets the data line (1)
+ */
+static void set_data(void)
+{
+ //we set the data to be an input
+ PSX_DDR &= ~PSX_DATA_MASK;
+ PSX_PORT |= PSX_DATA_MASK; //pull-up enabled
+}
+
+/**
+ * Resets the data line (0)
+ */
+static void reset_data(void)
+{
+ //we set the data to be an output
+ PSX_DDR |= PSX_DATA_MASK;
+ PSX_PORT &= ~PSX_DATA_MASK; //pull it low
+}
+
+char psx_send(unsigned char data)
+{
+ if (sendState.size == 5) {
+ return 0;
+ }
+
+ buffer[sendState.size] = data;
+
+ sendState.size++;
+
+ return sendState.size;
+}
+
+ISR(INT1_vect)
+{
+ //reset our transmission state
+ sendState.size = 0; //we set this first so thing is transmitted
+ sendState.index = 0;
+ sendState.sendMask = 0x01;
+
+ //notify that we have had our attention called
+ psx_on_att();
+}
+
+ISR(INT0_vect)
+{
+
+ if (PSX_PORT & PSX_CLK_MASK)
+ {
+ //rising edge: we can receive
+ }
+ else
+ {
+ if (sendState.index >= sendState.size)
+ {
+ //we have nothing to send
+ return;
+ }
+
+ //falling edge: we send
+ if (buffer[sendState.index] & sendState.sendMask)
+ {
+ //it is high
+ set_data();
+ }
+ else
+ {
+ //it is low
+ reset_data();
+ }
+
+ //we now increment our things
+ if (sendState.sendMask == 0x80)
+ {
+ //we have completed a byte and need to reset and increment
+ sendState.sendMask = 0x01;
+ sendState.index++;
+ }
+ else
+ {
+ sendState.sendMask = sendState.sendMask << 1;
+ }
+ }
+}

0 comments on commit 7a4fef3

Please sign in to comment.