Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 8 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,14 @@ Cute Mouse Driver is part of FreeDos project and is free and open source.
## Jumper Settings

There are two jumpers, which can be used to set different modes. Currently you
can choose between 2- and 3-button mouse modes and select so called remote and
streaming mode. Remote mode sends mouse data all the time and has a better
response times in current implementation. Streaming mode sends only data, when
mouse position or button state changes. Unfortunately, this mode is currently
not in a good shape. It has a higher delay and can result in some timing
issues. However, it is interesting to have it for experimental purpose. Default
values are when the jumpers are unset.

JP1 | Setting |Description
----|---------|------------------------------
1-2 | unset | 3-button Logitech mouse
1-2 | set | 2-button Microsoft mouse
3-4 | unset | remote mode
3-4 | set | streaming mode (experimental)
can choose between 2-button, 3-button, and wheel mouse modes. In the table below, O means open or unset, and X means closed or set.

JP1 |JP2 |Description
-----|-----|------------------------------
O | O | 3-button Logitech mouse
X | O | 2-button Microsoft mouse
O | X | Wheel mouse (cutemouse driver required)
X | X | Undefined (2-button mode will override)

## Bill of materials

Expand Down
2 changes: 2 additions & 0 deletions firmware/ps2adapter/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.pio
.vscode
122 changes: 122 additions & 0 deletions firmware/ps2adapter/LEDMessenger.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#include <Arduino.h>
#include "LEDMessenger.h"
#include "ProMini.h"


LEDMessenger::LEDMessenger() {
list = NULL;
length = 0;
m_timerResolution = 10;
m_nextMessageDelay = 0;
};

LEDMessenger::~LEDMessenger() {
while (list) {
node *tmp = list;
list = list->next;
delete tmp;
}
};

LEDMessenger* LEDMessenger::instance = NULL;

void LEDMessenger::TimerStatic() {
LEDMessenger::instance->update();
};

typedef void (*voidFuncPtr)(void);
static volatile voidFuncPtr intFunc = NULL;

ISR(TIMER1_OVF_vect)
{
TCNT1 = 45535; // Timer Preloading
if (intFunc != NULL)
intFunc();
}

void LEDMessenger::start() {
instance = this;
intFunc = TimerStatic;
LED_SETLOW();
TCCR1A = 0; // Init Timer1A
TCCR1B = 0; // Init Timer1B
TCCR1B |= B00000010; // Prescaler = 64
TCNT1 = 45535; // Timer Preloading
TIMSK1 |= B00000001; // Enable Timer Overflow Interrupt
};

void LEDMessenger::push(int delay, int repeat, int nextMessageDelay) {
node *newNode = new node;
newNode->item.state = HIGH;
newNode->item.stepDelay = delay;
newNode->item.curStepDelay = delay;
newNode->item.repeat = repeat;
newNode->item.nextMessageDelay = nextMessageDelay;
newNode->next = NULL;
if (list) {
node *tmp = list;
while (tmp->next) {
tmp = tmp->next;
}
tmp->next = newNode;
} else {
list = newNode;
}
length++;
};

void LEDMessenger::pop() {
if (list) {
node *tmp = list;
list = list->next;
delete tmp;
length--;
}
};

LEDMessenger::LEDMessage* LEDMessenger::get() {
if (list) {
return &(list->item);
} else {
return NULL;
};
};

int LEDMessenger::size() {
return length;
};

void LEDMessenger::update() {
if (m_nextMessageDelay > 0) {
m_nextMessageDelay -= m_nextMessageDelay;
return;
}

LEDMessenger::LEDMessage* pItem = get();
if (pItem) {
LED_SET(pItem->state);
if (pItem->curStepDelay > 0) {
pItem->curStepDelay -= m_timerResolution;
} else {
pItem->curStepDelay = pItem->stepDelay;
pItem->state = HIGH - pItem->state;
// one full HIGH -> LOW -> HIGH transistion
if (pItem->state == HIGH) {
// continous blink
if (pItem->repeat < 0) {
// waiting message
if (size() > 1) {
m_nextMessageDelay = pItem->nextMessageDelay;
pop();
}
return;
}
pItem->repeat--;
if (pItem->repeat <= 0) {
m_nextMessageDelay = pItem->nextMessageDelay;
pop();
}
}
}
}
}
38 changes: 38 additions & 0 deletions firmware/ps2adapter/LEDMessenger.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#pragma once

