The code you copied below seems to be incomplete. After the routine “set_slave_addr” and before the comment “//P9 Connector settings”, I believe there is missing code. I therefore cannot tell if your setup code is complete.
Graham From: beagleboard@googlegroups.com [mailto:beagleboard@googlegroups.com] On Behalf Of marcbo...@gmail.com Sent: Saturday, August 15, 2020 2:35 PM To: BeagleBoard <beagleboard@googlegroups.com> Subject: [beagleboard] Re: I2C driver for a PCA9685 servo controller board for s90 servos 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 beagleboard+unsubscr...@googlegroups.com <mailto:beagleboard+unsubscr...@googlegroups.com> . To view this discussion on the web visit https://groups.google.com/d/msgid/beagleboard/5a0fb22d-8c0b-4c1e-8e90-6576aba1717eo%40googlegroups.com <https://groups.google.com/d/msgid/beagleboard/5a0fb22d-8c0b-4c1e-8e90-6576aba1717eo%40googlegroups.com?utm_medium=email&utm_source=footer> . -- 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 beagleboard+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/beagleboard/002601d6735a%24954dc0c0%24bfe94240%24%40comcast.net.