uint8_t rfm70ReceivePayload() { uint8_t len; uint8_t status; uint8_t fifo_status; uint8_t rx_buf[32]; bool msg_received = false; fifo_status = rfm70ReadRegValue(RFM70_REG_FIFO_STATUS); status = rfm70ReadRegValue(RFM70_REG_STATUS); // check if receive data ready (RX_DR) interrupt if (status & RFM70_IRQ_STATUS_RX_DR) { msg_received = true; do { // read length of playload packet len = rfm70ReadRegValue(RFM70_CMD_RX_PL_WID); if (len >= 5 && len <= 32) // 32 = max packet length { // read data from FIFO Buffer rfm70ReadRegPgmBuf(RFM70_CMD_RD_RX_PLOAD, rx_buf, len); // Send message with ack payload of the beacon message // if receiver allows and button is pressed if (stateChanged) { stateChanged = false; rfm70SendPayload(buf, 32, -1, 1); } } else { // flush RX FIFO rfm70WriteRegPgmBuf((uint8_t *)RFM70_CMD_FLUSH_RX, sizeof(RFM70_CMD_FLUSH_RX)); } fifo_status = rfm70ReadRegValue(RFM70_REG_FIFO_STATUS); } while ((fifo_status & RFM70_FIFO_STATUS_RX_EMPTY) == 0); } rfm70WriteRegValue(RFM70_CMD_WRITE_REG | RFM70_REG_STATUS, status); return msg_received; }
// ---------------------------------------------------------------------------- // rfm70SendPayload // queries the FIFO status // if its not full, write payload to FIFO // ---------------------------------------------------------------------------- uint8_t rfm70SendPayload(uint8_t *payload, uint8_t len, uint8_t toAck, int pipe) { uint8_t status; // read status register status = rfm70ReadRegValue(RFM70_REG_FIFO_STATUS); // if the FIFO is full, do nothing just return false if (status & RFM70_FIFO_STATUS_TX_FULL) { return false; } // enable CSN spiSelect(csRFM73); _delay_ms(0); if (pipe==0) { spiSendMsg(RFM70_CMD_W_ACK_PAYLOAD_P0); } if (pipe==1) { spiSendMsg(RFM70_CMD_W_ACK_PAYLOAD_P1); } // send TX cmd via SPI if (toAck == -1) { // cmd: write payload with ack of received message used in RX mode //if (pipe == 0) // spiSendMsg(RFM70_CMD_W_ACK_PAYLOAD_P0); //else // spiSendMsg(RFM70_CMD_W_ACK_PAYLOAD_P1); } else if (toAck == 0) { // cmd: write TX payload and disable AUTOACK // spiSendMsg(RFM70_CMD_W_TX_PAYLOAD_NOACK); } else { // cmd: write TX payload with defined ACK packet // spiSendMsg(RFM70_CMD_WR_TX_PLOAD); } // send payload while (len--) { spiSendMsg(*(payload)); payload++; } // disable CSN spiSelect(csNONE); _delay_ms(0); return true; }
// ---------------------------------------------------------------------------- // rfm70SendPayload // queries the FIFO status // if its not full, write payload to FIFO // ---------------------------------------------------------------------------- uint8_t rfm70SendPayload(uint8_t *payload, uint8_t len, uint8_t toAck) { uint8_t status; rfm70SetModeTX(); _delay_ms(1); // read status register status = rfm70ReadRegValue(RFM70_REG_FIFO_STATUS); // if the FIFO is full, do nothing just return false if (status & RFM70_FIFO_STATUS_TX_FULL) { return false; } // set CE low // rfm needs a CE high pulse of at least 10 us and stays in // TX mode as long CE==1 and FIFO is not empty. He returns // to standbyII if FIFO is empty. // rfm70SetCE(0); // enable CSN spiSelect(csRFM73); _delay_ms(0); // send TX cmd via SPI if (toAck == -1) { // cmd: write TX payload spiSendMsg(RFM70_CMD_W_ACK_PAYLOAD); } else if (toAck == 0) { // cmd: write TX payload and disable AUTOACK spiSendMsg(RFM70_CMD_W_TX_PAYLOAD_NOACK); } else { // cmd: write TX payload with defined ACK packet spiSendMsg(RFM70_CMD_WR_TX_PLOAD); } // send payload while (len--) { spiSendMsg(*(payload)); payload++; } // disable CSN spiSelect(csNONE); _delay_ms(0); // now reset CE=1 to initiate transmitting the FIFO content //rfm70SetCE(1); return true; }
// ---------------------------------------------------------------------------- // main // ---------------------------------------------------------------------------- int main(void) { _delay_ms(100); struct { uint8_t buttons; // state of all buttons // bit 2: button 3 pressed = 0, not pressed = 1; // bit 1: button 2 pressed = 0, not pressed = 1; // bit 0: button 1 pressed = 0, not pressed = 1; int8_t touchpadX; // x-coord of the touchpad int8_t touchpadY; // y-coord of the touchpad uint8_t wheelCounter; // wheel counter, if we happen to have a wheel some time uint8_t ID; // ID of the device } stateCurrent, stateLast; bool stateChanged; /////////////////////////////////////////////////////////////////////////// //in DDRB &= ~((1 << BUTTON_1)); PORTB |= (1 << BUTTON_1); // pullup DDRD &= ~((1 << BUTTON_2) | (1 << BUTTON_3) | (1 << BUTTON_4)); PORTD |= (1 << BUTTON_2) | (1 << BUTTON_3) | (1 << BUTTON_4); // pullup DDRC &= ~((1 << BUTTON_5)); PORTC |= (1 << BUTTON_5); // pullup // all unused Ports need to be input with pullup, otherwise it does not start up propperly DDRB &= ~((1 << DDB1) | (1 << DDB2)); PORTB |= ((1 << DDB1) | (1 << DDB2)); DDRD &= ~((1 << DDD4)); PORTD |= (1 << DDD4); DDRC &= ~((1 << DDC0) | (1 << DDC1) | (1 << DDC2) | (1 << DDC3) | (1 << DDC4) | (1 << DDC5)); PORTC |= ((1 << DDC2) | (1 << DDC3) | (1 << DDC4) | (1 << DDC5)); cbi(DDRC, DDC0); // DataReady is on C0 sbi(PORTC, DDC0); // pullup cbi(DDRC, DDC1); // Touchpad button is on C1 sbi(PORTC, DDC1); // pullup //out DDRD |= (1 << LED_2); DDRD |= (1 << LED_3); DDRD |= (1 << LED_4); LED2OFF; LED3OFF; LED4OFF; //out RFM73_CSN_DIR |= (1 << RFM73_CSN_PIN); spiSelect(csNONE); RFM73_CE_DIR |= (1 << RFM73_CE_PIN); //in RFM73_IRQ_DIR &= ~(1 << RFM73_IRQ_PIN); RFM73_CE_LOW; // low level init // IO-pins and pullups spiInit(); spiSelect(csNONE); LED3ON; if (rfm70InitRegisters()) { LED2OFF; LED3OFF; } else { LED2ON; LED3OFF; } sei(); cbi(PORTB, DDB2); // chip enable of the touchpad to low _delay_ms(10); uint16_t initStreaming = 0x5ABA; spiSelect(csTOUCH); spiSendMsg16(initStreaming); spiSelect(csNONE); cbi(PORTB, DDB2); // chip enable of the touchpad to low ////////////////////////////////////////////////////////////////////////// unsigned char buf[32]; uint8_t value; stateCurrent.buttons = 0x00; stateCurrent.touchpadX = 0; stateCurrent.touchpadY = 0; stateLast = stateCurrent; stateChanged = false; uint8_t oldDataReady = 0; ////////////////////////////////////////////////////////////////////////// // start main loop uint8_t firsttime = 2; sei(); while (true) { //wdt_reset(); // keep the watchdog happy /*if((PINC & (1<<DDC0)) != 0) { oldDataReady = 1; }*/ if (((PINC & (1 << DDC0)) == 0) /* && (oldDataReady != 0)*/) { int8_t tmpdata[2]; // data is ready, read it oldDataReady = 0; spiSelect(csTOUCH); spiReadMaster(&tmpdata, 2); spiSelect(csNONE); spiSelect(csTOUCH); spiReadMaster(&tmpdata, 3); spiSelect(csNONE); stateCurrent.touchpadY += tmpdata[1]; spiSelect(csTOUCH); spiReadMaster(&tmpdata, 4); spiSelect(csNONE); stateCurrent.touchpadX += tmpdata[1]; spiSelect(csTOUCH); spiReadMaster(&tmpdata, 2); spiSelect(csNONE); } else { } // get current state of all inputs // buttons if ((PINB & (1 << BUTTON_1)) == 0) { stateCurrent.buttons |= (1 << BUTTON_BIT0); } else { stateCurrent.buttons &= ~(1 << BUTTON_BIT0); } if ((PIND & (1 << BUTTON_2)) == 0) { stateCurrent.buttons |= (1 << BUTTON_BIT1); } else { stateCurrent.buttons &= ~(1 << BUTTON_BIT1); } if ((PIND & (1 << BUTTON_3)) == 0) { stateCurrent.buttons |= (1 << BUTTON_BIT2); } else { stateCurrent.buttons &= ~(1 << BUTTON_BIT2); } if ((PIND & (1 << BUTTON_4)) == 0) { stateCurrent.buttons |= (1 << BUTTON_BIT3); } else { stateCurrent.buttons &= ~(1 << BUTTON_BIT3); } if ((PINC & (1 << BUTTON_5)) == 0) { stateCurrent.buttons |= (1 << BUTTON_BIT4); } else { stateCurrent.buttons &= ~(1 << BUTTON_BIT4); } //check if something changed if ((stateCurrent.buttons != stateLast.buttons) || (stateCurrent.touchpadX != stateLast.touchpadX) || (stateCurrent.touchpadY != stateLast.touchpadY)) { stateChanged = true; stateLast = stateCurrent; } if (stateChanged) { /*if(firsttime>0) { //firsttime --; uint16_t initStreaming = 0x5ABA; spiSelect(csTOUCH); spiSendMsg16(initStreaming); spiSelect(csNONE); }*/ stateChanged = false; // copy current state to buffer buf[0] = stateCurrent.buttons; buf[1] = stateCurrent.touchpadX; buf[2] = stateCurrent.touchpadY; buf[3] = CYBERSTICK_ID; LED4ON; // send buffer if (rfm70SendPayload(buf, 32, 0) == true) { _delay_ms(10); } value = rfm70ReadRegValue(RFM70_REG_STATUS); if ((value & 0x20) == 0x00) { _delay_ms(50); } } else { LED4OFF; } } }
uint8_t rfm70ReceivePayload(uint8_t *payload) { uint8_t len; uint8_t status; //uint8_t detect; uint8_t fifo_status; uint8_t rx_buf[32]; status = rfm70ReadRegValue(RFM70_REG_STATUS); /* detect = rfm70ReadRegValue(RFM70_REG_CD); // Read value of Carrier Detection register if (fifo_status & RFM70_FIFO_STATUS_RX_FULL) { return false; } if ((detect & RFM70_CARRIER_DETECTION) == 0x01) // Confirm that the CD bit is set high/low { cbi(PORTC, LED_YELLOW); lcd_goto(1,0); lcd_writeText("CD found ", 16); } else { sbi(PORTC, LED_YELLOW); lcd_goto(1,0); lcd_writeText("CD not found ", 16); } */ //char charValue [6] = " "; // check if receive data ready (RX_DR) interrupt if (status & RFM70_IRQ_STATUS_RX_DR) { do { // read length of playload packet len = rfm70ReadRegValue(RFM70_CMD_RX_PL_WID); if (len <= 32) // 32 = max packet length { // read data from FIFO Buffer rfm70ReadRegPgmBuf(RFM70_CMD_RD_RX_PLOAD, rx_buf, len); sbi(PORTD, LED_RED); _delay_ms(100); cbi(PORTD, LED_RED); nextDigit = &valueBuffer[sizeof(valueBuffer)]; *--nextDigit = 0xff; /* terminate with 0xff */ *--nextDigit = 0; *--nextDigit = KEY_RETURN; *--nextDigit = (rx_buf[0] & 0xf) + 4; /*if(rx_buf[0]&1) { *--nextDigit = KEY_1; } else { *--nextDigit = KEY_0; } if(rx_buf[0]&2) { *--nextDigit = KEY_1; } else { *--nextDigit = KEY_0; } if(rx_buf[0]&4) { *--nextDigit = KEY_1; } else { *--nextDigit = KEY_0; } if(rx_buf[0]&8) { *--nextDigit = KEY_1; } else { *--nextDigit = KEY_0; }*/ //itoa(len, charValue, 16); //lcd_clear(); //lcd_goto(1,0); //lcd_writeText(charValue, 2); //itoa(rx_buf[0], charValue, 16); //lcd_goto(1,3); //lcd_writeText(charValue, 2); //itoa(rx_buf[1], charValue, 16); //lcd_goto(1,6); //lcd_writeText(charValue, 2); //itoa(rx_buf[2], charValue, 16); //lcd_goto(1,9); //lcd_writeText(charValue, 2); } else { // flush RX FIFO rfm70WriteRegPgmBuf((uint8_t *)RFM70_CMD_FLUSH_RX, sizeof(RFM70_CMD_FLUSH_RX)); } fifo_status = rfm70ReadRegValue(RFM70_REG_FIFO_STATUS); } while ((fifo_status & RFM70_FIFO_STATUS_RX_EMPTY) == 0); if ((rx_buf[0] == 0xAA) && (rx_buf[1] == 0x80)) { //sbi(PORTD, LED_RED); _delay_ms(100); //cbi(PORTD, LED_RED); rfm70SetModeRX(); } } rfm70WriteRegValue(RFM70_CMD_WRITE_REG | RFM70_REG_STATUS, status); return 0; }