Just to get your thought process going, a basic delay function can be implemented by using a timer interrupt (Systick works fine) and sleep mode. The idea is that you start a timer that will count for the desired delay duration. While it is counting, the MCU can be put into Sleep mode ensuring no code is being executed. Once the timer goes off, the interrupt will wake up the MCU and resume code execution. You can then disable the timer and exit the delay function.