<?php
/*********************************************
Project : PG 8x8 Midi Matrix
Version : 0.1
Date : 17.9.2002
Author : Matti Leino
Company : Project Groove
PG 8x8 Midi Matrix uses MAXIMs MAX456 video crosspoint switch to route midi signals.
See Maxims datasheet for information: http://www.maxim-ic.com
If you have any questions, feel free to ask: mle@nic.fi
And of course, this code is GPL, so use it any way you want, but please keep these commanted lines in code.
(c) Matti Leino
Chip type : AT90S2313
Clock frequency : 4,000000 MHz
Memory model : Tiny
Internal SRAM size : 128
External SRAM size : 0
Data Stack size : 32
------ss
---------------------------------------
IOs
PortB 0 LCD RS
PortB 1 LCD RD
PortB 2 LCD EN
PortB 3 free (output)
PortB 4 LCD DB4
PortB 5 LCD DB5
PortB 6 LCD DB6
PortB 7 LCD DB7
PortD 0 free (input)
PortD 1 Rotary Encoder Input A
PortD 2 Rotary Encoder Input B (Ext IRQ 0)
PortD 3 Exec-button (Ext IRQ 1)
PortD 4 /LATCH for matrix
PortD 5 DATA for matrix
PortD 6 WR/SCLK for matrix
---------------------------------------------
*********************************************/
#include <90s2313.h>
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x18
#endasm
#include <lcd.h>
#include <delay.h>
#include <stdio.h>
/***************************************
* Global constants *
***************************************/
#define ENC_CH_A !PIND.1
#define ENC_CH_B !PIND.2
#define EXEC !PIND.3
#define CP_LATCH PIND.4
#define CP_DATA PIND.5
#define CP_WR PIND.6
typedef unsigned char byte;
/*************************************************
* There's two special characters defined. *
* outOff indicates, as you propably can imagine, *
* if output is not selected for current input. *
* outOn if output is selected *
*************************************************/
flash byte outOff[8]=
{
0b0000000,
0b0011111,
0b0010001,
0b0010001,
0b0010001,
0b0011111,
0b0000000,
0b0000000
};
flash byte outOn[8]=
{
0b0000000,
0b0011111,
0b0011111,
0b0011111,
0b0011111,
0b0011111,
0b0000000,
0b0000000
};
/******************************************
* This function is straightly copy/pasted *
* from CodeVisions manual *
*******************************************/
void define_char(byte flash *pc,byte char_code)
{
byte i,a;
a = (char_code<<3) | 0x40;
for(i = 0; i < 8; i++) lcd_write_byte(a++,*pc++);
}
/***************************************
* Global variables *
***************************************/
eeprom byte savedOutArray[8] = { 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9 };
byte inputOpCodes[8] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 };
byte outputSel[8] = { 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9 };
unsigned char execValue = 0;
unsigned char new_limit = 8;
unsigned char buff[9];
unsigned char work0 = 0;
unsigned char work1 = 0;
unsigned char exec_counter = 0;
unsigned char encValue = 0;
unsigned char inputValue = 0;
unsigned char i = 0;
unsigned long int CP_data;
/***************************************
* Global functions *
***************************************/
void setupIO(void);
void initLCD(void);
void chooseInput(void);
void chooseOutput(void);
void crunchData(void);
void setCP(void);
void save_e2(void);
/***************************************
* External Interrupt 0 service routine *
***************************************/
interrupt [EXT_INT0] void ext_int0_isr(void)
{
if(!ENC_CH_A)
{
if(encValue < new_limit)
{
encValue++;
delay_ms(15);
}
else
{
encValue = 0;
delay_ms(15);
}
}
else
{
if(encValue != 0)
{
encValue--;
delay_ms(15);
}
else
{
encValue = new_limit;
delay_ms(15);
}
}
delay_ms(55);
}
/***************************************
* External Interrupt 1 service routine *
***************************************/
interrupt [EXT_INT1] void ext_int1_isr(void)
{
while(EXEC)
{
exec_counter++;
delay_ms(100);
}
if(exec_counter <= 35)
{
execValue = 1;
delay_ms(50);
}
else
save_e2();
exec_counter = 0;
}
/***************************************
* MAIN *
***************************************/
void main(void)
{
setupIO();
define_char(outOff,0);
define_char(outOn,1);
_lcd_ready();
_lcd_write_data(0xe);
lcd_gotoxy(0,0);
sprintf(buff, "in:%-1uout:", encValue+1);
lcd_puts(buff);
for(i = 0; i < 8; i++)
outputSel[i] = savedOutArray[i];
initLCD();
lcd_gotoxy(3,0);
crunchData();
setCP();
/***************************************
* Main loop *
***************************************/
while (1)
{
if(encValue == 0)
lcd_gotoxy(3,0);
else
lcd_gotoxy(encValue-1,1);
if(encValue == 0 && execValue == 1)
{
chooseInput();
delay_ms(250);
encValue = 0;
execValue = 0;
}
if(encValue != 0 && execValue == 1)
{
chooseOutput();
}
};
}
/**************************************************************************************/
/***************** FUNCTIONS ***************/
/**************************************************************************************/
void setupIO(void)
{
// Declare your local variables here
// Input/Output Ports initialization
// Port B
PORTB=0x00;
DDRB=0xFF;
// Port D
PORTD=0x1F;
DDRD=0x70;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Output Compare
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Output Compare
// OC1 output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// These has been disabled cause of the lack of the code memory...=)
/*
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
OCR1H=0x00;
OCR1L=0x00;
*/
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Low level
// INT1: On
// INT1 Mode: Low level
GIMSK=0xC0;
MCUCR=0x00;
GIFR=0xC0;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
// LCD module initialization
lcd_init(8);
// Global enable interrupts
#asm("sei")
}
/*******************************************************************************************************/
void initLCD(void)
{
for(i = 0; i < 8; i++)
{
lcd_gotoxy(i,1);
if( outputSel[i] == inputOpCodes[inputValue-1] ) //(outputSel[i] != 0xa)
lcd_putchar(1);
else
lcd_putchar(0);
}
}
/*******************************************************************************************************/
void chooseInput(void)
{
new_limit = 7;
execValue = 0;
while( execValue == 0 )
{
inputValue = encValue+1;
lcd_gotoxy(3,0);
sprintf(buff, "%-1u", inputValue);
lcd_puts(buff);
initLCD();
lcd_gotoxy(0,0);
delay_ms(50);
};
new_limit = 8;
}
/*******************************************************************************************************/
void chooseOutput(void)
{
lcd_gotoxy(encValue-1,1);
execValue = 0;
if(outputSel[encValue-1] != 0x9)
{
lcd_putchar(0);
outputSel[encValue-1] = 0x9;
}
else
{
lcd_putchar(1);
outputSel[encValue-1] = inputOpCodes[inputValue-1];
}
lcd_gotoxy(encValue-1,1);
crunchData();
setCP();
}
/*******************************************************************************************************/
void crunchData(void)
{
for(i = 0; i < 8; i+=2)
{
work0 = 0;
work1 = 0;
work0 = outputSel[i];
work1 = outputSel[i+1];
work0 <<= 4; // Shiftataan 4 bittiä vasuriin...
work0 &= 0xF0;
work0 |= work1; // Oorataan siihen work1 -> saadaan tavu, jossa4 ylintä on work0, ja 4 alinta work1
CP_data |= work0; // Oorataan se CP_dataan.
if( i < 6 )
CP_data <<= 8; // Shiftataan 8 vasuriin.
}
/*
sprintf(buff,"%-lu",CP_data);
lcd_gotoxy(0,1);
lcd_puts(buff);
delay_ms(5000);
initLCD();
*/
}
/*******************************************************************************************************/
void save_e2(void)
{
for(i = 0; i < 8; i++)
savedOutArray[i] = outputSel[i];
lcd_gotoxy(0,1);
lcd_putsf("Saved! ");
delay_ms(3000);
initLCD();
}
/*******************************************************************************************************/
void setCP(void)
{
CP_LATCH = 0;
for(i = 0; i < 32; i++)
{
#asm
bst r23,7
in r0,0x10
bld r0,5
out 0x10,r0
#endasm
CP_data <<= 1;
CP_WR = 1; // Kellotetaan Crosspointille.
CP_WR = 0;
}
delay_us(5);
CP_LATCH = 1;
}
// End Of File
/* for(i = 32; i > 0; i--)
{
CP_DATA = (CP_data << i) & 0x1;
CP_WR = 1; // Kellotetaan Crosspointille.
CP_WR = 0;
}*/
/*
CP_LATCH = 0;
delay_ms(500);
CP_LATCH = 1;
CP_DATA = 0;
delay_ms(500);
CP_DATA = 1;
CP_WR = 0;
delay_ms(500);
CP_WR = 1;
CP_DATA = 0;
delay_ms(500);
CP_DATA = 1;
*/
?>