I'm working on a device for the TI-83+/TI-84+ a bit similar to the Innovator Hub but you control it through the link port rather than the USB port, although it still has to be externally powered to be used, such as through miniUSB as is what I am using.
I plan for it to have 8 output pins and 8 input pins as the final goal.
Note that I have no education in electronics so if some of my designs seem nonsensical don't be afraid to tell me, I am just figuring things out as I go along.
I plan for it to be compatible with assembly, C, and TI-BASIC.
I have gotten the output pins to work on a breadboard. You can see me using some of them to drive a LED matrix display here:
As you can tell, it is WAY faster than doing the same thing on the Innovator Hub.
This is because the code to control it is written in C and not TI-BASIC.
Here's the code I used to draw the smiley face to the display:
main.c
Code:
wiringTi.h
Code:
wiringTi.c
Code:
As you can tell, I modeled it after wiringPi, because that's what I'm familiar with.
Each of the 8 output pins you can write to individually. The only issue I'm having is that the tiniest bit of noise, like if you wiggle the cable or something, causes the hardware to get out of sync with the software, and neither will work until you restart both of them.
A latched shift register requires 3 inputs to drive it: SER, SRCLK, and RCLK. The calculator only has 2 data pins. So what I'm doing is using a counter to track how many bits you've pushed onto the shift register to toggle RCLK for you when it is full.
I could also use that same counter to connect it to an 8-to-1 multiplexer for reading pins but I don't have a multiplexer right now.
I plan for it to have 8 output pins and 8 input pins as the final goal.
Note that I have no education in electronics so if some of my designs seem nonsensical don't be afraid to tell me, I am just figuring things out as I go along.
I plan for it to be compatible with assembly, C, and TI-BASIC.
I have gotten the output pins to work on a breadboard. You can see me using some of them to drive a LED matrix display here:
As you can tell, it is WAY faster than doing the same thing on the Innovator Hub.
This is because the code to control it is written in C and not TI-BASIC.
Here's the code I used to draw the smiley face to the display:
main.c
Code:
#include "ti83plus.h"
#include "wiringTi.h"
#define PIN_CLK 0
#define PIN_CS 1
#define PIN_DIN 2
void sendData(uint16 data) {
uint8 i;
for (i = 0; i < 16; i++) {
if (data & 0b1000000000000000) digitalWrite(PIN_DIN, HIGH);
else digitalWrite(PIN_DIN, LOW);
digitalWrite(PIN_CLK, HIGH);
digitalWrite(PIN_CLK, LOW);
data = data << 1;
}
digitalWrite(PIN_CS, HIGH);
digitalWrite(PIN_CS, LOW);
}
void bootDisplay() {
sendData(0b0000101100000111);
sendData(0b0000100100000000);
sendData(0b0000110000000001);
sendData(0b0000111100000000);
}
void drawImage(uint8 image[8]) {
uint8 i;
uint16 row;
for (i = 0; i < 8; i++) {
row = (i + 1) << 8;
sendData(row | image[i]);
}
}
void main() {
uint8 image[8];
image[0] = 0b00111100;
image[1] = 0b01000010;
image[2] = 0b10100101;
image[3] = 0b10000001;
image[4] = 0b10100101;
image[5] = 0b10011001;
image[6] = 0b01000010;
image[7] = 0b00111100;
wiringTiSetup();
bootDisplay();
drawImage(image);
}
wiringTi.h
Code:
#define HIGH 1
#define LOW 0
#define WIRING_TI_SER 1
#define WIRING_TI_CLK 2
#define WIRING_TI_DELAY 0
uint8 WIRING_TI_PINS;
void wiringTiSetup();
void _writeToBoard();
void _writeToLinkPort(uint8 pinCode);
void _readFromLinkPort(uint8 *pinCode);
void delay(uint16 ms);
void digitalWrite(uint8 pin, uint8 mode);
#include "wiringTi.c"
wiringTi.c
Code:
void wiringTiSetup() {
WIRING_TI_PINS = 0b00000000;
_writeToBoard();
}
void _writeToBoard() {
uint8 i, bit, pins;
pins = WIRING_TI_PINS;
for (i = 0; i < 8; i++) {
if (pins & 0b10000000) bit = WIRING_TI_SER;
else bit = 0;
_writeToLinkPort(bit);
delay(WIRING_TI_DELAY);
_writeToLinkPort(WIRING_TI_CLK | bit);
delay(WIRING_TI_DELAY);
_writeToLinkPort(bit);
delay(WIRING_TI_DELAY);
pins = pins << 1;
}
_writeToLinkPort(0b00);
}
void _writeToLinkPort(uint8 pinCode) {
__asm
ld a, 4(ix)
out (0x00), a
__endasm;
(void)pinCode;
}
void _readFromLinkPort(uint8 *pinCode) {
__asm
in a, (0x00)
ld h, 5(ix)
ld l, 4(ix)
ld (hl), a
__endasm;
(void)pinCode;
}
//This function wastes 6000 clock cycles per 1 ms.
// There is roughly 209 clock cycles of overhead, but this can vary slightly based on how this routine is called. This means if you delay for 10 ms, you will actually delay for about 60,209 clock cycles.
void delay(uint16 ms) {
__asm
ld de, #0
ld h, 5(ix)
ld l, 4(ix)
add hl, de
ld a, #0
or a, h
or a, l
cp #0
.db #0x28
.db #0x0F
dec hl
ld a, #108
ld de, #0
add hl, de
add hl, de
dec a
cp #0
.db #0x20
.db #0xF6
.db #0x18
.db #0xE8
__endasm;
(void)ms;
return;
}
void digitalWrite(uint8 pin, uint8 mode) {
pin = 1 << pin;
if (mode == HIGH) WIRING_TI_PINS |= pin;
else if (WIRING_TI_PINS & pin) WIRING_TI_PINS ^= pin;
_writeToBoard();
}
As you can tell, I modeled it after wiringPi, because that's what I'm familiar with.
Each of the 8 output pins you can write to individually. The only issue I'm having is that the tiniest bit of noise, like if you wiggle the cable or something, causes the hardware to get out of sync with the software, and neither will work until you restart both of them.
A latched shift register requires 3 inputs to drive it: SER, SRCLK, and RCLK. The calculator only has 2 data pins. So what I'm doing is using a counter to track how many bits you've pushed onto the shift register to toggle RCLK for you when it is full.
I could also use that same counter to connect it to an 8-to-1 multiplexer for reading pins but I don't have a multiplexer right now.