diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8ebf0c4..492d498 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Added
- DelayUs and DelayMs trait implementations for timer
+- SPI implementation for blocking API
## [0.2.1]
diff --git a/examples/spi.rs b/examples/spi.rs
new file mode 100644
index 0000000..e714a6e
--- /dev/null
+++ b/examples/spi.rs
@@ -0,0 +1,175 @@
+//! SPI example application
+#![no_main]
+#![no_std]
+
+use core::cell::RefCell;
+
+use cortex_m_rt::entry;
+use embedded_hal::spi::{Mode, MODE_0};
+use panic_rtt_target as _;
+use rtt_target::{rprintln, rtt_init_print};
+use va108xx_hal::{
+ gpio::{PinsA, PinsB},
+ pac::{self, SPIA, SPIB},
+ prelude::*,
+ spi::{self, NoneT, Spi, SpiBase, TransferConfig},
+ timer::CountDownTimer,
+};
+
+#[derive(PartialEq, Debug)]
+pub enum ExampleSelect {
+ // Enter loopback mode. It is not necessary to tie MOSI/MISO together for this
+ Loopback,
+ // Send a test buffer and print everything received
+ TestBuffer,
+}
+
+#[derive(PartialEq, Debug)]
+pub enum SpiBusSelect {
+ SpiAPortA,
+ SpiAPortB,
+ SpiBPortB,
+}
+
+const EXAMPLE_SEL: ExampleSelect = ExampleSelect::Loopback;
+const SPI_BUS_SEL: SpiBusSelect = SpiBusSelect::SpiBPortB;
+const SPI_SPEED_KHZ: u32 = 1000;
+const SPI_MODE: Mode = MODE_0;
+const BLOCKMODE: bool = false;
+
+#[entry]
+fn main() -> ! {
+ rtt_init_print!();
+ rprintln!("-- VA108xx SPI example application--");
+ let mut dp = pac::Peripherals::take().unwrap();
+
+ let spia_ref: RefCell