Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00018 #include <stdint.h>
00019 #include <stdbool.h>
00020
00021 #include "nrf24le1.h"
00022 #include "nordic_common.h"
00023 #include "hal_w2.h"
00024 #include "hal_delay.h"
00025
00026 #define BROADCAST_ENABLE 7 // W2CON0 register bit 7
00027 #define CLOCK_STOP 6 // W2CON0 register bit 6
00028 #define X_STOP 5 // W2CON0 register bit 5
00029 #define X_START 4 // W2CON0 register bit 4
00030 #define CLOCK_FREQUENCY_1 3 // W2CON0 register bit 3
00031 #define CLOCK_FREQUENCY_0 2 // W2CON0 register bit 2
00032 #define MASTER_SELECT 1 // W2CON0 register bit 1
00033 #define WIRE_2_ENABLE 0 // W2CON0 register bit 0
00034
00035 void hal_w2_soft_reset();
00036
00037
00038
00039 void hal_w2_respond_to_gen_adr(bool resp_gen)
00040 {
00041 if(resp_gen)
00042 {
00043 W2CON0 = W2CON0 | (1 << BROADCAST_ENABLE);
00044 }
00045 else
00046 {
00047 W2CON0 = W2CON0 & ~(1 << BROADCAST_ENABLE);
00048 }
00049 }
00050
00051 void hal_w2_alter_clock(bool alt_clk)
00052 {
00053 if(alt_clk)
00054 {
00055 W2CON0 = W2CON0 | (1 << CLOCK_STOP);
00056 }
00057 else
00058 {
00059 W2CON0 = W2CON0 & ~(1 << CLOCK_STOP);
00060 }
00061 }
00062
00063 void hal_w2_irq_stop_cond_enable(bool stop_cond)
00064 {
00065 if(stop_cond)
00066 {
00067 W2CON0 = W2CON0 & ~(1 << X_STOP);
00068 }
00069 else
00070 {
00071 W2CON0 = W2CON0 | (1 << X_STOP);
00072 }
00073 }
00074
00075 void hal_w2_irq_adr_match_enable(bool addr_match)
00076 {
00077 if(addr_match)
00078 {
00079 W2CON0 = W2CON0 & ~(1 << X_START);
00080 }
00081 else
00082 {
00083 W2CON0 = W2CON0 | (1 << X_START);
00084 }
00085 }
00086
00087 void hal_w2_set_slave_address(uint8_t address)
00088 {
00089 W2SADR = (address & 0x7F);
00090 }
00091
00092
00093
00094 void hal_w2_set_clk_freq(hal_w2_clk_freq_t freq)
00095 {
00096 W2CON0 = (W2CON0 & 0xF3) | (((uint8_t)freq) << CLOCK_FREQUENCY_0);
00097 }
00098
00099 void hal_w2_set_op_mode(hal_w2_op_mode_t mode)
00100 {
00101 if(mode == HAL_W2_MASTER)
00102 {
00103 W2CON0 = W2CON0 | (1 << MASTER_SELECT);
00104 }
00105 else
00106 {
00107 W2CON0 = W2CON0 & ~(1 << MASTER_SELECT);
00108 }
00109 }
00110
00111 void hal_w2_enable(bool en)
00112 {
00113 if(en)
00114 {
00115 W2CON0 = W2CON0 | (1 << WIRE_2_ENABLE);
00116 }
00117 else
00118 {
00119 W2CON0 = W2CON0 & ~(1 << WIRE_2_ENABLE);
00120 }
00121 }
00122
00123 void hal_w2_all_irq_enable(bool irq)
00124 {
00125
00126
00127 if(irq)
00128 {
00129 W2CON1 = ~(BIT_5);
00130 }
00131 else
00132 {
00133 W2CON1 = BIT_5;
00134 }
00135 }
00136
00137 void hal_w2_configure_master(hal_w2_clk_freq_t mode)
00138 {
00139 hal_w2_enable(true);
00140 hal_w2_set_clk_freq(mode);
00141 hal_w2_set_op_mode(HAL_W2_MASTER);
00142
00143 INTEXP |= 0x04;
00144 W2CON1 = 0x00;
00145 hal_w2_all_irq_enable(true);
00146 SPIF = 0;
00147 }
00148
00149 uint8_t hal_w2_wait_data_ready(void)
00150 {
00151 uint32_t timeout_counter = 0x0FF;
00152 uint8_t w2_status;
00153 bool data_ready;
00154 bool nack_received;
00155
00156 do
00157 {
00158 w2_status = W2CON1;
00159 data_ready = (w2_status & W2CON1_FLAG_DATA_READY);
00160 nack_received = (w2_status & W2CON1_FLAG_NACK);
00161 delay_us(10);
00162 } while (!data_ready);
00163
00164
00165 return w2_status;
00166 }
00167
00168 bool hal_w2_init_transfer(uint8_t address, hal_w2_direction_t direction)
00169 {
00170 uint8_t w2_status;
00171
00172 HAL_W2_ISSUE_START_COND;
00173 HAL_W2_WRITE((address << 1) | (uint8_t)direction);
00174
00175 w2_status = hal_w2_wait_data_ready();
00176
00177 if (w2_status & W2CON1_FLAG_NACK)
00178 {
00179 return false;
00180 }
00181 else
00182 {
00183 return true;
00184 }
00185 }
00186
00187 bool hal_w2_write(uint8_t address, const uint8_t *data_ptr, uint8_t data_len)
00188 {
00189 bool ack_received;
00190 ack_received = hal_w2_init_transfer(address, HAL_W2_DIR_WRITE);
00191
00192 while (data_len-- > 0 && ack_received == true)
00193 {
00194 uint8_t w2_status;
00195 HAL_W2_WRITE(*data_ptr++);
00196 w2_status = hal_w2_wait_data_ready();
00197 if (w2_status & W2CON1_FLAG_NACK)
00198 {
00199 ack_received = false;
00200 }
00201 }
00202
00203 HAL_W2_ISSUE_STOP_COND;
00204
00205 return ack_received;
00206 }
00207
00208 bool hal_w2_read(uint8_t address, uint8_t *data_ptr, uint8_t data_len)
00209 {
00210 uint8_t w2_status;
00211 bool ack_received;
00212
00213 ack_received = hal_w2_init_transfer(address, HAL_W2_DIR_READ);
00214
00215 if (ack_received == false)
00216 {
00217
00218 hal_w2_soft_reset();
00219 }
00220
00221
00222 while (data_len-- && ack_received)
00223 {
00224 if (data_len == 0)
00225 {
00226 HAL_W2_ISSUE_STOP_COND;
00227 }
00228
00229 w2_status = hal_w2_wait_data_ready();
00230
00231 *data_ptr++ = HAL_W2_READ();
00232 ack_received = !(w2_status & W2CON1_FLAG_NACK);
00233 }
00234
00235 return ack_received;
00236 }
00237
00238 void hal_w2_soft_reset()
00239 {
00240 #ifndef W2_SOFT_RESET_NOT_AVAILABLE
00241 uint8_t pulsecount, w2_freq;
00242
00243
00244 w2_freq = W2CON0 & 0x0C;
00245
00246 HAL_W2_CLEAR_SDA_SCL;
00247 HAL_W2_OVERRIDE_SDA_SCL(1, 1);
00248
00249
00250
00251 W2CON0 = 0x03;
00252 W2CON0 = 0x07;
00253
00254
00255 W2CON0 = 0x06;
00256
00257
00258
00259
00260 HAL_W2_OVERRIDE_SDA_SCL(1, 0);
00261
00262
00263 delay_us(5);
00264
00265 HAL_W2_OVERRIDE_SDA_SCL(0, 0);
00266
00267
00268
00269 delay_us(5);
00270 for( pulsecount = 0; pulsecount < 8; pulsecount++ )
00271 {
00272
00273 HAL_W2_OVERRIDE_SDA_SCL(0, 1);
00274 delay_us(5);
00275
00276 HAL_W2_OVERRIDE_SDA_SCL(0, 0);
00277 delay_us(5);
00278 }
00279
00280
00281 delay_us(5);
00282
00283 HAL_W2_OVERRIDE_SDA_SCL(0, 1);
00284
00285
00286 delay_us(5);
00287
00288 HAL_W2_OVERRIDE_SDA_SCL(1, 1);
00289
00290
00291 W2CON0 = 0x07;
00292
00293
00294 W2CON0 = 0x03;
00295 W2CON0 = 0x03 | w2_freq;
00296 #endif
00297 }