Skip to content

Commit

Permalink
Begin Crazyflie work
Browse files Browse the repository at this point in the history
  • Loading branch information
simondlevy committed Mar 3, 2025
1 parent ec65168 commit 25cf79b
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 0 deletions.
1 change: 1 addition & 0 deletions crazyflie/test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build/
23 changes: 23 additions & 0 deletions crazyflie/test/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
SKETCH = test

FQBN = STMicroelectronics:stm32:GenF4:pnum=GENERIC_F405RGTX

PORT = /dev/ttyACM0

BIN = build/$(SKETCH).ino.bin

$(BIN): $(SKETCH).ino *.cpp *.h
arduino-cli compile --fqbn $(FQBN) --build-path=$(PWD)/build $(SKETCH).ino

flash: $(BIN)
./usb-bootloader.py
dfu-util -d 0483:df11 -a 0 -s 0x08004000:leave -D $(BIN)

clean:
rm -rf build

edit:
vim $(SKETCH).ino

listen:
miniterm.py $(PORT) 115200
88 changes: 88 additions & 0 deletions crazyflie/test/bootloader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/**
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie Firmware
*
* Copyright (C) Bitcraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @file bootloader.c
* Functions to handle transitioning from the firmware to bootloader (DFU) mode on startup
*
*/

#include <stm32f4xx.h>

#include "bootloader.h"

#if 0
// bootloader code based from micropython machine_bootloader function

// STM32H7 has ECC and writes to RAM must be 64-bit so they are fully committed
// to actual SRAM before a system reset occurs.
#define BL_STATE_PTR ((uint64_t *) SRAM2_BASE) //start of 16kb SRAM bank in stm32f405
#define BL_STATE_KEY (0x5a5) //arbitrary bit pattern used as a marker
#define BL_STATE_KEY_MASK (0xfff)
#define BL_STATE_KEY_SHIFT (32)
#define BL_STATE_INVALID (0)
#define BL_STATE_VALID(reg, addr) ((uint64_t)(reg) | ((uint64_t)((addr) | BL_STATE_KEY)) << BL_STATE_KEY_SHIFT)
#define BL_STATE_GET_REG(s) ((s) & 0xffffffff)
#define BL_STATE_GET_KEY(s) (((s) >> BL_STATE_KEY_SHIFT) & BL_STATE_KEY_MASK)
#define BL_STATE_GET_ADDR(s) (((s) >> BL_STATE_KEY_SHIFT) & ~BL_STATE_KEY_MASK)


/**
* @brief Branch directly to the bootloader address, setting the
* stack pointer and destination address first.
* Based from the micropython machine_bootloader function.
*
* @param r0 The register to utilize
* @param bl_addr The bootloader address to jump to
*/
static void branch_to_bootloader(uint32_t r0, uint32_t bl_addr){
__asm volatile (
"ldr r2, [r1, #0]\n" // get address of stack pointer
"msr msp, r2\n" // get stack pointer
"ldr r2, [r1, #4]\n" // get address of destination
"bx r2\n" // branch to bootloader
);
//unreachable code
while(1);
}

void check_enter_bootloader(){
uint64_t bl_state = *BL_STATE_PTR;
//set to invalid for next boot
*BL_STATE_PTR = BL_STATE_INVALID;

if(BL_STATE_GET_KEY(bl_state) == BL_STATE_KEY && (RCC->CSR & RCC_CSR_SFTRSTF)){
//if botloader data valid and was just reset with NVIC_SystemReset

//remap memory to system flash
SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SystemFlash);
branch_to_bootloader(BL_STATE_GET_REG(bl_state), BL_STATE_GET_ADDR(bl_state));
}
}

void enter_bootloader(uint32_t r0, uint32_t bl_addr){
//set bootloader state values
*BL_STATE_PTR = BL_STATE_VALID(r0, bl_addr);

NVIC_SystemReset();
}
#endif
56 changes: 56 additions & 0 deletions crazyflie/test/bootloader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie Firmware
*
* Copyright (C) Bitcraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @file bootloader.h
* Functions to handle transitioning from the firmware to bootloader (DFU) mode on startup
*
*/

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Check if memory is set after software
* reboot indicating we need to branch to the bootloader.
* Run every time on startup.
*/
void check_enter_bootloader();

/**
* @brief Initiate the procedure to reboot into the bootloader.
*
* This function does not return, instead setting a flag to
* jump to the bootloader on the next start and
* issuing a software reset.
*
* @param r0 The register to utilize when jumping
* @param bl_addr The bootloader address to jump to
*/
void enter_bootloader(uint32_t r0, uint32_t bl_addr);

#ifdef __cplusplus
}
#endif
15 changes: 15 additions & 0 deletions crazyflie/test/test.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "bootloader.h"

void setup()
{
Serial.begin(115200);
}

void loop()
{
static uint32_t count = 0;

Serial.println(count++);

delay(1000);
}
23 changes: 23 additions & 0 deletions crazyflie/test/usb-bootloader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/python3

#send a USB request to the crazyflie, causing it to enter DFU mode (bootloader) automatically
#flash new firmware using 'make flash_dfu'

from time import sleep
import usb
import usb.core

#find connected crazyflie, usb vendor and product id = 0483:5740
dev = usb.core.find(idVendor=0x0483, idProduct=0x5740)
if dev is None:
raise ValueError('Could not find any USB connected crazyflie')

#send signal to enter bootloader
try:
dev.ctrl_transfer(bmRequestType=usb.TYPE_VENDOR,
bRequest=0x01, wValue=0x01, wIndex=2)
except IOError:
#io error expected because the crazyflie will not respond to USB request as it resets into the bootloader
#TODO usbd_cf_Setup function in firmware needs to return USBD_OK before rebooting to fix this
#sleep to allow time for crazyflie to get into DFU mode
sleep(0.5)

0 comments on commit 25cf79b

Please sign in to comment.