void WR_Handle_Comms(void)
{
    if (wrflags.header_rcvd) {
        if (wrflags.rx_packet_ready) {
            // New packet request received but
            // previous packet still not handled
            // TODO: Handle WRRXPacket Overflow
            return;
        }
        // Copy the header into the received packet buffer
        memcpy(&WRRXPacket, rx_data, SPI_HEADER_LEN);
        // Disable SPI interrupts to allow DMA to handle incoming/outgoing
        // packet
        disable_spi_interrupts();
        // Enable DMA Tx if payload length is zero, else enable DMA Rx
        if (rx_data[0] == 0x00) {
            if (wrflags.tx_packet_ready)
                enable_dma_tx(WRTXPacket.header.payload_length);
            else
                return;
            // Reset SPI module to clear FIFO buffers.
            // TODO: test for potential problems
            WR_SPI_STAT.SPIEN = 0;
            WR_SPI_STAT.SPIEN = 1;
            led = 0;
            WR_TX_DMAREQ.FORCE=1; // Force transfer of first byte
        }
        else {
            enable_dma_rx(((WRHeader *)&rx_data)->payload_length);
            // Reset SPI module to clear FIFO buffers.
            // TODO: test for potential problems
            WR_SPI_STAT.SPIEN = 0;
            WR_SPI_STAT.SPIEN = 1;
            WR_SPIBUF         = 0x00;
        }
        wrflags.DMA_Ready = 1;
        wrflags.header_rcvd = 0;
    }
    if (wrflags.dma_transfer_done) {
        // Transfer complete, re-enable everything.
        // Packet Handled in SD_PContinue()
        disable_dma_interrupts();
        if(!rx_data[0]) {
            while (!WR_SPI_STAT.SPIRBF) // IMP! Makes sure last transfer is complete.
            wrflags.tx_packet_ready = 0;
        }
        else
            wrflags.rx_packet_ready = 1;
        enable_spi_interrupts();
        wrflags.dma_transfer_done = 0;
    }
}
/* Cellular */
static void usart_device_init_3(size_t bits, size_t parity,
                                size_t stopBits, size_t baud)
{
        volatile struct usart_info* ui = usart_data + UART_TELEMETRY;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

        initGPIO(GPIOA, (GPIO_Pin_0 | GPIO_Pin_1));
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_UART4);
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_UART4);

        init_usart(ui->usart, bits, parity, stopBits, baud);

        enable_dma_rx(RCC_AHB1Periph_DMA1, DMA1_Stream2_IRQn,
                      DMA_IRQ_PRIORITY, DMA_IT_TC | DMA_IT_HT, ui);

        enable_dma_tx(RCC_AHB1Periph_DMA1, DMA1_Stream4_IRQn,
                      DMA_IRQ_PRIORITY, DMA_IT_TC, ui);
}
/* GPS */
static void usart_device_init_2(size_t bits, size_t parity,
                                size_t stopBits, size_t baud)
{
        volatile struct usart_info* ui = usart_data + UART_GPS;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

        initGPIO(GPIOD, (GPIO_Pin_5 | GPIO_Pin_6));
        GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_USART2);
        GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_USART2);

        init_usart(ui->usart, bits, parity, stopBits, baud);
        /* No TX DMA here becasue I2C is using that stream */
        enableRxTxIrq(ui->usart, USART2_IRQn, UART_GPS_IRQ_PRIORITY,
                      UART_TX_IRQ);

        enable_dma_rx(RCC_AHB1Periph_DMA1, DMA1_Stream5_IRQn,
                      DMA_IRQ_PRIORITY, DMA_IT_TC | DMA_IT_HT, ui);
}
/* Auxilary port */
static void usart_device_init_1(size_t bits, size_t parity,
                                size_t stopBits, size_t baud)
{
        volatile struct usart_info* ui = usart_data + UART_AUX;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

        initGPIO(GPIOD, (GPIO_Pin_8 | GPIO_Pin_9));
        GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_USART3);
        GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_USART3);

        init_usart(ui->usart, bits, parity, stopBits, baud);

        enable_dma_rx(RCC_AHB1Periph_DMA1, DMA1_Stream1_IRQn,
                      DMA_IRQ_PRIORITY, DMA_IT_TC | DMA_IT_HT, ui);

        enable_dma_tx(RCC_AHB1Periph_DMA1, DMA1_Stream3_IRQn,
                      DMA_IRQ_PRIORITY, DMA_IT_TC, ui);
}
/* Bluetooth */
static void usart_device_init_0(size_t bits, size_t parity,
                                size_t stopBits, size_t baud)
{
        volatile struct usart_info* ui = usart_data + UART_WIRELESS;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

        initGPIO(GPIOA, (GPIO_Pin_9 | GPIO_Pin_10));
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);

        init_usart(ui->usart, bits, parity, stopBits, baud);

        enable_dma_rx(RCC_AHB1Periph_DMA2, DMA2_Stream5_IRQn,
                      DMA_IRQ_PRIORITY, DMA_IT_TC | DMA_IT_HT, ui);

        enable_dma_tx(RCC_AHB1Periph_DMA1, DMA2_Stream7_IRQn,
                      DMA_IRQ_PRIORITY, DMA_IT_TC, ui);

}