class LEDMessenger
{
public:
LEDMessenger();
~LEDMessenger();
void start();
void push(int delay, int repeat, int nextMessageDelay);

private:
int m_timerResolution;
int m_nextMessageDelay;
static LEDMessenger *instance;

struct LEDMessage {
byte state;
int repeat;
int stepDelay;
int curStepDelay;
int nextMessageDelay;
};

typedef struct node
{
LEDMessage item;
node *next;
} node;

node *list;
int length;

void update();
static void TimerStatic();
void pop();
LEDMessage* get();
int size();
};
74 changes: 74 additions & 0 deletions firmware/ps2adapter/ProMini.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#pragma once
/*
* Created by Jason Hill
* 2023/06/18
*
* Updated by Peter Edwards
* 2024/01/02
*
*/

/****************************************************
* The following defines assume default pinout
* of Arduino Pro Mini or similiar:
*
* PS2_CLOCK = 2; //PD2 - Port D, bit 2
* PS2_DATA = 17;//PC3 - Port C, bit 3
*
* RS232_RTS = 3; //PD3 - Port D, bit 3
* RS232_TX = 4; //PD4 - Port D, bit 4
*
* JP12 = 11; //PB3 - Port B, bit 3
* JP24 = 12; //PB4 - Port B, bit 4
* LED = 13; //PB5 - Port B, bit 5
*
* The following defines Pin and Port addressing to
* more quickly set individual pins to their desired
* states.
*/

/****************************************************/
/* PS/2 data pin operations */
#define PS2_DATA_BIT (_BV(3))
#define PS2_SETDATAHIGH() ( PORTC |= PS2_DATA_BIT )
#define PS2_SETDATALOW() ( PORTC &= ~PS2_DATA_BIT )
#define PS2_SETDATA(val) (val) ? PS2_SETDATAHIGH() : PS2_SETDATALOW()
#define PS2_DIRDATAIN() ( DDRC &= ~PS2_DATA_BIT )
#define PS2_DIRDATAIN_UP() ( DDRC &= ~PS2_DATA_BIT )
#define PS2_DIRDATAOUT() ( DDRC |= PS2_DATA_BIT )
#define PS2_READDATA() ( (PINC &= PS2_DATA_BIT)>>3 )

#define PS2_CLOCK_BIT (_BV(2))
#define PS2_SETCLOCKHIGH() ( PORTD |= PS2_CLOCK_BIT )
#define PS2_SETCLOCKLOW() ( PORTD &= ~PS2_CLOCK_BIT)
#define PS2_SETCLOCK(val) (val) ? PS2_SETCLOCKHIGH() : PS2_SETCLOCKLOW()
#define PS2_DIRCLOCKIN() ( DDRD &= ~PS2_CLOCK_BIT )
#define PS2_DIRCLOCKIN_UP() ( DDRD &= ~PS2_CLOCK_BIT ); PS2_SETCLOCKHIGH()
#define PS2_DIRCLOCKOUT() ( DDRD |= PS2_CLOCK_BIT )
#define PS2_READCLOCK() ( (PIND &= PS2_CLOCK_BIT)>>2 )

/****************************************************/
/* RS-232 pin operations */
#define RS_SETTXHIGH() (PORTD |=0b00010000)
#define RS_SETTXLOW() (PORTD &=0b11101111)
#define RS_SETTX(val) (val) ? RS_SETTXHIGH() : RS_SETTXLOW()
#define RS_DIRTXOUT() (DDRD |=0b00010000)

/****************************************************/
/* JUMPER pin operations */
#define JP12_SETHIGH() (PORTB |=0b00001000)
#define JP12_DIRIN() (DDRB &=0b11110111)
#define JP12_DIRIN_UP() (DDRB &=0b11110111); JP12_SETHIGH()
#define JP12_READ() ((PINB &=0b00001000)>>3)

#define JP34_SETHIGH() (PORTB |=0b00010000)
#define JP34_DIRIN() (DDRB &=0b11101111)
#define JP34_DIRIN_UP() (DDRB &=0b11101111); JP34_SETHIGH()
#define JP34_READ() ((PINB &=0b00010000)>>4)

/****************************************************/
/* LED pin operations */
#define LED_SETHIGH() (PORTB |=0b00100000)
#define LED_SETLOW() (PORTB &=0b11011111)
#define LED_SET(val) (val) ? LED_SETHIGH() : LED_SETLOW()
#define LED_DIROUT() (DDRB |=0b00100000)
Loading