/** * @brief Read multiple bytes from RX FIFO of CC2500. * @param buffer buffer to write result to * @param NumByteToRead number of bytes to read from RX FIFO * @retval void */ __inline void CC2500_read_rx(uint8_t* buffer, uint8_t NumByteToRead) { if (NumByteToRead == 1) { CC2500_Read(buffer, CC2500_RX_FIFO, NumByteToRead); } else if (NumByteToRead > 1) { CC2500_Read(buffer, CC2500_RX_FIFO_BURST, NumByteToRead); } }
/* Receive Keypad variables. uint8_t *ctrl = pointer to control value float *value = pointer to the value you are expecting in the keypad sequence, i.e. pitch,roll,time */ void receive_keypad(uint8_t *ctrl, float *value) { wait_for_idle(); // Determine number of bytes to read uint8_t bytesToRead; CC2500_Read(&bytesToRead, CC2500_RXBYTES,1); bytesToRead = bytesToRead & 0x7F; uint8_t buffer[bytesToRead]; CC2500_Read(&buffer[0], CC2500_FIFOADDR, bytesToRead); bytesToRead -= 2; packet_t *pkt_pnt = (packet_t *) &buffer[0]; *value = pkt_pnt->f1; *ctrl = pkt_pnt->b1; //uint8_t ctrl2 = pkt_pnt->b2; // Exract data //*pitch = buffer[0]; //*roll = (float) buffer[4]; //uint16_t ctrl = buffer[8]; //printf(" Pitch: %f Roll: %f \n",pkt_pnt->f1,pkt_pnt->f2); // Move back to recieve state CC2500_CommandProbe(CC2500_READBIT, CC2500_SRX); }
/** * @brief This function transmits wireless a given data array * @param array The array to transmit * @param length The size of the array */ void transmit(uint8_t* array, int length) { uint8_t i = 0; uint8_t pending_write = 0; do { CC2500_Read(s2, CC2500_MARCSTATE | 0xC0, 1); if (s2[0] != 19) { CC2500_Read(s2 + 1, CC2500_STX | 0xC0, 1); } else { break; } } while (1); while (i < length) { CC2500_Read(s2, CC2500_MARCSTATE, 2); if (s2[0] == 22) { i = 1; } else if (s2[0] == 19 && pending_write == 0) { CC2500_Write(array + i, CC2500_FIFO, 1); i = i + 1; pending_write = 1; } else { CC2500_Read(s2 + 1, CC2500_STX, 1); pending_write = 0; } for (uint32_t j = 0; j < 18641351; j++); } }
/* Receives the pitch and roll from the transmitter and parses the packet for the angles Input: float* pitch, float* roll = pointers to the angles uint8_t* ctrl2 = pointer to the control value so that we can update it. */ uint16_t receive_pitchroll(float* pitch, float* roll, uint8_t* ctrl2) { // assume already in RX // Wait for a transmisson to be read. When this happens, the CC2500 will move to the idle state wait_for_idle(); // Determine number of bytes to read uint8_t bytesToRead; CC2500_Read(&bytesToRead, CC2500_RXBYTES,1); bytesToRead = bytesToRead & 0x7F; uint8_t buffer[bytesToRead]; CC2500_Read(&buffer[0], CC2500_FIFOADDR, bytesToRead); bytesToRead -= 2; //printf("Data: %x %x %x %x %x %x %x %x %x %x \n ",buffer[0],buffer[1],buffer[2],buffer[3], // buffer[4],buffer[5],buffer[6],buffer[7],buffer[8],buffer[9]); packet_t *pkt_pnt = (packet_t *) &buffer[0]; *pitch = pkt_pnt->f1; *roll = pkt_pnt->f2; uint8_t ctrl1 = pkt_pnt->b1; *ctrl2 = pkt_pnt->b2; // Exract data //*pitch = buffer[0]; //*roll = (float) buffer[4]; uint16_t ctrl = buffer[8]; //printf(" Pitch: %f Roll: %f \n",pkt_pnt->f1,pkt_pnt->f2); // Move back to recieve state CC2500_CommandProbe(CC2500_READBIT, CC2500_SRX); return ctrl; }
void test_read_write(void){ uint8_t test_values[3] = {0x1F,0xDE,0xAD}; uint8_t orig[3], res[3]; CC2500_Read(orig, 0x00, 3); WIRELESS_TRY(orig[0], VAL_CC2500_IOCFG2); WIRELESS_TRY(orig[1], VAL_CC2500_IOCFG1); WIRELESS_TRY(orig[2], VAL_CC2500_IOCFG0); //CC2500_Read(&result, 0x00, 1); //printf("result = %d\n", result); //uint8_t val2[3] = {65,80,43}; CC2500_Write(test_values, 0x00, 3); CC2500_Read(res, 0x00, 3); WIRELESS_TRY(res[0], test_values[0]); WIRELESS_TRY(res[1], test_values[1]); WIRELESS_TRY(res[2], test_values[2]); CC2500_Write(orig, 0x00, 3); CC2500_Read(res, 0x00, 3); WIRELESS_TRY(res[0], VAL_CC2500_IOCFG2); WIRELESS_TRY(res[1], VAL_CC2500_IOCFG1); WIRELESS_TRY(res[2], VAL_CC2500_IOCFG0); printf("result = %d, %d, %d\n", res[0], res[1], res[2]); }
/** * @brief Recieves wireless data. * * @notes Recieves wireless data, checks the CRC for correctness, and then * returns the value if it is ok. Otherwise an error value is returned. * @retval The angle data from the transmitter board or an error code. */ angle_data CC2500_RXData(void){ uint8_t bytes_in_rxfifo; uint8_t data[4]; uint8_t crc; angle_data processed_data; CC2500_Strobe(SRX); while(CC2500_Strobe(SNOP) != 1); CC2500_Read(&bytes_in_rxfifo, RXBYTES, 1); bytes_in_rxfifo = bytes_in_rxfifo & 0x7F; if(bytes_in_rxfifo >= 4){ CC2500_Read(data, 0xFF, 4); crc = data[3] & 0x80; if(crc){ processed_data.pitch = data[PITCH_DATA] - 90; processed_data.roll = data[ROLL_DATA] - 90; } CC2500_Strobe(SIDLE); while(CC2500_Strobe(SNOP) != 0); CC2500_Strobe(SFRX); // Return to RX mode CC2500_Strobe(SRX); // Wait until mode changes while(CC2500_Strobe(SNOP) != 1); } return processed_data; }
void set_transmit_mode() { CC2500_Read(&m_state_set_transmit, CC2500_MARCSTATE, 2); while (m_state_set_transmit != 19 && m_state_set_transmit != 20) { if (m_state_set_transmit == 22) { flush_TXFIFO(); } CC2500_Read(&status_byte, CC2500_STX, 1); CC2500_Read(&m_state_set_transmit, CC2500_MARCSTATE, 2); } }
/** * @brief This function is responsible for setting up the necessary components for wireless reception */ void set_receive_mode() { CC2500_Read(&m_state_set_receive, CC2500_MARCSTATE, 2); while(m_state_set_receive != 13 && m_state_set_receive != 14 && m_state_set_receive != 15) { if (m_state_set_receive == 17) { flush_RXFIFO(); } CC2500_Read(&status_byte, CC2500_SRX, 1); CC2500_Read(&m_state_set_receive, CC2500_MARCSTATE, 2); } }
/** * @brief Reads one packet from * @param Memory pointer to store recieved packets * @param Number of bytes to read (packet length + <optional * @note Flushes the FIFO after retrieving and puts CC2500 in IDLE mode. Assumes RX packets are already in RX FIFO */ void CC2500_RxPackets(uint8_t* pBuffer, uint16_t NumByteToRead) { // Read the packet(s) CC2500_Read(pBuffer, CC2500_FIFO_ADDR, NumByteToRead); // Go to idle and flush rx buffer. CC2500_Strobe(CC2500_STROBE_SIDLE, DUMMY_BYTE); CC2500_Strobe(CC2500_STROBE_SFRX, DUMMY_BYTE); }
/** * @brief This function reads what is being received by the transmitter */ void read_RXFIFO() { set_receive_mode(); CC2500_Read(&bytes_received, CC2500_RXBYTES, 2); int bytes_read = 0; uint32_t i; while (1) { // this should be replaced with check on number of bytes received CC2500_Read((buffer + bytes_read), CC2500_FIFO, 1); CC2500_Read(&bytes_received, CC2500_RXBYTES, 2); for (i = 0; i < 16800000; i++); // delay CC2500_Read(&m_state_read_rxfifo, CC2500_MARCSTATE, 2); if (m_state_read_rxfifo != 13 && m_state_read_rxfifo != 14 && m_state_read_rxfifo != 15) { set_receive_mode(); } bytes_read = (bytes_read + 1) % 32; // change to buffer length for greater modularity } }
void transmit(uint8_t* array, int length) { uint8_t i = 0; uint8_t pending_write = 0; do { CC2500_Read(s2, CC2500_MARCSTATE | 0xC0, 1); if (s2[0] != 19) { CC2500_Read(s2 + 1, CC2500_STX | 0xC0, 1); } else { break; } } while (1); while (1) { /*set_transmit_mode(); uint8_t a = 2; CC2500_Write(&a, CC2500_FIFO, 1); int i; for (i = 0; i < 16900000; i++); a = 5; CC2500_Write(&a, CC2500_FIFO, 1); for (i = 0; i < 16900000; i++);*/ CC2500_Read(s2, CC2500_MARCSTATE, 2); if (s2[0] == 22) { i = 1; } else if (s2[0] == 19 && pending_write == 0) { CC2500_Write(write_test + i, CC2500_FIFO, 1); i = (i + 1) % 5; pending_write = 1; } else { CC2500_Read(s2 + 1, CC2500_STX, 1); pending_write = 0; } for (uint32_t j = 0; j < 18641351; j++); } }
/* Reads packet from wireless chip. Input: packet_t *return_pktpnt = pointer to where received packet will be stored */ void read_packet(packet_t *return_pktpnt) { // Determine number of bytes to read uint8_t bytesToRead; CC2500_Read(&bytesToRead, CC2500_RXBYTES,1); bytesToRead = bytesToRead & 0x7F; uint8_t buffer[bytesToRead]; CC2500_Read(&buffer[0], CC2500_FIFOADDR, bytesToRead); bytesToRead -= 2; packet_t *pkt_pnt = (packet_t *) &buffer[0]; return_pktpnt->f1 = pkt_pnt->f1; return_pktpnt->f2 = pkt_pnt->f2; return_pktpnt->b1 = pkt_pnt->b1; return_pktpnt->b2 = pkt_pnt->b2; // Move back to recieve state CC2500_CommandProbe(CC2500_READBIT, CC2500_SRX); }
void set_receive_mode() { CC2500_Read(&m_state_set_receive, CC2500_MARCSTATE, 2); while(m_state_set_receive != 13 && m_state_set_receive != 14 && m_state_set_receive != 15) { if (m_state_set_receive == 17) { flush_RXFIFO(); } CC2500_Read(&status_byte, CC2500_SRX, 1); CC2500_Read(&m_state_set_receive, CC2500_MARCSTATE, 2); } /* uint8_t flag = status_byte & state_mask; while (flag != 16) { flush_RXFIFO(); CC2500_Read(&status_byte, CC2500_SRX, 1); flag = status_byte & state_mask; } */ }
/** * @brief Checks registers against a given value. * * @notes Reads the given numbers of registers from the start address, and * compares them to the given value. * @param pBuffer: The given values to test registers against. * @param TestAddr: The initial register to test. * @param NumByteToTest: The number of registers to test. * @retval 1 if all registers are OK, 0 otherwise. */ uint8_t CC2500_CheckRegisters(uint8_t* pBuffer, uint8_t TestAddr, uint16_t NumByteToTest){ uint8_t ctrl[16]; int i = 0; CC2500_Read(ctrl, TestAddr, NumByteToTest); while(i < NumByteToTest){ if(pBuffer[i] != ctrl[i]) return 0; i++; } return 1; }
void test_wireless(void){ uint8_t res2[3]; CC2500_Read(res2, CC2500_FREQ_REG, 3); printf("result = %x, %x, %x\n", res2[0], res2[1], res2[2]); CC2500_INT_INIT(); for (int i=0; i<168000000/6; i++); while(1); }
/** * @brief Read status registor on he device * @param Address of the status register to read * @retval Status register bits received from CC2500 */ uint8_t CC2500_StatusReg(uint8_t StatusRegAddr) { uint8_t reg; //Set the Chip Select to low at the beginning of the transmission (page 21, CC2500) CC2500_CS_LOW(); // set burst bit to high to distinct from strobe command (page 5, cc2500 design note) StatusRegAddr |= BURST_BIT; CC2500_Read(®, StatusRegAddr, 1); // set the chip select to high marking end of transmission CC2500_CS_HIGH(); return reg; }
void test_transmit(void){ uint8_t res2[3]; uint8_t to_send = 0; CC2500_Read(res2, CC2500_FREQ_REG, 3); printf("result = %x, %x, %x\n", res2[0], res2[1], res2[2]); while(1){ CC2500_Write(&to_send, CC2500_FIFO_REG, 1); to_send = (to_send + 2) % 10; printf("sent = %d\n", to_send); for (int i=0; i<168000000/12; i++); } }
void RxPacket(void const *argument){ uint8_t mode_filter, transmit_mode; //uint8_t buf; uint8_t buf; Packet pkt; GPIO_ResetBits(GPIOD, GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15); mode_filter = 0x70; transmit_mode = 0x20; printf("Thread_started. waitig for signal\n"); // put reciever in RX mode CC2500_Strobe(CC2500_STROBE_SRX, 0x00); while(1){ int i; osSignalWait(RX_PKT, osWaitForever); //turn on LED on packet RX GPIO_ToggleBits(GPIOD, GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15); CC2500_Read(&buf ,CC2500_FIFO_ADDR, 1); //CC2500_RxPackets((uint8_t*)&pkt, CC2500_SETTING_PKTLEN + 2); printf("buf is %d \n", buf); if(pkt.Src_addr == 0x01){ i++; // put the measured RSSI in byte 3 for main board pkt.Aux_rssi = pkt.Rssi; printf("%d Packet received from user beacon\n", i); printf("SRC: 0x%02x\t\t", pkt.Src_addr); printf("SEQ: 0x%02x\t\t", pkt.Seq_num); printf("RAW_RSSI: 0x%02x\n", pkt.Rssi); buf = CC2500_Strobe(CC2500_STROBE_SRX, 0x3F); printf("Buffer : 0x%02x\n", buf); } // change the source address on the packet pkt.Src_addr = CC2500_SETTING_ADDR; // transmit this packet for main board osDelay(100); CC2500_TxPacket((uint8_t*)&pkt, CC2500_SETTING_PKTLEN); // turn off LED on successful Tx GPIO_ToggleBits(GPIOD, GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15); // put device back to rx mode osDelay(100); } }
/** * @brief Function that receives data and performs Triple Modular Redundancy. This is a blocking call. * @param *receiver: pointer to a Receiver structure. * @retval None. */ void wireless_RX(struct Receiver *receiver) { uint8_t i=0; uint8_t temp_data=0; osMutexWait(receiver->mutexID, osWaitForever); uint8_t raw_data[sizeof(receiver->data)/sizeof(receiver->data[0]) * 3]; CC2500_StrobeSend(SRX_R,&(receiver->state),&(receiver->buffer_space)); osMutexRelease(receiver->mutexID); osDelay(STROBE_DELAY); while (i<(sizeof(receiver->data)/sizeof(receiver->data[0]) * 3)) { osMutexWait(receiver->mutexID, osWaitForever); CC2500_StrobeSend(SNOP_R,&(receiver->state),&(receiver->buffer_space)); if (receiver->buffer_space>0) { CC2500_Read(&temp_data, 0x3F, 1); if ((temp_data&0xF0)==0xF0) { raw_data[0]=temp_data&0x0F; i=1; } else if (i>0) { if ((temp_data&0xF0)==i<<4) { raw_data[i]=temp_data&0x0F; i++; } else { i=0; } } } osMutexRelease(receiver->mutexID); osDelay(STROBE_DELAY); } osMutexWait(receiver->mutexID, osWaitForever); for(uint32_t j=0;j<sizeof(receiver->data)/sizeof(receiver->data[0]);j++){ receiver->data[j] = ((raw_data[3*j]&raw_data[3*j+1]) | (raw_data[3*j]&raw_data[3*j+2]) | (raw_data[3*j+2]&raw_data[3*j+1])); } CC2500_StrobeSend(SIDLE_R,&(receiver->state),&(receiver->buffer_space)); osMutexRelease(receiver->mutexID); osDelay(STROBE_DELAY); osMutexWait(receiver->mutexID, osWaitForever); CC2500_StrobeSend(SNOP_R,&(receiver->state),&(receiver->buffer_space)); osMutexRelease(receiver->mutexID); osDelay(STROBE_DELAY); }
/** * @brief Receive packets * @param Pre-Set Argument * @retval Null */ void RxPacket(void const *argument){ uint8_t mode_filter, transmit_mode; //uint8_t buf; uint8_t buf[2]; GPIO_ResetBits(GPIOD, GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15); mode_filter = 0x70; transmit_mode = 0x20; printf("Thread_started. waiting for signal\n"); // put reciever in RX mode CC2500_Strobe(CC2500_STROBE_SRX, 0x00); while(1){ int i = 0; status = CC2500_Strobe(CC2500_STROBE_SRX, 0x00); CC2500_Read(&temp, CC2500_STATUS_REG_RXBYTES , 2); CC2500_Read(&test, CC2500_STATUS_REG_PKTSTATUS , 2); //Read only if correct packet length if(temp == CC2500_SETTING_PKTLEN) { status = CC2500_Strobe(CC2500_STROBE_SRX, 0x00); CC2500_RxPackets((uint8_t*)received, CC2500_SETTING_PKTLEN ); //Store in float array } osDelay(100); } }
/* Returns the signal strength of the wireless chip. Reads the RSSI resgister and converts the values to dB. Return variable is a signed Integer. */ int get_signal_strength(void) { uint8_t byte; CC2500_Read(&byte, CC2500_RSSI,1); //printf("RSSI = %i \n",byte); int rssi = (int) byte; /* 1) Read the RSSI status register 2) Convert the reading from a hexadecimal number to a decimal number (RSSI_dec) 3) If RSSI_dec >= 128 then RSSI_dBm = (RSSI_dec - 256)/2 – RSSI_offset 4) Else if RSSI_dec < 128 then RSSI_dBm = (RSSI_dec)/2 – RSSI_offset */ int offset = 70; if (rssi >= 128) rssi = (rssi - 256)/2 - offset; else rssi = (rssi)/2 - offset; return rssi; }
/** * @brief Read one byte from CC2500. * @param ReadAddr : address to read from * @retval byte value read from CC2500 */ __inline uint8_t CC2500_read_one(uint8_t ReadAddr) { uint8_t temp; CC2500_Read(&temp, ReadAddr, 1); return temp; }
void setup() { config_wireless(); CC2500_Read(&status_byte, CC2500_STX, 1); // signal fill_with_zeros(buffer, 64); }