Kenji Arai / TYBLE16_mbedlized_os5_several_examples_1st

Dependencies:   nRF51_Vdd TextLCD BME280

Committer:
kenjiArai
Date:
Thu Dec 19 07:27:50 2019 +0000
Revision:
6:6dd8c932bd56
Parent:
4:e9dfb4ca4277
updated each main.cpp

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 4:e9dfb4ca4277 1 /*
kenjiArai 4:e9dfb4ca4277 2 * Copyright (c) 2014-2018, ARM Limited, All Rights Reserved
kenjiArai 4:e9dfb4ca4277 3 * SPDX-License-Identifier: Apache-2.0
kenjiArai 4:e9dfb4ca4277 4 *
kenjiArai 4:e9dfb4ca4277 5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
kenjiArai 4:e9dfb4ca4277 6 * not use this file except in compliance with the License.
kenjiArai 4:e9dfb4ca4277 7 * You may obtain a copy of the License at
kenjiArai 4:e9dfb4ca4277 8 *
kenjiArai 4:e9dfb4ca4277 9 * http://www.apache.org/licenses/LICENSE-2.0
kenjiArai 4:e9dfb4ca4277 10 *
kenjiArai 4:e9dfb4ca4277 11 * Unless required by applicable law or agreed to in writing, software
kenjiArai 4:e9dfb4ca4277 12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
kenjiArai 4:e9dfb4ca4277 13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kenjiArai 4:e9dfb4ca4277 14 * See the License for the specific language governing permissions and
kenjiArai 4:e9dfb4ca4277 15 * limitations under the License.
kenjiArai 4:e9dfb4ca4277 16 */
kenjiArai 4:e9dfb4ca4277 17 /**
kenjiArai 4:e9dfb4ca4277 18 * \file pn512_transceive.c
kenjiArai 4:e9dfb4ca4277 19 * \copyright Copyright (c) ARM Ltd 2014
kenjiArai 4:e9dfb4ca4277 20 * \author Donatien Garnier
kenjiArai 4:e9dfb4ca4277 21 */
kenjiArai 4:e9dfb4ca4277 22
kenjiArai 4:e9dfb4ca4277 23 #define __DEBUG__ 0
kenjiArai 4:e9dfb4ca4277 24 #ifndef __MODULE__
kenjiArai 4:e9dfb4ca4277 25 #define __MODULE__ "pn512_transceive.c"
kenjiArai 4:e9dfb4ca4277 26 #endif
kenjiArai 4:e9dfb4ca4277 27
kenjiArai 4:e9dfb4ca4277 28 #include "stack/nfc_errors.h"
kenjiArai 4:e9dfb4ca4277 29
kenjiArai 4:e9dfb4ca4277 30 #include "pn512.h"
kenjiArai 4:e9dfb4ca4277 31 #include "pn512_transceive.h"
kenjiArai 4:e9dfb4ca4277 32 #include "pn512_rf.h"
kenjiArai 4:e9dfb4ca4277 33 #include "pn512_irq.h"
kenjiArai 4:e9dfb4ca4277 34 #include "pn512_cmd.h"
kenjiArai 4:e9dfb4ca4277 35 #include "pn512_registers.h"
kenjiArai 4:e9dfb4ca4277 36 #include "pn512_internal.h"
kenjiArai 4:e9dfb4ca4277 37
kenjiArai 4:e9dfb4ca4277 38
kenjiArai 4:e9dfb4ca4277 39 #define TIMEOUT 1000
kenjiArai 4:e9dfb4ca4277 40
kenjiArai 4:e9dfb4ca4277 41 void pn512_transceive_hw_tx_iteration(pn512_t *pPN512, bool start)
kenjiArai 4:e9dfb4ca4277 42 {
kenjiArai 4:e9dfb4ca4277 43 uint16_t irqs_en = pn512_irq_enabled(pPN512);
kenjiArai 4:e9dfb4ca4277 44
kenjiArai 4:e9dfb4ca4277 45 if (ac_buffer_reader_readable(&pPN512->writeBuf) > 0) {
kenjiArai 4:e9dfb4ca4277 46 //Fill FIFO
kenjiArai 4:e9dfb4ca4277 47 pn512_fifo_write(pPN512, &pPN512->writeBuf);
kenjiArai 4:e9dfb4ca4277 48
kenjiArai 4:e9dfb4ca4277 49 if (ac_buffer_reader_readable(&pPN512->writeBuf) > 0) { //Did not fit in FIFO
kenjiArai 4:e9dfb4ca4277 50 pn512_irq_clear(pPN512, PN512_IRQ_LOW_ALERT);
kenjiArai 4:e9dfb4ca4277 51 //Has low FIFO alert IRQ already been enabled?
kenjiArai 4:e9dfb4ca4277 52 if (!(irqs_en & PN512_IRQ_LOW_ALERT)) {
kenjiArai 4:e9dfb4ca4277 53 irqs_en |= PN512_IRQ_LOW_ALERT;
kenjiArai 4:e9dfb4ca4277 54 pn512_irq_set(pPN512, irqs_en);
kenjiArai 4:e9dfb4ca4277 55 }
kenjiArai 4:e9dfb4ca4277 56 } else {
kenjiArai 4:e9dfb4ca4277 57 if (irqs_en & PN512_IRQ_LOW_ALERT) {
kenjiArai 4:e9dfb4ca4277 58 //Buffer has been fully sent
kenjiArai 4:e9dfb4ca4277 59 irqs_en &= ~PN512_IRQ_LOW_ALERT;
kenjiArai 4:e9dfb4ca4277 60 pn512_irq_set(pPN512, irqs_en);
kenjiArai 4:e9dfb4ca4277 61 }
kenjiArai 4:e9dfb4ca4277 62 }
kenjiArai 4:e9dfb4ca4277 63 }
kenjiArai 4:e9dfb4ca4277 64
kenjiArai 4:e9dfb4ca4277 65
kenjiArai 4:e9dfb4ca4277 66 if (start) {
kenjiArai 4:e9dfb4ca4277 67 if ((pPN512->transceive.mode == pn512_transceive_mode_transmit) || (pPN512->transceive.mode == pn512_transceive_mode_transmit_and_target_autocoll)) {
kenjiArai 4:e9dfb4ca4277 68 //Update bitframing register
kenjiArai 4:e9dfb4ca4277 69 pn512_register_write(pPN512, PN512_REG_BITFRAMING,
kenjiArai 4:e9dfb4ca4277 70 0x00 | ((pPN512->readFirstByteAlign & 0x7) << 4) | (pPN512->writeLastByteLength & 0x7));
kenjiArai 4:e9dfb4ca4277 71
kenjiArai 4:e9dfb4ca4277 72 //Use transmit command
kenjiArai 4:e9dfb4ca4277 73 pn512_cmd_exec(pPN512, PN512_CMD_TRANSMIT);
kenjiArai 4:e9dfb4ca4277 74 } else {
kenjiArai 4:e9dfb4ca4277 75 NFC_DBG("Bitframing %02X", 0x80 | ((pPN512->readFirstByteAlign & 0x7) << 4) | (pPN512->writeLastByteLength & 0x7));
kenjiArai 4:e9dfb4ca4277 76 //Update bitframing register to start transmission
kenjiArai 4:e9dfb4ca4277 77 pn512_register_write(pPN512, PN512_REG_BITFRAMING,
kenjiArai 4:e9dfb4ca4277 78 0x80 | ((pPN512->readFirstByteAlign & 0x7) << 4) | (pPN512->writeLastByteLength & 0x7));
kenjiArai 4:e9dfb4ca4277 79 }
kenjiArai 4:e9dfb4ca4277 80
kenjiArai 4:e9dfb4ca4277 81 //Reset last byte length, first byte align
kenjiArai 4:e9dfb4ca4277 82 pPN512->writeLastByteLength = 8;
kenjiArai 4:e9dfb4ca4277 83 pPN512->readFirstByteAlign = 0;
kenjiArai 4:e9dfb4ca4277 84 }
kenjiArai 4:e9dfb4ca4277 85
kenjiArai 4:e9dfb4ca4277 86 //Queue task to process IRQ
kenjiArai 4:e9dfb4ca4277 87 task_init(&pPN512->transceiver.task, EVENT_HW_INTERRUPT | EVENT_TIMEOUT, TIMEOUT, pn512_transceive_hw_tx_task, pPN512);
kenjiArai 4:e9dfb4ca4277 88 nfc_scheduler_queue_task(&pPN512->transceiver.scheduler, &pPN512->transceiver.task);
kenjiArai 4:e9dfb4ca4277 89 }
kenjiArai 4:e9dfb4ca4277 90
kenjiArai 4:e9dfb4ca4277 91 void pn512_transceive_hw_tx_task(uint32_t events, void *pUserData)
kenjiArai 4:e9dfb4ca4277 92 {
kenjiArai 4:e9dfb4ca4277 93 pn512_t *pPN512 = (pn512_t *) pUserData;
kenjiArai 4:e9dfb4ca4277 94
kenjiArai 4:e9dfb4ca4277 95 if (events & EVENT_ABORTED) {
kenjiArai 4:e9dfb4ca4277 96 //Stop command
kenjiArai 4:e9dfb4ca4277 97 pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
kenjiArai 4:e9dfb4ca4277 98 pPN512->transceive.mode = pn512_transceive_mode_idle;
kenjiArai 4:e9dfb4ca4277 99
kenjiArai 4:e9dfb4ca4277 100 NFC_ERR("Aborted TX");
kenjiArai 4:e9dfb4ca4277 101
kenjiArai 4:e9dfb4ca4277 102 pn512_irq_set(pPN512, PN512_IRQ_NONE);
kenjiArai 4:e9dfb4ca4277 103 pn512_irq_clear(pPN512, PN512_IRQ_ALL);
kenjiArai 4:e9dfb4ca4277 104
kenjiArai 4:e9dfb4ca4277 105 pn512_transceive_callback(pPN512, NFC_ERR_ABORTED);
kenjiArai 4:e9dfb4ca4277 106 return;
kenjiArai 4:e9dfb4ca4277 107 }
kenjiArai 4:e9dfb4ca4277 108
kenjiArai 4:e9dfb4ca4277 109 NFC_DBG("TX task");
kenjiArai 4:e9dfb4ca4277 110 if (events & EVENT_TIMEOUT) {
kenjiArai 4:e9dfb4ca4277 111 // Check status
kenjiArai 4:e9dfb4ca4277 112 NFC_DBG("Status = %02X %02X", pn512_register_read(pPN512, PN512_REG_STATUS1), pn512_register_read(pPN512, PN512_REG_STATUS2));
kenjiArai 4:e9dfb4ca4277 113
kenjiArai 4:e9dfb4ca4277 114 //Stop command
kenjiArai 4:e9dfb4ca4277 115 pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
kenjiArai 4:e9dfb4ca4277 116 pPN512->transceive.mode = pn512_transceive_mode_idle;
kenjiArai 4:e9dfb4ca4277 117
kenjiArai 4:e9dfb4ca4277 118 NFC_ERR("Timeout on TX");
kenjiArai 4:e9dfb4ca4277 119
kenjiArai 4:e9dfb4ca4277 120 pn512_irq_set(pPN512, PN512_IRQ_NONE);
kenjiArai 4:e9dfb4ca4277 121 pn512_irq_clear(pPN512, PN512_IRQ_ALL);
kenjiArai 4:e9dfb4ca4277 122
kenjiArai 4:e9dfb4ca4277 123 //Call callback
kenjiArai 4:e9dfb4ca4277 124 pn512_transceive_callback(pPN512, NFC_ERR_TIMEOUT);
kenjiArai 4:e9dfb4ca4277 125 return;
kenjiArai 4:e9dfb4ca4277 126 }
kenjiArai 4:e9dfb4ca4277 127
kenjiArai 4:e9dfb4ca4277 128 uint16_t irqs_en = pn512_irq_enabled(pPN512);
kenjiArai 4:e9dfb4ca4277 129 uint16_t irqs = pn512_irq_get(pPN512);
kenjiArai 4:e9dfb4ca4277 130
kenjiArai 4:e9dfb4ca4277 131 if (irqs & PN512_IRQ_RF_OFF) {
kenjiArai 4:e9dfb4ca4277 132 //Stop command
kenjiArai 4:e9dfb4ca4277 133 pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
kenjiArai 4:e9dfb4ca4277 134 pPN512->transceive.mode = pn512_transceive_mode_idle;
kenjiArai 4:e9dfb4ca4277 135
kenjiArai 4:e9dfb4ca4277 136 pn512_irq_set(pPN512, PN512_IRQ_NONE);
kenjiArai 4:e9dfb4ca4277 137 pn512_irq_clear(pPN512, PN512_IRQ_ALL);
kenjiArai 4:e9dfb4ca4277 138 NFC_WARN("RF Off");
kenjiArai 4:e9dfb4ca4277 139 pn512_transceive_callback(pPN512, NFC_ERR_FIELD);
kenjiArai 4:e9dfb4ca4277 140 return;
kenjiArai 4:e9dfb4ca4277 141 }
kenjiArai 4:e9dfb4ca4277 142 if (irqs & PN512_IRQ_TX) {
kenjiArai 4:e9dfb4ca4277 143 if (irqs_en & PN512_IRQ_LOW_ALERT) {
kenjiArai 4:e9dfb4ca4277 144 //If the transmission has been completed without us getting a chance to fill the buffer up it means that we had a buffer underflow
kenjiArai 4:e9dfb4ca4277 145 NFC_ERR("Buffer underflow");
kenjiArai 4:e9dfb4ca4277 146 pn512_irq_set(pPN512, PN512_IRQ_NONE);
kenjiArai 4:e9dfb4ca4277 147 pn512_irq_clear(pPN512, PN512_IRQ_ALL);
kenjiArai 4:e9dfb4ca4277 148
kenjiArai 4:e9dfb4ca4277 149 pn512_transceive_callback(pPN512, NFC_ERR_UNDERFLOW);
kenjiArai 4:e9dfb4ca4277 150 return;
kenjiArai 4:e9dfb4ca4277 151 }
kenjiArai 4:e9dfb4ca4277 152
kenjiArai 4:e9dfb4ca4277 153 //Transmission complete
kenjiArai 4:e9dfb4ca4277 154 pn512_irq_set(pPN512, PN512_IRQ_NONE);
kenjiArai 4:e9dfb4ca4277 155 pn512_irq_clear(pPN512, PN512_IRQ_TX | PN512_IRQ_LOW_ALERT);
kenjiArai 4:e9dfb4ca4277 156
kenjiArai 4:e9dfb4ca4277 157 //Start receiving
kenjiArai 4:e9dfb4ca4277 158 NFC_DBG("Transmission complete");
kenjiArai 4:e9dfb4ca4277 159 if (pPN512->transceive.mode != pn512_transceive_mode_transmit) {
kenjiArai 4:e9dfb4ca4277 160 if (pPN512->transceive.mode == pn512_transceive_mode_transmit_and_target_autocoll) {
kenjiArai 4:e9dfb4ca4277 161 //Make sure bitframing reg is clean
kenjiArai 4:e9dfb4ca4277 162 pn512_register_write(pPN512, PN512_REG_BITFRAMING, 0x00);
kenjiArai 4:e9dfb4ca4277 163
kenjiArai 4:e9dfb4ca4277 164 pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
kenjiArai 4:e9dfb4ca4277 165 pn512_transceive_hw_rx_start(pPN512);
kenjiArai 4:e9dfb4ca4277 166
kenjiArai 4:e9dfb4ca4277 167 //Start autocoll
kenjiArai 4:e9dfb4ca4277 168 pn512_cmd_exec(pPN512, PN512_CMD_AUTOCOLL);
kenjiArai 4:e9dfb4ca4277 169 } else {
kenjiArai 4:e9dfb4ca4277 170 pn512_transceive_hw_rx_start(pPN512);
kenjiArai 4:e9dfb4ca4277 171 }
kenjiArai 4:e9dfb4ca4277 172 return;
kenjiArai 4:e9dfb4ca4277 173 } else {
kenjiArai 4:e9dfb4ca4277 174 pn512_irq_set(pPN512, PN512_IRQ_NONE);
kenjiArai 4:e9dfb4ca4277 175 pn512_irq_clear(pPN512, PN512_IRQ_RX | PN512_IRQ_HIGH_ALERT);
kenjiArai 4:e9dfb4ca4277 176
kenjiArai 4:e9dfb4ca4277 177 pn512_transceive_callback(pPN512, NFC_OK);
kenjiArai 4:e9dfb4ca4277 178 return;
kenjiArai 4:e9dfb4ca4277 179 }
kenjiArai 4:e9dfb4ca4277 180 }
kenjiArai 4:e9dfb4ca4277 181 if ((irqs & PN512_IRQ_LOW_ALERT) && (ac_buffer_reader_readable(&pPN512->writeBuf) > 0)) {
kenjiArai 4:e9dfb4ca4277 182 //Continue to fill FIFO
kenjiArai 4:e9dfb4ca4277 183 pn512_irq_clear(pPN512, PN512_IRQ_LOW_ALERT);
kenjiArai 4:e9dfb4ca4277 184
kenjiArai 4:e9dfb4ca4277 185 pn512_transceive_hw_tx_iteration(pPN512, false);
kenjiArai 4:e9dfb4ca4277 186 return;
kenjiArai 4:e9dfb4ca4277 187 }
kenjiArai 4:e9dfb4ca4277 188
kenjiArai 4:e9dfb4ca4277 189 if (irqs & PN512_IRQ_IDLE) {
kenjiArai 4:e9dfb4ca4277 190 pn512_irq_clear(pPN512, PN512_IRQ_ERR);
kenjiArai 4:e9dfb4ca4277 191
kenjiArai 4:e9dfb4ca4277 192 NFC_ERR("Modem went to idle");
kenjiArai 4:e9dfb4ca4277 193
kenjiArai 4:e9dfb4ca4277 194 pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
kenjiArai 4:e9dfb4ca4277 195 pPN512->transceive.mode = pn512_transceive_mode_idle;
kenjiArai 4:e9dfb4ca4277 196
kenjiArai 4:e9dfb4ca4277 197 pn512_irq_set(pPN512, PN512_IRQ_NONE);
kenjiArai 4:e9dfb4ca4277 198 pn512_irq_clear(pPN512, PN512_IRQ_ALL);
kenjiArai 4:e9dfb4ca4277 199 pn512_transceive_callback(pPN512, NFC_ERR_WRONG_COMM);
kenjiArai 4:e9dfb4ca4277 200 return;
kenjiArai 4:e9dfb4ca4277 201 }
kenjiArai 4:e9dfb4ca4277 202
kenjiArai 4:e9dfb4ca4277 203 //Call back function
kenjiArai 4:e9dfb4ca4277 204 pn512_transceive_hw_tx_iteration(pPN512, false);
kenjiArai 4:e9dfb4ca4277 205 }
kenjiArai 4:e9dfb4ca4277 206
kenjiArai 4:e9dfb4ca4277 207 void pn512_transceive_hw_rx_start(pn512_t *pPN512)
kenjiArai 4:e9dfb4ca4277 208 {
kenjiArai 4:e9dfb4ca4277 209 uint16_t irqs_en = PN512_IRQ_RX | PN512_IRQ_HIGH_ALERT | PN512_IRQ_ERR;
kenjiArai 4:e9dfb4ca4277 210 if (PN512_FRAMING_IS_TARGET(pPN512->framing)) {
kenjiArai 4:e9dfb4ca4277 211 irqs_en |= PN512_IRQ_RF_OFF;
kenjiArai 4:e9dfb4ca4277 212 }
kenjiArai 4:e9dfb4ca4277 213
kenjiArai 4:e9dfb4ca4277 214 pn512_irq_set(pPN512, irqs_en);
kenjiArai 4:e9dfb4ca4277 215
kenjiArai 4:e9dfb4ca4277 216 //Reset buffer except if data should be appended to this -- TODO
kenjiArai 4:e9dfb4ca4277 217 ac_buffer_builder_reset(&pPN512->readBufBldr);
kenjiArai 4:e9dfb4ca4277 218
kenjiArai 4:e9dfb4ca4277 219 //Queue task to process IRQ
kenjiArai 4:e9dfb4ca4277 220 task_init(&pPN512->transceiver.task, EVENT_HW_INTERRUPT | EVENT_TIMEOUT,
kenjiArai 4:e9dfb4ca4277 221 pPN512->timeout, pn512_transceive_hw_rx_task, pPN512);
kenjiArai 4:e9dfb4ca4277 222 nfc_scheduler_queue_task(&pPN512->transceiver.scheduler,
kenjiArai 4:e9dfb4ca4277 223 &pPN512->transceiver.task);
kenjiArai 4:e9dfb4ca4277 224 }
kenjiArai 4:e9dfb4ca4277 225
kenjiArai 4:e9dfb4ca4277 226 void pn512_transceive_hw_rx_task(uint32_t events, void *pUserData)
kenjiArai 4:e9dfb4ca4277 227 {
kenjiArai 4:e9dfb4ca4277 228 pn512_t *pPN512 = (pn512_t *) pUserData;
kenjiArai 4:e9dfb4ca4277 229
kenjiArai 4:e9dfb4ca4277 230 NFC_DBG("RX task");
kenjiArai 4:e9dfb4ca4277 231 if (events & EVENT_ABORTED) {
kenjiArai 4:e9dfb4ca4277 232 //Stop command
kenjiArai 4:e9dfb4ca4277 233 pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
kenjiArai 4:e9dfb4ca4277 234 pPN512->transceive.mode = pn512_transceive_mode_idle;
kenjiArai 4:e9dfb4ca4277 235
kenjiArai 4:e9dfb4ca4277 236 NFC_ERR("Aborted RX");
kenjiArai 4:e9dfb4ca4277 237
kenjiArai 4:e9dfb4ca4277 238 pn512_irq_set(pPN512, PN512_IRQ_NONE);
kenjiArai 4:e9dfb4ca4277 239 pn512_irq_clear(pPN512, PN512_IRQ_ALL);
kenjiArai 4:e9dfb4ca4277 240
kenjiArai 4:e9dfb4ca4277 241 pn512_transceive_callback(pPN512, NFC_ERR_ABORTED);
kenjiArai 4:e9dfb4ca4277 242 return;
kenjiArai 4:e9dfb4ca4277 243 }
kenjiArai 4:e9dfb4ca4277 244
kenjiArai 4:e9dfb4ca4277 245 if (events & EVENT_TIMEOUT) {
kenjiArai 4:e9dfb4ca4277 246 NFC_WARN("Timeout");
kenjiArai 4:e9dfb4ca4277 247 //Stop command
kenjiArai 4:e9dfb4ca4277 248 pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
kenjiArai 4:e9dfb4ca4277 249 pPN512->transceive.mode = pn512_transceive_mode_idle;
kenjiArai 4:e9dfb4ca4277 250
kenjiArai 4:e9dfb4ca4277 251 pn512_irq_set(pPN512, PN512_IRQ_NONE);
kenjiArai 4:e9dfb4ca4277 252 pn512_irq_clear(pPN512, PN512_IRQ_ALL);
kenjiArai 4:e9dfb4ca4277 253
kenjiArai 4:e9dfb4ca4277 254 //Call callback
kenjiArai 4:e9dfb4ca4277 255 pn512_transceive_callback(pPN512, NFC_ERR_TIMEOUT);
kenjiArai 4:e9dfb4ca4277 256 return;
kenjiArai 4:e9dfb4ca4277 257 }
kenjiArai 4:e9dfb4ca4277 258
kenjiArai 4:e9dfb4ca4277 259 uint16_t irqs = pn512_irq_get(pPN512);
kenjiArai 4:e9dfb4ca4277 260 NFC_DBG("irqs %04x", irqs);
kenjiArai 4:e9dfb4ca4277 261 bool collision_detected = false;
kenjiArai 4:e9dfb4ca4277 262 if (irqs & PN512_IRQ_ERR) {
kenjiArai 4:e9dfb4ca4277 263 pn512_irq_clear(pPN512, PN512_IRQ_ERR);
kenjiArai 4:e9dfb4ca4277 264
kenjiArai 4:e9dfb4ca4277 265 uint8_t err_reg = pn512_register_read(pPN512, PN512_REG_ERROR);
kenjiArai 4:e9dfb4ca4277 266 NFC_ERR("Got error - error reg is %02X", err_reg);
kenjiArai 4:e9dfb4ca4277 267 // if err_reg == 0, sticky error that must have been cleared automatically, continue
kenjiArai 4:e9dfb4ca4277 268 if (err_reg != 0) {
kenjiArai 4:e9dfb4ca4277 269 //If it's a collsision, flag it but still carry on with RX procedure
kenjiArai 4:e9dfb4ca4277 270 collision_detected = true;
kenjiArai 4:e9dfb4ca4277 271
kenjiArai 4:e9dfb4ca4277 272 if ((err_reg == 0x08) || (err_reg == 0x0A)) { // Collision (and maybe parity) (and no other error)
kenjiArai 4:e9dfb4ca4277 273 irqs &= ~PN512_IRQ_ERR;
kenjiArai 4:e9dfb4ca4277 274 irqs |= PN512_IRQ_RX;
kenjiArai 4:e9dfb4ca4277 275 } else {
kenjiArai 4:e9dfb4ca4277 276 NFC_DBG_BLOCK(
kenjiArai 4:e9dfb4ca4277 277 //Empty FIFO into buffer
kenjiArai 4:e9dfb4ca4277 278 pn512_fifo_read(pPN512, &pPN512->readBufBldr);
kenjiArai 4:e9dfb4ca4277 279
kenjiArai 4:e9dfb4ca4277 280 NFC_DBG("Received");
kenjiArai 4:e9dfb4ca4277 281 ac_buffer_dump(ac_buffer_builder_buffer(&pPN512->readBufBldr));
kenjiArai 4:e9dfb4ca4277 282
kenjiArai 4:e9dfb4ca4277 283 NFC_DBG("Computed CRC = %02X %02X", pn512_register_read(pPN512, PN512_REG_CRCRESULT_MSB), pn512_register_read(pPN512, PN512_REG_CRCRESULT_LSB));
kenjiArai 4:e9dfb4ca4277 284
kenjiArai 4:e9dfb4ca4277 285 )
kenjiArai 4:e9dfb4ca4277 286
kenjiArai 4:e9dfb4ca4277 287 //Stop command
kenjiArai 4:e9dfb4ca4277 288 pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
kenjiArai 4:e9dfb4ca4277 289 pPN512->transceive.mode = pn512_transceive_mode_idle;
kenjiArai 4:e9dfb4ca4277 290
kenjiArai 4:e9dfb4ca4277 291 pn512_irq_set(pPN512, PN512_IRQ_NONE);
kenjiArai 4:e9dfb4ca4277 292 pn512_irq_clear(pPN512, PN512_IRQ_ALL);
kenjiArai 4:e9dfb4ca4277 293
kenjiArai 4:e9dfb4ca4277 294 //Call callback
kenjiArai 4:e9dfb4ca4277 295 pn512_transceive_callback(pPN512, NFC_ERR_WRONG_COMM);
kenjiArai 4:e9dfb4ca4277 296 return;
kenjiArai 4:e9dfb4ca4277 297 }
kenjiArai 4:e9dfb4ca4277 298 }
kenjiArai 4:e9dfb4ca4277 299 }
kenjiArai 4:e9dfb4ca4277 300 if ((irqs & PN512_IRQ_RX) || (irqs & PN512_IRQ_HIGH_ALERT)) {
kenjiArai 4:e9dfb4ca4277 301 //Empty FIFO into buffer
kenjiArai 4:e9dfb4ca4277 302 pn512_fifo_read(pPN512, &pPN512->readBufBldr);
kenjiArai 4:e9dfb4ca4277 303
kenjiArai 4:e9dfb4ca4277 304 if ((ac_buffer_builder_writable(&pPN512->readBufBldr) == 0) && (pn512_fifo_length(pPN512) > 0)) {
kenjiArai 4:e9dfb4ca4277 305 //Stop command
kenjiArai 4:e9dfb4ca4277 306 pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
kenjiArai 4:e9dfb4ca4277 307 pPN512->transceive.mode = pn512_transceive_mode_idle;
kenjiArai 4:e9dfb4ca4277 308
kenjiArai 4:e9dfb4ca4277 309 NFC_WARN("RX buffer overflow");
kenjiArai 4:e9dfb4ca4277 310
kenjiArai 4:e9dfb4ca4277 311 pn512_irq_set(pPN512, PN512_IRQ_NONE);
kenjiArai 4:e9dfb4ca4277 312 pn512_irq_clear(pPN512, PN512_IRQ_ALL);
kenjiArai 4:e9dfb4ca4277 313 //Call callback
kenjiArai 4:e9dfb4ca4277 314 pn512_transceive_callback(pPN512, NFC_ERR_BUFFER_TOO_SMALL);
kenjiArai 4:e9dfb4ca4277 315 return; //overflow
kenjiArai 4:e9dfb4ca4277 316 }
kenjiArai 4:e9dfb4ca4277 317
kenjiArai 4:e9dfb4ca4277 318 if (irqs & PN512_IRQ_HIGH_ALERT) {
kenjiArai 4:e9dfb4ca4277 319 NFC_DBG("High alert");
kenjiArai 4:e9dfb4ca4277 320 pn512_irq_clear(pPN512, PN512_IRQ_HIGH_ALERT);
kenjiArai 4:e9dfb4ca4277 321 }
kenjiArai 4:e9dfb4ca4277 322
kenjiArai 4:e9dfb4ca4277 323 if (irqs & PN512_IRQ_RX) {
kenjiArai 4:e9dfb4ca4277 324 pn512_irq_clear(pPN512, PN512_IRQ_RX);
kenjiArai 4:e9dfb4ca4277 325
kenjiArai 4:e9dfb4ca4277 326 size_t last_byte_length = pn512_register_read(pPN512, PN512_REG_CONTROL) & 0x7;
kenjiArai 4:e9dfb4ca4277 327 if (last_byte_length == 0) {
kenjiArai 4:e9dfb4ca4277 328 last_byte_length = 8;
kenjiArai 4:e9dfb4ca4277 329 }
kenjiArai 4:e9dfb4ca4277 330 pPN512->readLastByteLength = last_byte_length;
kenjiArai 4:e9dfb4ca4277 331
kenjiArai 4:e9dfb4ca4277 332 pn512_irq_set(pPN512, PN512_IRQ_NONE);
kenjiArai 4:e9dfb4ca4277 333 pn512_irq_clear(pPN512, PN512_IRQ_RX | PN512_IRQ_HIGH_ALERT);
kenjiArai 4:e9dfb4ca4277 334
kenjiArai 4:e9dfb4ca4277 335 NFC_DBG("Received:");
kenjiArai 4:e9dfb4ca4277 336 NFC_DBG_BLOCK(ac_buffer_dump(ac_buffer_builder_buffer(&pPN512->readBufBldr));)
kenjiArai 4:e9dfb4ca4277 337
kenjiArai 4:e9dfb4ca4277 338 if ((pPN512->transceive.mode == pn512_transceive_mode_target_autocoll) || (pPN512->transceive.mode == pn512_transceive_mode_transmit_and_target_autocoll)) {
kenjiArai 4:e9dfb4ca4277 339 //Check if target was activated
kenjiArai 4:e9dfb4ca4277 340 if (!(pn512_register_read(pPN512, PN512_REG_STATUS2) & 0x10)) {
kenjiArai 4:e9dfb4ca4277 341 pPN512->transceive.mode = pn512_transceive_mode_idle;
kenjiArai 4:e9dfb4ca4277 342
kenjiArai 4:e9dfb4ca4277 343 pn512_irq_set(pPN512, PN512_IRQ_NONE);
kenjiArai 4:e9dfb4ca4277 344 pn512_irq_clear(pPN512, PN512_IRQ_ALL);
kenjiArai 4:e9dfb4ca4277 345 //Call callback
kenjiArai 4:e9dfb4ca4277 346 pn512_transceive_callback(pPN512, NFC_ERR_PROTOCOL);
kenjiArai 4:e9dfb4ca4277 347 return;
kenjiArai 4:e9dfb4ca4277 348 }
kenjiArai 4:e9dfb4ca4277 349 //PN512 switches to transceive automatically
kenjiArai 4:e9dfb4ca4277 350 pPN512->transceive.mode = pn512_transceive_mode_transceive;
kenjiArai 4:e9dfb4ca4277 351 } else if (pPN512->transceive.mode == pn512_transceive_mode_receive) {
kenjiArai 4:e9dfb4ca4277 352 pPN512->transceive.mode = pn512_transceive_mode_transceive;
kenjiArai 4:e9dfb4ca4277 353 //pn512_cmd_exec(pPN512, PN512_CMD_IDLE); //Useful?
kenjiArai 4:e9dfb4ca4277 354 }
kenjiArai 4:e9dfb4ca4277 355
kenjiArai 4:e9dfb4ca4277 356 if (!collision_detected) {
kenjiArai 4:e9dfb4ca4277 357 pn512_transceive_callback(pPN512, NFC_OK);
kenjiArai 4:e9dfb4ca4277 358 } else {
kenjiArai 4:e9dfb4ca4277 359 pn512_transceive_callback(pPN512, NFC_ERR_COLLISION);
kenjiArai 4:e9dfb4ca4277 360 }
kenjiArai 4:e9dfb4ca4277 361
kenjiArai 4:e9dfb4ca4277 362 return;
kenjiArai 4:e9dfb4ca4277 363 }
kenjiArai 4:e9dfb4ca4277 364 }
kenjiArai 4:e9dfb4ca4277 365 if (irqs & PN512_IRQ_RF_OFF) {
kenjiArai 4:e9dfb4ca4277 366 //Stop command
kenjiArai 4:e9dfb4ca4277 367 pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
kenjiArai 4:e9dfb4ca4277 368 pPN512->transceive.mode = pn512_transceive_mode_idle;
kenjiArai 4:e9dfb4ca4277 369
kenjiArai 4:e9dfb4ca4277 370 pn512_irq_set(pPN512, PN512_IRQ_NONE);
kenjiArai 4:e9dfb4ca4277 371 pn512_irq_clear(pPN512, PN512_IRQ_ALL);
kenjiArai 4:e9dfb4ca4277 372
kenjiArai 4:e9dfb4ca4277 373 //Call callback
kenjiArai 4:e9dfb4ca4277 374 pn512_transceive_callback(pPN512, NFC_ERR_FIELD);
kenjiArai 4:e9dfb4ca4277 375 return;
kenjiArai 4:e9dfb4ca4277 376 }
kenjiArai 4:e9dfb4ca4277 377
kenjiArai 4:e9dfb4ca4277 378 //Queue task to process IRQ
kenjiArai 4:e9dfb4ca4277 379 task_init(&pPN512->transceiver.task, EVENT_HW_INTERRUPT | EVENT_TIMEOUT,
kenjiArai 4:e9dfb4ca4277 380 pPN512->timeout, pn512_transceive_hw_rx_task, pPN512);
kenjiArai 4:e9dfb4ca4277 381 nfc_scheduler_queue_task(&pPN512->transceiver.scheduler,
kenjiArai 4:e9dfb4ca4277 382 &pPN512->transceiver.task);
kenjiArai 4:e9dfb4ca4277 383 }
kenjiArai 4:e9dfb4ca4277 384
kenjiArai 4:e9dfb4ca4277 385 void pn512_transceive_hw(pn512_t *pPN512, pn512_transceive_mode_t mode, pn512_cb_t cb)
kenjiArai 4:e9dfb4ca4277 386 {
kenjiArai 4:e9dfb4ca4277 387 uint16_t irqs_en;
kenjiArai 4:e9dfb4ca4277 388
kenjiArai 4:e9dfb4ca4277 389 //Store callback
kenjiArai 4:e9dfb4ca4277 390 pPN512->transceive.cb = cb;
kenjiArai 4:e9dfb4ca4277 391
kenjiArai 4:e9dfb4ca4277 392 //Clear FIFO
kenjiArai 4:e9dfb4ca4277 393 pn512_fifo_clear(pPN512);
kenjiArai 4:e9dfb4ca4277 394
kenjiArai 4:e9dfb4ca4277 395 //Clear previous IRQs if present
kenjiArai 4:e9dfb4ca4277 396 pn512_irq_clear(pPN512, PN512_IRQ_RX | PN512_IRQ_TX | PN512_IRQ_HIGH_ALERT | PN512_IRQ_LOW_ALERT | PN512_IRQ_ERR | PN512_IRQ_IDLE | PN512_IRQ_RF_OFF);
kenjiArai 4:e9dfb4ca4277 397
kenjiArai 4:e9dfb4ca4277 398 if (PN512_FRAMING_IS_TARGET(pPN512->framing)) {
kenjiArai 4:e9dfb4ca4277 399 //RF off?
kenjiArai 4:e9dfb4ca4277 400 if (!(pn512_register_read(pPN512, PN512_REG_STATUS1) & 0x04)) {
kenjiArai 4:e9dfb4ca4277 401 //Call callback
kenjiArai 4:e9dfb4ca4277 402 pn512_transceive_callback(pPN512, NFC_ERR_FIELD);
kenjiArai 4:e9dfb4ca4277 403 return;
kenjiArai 4:e9dfb4ca4277 404 }
kenjiArai 4:e9dfb4ca4277 405 } else if ((pPN512->transceive.mode != mode) && (mode == pn512_transceive_mode_transceive)) {
kenjiArai 4:e9dfb4ca4277 406 pn512_cmd_exec(pPN512, PN512_CMD_TRANSCEIVE);
kenjiArai 4:e9dfb4ca4277 407 }
kenjiArai 4:e9dfb4ca4277 408
kenjiArai 4:e9dfb4ca4277 409 pPN512->transceive.mode = mode;
kenjiArai 4:e9dfb4ca4277 410
kenjiArai 4:e9dfb4ca4277 411 if (mode == pn512_transceive_mode_receive) {
kenjiArai 4:e9dfb4ca4277 412 pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
kenjiArai 4:e9dfb4ca4277 413 pn512_transceive_hw_rx_start(pPN512);
kenjiArai 4:e9dfb4ca4277 414 pn512_cmd_exec(pPN512, PN512_CMD_TRANSCEIVE);
kenjiArai 4:e9dfb4ca4277 415 } else if (mode == pn512_transceive_mode_target_autocoll) {
kenjiArai 4:e9dfb4ca4277 416 //Make sure bitframing reg is clean
kenjiArai 4:e9dfb4ca4277 417 pn512_register_write(pPN512, PN512_REG_BITFRAMING, 0x00);
kenjiArai 4:e9dfb4ca4277 418
kenjiArai 4:e9dfb4ca4277 419 pn512_transceive_hw_rx_start(pPN512);
kenjiArai 4:e9dfb4ca4277 420
kenjiArai 4:e9dfb4ca4277 421 //Start autocoll
kenjiArai 4:e9dfb4ca4277 422 pn512_cmd_exec(pPN512, PN512_CMD_AUTOCOLL);
kenjiArai 4:e9dfb4ca4277 423 return;
kenjiArai 4:e9dfb4ca4277 424 } else {
kenjiArai 4:e9dfb4ca4277 425 NFC_DBG("Sending:");
kenjiArai 4:e9dfb4ca4277 426 NFC_DBG_BLOCK(ac_buffer_dump(&pPN512->writeBuf);)
kenjiArai 4:e9dfb4ca4277 427
kenjiArai 4:e9dfb4ca4277 428 //Transmit a frame to remote target/initiator
kenjiArai 4:e9dfb4ca4277 429 irqs_en = PN512_IRQ_TX | PN512_IRQ_IDLE;
kenjiArai 4:e9dfb4ca4277 430 if (PN512_FRAMING_IS_TARGET(pPN512->framing)) {
kenjiArai 4:e9dfb4ca4277 431 irqs_en |= PN512_IRQ_RF_OFF;
kenjiArai 4:e9dfb4ca4277 432 }
kenjiArai 4:e9dfb4ca4277 433
kenjiArai 4:e9dfb4ca4277 434 pn512_irq_set(pPN512, irqs_en);
kenjiArai 4:e9dfb4ca4277 435
kenjiArai 4:e9dfb4ca4277 436 pn512_transceive_hw_tx_iteration(pPN512, true);
kenjiArai 4:e9dfb4ca4277 437 }
kenjiArai 4:e9dfb4ca4277 438 }
kenjiArai 4:e9dfb4ca4277 439
kenjiArai 4:e9dfb4ca4277 440
kenjiArai 4:e9dfb4ca4277 441