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.
Fork of mbed-dev by
targets/TARGET_ONSEMI/TARGET_NCS36510/i2c_api.c@151:91825d030f9b, 2016-11-14 (annotated)
- Committer:
- DangerousElectrician
- Date:
- Mon Nov 14 04:39:23 2016 +0000
- Revision:
- 151:91825d030f9b
- Parent:
- 149:156823d33999
stuff changed?
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
<> | 149:156823d33999 | 1 | /** |
<> | 149:156823d33999 | 2 | ******************************************************************************* |
<> | 149:156823d33999 | 3 | * @file i2c.c |
<> | 149:156823d33999 | 4 | * @brief Implementation of an i2c api |
<> | 149:156823d33999 | 5 | * @internal |
<> | 149:156823d33999 | 6 | * @author ON Semiconductor |
<> | 149:156823d33999 | 7 | * $Rev: 3525 $ |
<> | 149:156823d33999 | 8 | * $Date: 2015-07-20 15:24:25 +0530 (Mon, 20 Jul 2015) $ |
<> | 149:156823d33999 | 9 | ****************************************************************************** |
<> | 149:156823d33999 | 10 | * Copyright 2016 Semiconductor Components Industries LLC (d/b/a ON Semiconductor). |
<> | 149:156823d33999 | 11 | * All rights reserved. This software and/or documentation is licensed by ON Semiconductor |
<> | 149:156823d33999 | 12 | * under limited terms and conditions. The terms and conditions pertaining to the software |
<> | 149:156823d33999 | 13 | * and/or documentation are available at http://www.onsemi.com/site/pdf/ONSEMI_T&C.pdf |
<> | 149:156823d33999 | 14 | * (ON Semiconductor Standard Terms and Conditions of Sale, Section 8 Software) and |
<> | 149:156823d33999 | 15 | * if applicable the software license agreement. Do not use this software and/or |
<> | 149:156823d33999 | 16 | * documentation unless you have carefully read and you agree to the limited terms and |
<> | 149:156823d33999 | 17 | * conditions. By using this software and/or documentation, you agree to the limited |
<> | 149:156823d33999 | 18 | * terms and conditions. |
<> | 149:156823d33999 | 19 | * |
<> | 149:156823d33999 | 20 | * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED |
<> | 149:156823d33999 | 21 | * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF |
<> | 149:156823d33999 | 22 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. |
<> | 149:156823d33999 | 23 | * ON SEMICONDUCTOR SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, |
<> | 149:156823d33999 | 24 | * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. |
<> | 149:156823d33999 | 25 | * @endinternal |
<> | 149:156823d33999 | 26 | * |
<> | 149:156823d33999 | 27 | * @ingroup i2c |
<> | 149:156823d33999 | 28 | * |
<> | 149:156823d33999 | 29 | */ |
<> | 149:156823d33999 | 30 | #if DEVICE_I2C |
<> | 149:156823d33999 | 31 | |
<> | 149:156823d33999 | 32 | #include "i2c.h" |
<> | 149:156823d33999 | 33 | #include "i2c_api.h" |
<> | 149:156823d33999 | 34 | |
<> | 149:156823d33999 | 35 | #define I2C_READ_WRITE_BIT_MASK 0xFE |
<> | 149:156823d33999 | 36 | |
<> | 149:156823d33999 | 37 | /* See i2c_api.h for details */ |
<> | 149:156823d33999 | 38 | void i2c_init(i2c_t *obj, PinName sda, PinName scl) |
<> | 149:156823d33999 | 39 | { |
<> | 149:156823d33999 | 40 | fI2cInit(obj, sda, scl); |
<> | 149:156823d33999 | 41 | } |
<> | 149:156823d33999 | 42 | |
<> | 149:156823d33999 | 43 | /* See i2c_api.h for details */ |
<> | 149:156823d33999 | 44 | void i2c_frequency(i2c_t *obj, int hz) |
<> | 149:156823d33999 | 45 | { |
<> | 149:156823d33999 | 46 | fI2cFrequency(obj, hz); |
<> | 149:156823d33999 | 47 | } |
<> | 149:156823d33999 | 48 | |
<> | 149:156823d33999 | 49 | /* See i2c_api.h for details */ |
<> | 149:156823d33999 | 50 | int i2c_start(i2c_t *obj) |
<> | 149:156823d33999 | 51 | { |
<> | 149:156823d33999 | 52 | return(fI2cStart(obj)); |
<> | 149:156823d33999 | 53 | } |
<> | 149:156823d33999 | 54 | |
<> | 149:156823d33999 | 55 | /* See i2c_api.h for details */ |
<> | 149:156823d33999 | 56 | int i2c_stop(i2c_t *obj) |
<> | 149:156823d33999 | 57 | { |
<> | 149:156823d33999 | 58 | return(fI2cStop(obj)); |
<> | 149:156823d33999 | 59 | } |
<> | 149:156823d33999 | 60 | |
<> | 149:156823d33999 | 61 | /* See i2c_api.h for details */ |
<> | 149:156823d33999 | 62 | int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) |
<> | 149:156823d33999 | 63 | { |
<> | 149:156823d33999 | 64 | /* TODO address parameter not usable */ |
<> | 149:156823d33999 | 65 | int Count, status; |
<> | 149:156823d33999 | 66 | const char WriteData = (address | (~I2C_READ_WRITE_BIT_MASK)) & 0xFF; |
<> | 149:156823d33999 | 67 | |
<> | 149:156823d33999 | 68 | /* Send start bit */ |
<> | 149:156823d33999 | 69 | status = fI2cStart(obj); |
<> | 149:156823d33999 | 70 | if(status) { |
<> | 149:156823d33999 | 71 | /* Error sending start bit */ |
<> | 149:156823d33999 | 72 | return status; |
<> | 149:156823d33999 | 73 | } |
<> | 149:156823d33999 | 74 | |
<> | 149:156823d33999 | 75 | /* Send address | read */ |
<> | 149:156823d33999 | 76 | Count = fI2cWriteB(obj, &WriteData, 1); |
<> | 149:156823d33999 | 77 | if(Count != 1) { |
<> | 149:156823d33999 | 78 | /* Error sending address */ |
<> | 149:156823d33999 | 79 | return Count; |
<> | 149:156823d33999 | 80 | } |
<> | 149:156823d33999 | 81 | |
<> | 149:156823d33999 | 82 | /* Send command/s */ |
<> | 149:156823d33999 | 83 | Count = fI2cReadB(obj, data, length); |
<> | 149:156823d33999 | 84 | if(Count != length) { |
<> | 149:156823d33999 | 85 | /* Error sending coomand/s */ |
<> | 149:156823d33999 | 86 | return Count; |
<> | 149:156823d33999 | 87 | } |
<> | 149:156823d33999 | 88 | if(stop) { /* Send stop bit if requested */ |
<> | 149:156823d33999 | 89 | status = fI2cStop(obj); |
<> | 149:156823d33999 | 90 | if(status) { |
<> | 149:156823d33999 | 91 | /* Error sending stop bit */ |
<> | 149:156823d33999 | 92 | return status; |
<> | 149:156823d33999 | 93 | } |
<> | 149:156823d33999 | 94 | } |
<> | 149:156823d33999 | 95 | return Count; |
<> | 149:156823d33999 | 96 | } |
<> | 149:156823d33999 | 97 | |
<> | 149:156823d33999 | 98 | /* See i2c_api.h for details */ |
<> | 149:156823d33999 | 99 | int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) |
<> | 149:156823d33999 | 100 | { |
<> | 149:156823d33999 | 101 | int Count, status; |
<> | 149:156823d33999 | 102 | const char WriteData = (address & I2C_READ_WRITE_BIT_MASK) & 0xFF; |
<> | 149:156823d33999 | 103 | |
<> | 149:156823d33999 | 104 | /* Send start bit */ |
<> | 149:156823d33999 | 105 | status = fI2cStart(obj); |
<> | 149:156823d33999 | 106 | if(status) { |
<> | 149:156823d33999 | 107 | /* Error sending start bit */ |
<> | 149:156823d33999 | 108 | return status; |
<> | 149:156823d33999 | 109 | } |
<> | 149:156823d33999 | 110 | |
<> | 149:156823d33999 | 111 | /* Send address | write */ |
<> | 149:156823d33999 | 112 | Count = fI2cWriteB(obj, &WriteData, 1); |
<> | 149:156823d33999 | 113 | if(Count != 1) { |
<> | 149:156823d33999 | 114 | /* Error sending address */ |
<> | 149:156823d33999 | 115 | return Count; |
<> | 149:156823d33999 | 116 | } |
<> | 149:156823d33999 | 117 | |
<> | 149:156823d33999 | 118 | /* Sens command, [data] */ |
<> | 149:156823d33999 | 119 | Count = fI2cWriteB(obj, data, length); |
<> | 149:156823d33999 | 120 | if(Count != length) { |
<> | 149:156823d33999 | 121 | /* Error sending address */ |
<> | 149:156823d33999 | 122 | return Count; |
<> | 149:156823d33999 | 123 | } |
<> | 149:156823d33999 | 124 | |
<> | 149:156823d33999 | 125 | if(stop) { /* If stop requested */ |
<> | 149:156823d33999 | 126 | /* Send stop bit */ |
<> | 149:156823d33999 | 127 | status = fI2cStop(obj); |
<> | 149:156823d33999 | 128 | if(status) { |
<> | 149:156823d33999 | 129 | /* Error sending stop bit */ |
<> | 149:156823d33999 | 130 | return status; |
<> | 149:156823d33999 | 131 | } |
<> | 149:156823d33999 | 132 | } |
<> | 149:156823d33999 | 133 | return Count; |
<> | 149:156823d33999 | 134 | } |
<> | 149:156823d33999 | 135 | |
<> | 149:156823d33999 | 136 | /* See i2c_api.h for details */ |
<> | 149:156823d33999 | 137 | void i2c_reset(i2c_t *obj) |
<> | 149:156823d33999 | 138 | { |
<> | 149:156823d33999 | 139 | (void)fI2cStop(obj); |
<> | 149:156823d33999 | 140 | } |
<> | 149:156823d33999 | 141 | |
<> | 149:156823d33999 | 142 | /* See i2c_api.h for details */ |
<> | 149:156823d33999 | 143 | int i2c_byte_read(i2c_t *obj, int last) /* TODO return size can be uint8_t */ |
<> | 149:156823d33999 | 144 | { |
<> | 149:156823d33999 | 145 | int Count; |
<> | 149:156823d33999 | 146 | char data; |
<> | 149:156823d33999 | 147 | Count = fI2cReadB(obj, &data, 1); |
<> | 149:156823d33999 | 148 | if(Count != 1) { |
<> | 149:156823d33999 | 149 | /* Error */ |
<> | 149:156823d33999 | 150 | return Count; |
<> | 149:156823d33999 | 151 | } |
<> | 149:156823d33999 | 152 | if(last) { |
<> | 149:156823d33999 | 153 | /* ACK */ |
<> | 149:156823d33999 | 154 | obj->membase->CMD_REG = I2C_CMD_WDAT0; |
<> | 149:156823d33999 | 155 | } else { |
<> | 149:156823d33999 | 156 | /* No ACK */ |
<> | 149:156823d33999 | 157 | obj->membase->CMD_REG = I2C_CMD_WDAT1; |
<> | 149:156823d33999 | 158 | } |
<> | 149:156823d33999 | 159 | return data; |
<> | 149:156823d33999 | 160 | } |
<> | 149:156823d33999 | 161 | |
<> | 149:156823d33999 | 162 | /* See i2c_api.h for details */ |
<> | 149:156823d33999 | 163 | int i2c_byte_write(i2c_t *obj, int data) |
<> | 149:156823d33999 | 164 | { |
<> | 149:156823d33999 | 165 | int Count; |
<> | 149:156823d33999 | 166 | Count = fI2cWriteB(obj, (const char *)&data, 1); |
<> | 149:156823d33999 | 167 | if(Count != 1) { |
<> | 149:156823d33999 | 168 | return Count; |
<> | 149:156823d33999 | 169 | } |
<> | 149:156823d33999 | 170 | |
<> | 149:156823d33999 | 171 | obj->membase->CMD_REG = I2C_CMD_VRFY_ACK; /* Verify ACK */ |
<> | 149:156823d33999 | 172 | |
<> | 149:156823d33999 | 173 | while(obj->membase->STATUS.WORD & I2C_STATUS_CMD_FIFO_OFL_BIT); /* Wait till command overflow ends */ |
<> | 149:156823d33999 | 174 | |
<> | 149:156823d33999 | 175 | if(obj->membase->STATUS.WORD & I2C_STATUS_BUS_ERR_BIT) { |
<> | 149:156823d33999 | 176 | /* Bus error means NAK received */ |
<> | 149:156823d33999 | 177 | return 0; |
<> | 149:156823d33999 | 178 | } else { |
<> | 149:156823d33999 | 179 | /* ACK received */ |
<> | 149:156823d33999 | 180 | return 1; |
<> | 149:156823d33999 | 181 | } |
<> | 149:156823d33999 | 182 | } |
<> | 149:156823d33999 | 183 | |
<> | 149:156823d33999 | 184 | #endif /* DEVICE_I2C */ |