void ST_RadioTransmitCompleteIsrCallback(StStatus status, u32 txSyncTime, boolean framePending) { ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); ENERGEST_ON(ENERGEST_TYPE_LISTEN); LED_TX_OFF(); last_tx_status = status; if(status == ST_SUCCESS || status == ST_PHY_ACK_RECEIVED){ CLEAN_TXBUF(); } else { if(RETRY_CNT_GTZ()){ // Retransmission LED_TX_ON(); if(ST_RadioTransmit(stm32w_txbuf)==ST_SUCCESS){ ENERGEST_OFF(ENERGEST_TYPE_LISTEN); ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); PRINTF("stm32w: retransmission.\r\n"); DEC_RETRY_CNT(); } else { CLEAN_TXBUF(); LED_TX_OFF(); PRINTF("stm32w: retransmission failed.\r\n"); } } else { CLEAN_TXBUF(); } } /* Debug outputs. */ if(status == ST_SUCCESS || status == ST_PHY_ACK_RECEIVED){ PRINTF("stm32w: return status TX_END\r\n"); } else if (status == ST_MAC_NO_ACK_RECEIVED){ PRINTF("stm32w: return status TX_END_NOACK\r\n"); } else if (status == ST_PHY_TX_CCA_FAIL){ PRINTF("stm32w: return status TX_END_CCA_FAIL\r\n"); } else if(status == ST_PHY_TX_UNDERFLOW){ PRINTF("stm32w: return status TX_END_UNDERFLOW\r\n"); } else { PRINTF("stm32w: return status TX_END_INCOMPLETE\r\n"); } }
static void ispDetachFromDevice() { /* ensure we have no pull-ups active */ PIN_MODE(ISP_SCK, INPUT); PIN_MODE(ISP_MOSI, INPUT); PIN_MODE(ISP_RST, INPUT); DIGITAL_WRITE(ISP_SCK, LOW); DIGITAL_WRITE(ISP_MOSI, LOW); LED_TX_OFF(); }
/*---------------------------------------------------------------------------*/ static int stm32w_radio_transmit(unsigned short payload_len) { stm32w_txbuf[0] = payload_len + CHECKSUM_LEN; INIT_RETRY_CNT(); if(onoroff == OFF) { PRINTF("stm32w: Radio is off, turning it on.\r\n"); ST_RadioWake(); ENERGEST_ON(ENERGEST_TYPE_LISTEN); } #if RADIO_WAIT_FOR_PACKET_SENT GET_LOCK(); #endif /* RADIO_WAIT_FOR_PACKET_SENT */ last_tx_status = -1; LED_TX_ON(); if(ST_RadioTransmit(stm32w_txbuf) == ST_SUCCESS) { ENERGEST_OFF(ENERGEST_TYPE_LISTEN); ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); PRINTF("stm32w: sending %d bytes\r\n", payload_len); #if DEBUG > 1 for(uint8_t c = 1; c <= stm32w_txbuf[0] - 2; c++) { PRINTF("%x:", stm32w_txbuf[c]); } PRINTF("\r\n"); #endif #if RADIO_WAIT_FOR_PACKET_SENT if(wait_for_tx()) { PRINTF("stm32w: unknown tx error.\r\n"); TO_PREV_STATE(); LED_TX_OFF(); RELEASE_LOCK(); return RADIO_TX_ERR; } TO_PREV_STATE(); if(last_tx_status == ST_SUCCESS || last_tx_status == ST_PHY_ACK_RECEIVED || last_tx_status == ST_MAC_NO_ACK_RECEIVED) { RELEASE_LOCK(); if(last_tx_status == ST_PHY_ACK_RECEIVED) { return RADIO_TX_OK; /* ACK status */ } else if(last_tx_status == ST_MAC_NO_ACK_RECEIVED || last_tx_status == ST_SUCCESS) { return RADIO_TX_NOACK; } } LED_TX_OFF(); RELEASE_LOCK(); return RADIO_TX_ERR; #else /* RADIO_WAIT_FOR_PACKET_SENT */ TO_PREV_STATE(); LED_TX_OFF(); return RADIO_TX_OK; #endif /* RADIO_WAIT_FOR_PACKET_SENT */ } #if RADIO_WAIT_FOR_PACKET_SENT RELEASE_LOCK(); #endif /* RADIO_WAIT_FOR_PACKET_SENT */ TO_PREV_STATE(); PRINTF("stm32w: transmission never started.\r\n"); /* TODO: Do we have to retransmit? */ CLEAN_TXBUF(); LED_TX_OFF(); return RADIO_TX_ERR; }
void UserInit(void) { byte i; #if defined(USE_USB_BUS_SENSE_IO) tris_usb_bus_sense = INPUT_PIN; // See io_cfg.h #endif #if defined(USE_SELF_POWER_SENSE_IO) tris_self_power = INPUT_PIN; #endif CS_2515_HIGH(); //Drive high tris_CS = 0; //Output OpenSPI(SPI_FOSC_16, MODE_00, SMPMID); TRISBbits.TRISB0 = 1; //SDI TRISBbits.TRISB1 = 0; //SCK //------------------------- // initialize variables //------------------------- for (i = 0; i < BUF_SIZE; i++) // initialize input and output buffer to 0 { inbuffer[i] = 0; outbuffer[i] = 0; } //Timer 0 TMR0H = 0; //clear timer TMR0L = 0; //clear timer T0CONbits.PSA = 0; //Assign prescaler to Timer 0 T0CONbits.T0PS2 = 1; //Setup prescaler T0CONbits.T0PS1 = 1; //Will time out every 51 us based on T0CONbits.T0PS0 = 1; //20 MHz Fosc T0CONbits.T0CS = 0; //Increment on instuction cycle INTCON2 = 0xFF; //INT2 on rising edge INTCON3bits.INT2IP = 0; //Low priority INTCON3bits.INT2IF = 0; //Clear flag INTCON3bits.INT2IE = 1; //Enable INT2 interrupt //Outputs for the LEDs ADCON1 = 0x0F; //Digital pins CMCON = 0x07; //Digital pins LED_25PCT_OFF(); LED_50PCT_OFF(); LED_75PCT_OFF(); LED_100PCT_OFF(); TRISBbits.TRISB6 = INPUT_PIN; TRISBbits.TRISB7 = INPUT_PIN; tris_LED_25PCT = OUTPUT_PIN; tris_LED_50PCT = OUTPUT_PIN; tris_LED_75PCT = OUTPUT_PIN; tris_LED_100PCT = OUTPUT_PIN; UserFlag.CANLoading = OFF; LED_RX_OFF(); LED_TX_OFF(); tris_LED_TX = OUTPUT_PIN; tris_LED_RX = OUTPUT_PIN; tris_SW_LOAD = INPUT_PIN; //RTS Pin Outputs RTS0_2515_HIGH(); tris_RTS0_pin = OUTPUT_PIN; RTS1_2515_HIGH(); tris_RTS1_pin = OUTPUT_PIN; RTS2_2515_HIGH(); tris_RTS2_pin = OUTPUT_PIN; tris_CAN_RES = OUTPUT_PIN; CAN_RES_ON(); //JM // CAN_RES_OFF(); //Disconnect the termination resistor by default UserFlag.MCP_RXBn = 0; //clear flag UserFlag.USBsend = 0; //clear flag UserFlag.USBQueue = 0; //Clear message queue //Need to set up MCP2515 before enabling interrupts CANInit(); // See BusMon.c & .h RCONbits.IPEN = 1; INTCONbits.PEIE = 1; INTCONbits.GIE = 1; }//end UserInit
/****************************************************************************** * Function: void ProcessIO * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This function is a place holder for other user routines. * It is a mixture of both USB and non-USB tasks. * * Note: None *****************************************************************************/ void ProcessIO(void) { unsigned char n, b, c, y; int a; // User Application USB tasks if (!(isUsbPowered)) //Only generate traffic if NOT connected to USB { CheckLoadButton(); CANLoadTX(); return; } if ((usb_device_state < CONFIGURED_STATE) || (UCONbits.SUSPND == 1)) return; //----- Read USB buffer if it has data from the host ----- if (HIDRxReport(inbuffer, 64)) // USB receive buffer has data { LED_RX_ON(); //Turn LED on T0CONbits.TMR0ON = 1; //Start timer for TX LED on time gTimeout = 0; //Reset timout //---- CANmsgs: Check if host has requested CAN messages to be transmited switch (inbuffer[u_CANmsgs]) // interpret command { case 0x00: // No messages are available break; case 0x01: // Message 1 is available GetUSBData(m1_SIDH, 13, DataArray); n = SPILoadTX(CAN_LOAD_TX, 13, DataArray); if (n == CAN_LD_TXB0_ID) //if TX0 is loaded { RTS0_2515_LOW(); RTS0_2515_HIGH(); } else if (n == CAN_LD_TXB1_ID) //if TX1 is loaded { RTS1_2515_LOW(); RTS1_2515_HIGH(); } else if (n == CAN_LD_TXB2_ID) //if TX2 is loaded { RTS2_2515_LOW(); RTS2_2515_HIGH(); } break; case 0x02: // Message 1 and 2 are available //Message 1 GetUSBData(m1_SIDH, m1_DLC + 5, DataArray); n = SPILoadTX(CAN_LOAD_TX, m1_DLC + 5, DataArray); if (n == CAN_LD_TXB0_ID) //if TX0 is loaded { RTS0_2515_LOW(); RTS0_2515_HIGH(); } else if (n == CAN_LD_TXB1_ID) //if TX1 is loaded { RTS1_2515_LOW(); RTS1_2515_HIGH(); } else if (n == CAN_LD_TXB2_ID) //if TX2 is loaded { RTS2_2515_LOW(); RTS2_2515_HIGH(); } //Message 2 GetUSBData(m2_SIDH, m2_DLC + 5, DataArray); n = SPILoadTX(CAN_LOAD_TX, m2_DLC + 5, DataArray); if (n == CAN_LD_TXB0_ID) //if TX0 is loaded { RTS0_2515_LOW(); RTS0_2515_HIGH(); } else if (n == CAN_LD_TXB1_ID) //if TX1 is loaded { RTS1_2515_LOW(); RTS1_2515_HIGH(); } else if (n == CAN_LD_TXB2_ID) //if TX2 is loaded { RTS2_2515_LOW(); RTS2_2515_HIGH(); } break; case 0x03: // Message 1, 2, and 3 are available //Message 1 GetUSBData(m1_SIDH, m1_DLC + 5, DataArray); n = SPILoadTX(CAN_LOAD_TX, m1_DLC + 5, DataArray); if (n == CAN_LD_TXB0_ID) //if TX0 is loaded { RTS0_2515_LOW(); RTS0_2515_HIGH(); } else if (n == CAN_LD_TXB1_ID) //if TX1 is loaded { RTS1_2515_LOW(); RTS1_2515_HIGH(); } else if (n == CAN_LD_TXB2_ID) //if TX2 is loaded { RTS2_2515_LOW(); RTS2_2515_HIGH(); } //Message 2 GetUSBData(m2_SIDH, m2_DLC + 5, DataArray); n = SPILoadTX(CAN_LOAD_TX, m2_DLC + 5, DataArray); if (n == CAN_LD_TXB0_ID) //if TX0 is loaded { RTS0_2515_LOW(); RTS0_2515_HIGH(); } else if (n == CAN_LD_TXB1_ID) //if TX1 is loaded { RTS1_2515_LOW(); RTS1_2515_HIGH(); } else if (n == CAN_LD_TXB2_ID) //if TX2 is loaded { RTS2_2515_LOW(); RTS2_2515_HIGH(); } //Message 3 GetUSBData(m3_SIDH, m3_DLC + 5, DataArray); n = SPILoadTX(CAN_LOAD_TX, m3_DLC + 5, DataArray); if (n == CAN_LD_TXB0_ID) //if TX0 is loaded { RTS0_2515_LOW(); RTS0_2515_HIGH(); } else if (n == CAN_LD_TXB1_ID) //if TX1 is loaded { RTS1_2515_LOW(); RTS1_2515_HIGH(); } else if (n == CAN_LD_TXB2_ID) //if TX2 is loaded { RTS2_2515_LOW(); RTS2_2515_HIGH(); } break; case 0x04: //--FUTURE-- Message 1, 2, 3, and 4 are available break; default: // unrecognized or null command ; }// END switch: inbuffer[u_CANmsgs] //---- CANCTRL: Write to the CANCTRL register if changed if (inbuffer[u_CANCTRL] != old_CANCTRL) //If host sent new CANCTRL value { SPIByteWrite(CANCTRL, inbuffer[u_CANCTRL]); //Write to CANCTRL EEPROMBYTEWrite(CANCTRL, inbuffer[u_CANCTRL]); EEPROMCRCWrite(0, 128); old_CANCTRL = inbuffer[u_CANCTRL]; // outbuffer[u_CANSTAT] = SPIByteRead(CANSTAT); while ((outbuffer[u_CANSTAT] & 0xE0) != (inbuffer[u_CANCTRL] & 0xE0))//if didn't change modes yet { outbuffer[u_CANSTAT] = SPIByteRead(CANSTAT); } UserFlag.USBsend = 1; //Set flag so will send USB message } //---- SPI: SPI command from host if (inbuffer[u_SPI]) //If host sent SPI command (non-zero) { switch (inbuffer[u_SPI]) { case CAN_RESET: // SPIReset(); CANInit(); break; case CAN_READ: // if (!UserFlag.USBQueue) // If previous message is queued { outbuffer[u_SPI] = CAN_READ; //Send back to host outbuffer[u_REG] = inbuffer[u_REG]; //Send back to host outbuffer[u_DATA] = SPIByteRead(inbuffer[u_REG]); //Send back to host } UserFlag.USBsend = 1; //Set flag so will send USB message UserFlag.USBQueue = 1; //Indicates msg is queued, but not sent break; case CAN_WRITE: // //outbuffer[u_SPI] = 0; //Send back to host //JM SPIByteWrite(inbuffer[u_REG], inbuffer[u_DATA]); EEPROMBYTEWrite(inbuffer[u_REG], inbuffer[u_DATA]); EEPROMCRCWrite(0, 128); break; case CAN_RTS: // SPI_RTS(inbuffer[u_DATA]); break; case CAN_RD_STATUS: // outbuffer[u_DATA] = SPIReadStatus(); UserFlag.USBsend = 1; //Set flag so will send USB message break; case FIRMWARE_VER_RD: memmove(&outbuffer[u_STATUS], firmware_version, sizeof (firmware_version)); outbuffer[u_STATUS + sizeof (firmware_version)] = 0; UserFlag.USBsend = 1; //Set flag so will send USB message break; default: // unrecognized or null command ; }// END switch: inbuffer[u_SPI] } }//END if (HIDRxReport(inbuffer, 1) //---- Check RXnBF pins and service messages as needed --- switch (CheckCANRX()) // Check if CAN message received { case 0x01: // Message in RXB0 (Msgs in this buffer are Standard) SPIReadRX(CAN_RD_START_RXB0SIDH, 13, ReadArray); LoadUSBString(ReadArray); break; case 0x02: // Message in RXB1 (Msgs in this buffer are Extended) SPIReadRX(CAN_RD_START_RXB1SIDH, 13, ReadArray); LoadUSBString(ReadArray); break; case 0x03: // Message in RXB0 and RXB1 SPIReadRX(CAN_RD_START_RXB0SIDH, 13, ReadArray); LoadUSBString(ReadArray); SPIReadRX(CAN_RD_START_RXB1SIDH, 13, ReadArray); LoadUSBString(ReadArray); break; default: // unrecognized or null command ; }// END switch: CheckCANRX() //---- The following turns off the TX and RX USB indicator LEDs after some time //Inst. cycle = 200 ns; TMR0IF sets every 51 us if (INTCONbits.TMR0IF) { TimerCounter++; if (!TimerCounter) //if rolled over, set flag. User code will handle the rest. { LED_TX_OFF(); //Turn LED off LED_RX_OFF(); //Turn LED off T0CONbits.TMR0ON = 0; //Start timer for TX LED on time TimerCounter = 0xFE; gTimeout = 1; //Reset timout } INTCONbits.TMR0IF = 0; } //------ Load USB Data to be transmitted to the host -------- if (UserFlag.MCP_RXBn | UserFlag.USBsend) { if (!mHIDTxIsBusy()) { HIDTxReport(outbuffer, 64); outbuffer[0] = 0x00; //PKR$$$ Need this?? UserFlag.MCP_RXBn = 0; //clear flag UserFlag.USBsend = 0; //clear flag UserFlag.USBQueue = 0; //Clear message queue LED_TX_ON(); //Turn LED on T0CONbits.TMR0ON = 1; //Start timer for TX LED on time gTimeout = 0; //Reset timout outbuffer[u_SPI] = 0x00; //clear back to 00h so host doesn't detect "SPI response" USB_ptr = 0xFF; //Point to location 0xFF outbuffer[u_CANmsgs] = 0x00; //Clear message status } } }//end ProcessIO