从模式示例
## 从模式示例
```language
/**
* @file spi_slave_demo.c
* @ingroup peripheral
* @brief SPI从设备工作模式Demo
*
***********************************************************************************/
#include "softap_api.h"
#if DEMO_TEST
#include "xy_peripheral.h"
//these define are provide a modification for user
#define SPI_MOSI_PIN GPIO_PIN_NUM_6
#define SPI_MISO_PIN GPIO_PIN_NUM_8
#define SPI_SCLK_PIN GPIO_PIN_NUM_7
#define SPI_CS_PIN GPIO_PIN_NUM_9
#define SPI_WORK_MODE SPI_WORK_MODE_0 //can use: 0 1 2 3
#define SPI_DATA_WIDTH SPI_DATA_WIDTH_8 //can use: 8 16 32
#define SPI_SLAVE_TASK_PRIORITY 5
#define SPI_SLAVE_STACK_SIZE 1024
UINT32 g_spi_slave_sem = -1;
UINT32 g_spi_slave_TskHandle = -1;
UINT32 rcv_cmd; // save the command
/**
* @brief 功能1,SPI写功能
*
*/
void test_function1(void)
{
uint8_t wData[] = {0xAA, 0xBB};
xy_SPI_Write(SPI1, (void *)wData, sizeof(wData));
}
/**
* @brief 功能2,SPI读功能,并将读到的SPI数据通过AT口传出
*
*/
void test_function2(void)
{
uint8_t rcv_len;
uint8_t *p_rcv;
xy_SPI_Read(SPI1, (void *)&rcv_len, sizeof(rcv_len));
p_rcv = xy_malloc(rcv_len);
xy_SPI_Read(SPI1, (void *)p_rcv, rcv_len);
xy_SPI_IntCmd(SPI1, SPI_INTTYPE_RX_FIFO_NE, ENABLE);
write_to_csp(p_rcv, rcv_len);
xy_free(p_rcv);
}
void user_hook_spi_slave_handler(void)
{
switch(rcv_cmd)
{
case 0xA5: test_function1(); break;
case 0x15: test_function2(); break;
}
}
void spi_int_handle(void) __attribute__((section(".ramtext")));
/**
* @brief SPI中断服务函数
* @code
* xy_SPI_Read(SPI1, (void *)&rcv_cmd, 1);
if(rcv_cmd == 0x15) // receive data command, close interrupt to receive data
xy_SPI_IntCmd(SPI1, SPI_INTTYPE_RX_FIFO_NE, DISABLE);
xy_Semaphore_Give(&g_spi_slave_sem);
* @endcode
*
*/
void spi_int_handle(void)
{
xy_SPI_Read(SPI1, (void *)&rcv_cmd, 1);
if(rcv_cmd == 0x15) // receive data command, close interrupt to receive data
xy_SPI_IntCmd(SPI1, SPI_INTTYPE_RX_FIFO_NE, DISABLE);
xy_Semaphore_Give(&g_spi_slave_sem);
}
/**
* @brief SPI初始化函数
* @note 在配置IO前需要清空配置寄存器并开启外设时钟
*
* @code
*
* xy_PRCM_ClockCmd(PRCM_CKG_CTL_SPI1, ENABLE);
xy_PRCM_ClockCmd(PRCM_CKG_CTL_GPIO, ENABLE);
xy_GPIO_ClearConfig(SPI_MISO_PIN);
xy_GPIO_ClearConfig(SPI_MOSI_PIN);
xy_GPIO_ClearConfig(SPI_SCLK_PIN);
xy_GPIO_ClearConfig(SPI_CS_PIN);
xy_GPIO_Remapping(SPI_SCLK_PIN, REMAP_SPI_SCLK);
xy_GPIO_Remapping(SPI_MISO_PIN, REMAP_SPI_MISO);
xy_GPIO_Remapping(SPI_MOSI_PIN, REMAP_SPI_MOSI);
xy_GPIO_Remapping(SPI_CS_PIN, REMAP_SPI_CS);
xy_GPIO_SetIOMode(SPI_SCLK_PIN, GPIO_MODE_HW_PER);
xy_GPIO_SetIOMode(SPI_MISO_PIN, GPIO_MODE_HW_PER);
xy_GPIO_SetIOMode(SPI_MOSI_PIN, GPIO_MODE_HW_PER);
xy_GPIO_SetIOMode(SPI_CS_PIN, GPIO_MODE_HW_PER);
xy_SPI_SlaveInit(SPI1, SPI_WORK_MODE, SPI_DATA_WIDTH);
xy_SPI_FIFO_Level_Set(SPI1, 20, 1);
//xy_SPI_Delay_Set(SPI1, 4, 4, 4, 4);
xy_Semaphore_Create(&g_spi_slave_sem);
xy_NVIC_IntRegister(SPI1_IRQn, 1, spi_int_handle);
xy_SPI_IntCmd(SPI1, SPI_INTTYPE_RX_FIFO_NE, ENABLE);
xy_SPI_Cmd(SPI1, ENABLE);
*
* @endcode
*
*/
void spi_slave_gpio_init(void)
{
xy_PRCM_ClockCmd(PRCM_CKG_CTL_SPI1, ENABLE);
xy_PRCM_ClockCmd(PRCM_CKG_CTL_GPIO, ENABLE);
xy_GPIO_ClearConfig(SPI_MISO_PIN);
xy_GPIO_ClearConfig(SPI_MOSI_PIN);
xy_GPIO_ClearConfig(SPI_SCLK_PIN);
xy_GPIO_ClearConfig(SPI_CS_PIN);
xy_GPIO_Remapping(SPI_SCLK_PIN, REMAP_SPI_SCLK);
xy_GPIO_Remapping(SPI_MISO_PIN, REMAP_SPI_MISO);
xy_GPIO_Remapping(SPI_MOSI_PIN, REMAP_SPI_MOSI);
xy_GPIO_Remapping(SPI_CS_PIN, REMAP_SPI_CS);
xy_GPIO_SetIOMode(SPI_SCLK_PIN, GPIO_MODE_HW_PER);
xy_GPIO_SetIOMode(SPI_MISO_PIN, GPIO_MODE_HW_PER);
xy_GPIO_SetIOMode(SPI_MOSI_PIN, GPIO_MODE_HW_PER);
xy_GPIO_SetIOMode(SPI_CS_PIN, GPIO_MODE_HW_PER);
xy_SPI_SlaveInit(SPI1, SPI_WORK_MODE, SPI_DATA_WIDTH);
xy_SPI_FIFO_Level_Set(SPI1, 20, 1);
//xy_SPI_Delay_Set(SPI1, 4, 4, 4, 4);
xy_Semaphore_Create(&g_spi_slave_sem);
xy_NVIC_IntRegister(SPI1_IRQn, 1, spi_int_handle);
xy_SPI_IntCmd(SPI1, SPI_INTTYPE_RX_FIFO_NE, ENABLE);
xy_SPI_Cmd(SPI1, ENABLE);
}
/**
* @brief SPI工作线程
*
*/
void spi_slave_work_task(void)
{
while(1)
{
if( RET_OK == xy_Semaphore_Take(&g_spi_slave_sem, K_FOREVER) )
{
user_hook_spi_slave_handler();
}
}
}
/**
* @brief 这个函数为SPIdemo提供了一个工作线程
*
* @return UINT32
*/
UINT32 spi_slave_work_task_init(void)
{
UINT32 uwRet = LOS_NOK;
uwRet = xy_TaskCreate((TaskFunc_t)spi_slave_work_task, "spi_slave_work_task", SPI_SLAVE_STACK_SIZE, NULL, SPI_SLAVE_TASK_PRIORITY, &g_spi_slave_TskHandle);
return uwRet;
}
#endif
```