PN532 Driver library This library provides an abstract API to drive the pn532 nfc chip, with I2C/HSU/SPI interface. Its based on the Seeed Studio's Arduino version.
Dependents: PN532_ReadUid Nfctest2
Wire.cpp@0:db8030e71f55, 2016-09-13 (annotated)
- Committer:
- dotnfc
- Date:
- Tue Sep 13 06:01:19 2016 +0000
- Revision:
- 0:db8030e71f55
first commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
dotnfc | 0:db8030e71f55 | 1 | /* |
dotnfc | 0:db8030e71f55 | 2 | * TwoWire.h |
dotnfc | 0:db8030e71f55 | 3 | * Copyright (c) 2011 Cristian Maglie <c.maglie@bug.st>. |
dotnfc | 0:db8030e71f55 | 4 | * All rights reserved. |
dotnfc | 0:db8030e71f55 | 5 | * |
dotnfc | 0:db8030e71f55 | 6 | * This library is free software; you can redistribute it and/or |
dotnfc | 0:db8030e71f55 | 7 | * modify it under the terms of the GNU Lesser General Public |
dotnfc | 0:db8030e71f55 | 8 | * License as published by the Free Software Foundation; either |
dotnfc | 0:db8030e71f55 | 9 | * version 2.1 of the License, or (at your option) any later version. |
dotnfc | 0:db8030e71f55 | 10 | * |
dotnfc | 0:db8030e71f55 | 11 | * This library is distributed in the hope that it will be useful, |
dotnfc | 0:db8030e71f55 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
dotnfc | 0:db8030e71f55 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
dotnfc | 0:db8030e71f55 | 14 | * Lesser General Public License for more details. |
dotnfc | 0:db8030e71f55 | 15 | * |
dotnfc | 0:db8030e71f55 | 16 | * You should have received a copy of the GNU Lesser General Public |
dotnfc | 0:db8030e71f55 | 17 | * License along with this library; if not, write to the Free Software |
dotnfc | 0:db8030e71f55 | 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
dotnfc | 0:db8030e71f55 | 19 | */ |
dotnfc | 0:db8030e71f55 | 20 | |
dotnfc | 0:db8030e71f55 | 21 | extern "C" { |
dotnfc | 0:db8030e71f55 | 22 | #include <string.h> |
dotnfc | 0:db8030e71f55 | 23 | } |
dotnfc | 0:db8030e71f55 | 24 | |
dotnfc | 0:db8030e71f55 | 25 | #include "Wire.h" |
dotnfc | 0:db8030e71f55 | 26 | |
dotnfc | 0:db8030e71f55 | 27 | |
dotnfc | 0:db8030e71f55 | 28 | |
dotnfc | 0:db8030e71f55 | 29 | #define EVENT_TIMEOUT 100 |
dotnfc | 0:db8030e71f55 | 30 | |
dotnfc | 0:db8030e71f55 | 31 | |
dotnfc | 0:db8030e71f55 | 32 | TwoWire::TwoWire(I2C_TypeDef *_twi) : |
dotnfc | 0:db8030e71f55 | 33 | twi(_twi), rxBufferIndex(0), rxBufferLength(0), txAddress(0), |
dotnfc | 0:db8030e71f55 | 34 | txBufferLength(0), srvBufferIndex(0), srvBufferLength(0), status( |
dotnfc | 0:db8030e71f55 | 35 | UNINITIALIZED){ |
dotnfc | 0:db8030e71f55 | 36 | // Empty |
dotnfc | 0:db8030e71f55 | 37 | } |
dotnfc | 0:db8030e71f55 | 38 | |
dotnfc | 0:db8030e71f55 | 39 | void TwoWire::begin(void) { |
dotnfc | 0:db8030e71f55 | 40 | if (onBeginCallback) |
dotnfc | 0:db8030e71f55 | 41 | onBeginCallback(); |
dotnfc | 0:db8030e71f55 | 42 | |
dotnfc | 0:db8030e71f55 | 43 | if (twi==I2C1) |
dotnfc | 0:db8030e71f55 | 44 | { |
dotnfc | 0:db8030e71f55 | 45 | RCC_I2CCLKConfig(RCC_I2C1CLK_HSI); |
dotnfc | 0:db8030e71f55 | 46 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); |
dotnfc | 0:db8030e71f55 | 47 | |
dotnfc | 0:db8030e71f55 | 48 | pinMode(SDA, ALTERNATE); |
dotnfc | 0:db8030e71f55 | 49 | pinMode(SCL, ALTERNATE); |
dotnfc | 0:db8030e71f55 | 50 | } |
dotnfc | 0:db8030e71f55 | 51 | else if (twi == I2C2) |
dotnfc | 0:db8030e71f55 | 52 | { |
dotnfc | 0:db8030e71f55 | 53 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE); |
dotnfc | 0:db8030e71f55 | 54 | |
dotnfc | 0:db8030e71f55 | 55 | pinMode(SDA1, ALTERNATE); |
dotnfc | 0:db8030e71f55 | 56 | pinMode(SCL1, ALTERNATE); |
dotnfc | 0:db8030e71f55 | 57 | } |
dotnfc | 0:db8030e71f55 | 58 | |
dotnfc | 0:db8030e71f55 | 59 | |
dotnfc | 0:db8030e71f55 | 60 | I2C_DeInit(twi); |
dotnfc | 0:db8030e71f55 | 61 | |
dotnfc | 0:db8030e71f55 | 62 | I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; |
dotnfc | 0:db8030e71f55 | 63 | I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable; |
dotnfc | 0:db8030e71f55 | 64 | I2C_InitStructure.I2C_DigitalFilter = 0x00; |
dotnfc | 0:db8030e71f55 | 65 | if (status == UNINITIALIZED) |
dotnfc | 0:db8030e71f55 | 66 | { |
dotnfc | 0:db8030e71f55 | 67 | I2C_InitStructure.I2C_OwnAddress1 = 0x00; |
dotnfc | 0:db8030e71f55 | 68 | status = MASTER_IDLE; |
dotnfc | 0:db8030e71f55 | 69 | } |
dotnfc | 0:db8030e71f55 | 70 | I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; |
dotnfc | 0:db8030e71f55 | 71 | I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; |
dotnfc | 0:db8030e71f55 | 72 | I2C_InitStructure.I2C_Timing = 0x00E0D3FF; |
dotnfc | 0:db8030e71f55 | 73 | I2C_Init(twi, &I2C_InitStructure); |
dotnfc | 0:db8030e71f55 | 74 | |
dotnfc | 0:db8030e71f55 | 75 | I2C_Cmd(twi, ENABLE); |
dotnfc | 0:db8030e71f55 | 76 | |
dotnfc | 0:db8030e71f55 | 77 | |
dotnfc | 0:db8030e71f55 | 78 | } |
dotnfc | 0:db8030e71f55 | 79 | |
dotnfc | 0:db8030e71f55 | 80 | void TwoWire::begin(uint8_t address) { |
dotnfc | 0:db8030e71f55 | 81 | if (onBeginCallback) |
dotnfc | 0:db8030e71f55 | 82 | onBeginCallback(); |
dotnfc | 0:db8030e71f55 | 83 | status = SLAVE_IDLE; |
dotnfc | 0:db8030e71f55 | 84 | if (twi==I2C1) |
dotnfc | 0:db8030e71f55 | 85 | { |
dotnfc | 0:db8030e71f55 | 86 | RCC_I2CCLKConfig(RCC_I2C1CLK_HSI); |
dotnfc | 0:db8030e71f55 | 87 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); |
dotnfc | 0:db8030e71f55 | 88 | |
dotnfc | 0:db8030e71f55 | 89 | pinMode(SDA, ALTERNATE); |
dotnfc | 0:db8030e71f55 | 90 | pinMode(SCL, ALTERNATE); |
dotnfc | 0:db8030e71f55 | 91 | } |
dotnfc | 0:db8030e71f55 | 92 | |
dotnfc | 0:db8030e71f55 | 93 | |
dotnfc | 0:db8030e71f55 | 94 | I2C_DeInit(twi); |
dotnfc | 0:db8030e71f55 | 95 | |
dotnfc | 0:db8030e71f55 | 96 | I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; |
dotnfc | 0:db8030e71f55 | 97 | I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable; |
dotnfc | 0:db8030e71f55 | 98 | I2C_InitStructure.I2C_DigitalFilter = 0x00; |
dotnfc | 0:db8030e71f55 | 99 | I2C_InitStructure.I2C_OwnAddress1 = address; |
dotnfc | 0:db8030e71f55 | 100 | I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; |
dotnfc | 0:db8030e71f55 | 101 | I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; |
dotnfc | 0:db8030e71f55 | 102 | I2C_InitStructure.I2C_Timing = 0x00E0D3FF; |
dotnfc | 0:db8030e71f55 | 103 | I2C_Init(twi, &I2C_InitStructure); |
dotnfc | 0:db8030e71f55 | 104 | |
dotnfc | 0:db8030e71f55 | 105 | NVIC_SetPriority(I2C1_IRQn, 0); |
dotnfc | 0:db8030e71f55 | 106 | NVIC_EnableIRQ(I2C1_IRQn); |
dotnfc | 0:db8030e71f55 | 107 | I2C_Cmd(twi, ENABLE); |
dotnfc | 0:db8030e71f55 | 108 | I2C_ITConfig(twi, I2C_IT_ADDRI, ENABLE); |
dotnfc | 0:db8030e71f55 | 109 | } |
dotnfc | 0:db8030e71f55 | 110 | |
dotnfc | 0:db8030e71f55 | 111 | void TwoWire::begin(int address) { |
dotnfc | 0:db8030e71f55 | 112 | address <<= 1; |
dotnfc | 0:db8030e71f55 | 113 | begin((uint8_t) address); |
dotnfc | 0:db8030e71f55 | 114 | } |
dotnfc | 0:db8030e71f55 | 115 | |
dotnfc | 0:db8030e71f55 | 116 | uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) { |
dotnfc | 0:db8030e71f55 | 117 | address <<= 1; |
dotnfc | 0:db8030e71f55 | 118 | if (quantity > BUFFER_LENGTH) |
dotnfc | 0:db8030e71f55 | 119 | quantity = BUFFER_LENGTH; |
dotnfc | 0:db8030e71f55 | 120 | uint32_t _millis; |
dotnfc | 0:db8030e71f55 | 121 | |
dotnfc | 0:db8030e71f55 | 122 | _millis = millis(); |
dotnfc | 0:db8030e71f55 | 123 | while(I2C_GetFlagStatus(twi, I2C_FLAG_BUSY) != RESET) |
dotnfc | 0:db8030e71f55 | 124 | { |
dotnfc | 0:db8030e71f55 | 125 | if(EVENT_TIMEOUT < (millis() - _millis)) return 0; |
dotnfc | 0:db8030e71f55 | 126 | } |
dotnfc | 0:db8030e71f55 | 127 | |
dotnfc | 0:db8030e71f55 | 128 | I2C_TransferHandling(twi, address, quantity, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); |
dotnfc | 0:db8030e71f55 | 129 | |
dotnfc | 0:db8030e71f55 | 130 | |
dotnfc | 0:db8030e71f55 | 131 | uint8_t *pBuffer = rxBuffer; |
dotnfc | 0:db8030e71f55 | 132 | uint8_t numByteToRead = quantity; |
dotnfc | 0:db8030e71f55 | 133 | uint8_t bytesRead = 0; |
dotnfc | 0:db8030e71f55 | 134 | /* While there is data to be read */ |
dotnfc | 0:db8030e71f55 | 135 | while(numByteToRead) |
dotnfc | 0:db8030e71f55 | 136 | { |
dotnfc | 0:db8030e71f55 | 137 | _millis = millis(); |
dotnfc | 0:db8030e71f55 | 138 | while(I2C_GetFlagStatus(twi, I2C_FLAG_RXNE) == RESET) |
dotnfc | 0:db8030e71f55 | 139 | { |
dotnfc | 0:db8030e71f55 | 140 | if(EVENT_TIMEOUT < (millis() - _millis)) return 0; |
dotnfc | 0:db8030e71f55 | 141 | } |
dotnfc | 0:db8030e71f55 | 142 | /* Read a byte from the Slave */ |
dotnfc | 0:db8030e71f55 | 143 | *pBuffer = I2C_ReceiveData(twi); |
dotnfc | 0:db8030e71f55 | 144 | |
dotnfc | 0:db8030e71f55 | 145 | bytesRead++; |
dotnfc | 0:db8030e71f55 | 146 | |
dotnfc | 0:db8030e71f55 | 147 | /* Point to the next location where the byte read will be saved */ |
dotnfc | 0:db8030e71f55 | 148 | pBuffer++; |
dotnfc | 0:db8030e71f55 | 149 | |
dotnfc | 0:db8030e71f55 | 150 | /* Decrement the read bytes counter */ |
dotnfc | 0:db8030e71f55 | 151 | numByteToRead--; |
dotnfc | 0:db8030e71f55 | 152 | } |
dotnfc | 0:db8030e71f55 | 153 | _millis = millis(); |
dotnfc | 0:db8030e71f55 | 154 | while(I2C_GetFlagStatus(twi, I2C_FLAG_STOPF) == RESET) |
dotnfc | 0:db8030e71f55 | 155 | { |
dotnfc | 0:db8030e71f55 | 156 | if(EVENT_TIMEOUT < (millis() - _millis)) return 0; |
dotnfc | 0:db8030e71f55 | 157 | } |
dotnfc | 0:db8030e71f55 | 158 | // set rx buffer iterator vars |
dotnfc | 0:db8030e71f55 | 159 | rxBufferIndex = 0; |
dotnfc | 0:db8030e71f55 | 160 | rxBufferLength = bytesRead; |
dotnfc | 0:db8030e71f55 | 161 | |
dotnfc | 0:db8030e71f55 | 162 | return bytesRead; |
dotnfc | 0:db8030e71f55 | 163 | } |
dotnfc | 0:db8030e71f55 | 164 | |
dotnfc | 0:db8030e71f55 | 165 | uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity) { |
dotnfc | 0:db8030e71f55 | 166 | return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) true); |
dotnfc | 0:db8030e71f55 | 167 | } |
dotnfc | 0:db8030e71f55 | 168 | |
dotnfc | 0:db8030e71f55 | 169 | uint8_t TwoWire::requestFrom(int address, int quantity) { |
dotnfc | 0:db8030e71f55 | 170 | return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) true); |
dotnfc | 0:db8030e71f55 | 171 | } |
dotnfc | 0:db8030e71f55 | 172 | |
dotnfc | 0:db8030e71f55 | 173 | uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop) { |
dotnfc | 0:db8030e71f55 | 174 | return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) sendStop); |
dotnfc | 0:db8030e71f55 | 175 | } |
dotnfc | 0:db8030e71f55 | 176 | |
dotnfc | 0:db8030e71f55 | 177 | void TwoWire::beginTransmission(uint8_t address) { |
dotnfc | 0:db8030e71f55 | 178 | status = MASTER_SEND; |
dotnfc | 0:db8030e71f55 | 179 | |
dotnfc | 0:db8030e71f55 | 180 | // save address of target and empty buffer |
dotnfc | 0:db8030e71f55 | 181 | txAddress = address; |
dotnfc | 0:db8030e71f55 | 182 | txBufferLength = 0; |
dotnfc | 0:db8030e71f55 | 183 | } |
dotnfc | 0:db8030e71f55 | 184 | |
dotnfc | 0:db8030e71f55 | 185 | void TwoWire::beginTransmission(int address) { |
dotnfc | 0:db8030e71f55 | 186 | address <<= 1; |
dotnfc | 0:db8030e71f55 | 187 | beginTransmission((uint8_t) address); |
dotnfc | 0:db8030e71f55 | 188 | } |
dotnfc | 0:db8030e71f55 | 189 | |
dotnfc | 0:db8030e71f55 | 190 | // |
dotnfc | 0:db8030e71f55 | 191 | // Originally, 'endTransmission' was an f(void) function. |
dotnfc | 0:db8030e71f55 | 192 | // It has been modified to take one parameter indicating |
dotnfc | 0:db8030e71f55 | 193 | // whether or not a STOP should be performed on the bus. |
dotnfc | 0:db8030e71f55 | 194 | // Calling endTransmission(false) allows a sketch to |
dotnfc | 0:db8030e71f55 | 195 | // perform a repeated start. |
dotnfc | 0:db8030e71f55 | 196 | // |
dotnfc | 0:db8030e71f55 | 197 | // WARNING: Nothing in the library keeps track of whether |
dotnfc | 0:db8030e71f55 | 198 | // the bus tenure has been properly ended with a STOP. It |
dotnfc | 0:db8030e71f55 | 199 | // is very possible to leave the bus in a hung state if |
dotnfc | 0:db8030e71f55 | 200 | // no call to endTransmission(true) is made. Some I2C |
dotnfc | 0:db8030e71f55 | 201 | // devices will behave oddly if they do not see a STOP. |
dotnfc | 0:db8030e71f55 | 202 | // |
dotnfc | 0:db8030e71f55 | 203 | uint8_t TwoWire::endTransmission(uint8_t sendStop) { |
dotnfc | 0:db8030e71f55 | 204 | uint32_t _millis; |
dotnfc | 0:db8030e71f55 | 205 | |
dotnfc | 0:db8030e71f55 | 206 | _millis = millis(); |
dotnfc | 0:db8030e71f55 | 207 | while(I2C_GetFlagStatus(twi, I2C_FLAG_BUSY) != RESET) |
dotnfc | 0:db8030e71f55 | 208 | { |
dotnfc | 0:db8030e71f55 | 209 | if(EVENT_TIMEOUT < (millis() - _millis)) return 0; |
dotnfc | 0:db8030e71f55 | 210 | } |
dotnfc | 0:db8030e71f55 | 211 | if (sendStop == true) |
dotnfc | 0:db8030e71f55 | 212 | { |
dotnfc | 0:db8030e71f55 | 213 | I2C_TransferHandling(twi, txAddress, txBufferLength, I2C_AutoEnd_Mode, I2C_Generate_Start_Write); |
dotnfc | 0:db8030e71f55 | 214 | } |
dotnfc | 0:db8030e71f55 | 215 | else |
dotnfc | 0:db8030e71f55 | 216 | { |
dotnfc | 0:db8030e71f55 | 217 | I2C_TransferHandling(twi, txAddress, txBufferLength, I2C_SoftEnd_Mode, I2C_Generate_Start_Write); |
dotnfc | 0:db8030e71f55 | 218 | } |
dotnfc | 0:db8030e71f55 | 219 | uint8_t *pBuffer = txBuffer; |
dotnfc | 0:db8030e71f55 | 220 | uint8_t NumByteToWrite = txBufferLength; |
dotnfc | 0:db8030e71f55 | 221 | /* While there is data to be read */ |
dotnfc | 0:db8030e71f55 | 222 | while(NumByteToWrite--) |
dotnfc | 0:db8030e71f55 | 223 | { |
dotnfc | 0:db8030e71f55 | 224 | _millis = millis(); |
dotnfc | 0:db8030e71f55 | 225 | while(I2C_GetFlagStatus(twi, I2C_FLAG_TXIS) == RESET) |
dotnfc | 0:db8030e71f55 | 226 | { |
dotnfc | 0:db8030e71f55 | 227 | if(EVENT_TIMEOUT < (millis() - _millis)) return 0; |
dotnfc | 0:db8030e71f55 | 228 | } |
dotnfc | 0:db8030e71f55 | 229 | /* Send the current byte to slave */ |
dotnfc | 0:db8030e71f55 | 230 | I2C_SendData(twi, *pBuffer++); |
dotnfc | 0:db8030e71f55 | 231 | } |
dotnfc | 0:db8030e71f55 | 232 | _millis = millis(); |
dotnfc | 0:db8030e71f55 | 233 | if (sendStop == true) |
dotnfc | 0:db8030e71f55 | 234 | { |
dotnfc | 0:db8030e71f55 | 235 | while(I2C_GetFlagStatus(twi, I2C_FLAG_STOPF) == RESET) |
dotnfc | 0:db8030e71f55 | 236 | { |
dotnfc | 0:db8030e71f55 | 237 | if(EVENT_TIMEOUT < (millis() - _millis)) return 0; |
dotnfc | 0:db8030e71f55 | 238 | } |
dotnfc | 0:db8030e71f55 | 239 | } |
dotnfc | 0:db8030e71f55 | 240 | else |
dotnfc | 0:db8030e71f55 | 241 | { |
dotnfc | 0:db8030e71f55 | 242 | while(I2C_GetFlagStatus(twi, I2C_FLAG_STOPF) == RESET) |
dotnfc | 0:db8030e71f55 | 243 | { |
dotnfc | 0:db8030e71f55 | 244 | if(EVENT_TIMEOUT < (millis() - _millis)) return 0; |
dotnfc | 0:db8030e71f55 | 245 | } |
dotnfc | 0:db8030e71f55 | 246 | } |
dotnfc | 0:db8030e71f55 | 247 | // reset tx buffer iterator vars |
dotnfc | 0:db8030e71f55 | 248 | txBufferLength = 0; |
dotnfc | 0:db8030e71f55 | 249 | |
dotnfc | 0:db8030e71f55 | 250 | status = MASTER_IDLE; |
dotnfc | 0:db8030e71f55 | 251 | return 0; |
dotnfc | 0:db8030e71f55 | 252 | } |
dotnfc | 0:db8030e71f55 | 253 | |
dotnfc | 0:db8030e71f55 | 254 | // This provides backwards compatibility with the original |
dotnfc | 0:db8030e71f55 | 255 | // definition, and expected behaviour, of endTransmission |
dotnfc | 0:db8030e71f55 | 256 | // |
dotnfc | 0:db8030e71f55 | 257 | uint8_t TwoWire::endTransmission(void) |
dotnfc | 0:db8030e71f55 | 258 | { |
dotnfc | 0:db8030e71f55 | 259 | return endTransmission(true); |
dotnfc | 0:db8030e71f55 | 260 | } |
dotnfc | 0:db8030e71f55 | 261 | |
dotnfc | 0:db8030e71f55 | 262 | size_t TwoWire::write(uint8_t data) { |
dotnfc | 0:db8030e71f55 | 263 | if (status == MASTER_SEND) { |
dotnfc | 0:db8030e71f55 | 264 | if (txBufferLength >= BUFFER_LENGTH) |
dotnfc | 0:db8030e71f55 | 265 | return 0; |
dotnfc | 0:db8030e71f55 | 266 | txBuffer[txBufferLength++] = data; |
dotnfc | 0:db8030e71f55 | 267 | return 1; |
dotnfc | 0:db8030e71f55 | 268 | } else { |
dotnfc | 0:db8030e71f55 | 269 | if (srvBufferLength >= BUFFER_LENGTH) |
dotnfc | 0:db8030e71f55 | 270 | return 0; |
dotnfc | 0:db8030e71f55 | 271 | srvBuffer[srvBufferLength++] = data; |
dotnfc | 0:db8030e71f55 | 272 | return 1; |
dotnfc | 0:db8030e71f55 | 273 | } |
dotnfc | 0:db8030e71f55 | 274 | } |
dotnfc | 0:db8030e71f55 | 275 | |
dotnfc | 0:db8030e71f55 | 276 | size_t TwoWire::write(const uint8_t *data, size_t quantity) { |
dotnfc | 0:db8030e71f55 | 277 | if (status == MASTER_SEND) { |
dotnfc | 0:db8030e71f55 | 278 | for (size_t i = 0; i < quantity; ++i) { |
dotnfc | 0:db8030e71f55 | 279 | if (txBufferLength >= BUFFER_LENGTH) |
dotnfc | 0:db8030e71f55 | 280 | return i; |
dotnfc | 0:db8030e71f55 | 281 | txBuffer[txBufferLength++] = data[i]; |
dotnfc | 0:db8030e71f55 | 282 | } |
dotnfc | 0:db8030e71f55 | 283 | } else { |
dotnfc | 0:db8030e71f55 | 284 | for (size_t i = 0; i < quantity; ++i) { |
dotnfc | 0:db8030e71f55 | 285 | if (srvBufferLength >= BUFFER_LENGTH) |
dotnfc | 0:db8030e71f55 | 286 | return i; |
dotnfc | 0:db8030e71f55 | 287 | srvBuffer[srvBufferLength++] = data[i]; |
dotnfc | 0:db8030e71f55 | 288 | } |
dotnfc | 0:db8030e71f55 | 289 | } |
dotnfc | 0:db8030e71f55 | 290 | return quantity; |
dotnfc | 0:db8030e71f55 | 291 | } |
dotnfc | 0:db8030e71f55 | 292 | |
dotnfc | 0:db8030e71f55 | 293 | int TwoWire::available(void) { |
dotnfc | 0:db8030e71f55 | 294 | return rxBufferLength - rxBufferIndex; |
dotnfc | 0:db8030e71f55 | 295 | } |
dotnfc | 0:db8030e71f55 | 296 | |
dotnfc | 0:db8030e71f55 | 297 | int TwoWire::read(void) { |
dotnfc | 0:db8030e71f55 | 298 | if (rxBufferIndex < rxBufferLength) |
dotnfc | 0:db8030e71f55 | 299 | return rxBuffer[rxBufferIndex++]; |
dotnfc | 0:db8030e71f55 | 300 | return -1; |
dotnfc | 0:db8030e71f55 | 301 | } |
dotnfc | 0:db8030e71f55 | 302 | |
dotnfc | 0:db8030e71f55 | 303 | int TwoWire::peek(void) { |
dotnfc | 0:db8030e71f55 | 304 | if (rxBufferIndex < rxBufferLength) |
dotnfc | 0:db8030e71f55 | 305 | return rxBuffer[rxBufferIndex]; |
dotnfc | 0:db8030e71f55 | 306 | return -1; |
dotnfc | 0:db8030e71f55 | 307 | } |
dotnfc | 0:db8030e71f55 | 308 | |
dotnfc | 0:db8030e71f55 | 309 | void TwoWire::flush(void) { |
dotnfc | 0:db8030e71f55 | 310 | // Do nothing, use endTransmission(..) to force |
dotnfc | 0:db8030e71f55 | 311 | // data transfer. |
dotnfc | 0:db8030e71f55 | 312 | } |
dotnfc | 0:db8030e71f55 | 313 | |
dotnfc | 0:db8030e71f55 | 314 | void TwoWire::onReceive(void(*function)(int)) { |
dotnfc | 0:db8030e71f55 | 315 | onReceiveCallback = function; |
dotnfc | 0:db8030e71f55 | 316 | } |
dotnfc | 0:db8030e71f55 | 317 | |
dotnfc | 0:db8030e71f55 | 318 | void TwoWire::onRequest(void(*function)(void)) { |
dotnfc | 0:db8030e71f55 | 319 | onRequestCallback = function; |
dotnfc | 0:db8030e71f55 | 320 | } |
dotnfc | 0:db8030e71f55 | 321 | |
dotnfc | 0:db8030e71f55 | 322 | void TwoWire::onService(void) |
dotnfc | 0:db8030e71f55 | 323 | { |
dotnfc | 0:db8030e71f55 | 324 | if (I2C_GetITStatus(twi, I2C_IT_ADDR) == SET) |
dotnfc | 0:db8030e71f55 | 325 | { |
dotnfc | 0:db8030e71f55 | 326 | I2C_ITConfig(twi, I2C_IT_RXI | I2C_IT_TXI | I2C_IT_STOPI, ENABLE); |
dotnfc | 0:db8030e71f55 | 327 | srvBufferLength = 0; |
dotnfc | 0:db8030e71f55 | 328 | srvBufferIndex = 0; |
dotnfc | 0:db8030e71f55 | 329 | if (twi->ISR & (1 << 16)) { |
dotnfc | 0:db8030e71f55 | 330 | status = SLAVE_SEND; |
dotnfc | 0:db8030e71f55 | 331 | if (onRequestCallback) |
dotnfc | 0:db8030e71f55 | 332 | onRequestCallback(); |
dotnfc | 0:db8030e71f55 | 333 | } else { |
dotnfc | 0:db8030e71f55 | 334 | status = SLAVE_RECV; |
dotnfc | 0:db8030e71f55 | 335 | } |
dotnfc | 0:db8030e71f55 | 336 | |
dotnfc | 0:db8030e71f55 | 337 | I2C_ClearITPendingBit(twi, I2C_IT_ADDR); |
dotnfc | 0:db8030e71f55 | 338 | } |
dotnfc | 0:db8030e71f55 | 339 | if (I2C_GetITStatus(twi, I2C_IT_TXIS) == SET) |
dotnfc | 0:db8030e71f55 | 340 | { |
dotnfc | 0:db8030e71f55 | 341 | uint8_t c = 'x'; |
dotnfc | 0:db8030e71f55 | 342 | if (srvBufferIndex < srvBufferLength) |
dotnfc | 0:db8030e71f55 | 343 | c = srvBuffer[srvBufferIndex++]; |
dotnfc | 0:db8030e71f55 | 344 | I2C_SendData(twi, c); |
dotnfc | 0:db8030e71f55 | 345 | } |
dotnfc | 0:db8030e71f55 | 346 | if (I2C_GetITStatus(twi, I2C_IT_RXNE) == SET) |
dotnfc | 0:db8030e71f55 | 347 | { |
dotnfc | 0:db8030e71f55 | 348 | if (srvBufferLength < BUFFER_LENGTH) |
dotnfc | 0:db8030e71f55 | 349 | srvBuffer[srvBufferLength++] = I2C_ReceiveData(twi); |
dotnfc | 0:db8030e71f55 | 350 | } |
dotnfc | 0:db8030e71f55 | 351 | if (I2C_GetITStatus(twi, I2C_IT_STOPF) == SET) |
dotnfc | 0:db8030e71f55 | 352 | { |
dotnfc | 0:db8030e71f55 | 353 | if (status == SLAVE_RECV && onReceiveCallback) { |
dotnfc | 0:db8030e71f55 | 354 | // Copy data into rxBuffer |
dotnfc | 0:db8030e71f55 | 355 | // (allows to receive another packet while the |
dotnfc | 0:db8030e71f55 | 356 | // user program reads actual data) |
dotnfc | 0:db8030e71f55 | 357 | for (uint8_t i = 0; i < srvBufferLength; ++i) |
dotnfc | 0:db8030e71f55 | 358 | rxBuffer[i] = srvBuffer[i]; |
dotnfc | 0:db8030e71f55 | 359 | rxBufferIndex = 0; |
dotnfc | 0:db8030e71f55 | 360 | rxBufferLength = srvBufferLength; |
dotnfc | 0:db8030e71f55 | 361 | // Alert calling program |
dotnfc | 0:db8030e71f55 | 362 | onReceiveCallback( rxBufferLength); |
dotnfc | 0:db8030e71f55 | 363 | } |
dotnfc | 0:db8030e71f55 | 364 | I2C_ITConfig(twi, I2C_IT_ADDRI, ENABLE); |
dotnfc | 0:db8030e71f55 | 365 | I2C_ITConfig(twi, I2C_IT_RXI | I2C_IT_TXI | I2C_IT_STOPI, DISABLE); |
dotnfc | 0:db8030e71f55 | 366 | I2C_ClearITPendingBit(twi, I2C_IT_STOPF); |
dotnfc | 0:db8030e71f55 | 367 | } |
dotnfc | 0:db8030e71f55 | 368 | } |
dotnfc | 0:db8030e71f55 | 369 | |
dotnfc | 0:db8030e71f55 | 370 | |
dotnfc | 0:db8030e71f55 | 371 | |
dotnfc | 0:db8030e71f55 | 372 | |
dotnfc | 0:db8030e71f55 | 373 | TwoWire Wire = TwoWire(I2C1); |
dotnfc | 0:db8030e71f55 | 374 | TwoWire Wire1 = TwoWire(I2C2); |
dotnfc | 0:db8030e71f55 | 375 | |
dotnfc | 0:db8030e71f55 | 376 | #ifdef __cplusplus |
dotnfc | 0:db8030e71f55 | 377 | extern "C" { |
dotnfc | 0:db8030e71f55 | 378 | #endif |
dotnfc | 0:db8030e71f55 | 379 | void WIRE_ISR_HANDLER(void) { |
dotnfc | 0:db8030e71f55 | 380 | Wire.onService(); |
dotnfc | 0:db8030e71f55 | 381 | } |
dotnfc | 0:db8030e71f55 | 382 | |
dotnfc | 0:db8030e71f55 | 383 | void WIRE1_ISR_HANDLER(void) { |
dotnfc | 0:db8030e71f55 | 384 | Wire1.onService(); |
dotnfc | 0:db8030e71f55 | 385 | } |
dotnfc | 0:db8030e71f55 | 386 | #ifdef __cplusplus |
dotnfc | 0:db8030e71f55 | 387 | } |
dotnfc | 0:db8030e71f55 | 388 | #endif |
dotnfc | 0:db8030e71f55 | 389 | |
dotnfc | 0:db8030e71f55 | 390 | |
dotnfc | 0:db8030e71f55 | 391 |