Exemplo n.º 1
0
static OSStatus receive_bytes( platform_uart_driver_t* driver, void* data, uint32_t size, uint32_t timeout )
{
  OSStatus err = kNoErr;

  if ( driver->rx_buffer != NULL )
  {
    driver->peripheral->rx_dma_config.stream->CR |= DMA_SxCR_CIRC;
    
    // Enabled individual byte interrupts so progress can be updated
    USART_ClearITPendingBit( driver->peripheral->port, USART_IT_RXNE );
    USART_ITConfig( driver->peripheral->port, USART_IT_RXNE, ENABLE );
  }
  else
  {
    driver->rx_size = size;
    driver->peripheral->rx_dma_config.stream->CR &= ~(uint32_t) DMA_SxCR_CIRC;
  }
  
  clear_dma_interrupts( driver->peripheral->rx_dma_config.stream, driver->peripheral->rx_dma_config.complete_flags | driver->peripheral->rx_dma_config.error_flags );

  driver->peripheral->rx_dma_config.stream->NDTR  = size;
  driver->peripheral->rx_dma_config.stream->M0AR  = (uint32_t)data;
  driver->peripheral->rx_dma_config.stream->CR   |= DMA_SxCR_EN;
  USART_DMACmd( driver->peripheral->port, USART_DMAReq_Rx, ENABLE );
  
  if ( timeout > 0 )
  {
    err = mico_rtos_get_semaphore( &driver->rx_complete, timeout );
  }
  return err;
}
OSStatus host_platform_spi_transfer( bus_transfer_direction_t dir, uint8_t* buffer, uint16_t buffer_length )
{
    OSStatus result;
    uint32_t junk;

    platform_mcu_powersave_disable();

    wifi_spi.tx_dma.stream->NDTR = buffer_length;
    wifi_spi.tx_dma.stream->M0AR = (uint32_t) buffer;
    if ( dir == BUS_READ )
    {
        wifi_spi.rx_dma.stream->NDTR = buffer_length;
        wifi_spi.rx_dma.stream->M0AR = (uint32_t) buffer;
        wifi_spi.rx_dma.stream->CR  |= DMA_MemoryInc_Enable  | ( 1 << 4);
    }
    else
    {
        wifi_spi.rx_dma.stream->NDTR = buffer_length;
        wifi_spi.rx_dma.stream->M0AR = (uint32_t) &junk;
        wifi_spi.rx_dma.stream->CR &= ( ~DMA_MemoryInc_Enable ) | ( 1 << 4);
    }

    platform_gpio_output_low( &wifi_spi_pins[WIFI_PIN_SPI_CS] );
    DMA_Cmd( wifi_spi.rx_dma.stream, ENABLE );
    DMA_Cmd( wifi_spi.tx_dma.stream, ENABLE );

    /* Wait for DMA TX to complete */
    result = mico_rtos_get_semaphore( &spi_transfer_finished_semaphore, 100 );
//    loop_count = 0;
//    while ( ( DMA_GetFlagStatus( SPIX_DMA_RX_STREAM, DMA_FLAG_TCIF3 ) == RESET ) && ( loop_count < (uint32_t) DMA_TIMEOUT_LOOPS ) )
//    {
//        loop_count++;
//    }

    DMA_Cmd( wifi_spi.rx_dma.stream, DISABLE );
    DMA_Cmd( wifi_spi.tx_dma.stream, DISABLE );

    /* Clear the CS pin and the DMA status flag */
    platform_gpio_output_high( &wifi_spi_pins[WIFI_PIN_SPI_CS] ); /* CS high (to deselect) */
    clear_dma_interrupts( wifi_spi.rx_dma.stream, wifi_spi.rx_dma.complete_flags );
    clear_dma_interrupts( wifi_spi.tx_dma.stream, wifi_spi.tx_dma.complete_flags );

    platform_mcu_powersave_enable();

    return result;
}
Exemplo n.º 3
0
void platform_uart_rx_dma_irq( platform_uart_driver_t* driver )
{
    if ( ( get_dma_irq_status( driver->peripheral->rx_dma_config.stream ) & driver->peripheral->rx_dma_config.complete_flags ) != 0 )
    {
        clear_dma_interrupts( driver->peripheral->rx_dma_config.stream, driver->peripheral->rx_dma_config.complete_flags );
        driver->last_receive_result = kNoErr;
    }

    if ( ( get_dma_irq_status( driver->peripheral->rx_dma_config.stream ) & driver->peripheral->rx_dma_config.error_flags ) != 0 )
    {
        clear_dma_interrupts( driver->peripheral->rx_dma_config.stream, driver->peripheral->rx_dma_config.error_flags );
        driver->last_receive_result = kGeneralErr;
    }

    if ( driver->rx_size > 0 )
    {
        /* Set semaphore regardless of result to prevent waiting thread from locking up */
        mico_rtos_set_semaphore( &driver->rx_complete );
    }
}
Exemplo n.º 4
0
OSStatus platform_uart_transmit_bytes( platform_uart_driver_t* driver, const uint8_t* data_out, uint32_t size )
{
    OSStatus err = kNoErr;

    platform_mcu_powersave_disable();

#ifndef NO_MICO_RTOS
    mico_rtos_lock_mutex( &driver->tx_mutex );
#endif

    require_action_quiet( ( driver != NULL ) && ( data_out != NULL ) && ( size != 0 ), exit, err = kParamErr);

    /* Clear interrupt status before enabling DMA otherwise error occurs immediately */
    clear_dma_interrupts( driver->peripheral->tx_dma_config.stream, driver->peripheral->tx_dma_config.complete_flags | driver->peripheral->tx_dma_config.error_flags );

    /* Init DMA parameters and variables */
    driver->last_transmit_result                    = kGeneralErr;
    driver->tx_size                                 = size;
    driver->peripheral->tx_dma_config.stream->CR   &= ~(uint32_t) DMA_SxCR_CIRC;
    driver->peripheral->tx_dma_config.stream->NDTR  = size;
    driver->peripheral->tx_dma_config.stream->M0AR  = (uint32_t)data_out;

    USART_DMACmd( driver->peripheral->port, USART_DMAReq_Tx, ENABLE );
    USART_ClearFlag( driver->peripheral->port, USART_FLAG_TC );
    driver->peripheral->tx_dma_config.stream->CR   |= DMA_SxCR_EN;

    /* Wait for transmission complete */
#ifndef NO_MICO_RTOS
    mico_rtos_get_semaphore( &driver->tx_complete, MICO_NEVER_TIMEOUT );
#else
    while( driver->tx_complete == false );
    driver->tx_complete = false;
#endif

    while ( ( driver->peripheral->port->SR & USART_SR_TC ) == 0 )
    {
    }

    /* Disable DMA and clean up */
    USART_DMACmd( driver->peripheral->port, USART_DMAReq_Tx, DISABLE );
    driver->tx_size = 0;
    err = driver->last_transmit_result;

exit:
#ifndef NO_MICO_RTOS
    mico_rtos_unlock_mutex( &driver->tx_mutex );
#endif
    platform_mcu_powersave_enable();
    return err;
}
Exemplo n.º 5
0
void platform_uart_tx_dma_irq( platform_uart_driver_t* driver )
{
    if ( ( get_dma_irq_status( driver->peripheral->tx_dma_config.stream ) & driver->peripheral->tx_dma_config.complete_flags ) != 0 )
    {
        clear_dma_interrupts( driver->peripheral->tx_dma_config.stream, driver->peripheral->tx_dma_config.complete_flags );
        driver->last_transmit_result = kNoErr;
    }

    if ( ( get_dma_irq_status( driver->peripheral->tx_dma_config.stream ) & driver->peripheral->tx_dma_config.error_flags ) != 0 )
    {
        clear_dma_interrupts( driver->peripheral->tx_dma_config.stream, driver->peripheral->tx_dma_config.error_flags );
        driver->last_transmit_result = kGeneralErr;
    }

    if ( driver->tx_size > 0 )
    {
#ifndef NO_MICO_RTOS
        /* Set semaphore regardless of result to prevent waiting thread from locking up */
        mico_rtos_set_semaphore( &driver->tx_complete );
#else
        driver->tx_complete = true;
#endif
    }
}
Exemplo n.º 6
0
static OSStatus receive_bytes( platform_uart_driver_t* driver, void* data, uint32_t size, uint32_t timeout )
{
    OSStatus err = kNoErr;

    if ( driver->rx_buffer != NULL )
    {
        driver->peripheral->rx_dma_config.stream->CR |= DMA_SxCR_CIRC;

        // Enabled individual byte interrupts so progress can be updated
        USART_ClearITPendingBit( driver->peripheral->port, USART_IT_RXNE );
        USART_ITConfig( driver->peripheral->port, USART_IT_RXNE, ENABLE );
    }
    else
    {
        driver->rx_size = size;
        driver->peripheral->rx_dma_config.stream->CR &= ~(uint32_t) DMA_SxCR_CIRC;
    }

    clear_dma_interrupts( driver->peripheral->rx_dma_config.stream, driver->peripheral->rx_dma_config.complete_flags | driver->peripheral->rx_dma_config.error_flags );

    driver->peripheral->rx_dma_config.stream->NDTR  = size;
    driver->peripheral->rx_dma_config.stream->M0AR  = (uint32_t)data;
    driver->peripheral->rx_dma_config.stream->CR   |= DMA_SxCR_EN;
    USART_DMACmd( driver->peripheral->port, USART_DMAReq_Rx, ENABLE );

    if ( timeout > 0 )
    {
#ifndef NO_MICO_RTOS
        err = mico_rtos_get_semaphore( &driver->rx_complete, timeout );
#else
        driver->rx_complete = false;
        int delay_start = mico_get_time_no_os();
        while( driver->rx_complete == false ) {
            if(mico_get_time_no_os() >= delay_start + timeout && timeout != MICO_NEVER_TIMEOUT) {
                err = kTimeoutErr;
                goto exit;
            }
        }
#endif
    }
exit:
    return err;
}
Exemplo n.º 7
0
OSStatus platform_uart_init( platform_uart_driver_t* driver, const platform_uart_t* peripheral, const platform_uart_config_t* config, ring_buffer_t* optional_ring_buffer )
{
    DMA_InitTypeDef   dma_init_structure;
    USART_InitTypeDef uart_init_structure;
    uint32_t          uart_number;
    OSStatus          err = kNoErr;

    platform_mcu_powersave_disable();

    require_action_quiet( ( driver != NULL ) && ( peripheral != NULL ) && ( config != NULL ), exit, err = kParamErr);
    require_action_quiet( (optional_ring_buffer == NULL) || ((optional_ring_buffer->buffer != NULL ) && (optional_ring_buffer->size != 0)), exit, err = kParamErr);

    uart_number = platform_uart_get_port_number( peripheral->port );

    driver->rx_size              = 0;
    driver->tx_size              = 0;
    driver->last_transmit_result = kNoErr;
    driver->last_receive_result  = kNoErr;
    driver->peripheral           = (platform_uart_t*)peripheral;
#ifndef NO_MICO_RTOS
    mico_rtos_init_semaphore( &driver->tx_complete, 1 );
    mico_rtos_init_semaphore( &driver->rx_complete, 1 );
    mico_rtos_init_semaphore( &driver->sem_wakeup,  1 );
    mico_rtos_init_mutex    ( &driver->tx_mutex );
#else
    driver->tx_complete = false;
    driver->rx_complete = false;
#endif

    /* Configure TX and RX pin_mapping */
    platform_gpio_set_alternate_function( peripheral->pin_tx->port, peripheral->pin_tx->pin_number, GPIO_OType_PP, GPIO_PuPd_NOPULL, uart_alternate_functions[ uart_number ] );
    platform_gpio_set_alternate_function( peripheral->pin_rx->port, peripheral->pin_rx->pin_number, GPIO_OType_PP, GPIO_PuPd_NOPULL, uart_alternate_functions[ uart_number ] );

    if ( ( peripheral->pin_cts != NULL ) && ( config->flow_control == FLOW_CONTROL_CTS || config->flow_control == FLOW_CONTROL_CTS_RTS ) )
    {
        platform_gpio_set_alternate_function( peripheral->pin_cts->port, peripheral->pin_cts->pin_number, GPIO_OType_PP, GPIO_PuPd_NOPULL, uart_alternate_functions[ uart_number ] );
    }

    if ( ( peripheral->pin_rts != NULL ) && ( config->flow_control == FLOW_CONTROL_RTS || config->flow_control == FLOW_CONTROL_CTS_RTS ) )
    {
        platform_gpio_set_alternate_function( peripheral->pin_rts->port, peripheral->pin_rts->pin_number, GPIO_OType_PP, GPIO_PuPd_NOPULL, uart_alternate_functions[ uart_number ] );
    }

#ifndef NO_MICO_RTOS
    if(config->flags & UART_WAKEUP_ENABLE) {
        mico_rtos_init_semaphore( driver->sem_wakeup, 1 );
        mico_rtos_create_thread(NULL, MICO_APPLICATION_PRIORITY, "UART_WAKEUP", thread_wakeup, 0x100, driver);
    }
#endif

    /* Enable UART peripheral clock */
    uart_peripheral_clock_functions[ uart_number ]( uart_peripheral_clocks[ uart_number ], ENABLE );

    uart_init_structure.USART_Mode       = USART_Mode_Rx | USART_Mode_Tx;
    uart_init_structure.USART_BaudRate   = config->baud_rate;
    uart_init_structure.USART_WordLength = ( ( config->data_width == DATA_WIDTH_9BIT ) || ( ( config->data_width == DATA_WIDTH_8BIT ) && ( config->parity != NO_PARITY ) ) ) ? USART_WordLength_9b : USART_WordLength_8b;
    uart_init_structure.USART_StopBits   = ( config->stop_bits == STOP_BITS_1 ) ? USART_StopBits_1 : USART_StopBits_2;

    switch ( config->parity )
    {
    case NO_PARITY:
        uart_init_structure.USART_Parity = USART_Parity_No;
        break;

    case EVEN_PARITY:
        uart_init_structure.USART_Parity = USART_Parity_Even;
        break;

    case ODD_PARITY:
        uart_init_structure.USART_Parity = USART_Parity_Odd;
        break;

    default:
        err = kParamErr;
        goto exit;
    }

    switch ( config->flow_control )
    {
    case FLOW_CONTROL_DISABLED:
        uart_init_structure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        break;

    case FLOW_CONTROL_CTS:
        uart_init_structure.USART_HardwareFlowControl = USART_HardwareFlowControl_CTS;
        break;

    case FLOW_CONTROL_RTS:
        uart_init_structure.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS;
        break;

    case FLOW_CONTROL_CTS_RTS:
        uart_init_structure.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS;
        break;

    default:
        err = kParamErr;
        goto exit;
    }


    /* Initialise USART peripheral */
    USART_DeInit( peripheral->port );
    USART_Init( peripheral->port, &uart_init_structure );

    /**************************************************************************
    * Initialise STM32 DMA registers
    * Note: If DMA is used, USART interrupt isn't enabled.
    **************************************************************************/
    /* Enable DMA peripheral clock */
    if ( peripheral->tx_dma_config.controller == DMA1 )
    {
        RCC->AHB1ENR |= RCC_AHB1Periph_DMA1;
    }
    else
    {
        RCC->AHB1ENR |= RCC_AHB1Periph_DMA2;
    }

    /* Fill init structure with common DMA settings */
    dma_init_structure.DMA_PeripheralInc   = DMA_PeripheralInc_Disable;
    dma_init_structure.DMA_MemoryInc       = DMA_MemoryInc_Enable;
    dma_init_structure.DMA_Priority        = DMA_Priority_VeryHigh;
    dma_init_structure.DMA_FIFOMode        = DMA_FIFOMode_Disable;
    dma_init_structure.DMA_FIFOThreshold   = DMA_FIFOThreshold_Full;
    dma_init_structure.DMA_MemoryBurst     = DMA_MemoryBurst_Single;
    dma_init_structure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

    if ( config->data_width == DATA_WIDTH_9BIT )
    {
        dma_init_structure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
        dma_init_structure.DMA_MemoryDataSize     = DMA_MemoryDataSize_HalfWord;
    }
    else
    {
        dma_init_structure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
        dma_init_structure.DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte;
    }

    /* Initialise TX DMA */
    DMA_DeInit( peripheral->tx_dma_config.stream );
    dma_init_structure.DMA_Channel            = peripheral->tx_dma_config.channel;
    dma_init_structure.DMA_PeripheralBaseAddr = (uint32_t) &peripheral->port->DR;
    dma_init_structure.DMA_Memory0BaseAddr    = (uint32_t) 0;
    dma_init_structure.DMA_DIR                = DMA_DIR_MemoryToPeripheral;
    dma_init_structure.DMA_BufferSize         = 0xFFFF;                     // This parameter will be configured during communication
    dma_init_structure.DMA_Mode               = DMA_Mode_Normal;
    DMA_Init( peripheral->tx_dma_config.stream, &dma_init_structure );

    /* Initialise RX DMA */
    DMA_DeInit( peripheral->rx_dma_config.stream );
    dma_init_structure.DMA_Channel            = peripheral->rx_dma_config.channel;
    dma_init_structure.DMA_PeripheralBaseAddr = (uint32_t) &peripheral->port->DR;
    dma_init_structure.DMA_Memory0BaseAddr    = (uint32_t) 0;
    dma_init_structure.DMA_DIR                = DMA_DIR_PeripheralToMemory;
    dma_init_structure.DMA_BufferSize         = 0xFFFF;                     // This parameter will be configured during communication
    dma_init_structure.DMA_Mode               = DMA_Mode_Normal;
    DMA_Init( peripheral->rx_dma_config.stream, &dma_init_structure );

    /**************************************************************************
    * Initialise STM32 DMA interrupts
    **************************************************************************/

    /* Configure TX DMA interrupt on Cortex-M3 */
    NVIC_EnableIRQ( peripheral->tx_dma_config.irq_vector );

    /* Enable TC (transfer complete) and TE (transfer error) interrupts on source */
    clear_dma_interrupts( peripheral->tx_dma_config.stream, peripheral->tx_dma_config.complete_flags | peripheral->tx_dma_config.error_flags );
    DMA_ITConfig( peripheral->tx_dma_config.stream, DMA_INTERRUPT_FLAGS, ENABLE );

    /* Enable USART interrupt vector in Cortex-M3 */
    NVIC_EnableIRQ( uart_irq_vectors[uart_number] );
    USART_DMACmd( driver->peripheral->port, USART_DMAReq_Tx, DISABLE );

    /* Enable USART */
    USART_Cmd( peripheral->port, ENABLE );

    /* Enable both transmit and receive */
    peripheral->port->CR1 |= USART_CR1_TE;
    peripheral->port->CR1 |= USART_CR1_RE;

    /* Setup ring buffer */
    if ( optional_ring_buffer != NULL )
    {
        /* Note that the ring_buffer should've been initialised first */
        driver->rx_buffer = optional_ring_buffer;
        driver->rx_size   = 0;
        receive_bytes( driver, optional_ring_buffer->buffer, optional_ring_buffer->size, 0 );
    }
    else
    {
        /* Not using ring buffer. Configure RX DMA interrupt on Cortex-M3 */
        NVIC_EnableIRQ( peripheral->rx_dma_config.irq_vector );

        /* Enable TC (transfer complete) and TE (transfer error) interrupts on source */
        clear_dma_interrupts( peripheral->rx_dma_config.stream, peripheral->rx_dma_config.complete_flags | peripheral->rx_dma_config.error_flags );
        DMA_ITConfig( peripheral->rx_dma_config.stream, DMA_INTERRUPT_FLAGS, ENABLE );
    }

exit:
    MicoMcuPowerSaveConfig(true);
    return err;
}
void platform_wifi_spi_rx_dma_irq( void )
{
    /* Clear interrupt */
    clear_dma_interrupts( wifi_spi.rx_dma.stream, wifi_spi.rx_dma.complete_flags );
    mico_rtos_set_semaphore( &spi_transfer_finished_semaphore );
}