Library for the nRF2401A Transceiver
Dependents: nRF2401A_Hello_World nRF2401A_Wireless_Accelerometer_joypad nRF2401A_Gameduino_Invaders
nRF2401A.cpp@9:7245524e37e4, 2014-03-09 (annotated)
- Committer:
- TheChrisyd
- Date:
- Sun Mar 09 11:57:33 2014 +0000
- Revision:
- 9:7245524e37e4
- Parent:
- 7:22f69cf045d9
Update after feedback, parameters set to defaults, removed references ti this and added error checking to the functions instead, moved defines and updated documentation.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
TheChrisyd | 3:7ae3a5e53a1f | 1 | /** |
TheChrisyd | 3:7ae3a5e53a1f | 2 | *@section DESCRIPTION |
TheChrisyd | 3:7ae3a5e53a1f | 3 | * mbed nRF2401A Library |
TheChrisyd | 3:7ae3a5e53a1f | 4 | *@section LICENSE |
TheChrisyd | 0:17cb4be1e37f | 5 | * Copyright (c) 2011, Per Söderstam |
TheChrisyd | 0:17cb4be1e37f | 6 | * |
TheChrisyd | 0:17cb4be1e37f | 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
TheChrisyd | 0:17cb4be1e37f | 8 | * of this software and associated documentation files (the "Software"), to deal |
TheChrisyd | 0:17cb4be1e37f | 9 | * in the Software without restriction, including without limitation the rights |
TheChrisyd | 0:17cb4be1e37f | 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
TheChrisyd | 0:17cb4be1e37f | 11 | * copies of the Software, and to permit persons to whom the Software is |
TheChrisyd | 0:17cb4be1e37f | 12 | * furnished to do so, subject to the following conditions: |
TheChrisyd | 0:17cb4be1e37f | 13 | * |
TheChrisyd | 0:17cb4be1e37f | 14 | * The above copyright notice and this permission notice shall be included in |
TheChrisyd | 0:17cb4be1e37f | 15 | * all copies or substantial portions of the Software. |
TheChrisyd | 0:17cb4be1e37f | 16 | * |
TheChrisyd | 0:17cb4be1e37f | 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
TheChrisyd | 0:17cb4be1e37f | 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
TheChrisyd | 0:17cb4be1e37f | 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
TheChrisyd | 0:17cb4be1e37f | 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
TheChrisyd | 0:17cb4be1e37f | 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
TheChrisyd | 0:17cb4be1e37f | 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
TheChrisyd | 0:17cb4be1e37f | 23 | * THE SOFTWARE. |
TheChrisyd | 3:7ae3a5e53a1f | 24 | * @file "nRF2401A.cpp" |
TheChrisyd | 0:17cb4be1e37f | 25 | */ |
TheChrisyd | 0:17cb4be1e37f | 26 | |
TheChrisyd | 0:17cb4be1e37f | 27 | #include "nRF2401A.h" |
TheChrisyd | 0:17cb4be1e37f | 28 | |
TheChrisyd | 9:7245524e37e4 | 29 | #define Ts 1 /**< Setup time from data to rising clock edge on write (accualy 500 ns). */ |
TheChrisyd | 9:7245524e37e4 | 30 | #define Th 1 /**< Hold time from rising clock to data toggle/falling clock (accualy 500 ns). */ |
TheChrisyd | 9:7245524e37e4 | 31 | #define Tcs2data 5 /**< Min delay from CS assert to data, in us. */ |
TheChrisyd | 9:7245524e37e4 | 32 | #define Tce2data 5 /**< Min delay from CE assert to data, in us. */ |
TheChrisyd | 9:7245524e37e4 | 33 | #define Td 1 /**< Minimum delay between edges (actually 50 ns). */ |
TheChrisyd | 9:7245524e37e4 | 34 | #define Tpd2cfgm 3 /**< Minimum delay from power up of tranciever to configuration. */ |
TheChrisyd | 9:7245524e37e4 | 35 | #define Tsby2txSB 195 /**< Minimum delay from tx initation to air, in us. */ |
TheChrisyd | 9:7245524e37e4 | 36 | #define Tsby2rx 202 /**< Minimum delay from stanby to rx mode, in us. */ |
TheChrisyd | 9:7245524e37e4 | 37 | #define Thmin 5 /**< */ |
TheChrisyd | 9:7245524e37e4 | 38 | #define Tclk2data 1 /**< */ |
TheChrisyd | 9:7245524e37e4 | 39 | #define MAXIMUM_ADDR_LENGTH 40 /**< */ |
TheChrisyd | 9:7245524e37e4 | 40 | |
TheChrisyd | 0:17cb4be1e37f | 41 | |
TheChrisyd | 0:17cb4be1e37f | 42 | nRF2401A::nRF2401A(PinName ce, |
TheChrisyd | 0:17cb4be1e37f | 43 | PinName cs, |
TheChrisyd | 0:17cb4be1e37f | 44 | PinName dr1, |
TheChrisyd | 0:17cb4be1e37f | 45 | PinName clk1, |
TheChrisyd | 0:17cb4be1e37f | 46 | PinName data) |
TheChrisyd | 9:7245524e37e4 | 47 | : |
TheChrisyd | 9:7245524e37e4 | 48 | _ce(DigitalOut(ce)), |
TheChrisyd | 0:17cb4be1e37f | 49 | _cs(DigitalOut(cs)), |
TheChrisyd | 0:17cb4be1e37f | 50 | _dr1(DigitalIn(dr1)), |
TheChrisyd | 0:17cb4be1e37f | 51 | _clk1(DigitalOut(clk1)), |
TheChrisyd | 0:17cb4be1e37f | 52 | _data(DigitalInOut(data)), |
TheChrisyd | 7:22f69cf045d9 | 53 | _state(nRF2401A::STANDBY), |
TheChrisyd | 0:17cb4be1e37f | 54 | _rx_handler((nRF2401A_rx_handler_t) 0), |
TheChrisyd | 0:17cb4be1e37f | 55 | _rx_handler_arg((void *) 0), |
TheChrisyd | 5:18ce8a56b248 | 56 | _dr1_isr(InterruptIn(dr1)) { |
TheChrisyd | 9:7245524e37e4 | 57 | |
TheChrisyd | 0:17cb4be1e37f | 58 | // init member variables |
TheChrisyd | 0:17cb4be1e37f | 59 | _data.output(); |
TheChrisyd | 9:7245524e37e4 | 60 | // set defaults |
TheChrisyd | 9:7245524e37e4 | 61 | _ctrl_packet_buf.crc_config = NO_CRC; |
TheChrisyd | 9:7245524e37e4 | 62 | _ctrl_packet_buf.rf_data_rate = BIT_RATE_250KBITS; |
TheChrisyd | 9:7245524e37e4 | 63 | _ctrl_packet_buf.rf_channel = 0x02; |
TheChrisyd | 9:7245524e37e4 | 64 | _ctrl_packet_buf.channel_1_data_payload_len = 0x20; |
TheChrisyd | 0:17cb4be1e37f | 65 | // setup... |
TheChrisyd | 0:17cb4be1e37f | 66 | _ctrl_packet = (uint8_t *) &_ctrl_packet_buf; |
TheChrisyd | 0:17cb4be1e37f | 67 | _dr1_isr.rise(this, &nRF2401A::dataReadyHandler); |
TheChrisyd | 1:8c57f88ff574 | 68 | // ...tranceiver in standby... |
TheChrisyd | 0:17cb4be1e37f | 69 | _ce = 0; |
TheChrisyd | 0:17cb4be1e37f | 70 | _cs = 0; |
TheChrisyd | 0:17cb4be1e37f | 71 | // ...and clear receive buffer |
TheChrisyd | 0:17cb4be1e37f | 72 | for (int i = 0; i < 16; i++) |
TheChrisyd | 0:17cb4be1e37f | 73 | _data_buf[i] = 0x0; |
TheChrisyd | 0:17cb4be1e37f | 74 | // ...set imutable control fields... |
TheChrisyd | 0:17cb4be1e37f | 75 | _ctrl_packet_buf.enable_dual_channel_mode = 0x0; // single channel receive |
TheChrisyd | 0:17cb4be1e37f | 76 | _ctrl_packet_buf.communication_mode = 0x1; // ShockBurst mode |
TheChrisyd | 0:17cb4be1e37f | 77 | _ctrl_packet_buf.xo_frequency = 0x3; // 16 MHz crystal |
TheChrisyd | 0:17cb4be1e37f | 78 | _ctrl_packet_buf.rf_power = 0x3; // 0 dBm (1 mW) output power |
TheChrisyd | 0:17cb4be1e37f | 79 | // ...start in RX mode |
TheChrisyd | 0:17cb4be1e37f | 80 | _ctrl_packet_buf.txr_switch = nRF2401A::RX_MODE; |
TheChrisyd | 7:22f69cf045d9 | 81 | _state = nRF2401A::RX ; |
TheChrisyd | 1:8c57f88ff574 | 82 | // assure minimum wake up time while assuming tranceiver powers up with uP |
TheChrisyd | 0:17cb4be1e37f | 83 | wait_ms(Tpd2cfgm); |
TheChrisyd | 0:17cb4be1e37f | 84 | |
TheChrisyd | 0:17cb4be1e37f | 85 | return; |
TheChrisyd | 0:17cb4be1e37f | 86 | } |
TheChrisyd | 0:17cb4be1e37f | 87 | |
TheChrisyd | 9:7245524e37e4 | 88 | /* Public functions */ |
TheChrisyd | 7:22f69cf045d9 | 89 | |
TheChrisyd | 9:7245524e37e4 | 90 | /* Print control packet |
TheChrisyd | 9:7245524e37e4 | 91 | * Print the control packet to a serial port |
TheChrisyd | 9:7245524e37e4 | 92 | * @param arg Pointer to the port to transmit on |
TheChrisyd | 9:7245524e37e4 | 93 | * @return bool for correct parameters supplied |
TheChrisyd | 9:7245524e37e4 | 94 | */ |
TheChrisyd | 9:7245524e37e4 | 95 | bool nRF2401A::printControlPacket(Serial& port) |
TheChrisyd | 0:17cb4be1e37f | 96 | { |
TheChrisyd | 9:7245524e37e4 | 97 | bool ok = false; |
TheChrisyd | 9:7245524e37e4 | 98 | if (port != NULL) |
TheChrisyd | 9:7245524e37e4 | 99 | { |
TheChrisyd | 9:7245524e37e4 | 100 | for(int i = 0; i < sizeof(_ctrl_packet_buf); i++) |
TheChrisyd | 9:7245524e37e4 | 101 | { |
TheChrisyd | 9:7245524e37e4 | 102 | port.printf("%02x ", _ctrl_packet[i]); |
TheChrisyd | 9:7245524e37e4 | 103 | } |
TheChrisyd | 9:7245524e37e4 | 104 | port.printf("\n\r"); |
TheChrisyd | 9:7245524e37e4 | 105 | ok = true; |
TheChrisyd | 9:7245524e37e4 | 106 | } |
TheChrisyd | 9:7245524e37e4 | 107 | return ok; |
TheChrisyd | 0:17cb4be1e37f | 108 | } |
TheChrisyd | 0:17cb4be1e37f | 109 | |
TheChrisyd | 9:7245524e37e4 | 110 | /* Print data packet |
TheChrisyd | 9:7245524e37e4 | 111 | * Print the data packet to a serial port |
TheChrisyd | 9:7245524e37e4 | 112 | * @param arg Pointer to the port to transmit on |
TheChrisyd | 9:7245524e37e4 | 113 | * @return bool for correct parameters supplied |
TheChrisyd | 9:7245524e37e4 | 114 | */ |
TheChrisyd | 9:7245524e37e4 | 115 | bool nRF2401A::printDataPacket(Serial& port) |
TheChrisyd | 0:17cb4be1e37f | 116 | { |
TheChrisyd | 9:7245524e37e4 | 117 | bool ok = false; |
TheChrisyd | 9:7245524e37e4 | 118 | if (port != NULL) |
TheChrisyd | 9:7245524e37e4 | 119 | { |
TheChrisyd | 9:7245524e37e4 | 120 | for(int i = 0; i < sizeof(_data_buf); i++) |
TheChrisyd | 9:7245524e37e4 | 121 | { |
TheChrisyd | 9:7245524e37e4 | 122 | port.printf("%02x ", _data_buf[i]); |
TheChrisyd | 9:7245524e37e4 | 123 | } |
TheChrisyd | 9:7245524e37e4 | 124 | port.printf("\r"); |
TheChrisyd | 9:7245524e37e4 | 125 | ok = true; |
TheChrisyd | 9:7245524e37e4 | 126 | } |
TheChrisyd | 9:7245524e37e4 | 127 | return ok; |
TheChrisyd | 0:17cb4be1e37f | 128 | } |
TheChrisyd | 0:17cb4be1e37f | 129 | |
TheChrisyd | 9:7245524e37e4 | 130 | /* Send the control packet to the nRF2401A. |
TheChrisyd | 9:7245524e37e4 | 131 | * This function transfer the control packet image to the nRF2401A. |
TheChrisyd | 9:7245524e37e4 | 132 | * @return bool for successfull flushing of the packet |
TheChrisyd | 9:7245524e37e4 | 133 | */ |
TheChrisyd | 9:7245524e37e4 | 134 | bool nRF2401A::flushControlPacket() { |
TheChrisyd | 9:7245524e37e4 | 135 | bool flush = false; |
TheChrisyd | 7:22f69cf045d9 | 136 | switch (_state) { |
TheChrisyd | 7:22f69cf045d9 | 137 | case nRF2401A::RX: |
TheChrisyd | 7:22f69cf045d9 | 138 | pushCtrl(_ctrl_packet, 15 << 3 ); |
TheChrisyd | 7:22f69cf045d9 | 139 | _state = nRF2401A::RX; |
TheChrisyd | 7:22f69cf045d9 | 140 | _ce = 1; |
TheChrisyd | 7:22f69cf045d9 | 141 | _cs = 0; |
TheChrisyd | 9:7245524e37e4 | 142 | flush = true; |
TheChrisyd | 7:22f69cf045d9 | 143 | break; |
TheChrisyd | 7:22f69cf045d9 | 144 | case nRF2401A::STANDBY: |
TheChrisyd | 7:22f69cf045d9 | 145 | pushCtrl(_ctrl_packet, 15 << 3 ); |
TheChrisyd | 7:22f69cf045d9 | 146 | _state = nRF2401A::STANDBY; |
TheChrisyd | 7:22f69cf045d9 | 147 | _ce = 0; |
TheChrisyd | 7:22f69cf045d9 | 148 | _cs = 0; |
TheChrisyd | 9:7245524e37e4 | 149 | flush = true; |
TheChrisyd | 7:22f69cf045d9 | 150 | break; |
TheChrisyd | 7:22f69cf045d9 | 151 | case nRF2401A::TX: |
TheChrisyd | 7:22f69cf045d9 | 152 | default: |
TheChrisyd | 7:22f69cf045d9 | 153 | _ce = 0; |
TheChrisyd | 7:22f69cf045d9 | 154 | _cs = 0; |
TheChrisyd | 7:22f69cf045d9 | 155 | } |
TheChrisyd | 9:7245524e37e4 | 156 | return flush; |
TheChrisyd | 7:22f69cf045d9 | 157 | } |
TheChrisyd | 7:22f69cf045d9 | 158 | |
TheChrisyd | 9:7245524e37e4 | 159 | /* Register a receive action callback. |
TheChrisyd | 9:7245524e37e4 | 160 | * Attach a callback that will be called when the tranceiver intercept a |
TheChrisyd | 9:7245524e37e4 | 161 | * message. This callback will be called in the context of an interrupt |
TheChrisyd | 9:7245524e37e4 | 162 | * routine and should act accordingly. |
TheChrisyd | 9:7245524e37e4 | 163 | * @param handler The callback, of type nRF2401_rx_handler_t. |
TheChrisyd | 9:7245524e37e4 | 164 | * @param arg Pointer to data supplied to the handler at call time. |
TheChrisyd | 9:7245524e37e4 | 165 | * @return Reference to the invoked object (for chaining operations). |
TheChrisyd | 9:7245524e37e4 | 166 | */ |
TheChrisyd | 9:7245524e37e4 | 167 | bool nRF2401A::attachRXHandler(nRF2401A_rx_handler_t handler, void *arg) |
TheChrisyd | 4:e8523ef6e472 | 168 | { |
TheChrisyd | 9:7245524e37e4 | 169 | bool ok = false; |
TheChrisyd | 9:7245524e37e4 | 170 | if (handler != NULL) |
TheChrisyd | 9:7245524e37e4 | 171 | { |
TheChrisyd | 9:7245524e37e4 | 172 | _rx_handler = handler; |
TheChrisyd | 9:7245524e37e4 | 173 | _rx_handler_arg = arg; |
TheChrisyd | 9:7245524e37e4 | 174 | ok = true; |
TheChrisyd | 9:7245524e37e4 | 175 | } |
TheChrisyd | 9:7245524e37e4 | 176 | return ok; |
TheChrisyd | 0:17cb4be1e37f | 177 | } |
TheChrisyd | 0:17cb4be1e37f | 178 | |
TheChrisyd | 9:7245524e37e4 | 179 | /* Set the payload length, in bits. |
TheChrisyd | 9:7245524e37e4 | 180 | * Set the control packet field for length, in number of bits, of the message payload. |
TheChrisyd | 9:7245524e37e4 | 181 | * @param n Number of bits of the message payload. |
TheChrisyd | 9:7245524e37e4 | 182 | * @return void |
TheChrisyd | 9:7245524e37e4 | 183 | */ |
TheChrisyd | 9:7245524e37e4 | 184 | void nRF2401A::setDataPayloadLength(uint8_t n) |
TheChrisyd | 9:7245524e37e4 | 185 | { |
TheChrisyd | 9:7245524e37e4 | 186 | _ctrl_packet_buf.channel_1_data_payload_len = n; |
TheChrisyd | 9:7245524e37e4 | 187 | } |
TheChrisyd | 9:7245524e37e4 | 188 | |
TheChrisyd | 9:7245524e37e4 | 189 | /* Set the address of channel 1. |
TheChrisyd | 9:7245524e37e4 | 190 | * The channel address is a up to 40 bit number identifying the tranceiver. |
TheChrisyd | 9:7245524e37e4 | 191 | * @param addr4 Bits 39-32 of the address. |
TheChrisyd | 9:7245524e37e4 | 192 | * @param addr4 Bits 31-24 of the address. |
TheChrisyd | 9:7245524e37e4 | 193 | * @param addr4 Bits 23-16 of the address. |
TheChrisyd | 9:7245524e37e4 | 194 | * @param addr4 Bits 15-8 of the address. |
TheChrisyd | 9:7245524e37e4 | 195 | * @param addr4 Bits 7-0 of the address. |
TheChrisyd | 9:7245524e37e4 | 196 | * @param n_bits Number of bits used in the address. |
TheChrisyd | 9:7245524e37e4 | 197 | * @return bool for correct settings supplied |
TheChrisyd | 9:7245524e37e4 | 198 | */ |
TheChrisyd | 9:7245524e37e4 | 199 | bool nRF2401A::setAddress(uint8_t addr4, uint8_t addr3, uint8_t addr2, uint8_t addr1, uint8_t addr0, uint8_t n_bits) |
TheChrisyd | 9:7245524e37e4 | 200 | { |
TheChrisyd | 9:7245524e37e4 | 201 | bool ok = false; |
TheChrisyd | 9:7245524e37e4 | 202 | if (n_bits <= MAXIMUM_ADDR_LENGTH) |
TheChrisyd | 5:18ce8a56b248 | 203 | { |
TheChrisyd | 9:7245524e37e4 | 204 | _ctrl_packet_buf.channel_1_address[0] = addr4; |
TheChrisyd | 9:7245524e37e4 | 205 | _ctrl_packet_buf.channel_1_address[1] = addr3; |
TheChrisyd | 9:7245524e37e4 | 206 | _ctrl_packet_buf.channel_1_address[2] = addr2; |
TheChrisyd | 9:7245524e37e4 | 207 | _ctrl_packet_buf.channel_1_address[3] = addr1; |
TheChrisyd | 9:7245524e37e4 | 208 | _ctrl_packet_buf.channel_1_address[4] = addr0; |
TheChrisyd | 9:7245524e37e4 | 209 | _ctrl_packet_buf.channel_address_len = n_bits; |
TheChrisyd | 9:7245524e37e4 | 210 | ok = true; |
TheChrisyd | 5:18ce8a56b248 | 211 | } |
TheChrisyd | 9:7245524e37e4 | 212 | return ok; |
TheChrisyd | 5:18ce8a56b248 | 213 | } |
TheChrisyd | 5:18ce8a56b248 | 214 | |
TheChrisyd | 9:7245524e37e4 | 215 | /* Set CRC use. |
TheChrisyd | 9:7245524e37e4 | 216 | * Set the CRC mode field of the control packet. Defaults to no CRC. |
TheChrisyd | 9:7245524e37e4 | 217 | * @param mode The CRC mode of choise. |
TheChrisyd | 9:7245524e37e4 | 218 | * @return bool for correct parameter supplied |
TheChrisyd | 9:7245524e37e4 | 219 | */ |
TheChrisyd | 9:7245524e37e4 | 220 | bool nRF2401A::setCRCMode(CRC_T mode) |
TheChrisyd | 9:7245524e37e4 | 221 | { |
TheChrisyd | 9:7245524e37e4 | 222 | bool ok = false; |
TheChrisyd | 9:7245524e37e4 | 223 | if (mode < INVALID_CRC) |
TheChrisyd | 9:7245524e37e4 | 224 | { |
TheChrisyd | 9:7245524e37e4 | 225 | _ctrl_packet_buf.crc_config = mode; |
TheChrisyd | 9:7245524e37e4 | 226 | ok = true; |
TheChrisyd | 9:7245524e37e4 | 227 | } |
TheChrisyd | 9:7245524e37e4 | 228 | return ok; |
TheChrisyd | 5:18ce8a56b248 | 229 | } |
TheChrisyd | 5:18ce8a56b248 | 230 | |
TheChrisyd | 9:7245524e37e4 | 231 | /* Set RF power use. |
TheChrisyd | 9:7245524e37e4 | 232 | * Set the RF power field of the control packet. Defaults to full power. |
TheChrisyd | 9:7245524e37e4 | 233 | * @param power The RF power of choise. |
TheChrisyd | 9:7245524e37e4 | 234 | * @return bool for correct parameter supplied |
TheChrisyd | 9:7245524e37e4 | 235 | */ |
TheChrisyd | 9:7245524e37e4 | 236 | bool nRF2401A::setRFpower(RF_POWER_T power) |
TheChrisyd | 9:7245524e37e4 | 237 | { |
TheChrisyd | 9:7245524e37e4 | 238 | bool ok = false; |
TheChrisyd | 9:7245524e37e4 | 239 | if (power < INVALID_POWER) |
TheChrisyd | 9:7245524e37e4 | 240 | { |
TheChrisyd | 9:7245524e37e4 | 241 | _ctrl_packet_buf.rf_power = power; |
TheChrisyd | 9:7245524e37e4 | 242 | ok = true; |
TheChrisyd | 9:7245524e37e4 | 243 | } |
TheChrisyd | 9:7245524e37e4 | 244 | return ok; |
TheChrisyd | 9:7245524e37e4 | 245 | } |
TheChrisyd | 9:7245524e37e4 | 246 | |
TheChrisyd | 9:7245524e37e4 | 247 | /* Set tranceiver data rate. |
TheChrisyd | 9:7245524e37e4 | 248 | * Sets the data rate field to either 250 kbit/s or 1 Mbit/s data transfer rate. |
TheChrisyd | 9:7245524e37e4 | 249 | * Defaults to 250 kbit/s. |
TheChrisyd | 9:7245524e37e4 | 250 | * @param mode The data rate of choise. |
TheChrisyd | 9:7245524e37e4 | 251 | * @return bool for correct parameter supplied |
TheChrisyd | 9:7245524e37e4 | 252 | */ |
TheChrisyd | 9:7245524e37e4 | 253 | bool nRF2401A::setDataRate(DATA_RATE_T data_rate) |
TheChrisyd | 9:7245524e37e4 | 254 | { |
TheChrisyd | 9:7245524e37e4 | 255 | bool ok = false; |
TheChrisyd | 9:7245524e37e4 | 256 | if ( data_rate < INVALID_RATE) |
TheChrisyd | 9:7245524e37e4 | 257 | { |
TheChrisyd | 9:7245524e37e4 | 258 | _ctrl_packet_buf.rf_data_rate = data_rate; |
TheChrisyd | 9:7245524e37e4 | 259 | ok = true; |
TheChrisyd | 9:7245524e37e4 | 260 | } |
TheChrisyd | 9:7245524e37e4 | 261 | return ok; |
TheChrisyd | 9:7245524e37e4 | 262 | } |
TheChrisyd | 9:7245524e37e4 | 263 | |
TheChrisyd | 9:7245524e37e4 | 264 | /** Set RF channel. |
TheChrisyd | 9:7245524e37e4 | 265 | * Sets the control packet field for channel number. Channel numbers are from 0 to 127 |
TheChrisyd | 9:7245524e37e4 | 266 | * representing channel frequencies equal to (2400 + channel number) MHz. Defaults to channel 1. |
TheChrisyd | 9:7245524e37e4 | 267 | * @param ch Channel number, from the range [0, 127]. |
TheChrisyd | 9:7245524e37e4 | 268 | * @return boolean to confirm valid parameters have been supplied |
TheChrisyd | 9:7245524e37e4 | 269 | */ |
TheChrisyd | 9:7245524e37e4 | 270 | bool nRF2401A::setChannel(uint8_t ch) |
TheChrisyd | 9:7245524e37e4 | 271 | { |
TheChrisyd | 9:7245524e37e4 | 272 | bool result = false; |
TheChrisyd | 9:7245524e37e4 | 273 | if (ch < 128) |
TheChrisyd | 9:7245524e37e4 | 274 | { |
TheChrisyd | 9:7245524e37e4 | 275 | _ctrl_packet_buf.rf_channel = ch; |
TheChrisyd | 9:7245524e37e4 | 276 | result = true; |
TheChrisyd | 9:7245524e37e4 | 277 | } |
TheChrisyd | 9:7245524e37e4 | 278 | return result; |
TheChrisyd | 9:7245524e37e4 | 279 | } |
TheChrisyd | 0:17cb4be1e37f | 280 | |
TheChrisyd | 9:7245524e37e4 | 281 | /* Read a message. |
TheChrisyd | 9:7245524e37e4 | 282 | * This routine will transfer the data from the receive buffer to the buffer |
TheChrisyd | 9:7245524e37e4 | 283 | * supplied. It will transfer a number of Bytes equal to the specified length. |
TheChrisyd | 9:7245524e37e4 | 284 | * @param msg_buf Message buffer. |
TheChrisyd | 9:7245524e37e4 | 285 | * @param msg_len Length of message, in bytes. |
TheChrisyd | 9:7245524e37e4 | 286 | * @return boolean to confirm if valid parameters have been supplied |
TheChrisyd | 9:7245524e37e4 | 287 | */ |
TheChrisyd | 9:7245524e37e4 | 288 | bool nRF2401A::readMsg( uint8_t *msg_buf, uint8_t msg_len ) { |
TheChrisyd | 9:7245524e37e4 | 289 | bool result = false; |
TheChrisyd | 9:7245524e37e4 | 290 | if ((msg_buf != NULL) && (msg_len <= DATA_BUFFER_SIZE)) |
TheChrisyd | 9:7245524e37e4 | 291 | { |
TheChrisyd | 9:7245524e37e4 | 292 | for(int i = 0; i < msg_len; i++) |
TheChrisyd | 9:7245524e37e4 | 293 | { |
TheChrisyd | 9:7245524e37e4 | 294 | msg_buf[i] = _data_buf[i]; |
TheChrisyd | 9:7245524e37e4 | 295 | } |
TheChrisyd | 9:7245524e37e4 | 296 | result = true; |
TheChrisyd | 9:7245524e37e4 | 297 | } |
TheChrisyd | 9:7245524e37e4 | 298 | return result; |
TheChrisyd | 9:7245524e37e4 | 299 | } |
TheChrisyd | 9:7245524e37e4 | 300 | |
TheChrisyd | 9:7245524e37e4 | 301 | /* Read a byte from message. |
TheChrisyd | 9:7245524e37e4 | 302 | * This routine will transfer the data from the receive buffer to the buffer |
TheChrisyd | 9:7245524e37e4 | 303 | * supplied. It will transfer one Bytes at index buf_index. |
TheChrisyd | 9:7245524e37e4 | 304 | * @param msg_buf Message body. |
TheChrisyd | 9:7245524e37e4 | 305 | * @param buf_index index of byte to be read. |
TheChrisyd | 9:7245524e37e4 | 306 | * @return one Byte of the message buffer |
TheChrisyd | 9:7245524e37e4 | 307 | */ |
TheChrisyd | 9:7245524e37e4 | 308 | uint8_t nRF2401A::readMsg_byte( uint8_t buf_index ) { |
TheChrisyd | 9:7245524e37e4 | 309 | return _data_buf[buf_index]; |
TheChrisyd | 9:7245524e37e4 | 310 | } |
TheChrisyd | 0:17cb4be1e37f | 311 | |
TheChrisyd | 9:7245524e37e4 | 312 | /** Send a message. |
TheChrisyd | 9:7245524e37e4 | 313 | * This routine will transfer the data from the supplied buffer and send |
TheChrisyd | 9:7245524e37e4 | 314 | * it to the specified address using the current control packet settings. |
TheChrisyd | 9:7245524e37e4 | 315 | * @param addr The address to send to. |
TheChrisyd | 9:7245524e37e4 | 316 | * @param addr_len Length of address, in bits. |
TheChrisyd | 9:7245524e37e4 | 317 | * @param msg_buf Message body. |
TheChrisyd | 9:7245524e37e4 | 318 | * @param msg_len Length of message, in bits. |
TheChrisyd | 9:7245524e37e4 | 319 | * @return Reference to the invoked object (for chaining operations). |
TheChrisyd | 9:7245524e37e4 | 320 | */ |
TheChrisyd | 9:7245524e37e4 | 321 | bool nRF2401A::sendMsg(nRF2401A::address_t addr, uint8_t addr_len, uint8_t *msg_buf, uint8_t msg_len) { |
TheChrisyd | 9:7245524e37e4 | 322 | bool sent = false; |
TheChrisyd | 9:7245524e37e4 | 323 | if ((msg_buf != NULL) && (addr_len <= MAXIMUM_ADDR_LENGTH)) |
TheChrisyd | 9:7245524e37e4 | 324 | { |
TheChrisyd | 9:7245524e37e4 | 325 | // point to start of address byte in address |
TheChrisyd | 9:7245524e37e4 | 326 | uint8_t *aligned_addr = &addr[sizeof(address_t) - (addr_len / 8)]; |
TheChrisyd | 9:7245524e37e4 | 327 | // wait for tx completion |
TheChrisyd | 9:7245524e37e4 | 328 | int Toa = (_ctrl_packet_buf.rf_data_rate == nRF2401A::BIT_RATE_1MBITS ? 1 : 4) * (addr_len + msg_len + 1 + 16); |
TheChrisyd | 9:7245524e37e4 | 329 | |
TheChrisyd | 9:7245524e37e4 | 330 | switch (_state) { |
TheChrisyd | 9:7245524e37e4 | 331 | case nRF2401A::STANDBY: |
TheChrisyd | 9:7245524e37e4 | 332 | //come out of standby into RX mode |
TheChrisyd | 9:7245524e37e4 | 333 | standby_mode(true); |
TheChrisyd | 9:7245524e37e4 | 334 | case nRF2401A::TX: |
TheChrisyd | 9:7245524e37e4 | 335 | //wait while in tx mode |
TheChrisyd | 9:7245524e37e4 | 336 | while (_state == nRF2401A::TX ) { |
TheChrisyd | 9:7245524e37e4 | 337 | } |
TheChrisyd | 9:7245524e37e4 | 338 | case nRF2401A::RX: |
TheChrisyd | 9:7245524e37e4 | 339 | // switch to transmit |
TheChrisyd | 9:7245524e37e4 | 340 | transmit_mode(); |
TheChrisyd | 9:7245524e37e4 | 341 | // push out the bits |
TheChrisyd | 9:7245524e37e4 | 342 | _data = nRF2401A::TX_MODE; |
TheChrisyd | 0:17cb4be1e37f | 343 | wait_us(Ts); |
TheChrisyd | 0:17cb4be1e37f | 344 | _clk1 = 1; |
TheChrisyd | 0:17cb4be1e37f | 345 | wait_us(Th); |
TheChrisyd | 0:17cb4be1e37f | 346 | _clk1 = 0; |
TheChrisyd | 9:7245524e37e4 | 347 | // wait Td |
TheChrisyd | 9:7245524e37e4 | 348 | wait_us(Td); |
TheChrisyd | 9:7245524e37e4 | 349 | // deassert CS/CE and done... |
TheChrisyd | 9:7245524e37e4 | 350 | _cs = 0; |
TheChrisyd | 9:7245524e37e4 | 351 | _ce = 0; |
TheChrisyd | 9:7245524e37e4 | 352 | |
TheChrisyd | 9:7245524e37e4 | 353 | // zero control and data lines |
TheChrisyd | 0:17cb4be1e37f | 354 | _clk1 = 0; |
TheChrisyd | 9:7245524e37e4 | 355 | _data = 0; |
TheChrisyd | 9:7245524e37e4 | 356 | // wait Td |
TheChrisyd | 9:7245524e37e4 | 357 | wait_us(Td); |
TheChrisyd | 9:7245524e37e4 | 358 | // assert CE and wait Tcs2data |
TheChrisyd | 9:7245524e37e4 | 359 | _ce = 1; |
TheChrisyd | 9:7245524e37e4 | 360 | wait_us(Tce2data); |
TheChrisyd | 9:7245524e37e4 | 361 | // push out the address bits |
TheChrisyd | 9:7245524e37e4 | 362 | for (int i = 0; i < addr_len; i++) { |
TheChrisyd | 9:7245524e37e4 | 363 | _data = ((0x80 >> (i % 8)) & aligned_addr[i / 8]) ? 0x1 : 0x0; |
TheChrisyd | 9:7245524e37e4 | 364 | wait_us(Ts); |
TheChrisyd | 9:7245524e37e4 | 365 | _clk1 = 1; |
TheChrisyd | 9:7245524e37e4 | 366 | wait_us(Th); |
TheChrisyd | 9:7245524e37e4 | 367 | _clk1 = 0; |
TheChrisyd | 9:7245524e37e4 | 368 | } |
TheChrisyd | 9:7245524e37e4 | 369 | // push out the message bits |
TheChrisyd | 9:7245524e37e4 | 370 | for (int i = 0; i < msg_len; i++) { |
TheChrisyd | 9:7245524e37e4 | 371 | _data = ((0x80 >> (i % 8)) & msg_buf[i / 8]) ? 0x1 : 0x0; |
TheChrisyd | 9:7245524e37e4 | 372 | wait_us(Ts); |
TheChrisyd | 9:7245524e37e4 | 373 | _clk1 = 1; |
TheChrisyd | 9:7245524e37e4 | 374 | wait_us(Th); |
TheChrisyd | 9:7245524e37e4 | 375 | _clk1 = 0; |
TheChrisyd | 9:7245524e37e4 | 376 | } |
TheChrisyd | 9:7245524e37e4 | 377 | // reset data |
TheChrisyd | 9:7245524e37e4 | 378 | _data = 0; |
TheChrisyd | 9:7245524e37e4 | 379 | // deassert CE will initiate transmission |
TheChrisyd | 9:7245524e37e4 | 380 | _ce = 0; |
TheChrisyd | 9:7245524e37e4 | 381 | wait_us(Tsby2txSB + Toa); |
TheChrisyd | 0:17cb4be1e37f | 382 | |
TheChrisyd | 9:7245524e37e4 | 383 | // switch back to receive |
TheChrisyd | 9:7245524e37e4 | 384 | receive_mode(); |
TheChrisyd | 9:7245524e37e4 | 385 | sent = true; |
TheChrisyd | 9:7245524e37e4 | 386 | break; |
TheChrisyd | 9:7245524e37e4 | 387 | } |
TheChrisyd | 7:22f69cf045d9 | 388 | } |
TheChrisyd | 9:7245524e37e4 | 389 | return sent; |
TheChrisyd | 7:22f69cf045d9 | 390 | } |
TheChrisyd | 7:22f69cf045d9 | 391 | |
TheChrisyd | 7:22f69cf045d9 | 392 | |
TheChrisyd | 9:7245524e37e4 | 393 | /* Put the tranceiver into, or bring out of standby. |
TheChrisyd | 9:7245524e37e4 | 394 | * Tx mode 10.5mA, RX mode 18mA, Standby 400nA. |
TheChrisyd | 9:7245524e37e4 | 395 | * @param active set standby state |
TheChrisyd | 9:7245524e37e4 | 396 | */ |
TheChrisyd | 9:7245524e37e4 | 397 | nRF2401A::STATE_T nRF2401A::standby_mode(bool active) { |
TheChrisyd | 7:22f69cf045d9 | 398 | switch (_state) { |
TheChrisyd | 7:22f69cf045d9 | 399 | case nRF2401A::TX: |
TheChrisyd | 7:22f69cf045d9 | 400 | //wait while in tx mode |
TheChrisyd | 7:22f69cf045d9 | 401 | while (_state == nRF2401A::TX ) { |
TheChrisyd | 7:22f69cf045d9 | 402 | } |
TheChrisyd | 7:22f69cf045d9 | 403 | case nRF2401A::RX: |
TheChrisyd | 7:22f69cf045d9 | 404 | if (!active) { |
TheChrisyd | 7:22f69cf045d9 | 405 | _state = nRF2401A::STANDBY; |
TheChrisyd | 7:22f69cf045d9 | 406 | _ce = 0; |
TheChrisyd | 7:22f69cf045d9 | 407 | _cs = 0; |
TheChrisyd | 9:7245524e37e4 | 408 | wait_us(Tsby2rx); |
TheChrisyd | 7:22f69cf045d9 | 409 | } |
TheChrisyd | 0:17cb4be1e37f | 410 | break; |
TheChrisyd | 0:17cb4be1e37f | 411 | case nRF2401A::STANDBY: |
TheChrisyd | 7:22f69cf045d9 | 412 | if (active) { |
TheChrisyd | 7:22f69cf045d9 | 413 | _state = nRF2401A::RX; |
TheChrisyd | 7:22f69cf045d9 | 414 | _ce = 1; |
TheChrisyd | 7:22f69cf045d9 | 415 | _cs = 0; |
TheChrisyd | 7:22f69cf045d9 | 416 | } |
TheChrisyd | 0:17cb4be1e37f | 417 | break; |
TheChrisyd | 0:17cb4be1e37f | 418 | } |
TheChrisyd | 9:7245524e37e4 | 419 | return _state; |
TheChrisyd | 7:22f69cf045d9 | 420 | } |
TheChrisyd | 0:17cb4be1e37f | 421 | |
TheChrisyd | 9:7245524e37e4 | 422 | /* Private functions */ |
TheChrisyd | 7:22f69cf045d9 | 423 | |
TheChrisyd | 9:7245524e37e4 | 424 | /* transmit_mode |
TheChrisyd | 9:7245524e37e4 | 425 | * |
TheChrisyd | 9:7245524e37e4 | 426 | * put the transceiver into transmit mode |
TheChrisyd | 9:7245524e37e4 | 427 | */ |
TheChrisyd | 7:22f69cf045d9 | 428 | void nRF2401A::transmit_mode( void ) { |
TheChrisyd | 7:22f69cf045d9 | 429 | _ce = 0; |
TheChrisyd | 7:22f69cf045d9 | 430 | _cs = 0; |
TheChrisyd | 7:22f69cf045d9 | 431 | wait_us(Td); |
TheChrisyd | 7:22f69cf045d9 | 432 | // assert CS/CE and wait Tcs2data |
TheChrisyd | 7:22f69cf045d9 | 433 | _ce = 0; |
TheChrisyd | 7:22f69cf045d9 | 434 | _cs = 1; |
TheChrisyd | 7:22f69cf045d9 | 435 | wait_us(Tcs2data); |
TheChrisyd | 7:22f69cf045d9 | 436 | _state = nRF2401A::TX; |
TheChrisyd | 7:22f69cf045d9 | 437 | } |
TheChrisyd | 7:22f69cf045d9 | 438 | |
TheChrisyd | 9:7245524e37e4 | 439 | /* receive_mode |
TheChrisyd | 9:7245524e37e4 | 440 | * |
TheChrisyd | 9:7245524e37e4 | 441 | * put the transceiver into receive mode |
TheChrisyd | 9:7245524e37e4 | 442 | */ |
TheChrisyd | 7:22f69cf045d9 | 443 | void nRF2401A::receive_mode( void ) { |
TheChrisyd | 7:22f69cf045d9 | 444 | wait_us(Td); |
TheChrisyd | 7:22f69cf045d9 | 445 | // assert CS/CE and wait Tcs2data |
TheChrisyd | 7:22f69cf045d9 | 446 | _cs = 1; |
TheChrisyd | 7:22f69cf045d9 | 447 | wait_us(Tcs2data); |
TheChrisyd | 7:22f69cf045d9 | 448 | // push out the bits |
TheChrisyd | 7:22f69cf045d9 | 449 | _data = nRF2401A::RX_MODE; |
TheChrisyd | 7:22f69cf045d9 | 450 | wait_us(Ts); |
TheChrisyd | 7:22f69cf045d9 | 451 | _clk1 = 1; |
TheChrisyd | 7:22f69cf045d9 | 452 | wait_us(Th); |
TheChrisyd | 7:22f69cf045d9 | 453 | _clk1 = 0; |
TheChrisyd | 7:22f69cf045d9 | 454 | // wait Td |
TheChrisyd | 7:22f69cf045d9 | 455 | wait_us(Td); |
TheChrisyd | 7:22f69cf045d9 | 456 | _data = 0; |
TheChrisyd | 7:22f69cf045d9 | 457 | // deassert CS/CE and done... |
TheChrisyd | 7:22f69cf045d9 | 458 | _cs = 0; |
TheChrisyd | 7:22f69cf045d9 | 459 | // wait Td to avoid simultaineous control high |
TheChrisyd | 7:22f69cf045d9 | 460 | wait_us(Td); |
TheChrisyd | 7:22f69cf045d9 | 461 | _ce = 1; |
TheChrisyd | 7:22f69cf045d9 | 462 | // done |
TheChrisyd | 7:22f69cf045d9 | 463 | _state = nRF2401A::RX; |
TheChrisyd | 7:22f69cf045d9 | 464 | } |
TheChrisyd | 7:22f69cf045d9 | 465 | |
TheChrisyd | 9:7245524e37e4 | 466 | /* dataReadyHandler |
TheChrisyd | 9:7245524e37e4 | 467 | * |
TheChrisyd | 9:7245524e37e4 | 468 | * handle the incoming data and call callback |
TheChrisyd | 9:7245524e37e4 | 469 | */ |
TheChrisyd | 7:22f69cf045d9 | 470 | void nRF2401A::dataReadyHandler(void) { |
TheChrisyd | 7:22f69cf045d9 | 471 | switch (_state) { |
TheChrisyd | 7:22f69cf045d9 | 472 | case nRF2401A::RX: |
TheChrisyd | 7:22f69cf045d9 | 473 | pull(_data_buf); |
TheChrisyd | 7:22f69cf045d9 | 474 | if (_rx_handler != (nRF2401A_rx_handler_t) 0) |
TheChrisyd | 7:22f69cf045d9 | 475 | _rx_handler(_rx_handler_arg); |
TheChrisyd | 7:22f69cf045d9 | 476 | break; |
TheChrisyd | 7:22f69cf045d9 | 477 | default: |
TheChrisyd | 7:22f69cf045d9 | 478 | // todo: error msg |
TheChrisyd | 7:22f69cf045d9 | 479 | break; |
TheChrisyd | 7:22f69cf045d9 | 480 | } |
TheChrisyd | 7:22f69cf045d9 | 481 | return; |
TheChrisyd | 7:22f69cf045d9 | 482 | } |
TheChrisyd | 7:22f69cf045d9 | 483 | |
TheChrisyd | 9:7245524e37e4 | 484 | /* pull |
TheChrisyd | 9:7245524e37e4 | 485 | * |
TheChrisyd | 9:7245524e37e4 | 486 | * Pull the data from the transceiver |
TheChrisyd | 9:7245524e37e4 | 487 | */ |
TheChrisyd | 7:22f69cf045d9 | 488 | int nRF2401A::pull(uint8_t *buf) { |
TheChrisyd | 7:22f69cf045d9 | 489 | int n = 0; |
TheChrisyd | 7:22f69cf045d9 | 490 | |
TheChrisyd | 7:22f69cf045d9 | 491 | // read from data pin |
TheChrisyd | 7:22f69cf045d9 | 492 | _data.input(); |
TheChrisyd | 7:22f69cf045d9 | 493 | // init signals, go to standby |
TheChrisyd | 7:22f69cf045d9 | 494 | _ce = 1; |
TheChrisyd | 7:22f69cf045d9 | 495 | _cs = 0; |
TheChrisyd | 7:22f69cf045d9 | 496 | _clk1 = 0; |
TheChrisyd | 7:22f69cf045d9 | 497 | // ensure time from DR |
TheChrisyd | 7:22f69cf045d9 | 498 | wait_us(Td); |
TheChrisyd | 7:22f69cf045d9 | 499 | |
TheChrisyd | 7:22f69cf045d9 | 500 | while (_dr1 == 1) { |
TheChrisyd | 7:22f69cf045d9 | 501 | _clk1 = 1; |
TheChrisyd | 7:22f69cf045d9 | 502 | wait_us(Thmin); |
TheChrisyd | 7:22f69cf045d9 | 503 | if(_data.read()) |
TheChrisyd | 7:22f69cf045d9 | 504 | buf[n / 8] |= (0x80 >> (n % 8)); |
TheChrisyd | 7:22f69cf045d9 | 505 | else |
TheChrisyd | 7:22f69cf045d9 | 506 | buf[n / 8] &= ~(0x80 >> (n % 8)); |
TheChrisyd | 7:22f69cf045d9 | 507 | n++; |
TheChrisyd | 7:22f69cf045d9 | 508 | _clk1 = 0; |
TheChrisyd | 7:22f69cf045d9 | 509 | wait_us(Thmin); |
TheChrisyd | 7:22f69cf045d9 | 510 | } |
TheChrisyd | 7:22f69cf045d9 | 511 | // return to active |
TheChrisyd | 7:22f69cf045d9 | 512 | _ce = 1; |
TheChrisyd | 7:22f69cf045d9 | 513 | // reset data pin direction |
TheChrisyd | 7:22f69cf045d9 | 514 | _data.output(); |
TheChrisyd | 7:22f69cf045d9 | 515 | |
TheChrisyd | 7:22f69cf045d9 | 516 | return n; |
TheChrisyd | 0:17cb4be1e37f | 517 | } |
TheChrisyd | 0:17cb4be1e37f | 518 | |
TheChrisyd | 9:7245524e37e4 | 519 | /* pushCtrl |
TheChrisyd | 9:7245524e37e4 | 520 | * |
TheChrisyd | 9:7245524e37e4 | 521 | * Push the data to the transceiver |
TheChrisyd | 9:7245524e37e4 | 522 | */ |
TheChrisyd | 0:17cb4be1e37f | 523 | void nRF2401A::pushCtrl(uint8_t *buf, uint8_t n_bits, bool is_ctrl) { |
TheChrisyd | 0:17cb4be1e37f | 524 | |
TheChrisyd | 0:17cb4be1e37f | 525 | DigitalOut &ctrl_pin = is_ctrl ? _cs : _ce; |
TheChrisyd | 0:17cb4be1e37f | 526 | |
TheChrisyd | 0:17cb4be1e37f | 527 | // set data to output |
TheChrisyd | 0:17cb4be1e37f | 528 | _data.output(); |
TheChrisyd | 0:17cb4be1e37f | 529 | // zero control and data lines |
TheChrisyd | 0:17cb4be1e37f | 530 | _cs = 0; |
TheChrisyd | 0:17cb4be1e37f | 531 | _ce = 0; |
TheChrisyd | 0:17cb4be1e37f | 532 | _clk1 = 0; |
TheChrisyd | 0:17cb4be1e37f | 533 | _data = 0; |
TheChrisyd | 0:17cb4be1e37f | 534 | // wait Td |
TheChrisyd | 0:17cb4be1e37f | 535 | wait_us(Td); |
TheChrisyd | 0:17cb4be1e37f | 536 | // assert CS/CE and wait Tcs2data |
TheChrisyd | 0:17cb4be1e37f | 537 | ctrl_pin = 1; |
TheChrisyd | 0:17cb4be1e37f | 538 | wait_us(Tcs2data); |
TheChrisyd | 0:17cb4be1e37f | 539 | // push out the bits |
TheChrisyd | 0:17cb4be1e37f | 540 | for (int i = 0; i < n_bits; i++) { |
TheChrisyd | 0:17cb4be1e37f | 541 | _data = ((0x80 >> (i % 8)) & buf[i / 8]) ? 0x1 : 0x0; |
TheChrisyd | 0:17cb4be1e37f | 542 | wait_us(Ts); |
TheChrisyd | 0:17cb4be1e37f | 543 | _clk1 = 1; |
TheChrisyd | 0:17cb4be1e37f | 544 | wait_us(Th); |
TheChrisyd | 0:17cb4be1e37f | 545 | _clk1 = 0; |
TheChrisyd | 0:17cb4be1e37f | 546 | } |
TheChrisyd | 0:17cb4be1e37f | 547 | _data = 0; |
TheChrisyd | 0:17cb4be1e37f | 548 | // wait Td |
TheChrisyd | 0:17cb4be1e37f | 549 | wait_us(Td); |
TheChrisyd | 0:17cb4be1e37f | 550 | // deassert CS/CE and done... |
TheChrisyd | 0:17cb4be1e37f | 551 | ctrl_pin = 0; |
TheChrisyd | 0:17cb4be1e37f | 552 | |
TheChrisyd | 0:17cb4be1e37f | 553 | return; |
TheChrisyd | 0:17cb4be1e37f | 554 | } |