/* nrf_conf_inicial configura los registros del nrf para que funcione como PRX. * En esta funcion se establece la velocidad, potencia y canal que se usaran en * el resto del programa */ void nrf_conf_inicial(void){ desactivar_nrf(); escribir_reg_8bits(0x00,0x0C); //PRIM_RX = 0 escribir_reg_8bits(0x05,120); // Canal 120 escribir_reg_8bits(0x06,0x07); // 1Mbps escribir_reg_8bits(0x02,0x03); // Habilitar recepcion en pipe0 y pipe1 [EN_RXADDR] escribir_reg_8bits(0x01,0x03); // Habilitar AutoAck en pipe0 y pipe1 [EN_AA] escribir_reg_8bits(0x03,0x03); // Direcciones de 5 bytes [SETUP_AW] escribir_reg_8bits(0x11,0x20); // pipe0 recibe payloads con 32 bytes escribir_reg_8bits(0x12,0x20); // pipe1 recibe payloads con 32 bytes escribir_reg_40bits(0x0A,0x65646f4e31); // pipe0 RX_ADDR escribir_reg_8bits(0x07,0x00); // Limpiar IRQs => REEMPLAZAR POR nrf_limpiar_flags(); escribir_reg_8bits(0x00,0x0f); // Seleccionar PRIM_RX EN_CRC PWR_UP CRCO [CONFIG] // Delay de 5 ms (6.1.7 Timing Information [Tpd2stby] pag. 24). __delay_cycles(80000); // a 16MHz flush_rx(); flush_tx(); activar_nrf(); // El nrf24l01+ queda como PRX activo. }
void Radio::startListening(void) { write_register(CONFIG, read_register(CONFIG) | _BV(PRIM_RX)); write_register(STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT)); if (read_register(FEATURE) & _BV(EN_ACK_PAY)) { flush_tx(); } }
/* nrf_cargar_y_transmitir(uint8_t * data32bytes) borra cualquier paquete * pendiente, carga los 32 bytes del buffer data32bytes y los transmite */ void nrf_cargar_y_transmitir(uint8_t * data32bytes){ desactivar_nrf(); flush_tx(); escribir_tx_payload(data32bytes); activar_nrf(); __delay_cycles(2000); desactivar_nrf(); }
bool Radio::txStandBy() { while (!(read_register(FIFO_STATUS) & _BV(TX_EMPTY))) { if (get_status() & _BV(MAX_RT)) { write_register(STATUS, _BV(MAX_RT)); // Non blocking, flush the data. flush_tx(); return 0; } } return 1; }
void Radio::stopListening(void) { if (read_register(FEATURE) & _BV(EN_ACK_PAY)) { _delay_us(155); flush_tx(); } write_register(CONFIG, (read_register(CONFIG)) & ~_BV(PRIM_RX)); // for 3 pins solution TX mode is only left with additional powerDown/powerUp cycle. powerDown(); powerUp(); }
bool Radio::setup(void) { HalfDuplexSPI::setup(); csnHigh(); // Must allow the radio time to settle else configuration bits will not necessarily stick. // This is actually only required following power up but some settling time also appears to // be required after resets too. For full coverage, we'll always assume the worst. // Enabling 16b CRC is by far the most obvious case if the wrong timing is used - or skipped. // Technically we require 4.5ms + 14us as a worst case. We'll just call it 5ms for good measure. // WARNING: Delay is based on P-variant whereby non-P *may* require different timing. _delay_ms(5); // Reset CONFIG and enable 16-bit CRC. write_register(CONFIG, 0 | _BV(EN_CRC) | _BV(CRCO)); // Set 1500uS (minimum for 32B payload in ESB@250KBPS) timeouts, to make testing a little easier // WARNING: If this is ever lowered, either 250KBS mode with AA is broken or maximum packet // sizes must never be used. See documentation for a more complete explanation. setRetries(5, 15); uint8_t setup = read_register(RF_SETUP); // Then set the data rate to the slowest (and most reliable) speed supported by all // hardware. setDataRate(DataRate::RATE_1MBPS); write_register(FEATURE, 0); write_register(DYNPD, 0); // Reset current status // Notice reset and flush is the last thing we do write_register(STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT)); setChannel(76); // Flush buffers flush_rx(); flush_tx(); //Power up by default when setup() is called. powerUp(); // Enable PTX, do not write CE high so radio will remain in standby I mode ( 130us max to transition to RX or TX // instead of 1500us from powerUp ) PTX should use only 22uA of power. write_register(CONFIG, (read_register(CONFIG)) & ~_BV(PRIM_RX)); // If setup is 0 or ff then there was no response from module. return setup != 0 && setup != 0xff; }
bool Radio::txStandBy(uint32_t timeout) { uint32_t elapsed = 0; while (!(read_register(FIFO_STATUS) & _BV(TX_EMPTY))) { if (get_status() & _BV(MAX_RT)) { write_register(STATUS, _BV(MAX_RT)); if (elapsed >= timeout) { flush_tx(); return 0; } } elapsed += 200; _delay_ms(200); } return 1; }
/* Configura el nrf24l01+ como transmisor primario (PTX) en la direccion "dir" con AutoAck*/ void nrf_como_PTX(uint64_t dir){ desactivar_nrf(); nrf_limpiar_flags(); escribir_reg_8bits(0x00,0x0C); // [CONFIG] como PTX y POWER-DOWN escribir_reg_40bits(0x0A,dir); // pipe0 RX_ADDR escribir_reg_40bits(0x10,dir); // TX_ADDR escribir_reg_8bits(0x04,0xFF); // 4ms y 15 ret. //__delay_cycles(10000); //CHECK THIS flush_rx(); flush_tx(); //__delay_cycles(10000); escribir_reg_8bits(0x00,0x0C | 0x02); // Power-Up // Delay de 5 ms (6.1.7 Timing Information [Tpd2stby] pag. 24). __delay_cycles(80000); // a 16MHz // Delay de 130 us (6.1.7 Timing Information [Tstby2a] pag. 24). __delay_cycles(3200); // a 16MHz }
/*================================================================================================== FUNCTION: Uart_deinit DESCRIPTION: ==================================================================================================*/ UartResult Uart_deinit(UartHandle h) { UART_CONTEXT* uart_ctxt; UartResult result = UART_SUCCESS; UART_LOG_0(INFO,"+Uart_deinit"); if (NULL == h) { UART_LOG_0(ERROR,"Calling Uart_deinit with a NULL handle."); return UART_ERROR; } uart_ctxt = (UART_CONTEXT*)h; if (FALSE == uart_ctxt->is_port_open) { UART_LOG_0(ERROR,"Calling Uart_deinit on a closed port."); return UART_ERROR; } flush_tx(uart_ctxt); uart_ctxt->is_port_open = FALSE; if(UART_SUCCESS != Uart_clock_close(uart_ctxt)) { UART_LOG_0(ERROR, "Uart_clock_close failed."); result = UART_ERROR; } if(UART_SUCCESS != Uart_tlmm_close(uart_ctxt)) { UART_LOG_0(ERROR, "Uart_tlmm_close failed."); result = UART_ERROR; } if(UART_SUCCESS != Uart_interrupt_close(uart_ctxt)) { UART_LOG_0(ERROR, "Uart_interrupt_close failed."); result = UART_ERROR; } UART_LOG_0(INFO,"-Uart_deinit"); return result; }
// Program entry point void main() { rfcon = 0x06; // enable RF clock rfctl = 0x10; // enable SPI ien0 = 0x80; // enable interrupts TICKDV = 0xFF; // set the tick divider // Initialise and connect the USB controller init_usb(); // Flush the radio FIFOs flush_rx(); flush_tx(); // Everything is triggered via interrupts, so now we wait while(1) { REGXH = 0xFF; REGXL = 0xFF; REGXC = 0x08; delay_us(1000); } }
bool NRF24L01p::transmit(void* buf, uint8_t length) { write_tx_payload(buf, length); // Pulse CE to start TX mode spi.set_ce_pin(1); // Pulse add least 10 us to start TX mode // Thce = 10us TimeUtil::delay_microseconds(11); // We are transmitting only one packet spi.set_ce_pin(0); TimeUtil::delay_microseconds(130); uint8_t status = get_status(); while (!(status & (1 << STATUS_TX_DS | 1 << STATUS_MAX_RT))) { status = get_status(); } reset_tx_interrupts(); if (status & 1 << STATUS_TX_DS) { // Other party needs 130 us to get to RX mode again. // Tstby2a = 130us TimeUtil::delay_microseconds(130); return 1; } flush_tx(); return 0; }
//***************************************************************************** // // This example demonstrates how to send a string of data to the UART. // //***************************************************************************** int main(void) { // // Set the clocking to run directly from the crystal. // SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ); // // Initialize the OLED display and write status. // // // Enable the peripherals used by this example. // SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); //PC5,PC7 EN,CSN SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); GPIOPinTypeGPIOOutput(GPIO_PORTC_BASE,1<<5|1<<7); //SPI配置 unsigned long ulDataTx[NUM_SSI_DATA]; unsigned long ulDataRx[NUM_SSI_DATA]; unsigned long ulindex; unsigned long ultemp=0; SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0); //SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); GPIOPinConfigure(GPIO_PA2_SSI0CLK); GPIOPinConfigure(GPIO_PA3_SSI0FSS); GPIOPinConfigure(GPIO_PA4_SSI0RX); GPIOPinConfigure(GPIO_PA5_SSI0TX); GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2); SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 4000000, 8); /* GPIODirModeSet(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_DIR_MODE_OUT); GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD_WPU); GPIODirModeSet(GPIO_PORTB_BASE, GPIO_PIN_0, GPIO_DIR_MODE_OUT); GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_0 , GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD_WPU); */ SSIEnable(SSI0_BASE); // // Enable processor interrupts. // IntMasterEnable(); // // Set GPIO A0 and A1 as UART pins. // GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); // // Configure the UART for 115,200, 8-N-1 operation. // UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE)); // // Enable the UART interrupt. // IntEnable(INT_UART0); UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT); // // Prompt for text to be entered. // UARTStdioInit(0); UARTSend((unsigned char *)"Enter text:\n\r", 12); UARTSend((unsigned char *)"Enter text:\n\r", 12); //清零接收缓冲区 while(SSIDataGetNonBlocking(SSI0_BASE, &ulDataRx[0])) { } ulDataTx[0] = 's'; ulDataTx[1] = 'p'; ulDataTx[2] = 'i'; set_nrf24l01_csn_l(); /* for(ulindex = 0; ulindex < NUM_SSI_DATA; ulindex++) { UARTprintf("'%c' ", ulDataTx[ulindex]); SSIDataPut(SSI0_BASE, ulDataTx[ulindex]); } */ set_nrf24l01_csn_h(); _delay_ms(1); if( setDataRate( RF24_250KBPS ) ) { p_variant = true ; } //初始化NRF24L01 set_module_tx(); nrf_write_reg(NRF_CONFIG,0x0a); print_byte_register("CONFIG\t",NRF_CONFIG,1); init_NRF24L01(); set_module_tx(); unsigned char transfer_value[]="EEWORLD_MSP430_00"; //set_module_tx(); //读不出来spi数据的原因是,原来里面有没读取完的数据,需要先清理,再读写. setChannel(74); UARTprintf("getchannel:%d\r\n",getChannel()); // setChannel(24); // UARTprintf("getchannel:%d\r\n",getChannel()); //写地址 nrf_write_buf(TX_ADDR,(uint8_t*)&addresses[0],5); uint8_t recvbuf[5]; nrf_read_buf(TX_ADDR,&recvbuf[0],5); for(int i=0;i<5;i++) { UARTprintf("%d:%d ",i,recvbuf[i]); } UARTprintf("\r\n"); //end of test write address uint8_t data[32]; for(int i=0;i<32;i++) { data[i]=i; } UARTprintf("\r\n"); //while(SSIDataGetNonBlocking(SSI0_BASE, &ulDataRx[0])) //{ //} //重新发送前,避免写缓冲区满 flush_tx(); spi_write_reg(STATUS, ( spi_read_reg(STATUS) ) | _BV(MAX_RT) ); //role=role_ping_out openWritingPipe(addresses[0]); openReadingPipe(1,addresses[1]); nrf_write_buf(RX_ADDR_P0,(uint8_t*)&addresses[0],5); unsigned char test; //while(1) { test=spi_read_reg(0x05); UARTprintf("test:%d\r\n",test); _delay_ms(1000); } //调试关闭 //nrf_write_reg(EN_AA,0x00); nrf_write_reg(EN_RXADDR,0x02); //nrf_write_reg(SETUP_RETR,0x00); nrf_write_reg(RX_PW_P1,0x20); //set_module_tx(); nrf_write_reg(NRF_CONFIG,0x0b); nrf_write_reg(CONFIG, nrf_read_reg(CONFIG) | _BV(PRIM_RX)); nrf_write_reg(STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) ); set_nrf24l01_ce_h(); nrf_write_buf(RX_ADDR_P0,(uint8_t*)&addresses[0],5); set_nrf24l01_ce_h(); if(nrf_read_reg(FEATURE) & _BV(EN_ACK_PAY)) { flush_tx(); } flush_rx(); print_status(get_status()); nrf_write_reg(SETUP_AW,0x03); print_byte_register("SETUP_AW\t",SETUP_AW,1); print_address_register("RX_ADDR_P0-1",RX_ADDR_P0,2); print_byte_register("RX_ADDR_P2-5",RX_ADDR_P2,4); print_address_register("TX_ADDR\t",TX_ADDR,1); print_byte_register("RX_PW_P0-6",RX_PW_P0,6); print_byte_register("EN_AA\t",EN_AA,1); print_byte_register("EN_RXADDR",EN_RXADDR,1); print_byte_register("RF_CH\t",RF_CH,1); print_byte_register("RF_SETUP",RF_SETUP,1); print_byte_register("CONFIG\t",NRF_CONFIG,1); print_byte_register("DYNPD/FEATURE",DYNPD,2); UARTprintf("Data Rate\t = %s\r\n", pgm_read_word(&rf24_datarate_e_str_P[getDataRate()])); UARTprintf("Model\t\t = %s\r\n", pgm_read_word(&rf24_model_e_str_P[isPVariant()])); UARTprintf("CRC Length\t = %s\r\n",pgm_read_word(&rf24_crclength_e_str_P[getCRCLength()])); UARTprintf("PA Power\t = %s\r\n", pgm_read_word(&rf24_pa_dbm_e_str_P[getPALevel()])); Init_Timer_A(); set_nrf24l01_ce_h(); //将业务数据写入:WR_TX_PLOAD uint8_t fifo_status,status,state,i; while(1) { fifo_status=spi_read_reg(FIFO_STATUS); if(fifo_status&0x02) { status=spi_read_reg(STATUS); if(status&_BV(RX_DR)) { state=spi_send_byte(RD_RX_PLOAD); for(i=0;i<RX_PLOAD_WIDTH;i++) { status=spi_send_byte(0xff); //buf[i]=status; } nrf_write_reg(FLUSH_RX,0xFF); //UARTprintf("."); counter++; } if(status &0x02) { nrf_write_reg(FLUSH_RX,0xFF); //UARTprintf("."); counter++; } nrf_rx_packet(data); } } while(available(0)) { //UARTprintf("."); if(nrf_rx_packet(data) == 0) { counter++; } //UARTprintf("."); //_delay_ms(50); /* set_nrf24l01_ce_l(); nrf_write_buf(WR_TX_PLOAD,data,TX_PLOAD_WIDTH); set_nrf24l01_ce_h(); _delay_ms(30); */ } }
int main(){ uint8_t txretry_count=0, txretry_latch=0; WDTCTL = (WDTPW + WDTHOLD); DCOCTL = CALDCO_16MHZ; BCSCTL1 = CALBC1_16MHZ; BCSCTL2 = DIVS_1; // SMCLK = 8MHz // Inicializacao do transceiver rf_crc = RF24_EN_CRC; rf_addr_width = 5; rf_speed_power = RF24_SPEED_MIN | RF24_POWER_MAX; rf_channel = 8; msprf24_init(); msprf24_open_pipe(0, 1); // This is only for receiving auto-ACK packets. msprf24_set_pipe_packetsize(0, 0); // Dynamic payload support // Note: Pipe#0 is hardcoded in the transceiver hardware as the designated "pipe" for a TX node to receive // auto-ACKs. This does not have to match the pipe# used on the RX side. Serial_config(); // Main loop while (1) { // Handle any nRF24 IRQs first if (rf_irq & RF24_IRQ_FLAGGED) { msprf24_get_irq_reason(); if (rf_irq & RF24_IRQ_TX) { msprf24_irq_clear(RF24_IRQ_TX); flush_tx(); w_rx_addr(0, (uint8_t*)masterAddr); msprf24_powerdown(); } if (rf_irq & RF24_IRQ_TXFAILED) { msprf24_irq_clear(RF24_IRQ_TXFAILED); if (txretry_count) { txretry_count--; if (!txretry_latch) { txretry_latch = 1; tx_reuse_lastpayload(); } pulse_ce(); } else { // Ran out of retries, give up flush_tx(); w_rx_addr(0, (uint8_t*)masterAddr); txretry_latch = 0; msprf24_powerdown(); } } // No need to handle RX packets since we never enter RX mode } if (handle_serial){ if(serial_data_rcv == START_CHAR){ pl_index == 0; } else if(serial_data_rcv == END_CHAR){ send_pkg = true; pl_index == 0; } else if(pl_index < PL_SIZE){ rfpayload[pl_index++] = serial_data_rcv; } else{ pl_index = 0; } handle_serial = false; } if (msprf24_queue_state() & RF24_QUEUE_TXEMPTY && send_pkg) { Serial_escreve_texto("\nEnviando pacote: "); Serial_escreve_texto(rfpayload); msprf24_standby(); w_tx_addr((uint8_t*)nodeAddr); w_rx_addr(0, (uint8_t*)nodeAddr); // To catch the auto-ACK reply w_tx_payload(2, (uint8_t*)rfpayload); msprf24_activate_tx(); txretry_count = 20; // Try damned hard to send this, retrying up to 20 * ARC times (ARC=15 by default) send_pkg = false; } } }
int main() { uint8_t rfbuf[32], i, do_lpm, pktlen, pipeid; WDTCTL = WDTPW | WDTHOLD; // I/O ports used for status LED //P3DIR |= BIT6; P1DIR |= BIT0; //P1OUT &= ~BIT7; P1OUT &= ~BIT0; //P3OUT |= BIT6; // Blue LED signifies clock startup /* MSP430 F5172 */ //ucs_clockinit(16000000, 0, 0); /* MSP430 G-series */ DCOCTL = CALDCO_16MHZ; BCSCTL1 = CALBC1_16MHZ; BCSCTL2 = DIVS_1; //P3OUT &= ~BIT6; // Configure Nordic nRF24L01+ rf_crc = RF24_EN_CRC | RF24_CRCO; // CRC enabled, 16-bit rf_addr_width = 5; rf_speed_power = RF_SPEED | RF24_POWER_MAX; // RF_SPEED from tcsender.h rf_channel = RF_CHANNEL; // This #define is located in tcsender.h msprf24_init(); msprf24_open_pipe(0, 0); msprf24_set_pipe_packetsize(0, 0); packet_init_tasklist(); dmx512_init(); // Submit one color change. memcpy(dmx512_buffer, rgb_cust, 3); dmx512_output_channels(0x00, 1, dmx512_buffer, 3); while(1) { do_lpm = 1; // Handle RF acknowledgements if (rf_irq & RF24_IRQ_FLAGGED || msprf24_rx_pending()) { msprf24_get_irq_reason(); // Handle TX acknowledgements if (rf_irq & RF24_IRQ_TX) { // Acknowledge msprf24_irq_clear(RF24_IRQ_TX); P1OUT &= ~BIT0; } if (rf_irq & RF24_IRQ_TXFAILED) { msprf24_irq_clear(RF24_IRQ_TXFAILED); flush_tx(); } if (rf_irq & RF24_IRQ_RX || msprf24_rx_pending()) { pktlen = r_rx_peek_payload_size(); if (pktlen > 0 && pktlen < 33) { pipeid = r_rx_payload(pktlen, (char*)rfbuf); if (pipeid == 1) { for (i=0; i < pktlen; i++) { if (rfbuf[i]) { /* Process this packet if it's valid (and payload length doesn't send us * past the end of the rfbuf buffer) */ if ( (i+rfbuf[i+1] + 1) < pktlen ) { packet_processor(rfbuf[i], rfbuf[i+1], &rfbuf[i+2]); i += rfbuf[i+1] + 1; } else { i = pktlen; /* Otherwise, we're done, we assume the * the rest of the payload is corrupt. */ } } /* rfbuf[i] != 0x00 (i.e. valid program ID) */ } /* for(0 .. pktlen) */ } /* pipeid == 1 */ } else { // False alarm; bad packet, nuke it. flush_rx(); } /* pktlen is 1..32 */ msprf24_irq_clear(RF24_IRQ_RX); } /* rf_irq & RF24_IRQ_RX */ do_lpm = 0; } /* rf_irq & RF24_IRQ_FLAGGED */ if (packet_task_next() != NULL) { packet_process_txqueue(); } if (do_lpm) LPM4; } /* while(1) */ return 0; // Should never reach here }