/// Callback for the event that is triggered when an SPI request is added to the queue. extern "C" fn spi_event_callback(_event: *mut os::os_event) { loop { // For each mbuf chain found... // Get the next SPI request, stored as an mbuf chain. let om = unsafe { os::os_mqueue_get(&mut SPI_DATA_QUEUE) }; if om.is_null() { break; } // Send the mbuf chain. let mut m = om; let mut first_byte = true; while !m.is_null() { // For each mbuf in the chain... let data = unsafe { (*m).om_data }; // Fetch the data let len = unsafe { (*m).om_len }; // Fetch the length if first_byte { // First byte of the mbuf chain is always Command Byte first_byte = false; // Write the Command Byte. internal_spi_noblock_write( unsafe { core::mem::transmute(data) }, 1 as i32, // Write 1 Command Byte true ).expect("int spi fail"); // These commands require a delay. TODO: Move to caller if unsafe { *data } == 0x01 || // SWRESET unsafe { *data } == 0x11 || // SLPOUT unsafe { *data } == 0x29 { // DISPON delay_ms(200); } // Then write the Data Bytes. internal_spi_noblock_write( unsafe { core::mem::transmute(data.add(1)) }, (len - 1) as i32, // Then write 0 or more Data Bytes false ).expect("int spi fail"); } else { // Second and subsequently mbufs in the chain are all Data Bytes // Write the Data Bytes. internal_spi_noblock_write( unsafe { core::mem::transmute(data) }, len as i32, // Write all Data Bytes false ).expect("int spi fail"); } m = unsafe { (*m).om_next.sle_next }; // Fetch next mbuf in the chain. } // Free the entire mbuf chain. unsafe { os::os_mbuf_free_chain(om) }; // Release the throttle semaphore to allow next request to be queued. let rc = unsafe { os::os_sem_release(&mut SPI_THROTTLE_SEM) }; assert_eq!(rc, 0, "sem fail"); } }