diff --git a/radio/nrf24L01/nrf-ftdi-ring.c b/radio/nrf24L01/nrf-ftdi-ring.c index b8d37f1880e1b5eceb25b487e3d233366be14972..62b5f7230ec16be7d9dbffdc60b043a8d6c29460 100644 --- a/radio/nrf24L01/nrf-ftdi-ring.c +++ b/radio/nrf24L01/nrf-ftdi-ring.c @@ -69,6 +69,7 @@ uint8_t read_register(uint8_t reg){ return temp; } void write_register(uint8_t reg, uint8_t val){ + //must be in standby mode before calling this function! PORTC.OUTCLR = SS_BM; //SS low _delay_us(1); SPIC.DATA = W_REGISTER | reg; while(!(SPIC.STATUS & SPI_IF_bm)) {}; @@ -77,18 +78,18 @@ void write_register(uint8_t reg, uint8_t val){ _delay_us(1); } - USART_data_t USART_data; uint8_t token = 0; //token to pass uint8_t tempval = 0; const int pll_delay_us = 130; +const int ce_delay_us = 10; void check_registers(uint8_t id){ - //debug only + //for debug only //enter standby so we can write to configuration register. PORTC.OUTCLR = CE_BM; - _delay_us(10); + _delay_us(ce_delay_us); PORTC.OUTCLR = SS_BM; //SS low _delay_us(10); @@ -104,63 +105,16 @@ void check_registers(uint8_t id){ usart_send_byte(&USART_data,config); usart_send_byte(&USART_data,token); usart_send_byte(&USART_data,10); - - //interrupts - /*if (!(PORTC.IN & IRQ_BM)){ - usart_send_byte(&USART_data,1); - } - //clear interrupt on MAX_RT - PORTC.OUTCLR = SS_BM; //SS low - _delay_ms(1); - SPIC.DATA = W_REGISTER | STATUS; while(!(SPIC.STATUS & SPI_IF_bm)) {}; - SPIC.DATA |= MAX_RT; while(!(SPIC.STATUS & SPI_IF_bm)) {}; //write 1 to MAX_RT bit - PORTC.OUTSET = SS_BM; //SS high - _delay_ms(1); - //interrupts - if (!(PORTC.IN & IRQ_BM)){ - usart_send_byte(&USART_data,2); - }*/ } -// nRF24L01+ must be in a standby or power down mode before writing to the configuration registers. - -//overview -// - turn off autoretransmit -// - MAX_RT interrupts on IRQ -// - set interrupt service routine on rising edge of IRQ (RX_DR) -// - set interrupt service routing on USART RX -// - enter RX mode PRIM_RX = 1 (SPI transaction), CE = 1 -// - When IRQ interupt, -// - enter standby (CE=0) -// - read payload (SPI transaction) -// - process data and put result in TX fifo -// - enter TX (PRIM_RX=0, CE=1 for more than 10 us) (130us) -// - clear IRQ by writing 1 to STATUS register RX_DR bit. (SPI transaction) -// - set CE=0 so we return to Standby when finished transmitting -// - set PRIM_RX=1 (SPI transaction). can we only do this from standby? (130us) -// - When USART interrupt, -// - enter standby (CE=0) -// - put token in TX fifo -// - enter TX (PRIM_RX=0, CE=1 for more than 10 us) -// - set CE=0 so we return to Standby when finished transmitting -// - set PRIM_RX=1 (SPI transaction) to enter RX can we only do this from standby? (130us) - -//experiments -// RF_SETUP, RF_DR_LOW, RF_DR_HIGH. Default RF data rate is 250kbps ( 4 us per byte ). -// It can also be 1 Mbps (1 us per byte) and 2 Mbps (.5 us per byte) -// increase SPI rate. right now its running at clkper/128 = sysclk/128 = 250 kHz (4 us per byte) - - void rx_from_standby(){ - //enter standby so we can write to configuration register. - PORTC.OUTCLR = CE_BM; - _delay_us(10); //should be 10? - //enter RX mode: set PRIM_RX = 1 - tempval = read_register(CONFIG); - write_register(CONFIG, tempval | PRIM_RX) + //call this from standby to enter rx mode + //tempval = read_register(CONFIG); + //write_register(CONFIG, tempval | PRIM_RX); + write_register(CONFIG, 0x13); //replaces the spi read, but doesn't really speed things up much... //set CE for at least 10 us PORTC.OUTSET = CE_BM; - _delay_us(10); //should be 10? + //_delay_us(ce_delay_us); //is this necessary? //wait for pll to settle _delay_us(pll_delay_us); } @@ -200,9 +154,9 @@ void setup(){ SPIC.INTCTRL = SPI_INTLVL_OFF_gc; PORTC.DIRSET = PIN5_bm | PIN7_bm; //mosi and sck as outputs PORTC.OUTSET = SS_BM; //SS high - _delay_ms(5); //warm up + //nrf config //turn off auto-retransmit write_register(SETUP_RETR,0); //turn off disable auto-acknowledge @@ -229,76 +183,83 @@ void setup(){ _delay_ms(1); //give time to start up // and mask MAX_RT interrupts on IRQ tempval = read_register(CONFIG); - write_register(CONFIG,tempval | MAX_RT) + write_register(CONFIG,tempval | MAX_RT); //clear all interrupts tempval = read_register(STATUS); - write_register(STATUS,tempval | MAX_RT | RX_DR | TX_DS) + write_register(STATUS,tempval | MAX_RT | RX_DR | TX_DS); _delay_ms(1); sei(); - rx_from_standby(); + //enter standby so we can write to configuration register. + PORTC.OUTCLR = CE_BM; + _delay_us(ce_delay_us); + rx_from_standby(); //enter rx mode } -void send_token(){ - //transition from RX to standby1 (CE=0) - PORTC.OUTCLR = CE_BM; - _delay_us(10); + +void send_token(){ + //call this from standby1 //put token in tx fifo PORTC.OUTCLR = SS_BM; //SS low _delay_us(1); SPIC.DATA = W_TX_PAYLOAD; while(!(SPIC.STATUS & SPI_IF_bm)) {}; - SPIC.DATA = token; while(!(SPIC.STATUS & SPI_IF_bm)) {}; + tempval = SPIC.DATA; //get status while we have it + SPIC.DATA = 0; while(!(SPIC.STATUS & SPI_IF_bm)) {}; PORTC.OUTSET = SS_BM; //SS high _delay_us(1); - tempval = read_register(CONFIG); - write_register(CONFIG, tempval & (~PRIM_RX)) - //pulse CE for at least 10 us - PORTC.OUTSET = CE_BM; _delay_us(10); PORTC.OUTCLR = CE_BM; + //tempval = read_register(CONFIG); + write_register(CONFIG, tempval & (~PRIM_RX)); + //pulse CE + PORTC.OUTSET = CE_BM; _delay_us(ce_delay_us); PORTC.OUTCLR = CE_BM; //wait for pll to settle _delay_us(pll_delay_us); //wait until transmit complete while( PORTC.IN & IRQ_BM ){} //clear IRQ -- need to be in standby. tempval = read_register(STATUS); - write_register(STATUS, tempval | TX_DS) + write_register(STATUS, tempval | TX_DS); + //enter standby so we can write to configuration register. rx_from_standby(); //return to RX mode } void read_token(){ + //call this from rx //get token from rx fifo PORTC.OUTCLR = SS_BM; //SS low _delay_us(1); SPIC.DATA = R_RX_PAYLOAD; while(!(SPIC.STATUS & SPI_IF_bm)) {}; - SPIC.DATA = 0; while(!(SPIC.STATUS & SPI_IF_bm)) {}; + tempval = SPIC.DATA; //get status while we have it + SPIC.DATA = 0; while(!(SPIC.STATUS & SPI_IF_bm)) {}; token = SPIC.DATA; PORTC.OUTSET = SS_BM; //SS high _delay_us(1); //transition from RX to standby1 (CE=0) PORTC.OUTCLR = CE_BM; - _delay_us(10); + _delay_us(ce_delay_us); //clear IRQ - tempval = read_register(STATUS); - write_register(STATUS, tempval | RX_DR) + write_register(STATUS, tempval | RX_DR); //check_registers(66); } int main(void) { setup(); while(1){ - //should be in rx mode here. if ( !(PORTC.IN & IRQ_BM)){ read_token(); //in standby - token = 1-token; //transform token + token += 1; //increment token //check_registers(65); send_token(); } - //when we get signal from usart, send a token on nrf + //we use a signal on the usart to start the oscillation. if (USART_RXBufferData_Available(&USART_data)) { USART_RXBuffer_GetByte(&USART_data); //clear usart buffer so we only fire once. + //transition from RX to standby1 (CE=0) + PORTC.OUTCLR = CE_BM; + _delay_us(ce_delay_us); send_token(); //check_registers(64); } diff --git a/radio/nrf24L01/ring.png b/radio/nrf24L01/ring.png index febd3532de00111619867f96363154ff7b43b7b9..5dead4cc1a597751dfbf060b850f6686fcac480e 100755 Binary files a/radio/nrf24L01/ring.png and b/radio/nrf24L01/ring.png differ diff --git a/radio/nrf24L01/ring2.png b/radio/nrf24L01/ring2.png new file mode 100755 index 0000000000000000000000000000000000000000..c14e4aa21098978663438c43c5b15ee562bb06d3 Binary files /dev/null and b/radio/nrf24L01/ring2.png differ