Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
i2c_gpio.c
00001 /** 00002 * @file i2c_gpio.c 00003 * @brief I2C GPIO control for musca PCA9537 00004 * 00005 * DAPLink Interface Firmware 00006 * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved 00007 * SPDX-License-Identifier: Apache-2.0 00008 * 00009 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00010 * not use this file except in compliance with the License. 00011 * You may obtain a copy of the License at 00012 * 00013 * http://www.apache.org/licenses/LICENSE-2.0 00014 * 00015 * Unless required by applicable law or agreed to in writing, software 00016 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00017 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00018 * See the License for the specific language governing permissions and 00019 * limitations under the License. 00020 */ 00021 00022 #include "string.h" 00023 #include "stdio.h" 00024 #include "stdint.h" 00025 00026 #include "gpio.h" 00027 #include "utils.h" 00028 #include "i2c_gpio.h" 00029 00030 // Clock registers 00031 #define I2CGPIO_FREQ 6 // Sets OSC Clock SCL frequency 00032 #define I2CGPIO_WR 0 // Write command 00033 #define I2CGPIO_RD 1 // Read command 00034 #define I2CGPIO_ADDR 0x49 // Default slave address for PCA9537 00035 00036 /*---------------------------------------------------------------------------- 00037 I2C Address + Wr + A 00038 *----------------------------------------------------------------------------*/ 00039 void i2c_gpio_addr(unsigned int addr, unsigned int read) 00040 { 00041 unsigned int loop, data; 00042 00043 // Repeated Start condition (if required after Command) 00044 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] &= ~PIN_I2C_SCL; 00045 delay_us(I2CGPIO_FREQ); 00046 LPC_GPIO->DIR[PIN_I2C_SDA_PORT] &= ~PIN_I2C_SDA; 00047 delay_us(I2CGPIO_FREQ); 00048 00049 // Start condition 'S' (DATA > CLK) 00050 LPC_GPIO->DIR[PIN_I2C_SDA_PORT] |= PIN_I2C_SDA; 00051 delay_us(I2CGPIO_FREQ); 00052 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] |= PIN_I2C_SCL; 00053 delay_us(I2CGPIO_FREQ); 00054 00055 // Addr is 7 bits so add Read 00056 data = (addr << 1) & 0xFE; 00057 if (read) 00058 data |= 0x01; 00059 00060 // Clock out the 8 bits 00061 for (loop = 0; loop < 8; loop++) 00062 { 00063 if (data & (0x80 >> loop)) 00064 { 00065 LPC_GPIO->DIR[PIN_I2C_SDA_PORT] &= ~PIN_I2C_SDA; 00066 delay_us(I2CGPIO_FREQ); 00067 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] &= ~PIN_I2C_SCL; 00068 delay_us(I2CGPIO_FREQ); 00069 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] |= PIN_I2C_SCL; 00070 delay_us(I2CGPIO_FREQ); 00071 } 00072 else 00073 { 00074 LPC_GPIO->DIR[PIN_I2C_SDA_PORT] |= PIN_I2C_SDA; 00075 delay_us(I2CGPIO_FREQ); 00076 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] &= ~PIN_I2C_SCL; 00077 delay_us(I2CGPIO_FREQ); 00078 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] |= PIN_I2C_SCL; 00079 delay_us(I2CGPIO_FREQ); 00080 } 00081 } 00082 00083 // Set data low 00084 delay_us(I2CGPIO_FREQ); 00085 LPC_GPIO->DIR[PIN_I2C_SDA_PORT] |= PIN_I2C_SDA; 00086 delay_us(I2CGPIO_FREQ); 00087 00088 // Transmission clock 'A' 00089 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] &= ~PIN_I2C_SCL; 00090 delay_us(I2CGPIO_FREQ); 00091 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] |= PIN_I2C_SCL; 00092 delay_us(I2CGPIO_FREQ); 00093 } 00094 00095 /*---------------------------------------------------------------------------- 00096 I2C Command + A 00097 *----------------------------------------------------------------------------*/ 00098 void i2c_gpio_cmd(unsigned int cmd) 00099 { 00100 unsigned int loop; 00101 00102 // Clock out the 8 bits 00103 for (loop = 0; loop < 8; loop++) 00104 { 00105 if (cmd & (0x80 >> loop)) 00106 { 00107 LPC_GPIO->DIR[PIN_I2C_SDA_PORT] &= ~PIN_I2C_SDA; 00108 delay_us(I2CGPIO_FREQ); 00109 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] &= ~PIN_I2C_SCL; 00110 delay_us(I2CGPIO_FREQ); 00111 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] |= PIN_I2C_SCL; 00112 delay_us(I2CGPIO_FREQ); 00113 } 00114 else 00115 { 00116 LPC_GPIO->DIR[PIN_I2C_SDA_PORT] |= PIN_I2C_SDA; 00117 delay_us(I2CGPIO_FREQ); 00118 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] &= ~PIN_I2C_SCL; 00119 delay_us(I2CGPIO_FREQ); 00120 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] |= PIN_I2C_SCL; 00121 delay_us(I2CGPIO_FREQ); 00122 } 00123 } 00124 00125 // Set data low 00126 delay_us(I2CGPIO_FREQ); 00127 LPC_GPIO->DIR[PIN_I2C_SDA_PORT] |= PIN_I2C_SDA; 00128 delay_us(I2CGPIO_FREQ); 00129 00130 // Transmission clock 'A' 00131 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] &= ~PIN_I2C_SCL; 00132 delay_us(I2CGPIO_FREQ); 00133 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] |= PIN_I2C_SCL; 00134 delay_us(I2CGPIO_FREQ); 00135 } 00136 00137 /*---------------------------------------------------------------------------- 00138 I2C Write Data + A + P 00139 *----------------------------------------------------------------------------*/ 00140 void i2c_gpio_write(unsigned int data) 00141 { 00142 unsigned int loop; 00143 00144 // Clock out the 8 bits 00145 for (loop = 0; loop < 8; loop++) 00146 { 00147 if (data & (0x80 >> loop)) 00148 { 00149 LPC_GPIO->DIR[PIN_I2C_SDA_PORT] &= ~PIN_I2C_SDA; 00150 delay_us(I2CGPIO_FREQ); 00151 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] &= ~PIN_I2C_SCL; 00152 delay_us(I2CGPIO_FREQ); 00153 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] |= PIN_I2C_SCL; 00154 delay_us(I2CGPIO_FREQ); 00155 } 00156 else 00157 { 00158 LPC_GPIO->DIR[PIN_I2C_SDA_PORT] |= PIN_I2C_SDA; 00159 delay_us(I2CGPIO_FREQ); 00160 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] &= ~PIN_I2C_SCL; 00161 delay_us(I2CGPIO_FREQ); 00162 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] |= PIN_I2C_SCL; 00163 delay_us(I2CGPIO_FREQ); 00164 } 00165 } 00166 00167 // Set data low 00168 delay_us(I2CGPIO_FREQ); 00169 LPC_GPIO->DIR[PIN_I2C_SDA_PORT] |= PIN_I2C_SDA; 00170 delay_us(I2CGPIO_FREQ); 00171 00172 // Transmission clock 'A' 00173 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] &= ~PIN_I2C_SCL; 00174 delay_us(I2CGPIO_FREQ); 00175 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] |= PIN_I2C_SCL; 00176 delay_us(I2CGPIO_FREQ); 00177 00178 // Stop condition 'P' 00179 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] &= ~PIN_I2C_SCL; 00180 delay_us(I2CGPIO_FREQ); 00181 LPC_GPIO->DIR[PIN_I2C_SDA_PORT] &= ~PIN_I2C_SDA; 00182 delay_us(I2CGPIO_FREQ); 00183 } 00184 00185 /*---------------------------------------------------------------------------- 00186 I2C Read Data + A + P 00187 *----------------------------------------------------------------------------*/ 00188 void i2c_gpio_read(unsigned int *data, unsigned int ack) 00189 { 00190 unsigned int loop; 00191 00192 // Set SDA high (O/D) and allow PCA9537 to drive SDA 00193 LPC_GPIO->DIR[PIN_I2C_SDA_PORT] &= ~PIN_I2C_SDA; 00194 delay_us(I2CGPIO_FREQ); 00195 00196 // Clock in the 8 bits 00197 *data = 0; 00198 for (loop = 0; loop < 8; loop++) 00199 { 00200 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] &= ~PIN_I2C_SCL; 00201 delay_us(I2CGPIO_FREQ); 00202 if (LPC_GPIO->DIR[PIN_I2C_SDA_PORT] & PIN_I2C_SDA) 00203 *data &= ~(0x80 >> loop); 00204 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] |= PIN_I2C_SCL; 00205 delay_us(I2CGPIO_FREQ); 00206 } 00207 00208 // Set data for acknowledge 00209 delay_us(I2CGPIO_FREQ); 00210 if (ack) 00211 LPC_GPIO->DIR[PIN_I2C_SDA_PORT] |= PIN_I2C_SDA; 00212 else 00213 LPC_GPIO->DIR[PIN_I2C_SDA_PORT] &= ~PIN_I2C_SDA; 00214 delay_us(I2CGPIO_FREQ); 00215 00216 // Transmission clock 'A' 00217 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] &= ~PIN_I2C_SCL; 00218 delay_us(I2CGPIO_FREQ); 00219 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] |= PIN_I2C_SCL; 00220 delay_us(I2CGPIO_FREQ); 00221 00222 // End of acknowledge 00223 LPC_GPIO->DIR[PIN_I2C_SDA_PORT] |= PIN_I2C_SDA; 00224 delay_us(I2CGPIO_FREQ); 00225 00226 // Stop condition 'P' 00227 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] &= ~PIN_I2C_SCL; 00228 delay_us(I2CGPIO_FREQ); 00229 LPC_GPIO->DIR[PIN_I2C_SDA_PORT] &= ~PIN_I2C_SDA; 00230 delay_us(I2CGPIO_FREQ); 00231 } 00232 00233 /*---------------------------------------------------------------------------- 00234 I2C Write byte 00235 *----------------------------------------------------------------------------*/ 00236 void i2c_gpio_wbyte(unsigned int cmd, unsigned int data) 00237 { 00238 // Set slave address write 00239 i2c_gpio_addr(I2CGPIO_ADDR, I2CGPIO_WR); 00240 // Set command 00241 i2c_gpio_cmd(cmd); 00242 // Write the data 00243 i2c_gpio_write(data); 00244 } 00245 00246 /*---------------------------------------------------------------------------- 00247 I2C Read byte 00248 *----------------------------------------------------------------------------*/ 00249 void i2c_gpio_rbyte(unsigned int cmd, unsigned int *data) 00250 { 00251 // Set slave address write 00252 i2c_gpio_addr(I2CGPIO_ADDR, I2CGPIO_WR); 00253 // Set command 00254 i2c_gpio_cmd(cmd); 00255 00256 // Set slave address write 00257 i2c_gpio_addr(I2CGPIO_ADDR, I2CGPIO_RD); 00258 // Read the data 00259 i2c_gpio_read(data, 0); 00260 } 00261 00262 // end of i2c_gpio.c
Generated on Tue Jul 12 2022 15:37:18 by
