int main() { static char address[5]; sd_mbr_command(&startSdCmd); sd_softdevice_vector_table_base_set(BOOTLOADER_ADDRESS); // If the master boot switch has detected short or no click: boot the firmware if (((NRF_POWER->GPREGRET&0x86U) != 0x82U) && ((NRF_POWER->GPREGRET&0x40U) != 0x40U) && (*(uint32_t *)FW_ADDRESS != 0xFFFFFFFFU) ) { start_firmware(); } if (NRF_POWER->GPREGRET&0x40U) { address[4] = 0xb1; memcpy(&address[0], (char*)&NRF_FICR->DEVICEADDR[0], 4); esbSetAddress(address); } NRF_POWER->GPREGRET &= ~(0x60U); // Enable the radio LNA nrf_gpio_cfg_output(RADIO_PAEN_PIN); nrf_gpio_pin_set(RADIO_PAEN_PIN); // Initialize timer module. APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, false); ble_init(); /* NRF_CLOCK->LFCLKSRC = CLOCK_LFCLKSTAT_SRC_Synth; NRF_CLOCK->TASKS_LFCLKSTART = 1UL; while(!NRF_CLOCK->EVENTS_LFCLKSTARTED); */ systickInit(); buttonInit(buttonIdle); #ifndef DEBUG_TIMESLOT //sd_ppi_channel_assign(0, &(NRF_TIMER1->EVENTS_COMPARE[0]), &(NRF_GPIOTE->TASKS_OUT[0])); //sd_ppi_channel_enable_set(PPI_CHEN_CH0_Msk); //NRF_PPI->CH[0].EEP = &(NRF_TIMER1->EVENTS_COMPARE[0]); //NRF_PPI->CH[0].TEP = &(NRF_GPIOTE->TASKS_OUT[0]); //NRF_PPI->CHENSET = 1; #endif // Start (or continue) to blink the LED at 0.5Hz //NRF_TIMER1->TASKS_STOP = 1; //NRF_TIMER1->MODE = TIMER_MODE_MODE_Timer; //NRF_TIMER1->PRESCALER = 7; //NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos; //NRF_TIMER1->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Msk; // | TIMER_SHORTS_COMPARE1_CLEAR_Msk; //NRF_TIMER1->TASKS_CLEAR = 1; NRF_TIMER1->CC[0] = 1*SEC; //0x1E84 ; NRF_TIMER1->CC[1] = 2*SEC; nrf_gpio_cfg_output(LED_PIN); nrf_gpiote_task_config(0, LED_PIN, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW); NRF_TIMER1->TASKS_START = 1; // Enable 500mA USB input and enable battery charging nrf_gpio_cfg_output(PM_EN1); nrf_gpio_pin_set(PM_EN1); nrf_gpio_cfg_output(PM_EN2); nrf_gpio_pin_clear(PM_EN2); nrf_gpio_cfg_output(PM_CHG_EN); nrf_gpio_pin_clear(PM_CHG_EN); // Power STM32, hold reset nrf_gpio_cfg_output(PM_VCCEN_PIN); nrf_gpio_pin_set(PM_VCCEN_PIN); nrf_gpio_cfg_output(STM_NRST_PIN); nrf_gpio_pin_clear(STM_NRST_PIN); // Set flow control and activate pull-down on RX data pin nrf_gpio_cfg_output(UART_TX_PIN); nrf_gpio_pin_set(UART_TX_PIN); nrf_gpio_cfg_output(UART_RTS_PIN); nrf_gpio_pin_set(UART_RTS_PIN); nrf_gpio_cfg_input(UART_RX_PIN, NRF_GPIO_PIN_PULLDOWN); nrf_gpio_pin_set(STM_NRST_PIN); //systickInit(); //syslinkInit(); //buttonInit(); // nrf_gpio_cfg_input(BUTTON_PIN, NRF_GPIO_PIN_PULLUP); mainLoop(); while(1); }
void mainloop() { static struct syslinkPacket slRxPacket; static struct syslinkPacket slTxPacket; static EsbPacket esbRxPacket; bool esbReceived = false; bool slReceived; static int vbatSendTime; static int radioRSSISendTime; static uint8_t rssi; while(1) { #ifdef BLE if ((esbReceived == false) && bleCrazyfliesIsPacketReceived()) { EsbPacket* packet = bleCrazyfliesGetRxPacket(); memcpy(esbRxPacket.data, packet->data, packet->size); esbRxPacket.size = packet->size; esbReceived = true; bleCrazyfliesReleaseRxPacket(packet); } #endif #ifndef CONT_WAVE_TEST if ((esbReceived == false) && esbIsRxPacket()) { EsbPacket* packet = esbGetRxPacket(); //Store RSSI here so that we can send it to STM later rssi = packet->rssi; memcpy(esbRxPacket.data, packet->data, packet->size); esbRxPacket.size = packet->size; esbReceived = true; esbReleaseRxPacket(packet); } if (esbReceived) { EsbPacket* packet = &esbRxPacket; esbReceived = false; if((packet->size >= 4) && (packet->data[0]==0xff) && (packet->data[1]==0x03)) { handleRadioCmd(packet); } else if ((packet->size >2) && (packet->data[0]==0xff) && (packet->data[1]==0xfe)) { handleBootloaderCmd(packet); } else { memcpy(slTxPacket.data, packet->data, packet->size); slTxPacket.length = packet->size; slTxPacket.type = SYSLINK_RADIO_RAW; syslinkSend(&slTxPacket); } } slReceived = syslinkReceive(&slRxPacket); if (slReceived) { switch (slRxPacket.type) { case SYSLINK_RADIO_RAW: if (esbCanTxPacket() && (slRxPacket.length < SYSLINK_MTU)) { EsbPacket* packet = esbGetTxPacket(); if (packet) { memcpy(packet->data, slRxPacket.data, slRxPacket.length); packet->size = slRxPacket.length; esbSendTxPacket(packet); } bzero(slRxPacket.data, SYSLINK_MTU); } #ifdef BLE if (slRxPacket.length < SYSLINK_MTU) { static EsbPacket pk; memcpy(pk.data, slRxPacket.data, slRxPacket.length); pk.size = slRxPacket.length; bleCrazyfliesSendPacket(&pk); } #endif break; case SYSLINK_RADIO_CHANNEL: if(slRxPacket.length == 1) { esbSetChannel(slRxPacket.data[0]); slTxPacket.type = SYSLINK_RADIO_CHANNEL; slTxPacket.data[0] = slRxPacket.data[0]; slTxPacket.length = 1; syslinkSend(&slTxPacket); } break; case SYSLINK_RADIO_DATARATE: if(slRxPacket.length == 1) { esbSetDatarate(slRxPacket.data[0]); slTxPacket.type = SYSLINK_RADIO_DATARATE; slTxPacket.data[0] = slRxPacket.data[0]; slTxPacket.length = 1; syslinkSend(&slTxPacket); } break; case SYSLINK_RADIO_CONTWAVE: if(slRxPacket.length == 1) { esbSetContwave(slRxPacket.data[0]); slTxPacket.type = SYSLINK_RADIO_CONTWAVE; slTxPacket.data[0] = slRxPacket.data[0]; slTxPacket.length = 1; syslinkSend(&slTxPacket); } break; case SYSLINK_RADIO_ADDRESS: if(slRxPacket.length == 5) { uint64_t address = 0; memcpy(&address, &slRxPacket.data[0], 5); esbSetAddress(address); slTxPacket.type = SYSLINK_RADIO_ADDRESS; memcpy(slTxPacket.data, slRxPacket.data, 5); slTxPacket.length = 5; syslinkSend(&slTxPacket); } break; case SYSLINK_PM_ONOFF_SWITCHOFF: pmSetState(pmAllOff); break; case SYSLINK_OW_GETINFO: case SYSLINK_OW_READ: case SYSLINK_OW_SCAN: case SYSLINK_OW_WRITE: if (memorySyslink(&slRxPacket)) { syslinkSend(&slRxPacket); } break; } } // Wait a while to start pushing over the syslink since UART pins are used to launch STM32 i bootloader as well if (systickGetTick() > SYSLINK_STARTUP_DELAY_TIME_MS) { // Send the battery voltage and state to the STM every SYSLINK_SEND_PERIOD_MS if (systickGetTick() >= vbatSendTime + SYSLINK_SEND_PERIOD_MS) { float fdata; uint8_t flags = 0; vbatSendTime = systickGetTick(); slTxPacket.type = SYSLINK_PM_BATTERY_STATE; slTxPacket.length = 9; flags |= (pmIsCharging() == true)?0x01:0; flags |= (pmUSBPower() == true)?0x02:0; slTxPacket.data[0] = flags; fdata = pmGetVBAT(); memcpy(slTxPacket.data+1, &fdata, sizeof(float)); fdata = pmGetISET(); memcpy(slTxPacket.data+1+4, &fdata, sizeof(float)); syslinkSend(&slTxPacket); } //Send an RSSI sample to the STM every 10ms(100Hz) if (systickGetTick() >= radioRSSISendTime + 10) { radioRSSISendTime = systickGetTick(); slTxPacket.type = SYSLINK_RADIO_RSSI; //This message contains only the RSSI measurement which consist //of a single uint8_t slTxPacket.length = sizeof(uint8_t); memcpy(slTxPacket.data, &rssi, sizeof(uint8_t)); syslinkSend(&slTxPacket); } } #endif // Button event handling ButtonEvent be = buttonGetState(); bool usbConnected = pmUSBPower(); if ((pmGetState() != pmSysOff) && (be == buttonShortPress) && !usbConnected) { pmSetState(pmAllOff); /*swdInit(); swdTest();*/ } else if ((pmGetState() != pmSysOff) && (be == buttonShortPress) && usbConnected) { //pmSetState(pmSysOff); pmSetState(pmAllOff); /*swdInit(); swdTest();*/ } else if ((pmGetState() == pmSysOff) && (be == buttonShortPress)) { //Normal boot pmSysBootloader(false); pmSetState(pmSysRunning); } else if ((pmGetState() == pmSysOff) && boottedFromBootloader) { //Normal boot after bootloader pmSysBootloader(false); pmSetState(pmSysRunning); } else if ((pmGetState() == pmSysOff) && (be == buttonLongPress)) { //stm bootloader pmSysBootloader(true); pmSetState(pmSysRunning); } boottedFromBootloader = false; // processes loop buttonProcess(); pmProcess(); //owRun(); //TODO! } }