mirror of
https://github.com/oopuuu/zTC1.git
synced 2025-12-17 15:38:14 +08:00
修改了Web后台的部分界面,增加了HAmqtt中的总电量传感器,后台新增mqtt上报频率设置
This commit is contained in:
656
mico-os/platform/MCU/ATSAMG55/wlan_bus_driver/wlan_bus_SDIO.c
Normal file
656
mico-os/platform/MCU/ATSAMG55/wlan_bus_driver/wlan_bus_SDIO.c
Normal file
@@ -0,0 +1,656 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file wlan_bus_sdio.h
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 16-Sep-2014
|
||||
* @brief This file provides bus communication functions with Wi-Fi RF chip.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "MicoRtos.h"
|
||||
#include "misc.h"
|
||||
#include "string.h" /* For memcpy */
|
||||
#include "platform.h"
|
||||
#include "platform_config.h"
|
||||
#include "platform_peripheral.h"
|
||||
#include "platform_logging.h"
|
||||
#include "wlan_platform_common.h"
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
|
||||
#define COMMAND_FINISHED_CMD52_TIMEOUT_LOOPS (100000)
|
||||
#define COMMAND_FINISHED_CMD53_TIMEOUT_LOOPS (100000)
|
||||
#define SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS (100000)
|
||||
#define SDIO_DMA_TIMEOUT_LOOPS (1000000)
|
||||
#define MAX_TIMEOUTS (30)
|
||||
#define SDIO_ERROR_MASK ( SDIO_STA_CCRCFAIL | SDIO_STA_DCRCFAIL | SDIO_STA_CTIMEOUT | SDIO_STA_DTIMEOUT | SDIO_STA_TXUNDERR | SDIO_STA_RXOVERR | SDIO_STA_STBITERR )
|
||||
#define SDIO_IRQ_CHANNEL ((IRQn_Type)0x31)
|
||||
#define DMA2_3_IRQ_CHANNEL ((IRQn_Type)DMA2_Stream3_IRQn)
|
||||
#define BUS_LEVEL_MAX_RETRIES (5)
|
||||
#define SDIO_ENUMERATION_TIMEOUT_MS (500)
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/*@shared@*/ /*@null@*/ uint8_t* data;
|
||||
uint16_t length;
|
||||
} sdio_dma_segment_t;
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
/**
|
||||
* Transfer direction for the mico platform bus interface
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
/* If updating this enum, the bus_direction_mapping variable will also need to be updated */
|
||||
BUS_READ,
|
||||
BUS_WRITE
|
||||
} bus_transfer_direction_t;
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
static const uint32_t bus_direction_mapping[] =
|
||||
{
|
||||
[BUS_READ] = SDIO_TransferDir_ToSDIO,
|
||||
[BUS_WRITE] = SDIO_TransferDir_ToCard
|
||||
};
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/*
|
||||
* SDIO specific constants
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
SDIO_CMD_0 = 0,
|
||||
SDIO_CMD_3 = 3,
|
||||
SDIO_CMD_5 = 5,
|
||||
SDIO_CMD_7 = 7,
|
||||
SDIO_CMD_52 = 52,
|
||||
SDIO_CMD_53 = 53,
|
||||
__MAX_VAL = 64
|
||||
} sdio_command_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SDIO_BLOCK_MODE = ( 0 << 2 ), /* These are STM32 implementation specific */
|
||||
SDIO_BYTE_MODE = ( 1 << 2 ) /* These are STM32 implementation specific */
|
||||
} sdio_transfer_mode_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SDIO_1B_BLOCK = 1,
|
||||
SDIO_2B_BLOCK = 2,
|
||||
SDIO_4B_BLOCK = 4,
|
||||
SDIO_8B_BLOCK = 8,
|
||||
SDIO_16B_BLOCK = 16,
|
||||
SDIO_32B_BLOCK = 32,
|
||||
SDIO_64B_BLOCK = 64,
|
||||
SDIO_128B_BLOCK = 128,
|
||||
SDIO_256B_BLOCK = 256,
|
||||
SDIO_512B_BLOCK = 512,
|
||||
SDIO_1024B_BLOCK = 1024,
|
||||
SDIO_2048B_BLOCK = 2048
|
||||
} sdio_block_size_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RESPONSE_NEEDED,
|
||||
NO_RESPONSE
|
||||
} sdio_response_needed_t;
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Variables
|
||||
******************************************************/
|
||||
|
||||
static uint8_t temp_dma_buffer[2*1024];
|
||||
static uint8_t* user_data;
|
||||
static uint32_t user_data_size;
|
||||
static uint8_t* dma_data_source;
|
||||
static uint32_t dma_transfer_size;
|
||||
static mico_semaphore_t sdio_transfer_finished_semaphore;
|
||||
static bool sdio_transfer_failed;
|
||||
static bus_transfer_direction_t current_transfer_direction;
|
||||
static uint32_t current_command;
|
||||
/******************************************************
|
||||
* Function declarations
|
||||
******************************************************/
|
||||
|
||||
static uint32_t sdio_get_blocksize_dctrl ( sdio_block_size_t block_size );
|
||||
static sdio_block_size_t find_optimal_block_size ( uint32_t data_size );
|
||||
static void sdio_prepare_data_transfer ( bus_transfer_direction_t direction, sdio_block_size_t block_size, /*@unique@*/ uint8_t* data, uint16_t data_size ) /*@modifies dma_data_source, user_data, user_data_size, dma_transfer_size@*/;
|
||||
|
||||
void dma_irq ( void );
|
||||
OSStatus host_platform_sdio_transfer( bus_transfer_direction_t direction, sdio_command_t command, sdio_transfer_mode_t mode, sdio_block_size_t block_size, uint32_t argument, /*@null@*/ uint32_t* data, uint16_t data_size, sdio_response_needed_t response_expected, /*@out@*/ /*@null@*/ uint32_t* response );
|
||||
extern void wlan_notify_irq( void );
|
||||
|
||||
/******************************************************
|
||||
* Function definitions
|
||||
******************************************************/
|
||||
|
||||
#if !(defined (MICO_DISABLE_MCU_POWERSAVE)) && !(defined (SDIO_1_BIT)) //SDIO 4 Bit mode and enable MCU powersave, need an OOB interrupt
|
||||
static void sdio_oob_irq_handler( void* arg )
|
||||
{
|
||||
UNUSED_PARAMETER(arg);
|
||||
platform_mcu_powersave_exit_notify( );
|
||||
wlan_notify_irq( );
|
||||
}
|
||||
|
||||
OSStatus host_enable_oob_interrupt( void )
|
||||
{
|
||||
platform_gpio_init( &wifi_sdio_pins[WIFI_PIN_SDIO_OOB_IRQ], INPUT_HIGH_IMPEDANCE );
|
||||
platform_gpio_irq_enable( &wifi_sdio_pins[WIFI_PIN_SDIO_OOB_IRQ], IRQ_TRIGGER_RISING_EDGE, sdio_oob_irq_handler, 0 );
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
uint8_t host_platform_get_oob_interrupt_pin( void )
|
||||
{
|
||||
return MICO_WIFI_OOB_IRQ_GPIO_PIN;
|
||||
}
|
||||
|
||||
#elif defined (MICO_DISABLE_MCU_POWERSAVE) && !(defined (SDIO_1_BIT)) //SDIO 4 Bit mode and disable MCU powersave, do not need OOB interrupt
|
||||
|
||||
OSStatus host_enable_oob_interrupt( void )
|
||||
{
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
uint8_t host_platform_get_oob_interrupt_pin( void )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SDIO_1_BIT
|
||||
static void sdio_int_pin_irq_handler( void* arg ) //SDIO 1 Bit mode
|
||||
{
|
||||
UNUSED_PARAMETER(arg);
|
||||
platform_mcu_powersave_exit_notify( );
|
||||
wlan_notify_irq( );
|
||||
}
|
||||
|
||||
bool host_platform_is_sdio_int_asserted(void)
|
||||
{
|
||||
if ( platform_gpio_input_get( &wifi_sdio_pins[WIFI_PIN_SDIO_IRQ] ) == true) //SDIO INT pin is high
|
||||
return false;
|
||||
else
|
||||
return true; // SDIO D1 is low, data need read
|
||||
}
|
||||
|
||||
OSStatus host_enable_oob_interrupt( void )
|
||||
{
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void sdio_enable_bus_irq( void )
|
||||
{
|
||||
SDIO->MASK = SDIO_MASK_SDIOITIE | SDIO_MASK_CMDRENDIE | SDIO_MASK_CMDSENTIE;
|
||||
}
|
||||
|
||||
static void sdio_disable_bus_irq( void )
|
||||
{
|
||||
SDIO->MASK = 0;
|
||||
}
|
||||
|
||||
|
||||
void sdio_irq( void )
|
||||
{
|
||||
uint32_t intstatus = SDIO->STA;
|
||||
|
||||
if ( ( intstatus & ( SDIO_STA_CCRCFAIL | SDIO_STA_DCRCFAIL | SDIO_STA_TXUNDERR | SDIO_STA_RXOVERR | SDIO_STA_STBITERR )) != 0 )
|
||||
{
|
||||
sdio_transfer_failed = true;
|
||||
SDIO->ICR = (uint32_t) 0xffffffff;
|
||||
mico_rtos_set_semaphore( &sdio_transfer_finished_semaphore );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((intstatus & (SDIO_STA_CMDREND | SDIO_STA_CMDSENT)) != 0)
|
||||
{
|
||||
if ( ( SDIO->RESP1 & 0x800 ) != 0 )
|
||||
{
|
||||
sdio_transfer_failed = true;
|
||||
mico_rtos_set_semaphore( &sdio_transfer_finished_semaphore );
|
||||
}
|
||||
else if (current_command == SDIO_CMD_53)
|
||||
{
|
||||
if (current_transfer_direction == BUS_WRITE)
|
||||
{
|
||||
DMA2_Stream3->CR = DMA_DIR_MemoryToPeripheral |
|
||||
DMA_Channel_4 | DMA_PeripheralInc_Disable | DMA_MemoryInc_Enable |
|
||||
DMA_PeripheralDataSize_Word | DMA_MemoryDataSize_Word |
|
||||
DMA_Mode_Normal | DMA_Priority_VeryHigh |
|
||||
DMA_MemoryBurst_INC4 | DMA_PeripheralBurst_INC4 | DMA_SxCR_PFCTRL | DMA_SxCR_EN | DMA_SxCR_TCIE;
|
||||
}
|
||||
else
|
||||
{
|
||||
DMA2_Stream3->CR = DMA_DIR_PeripheralToMemory |
|
||||
DMA_Channel_4 | DMA_PeripheralInc_Disable | DMA_MemoryInc_Enable |
|
||||
DMA_PeripheralDataSize_Word | DMA_MemoryDataSize_Word |
|
||||
DMA_Mode_Normal | DMA_Priority_VeryHigh |
|
||||
DMA_MemoryBurst_INC4 | DMA_PeripheralBurst_INC4 | DMA_SxCR_PFCTRL | DMA_SxCR_EN | DMA_SxCR_TCIE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear all command/response interrupts */
|
||||
SDIO->ICR = (SDIO_STA_CMDREND | SDIO_STA_CMDSENT);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef SDIO_1_BIT
|
||||
/* Check whether the external interrupt was triggered */
|
||||
if ( ( intstatus & SDIO_STA_SDIOIT ) != 0 )
|
||||
{
|
||||
/* Clear the interrupt and then inform MiCO thread */
|
||||
SDIO->ICR = SDIO_ICR_SDIOITC;
|
||||
platform_mcu_powersave_exit_notify( );
|
||||
wlan_notify_irq( );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*@-exportheader@*/ /* Function picked up by linker script */
|
||||
void dma_irq( void )
|
||||
{
|
||||
OSStatus result;
|
||||
|
||||
/* Clear interrupt */
|
||||
DMA2->LIFCR = (uint32_t) (0x3F << 22);
|
||||
|
||||
result = mico_rtos_set_semaphore( &sdio_transfer_finished_semaphore );
|
||||
|
||||
/* check result if in debug mode */
|
||||
check_string(result == kNoErr, "failed to set dma semaphore" );
|
||||
|
||||
/*@-noeffect@*/
|
||||
(void) result; /* ignore result if in release mode */
|
||||
/*@+noeffect@*/
|
||||
}
|
||||
/*@+exportheader@*/
|
||||
|
||||
OSStatus host_platform_bus_init( void )
|
||||
{
|
||||
SDIO_InitTypeDef sdio_init_structure;
|
||||
OSStatus result;
|
||||
uint8_t a;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
result = mico_rtos_init_semaphore( &sdio_transfer_finished_semaphore, 1 );
|
||||
if ( result != kNoErr )
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Turn on SDIO IRQ */
|
||||
SDIO->ICR = (uint32_t) 0xffffffff;
|
||||
|
||||
/* Must be lower priority than the value of configMAX_SYSCALL_INTERRUPT_PRIORITY */
|
||||
/* otherwise FreeRTOS will not be able to mask the interrupt */
|
||||
/* keep in mind that ARMCM3 interrupt priority logic is inverted, the highest value */
|
||||
/* is the lowest priority */
|
||||
NVIC_EnableIRQ( SDIO_IRQ_CHANNEL );
|
||||
NVIC_EnableIRQ( DMA2_3_IRQ_CHANNEL );
|
||||
|
||||
/* Set GPIO_B[1:0] to 00 to put WLAN module into SDIO mode */
|
||||
#if defined ( MICO_WIFI_USE_GPIO_FOR_BOOTSTRAP )
|
||||
platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0], OUTPUT_PUSH_PULL );
|
||||
platform_gpio_output_low( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0] );
|
||||
platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1], OUTPUT_PUSH_PULL );
|
||||
platform_gpio_output_low( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1] );
|
||||
#endif
|
||||
|
||||
/* Setup GPIO pins for SDIO data & clock */
|
||||
for ( a = WIFI_PIN_SDIO_CLK; a < WIFI_PIN_SDIO_MAX; a++ )
|
||||
{
|
||||
platform_gpio_set_alternate_function( wifi_sdio_pins[ a ].port, wifi_sdio_pins[ a ].pin_number, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SDIO );
|
||||
}
|
||||
|
||||
#ifdef SDIO_1_BIT
|
||||
platform_gpio_init( &wifi_sdio_pins[WIFI_PIN_SDIO_IRQ], INPUT_PULL_UP );
|
||||
platform_gpio_irq_enable( &wifi_sdio_pins[WIFI_PIN_SDIO_IRQ], IRQ_TRIGGER_FALLING_EDGE, sdio_int_pin_irq_handler, 0 );
|
||||
#endif
|
||||
|
||||
/*!< Enable the SDIO AHB Clock and the DMA2 Clock */
|
||||
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_DMA2, ENABLE );
|
||||
RCC_APB2PeriphClockCmd( RCC_APB2Periph_SDIO, ENABLE );
|
||||
|
||||
SDIO_DeInit( );
|
||||
sdio_init_structure.SDIO_ClockDiv = (uint8_t) 120; /* 0x78, clock is taken from the high speed APB bus ; */ /* About 400KHz */
|
||||
sdio_init_structure.SDIO_ClockEdge = SDIO_ClockEdge_Rising;
|
||||
sdio_init_structure.SDIO_ClockBypass = SDIO_ClockBypass_Disable;
|
||||
sdio_init_structure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Enable;
|
||||
sdio_init_structure.SDIO_BusWide = SDIO_BusWide_1b;
|
||||
sdio_init_structure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable;
|
||||
SDIO_Init( &sdio_init_structure );
|
||||
SDIO_SetPowerState( SDIO_PowerState_ON );
|
||||
SDIO_SetSDIOReadWaitMode( SDIO_ReadWaitMode_CLK );
|
||||
SDIO_ClockCmd( ENABLE );
|
||||
|
||||
platform_mcu_powersave_enable();
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus host_platform_sdio_enumerate( void )
|
||||
{
|
||||
OSStatus result;
|
||||
uint32_t loop_count;
|
||||
uint32_t data = 0;
|
||||
|
||||
loop_count = 0;
|
||||
do
|
||||
{
|
||||
/* Send CMD0 to set it to idle state */
|
||||
host_platform_sdio_transfer( BUS_WRITE, SDIO_CMD_0, SDIO_BYTE_MODE, SDIO_1B_BLOCK, 0, 0, 0, NO_RESPONSE, NULL );
|
||||
|
||||
/* CMD5. */
|
||||
host_platform_sdio_transfer( BUS_READ, SDIO_CMD_5, SDIO_BYTE_MODE, SDIO_1B_BLOCK, 0, 0, 0, NO_RESPONSE, NULL );
|
||||
|
||||
/* Send CMD3 to get RCA. */
|
||||
result = host_platform_sdio_transfer( BUS_READ, SDIO_CMD_3, SDIO_BYTE_MODE, SDIO_1B_BLOCK, 0, 0, 0, RESPONSE_NEEDED, &data );
|
||||
loop_count++;
|
||||
if ( loop_count >= (uint32_t) SDIO_ENUMERATION_TIMEOUT_MS )
|
||||
{
|
||||
return kTimeoutErr;
|
||||
}
|
||||
} while ( ( result != kNoErr ) && ( mico_thread_msleep( (uint32_t) 1 ), ( 1 == 1 ) ) );
|
||||
/* If you're stuck here, check the platform matches your hardware */
|
||||
|
||||
/* Send CMD7 with the returned RCA to select the card */
|
||||
host_platform_sdio_transfer( BUS_WRITE, SDIO_CMD_7, SDIO_BYTE_MODE, SDIO_1B_BLOCK, data, 0, 0, RESPONSE_NEEDED, NULL );
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus host_platform_bus_deinit( void )
|
||||
{
|
||||
OSStatus result;
|
||||
uint32_t a;
|
||||
|
||||
result = mico_rtos_deinit_semaphore( &sdio_transfer_finished_semaphore );
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
/* Disable SPI and SPI DMA */
|
||||
sdio_disable_bus_irq( );
|
||||
SDIO_ClockCmd( DISABLE );
|
||||
SDIO_SetPowerState( SDIO_PowerState_OFF );
|
||||
SDIO_DeInit( );
|
||||
RCC_APB2PeriphClockCmd( RCC_APB2Periph_SDIO, DISABLE );
|
||||
|
||||
#ifdef SDIO_1_BIT
|
||||
platform_gpio_deinit( &wifi_sdio_pins[WIFI_PIN_SDIO_IRQ] );
|
||||
platform_gpio_irq_disable( &wifi_sdio_pins[WIFI_PIN_SDIO_IRQ] );
|
||||
#endif
|
||||
|
||||
for ( a = 0; a < WIFI_PIN_SDIO_MAX; a++ )
|
||||
{
|
||||
platform_gpio_deinit( &wifi_sdio_pins[ a ] );
|
||||
}
|
||||
|
||||
#if defined ( MICO_WIFI_USE_GPIO_FOR_BOOTSTRAP )
|
||||
platform_gpio_deinit( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0] );
|
||||
platform_gpio_deinit( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1] );
|
||||
#endif
|
||||
|
||||
/* Turn off SDIO IRQ */
|
||||
NVIC_DisableIRQ( SDIO_IRQ_CHANNEL );
|
||||
NVIC_DisableIRQ( DMA2_3_IRQ_CHANNEL );
|
||||
|
||||
platform_mcu_powersave_enable();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
OSStatus host_platform_sdio_transfer( bus_transfer_direction_t direction, sdio_command_t command, sdio_transfer_mode_t mode, sdio_block_size_t block_size, uint32_t argument, /*@null@*/ uint32_t* data, uint16_t data_size, sdio_response_needed_t response_expected, /*@out@*/ /*@null@*/ uint32_t* response )
|
||||
{
|
||||
uint32_t loop_count = 0;
|
||||
OSStatus result;
|
||||
uint16_t attempts = 0;
|
||||
|
||||
check_string(!((command == SDIO_CMD_53) && (data == NULL)), "Bad args" );
|
||||
|
||||
if ( response != NULL )
|
||||
{
|
||||
*response = 0;
|
||||
}
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
/* Ensure the bus isn't stuck half way through transfer */
|
||||
DMA2_Stream3->CR = 0;
|
||||
|
||||
restart:
|
||||
SDIO->ICR = (uint32_t) 0xFFFFFFFF;
|
||||
sdio_transfer_failed = false;
|
||||
++attempts;
|
||||
|
||||
/* Check if we've tried too many times */
|
||||
if (attempts >= (uint16_t) BUS_LEVEL_MAX_RETRIES)
|
||||
{
|
||||
result = kGeneralErr;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Prepare the data transfer register */
|
||||
current_command = command;
|
||||
if ( command == SDIO_CMD_53 )
|
||||
{
|
||||
sdio_enable_bus_irq();
|
||||
|
||||
/* Dodgy STM32 hack to set the CMD53 byte mode size to be the same as the block size */
|
||||
if ( mode == SDIO_BYTE_MODE )
|
||||
{
|
||||
block_size = find_optimal_block_size( data_size );
|
||||
if ( block_size < SDIO_512B_BLOCK )
|
||||
{
|
||||
argument = ( argument & (uint32_t) ( ~0x1FF ) ) | block_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
argument = ( argument & (uint32_t) ( ~0x1FF ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Prepare the SDIO for a data transfer */
|
||||
current_transfer_direction = direction;
|
||||
sdio_prepare_data_transfer( direction, block_size, (uint8_t*) data, data_size );
|
||||
|
||||
/* Send the command */
|
||||
SDIO->ARG = argument;
|
||||
SDIO->CMD = (uint32_t) ( command | SDIO_Response_Short | SDIO_Wait_No | SDIO_CPSM_Enable );
|
||||
|
||||
/* Wait for the whole transfer to complete */
|
||||
result = mico_rtos_get_semaphore( &sdio_transfer_finished_semaphore, (uint32_t) 50 );
|
||||
if ( result != kNoErr )
|
||||
{
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ( sdio_transfer_failed == true )
|
||||
{
|
||||
goto restart;
|
||||
}
|
||||
|
||||
/* Check if there were any SDIO errors */
|
||||
require(( SDIO->STA & ( SDIO_STA_DTIMEOUT | SDIO_STA_CTIMEOUT ) ) == 0, restart);
|
||||
require_string(( SDIO->STA & ( SDIO_STA_CCRCFAIL | SDIO_STA_DCRCFAIL | SDIO_STA_TXUNDERR | SDIO_STA_RXOVERR ) ) == 0, restart, "SDIO communication failure");
|
||||
|
||||
/* Wait till complete */
|
||||
loop_count = (uint32_t) SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS;
|
||||
do
|
||||
{
|
||||
loop_count--;
|
||||
if ( loop_count == 0 || ( ( SDIO->STA & SDIO_ERROR_MASK ) != 0 ) )
|
||||
{
|
||||
goto restart;
|
||||
}
|
||||
} while ( ( SDIO->STA & ( SDIO_STA_TXACT | SDIO_STA_RXACT ) ) != 0 );
|
||||
|
||||
if ( direction == BUS_READ )
|
||||
{
|
||||
memcpy( user_data, dma_data_source, (size_t) user_data_size );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t temp_sta;
|
||||
|
||||
/* Send the command */
|
||||
SDIO->ARG = argument;
|
||||
SDIO->CMD = (uint32_t) ( command | SDIO_Response_Short | SDIO_Wait_No | SDIO_CPSM_Enable );
|
||||
|
||||
loop_count = (uint32_t) COMMAND_FINISHED_CMD52_TIMEOUT_LOOPS;
|
||||
do
|
||||
{
|
||||
temp_sta = SDIO->STA;
|
||||
loop_count--;
|
||||
if ( loop_count == 0 || ( ( response_expected == RESPONSE_NEEDED ) && ( ( temp_sta & SDIO_ERROR_MASK ) != 0 ) ) )
|
||||
{
|
||||
goto restart;
|
||||
}
|
||||
} while ( ( temp_sta & SDIO_FLAG_CMDACT ) != 0 );
|
||||
}
|
||||
|
||||
if ( response != NULL )
|
||||
{
|
||||
*response = SDIO->RESP1;
|
||||
}
|
||||
result = kNoErr;
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
#ifndef SDIO_1_BIT
|
||||
SDIO->MASK = SDIO_MASK_SDIOITIE;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static void sdio_prepare_data_transfer( bus_transfer_direction_t direction, sdio_block_size_t block_size, /*@unique@*/ uint8_t* data, uint16_t data_size ) /*@modifies dma_data_source, user_data, user_data_size, dma_transfer_size@*/
|
||||
{
|
||||
/* Setup a single transfer using the temp buffer */
|
||||
user_data = data;
|
||||
user_data_size = data_size;
|
||||
dma_transfer_size = (uint32_t) ( ( ( data_size + (uint16_t) block_size - 1 ) / (uint16_t) block_size ) * (uint16_t) block_size );
|
||||
|
||||
if ( direction == BUS_WRITE )
|
||||
{
|
||||
dma_data_source = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
dma_data_source = temp_dma_buffer;
|
||||
}
|
||||
|
||||
SDIO->DTIMER = (uint32_t) 0xFFFFFFFF;
|
||||
SDIO->DLEN = dma_transfer_size;
|
||||
SDIO->DCTRL = (uint32_t)sdio_get_blocksize_dctrl(block_size) | bus_direction_mapping[(int)direction] | SDIO_TransferMode_Block | SDIO_DPSM_Enable | (1 << 3) | (1 << 11);
|
||||
|
||||
/* DMA2 Stream3 */
|
||||
DMA2_Stream3->CR = 0;
|
||||
DMA2->LIFCR = (uint32_t) ( 0x3F << 22 );
|
||||
DMA2_Stream3->FCR = (uint32_t) ( 0x00000021 | DMA_FIFOMode_Enable | DMA_FIFOThreshold_Full );
|
||||
DMA2_Stream3->PAR = (uint32_t) &SDIO->FIFO;
|
||||
DMA2_Stream3->M0AR = (uint32_t) dma_data_source;
|
||||
DMA2_Stream3->NDTR = dma_transfer_size/4;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void host_platform_enable_high_speed_sdio( void )
|
||||
{
|
||||
SDIO_InitTypeDef sdio_init_structure;
|
||||
|
||||
sdio_init_structure.SDIO_ClockDiv = (uint8_t) 0; /* 0 = 24MHz if SDIO clock = 48MHz */
|
||||
sdio_init_structure.SDIO_ClockEdge = SDIO_ClockEdge_Rising;
|
||||
sdio_init_structure.SDIO_ClockBypass = SDIO_ClockBypass_Disable;
|
||||
sdio_init_structure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable;
|
||||
#ifndef SDIO_1_BIT
|
||||
sdio_init_structure.SDIO_BusWide = SDIO_BusWide_4b;
|
||||
#else
|
||||
sdio_init_structure.SDIO_BusWide = SDIO_BusWide_1b;
|
||||
#endif
|
||||
sdio_init_structure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable;
|
||||
|
||||
SDIO_DeInit( );
|
||||
SDIO_Init( &sdio_init_structure );
|
||||
SDIO_SetPowerState( SDIO_PowerState_ON );
|
||||
SDIO_ClockCmd( ENABLE );
|
||||
sdio_enable_bus_irq( );
|
||||
}
|
||||
|
||||
static sdio_block_size_t find_optimal_block_size( uint32_t data_size )
|
||||
{
|
||||
if ( data_size > (uint32_t) 256 )
|
||||
return SDIO_512B_BLOCK;
|
||||
if ( data_size > (uint32_t) 128 )
|
||||
return SDIO_256B_BLOCK;
|
||||
if ( data_size > (uint32_t) 64 )
|
||||
return SDIO_128B_BLOCK;
|
||||
if ( data_size > (uint32_t) 32 )
|
||||
return SDIO_64B_BLOCK;
|
||||
if ( data_size > (uint32_t) 16 )
|
||||
return SDIO_32B_BLOCK;
|
||||
if ( data_size > (uint32_t) 8 )
|
||||
return SDIO_16B_BLOCK;
|
||||
if ( data_size > (uint32_t) 4 )
|
||||
return SDIO_8B_BLOCK;
|
||||
if ( data_size > (uint32_t) 2 )
|
||||
return SDIO_4B_BLOCK;
|
||||
|
||||
return SDIO_4B_BLOCK;
|
||||
}
|
||||
|
||||
static uint32_t sdio_get_blocksize_dctrl(sdio_block_size_t block_size)
|
||||
{
|
||||
switch (block_size)
|
||||
{
|
||||
case SDIO_1B_BLOCK: return SDIO_DataBlockSize_1b;
|
||||
case SDIO_2B_BLOCK: return SDIO_DataBlockSize_2b;
|
||||
case SDIO_4B_BLOCK: return SDIO_DataBlockSize_4b;
|
||||
case SDIO_8B_BLOCK: return SDIO_DataBlockSize_8b;
|
||||
case SDIO_16B_BLOCK: return SDIO_DataBlockSize_16b;
|
||||
case SDIO_32B_BLOCK: return SDIO_DataBlockSize_32b;
|
||||
case SDIO_64B_BLOCK: return SDIO_DataBlockSize_64b;
|
||||
case SDIO_128B_BLOCK: return SDIO_DataBlockSize_128b;
|
||||
case SDIO_256B_BLOCK: return SDIO_DataBlockSize_256b;
|
||||
case SDIO_512B_BLOCK: return SDIO_DataBlockSize_512b;
|
||||
case SDIO_1024B_BLOCK: return SDIO_DataBlockSize_1024b;
|
||||
case SDIO_2048B_BLOCK: return SDIO_DataBlockSize_2048b;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void SDIO_IRQHandler(void)
|
||||
{
|
||||
/* Process All SDIO Interrupt Sources */
|
||||
sdio_irq();
|
||||
}
|
||||
|
||||
void DMA2_Stream3_IRQHandler(void)
|
||||
{
|
||||
dma_irq();
|
||||
}
|
||||
263
mico-os/platform/MCU/ATSAMG55/wlan_bus_driver/wlan_bus_SPI.c
Normal file
263
mico-os/platform/MCU/ATSAMG55/wlan_bus_driver/wlan_bus_SPI.c
Normal file
@@ -0,0 +1,263 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file wlan_bus_spi.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provides SPI bus protocol for RF chip.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#include "string.h" /* for memcpy */
|
||||
#include "platform.h"
|
||||
#include "platform_peripheral.h"
|
||||
#include "platform_logging.h"
|
||||
#include "platform_config.h"
|
||||
#include "wlan_platform_common.h"
|
||||
|
||||
|
||||
/******************************************************
|
||||
* constants
|
||||
******************************************************/
|
||||
|
||||
/* Clock polarity. */
|
||||
#define SPI_CLK_POLARITY 0
|
||||
|
||||
/* Clock phase. */
|
||||
#define SPI_CLK_PHASE 1
|
||||
|
||||
#define SPI_BAUD_RATE 30000000
|
||||
|
||||
/**
|
||||
* transfer direction for the mico platform bus interface
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
/* if updating this enum, the bus_direction_mapping variable will also need to be updated */
|
||||
BUS_READ,
|
||||
BUS_WRITE
|
||||
} bus_transfer_direction_t;
|
||||
|
||||
/******************************************************
|
||||
* structures
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* variables
|
||||
******************************************************/
|
||||
static IRQn_Type platform_flexcom_irq_numbers[] =
|
||||
{
|
||||
[0] = FLEXCOM0_IRQn,
|
||||
[1] = FLEXCOM1_IRQn,
|
||||
[2] = FLEXCOM2_IRQn,
|
||||
[3] = FLEXCOM3_IRQn,
|
||||
[4] = FLEXCOM4_IRQn,
|
||||
[5] = FLEXCOM5_IRQn,
|
||||
[6] = FLEXCOM6_IRQn,
|
||||
[7] = FLEXCOM7_IRQn,
|
||||
};
|
||||
|
||||
static Flexcom *flexcom_base[] =
|
||||
{
|
||||
[0] = FLEXCOM0,
|
||||
[1] = FLEXCOM1,
|
||||
[2] = FLEXCOM2,
|
||||
[3] = FLEXCOM3,
|
||||
[4] = FLEXCOM4,
|
||||
[5] = FLEXCOM5,
|
||||
[6] = FLEXCOM6,
|
||||
[7] = FLEXCOM7,
|
||||
};
|
||||
static mico_semaphore_t spi_transfer_finished_semaphore;
|
||||
|
||||
/******************************************************
|
||||
* function declarations
|
||||
******************************************************/
|
||||
|
||||
extern void wlan_notify_irq( void );
|
||||
|
||||
/******************************************************
|
||||
* function definitions
|
||||
******************************************************/
|
||||
|
||||
static void spi_irq_handler( void* arg )
|
||||
{
|
||||
UNUSED_PARAMETER(arg);
|
||||
#ifndef MICO_DISABLE_MCU_POWERSAVE
|
||||
platform_mcu_powersave_exit_notify( );
|
||||
#endif /* ifndef MICO_DISABLE_MCU_POWERSAVE */
|
||||
wlan_notify_irq( );
|
||||
}
|
||||
|
||||
|
||||
OSStatus host_platform_bus_init( void )
|
||||
{
|
||||
pdc_packet_t pdc_spi_packet;
|
||||
Pdc* spi_pdc = spi_get_pdc_base( wifi_spi.port );
|
||||
|
||||
platform_mcu_powersave_disable( );
|
||||
|
||||
mico_rtos_init_semaphore( &spi_transfer_finished_semaphore, 1 );
|
||||
|
||||
/* Setup the SPI lines */
|
||||
platform_gpio_peripheral_pin_init( wifi_spi.mosi_pin, ( wifi_spi.mosi_pin_mux_mode | IOPORT_MODE_PULLUP ) );
|
||||
platform_gpio_peripheral_pin_init( wifi_spi.miso_pin, ( wifi_spi.miso_pin_mux_mode | IOPORT_MODE_PULLUP ) );
|
||||
platform_gpio_peripheral_pin_init( wifi_spi.clock_pin, ( wifi_spi.clock_pin_mux_mode | IOPORT_MODE_PULLUP ) );
|
||||
|
||||
/* Setup the interrupt input for WLAN_IRQ */
|
||||
platform_gpio_init( &wifi_spi_pins[WIFI_PIN_SPI_IRQ], INPUT_HIGH_IMPEDANCE );
|
||||
platform_gpio_irq_enable( &wifi_spi_pins[WIFI_PIN_SPI_IRQ], IRQ_TRIGGER_RISING_EDGE, spi_irq_handler, 0 );
|
||||
|
||||
/* Setup SPI slave select GPIOs */
|
||||
platform_gpio_init( &wifi_spi_pins[WIFI_PIN_SPI_CS], OUTPUT_PUSH_PULL );
|
||||
platform_gpio_output_high( &wifi_spi_pins[WIFI_PIN_SPI_CS] );
|
||||
|
||||
#if defined ( MICO_WIFI_USE_GPIO_FOR_BOOTSTRAP )
|
||||
/* Set GPIO_B[1:0] to 01 to put WLAN module into gSPI mode */
|
||||
platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0], OUTPUT_PUSH_PULL );
|
||||
platform_gpio_output_high( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0] );
|
||||
platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1], OUTPUT_PUSH_PULL );
|
||||
platform_gpio_output_low( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1] );
|
||||
#endif
|
||||
|
||||
/* Enable the peripheral and set SPI mode. */
|
||||
flexcom_enable( flexcom_base[ wifi_spi.spi_id ] );
|
||||
flexcom_set_opmode( flexcom_base[ wifi_spi.spi_id ], FLEXCOM_SPI );
|
||||
|
||||
/* Init pdc, and clear RX TX. */
|
||||
pdc_spi_packet.ul_addr = 0;
|
||||
pdc_spi_packet.ul_size = 1;
|
||||
pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
|
||||
spi_disable_interrupt(wifi_spi.port, 0xffffffff );
|
||||
spi_disable( wifi_spi.port );
|
||||
spi_reset( wifi_spi.port );
|
||||
spi_set_lastxfer( wifi_spi.port );
|
||||
spi_set_master_mode( wifi_spi.port );
|
||||
spi_disable_mode_fault_detect( wifi_spi.port );
|
||||
|
||||
spi_set_clock_polarity( wifi_spi.port, 0, SPI_CLK_POLARITY );
|
||||
spi_set_clock_phase( wifi_spi.port, 0, SPI_CLK_PHASE );
|
||||
spi_set_bits_per_transfer( wifi_spi.port, 0, SPI_CSR_BITS_8_BIT );
|
||||
spi_set_baudrate_div( wifi_spi.port, 0, (sysclk_get_cpu_hz() / SPI_BAUD_RATE) );
|
||||
spi_set_transfer_delay( wifi_spi.port, 0, 0, 0 );
|
||||
|
||||
/* Must be lower priority than the value of configMAX_SYSCALL_INTERRUPT_PRIORITY */
|
||||
/* otherwise FreeRTOS will not be able to mask the interrupt */
|
||||
/* keep in mind that ARMCM4 interrupt priority logic is inverted, the highest value */
|
||||
/* is the lowest priority */
|
||||
/* Configure SPI interrupts . */
|
||||
|
||||
NVIC_EnableIRQ( platform_flexcom_irq_numbers[wifi_spi.spi_id] );
|
||||
|
||||
spi_enable(wifi_spi.port);
|
||||
|
||||
platform_mcu_powersave_enable( );
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus host_platform_bus_deinit( void )
|
||||
{
|
||||
platform_mcu_powersave_disable( );
|
||||
|
||||
NVIC_DisableIRQ( platform_flexcom_irq_numbers[wifi_spi.spi_id] );
|
||||
pdc_disable_transfer( spi_get_pdc_base( wifi_spi.port ), PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS );
|
||||
spi_disable(wifi_spi.port);
|
||||
|
||||
/* Deinit the SPI lines */
|
||||
platform_gpio_peripheral_pin_init( wifi_spi.mosi_pin, INPUT_HIGH_IMPEDANCE );
|
||||
platform_gpio_peripheral_pin_init( wifi_spi.miso_pin, INPUT_HIGH_IMPEDANCE );
|
||||
platform_gpio_peripheral_pin_init( wifi_spi.clock_pin, INPUT_HIGH_IMPEDANCE );
|
||||
|
||||
/* Deinit the interrupt input for WLAN_IRQ */
|
||||
platform_gpio_init( &wifi_spi_pins[WIFI_PIN_SPI_IRQ], INPUT_HIGH_IMPEDANCE );
|
||||
platform_gpio_irq_disable( &wifi_spi_pins[WIFI_PIN_SPI_IRQ] );
|
||||
|
||||
/* Deinit SPI slave select GPIOs */
|
||||
platform_gpio_init( &wifi_spi_pins[WIFI_PIN_SPI_CS], INPUT_HIGH_IMPEDANCE );
|
||||
|
||||
#if defined ( MICO_WIFI_USE_GPIO_FOR_BOOTSTRAP )
|
||||
platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0], INPUT_HIGH_IMPEDANCE );
|
||||
platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1], INPUT_HIGH_IMPEDANCE );
|
||||
#endif
|
||||
|
||||
platform_mcu_powersave_enable( );
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus host_platform_spi_transfer( bus_transfer_direction_t dir, uint8_t* buffer, uint16_t buffer_length )
|
||||
{
|
||||
OSStatus result;
|
||||
|
||||
pdc_packet_t pdc_spi_packet = { (uint32_t)buffer, buffer_length };
|
||||
Pdc* spi_pdc = spi_get_pdc_base( wifi_spi.port );
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
platform_gpio_output_low( &wifi_spi_pins[WIFI_PIN_SPI_CS] );
|
||||
|
||||
pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL);
|
||||
|
||||
if ( dir == BUS_READ ) {
|
||||
pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL);
|
||||
|
||||
spi_enable_interrupt(wifi_spi.port, SPI_IER_RXBUFF );
|
||||
pdc_enable_transfer( spi_pdc, PERIPH_PTCR_TXTEN | PERIPH_PTCR_RXTEN );
|
||||
}
|
||||
|
||||
if ( dir == BUS_WRITE ) {
|
||||
spi_enable_interrupt( wifi_spi.port, SPI_IER_ENDTX );
|
||||
pdc_enable_transfer( spi_pdc, PERIPH_PTCR_TXTEN );
|
||||
}
|
||||
|
||||
result = mico_rtos_get_semaphore( &spi_transfer_finished_semaphore, 100 );
|
||||
|
||||
platform_gpio_output_high( &wifi_spi_pins[WIFI_PIN_SPI_CS] );
|
||||
|
||||
platform_mcu_powersave_enable();
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
void platform_wifi_spi_rx_dma_irq(void)
|
||||
{
|
||||
uint8_t junk1;
|
||||
uint16_t junk2;
|
||||
pdc_packet_t pdc_spi_packet = { 0, 1 };
|
||||
Pdc* spi_pdc = spi_get_pdc_base( wifi_spi.port );
|
||||
|
||||
uint32_t status = spi_read_status( wifi_spi.port );
|
||||
uint32_t mask = spi_read_interrupt_mask( wifi_spi.port );
|
||||
|
||||
if ( ( mask & SPI_IMR_RXBUFF ) && ( status & SPI_SR_RXBUFF ) )
|
||||
{
|
||||
pdc_disable_transfer( spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS );
|
||||
pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
spi_disable_interrupt( wifi_spi.port, SPI_IER_RXBUFF );
|
||||
}
|
||||
|
||||
if ( ( mask & SPI_IMR_ENDTX ) && ( status & SPI_SR_ENDTX ) )
|
||||
{
|
||||
pdc_disable_transfer( spi_pdc, PERIPH_PTCR_TXTDIS );
|
||||
pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
spi_disable_interrupt( wifi_spi.port, SPI_IER_ENDTX );
|
||||
/* Clear SPI RX data in a SPI send sequence */
|
||||
spi_read( wifi_spi.port, &junk2, &junk1);
|
||||
}
|
||||
|
||||
mico_rtos_set_semaphore( &spi_transfer_finished_semaphore );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file wlan_platform.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide functions called by MICO to wlan RF module
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "platform_config.h"
|
||||
#include "platform_peripheral.h"
|
||||
#include "platform_logging.h"
|
||||
|
||||
/* Used to give a 32k clock to EMW1062 wifi rf module */
|
||||
OSStatus host_platform_init_wlan_powersave_clock( void )
|
||||
{
|
||||
return kUnsupportedErr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user