futurecrew / patch-panel / patch-console.c

/**
 * \file Future crew patch panel
 *
 * Figure out which ports on the patch panel are cross connected
 */

#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <stdint.h>
#include <string.h>
#include <util/delay.h>
#include "usb_serial.h"
#include "bits.h"

void send_mem_str(const char *s);
uint8_t recv_str(char *buf, uint8_t size);
void parse_and_execute_command(const char *buf, uint8_t num);

static uint8_t
hexdigit(
	uint8_t x
)
{
	x &= 0xF;
	if (x < 0xA)
		return x + '0' - 0x0;
	else
		return x + 'A' - 0xA;
}


static const uint8_t ports[] = {
	0xB6,
	0xB5,
	0xB4,
	0xB3,
	0xB2,
	0xB1,
	0xB0,
	0xE7,
	0xE6,
	0xF0,
	0xF1,
	0xF2,
	0xF3,
	0xF4,
	0xF5,
	0xF6,
	0xF7,

	0xC7,
	0xC6,
	0xC5,
	0xC4,
	0xC3,
	0xC2,
	0xC1,
	0xC0,
	0xE1,
	0xE0,
	0xD7,
	0xD5,
	0xD4,
	0xD3,
	0xD2,
	0xD1,
	0xD0,
	0xB7,

/*
	0xA0,
	0xA1,
	0xA2,
	0xA3,
	0xA4,
	0xA5,
	0xA6,
	0xA7,
*/
};

#define INPUT_COUNT (sizeof(ports) / sizeof(*ports))
//#define INPUT_COUNT 28


int main(void)
{
	// set for 16 MHz clock
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
	CPU_PRESCALE(0);

	// Disable the ADC
	ADMUX = 0;

	// initialize the USB, and then wait for the host
	// to set configuration.  If the Teensy is powered
	// without a PC connected to the USB port, this 
	// will wait forever.
	usb_init();
	while (!usb_configured()) /* wait */ ;
	_delay_ms(1000);

	// wait for the user to run their terminal emulator program
	// which sets DTR to indicate it is ready to receive.
	while (!(usb_serial_get_control() & USB_SERIAL_DTR))
		continue;

	// discard anything that was received prior.  Sometimes the
	// operating system or other software will send a modem
	// "AT command", which can still be buffered.
	usb_serial_flush_input();

	// Activate pull ups on every port
	for (int i = 0 ; i < INPUT_COUNT ; i++)
	{
		ddr(ports[i], 0);
		out(ports[i], 1);
	}

	char line[128];

	while (1)
	{
		unsigned off = 0;
		uint8_t sw = PINA;
		line[off++] = hexdigit(sw >> 4);
		line[off++] = hexdigit(sw >> 0);

		// for each pin, set it low and then see which other
		// pins are pulled low
		for (int i = 0 ; i < INPUT_COUNT-1 ; i++)
		{
			out(ports[i], 0);
			ddr(ports[i], 1);

			for (int j = i + 1 ; j < INPUT_COUNT ; j++)
			{
				if (in(ports[j]))
					continue;
				line[off++] = ' ';
				line[off++] = hexdigit(i >> 4);
				line[off++] = hexdigit(i >> 0);
				line[off++] = ':';
				line[off++] = hexdigit(j >> 4);
				line[off++] = hexdigit(j >> 0);
			}

			ddr(ports[i], 0);
			out(ports[i], 1);
		}
		
		if (off == 0)
			continue;

		line[off++] = '\r';
		line[off++] = '\n';
		usb_serial_write(line, off);

		_delay_ms(250);
	}
}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.