//Test program for bit banging an I2C interface // // need to change Ack_Clk_Pulse so that it tests for an Ack and sends back true or false // need to change Clock_Out_Byte so that it clocks out two bytes with and Ack wait in between // //I2C clock can be a maximum of 100kHz for communicating with // NHD LCD //NIOS processor is running at 50MHz //So a delay loop of 250 instructions is needed between transistions of the clock // First attempt was with clkperiod = 500 and // it assumed one instruction per transition of the clock // resulted in an SCLK of 8.131kHz // // Second attempt was with clkperiod = 50 // resulted in a measured SCLK of 14.8us or 67.57kHz // // The loop compiles to: // for (delacount=0;delaycount<(clkperiod/2);delaycount++){ // add r2, zero, zero // addi r4, zero, 0x18 // addi r3, zero, 0x1 // add r2, r2, r3 // bge r4, r2, -0x8 (0x00001274) which is the add r2, r2, r3 instruction // Nios II Processor Reference Handbook pg 5-11 // Branch correctly predicted taken 2 cycles // Normal ALU instructions (e.g., add, cmplt) 1 cycle // Nios II Processor Reference Handbook pg 5-19 // Executes at most one instruction per six clock cycles // Does this mean 3 cycles and 6 clocks per cycle or // 50MHz/((3*6)*500) = 5.55kHz close // Instructions say 3 cycles // First attempt will be without a stop bit #define LEDG (volatile unsigned char *) 0x3000 #define sclk_p_oen (volatile unsigned char *) 0x3010 #define sclk_p_o (volatile unsigned char *) 0x3020 #define sdat_p_oen (volatile unsigned char *) 0x3030 #define sdat_p_o (volatile unsigned char *) 0x3040 #define FVLVPXCLK (volatile unsigned char *) 0x3050 //3 bit parallel input #define CAMDAT (volatile unsigned char *) 0x3060 //10 bit parallel input #define tstclk (volatile unsigned char *) 0x3070 //1 bit parallel output #define sramaddr (volatile unsigned char *) 0x3080 //18 bit parallel output #define ceweoelbub (volatile unsigned char *) 0x3090 //5 bit parallel output #define sramd (volatile unsigned char *) 0x30A0 //8 bit parallel output #define clkperiod 50 #define CAMI2CAddr 0x90 unsigned int CamSnap[] = { 2, 0xCC, 0x0000, // PROGRAM_SELECT 2, 0xCB, 0x0001 // PROGRAM_ADVANCE }; unsigned int CamModeSetup[]={ 0, 0x2D, 0x003C, 0, 0x2B, 0x0038, 0, 0x2E, 0x0038, 0, 0x2C, 0x0062, // BLUE_GAIN_REG 0, 0x09, 0x0200, // INTEG_TIME_REG 0, 0x0C, 0x0000, // SHUTTER_DELAY_REG 0, 0x04, 0x0500, // COL_WINDOW_SIZE_REG 0, 0x0A, 0x0011, // PIXCLK_SPEED_CTRL_REG 1, 0x06, 0x709E, // MODE_CONTROL 1, 0x06, 0x709E, // MODE_CONTROL 2, 0x2E, 0x0C44, // AE_PRECISION_TARGET 2, 0x2E, 0x0C44, // AE_PRECISION_TARGET 1, 0x34, 0x0000, // LUMA_OFFSET 1, 0x06, 0x709E, // MODE_CONTROL 2, 0x37, 0x0300, // SHUTTER_WIDTH_LIM_AE 2, 0x67, 0x4010, // DIGITAL_GAIN_LIMITS_AE 2, 0x67, 0x4010, // DIGITAL_GAIN_LIMITS_AE 2, 0x3D, 0x17D9, // ADC_LIMITS_AE_ADJ 2, 0x3D, 0x17D9, // ADC_LIMITS_AE_ADJ 2, 0x3D, 0x17D9, // ADC_LIMITS_AE_ADJ 2, 0x36, 0x7810, // GAIN_LIM_AE 2, 0x36, 0x7810, // GAIN_LIM_AE 2, 0x2A, 0x00D0, // STD_LIM_MONO_ZONE 2, 0x2A, 0x00D0, // STD_LIM_MONO_ZONE 2, 0x2A, 0x00D0, // STD_LIM_MONO_ZONE 2, 0x20, 0xC814, // LUM_LIMITS_WB_STATS 2, 0x20, 0xC814, // LUM_LIMITS_WB_STATS 2, 0x1F, 0x0090, // AWB_CR_CB_LIMITS 2, 0x1F, 0x0090, // AWB_CR_CB_LIMITS 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x03, 0x191A, // BASE_MATRIX_SCALE_K1_K5 2, 0x09, 0x00AB, // BASE_MATRIX_COEF_K1 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x16, 0x0051, // DELTA_MATRIX_COEF_D1 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x03, 0x191A, // BASE_MATRIX_SCALE_K1_K5 2, 0x0A, 0x008A, // BASE_MATRIX_COEF_K2 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x17, 0x0059, // DELTA_MATRIX_COEF_D2 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x03, 0x191A, // BASE_MATRIX_SCALE_K1_K5 2, 0x0B, 0x002D, // BASE_MATRIX_COEF_K3 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x18, 0x002C, // DELTA_MATRIX_COEF_D3 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x03, 0x191A, // BASE_MATRIX_SCALE_K1_K5 2, 0x0C, 0x0091, // BASE_MATRIX_COEF_K4 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x19, 0x00A5, // DELTA_MATRIX_COEF_D4 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x03, 0x191A, // BASE_MATRIX_SCALE_K1_K5 2, 0x0D, 0x0068, // BASE_MATRIX_COEF_K5 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x1A, 0x0034, // DELTA_MATRIX_COEF_D5 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x04, 0x02A3, // BASE_MATRIX_SCALE_K6_K9 2, 0x0E, 0x0080, // BASE_MATRIX_COEF_K6 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x1B, 0x0051, // DELTA_MATRIX_COEF_D6 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x04, 0x02A3, // BASE_MATRIX_SCALE_K6_K9 2, 0x0F, 0x001D, // BASE_MATRIX_COEF_K7 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x1C, 0x007D, // DELTA_MATRIX_COEF_D7 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x04, 0x02A3, // BASE_MATRIX_SCALE_K6_K9 2, 0x10, 0x0058, // BASE_MATRIX_COEF_K8 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x1D, 0x009D, // DELTA_MATRIX_COEF_D8 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x04, 0x02A3, // BASE_MATRIX_SCALE_K6_K9 2, 0x11, 0x005D, // BASE_MATRIX_COEF_K9 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x1E, 0x005F, // DELTA_MATRIX_COEF_D9 1, 0x06, 0x709E, // MODE_CONTROL 1, 0x06, 0x709E, // MODE_CONTROL 1, 0x06, 0x709E, // MODE_CONTROL 2, 0x5E, 0x674C, // RATIO_BASE_REG 2, 0x5F, 0x7959, // RATIO_DELTA_REG 2, 0x60, 0x0002, // SIGNS_DELTA_REG 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x03, 0x191A, // BASE_MATRIX_SCALE_K1_K5 2, 0x09, 0x00AB, // BASE_MATRIX_COEF_K1 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x16, 0x0051, // DELTA_MATRIX_COEF_D1 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x03, 0x191A, // BASE_MATRIX_SCALE_K1_K5 2, 0x0A, 0x008A, // BASE_MATRIX_COEF_K2 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x17, 0x0059, // DELTA_MATRIX_COEF_D2 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x03, 0x191A, // BASE_MATRIX_SCALE_K1_K5 2, 0x0B, 0x002D, // BASE_MATRIX_COEF_K3 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x18, 0x002C, // DELTA_MATRIX_COEF_D3 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x03, 0x191A, // BASE_MATRIX_SCALE_K1_K5 2, 0x0C, 0x0091, // BASE_MATRIX_COEF_K4 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x19, 0x00A5, // DELTA_MATRIX_COEF_D4 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x03, 0x191A, // BASE_MATRIX_SCALE_K1_K5 2, 0x0D, 0x0068, // BASE_MATRIX_COEF_K5 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x1A, 0x0034, // DELTA_MATRIX_COEF_D5 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x04, 0x02A3, // BASE_MATRIX_SCALE_K6_K9 2, 0x0E, 0x0080, // BASE_MATRIX_COEF_K6 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x1B, 0x0051, // DELTA_MATRIX_COEF_D6 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x04, 0x02A3, // BASE_MATRIX_SCALE_K6_K9 2, 0x0F, 0x001D, // BASE_MATRIX_COEF_K7 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x1C, 0x007D, // DELTA_MATRIX_COEF_D7 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x04, 0x02A3, // BASE_MATRIX_SCALE_K6_K9 2, 0x10, 0x0058, // BASE_MATRIX_COEF_K8 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x1D, 0x009D, // DELTA_MATRIX_COEF_D8 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x04, 0x02A3, // BASE_MATRIX_SCALE_K6_K9 2, 0x11, 0x005D, // BASE_MATRIX_COEF_K9 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x1E, 0x005F, // DELTA_MATRIX_COEF_D9 1, 0x06, 0x709E, // MODE_CONTROL 1, 0x06, 0x709E, // MODE_CONTROL 1, 0x06, 0x709E, // MODE_CONTROL 2, 0x5E, 0x674C, // RATIO_BASE_REG 2, 0x5F, 0x7959, // RATIO_DELTA_REG 2, 0x60, 0x0002, // SIGNS_DELTA_REG 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x03, 0x191A, // BASE_MATRIX_SCALE_K1_K5 2, 0x09, 0x00AB, // BASE_MATRIX_COEF_K1 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x16, 0x0051, // DELTA_MATRIX_COEF_D1 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x03, 0x191A, // BASE_MATRIX_SCALE_K1_K5 2, 0x0A, 0x008A, // BASE_MATRIX_COEF_K2 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x17, 0x0059, // DELTA_MATRIX_COEF_D2 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x03, 0x191A, // BASE_MATRIX_SCALE_K1_K5 2, 0x0B, 0x002D, // BASE_MATRIX_COEF_K3 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x18, 0x002C, // DELTA_MATRIX_COEF_D3 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x03, 0x191A, // BASE_MATRIX_SCALE_K1_K5 2, 0x0C, 0x0091, // BASE_MATRIX_COEF_K4 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x19, 0x00A5, // DELTA_MATRIX_COEF_D4 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x03, 0x191A, // BASE_MATRIX_SCALE_K1_K5 2, 0x0D, 0x0068, // BASE_MATRIX_COEF_K5 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x1A, 0x0034, // DELTA_MATRIX_COEF_D5 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x04, 0x02A3, // BASE_MATRIX_SCALE_K6_K9 2, 0x0E, 0x0080, // BASE_MATRIX_COEF_K6 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x1B, 0x0051, // DELTA_MATRIX_COEF_D6 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x04, 0x02A3, // BASE_MATRIX_SCALE_K6_K9 2, 0x0F, 0x001D, // BASE_MATRIX_COEF_K7 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x1C, 0x007D, // DELTA_MATRIX_COEF_D7 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x04, 0x02A3, // BASE_MATRIX_SCALE_K6_K9 2, 0x10, 0x0058, // BASE_MATRIX_COEF_K8 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x1D, 0x009D, // DELTA_MATRIX_COEF_D8 2, 0x02, 0x00EE, // BASE_MATRIX_SIGNS 2, 0x04, 0x02A3, // BASE_MATRIX_SCALE_K6_K9 2, 0x11, 0x005D, // BASE_MATRIX_COEF_K9 2, 0x15, 0x0111, // DELTA_COEFS_SIGNS 2, 0x1E, 0x005F, // DELTA_MATRIX_COEF_D9 1, 0x06, 0x709E, // MODE_CONTROL 1, 0x06, 0x709E, // MODE_CONTROL 1, 0x06, 0x709E, // MODE_CONTROL 2, 0x5E, 0x674C, // RATIO_BASE_REG 2, 0x5F, 0x7959, // RATIO_DELTA_REG 2, 0x60, 0x0002, // SIGNS_DELTA_REG 1, 0x34, 0x0000, // LUMA_OFFSET 1, 0x35, 0xFF00, // CLIPPING_LIM_OUT_LUMA 1, 0x53, 0x1A08, // GAMMA_A_Y1_Y2 1, 0x54, 0x603D, // GAMMA_A_Y3_Y4 1, 0x55, 0xAB8C, // GAMMA_A_Y5_Y6 1, 0x56, 0xDAC4, // GAMMA_A_Y7_Y8 1, 0x57, 0xFFED, // GAMMA_A_Y9_Y10 1, 0xDC, 0x1A08, // GAMMA_B_Y1_Y2 1, 0xDD, 0x603D, // GAMMA_B_Y3_Y4 1, 0xDE, 0xAB8C, // GAMMA_B_Y5_Y6 1, 0xDF, 0xDAC4, // GAMMA_B_Y7_Y8 1, 0xE0, 0xFFED, // GAMMA_B_Y9_Y10 1, 0x25, 0x002D, // AWB_SPEED_SATURATION 1, 0x08, 0x0080, // FORMAT_CONTROL 1, 0x08, 0x0080, // FORMAT_CONTROL 1, 0x06, 0x709E, // MODE_CONTROL 1, 0x80, 0x0007, // LENS_CORRECT_CONTROL 1, 0x8A, 0x8832, // LENS_ADJ_HORIZ_RED_0 1, 0x8B, 0xDDB2, // LENS_ADJ_HORIZ_RED_1_2 1, 0x8C, 0xF7EA, // LENS_ADJ_HORIZ_RED_3_4 1, 0x8D, 0x0002, // LENS_ADJ_HORIZ_RED_5 1, 0xBC, 0x240C, // LENS_ADJ_HORIZ_RED_6_7 1, 0xBD, 0x5E3C, // LENS_ADJ_HORIZ_RED_8_9 1, 0xBE, 0x007F, // LENS_ADJ_HORIZ_RED_10 1, 0x81, 0xDD0C, // LENS_ADJ_VERT_RED_0 1, 0x82, 0xF4E8, // LENS_ADJ_VERT_RED_1_2 1, 0x83, 0x04FC, // LENS_ADJ_VERT_RED_3_4 1, 0xB6, 0x110B, // LENS_ADJ_VERT_RED_5_6 1, 0xB7, 0x3C27, // LENS_ADJ_VERT_RED_7_8 1, 0x8E, 0xBA1E, // LENS_ADJ_HORIZ_GREEN_0 1, 0x8F, 0xECD3, // LENS_ADJ_HORIZ_GREEN_1_2 1, 0x90, 0xF7F1, // LENS_ADJ_HORIZ_GREEN_3_4 1, 0x91, 0x00FF, // LENS_ADJ_HORIZ_GREEN_5 1, 0xBF, 0x2008, // LENS_ADJ_HORIZ_GREEN_6_7 1, 0xC0, 0x4E37, // LENS_ADJ_HORIZ_GREEN_8_9 1, 0xC1, 0x0064, // LENS_ADJ_HORIZ_GREEN_10 1, 0x84, 0xE20C, // LENS_ADJ_VERT_GREEN_0 1, 0x85, 0xF6EC, // LENS_ADJ_VERT_GREEN_1_2 1, 0x86, 0x02FC, // LENS_ADJ_VERT_GREEN_3_4 1, 0xB8, 0x110A, // LENS_ADJ_VERT_GREEN_5_6 1, 0xB9, 0x3222, // LENS_ADJ_VERT_GREEN_7_8 1, 0x92, 0xBF1E, // LENS_ADJ_HORIZ_BLUE_0 1, 0x93, 0xEED6, // LENS_ADJ_HORIZ_BLUE_1_2 1, 0x94, 0xF7F2, // LENS_ADJ_HORIZ_BLUE_3_4 1, 0x95, 0x0003, // LENS_ADJ_HORIZ_BLUE_5 1, 0xC2, 0x210F, // LENS_ADJ_HORIZ_BLUE_6_7 1, 0xC3, 0x4B32, // LENS_ADJ_HORIZ_BLUE_8_9 1, 0xC4, 0x0064, // LENS_ADJ_HORIZ_BLUE_10 1, 0x87, 0xDD0C, // LENS_ADJ_VERT_BLUE_0 1, 0x88, 0xF4E8, // LENS_ADJ_VERT_BLUE_1_2 1, 0x89, 0x00FA, // LENS_ADJ_VERT_BLUE_3_4 1, 0xBA, 0x160B, // LENS_ADJ_VERT_BLUE_5_6 1, 0xBB, 0x3224, // LENS_ADJ_VERT_BLUE_7_8 1, 0x08, 0x0080, // FORMAT_CONTROL 1, 0x06, 0x709E, // MODE_CONTROL 1, 0xE3, 0xB023, // EFFECTS_SEPIA 1, 0xE2, 0x7000, // EFFECTS_MODE 0, 0x20, 0x0300, // READ_MODE_B 0, 0x2D, 0x0033, // RED_GAIN_REG 0, 0x2B, 0x0038, // GREEN1_GAIN_REG 0, 0x2E, 0x0038, // GREEN2_GAIN_REG 0, 0x2C, 0x00B8 // BLUE_GAIN_REG }; //245 sets long? //start signal will transition the SDAT line low // while the clock is still high // // Leaves SDAT & SCLK Tristate Buffers enabled // Leaves SDAT & SCLK Lines Low void Start_Signal (void){ int delaycount; *sdat_p_oen = 0; //enable sdat tristate buffer *sdat_p_o = 0; //drive SDAT low for (delaycount = 0; delaycount < (clkperiod/2); delaycount++){ //wait 1/2 clock period } *sclk_p_oen = 0; //drop SCLK line *sclk_p_o = 0; for (delaycount = 0; delaycount < (clkperiod/4); delaycount++){ //wait 1/4 clock period } } //Clock out Byte // takes a passed char // transfers it one bit at a time // by // putting one bit on the SDAT line // raising and lowering the SCLK line void Clock_Out_Byte (char bytetosend){ int bitcount; int delaycount; for (bitcount = 0; bitcount < 8; bitcount++){ //do the following 8 times if ((bytetosend & 0x80) == 0x80) *sdat_p_o = 1; //test MSB if 1 drive SDAT high else *sdat_p_o = 0; //else leave SDAT low for (delaycount = 0; delaycount < (clkperiod/4); delaycount++){ //wait 1/4 clock period } *sclk_p_o = 1; //drive SCLK high for (delaycount = 0; delaycount < (clkperiod/2); delaycount++){ //wait 1/2 clock period } *sclk_p_o = 0; //drive SCLK Low for (delaycount = 0; delaycount < (clkperiod/4); delaycount++){ //wait 1/4 clock period } bytetosend = bytetosend << 1; } *sdat_p_oen = 1; //after last bit disable SDAT tristate buffer // to free line for ACK bit } //end of clock out bit //wait for ack // just a single clock pulse void Ack_Clk_Pulse(){ int delaycount; for (delaycount = 0; delaycount < (clkperiod/4); delaycount++){ //wait 1/4 clock period } *sclk_p_o = 1; //drive SCLK high for (delaycount = 0; delaycount < (clkperiod/2); delaycount++){ //wait 1/2 clock period } *sclk_p_o = 0; //drive SCLK Low for (delaycount = 0; delaycount < (clkperiod/4); delaycount++){ //wait 1/4 clock period } *sdat_p_oen = 0; //enable SDAT tristate buffer } void Stop_Signal(){ int delaycount; for (delaycount = 0; delaycount < (clkperiod/4); delaycount++){ //wait 1/4 clock period } *sclk_p_o = 1; //drive SCLK high for (delaycount = 0; delaycount < (clkperiod/4); delaycount++){ //wait 1/4 clock period } *sdat_p_o = 1; //set the sdat line high for (delaycount = 0; delaycount < (clkperiod/4); delaycount++){ //wait 1/4 clock period } *sclk_p_o = 0; /drive SCLK low for (delaycount = 0; delaycount < (clkperiod/4); delaycount++){ //wait 1/4 clock period } } //end of Stop_Signal void Send_I2C_Byte(unsigned char ByteToSend){ Start_Signal(); //Start an I2C transaction Clock_Out_Byte(CAMI2CAddr); //Send the Address of the I2C slave /*If SADDR is LOW, the slave address is 0x90; if SADDR is HIGH, the slave address is 0xBA.*/ Ack_Clk_Pulse(); Clock_Out_Byte(ByteToSend); Ack_Clk_Pulse(); *sclk_p_oen = 1; //disable SCLK tristate buffer *sdat_p_oen = 1; //disable SDAT tristate buffer } void SendI2CCommand(unsigned char RegAddr, unsigned int WordToSend){ Start_Signal(); //Start an I2C transaction Clock_Out_Byte(CAMI2CAddr); //Send the Address of the I2C slave //If SADDR is LOW, the slave address is 0x90 // if SADDR is HIGH, the slave address is 0xBA Ack_Clk_Pulse(); Clock_Out_Byte(RegAddr); Ack_Clk_Pulse(); Clock_Out_Byte((WordToSend & 0xFF00)>> 8); Ack_Clk_Pulse(); Clock_Out_Byte(WordToSend & 0x00FF); Ack_Clk_Pulse(); Stop_Signal(); *sclk_p_oen = 1; //disable SCLK tristate buffer *sdat_p_oen = 1; //disable SDAT tristate buffer } void ChangeRegPage(unsigned char RegPage){ //Register F0 in all three Register Pages // provide the same function // of choosing the active Register Page //set Register F0 to the new RegPage unsigned int RegPage16 = 0; RegPage16 = RegPage16 | RegPage; SendI2CCommand(0xF0,RegPage16); } //end of ChangeRegPage void SetupCamMode(void){ /*When accessing internal registers through the two-wire serial interface, select the desired address space by programming the R0xF0 shared register. Pg 8 MTM9131 datasheet Note: getting a warning G:/SKC/HASP/I2C/Test_I2C_via_Bit_Banging_w_NIOSf_SRAM/Code/SnapShot.c:434: warning: comparison is always true due to limited range of data type tried changing RegPage to unsigned int from unsigned char with no effect changing CommandNumber to unsigned int from unsigned char fixed the error */ unsigned int CommandNumber; unsigned char RegPage = 4; // 4 is an unallowed register page that is used here so the first command requires a page change // and is assigned to unsigned int to match the assignment in the CamModeSetup array //sizeof returns the size of the array in bytes // because each entry in the CamMode array is 4 bytes long // divide sizeof(CamModeSetup) by 4 to get the number of writes for (CommandNumber = 0; CommandNumber < sizeof(CamModeSetup)/4; CommandNumber + 3){ if(CamModeSetup[CommandNumber] != RegPage) ChangeRegPage(CamModeSetup[CommandNumber]); SendI2CCommand(CamModeSetup[CommandNumber + 1], CamModeSetup[CommandNumber + 2]); } } //end of SetupCamMode void TakeImage(void){ ChangeRegPage(2); SendI2CCommand(CamSnap[1], CamSnap[2]); SendI2CCommand(CamSnap[4], CamSnap[5]); } //end of SendTakeImage void GetFrame(void){ } //end of GetFrame //main routine // sends out an address of 0x50 // and a data byte of 0x41 int main (){ SetupCamMode(); TakeImage(); GetFrame(); }// end of main