here's the deal, it sort of works when writing... i have been just testing my routines with a simple loop of altering leds on two of the outputs (i have shut all my interrupts off for testing). it works for about 2-3 seconds and then stops...
while(1) {
data_a=~data_a;
MCP2317_WRITE(MCP_OLATA,data_a);
delay_ms(300);
}//end while loop
reading a button press works only once and then corresponding INTB pin stays set(reading page 25 of data sheet says this should only occur as long as readbit is same as register bit ie. until button it let go). if have tried different configurations of reading GPIO and INCAP registers as well as enabling/disabling the INTCONB register.
any suggestions, comments or ideas would be greatly appreciated. I need to use the interrupt pins which are also the hardware MSSP pins so i need a soft spi library(which mikroc has) but i also need clock clock data on falling edge (for the AD55453 dac). It would just be nice to be able to get this to work... i think im close. I have a 2channel USB scope that i have been monitoring data with, clock is around 666Khz. thank you ever so much. Dave
Code: Select all
// CONFIG_SPI
#define SPI_SDO LATC.F7
#define SPI_CLK LATC.F6
#define SPI_SDI PORTC.F2
#define MCP2317_EN LATC.F1
#define MCP_RESET LATC.F0
#define MCP_INTB PORTB.F5
#define AD5453_LEN LATE.F1
#define AD5453_REN LATE.F2
#define MCP_OPCODE_WRITE 0b01001110 // hpen enabled
#define MCP_OPCODE_READ 0b01001111
//************** REGISTER ADDRESSES ******************************
//**************** IOCON.BANK = 1 ********************************
#define MCP_IODIRA 0x00
#define MCP_IODIRB 0x10
#define MCP_IPOLA 0x01 //input polarity, 1=GPIO register bit will reflect
#define MCP_IPOLB 0x11 //opposite logic of input, 0 will be the same
#define MCP_GPINTENA 0x02 //interrupt on change, defval and intcon register must be altered
#define MCP_GPINTENB 0x12 //1= enable interrupt on change, 0 disable
#define MCP_DEFVALA 0x03 //enabled via GPINTEN and INTCON, oppostite value on pin will
#define MCP_DEFVALB 0X13 //cause interrupt to occur, these bits set the value to compare, set as pull up/down value
#define MCP_INTCONA 0X04 //interrupt control register if bit is set the i/o is compared to
#define MCP_INTCONB 0X14 //same bit in defval reg
#define MCP_IOCONA 0x05 //config register f.7=bank, f.3=HAEN (address enable)
#define MCP_IOCONB 0x15
#define MCP_GPPUA 0x06 //gpio pull up 100k resistor on input pin 1=pull up enable
#define MCP_GPPUB 0x16
#define MCP_INTFA 0x07 //int flag register indicates if it has been enable via GPINTEN reg
#define MCP_INTFB 0x17 //read only 1=pin cause interrupt
#define MCP_INTCAPA 0x08 //interrupt caputre gpio value at time int occured read only, remain
#define MCP_INTCAPB 0x18 //unchange until clead via read intcap or gpio
#define MCP_GPIOA 0x09 //read from this register reads port, writing modifies OLAT
#define MCP_GPIOB 0x19
#define MCP_OLATA 0x0A //reads olat not port itself, write modifies the outputs
#define MCP_OLATB 0x1A
//************** REGISTER ADDRESSES ******************************
//**************** IOCON.BANK = 0 ********************************
#define BANK0_IOCON 0x0A //BANK 0 USE AFTER RESET
const unsigned int ad5453_array[100] = //logrithmic volume table
{ 0x0000, 0x0003, 0x0009, 0x0010, 0x0034, 0x0049, 0x004E, 0x0052,
0X0057, 0x005C, 0x0062, 0x0067, 0x006E, 0x0074, 0x007B, 0x0082,
0x008A, 0x0092, 0x009B, 0x00A4, 0x00AE, 0x00B8, 0x00C3, 0x00CE,
0x00DA, 0x00E7, 0x00F5, 0x0104, 0x0113, 0x0123, 0x0135, 0x0147,
0x015A, 0x016F, 0x0185, 0x019C, 0x01B4, 0x01CE, 0x01E9, 0x0206,
0x0225, 0x0245, 0x0268, 0x028C, 0x02B3, 0x02DC, 0x0307, 0x0335,
0x0366, 0x0399, 0x03D0, 0x040A, 0x0447, 0x0488, 0x04CD, 0x0515,
0x0563, 0x05B4, 0x060B, 0x0666, 0x06C7, 0x072E, 0x072B, 0x080F,
0x0889, 0x090A, 0x0993, 0x0A25, 0x0ABF, 0x0B62, 0x0C03, 0x0CC5,
0x0B87, 0x0E54, 0x0F2D, 0x1013, 0x1107, 0x120A, 0x131B, 0x143D,
0x1570, 0x16B5, 0x180E, 0x197B, 0x1AFD, 0x1C96, 0x1E48, 0x2013,
0x21FA, 0x23FD, 0x261F, 0x2862, 0x2AC6, 0x2D4F, 0x2FFE, 0x32D6,
0x35D9, 0x390A, 0x3C6B, 0x3FFF }; //
char volume_str[4];
char spi_cnt, read_cnt, spi_byte_in, high_byte,low_byte;
int out_16bits;
//******************** SPI_IN *****************************************
int SPI_IN() {
read_cnt=0;
SPI_CLK=0;
while(read_cnt<8) {
SPI_CLK=1;
if(SPI_SDI==1) spi_byte_in.F0=1;
if(SPI_SDI==0) spi_byte_in.F0=0;
SPI_CLK=0;
if(read_cnt<7) spi_byte_in<<=1; //shift data to left by 1 until first bit read reaches MSB
read_cnt++;
}//end while
return spi_byte_in;
}
//******************** SPI_OUT_LOW2HIGH **********************************
void SPI_OUT_LOW2HIGH(char spi_byte) { //clock data in on rising edge
spi_cnt=0;
while(spi_cnt<8)
{
SPI_CLK=0;
if(spi_byte.F7==1) SPI_SDO=1; //test msb and set output accordingly
if(spi_byte.F7==0) SPI_SDO=0;
SPI_CLK=1;
spi_byte<<=1; //shift data to left by one
spi_cnt++;
}
}
//************************ SPI_OUT_HIGH2LOW **********************************
void SPI_OUT_HIGH2LOW(char ad5453_byte) { //clock data on falling edge
spi_cnt=0;
while(spi_cnt<8)
{
SPI_CLK=1;
if(ad5453_byte.F7==1) SPI_SDO=1;
if(ad5453_byte.F7==0) SPI_SDO=0;
SPI_CLK=0;
ad5453_byte<<=1; //shift data to left by one
spi_cnt++;
}
}
//****************** MCP2317_WRITE***************************************
void MCP2317_WRITE(char address, char spi_data) {
MCP2317_EN=0;
SPI_OUT_LOW2HIGH(MCP_OPCODE_WRITE); //io config
SPI_OUT_LOW2HIGH(address);
SPI_OUT_LOW2HIGH(spi_data);
MCP2317_EN=1;
}
//*************************MCP2317_READ***************************************
int MCP2317_READ(char address_read) {
MCP2317_EN=0;
SPI_OUT_LOW2HIGH(MCP_OPCODE_READ); //io config
SPI_OUT_LOW2HIGH(address_read);
SPI_IN();
MCP2317_EN=1;
return spi_byte_in;
}
//********************* AD5453_OUT ************************************
void AD5453_OUT(char volume_out) {
out_16bits = ad5453_array[volume_out]; //convert array value to int
low_byte=out_16bits; //extract low byte
high_byte=out_16bits>>=8; //extract hig byte
high_byte=high_byte&0b00111111; // mask bits 15&14 (control for AD5453) clock on falling edge
AD5453_LEN=0;
AD5453_REN=0;
SPI_OUT_LOW2HIGH(high_byte);
SPI_OUT_LOW2HIGH(low_byte);
AD5453_LEN=1;
AD5453_REN=1;
}
//********************AD_SPI_HIGH2LOW**************************
void AD5453_OUT_CONFIG_LOWTOHIGH() { //config ad5453 to clock
//data on rising edge
AD5453_LEN=0; //load default state (clk high to low)
AD5453_REN=0;
SPI_OUT_HIGH2LOW(0b00000000);
SPI_OUT_HIGH2LOW(0x00);
AD5453_LEN=1;
AD5453_REN=1;
delay_us(1);
AD5453_LEN=0;
AD5453_REN=0;
SPI_OUT_HIGH2LOW(0b11000000); //send control bits to
SPI_OUT_HIGH2LOW(0x00); //clock on low to high
AD5453_LEN=1;
AD5453_REN=1;
delay_us(1);
AD5453_LEN=0;
AD5453_REN=0;
SPI_OUT_HIGH2LOW(0b00000000); //clk in new control byte
SPI_OUT_HIGH2LOW(0x00); //using high to low clock
AD5453_LEN=1;
AD5453_REN=1;
delay_us(1);
AD5453_LEN=0;
AD5453_REN=0;
SPI_OUT_LOW2HIGH(0b00000000); //clk in data low2high as 0x00
SPI_OUT_LOW2HIGH(0x00);
AD5453_LEN=1;
AD5453_REN=1;
}
//***********************CONFIG SPI*********************************************
//******************************************************************************
void CONFIG_SPI() {
AD5453_LEN=1;
AD5453_REN=1;
MCP2317_EN=1;
SPI_CLK = 0;
MCP_RESET = 1;
MCP_RESET = 0; //reset MCP device
delay_ms(1);
MCP_RESET = 1;
MCP2317_WRITE(BANK0_IOCON,0b10101000); //seperate port a and b hpen enable(address)
MCP2317_WRITE(MCP_IODIRA,0x00); //port a outputs
MCP2317_WRITE(MCP_OLATA,0xFF); //turn all port a on
MCP2317_WRITE(MCP_IODIRB,0b1100011); // port b inputs
MCP2317_WRITE(MCP_GPINTENB,0b11000011); //set interrupt on change
MCP2317_WRITE(MCP_DEFVALB,0xFF); //pull up resistor used
//MCP2317_WRITE(MCP_DEFVALB,0x00); //pull down resistor used
MCP2317_WRITE(MCP_INTCONB,0xFF); //compare to defval register
//MCP2317_WRITE(MCP_INTCONB,0x00); //compare to previous value
AD5453_OUT_CONFIG_LOWTOHIGH();
AD5453_OUT(0x00);
}//end config_spi