Exemple #1
0
/* write one page to flash */
int nrf_write_page(devp dev, int page, void *data){
    unsigned char *b = (unsigned char *)data;
    unsigned char cmd[2], ret;
    int block;

    if(page < 0 || page > 63){
        /* invalid page */
        return -1;
    }

    /* send the flash-write command */
    cmd[0] = 0x02;
    cmd[1] = (unsigned char)page;
    if(nrf_cmd(dev, cmd, sizeof(cmd), &ret, sizeof(ret)) || ret){
        return -1;
    }

    /* send a page of memory, one block at a time */
    for(block = 0; block < 8; block++){
        if(nrf_cmd(dev, &b[block * 64], 64, &ret, sizeof(ret)) || ret){
            return -2;
        }
    }

    return 0;
}
Exemple #2
0
/* compare/verify that a block on the device is identical to the one in data
 * returns result of memcpy() been device and data
 */
int nrf_compare_block(devp dev, int block, void *data){
    unsigned char cmd[2], devblock[64];

    /* request the block */
    cmd[0] = 0x03;
    cmd[1] = (unsigned char)block;
    if(nrf_cmd(dev, cmd, 2, devblock, 64)){
        return -1;
    }

    return memcmp(data, devblock, 64);
}
Exemple #3
0
// High-Level:
void nrf_rcv_pkt_start(void){

    nrf_write_reg(R_CONFIG,
            R_CONFIG_PRIM_RX| // Receive mode
            R_CONFIG_PWR_UP|  // Power on
            R_CONFIG_EN_CRC   // CRC on, single byte
            );

    nrf_cmd(C_FLUSH_RX);
    nrf_write_reg(R_STATUS,0);

    CE_HIGH();
};
Exemple #4
0
const char *nrf_version_str(devp dev){
    static unsigned char verbin[2];
    static char verstr[4];
    static unsigned char vercmd = 0x01;

    if(nrf_cmd(dev, &vercmd, 1, verbin, sizeof(verbin))){
        return "?.?";
    } else {
        verstr[0] = verbin[0] + '0';
        verstr[1] = '.';
        verstr[2] = verbin[0] + '0';
        verstr[3] = '\0';
        return verstr;
    }
}
Exemple #5
0
void nrf_rcv_pkt_end(void)
{
	CE_LOW();
	nrf_cmd(C_FLUSH_RX);
	nrf_write_reg(R_STATUS,R_STATUS_RX_DR);
};
Exemple #6
0
void main_bridge(void)
{
    GLOBAL(daytrig)=10;
    GLOBAL(lcdbacklight)=10;
    GLOBAL(privacy) = 3;
    char input[64];
    char led1=0;
    char led2=0;

    usbCDCInit();
    delayms(500);
    nrf_init();
    nrf_config_set(&config);
    
    nrf_rcv_pkt_start(R_CONFIG_EN_CRC);
    while(1){
        int l, i, status;
        CDC_OutBufAvailChar (&l);
        if(l>0){
            gpioSetValue (RB_LED0, led1);led1=1-led1;
            CDC_RdOutBuf (input, &l);
            for(i=0; i<l; i++){
                uint8_t cmd = serialmsg_put(input[i]);
                if( cmd != SERIAL_NONE ){
                    switch( cmd ){
                        case '1':
                            // can we loose packets here?
                            nrf_rcv_pkt_end();
                            status=snd_pkt_no_crc(serialmsg_len, serialmsg_message);
                            //status=nrf_snd_pkt_crc(serialmsg_len, serialmsg_message);
                            nrf_rcv_pkt_start(R_CONFIG_EN_CRC);
                        break;
                        case '3':
                            memcpy(config.txmac, serialmsg_message, 5);
                            nrf_write_long(C_W_REGISTER|R_TX_ADDR,5,config.txmac);
                        break;
                        case '4':
                            memcpy(config.mac0, serialmsg_message, 5);
                            nrf_write_long(C_W_REGISTER|R_RX_ADDR_P0,5,config.mac0);
                            nrf_write_reg(R_EN_RXADDR,1);
                        break;
                        case '5':
                            config.channel=serialmsg_message[0];
                            nrf_set_channel(config.channel);
                            nrf_cmd(C_FLUSH_RX);
                        break;
                        case '6':
                            config.maclen[0]=serialmsg_message[0];
                            nrf_write_reg(R_RX_PW_P0,config.maclen[0]);
                        break;
                        case '7':
                            puts("\\7");
                            char s[sizeof(uint32_t)+1];
                            *((uint32_t*)s) =GetUUID32();
                            s[sizeof(uint32_t)]=0;
                            puts(s);
                            puts("\\0");
                        break;
                        case '8': /* set mac width */
                            nrf_write_reg(R_SETUP_AW,serialmsg_message[0]);
                        break;
                        case '9': // Dis/Enable CRC
                            nrf_write_reg(R_CONFIG, R_CONFIG_PRIM_RX|R_CONFIG_PWR_UP|
                                    ((serialmsg_message[0]&1)?R_CONFIG_EN_CRC :0)|
                                    ((serialmsg_message[0]&2)?R_CONFIG_CRCO :0)
                                    
                                    );
                            /* maybe add enhanced shockburst stuff here */
                            nrf_cmd(C_FLUSH_RX);
                            nrf_write_reg(R_STATUS,0);
                        break;

                    };
                    puts("\\2\\0");
                }
            }
        }
        int len;
        uint8_t buf[32];
        len=nrf_rcv_pkt_poll(sizeof(buf),buf);
        if( len > 0 ){
            gpioSetValue (RB_LED2, led2);led2=1-led2;
            puts("\\1");
            dump_encoded(len, buf);
            puts("\\0");
        }
    }
}
Exemple #7
0
void APP_Run(void) {
  static const uint8_t chRf[] = {2, 26,80};
  static const uint8_t chLe[] = {37,38,39};
  uint8_t i, L, ch = 0;
  uint8_t buf[32];

  nrf_cmd(0x20, 0x12);  //on, no crc, int on RX/TX done
  nrf_cmd(0x21, 0x00);  //no auto-acknowledge
  nrf_cmd(0x22, 0x00);  //no RX
  nrf_cmd(0x23, 0x02);  //5-byte address
  nrf_cmd(0x24, 0x00);  //no auto-retransmit
  nrf_cmd(0x26, 0x06);  //1MBps at 0dBm
  nrf_cmd(0x27, 0x3E);  //clear various flags
  nrf_cmd(0x3C, 0x00);  //no dynamic payloads
  nrf_cmd(0x3D, 0x00);  //no features
  nrf_cmd(0x31, 32);  //always RX 32 bytes
  nrf_cmd(0x22, 0x01);  //RX on pipe 0

  buf[0] = 0x30;      //set addresses
  buf[1] = swapbits(0x8E);
  buf[2] = swapbits(0x89);
  buf[3] = swapbits(0xBE);
  buf[4] = swapbits(0xD6);
#if 0
  nrf_manybytes(buf, 5);
#else
  RF1_WriteRegisterData(RF1_TX_ADDR, &buf[1], 4);
#endif
  buf[0] = 0x2A;
#if 0
  nrf_manybytes(buf, 5);
#else
  RF1_WriteRegisterData(RF1_RX_ADDR_P0, &buf[1], 4);
#endif

  while(1) {
      L = 0;
      buf[L++] = 0x40;  //PDU type, given address is random
      buf[L++] = 11;  //17 bytes of payload

      buf[L++] = MY_MAC_0;
      buf[L++] = MY_MAC_1;
      buf[L++] = MY_MAC_2;
      buf[L++] = MY_MAC_3;
      buf[L++] = MY_MAC_4;
      buf[L++] = MY_MAC_5;

      buf[L++] = 2;   //flags (LE-only, limited discovery mode)
      buf[L++] = 0x01;
      buf[L++] = 0x05;

      buf[L++] = 7;
      buf[L++] = 0x08;
      buf[L++] = 'n';
      buf[L++] = 'R';
      buf[L++] = 'F';
      buf[L++] = ' ';
      buf[L++] = 'L';
      buf[L++] = 'E';

      buf[L++] = 0x55;  //CRC start value: 0x555555
      buf[L++] = 0x55;
      buf[L++] = 0x55;

      if(++ch == sizeof(chRf)) { /* channel hopping */
        ch = 0;
      }

      //nrf_cmd(0x25, chRf[ch]);
      (void)RF1_SetChannel(chRf[ch]);

      //nrf_cmd(0x27, 0x6E);  //clear flags
      RF1_WriteRegister(RF1_STATUS, RF1_STATUS_RX_DR|RF1_STATUS_TX_DS|RF1_STATUS_RX_P_NO_RX_FIFO_EMPTY); /* clear flags */

      btLePacketEncode(buf, L, chLe[ch]);

      //nrf_simplebyte(0xE2); //Clear RX Fifo
      RF1_Write(RF1_FLUSH_RX); /* flush old data */

      //nrf_simplebyte(0xE1); //Clear TX Fifo
      //RF1_Write(RF1_FLUSH_TX); /* flush old data */ /* done in RF1_TxPayload() */


      RF1_TxPayload(buf, L);
#if 0
      cbi(PORTB, PIN_nCS);
      spi_byte(0xA0);
      for(i = 0 ; i < L ; i++) {
        spi_byte(buf[i]);
      }
      sbi(PORTB, PIN_nCS);
      nrf_cmd(0x20, 0x12);  //tx on
      sbi(PORTB, PIN_CE);  //do tx
      delay_ms(10);
      cbi(PORTB, PIN_CE); (in preparation of switching to RX quickly);
#endif
      LED1_Neg();
      WAIT1_Waitms(10);
  } /* for */
}
Exemple #8
0
void main (void)
{
	static const uint8_t chRf[] = {2, 26,80};
	static const uint8_t chLe[] = {37,38,39};
	uint8_t i, L, ch = 0;
    // initialize buffer with set tx address command
    // address 8E 89 BE D6 bit-reversed
    // static rather than local saves 18 bytes
	static uint8_t buf[32]; //= {0x30, 0x6B, 0x7D, 0x91, 0x71};
	
	SPI_init();

	nrf_cmd(0x20, 0x12);	//on, no crc, int on RX/TX done
	_delay_ms(2);           // Tpd2stby
	//nrf_cmd(0x22, 0x00);	//no RX
	nrf_cmd(0x21, 0x00);	//no auto-acknowledge
	//nrf_cmd(0x22, 0x01);	//RX on pipe 0
	nrf_cmd(0x23, 0x02);	//4-byte address
	nrf_cmd(0x24, 0x00);	//no auto-retransmit
	//nrf_cmd(0x26, 0x06);	//1MBps at 0dBm
	nrf_cmd(0x26, 0x00);	//1MBps at -18dBm
	//nrf_cmd(0x27, 0x3E);	//clear various flags
	//nrf_cmd(0x31, 32);	    //always RX 32 bytes
	
	buf[0] = 0x30;			//set tx address
	buf[1] = swapbits(0x8E);
	buf[2] = swapbits(0x89);
	buf[3] = swapbits(0xBE);
	buf[4] = swapbits(0xD6);
	nrf_manybytes(buf, 5);
	//buf[0] = 0x2A;        // rx address P0
	//nrf_manybytes(buf, 5);
	
	
	while(1){
		if(++ch == sizeof(chRf)){
            ch = 0;
            sbi(NRF_PORT, DEBUG_PIN);
		    _delay_ms(109); // wait between advertisements
            cbi(NRF_PORT, DEBUG_PIN);
	    }

		L = 0;
		
		buf[L++] = 0x02;	//PDU type, given address is random
        buf[L++] = 11;      //11 + 6 = 17 bytes of payload
		
		buf[L++] = MY_MAC_0;
		buf[L++] = MY_MAC_1;
		buf[L++] = MY_MAC_2;
		buf[L++] = MY_MAC_3;
		buf[L++] = MY_MAC_4;
		buf[L++] = MY_MAC_5;
		
		buf[L++] = 2;		//flags (LE-only, limited discovery mode)
		buf[L++] = 0x01;
		buf[L++] = 0x05;
		
		buf[L++] = 7;
		buf[L++] = 0x08;
		buf[L++] = 'n';
		buf[L++] = 'R';
		buf[L++] = 'F';
		buf[L++] = ' ';
		buf[L++] = 'L';
		buf[L++] = 'E';
		
		buf[L++] = 0x55;	//CRC start value: 0x555555
		buf[L++] = 0x55;
		buf[L++] = 0x55;
		
		btLePacketEncode(buf, L, chLe[ch]);
		
		nrf_cmd(0x25, chRf[ch]);
		nrf_cmd(0x27, 0x6E);	//clear flags

		//nrf_simplebyte(0xE2); //Clear RX Fifo
		//nrf_simplebyte(0xE1); //Clear TX Fifo
	
		cbi(NRF_PORT, PIN_nCS);
		spi_byte(0xA0);
		for(i = 0 ; i < L ; i++) spi_byte(buf[i]);
		sbi(NRF_PORT, PIN_nCS);
	
		//nrf_cmd(0x20, 0x12);	//tx on
        // no CE pulse required when CE tied high 
		sbi(NRF_PORT, PIN_CE);	 //do tx
		_delay_us(15);
		cbi(NRF_PORT, PIN_CE);

        // only delay for debugging - i.e. check IRQ trigger
		//_delay_ms(1);           // let tx finish
	}
	
}
Exemple #9
0
/* write fn to device */
int nrf_program_nrf24lu(devp dev, const char *fn){
    unsigned char cmd[2], data[64], *flash_copy, dirty_bv[64];
    FILE *fp = NULL;
    int ecode, block, page, rc;
    unsigned int first_addr, last_addr;
    IHexRecord record;

    printf("Programming nRF24LU\n");
    /* read the entire ROM into memory
     *
     * Why? Because Nordic doesn't have decent software. Their flash write
     * command erases the page first, instead of letting me decide if the page
     * should be erased first.
     *
     * Byte-level writing is offered by using a read-modify-write operation.
     * It would be smarter to operate on a per-page basis, but Intel HEX files
     * are not guaranteed to have sequential addressing. Since Nordic screwed
     * up and wild IHX files are adhoc, let's work with the whole 32k flash
     * memory at once.
     */
    if((flash_copy = malloc(FLASH_SIZE)) == NULL){
        ecode = -4;
        goto err;
    }
    printf("[*] Reading device.\n");
    for(block = 0; block < 0x200; block++){
        /* set address MSB */
        if((block % 0x100) == 0){
            cmd[0] = 0x06;
            cmd[1] = (unsigned char)(block / 256);
            if(nrf_cmd(dev, cmd, 2, data, 1)){
                ecode = -2;
                goto err;
            }
        }
        /* request the block */
        cmd[0] = 0x03;
        cmd[1] = (unsigned char)block;
        if(nrf_cmd(dev, cmd, 2, &flash_copy[block2addr(block)], 64)){
            ecode = -2;
            goto err;
        }
    }

    /* overwrite in-memory with IHX contents */
    if((fp = fopen(fn, "r")) == NULL){
        ecode = -1;
        goto err;
    }
    memset(dirty_bv, 0, sizeof(dirty_bv));
    while((rc = Read_IHexRecord(&record, fp)) == IHEX_OK &&
            record.type != IHEX_TYPE_01){
        if(record.type != IHEX_TYPE_00){
            /* we cannot process segment or linear ihex files */
            printf("[!] IHX file contains segment or linear addressing.\n");
            ecode = -5;
            goto err;
        }
        /* first and last byte that is touched by this record */
        first_addr = record.address;
        last_addr = record.address + record.dataLen - 1;
        if(!addr_valid(first_addr) || !addr_valid(last_addr)){
            printf("[!] IHX record touches invalid or protected bytes: "
                    "0x%04X - 0x%04X\n", first_addr, last_addr);
            ecode = -6;
            goto err;
        }
        /* only write if the ihx record changes memory */
        if(memcmp(&flash_copy[first_addr], record.data, record.dataLen)){
            /* copy record into memory */
            memcpy(&flash_copy[first_addr], record.data, record.dataLen);
            /* mark dirty blocks */
            for(block = addr2block(first_addr); block <= addr2block(last_addr);
                    block++){
                /* check the block since we might have some *really* long
                 * record
                 */
                if(!addr_valid(block2addr(block))){
                    printf("[!] IHX record touches invalid or protected bytes:"
                            " 0x%04X\n", block2addr(block));
                    ecode = -6;
                    goto err;
                }
                bitset(dirty_bv, block);
            }
        }
    }
    if(rc != IHEX_OK && rc != IHEX_ERROR_EOF){
        /* we had an error that isn't EOF */
        ecode = -4;
        goto err;
    }

    /* write to flash */
    printf("[*] Writing device");
    fflush(stdout);
    for(page = 0; page < 64; page++){
        /* Each page is 8 blocks, which conviently maps to our dirty bit vector
         * on byte boundries.
         */
        if(dirty_bv[page]){
            printf(".");
            fflush(stdout);
            if(nrf_write_page(dev, page, &flash_copy[page2addr(page)])){
                printf("\n[!] Write failed.\n");
                ecode = -7;
                goto err;
            }
        }
    }
    printf("\n");

    /* verify */
    printf("[*] Verifying device");
    fflush(stdout);
    for(block = 0; block < 512; block++){
        if(bitisset(dirty_bv, block)){
            if(nrf_compare_block(dev, block, &flash_copy[block2addr(block)])){
                printf("\n[!] Block %d failed.\n", block);
                ecode = -8;
                goto err;
            } else {
                printf(".");
                fflush(stdout);
            }
        }
    }
    printf("\n");

    ecode = 0;
err:
    if(flash_copy){
        free(flash_copy);
    }
    if(fp){
        fclose(fp);
    }
    return ecode;
}
Exemple #10
0
/* dump all of device flash to fn */
int nrf_dump(devp dev, const char *fn){
    unsigned char cmd[2], data[64];
    FILE *fp = NULL;
    int ecode, block, sub_block;
    IHexRecord record;

    if((fp = fopen(fn, "w+")) == NULL){
        ecode = -1;
        goto err;
    }

    /* dump */
    for(block = 0; block < 0x200; block++){
        /* set address MSB */
        if((block % 0x100) == 0){
            cmd[0] = 0x06;
            cmd[1] = (unsigned char)(block / 256);
            if(nrf_cmd(dev, cmd, 2, data, 1)){
                ecode = -2;
                goto err;
            }
        }
        /* request the block */
        cmd[0] = 0x03;
        cmd[1] = (unsigned char)block;
        if(nrf_cmd(dev, cmd, 2, data, 64)){
            ecode = -2;
            goto err;
        }
        /* write two records for this block
         * records are only written if the block contains something not 0xFF
         */
        for(sub_block = 0; sub_block < 2; sub_block++){
            record.type = IHEX_TYPE_00;
            memcpy(record.data, &data[sub_block * 32], 32);
            record.dataLen = 32;
            record.address = block * 64 + sub_block * 32;
            if(memnotchr(record.data, 0xFF, 32) &&
                    Write_IHexRecord(&record, fp)){
                ecode = -3;
                goto err;
            }
        }
    }

    /* write EoF record */
    record.type = IHEX_TYPE_01;
    record.address = 0;
    record.dataLen = 0;
    if(Write_IHexRecord(&record, fp)){
        ecode = -3;
        goto err;
    }

    ecode = 0;
err:
    if(fp){
        fclose(fp);
    }
    return ecode;
}
Exemple #11
0
// High-Level:
int nrf_rcv_pkt_time_encr(int maxtime, int maxsize, uint8_t * pkt, uint32_t const key[4]){
    uint8_t len;
    uint8_t status=0;
    uint16_t cmpcrc;

    nrf_write_reg(R_CONFIG,
            R_CONFIG_PRIM_RX| // Receive mode
            R_CONFIG_PWR_UP|  // Power on
            R_CONFIG_EN_CRC   // CRC on, single byte
            );

    nrf_cmd(C_FLUSH_RX);
    nrf_write_reg(R_STATUS,0);

    CE_HIGH();

    for(int i=0;i<maxsize;i++) pkt[i] = 0x00; // Sanity: clear packet buffer

#define LOOPY 10
    for (;maxtime >= LOOPY;maxtime-=LOOPY){
        delayms(LOOPY);
        status =nrf_cmd_status(C_NOP);
        if( (status & R_STATUS_RX_DR) == R_STATUS_RX_DR){
            if( (status & R_STATUS_RX_P_NO) == R_STATUS_RX_FIFO_EMPTY){
                nrf_cmd(C_FLUSH_RX);
                delayms(1);
                nrf_write_reg(R_STATUS,0);
                continue;
            }else{ // Get/Check packet...
                nrf_read_long(C_R_RX_PL_WID,1,&len);
                if(len>32 || len==0){
                    continue;
                    return -2; // no packet error
                };

                if(len>maxsize){
                    continue;
                    return -1; // packet too large
                };

                nrf_read_pkt(len,pkt);
                if(key != NULL)
                    xxtea_decode_words((uint32_t*)pkt,len/4,key);

                cmpcrc=crc16(pkt,len-2);
                if(cmpcrc != (pkt[len-2] <<8 | pkt[len-1])) {
                    continue;
                    return -3; // CRC failed
                };
                break;
            };
        };
    };

    CE_LOW();
    CS_HIGH();

    if(maxtime<LOOPY)
        return 0; // timeout

    return len;
};