Junichi Katsu / Mbed 2 deprecated BLE_MPU6050_test6_challenge_sb

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers myi2c_api.c Source File

myi2c_api.c

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2013 Nordic Semiconductor
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 #include "mbed_assert.h"
00017 #include "myi2c_api.h"
00018 #include "cmsis.h"
00019 #include "pinmap.h"
00020 
00021 static const PinMap PinMap_I2C_SDA[] = {
00022     {p22, I2C_0, 1},
00023     {p13, I2C_1, 2},
00024     {NC, NC, 0}
00025 };
00026 
00027 static const PinMap PinMap_I2C_SCL[] = {
00028     {p21, I2C_0, 1},
00029     {p15, I2C_1, 2},
00030     {NC, NC,    0}
00031 };
00032 
00033 uint8_t addrSet = 0;
00034 
00035 void i2c_interface_enable(i2c_t *obj)
00036 {
00037     obj->i2c->ENABLE = (TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos);
00038 }
00039 
00040 void twi_master_init(i2c_t *obj, PinName sda, PinName scl, int frequency)
00041 {
00042     NRF_GPIO->PIN_CNF[scl] = ((GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) |
00043                               (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
00044                               (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
00045                               (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) |
00046                               (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos));
00047 
00048     NRF_GPIO->PIN_CNF[sda] = ((GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) |
00049                               (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
00050                               (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
00051                               (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) |
00052                               (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos));
00053 
00054     obj->i2c->PSELSCL = scl;
00055     obj->i2c->PSELSDA = sda;
00056     // set default frequency at 100k
00057     i2c_frequency(obj, frequency);
00058     i2c_interface_enable(obj);
00059 }
00060 
00061 void i2c_init(i2c_t *obj, PinName sda, PinName scl)
00062 {
00063     // determine the SPI to use
00064     I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
00065     I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
00066     I2CName i2c     = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
00067     obj->i2c = (NRF_TWI_Type *)i2c;
00068 
00069     MBED_ASSERT((int)obj->i2c != NC);
00070 
00071     obj->scl               = scl;
00072     obj->sda               = sda;
00073     obj->i2c->EVENTS_ERROR = 0;
00074     obj->i2c->ENABLE       = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
00075     obj->i2c->POWER        = 0;
00076 
00077     for (int i = 0; i<100; i++) {
00078     }
00079 
00080     obj->i2c->POWER = 1;
00081     twi_master_init(obj, sda, scl, 100000);
00082 }
00083 
00084 void i2c_reset(i2c_t *obj)
00085 {
00086     obj->i2c->EVENTS_ERROR = 0;
00087     obj->i2c->ENABLE       = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
00088     obj->i2c->POWER        = 0;
00089     for (int i = 0; i<100; i++) {
00090     }
00091 
00092     obj->i2c->POWER = 1;
00093     twi_master_init(obj, obj->sda, obj->scl, obj->freq);
00094 }
00095 
00096 int i2c_start(i2c_t *obj)
00097 {
00098     int status = 0;
00099     i2c_reset(obj);
00100     addrSet = 0;
00101     return status;
00102 }
00103 
00104 int i2c_stop(i2c_t *obj)
00105 {
00106     int timeOut = 100000;
00107     obj->i2c->EVENTS_STOPPED = 0;
00108     // write the stop bit
00109     obj->i2c->TASKS_STOP = 1;
00110     while (!obj->i2c->EVENTS_STOPPED) {
00111         timeOut--;
00112         if (timeOut<0) {
00113             return 1;
00114         }
00115     }
00116     addrSet = 0;
00117     i2c_reset(obj);
00118     return 0;
00119 }
00120 
00121 int i2c_do_write(i2c_t *obj, int value)
00122 {
00123     int timeOut = 100000;
00124     obj->i2c->TXD = value;
00125     while (!obj->i2c->EVENTS_TXDSENT) {
00126         timeOut--;
00127         if (timeOut<0) {
00128             return 1;
00129         }
00130     }
00131     obj->i2c->EVENTS_TXDSENT = 0;
00132     return 0;
00133 }
00134 
00135 int i2c_do_read(i2c_t *obj, char *data, int last)
00136 {
00137     int timeOut = 100000;
00138 
00139     if (last) {
00140         obj->i2c->TASKS_STOP = 1;
00141     }
00142     while (!obj->i2c->EVENTS_RXDREADY) {
00143         timeOut--;
00144         if (timeOut<0) {
00145             return 1;
00146         }
00147     }
00148     obj->i2c->EVENTS_RXDREADY = 0;
00149 
00150     *data = obj->i2c->RXD;
00151 
00152     for (int i = 0; i<320; i++) {
00153     }
00154 
00155     obj->i2c->TASKS_RESUME = 1;
00156 
00157     return 0;
00158 }
00159 
00160 void i2c_frequency(i2c_t *obj, int hz)
00161 {
00162     if (hz<250000) {
00163         obj->freq           = 100000;
00164         obj->i2c->FREQUENCY = (TWI_FREQUENCY_FREQUENCY_K100 << TWI_FREQUENCY_FREQUENCY_Pos);
00165     } else if (hz<400000) {
00166         obj->freq           = 250000;
00167         obj->i2c->FREQUENCY = (TWI_FREQUENCY_FREQUENCY_K250 << TWI_FREQUENCY_FREQUENCY_Pos);
00168     } else {
00169         obj->freq           = 400000;
00170         obj->i2c->FREQUENCY = (TWI_FREQUENCY_FREQUENCY_K400 << TWI_FREQUENCY_FREQUENCY_Pos);
00171     }
00172 }
00173 
00174 int checkError(i2c_t *obj)
00175 {
00176     if (obj->i2c->EVENTS_ERROR == 1) {
00177         if (obj->i2c->ERRORSRC & TWI_ERRORSRC_ANACK_Msk) {
00178             obj->i2c->EVENTS_ERROR = 0;
00179             obj->i2c->TASKS_STOP   = 1;
00180             return I2C_ERROR_BUS_BUSY;
00181         }
00182 
00183         obj->i2c->EVENTS_ERROR = 0;
00184         obj->i2c->TASKS_STOP   = 1;
00185         return I2C_ERROR_NO_SLAVE;
00186     }
00187     return 0;
00188 }
00189 
00190 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
00191 {
00192     int status, count, errorResult;
00193     obj->i2c->ADDRESS         = (address >> 1);
00194     obj->i2c->SHORTS          = 0;
00195     obj->i2c->EVENTS_RXDREADY = 0;
00196     obj->i2c->TASKS_STARTRX   = 1;
00197 
00198     // Read in all except last byte
00199     for (count = 0; count < (length - 1); count++) {
00200         status = i2c_do_read(obj, &data[count], 0);
00201         if (status) {
00202             errorResult = checkError(obj);
00203             i2c_reset(obj);
00204             if (errorResult<0) {
00205                 return errorResult;
00206             }
00207             return count;
00208         }
00209     }
00210 
00211     // read in last byte
00212     status = i2c_do_read(obj, &data[length - 1], 1);
00213     if (status) {
00214         i2c_reset(obj);
00215         return length - 1;
00216     }
00217     // If not repeated start, send stop.
00218     if (stop) {
00219         while (!obj->i2c->EVENTS_STOPPED) {
00220         }
00221         obj->i2c->EVENTS_STOPPED = 0;
00222     }
00223     return length;
00224 }
00225 
00226 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
00227 {
00228     int status, errorResult;
00229     obj->i2c->ADDRESS       = (address >> 1);
00230     obj->i2c->SHORTS        = 0;
00231     obj->i2c->TASKS_STARTTX = 1;
00232 
00233     for (int i = 0; i<length; i++) {
00234         status = i2c_do_write(obj, data[i]);
00235         if (status) {
00236             i2c_reset(obj);
00237             errorResult = checkError(obj);
00238             if (errorResult<0) {
00239                 return errorResult;
00240             }
00241             return i;
00242         }
00243     }
00244 
00245     // If not repeated start, send stop.
00246     if (stop) {
00247         if (i2c_stop(obj)) {
00248             return I2C_ERROR_NO_SLAVE;
00249         }
00250     }
00251     return length;
00252 }
00253 
00254 int i2c_byte_read(i2c_t *obj, int last)
00255 {
00256     char data;
00257     int status;
00258 
00259     status = i2c_do_read(obj, &data, last);
00260     if (status) {
00261         i2c_reset(obj);
00262     }
00263     return data;
00264 }
00265 
00266 int i2c_byte_write(i2c_t *obj, int data)
00267 {
00268     int status = 0;
00269     if (!addrSet) {
00270         addrSet           = 1;
00271         obj->i2c->ADDRESS = (data >> 1);
00272 
00273         if (data & 1) {
00274             obj->i2c->EVENTS_RXDREADY = 0;
00275             obj->i2c->TASKS_STARTRX   = 1;
00276         } else {
00277             obj->i2c->TASKS_STARTTX = 1;
00278         }
00279     } else {
00280         status = i2c_do_write(obj, data);
00281         if (status) {
00282             i2c_reset(obj);
00283         }
00284     }
00285     return (1 - status);
00286 }