So I have been working on this on my own time, I am a potential CE student. This was an assignment for someone who gave it to me along with caped BBB. I am running barebones using CCS and a TI XDS100v2 USB Debug Probe/CortxA8 sim. They wrote this program as an LCD driver using the I2C1 bus from the BBB.
I am trying to use this code to send a signal to the PWM PCA9685 LED15 pin to full ON. I am trying to configure the pins (19/20) on the BBB to use the I2C2 in Mode3 on the P9 connector The datasheet is here https://cdn-shop.adafruit.com/datasheets/PCA9685.pdf
Here is the code so far: It will run through the cases and go to the endless loop, but am not getting a signal on the pin 15 of the PCA9685. I am trying to just send two bytes at a time and I think this is what is wrong with the code, but I have been debugging.
// Define Indirect Addressing Macro for Registers
#define HWREG(x) (*((volatile unsigned int *)(x)))
// Common Defines
#define TRUE 1
#define FALSE 0
#define DELAY_COUNT 100000
// Base Module Defines
#define CTRLMOD_BASE 0x44E10000
#define CM_PER_BASE 0x44E00000
#define I2C2_BASE 0x4819C000
// Control Module Defines
#define CONF_I2C2_SCL 0x97C
#define CONF_I2C2_SDA 0x978
#define MODE3 0x3B
// Peripheral Control Module Defines
#define CM_PER_I2C2_CLKCTRL 0x44
#define CLK_ENABLE 0x2
// DRM Register Offset Defines
#define I2C_2_SUSPEND_CTRL 0x230
// Register Address Offset Defines
#define I2C_SA 0xAC
#define I2C_CNT 0x98
#define I2C_DATA 0x9C
#define I2C_IRQSTATUS_RAW 0x24
#define I2C_CON 0xA4
#define I2C_PSC 0xB0
#define I2C_SCLL 0xB4
#define I2C_SCLH 0xB8
#define I2C_BUFSTAT 0xC0
#define I2C_IRQENABLE_SET 0x2C
// I2C Register Values
#define _12MHZ_CLK 0x03
#define tLOW 0x08
#define tHIGH 0x0A
#define I2C2_ENABLE 0x8600
#define IRQ_DISABLED 0x0000
// Mask Defines
#define DCOUNT_VAL 0x0000FFFF
#define XRDY_RDY 0x00000010
#define XRDY_BIT 0x00000010
#define RRDY_BIT 0x00000008
#define RRDY_RDY 0x00000008
#define BF_BIT 0x00001000
#define BUS_IS_FREE 0
#define DATA_VAL 0xFF
#define BUFSTAT_VAL 0x0000003F
//I2C Communication Defines
#define SLAVE_ADDR 0x40
#define NUM_OF_DBYTES 10
#define START_COND 0x00000001
#define STOP_COND 0x00000002
#define MASTER_TX_MODE 0x600
#define NAME_BYTE_LENGTH 13
// General registers
#define PCA9685 0x80
// I2C address for PCA9865 with all inputs at zero
#define Reset 0x01 // Reset the device
#define MODE1 0x00 // 0x00 location for Mode1 register address
#define MODE2 0x01 // 0x01 location for Mode2 register address
#define PRE_SCALE 0xFE // Prescaler address
#define P_S_VALUE 0x79 // PWM frequency value
// MODE1 bits PCA9685
#define PCA96_INIT 0x11
#define LED15_ADD 0x43
// Variables
unsigned int x;
unsigned int y;
volatile unsigned int USR_STACK[100];
volatile unsigned int IRQ_STACK[100];
void wait(void){
while(1){
// Endless loop
};
}
void delay(unsigned long int y){
while(y>0){
y–;
}
}
int is_bus_free(void){
x = HWREG(I2C2_BASE + I2C_IRQSTATUS_RAW); //Read mask 0x00001000 from I2C_IRQSTATUS_RAW (I2C Status Raw Register) offset 0x24 to check bus status.
x = (x & BF_BIT); //Mask.
if(x == BUS_IS_FREE) return 1;
else return 0;
}
int is_i2c_write_ready(void){
x = HWREG(I2C2_BASE + I2C_IRQSTATUS_RAW); //Read mask 0x00000010 from I2C_IRQSTATUS_RAW (I2C Status Raw Register) offset 0x24 to see if write ready
x = (x & XRDY_BIT); //Mask.
if(x == XRDY_RDY) return 1;
else return 0;
}
void startstop_condition(void){
HWREG(I2C2_BASE + I2C_CON) = 0x8603; //Read-Modify-Write 0x8603 to I2C_CON (Configuration Register) offset 0xA4 to queue Start/Stop Condition.
// x = (x | START_COND | STOP_COND); //Mask.
// HWREG(I2C2_BASE + I2C_CON) = x; //Write back. //Write back.
}
void config_master_transmitter(void){
x = HWREG(I2C2_BASE + I2C_CON); //Read-Modify-Write 0xE00 to I2C_CON (Configuration Register)offset 0xA4 to configure mode.
x = (x | MASTER_TX_MODE); //Mask.
HWREG(I2C2_BASE + I2C_CON) = x; //Write back.
}
void set_num_databytes(unsigned int y){
// y = (y & DCOUNT_VAL);
//Number of Data Bytes pre-transmission.
HWREG(I2C2_BASE + I2C_CNT) = y;
}
void write_to_bus(unsigned char x){
x = (x & DATA_VAL );
HWREG(I2C2_BASE + I2C_DATA) = x; //Write to data bus.
delay(2000);
}
void set_slave_addr(unsigned int x){
//Slave address pre-transmission.
HWREG(I2C2_BASE + I2C_SA) = x; //Write 0x40 to I2C_SA (Slave Address Register) offset 0xAC Slave address value
}
//P9 Connector settings.
HWREG(CTRLMOD_BASE + CONF_I2C2_SCL) = 0x3B; //Write 0x3B to conf_uart1_rtsn offset 0x97C to enable (SCL) for MODE3 w/o pullup
HWREG(CTRLMOD_BASE + CONF_I2C2_SDA) = 0x3B; //Write 0x3B to conf_uart1_ctsn offset 0x978 to enable (SDA) for MODE3 w/o pullup
//Enable Clock to I2C2.
HWREG(CM_PER_BASE + CM_PER_I2C2_CLKCTRL) = CLK_ENABLE; //Write 0x2 to CM_PER_I2C2_CLKCTRL offset 0x48 to enable I2C2 Clock.
//Configure I2C2.
HWREG(I2C2_BASE + I2C_PSC) = _12MHZ_CLK; //Write 0x03 to I2C_PSC (Clock Prescalar Register) offset 0xB0 for ICLK of 12 MHz
HWREG(I2C2_BASE + I2C_SCLL) = tLOW; //Write 0x08 to I2C_SCLL (SCL Low Time Register) offset 0xB4 for tLOW to get 400kbps (1.25usec)
HWREG(I2C2_BASE + I2C_SCLH) = tHIGH; //Write 0x0A to I2C_SCLH (SCL High Time Register) offset 0xB8 for tHIGH to get 400kbps (1.25usec)
HWREG(I2C2_BASE + I2C_CON) = I2C2_ENABLE; //Write 0x8603 to I2C_CON (Configuration Register) offset 0xA4 to take out of reset, enable I2C2 module
//config_master_transmitter();
// HWREG(I2C2_BASE + I2C_IRQENABLE_SET) = IRQ_DISABLED;
set_slave_addr(SLAVE_ADDR);
}
void init_pwm(case_0){
HWREG(I2C2_BASE + I2C_IRQSTATUS_RAW) = 0x00000114;
HWREG(I2C2_BASE + I2C_CON) = I2C2_ENABLE; //Write 0x8603 to I2C_CON (Configuration Register) offset 0xA4 to take out of reset, enable I2C2 module
// config_master_transmitter();
//unsigned int current_DCOUNT;
// set_slave_addr(SLAVE_ADDR);
while(is_bus_free() != TRUE){
}
//set_num_databytes(0x2);
//startstop_condition();
//while((HWREG(I2C2_BASE + I2C_BUFSTAT) & BUFSTAT_VAL) > 0){
//current_DCOUNT = HWREG(I2C2_BASE + I2C_BUFSTAT) & BUFSTAT_VAL;
//while(is_bus_free() != TRUE){
//}
//set_num_databytes(0x2);
//startstop_condition();
if(is_i2c_write_ready()){//If ready to write
set_num_databytes(0x2);
startstop_condition();
switch(case_0){
case 0:
write_to_bus(0x00); //send 0x11 to Mode1 to set sleep and respond to AllCall
write_to_bus(0x11);
break;
case 1:
write_to_bus(0xFE); //send 0x79 for Prescaler (using formula)
write_to_bus(0x79);
break;
case 2:
write_to_bus(0x00);
write_to_bus(0x81); //Send 0x81 to enable RESTART,ALLCALL,INT_CLK,NORM_MODE
break;
case 3:
write_to_bus(0x01);
write_to_bus(0x04); //Send 0x04 to enable Totem pole structure, non-inverted
break;
case 4:
write_to_bus(0x45); //Send 0x10 to turn off LED15 before turning on
write_to_bus(0x10);
break;
case 5:
write_to_bus(0x43); //Send 0x00 to LED15 to full ON
write_to_bus(0x00);
break;
}
}
}
//}
int main(void){
i2c_init();
init_pwm(0);
init_pwm(1);
init_pwm(2);
init_pwm(3);
init_pwm(4);
init_pwm(5);
wait();
return 1;
}
Feel free to take a look and comment on something, maybe why I am not getting a signal?