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?
On Saturday, August 8, 2020 at 12:57:15 PM UTC-7, M wrote:
>
> Can anyone provide a C program that can be run in CCS that would program
> an I2C controller on the BBB board to generate the desired clock frequency
> signal and the required data signals on the I2C bus.
>
>
> Part 1. Program the device to generate signals to turn LED15 to full ON.
> Should be measurable voltage from the number 15 signal pin on the servo
> board.
>
> Part 2. Develop commands you send to PCA9685 to intialize it for the
> correct frequency for your servo, set up a timer on the BBB to control
> delays, and intialize the BBB User LEDs.
>
--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/beagleboard/5a0fb22d-8c0b-4c1e-8e90-6576aba1717eo%40googlegroups.com.